summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/RenderTextControl.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
commit32761a6cee1d0dee366b885b7b9c777e67885688 (patch)
treed6bec92bebfb216f4126356e55518842c2f476a1 /Source/WebCore/rendering/RenderTextControl.cpp
parenta4e969f4965059196ca948db781e52f7cfebf19e (diff)
downloadWebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/WebCore/rendering/RenderTextControl.cpp')
-rw-r--r--Source/WebCore/rendering/RenderTextControl.cpp163
1 files changed, 122 insertions, 41 deletions
diff --git a/Source/WebCore/rendering/RenderTextControl.cpp b/Source/WebCore/rendering/RenderTextControl.cpp
index 77712b1dc..ace5fc6b9 100644
--- a/Source/WebCore/rendering/RenderTextControl.cpp
+++ b/Source/WebCore/rendering/RenderTextControl.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2006, 2007, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
* (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
@@ -22,7 +22,6 @@
#include "config.h"
#include "RenderTextControl.h"
-#include "CSSPrimitiveValueMappings.h"
#include "HTMLTextFormControlElement.h"
#include "HitTestResult.h"
#include "RenderText.h"
@@ -30,15 +29,15 @@
#include "RenderTheme.h"
#include "ScrollbarTheme.h"
#include "StyleInheritedData.h"
-#include "StyleProperties.h"
#include "TextControlInnerElements.h"
+#include "TextIterator.h"
#include "VisiblePosition.h"
#include <wtf/unicode/CharacterNames.h>
namespace WebCore {
-RenderTextControl::RenderTextControl(HTMLTextFormControlElement& element, Ref<RenderStyle>&& style)
- : RenderBlockFlow(element, WTFMove(style))
+RenderTextControl::RenderTextControl(HTMLTextFormControlElement& element, PassRef<RenderStyle> style)
+ : RenderBlockFlow(element, std::move(style))
{
}
@@ -48,7 +47,7 @@ RenderTextControl::~RenderTextControl()
HTMLTextFormControlElement& RenderTextControl::textFormControlElement() const
{
- return downcast<HTMLTextFormControlElement>(nodeForNonAnonymous());
+ return toHTMLTextFormControlElement(nodeForNonAnonymous());
}
TextControlInnerTextElement* RenderTextControl::innerTextElement() const
@@ -69,40 +68,42 @@ void RenderTextControl::styleDidChange(StyleDifference diff, const RenderStyle*
innerTextRenderer->style().setHeight(Length());
innerTextRenderer->style().setWidth(Length());
innerTextRenderer->setStyle(createInnerTextStyle(&style()));
+ innerText->setNeedsStyleRecalc();
}
- textFormControlElement().updatePlaceholderVisibility();
+ textFormControlElement().updatePlaceholderVisibility(false);
}
-void RenderTextControl::adjustInnerTextStyle(const RenderStyle* startStyle, RenderStyle& textBlockStyle) const
+static inline bool updateUserModifyProperty(const HTMLTextFormControlElement& element, RenderStyle* style)
+{
+ bool isDisabled = element.isDisabledFormControl();
+ bool isReadOnlyControl = element.isReadOnly();
+
+ style->setUserModify((isReadOnlyControl || isDisabled) ? READ_ONLY : READ_WRITE_PLAINTEXT_ONLY);
+ return isDisabled;
+}
+
+void RenderTextControl::adjustInnerTextStyle(const RenderStyle* startStyle, RenderStyle* textBlockStyle) const
{
// The inner block, if present, always has its direction set to LTR,
// so we need to inherit the direction and unicode-bidi style from the element.
- textBlockStyle.setDirection(style().direction());
- textBlockStyle.setUnicodeBidi(style().unicodeBidi());
-
- HTMLTextFormControlElement& control = textFormControlElement();
- if (HTMLElement* innerText = control.innerTextElement()) {
- if (const StyleProperties* properties = innerText->presentationAttributeStyle()) {
- RefPtr<CSSValue> value = properties->getPropertyCSSValue(CSSPropertyWebkitUserModify);
- if (is<CSSPrimitiveValue>(value.get()))
- textBlockStyle.setUserModify(downcast<CSSPrimitiveValue>(*value));
- }
- }
+ textBlockStyle->setDirection(style().direction());
+ textBlockStyle->setUnicodeBidi(style().unicodeBidi());
- if (control.isDisabledFormControl())
- textBlockStyle.setColor(theme().disabledTextColor(textBlockStyle.visitedDependentColor(CSSPropertyColor), startStyle->visitedDependentColor(CSSPropertyBackgroundColor)));
+ bool disabled = updateUserModifyProperty(textFormControlElement(), textBlockStyle);
+ if (disabled)
+ textBlockStyle->setColor(theme().disabledTextColor(textBlockStyle->visitedDependentColor(CSSPropertyColor), startStyle->visitedDependentColor(CSSPropertyBackgroundColor)));
#if PLATFORM(IOS)
- if (textBlockStyle.textSecurity() != TSNONE && !textBlockStyle.isLeftToRightDirection()) {
+ if (textBlockStyle->textSecurity() != TSNONE && !textBlockStyle->isLeftToRightDirection()) {
// Preserve the alignment but force the direction to LTR so that the last-typed, unmasked character
// (which cannot have RTL directionality) will appear to the right of the masked characters. See <rdar://problem/7024375>.
- switch (textBlockStyle.textAlign()) {
+ switch (textBlockStyle->textAlign()) {
case TASTART:
case JUSTIFY:
- textBlockStyle.setTextAlign(RIGHT);
+ textBlockStyle->setTextAlign(RIGHT);
break;
case TAEND:
- textBlockStyle.setTextAlign(LEFT);
+ textBlockStyle->setTextAlign(LEFT);
break;
case LEFT:
case RIGHT:
@@ -113,7 +114,7 @@ void RenderTextControl::adjustInnerTextStyle(const RenderStyle* startStyle, Rend
break;
}
- textBlockStyle.setDirection(LTR);
+ textBlockStyle->setDirection(LTR);
}
#endif
}
@@ -135,10 +136,17 @@ int RenderTextControl::textBlockLogicalWidth() const
return unitWidth;
}
+void RenderTextControl::updateFromElement()
+{
+ TextControlInnerTextElement* innerText = innerTextElement();
+ if (innerText && innerText->renderer())
+ updateUserModifyProperty(textFormControlElement(), &innerText->renderer()->style());
+}
+
int RenderTextControl::scrollbarThickness() const
{
// FIXME: We should get the size of the scrollbar from the RenderTheme instead.
- return ScrollbarTheme::theme().scrollbarThickness();
+ return ScrollbarTheme::theme()->scrollbarThickness();
}
void RenderTextControl::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const
@@ -146,8 +154,8 @@ void RenderTextControl::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUni
TextControlInnerTextElement* innerText = innerTextElement();
ASSERT(innerText);
if (RenderBox* innerTextBox = innerText->renderBox()) {
- LayoutUnit nonContentHeight = innerTextBox->verticalBorderAndPaddingExtent() + innerTextBox->verticalMarginExtent();
- logicalHeight = computeControlLogicalHeight(innerTextBox->lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes), nonContentHeight) + verticalBorderAndPaddingExtent();
+ LayoutUnit nonContentHeight = innerTextBox->borderAndPaddingHeight() + innerTextBox->marginHeight();
+ logicalHeight = computeControlLogicalHeight(innerTextBox->lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes), nonContentHeight) + borderAndPaddingHeight();
// We are able to have a horizontal scrollbar if the overflow style is scroll, or if its auto and there's no word wrap.
if ((isHorizontalWritingMode() && (style().overflowX() == OSCROLL || (style().overflowX() == OAUTO && innerText->renderer()->style().overflowWrap() == NormalOverflowWrap)))
@@ -165,22 +173,89 @@ void RenderTextControl::hitInnerTextElement(HitTestResult& result, const LayoutP
return;
LayoutPoint adjustedLocation = accumulatedOffset + location();
- LayoutPoint localPoint = pointInContainer - toLayoutSize(adjustedLocation + innerText->renderBox()->location()) + scrolledContentOffset();
+ LayoutPoint localPoint = pointInContainer - toLayoutSize(adjustedLocation + innerText->renderBox()->location());
+ if (hasOverflowClip())
+ localPoint += scrolledContentOffset();
result.setInnerNode(innerText);
result.setInnerNonSharedNode(innerText);
result.setLocalPoint(localPoint);
}
-float RenderTextControl::getAverageCharWidth()
+static const char* fontFamiliesWithInvalidCharWidth[] = {
+ "American Typewriter",
+ "Arial Hebrew",
+ "Chalkboard",
+ "Cochin",
+ "Corsiva Hebrew",
+ "Courier",
+ "Euphemia UCAS",
+ "Geneva",
+ "Gill Sans",
+ "Hei",
+ "Helvetica",
+ "Hoefler Text",
+ "InaiMathi",
+ "Kai",
+ "Lucida Grande",
+ "Marker Felt",
+ "Monaco",
+ "Mshtakan",
+ "New Peninim MT",
+ "Osaka",
+ "Raanana",
+ "STHeiti",
+ "Symbol",
+ "Times",
+ "Apple Braille",
+ "Apple LiGothic",
+ "Apple LiSung",
+ "Apple Symbols",
+ "AppleGothic",
+ "AppleMyungjo",
+ "#GungSeo",
+ "#HeadLineA",
+ "#PCMyungjo",
+ "#PilGi",
+};
+
+// For font families where any of the fonts don't have a valid entry in the OS/2 table
+// for avgCharWidth, fallback to the legacy webkit behavior of getting the avgCharWidth
+// from the width of a '0'. This only seems to apply to a fixed number of Mac fonts,
+// but, in order to get similar rendering across platforms, we do this check for
+// all platforms.
+bool RenderTextControl::hasValidAvgCharWidth(AtomicString family)
{
- float width;
- if (style().fontCascade().fastAverageCharWidthIfAvailable(width))
- return width;
+ if (family.isEmpty())
+ return false;
+
+ // Internal fonts on OS X also have an invalid entry in the table for avgCharWidth.
+ // They are hidden by having a name that begins with a period, so simply search
+ // for that here rather than try to keep the list up to date.
+ if (family.startsWith('.'))
+ return false;
+
+ static HashSet<AtomicString>* fontFamiliesWithInvalidCharWidthMap = 0;
+
+ if (!fontFamiliesWithInvalidCharWidthMap) {
+ fontFamiliesWithInvalidCharWidthMap = new HashSet<AtomicString>;
+
+ for (size_t i = 0; i < WTF_ARRAY_LENGTH(fontFamiliesWithInvalidCharWidth); ++i)
+ fontFamiliesWithInvalidCharWidthMap->add(AtomicString(fontFamiliesWithInvalidCharWidth[i]));
+ }
+
+ return !fontFamiliesWithInvalidCharWidthMap->contains(family);
+}
+
+float RenderTextControl::getAvgCharWidth(AtomicString family)
+{
+ if (hasValidAvgCharWidth(family))
+ return roundf(style().font().primaryFont()->avgCharWidth());
const UChar ch = '0';
const String str = String(&ch, 1);
- const FontCascade& font = style().fontCascade();
- TextRun textRun = constructTextRun(this, font, str, style(), AllowTrailingExpansion);
+ const Font& font = style().font();
+ TextRun textRun = constructTextRun(this, font, str, style(), TextRun::AllowTrailingExpansion);
+ textRun.disableRoundingHacks();
return font.width(textRun);
}
@@ -188,16 +263,17 @@ float RenderTextControl::scaleEmToUnits(int x) const
{
// This matches the unitsPerEm value for MS Shell Dlg and Courier New from the "head" font table.
float unitsPerEm = 2048.0f;
- return roundf(style().fontCascade().size() * x / unitsPerEm);
+ return roundf(style().font().size() * x / unitsPerEm);
}
void RenderTextControl::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
{
// Use average character width. Matches IE.
- maxLogicalWidth = preferredContentLogicalWidth(const_cast<RenderTextControl*>(this)->getAverageCharWidth());
+ const AtomicString& family = style().font().firstFamily();
+ maxLogicalWidth = preferredContentLogicalWidth(const_cast<RenderTextControl*>(this)->getAvgCharWidth(family));
if (RenderBox* innerTextRenderBox = innerTextElement()->renderBox())
maxLogicalWidth += innerTextRenderBox->paddingStart() + innerTextRenderBox->paddingEnd();
- if (!style().logicalWidth().isPercentOrCalculated())
+ if (!style().logicalWidth().isPercent())
minLogicalWidth = maxLogicalWidth;
}
@@ -231,10 +307,10 @@ void RenderTextControl::computePreferredLogicalWidths()
setPreferredLogicalWidthsDirty(false);
}
-void RenderTextControl::addFocusRingRects(Vector<LayoutRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject*)
+void RenderTextControl::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject*)
{
if (!size().isEmpty())
- rects.append(LayoutRect(additionalOffset, size()));
+ rects.append(pixelSnappedIntRect(additionalOffset, size()));
}
RenderObject* RenderTextControl::layoutSpecialExcludedChild(bool relayoutChildren)
@@ -268,4 +344,9 @@ int RenderTextControl::innerLineHeight() const
}
#endif
+bool RenderTextControl::canBeReplacedWithInlineRunIn() const
+{
+ return false;
+}
+
} // namespace WebCore