Title: [205985] trunk/Source/WebCore
Revision
205985
Author
an...@apple.com
Date
2016-09-15 11:11:48 -0700 (Thu, 15 Sep 2016)

Log Message

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:

Modified Paths

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 ? &current->firstLineStyle() : &current->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 ? &current->firstLineStyle() : &current->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;
 };
     
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to