diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
commit | 32761a6cee1d0dee366b885b7b9c777e67885688 (patch) | |
tree | d6bec92bebfb216f4126356e55518842c2f476a1 /Source/WebCore/rendering/RenderTextControl.cpp | |
parent | a4e969f4965059196ca948db781e52f7cfebf19e (diff) | |
download | WebKitGtk-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.cpp | 163 |
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 |