Diff
Modified: trunk/Source/WebCore/ChangeLog (205984 => 205985)
--- trunk/Source/WebCore/ChangeLog 2016-09-15 18:04:45 UTC (rev 205984)
+++ trunk/Source/WebCore/ChangeLog 2016-09-15 18:11:48 UTC (rev 205985)
@@ -1,3 +1,26 @@
+2016-09-14 Antti Koivisto <an...@apple.com>
+
+ Move text decoration style computation from RenderObject to TextDecorationPainter
+ https://bugs.webkit.org/show_bug.cgi?id=162004
+
+ Reviewed by Zalan Bujtas.
+
+ It is mostly an implementation detail of TextDecorationPainter.
+
+ * accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
+ (AXAttributeStringSetStyle):
+ * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+ (AXAttributeStringSetStyle):
+ * rendering/RenderObject.cpp:
+ (WebCore::decorationColor): Deleted.
+ (WebCore::RenderObject::getTextDecorationColorsAndStyles): Deleted.
+ * rendering/RenderObject.h:
+ * rendering/TextDecorationPainter.cpp:
+ (WebCore::TextDecorationPainter::TextDecorationPainter):
+ (WebCore::TextDecorationPainter::paintTextDecoration):
+ (WebCore::decorationColor):
+ * rendering/TextDecorationPainter.h:
+
2016-09-15 Dave Hyatt <hy...@apple.com>
[CSS Parser] Make stylesheets parse using the new parser if the setting is enabled
Modified: trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm (205984 => 205985)
--- trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm 2016-09-15 18:04:45 UTC (rev 205984)
+++ trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm 2016-09-15 18:11:48 UTC (rev 205985)
@@ -2040,14 +2040,8 @@
AXAttributeStringSetFont(attrString, style.fontCascade().primaryFont().getCTFont(), range);
int decor = style.textDecorationsInEffect();
- if ((decor & (TextDecorationUnderline | TextDecorationLineThrough)) != 0) {
- Color underlineColor, overlineColor, linethroughColor;
- TextDecorationStyle underlineStyle, overlineStyle, linethroughStyle;
- renderer->getTextDecorationColorsAndStyles(decor, underlineColor, overlineColor, linethroughColor, underlineStyle, overlineStyle, linethroughStyle);
-
- if (decor & TextDecorationUnderline)
- AXAttributeStringSetNumber(attrString, UIAccessibilityTokenUnderline, [NSNumber numberWithBool:YES], range);
- }
+ if (decor & TextDecorationUnderline)
+ AXAttributeStringSetNumber(attrString, UIAccessibilityTokenUnderline, [NSNumber numberWithBool:YES], range);
}
static void AXAttributedStringAppendText(NSMutableAttributedString* attrString, Node* node, NSString *text)
Modified: trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm (205984 => 205985)
--- trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm 2016-09-15 18:04:45 UTC (rev 205984)
+++ trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm 2016-09-15 18:11:48 UTC (rev 205985)
@@ -68,6 +68,7 @@
#import "ScrollView.h"
#import "TextCheckerClient.h"
#import "TextCheckingHelper.h"
+#import "TextDecorationPainter.h"
#import "TextIterator.h"
#import "VisibleUnits.h"
#import "WebCoreFrameView.h"
@@ -1119,18 +1120,16 @@
if ((decor & (TextDecorationUnderline | TextDecorationLineThrough)) != 0) {
// FIXME: Should the underline style be reported here?
- Color underlineColor, overlineColor, linethroughColor;
- TextDecorationStyle underlineStyle, overlineStyle, linethroughStyle;
- renderer->getTextDecorationColorsAndStyles(decor, underlineColor, overlineColor, linethroughColor, underlineStyle, overlineStyle, linethroughStyle);
-
+ auto decorationStyles = TextDecorationPainter::stylesForRenderer(*renderer, decor);
+
if ((decor & TextDecorationUnderline) != 0) {
AXAttributeStringSetNumber(attrString, NSAccessibilityUnderlineTextAttribute, [NSNumber numberWithBool:YES], range);
- AXAttributeStringSetColor(attrString, NSAccessibilityUnderlineColorTextAttribute, nsColor(underlineColor), range);
+ AXAttributeStringSetColor(attrString, NSAccessibilityUnderlineColorTextAttribute, nsColor(decorationStyles.underlineColor), range);
}
if ((decor & TextDecorationLineThrough) != 0) {
AXAttributeStringSetNumber(attrString, NSAccessibilityStrikethroughTextAttribute, [NSNumber numberWithBool:YES], range);
- AXAttributeStringSetColor(attrString, NSAccessibilityStrikethroughColorTextAttribute, nsColor(linethroughColor), range);
+ AXAttributeStringSetColor(attrString, NSAccessibilityStrikethroughColorTextAttribute, nsColor(decorationStyles.linethroughColor), range);
}
}
Modified: trunk/Source/WebCore/rendering/RenderObject.cpp (205984 => 205985)
--- trunk/Source/WebCore/rendering/RenderObject.cpp 2016-09-15 18:04:45 UTC (rev 205984)
+++ trunk/Source/WebCore/rendering/RenderObject.cpp 2016-09-15 18:11:48 UTC (rev 205985)
@@ -36,7 +36,6 @@
#include "FrameView.h"
#include "GeometryUtilities.h"
#include "GraphicsContext.h"
-#include "HTMLAnchorElement.h"
#include "HTMLElement.h"
#include "HTMLImageElement.h"
#include "HTMLNames.h"
@@ -1643,79 +1642,6 @@
return style().computedLineHeight();
}
-static Color decorationColor(const RenderStyle* style)
-{
- Color result;
- // Check for text decoration color first.
- result = style->visitedDependentColor(CSSPropertyWebkitTextDecorationColor);
- if (result.isValid())
- return result;
- if (style->textStrokeWidth() > 0) {
- // Prefer stroke color if possible but not if it's fully transparent.
- result = style->visitedDependentColor(CSSPropertyWebkitTextStrokeColor);
- if (result.alpha())
- return result;
- }
-
- result = style->visitedDependentColor(CSSPropertyWebkitTextFillColor);
- return result;
-}
-
-void RenderObject::getTextDecorationColorsAndStyles(int decorations, Color& underlineColor, Color& overlineColor, Color& linethroughColor,
- TextDecorationStyle& underlineStyle, TextDecorationStyle& overlineStyle, TextDecorationStyle& linethroughStyle, bool firstlineStyle) const
-{
- const RenderObject* current = this;
- const RenderStyle* styleToUse = nullptr;
- TextDecoration currDecs = TextDecorationNone;
- Color resultColor;
- do {
- styleToUse = firstlineStyle ? ¤t->firstLineStyle() : ¤t->style();
- currDecs = styleToUse->textDecoration();
- resultColor = decorationColor(styleToUse);
- // Parameter 'decorations' is cast as an int to enable the bitwise operations below.
- if (currDecs) {
- if (currDecs & TextDecorationUnderline) {
- decorations &= ~TextDecorationUnderline;
- underlineColor = resultColor;
- underlineStyle = styleToUse->textDecorationStyle();
- }
- if (currDecs & TextDecorationOverline) {
- decorations &= ~TextDecorationOverline;
- overlineColor = resultColor;
- overlineStyle = styleToUse->textDecorationStyle();
- }
- if (currDecs & TextDecorationLineThrough) {
- decorations &= ~TextDecorationLineThrough;
- linethroughColor = resultColor;
- linethroughStyle = styleToUse->textDecorationStyle();
- }
- }
- if (current->isRubyText())
- return;
- current = current->parent();
- if (current && current->isAnonymousBlock() && downcast<RenderBlock>(*current).continuation())
- current = downcast<RenderBlock>(*current).continuation();
- } while (current && decorations && (!current->node() || (!is<HTMLAnchorElement>(*current->node()) && !current->node()->hasTagName(fontTag))));
-
- // If we bailed out, use the element we bailed out at (typically a <font> or <a> element).
- if (decorations && current) {
- styleToUse = firstlineStyle ? ¤t->firstLineStyle() : ¤t->style();
- resultColor = decorationColor(styleToUse);
- if (decorations & TextDecorationUnderline) {
- underlineColor = resultColor;
- underlineStyle = styleToUse->textDecorationStyle();
- }
- if (decorations & TextDecorationOverline) {
- overlineColor = resultColor;
- overlineStyle = styleToUse->textDecorationStyle();
- }
- if (decorations & TextDecorationLineThrough) {
- linethroughColor = resultColor;
- linethroughStyle = styleToUse->textDecorationStyle();
- }
- }
-}
-
#if ENABLE(DASHBOARD_SUPPORT)
void RenderObject::addAnnotatedRegions(Vector<AnnotatedRegionValue>& regions)
{
Modified: trunk/Source/WebCore/rendering/RenderObject.h (205984 => 205985)
--- trunk/Source/WebCore/rendering/RenderObject.h 2016-09-15 18:04:45 UTC (rev 205984)
+++ trunk/Source/WebCore/rendering/RenderObject.h 2016-09-15 18:11:48 UTC (rev 205985)
@@ -651,9 +651,6 @@
virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const;
- void getTextDecorationColorsAndStyles(int decorations, Color& underlineColor, Color& overlineColor, Color& linethroughColor,
- TextDecorationStyle& underlineStyle, TextDecorationStyle& overlineStyle, TextDecorationStyle& linethroughStyle, bool firstlineStyle = false) const;
-
// Return the RenderLayerModelObject in the container chain which is responsible for painting this object, or nullptr
// if painting is root-relative. This is the container that should be passed to the 'forRepaint'
// methods.
Modified: trunk/Source/WebCore/rendering/TextDecorationPainter.cpp (205984 => 205985)
--- trunk/Source/WebCore/rendering/TextDecorationPainter.cpp 2016-09-15 18:04:45 UTC (rev 205984)
+++ trunk/Source/WebCore/rendering/TextDecorationPainter.cpp 2016-09-15 18:11:48 UTC (rev 205985)
@@ -25,7 +25,10 @@
#include "FontCascade.h"
#include "GraphicsContext.h"
+#include "HTMLAnchorElement.h"
+#include "HTMLFontElement.h"
#include "InlineTextBoxStyle.h"
+#include "RenderBlock.h"
#include "RenderStyle.h"
#include "RenderText.h"
#include "ShadowData.h"
@@ -243,14 +246,9 @@
, m_decoration(decoration)
, m_wavyOffset(wavyOffsetFromDecoration())
, m_isPrinting(renderer.document().printing())
+ , m_styles(stylesForRenderer(renderer, m_decoration, isFirstLine))
, m_lineStyle(isFirstLine ? renderer.firstLineStyle() : renderer.style())
{
- renderer.getTextDecorationColorsAndStyles(m_decoration, m_underlineColor, m_overlineColor, m_linethroughColor, m_underlineStyle, m_overlineStyle,
- m_linethroughStyle);
- if (isFirstLine) {
- renderer.getTextDecorationColorsAndStyles(m_decoration, m_underlineColor, m_overlineColor, m_linethroughColor,
- m_underlineStyle, m_overlineStyle, m_linethroughStyle, true);
- }
}
void TextDecorationPainter::paintTextDecoration(const TextRun& textRun, const FloatPoint& textOrigin, const FloatPoint& boxOrigin)
@@ -264,10 +262,11 @@
m_context.setStrokeThickness(textDecorationThickness);
FloatPoint localOrigin = boxOrigin;
- auto paintDecoration = [&](TextDecoration decoration, TextDecorationStyle style, Color color, StrokeStyle strokeStyle,
- const FloatPoint& start, const FloatPoint& end, int offset) {
+ auto paintDecoration = [&](TextDecoration decoration, TextDecorationStyle style, Color color, const FloatPoint& start, const FloatPoint& end, int offset) {
m_context.setStrokeColor(color);
+ auto strokeStyle = textDecorationStyleToStrokeStyle(style);
+
if (style == TextDecorationStyleWavy)
strokeWavyTextDecoration(m_context, start, end, textDecorationThickness);
else if (decoration == TextDecorationUnderline || decoration == TextDecorationOverline) {
@@ -287,9 +286,9 @@
};
bool linesAreOpaque = !m_isPrinting
- && (!(m_decoration & TextDecorationUnderline) || m_underlineColor.alpha() == 255)
- && (!(m_decoration & TextDecorationOverline) || m_overlineColor.alpha() == 255)
- && (!(m_decoration & TextDecorationLineThrough) || m_linethroughColor.alpha() == 255);
+ && (!(m_decoration & TextDecorationUnderline) || m_styles.underlineColor.alpha() == 255)
+ && (!(m_decoration & TextDecorationOverline) || m_styles.overlineColor.alpha() == 255)
+ && (!(m_decoration & TextDecorationLineThrough) || m_styles.linethroughColor.alpha() == 255);
int extraOffset = 0;
bool clipping = !linesAreOpaque && m_shadow && m_shadow->next();
@@ -328,21 +327,21 @@
// These decorations should match the visual overflows computed in visualOverflowForDecorations()
if (m_decoration & TextDecorationUnderline) {
const int offset = computeUnderlineOffset(m_lineStyle.textUnderlinePosition(), m_lineStyle.fontMetrics(), m_inlineTextBox, textDecorationThickness);
- int wavyOffset = m_underlineStyle == TextDecorationStyleWavy ? m_wavyOffset : 0;
+ int wavyOffset = m_styles.underlineStyle == TextDecorationStyleWavy ? m_wavyOffset : 0;
FloatPoint start = localOrigin + FloatSize(0, offset + wavyOffset);
FloatPoint end = localOrigin + FloatSize(m_width, offset + wavyOffset);
- paintDecoration(TextDecorationUnderline, m_underlineStyle, m_underlineColor, textDecorationStyleToStrokeStyle(m_underlineStyle), start, end, offset);
+ paintDecoration(TextDecorationUnderline, m_styles.underlineStyle, m_styles.underlineColor, start, end, offset);
}
if (m_decoration & TextDecorationOverline) {
- int wavyOffset = m_overlineStyle == TextDecorationStyleWavy ? m_wavyOffset : 0;
+ int wavyOffset = m_styles.overlineStyle == TextDecorationStyleWavy ? m_wavyOffset : 0;
FloatPoint start = localOrigin - FloatSize(0, wavyOffset);
FloatPoint end = localOrigin + FloatSize(m_width, -wavyOffset);
- paintDecoration(TextDecorationOverline, m_overlineStyle, m_overlineColor, textDecorationStyleToStrokeStyle(m_overlineStyle), start, end, 0);
+ paintDecoration(TextDecorationOverline, m_styles.overlineStyle, m_styles.overlineColor, start, end, 0);
}
if (m_decoration & TextDecorationLineThrough) {
FloatPoint start = localOrigin + FloatSize(0, 2 * m_baseline / 3);
FloatPoint end = localOrigin + FloatSize(m_width, 2 * m_baseline / 3);
- paintDecoration(TextDecorationLineThrough, m_linethroughStyle, m_linethroughColor, textDecorationStyleToStrokeStyle(m_linethroughStyle), start, end, 0);
+ paintDecoration(TextDecorationLineThrough, m_styles.linethroughStyle, m_styles.linethroughColor, start, end, 0);
}
} while (shadow);
@@ -352,4 +351,78 @@
m_context.clearShadow();
}
+static Color decorationColor(const RenderStyle& style)
+{
+ // Check for text decoration color first.
+ Color result = style.visitedDependentColor(CSSPropertyWebkitTextDecorationColor);
+ if (result.isValid())
+ return result;
+ if (style.textStrokeWidth() > 0) {
+ // Prefer stroke color if possible but not if it's fully transparent.
+ result = style.visitedDependentColor(CSSPropertyWebkitTextStrokeColor);
+ if (result.alpha())
+ return result;
+ }
+
+ return style.visitedDependentColor(CSSPropertyWebkitTextFillColor);
+}
+
+static void collectStylesForRenderer(TextDecorationPainter::Styles& result, const RenderObject& renderer, unsigned requestedDecorations, bool firstLineStyle)
+{
+ unsigned remainingDecoration = requestedDecorations;
+ auto extractDecorations = [&] (const RenderStyle& style, unsigned decorations) {
+ auto color = decorationColor(style);
+ auto decorationStyle = style.textDecorationStyle();
+
+ if (decorations & TextDecorationUnderline) {
+ remainingDecoration &= ~TextDecorationUnderline;
+ result.underlineColor = color;
+ result.underlineStyle = decorationStyle;
+ }
+ if (decorations & TextDecorationOverline) {
+ remainingDecoration &= ~TextDecorationOverline;
+ result.overlineColor = color;
+ result.overlineStyle = decorationStyle;
+ }
+ if (decorations & TextDecorationLineThrough) {
+ remainingDecoration &= ~TextDecorationLineThrough;
+ result.linethroughColor = color;
+ result.linethroughStyle = decorationStyle;
+ }
+
+ };
+
+ auto* current = &renderer;
+ do {
+ auto& style = firstLineStyle ? current->firstLineStyle() : current->style();
+ extractDecorations(style, style.textDecoration());
+
+ if (current->isRubyText())
+ return;
+
+ current = current->parent();
+ if (current && current->isAnonymousBlock() && downcast<RenderBlock>(*current).continuation())
+ current = downcast<RenderBlock>(*current).continuation();
+
+ if (!remainingDecoration)
+ break;
+
+ } while (current && !is<HTMLAnchorElement>(current->node()) && !is<HTMLFontElement>(current->node()));
+
+ // If we bailed out, use the element we bailed out at (typically a <font> or <a> element).
+ if (remainingDecoration && current) {
+ auto& style = firstLineStyle ? current->firstLineStyle() : current->style();
+ extractDecorations(style, remainingDecoration);
+ }
+}
+
+auto TextDecorationPainter::stylesForRenderer(const RenderObject& renderer, unsigned requestedDecorations, bool firstLineStyle) -> Styles
+{
+ Styles result;
+ collectStylesForRenderer(result, renderer, requestedDecorations, false);
+ if (firstLineStyle)
+ collectStylesForRenderer(result, renderer, requestedDecorations, true);
+ return result;
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/rendering/TextDecorationPainter.h (205984 => 205985)
--- trunk/Source/WebCore/rendering/TextDecorationPainter.h 2016-09-15 18:04:45 UTC (rev 205984)
+++ trunk/Source/WebCore/rendering/TextDecorationPainter.h 2016-09-15 18:11:48 UTC (rev 205985)
@@ -32,6 +32,7 @@
class FontCascade;
class GraphicsContext;
class InlineTextBox;
+class RenderObject;
class RenderStyle;
class RenderText;
class ShadowData;
@@ -49,6 +50,16 @@
void addTextShadow(const ShadowData* textShadow) { m_shadow = textShadow; }
void paintTextDecoration(const TextRun&, const FloatPoint& textOrigin, const FloatPoint& boxOrigin);
+
+ struct Styles {
+ Color underlineColor;
+ Color overlineColor;
+ Color linethroughColor;
+ TextDecorationStyle underlineStyle;
+ TextDecorationStyle overlineStyle;
+ TextDecorationStyle linethroughStyle;
+ };
+ static Styles stylesForRenderer(const RenderObject&, unsigned requestedDecorations, bool firstLineStyle = false);
private:
GraphicsContext& m_context;
@@ -63,12 +74,7 @@
const InlineTextBox* m_inlineTextBox { nullptr };
const FontCascade* m_font { nullptr };
- Color m_underlineColor;
- Color m_overlineColor;
- Color m_linethroughColor;
- TextDecorationStyle m_underlineStyle;
- TextDecorationStyle m_overlineStyle;
- TextDecorationStyle m_linethroughStyle;
+ Styles m_styles;
const RenderStyle& m_lineStyle;
};