Changeset 205985 in webkit


Ignore:
Timestamp:
Sep 15, 2016 11:11:48 AM (8 years ago)
Author:
Antti Koivisto
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:
Location:
trunk/Source/WebCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r205984 r205985  
     12016-09-14  Antti Koivisto  <antti@apple.com>
     2
     3        Move text decoration style computation from RenderObject to TextDecorationPainter
     4        https://bugs.webkit.org/show_bug.cgi?id=162004
     5
     6        Reviewed by Zalan Bujtas.
     7
     8        It is mostly an implementation detail of TextDecorationPainter.
     9
     10        * accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
     11        (AXAttributeStringSetStyle):
     12        * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
     13        (AXAttributeStringSetStyle):
     14        * rendering/RenderObject.cpp:
     15        (WebCore::decorationColor): Deleted.
     16        (WebCore::RenderObject::getTextDecorationColorsAndStyles): Deleted.
     17        * rendering/RenderObject.h:
     18        * rendering/TextDecorationPainter.cpp:
     19        (WebCore::TextDecorationPainter::TextDecorationPainter):
     20        (WebCore::TextDecorationPainter::paintTextDecoration):
     21        (WebCore::decorationColor):
     22        * rendering/TextDecorationPainter.h:
     23
    1242016-09-15  Dave Hyatt  <hyatt@apple.com>
    225
  • trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm

    r204938 r205985  
    20412041               
    20422042    int decor = style.textDecorationsInEffect();
    2043     if ((decor & (TextDecorationUnderline | TextDecorationLineThrough)) != 0) {
    2044         Color underlineColor, overlineColor, linethroughColor;
    2045         TextDecorationStyle underlineStyle, overlineStyle, linethroughStyle;
    2046         renderer->getTextDecorationColorsAndStyles(decor, underlineColor, overlineColor, linethroughColor, underlineStyle, overlineStyle, linethroughStyle);
    2047        
    2048         if (decor & TextDecorationUnderline)
    2049             AXAttributeStringSetNumber(attrString, UIAccessibilityTokenUnderline, [NSNumber numberWithBool:YES], range);
    2050     }
     2043    if (decor & TextDecorationUnderline)
     2044        AXAttributeStringSetNumber(attrString, UIAccessibilityTokenUnderline, [NSNumber numberWithBool:YES], range);
    20512045}
    20522046
  • trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm

    r204563 r205985  
    6969#import "TextCheckerClient.h"
    7070#import "TextCheckingHelper.h"
     71#import "TextDecorationPainter.h"
    7172#import "TextIterator.h"
    7273#import "VisibleUnits.h"
     
    11201121    if ((decor & (TextDecorationUnderline | TextDecorationLineThrough)) != 0) {
    11211122        // FIXME: Should the underline style be reported here?
    1122         Color underlineColor, overlineColor, linethroughColor;
    1123         TextDecorationStyle underlineStyle, overlineStyle, linethroughStyle;
    1124         renderer->getTextDecorationColorsAndStyles(decor, underlineColor, overlineColor, linethroughColor, underlineStyle, overlineStyle, linethroughStyle);
    1125        
     1123        auto decorationStyles = TextDecorationPainter::stylesForRenderer(*renderer, decor);
     1124
    11261125        if ((decor & TextDecorationUnderline) != 0) {
    11271126            AXAttributeStringSetNumber(attrString, NSAccessibilityUnderlineTextAttribute, [NSNumber numberWithBool:YES], range);
    1128             AXAttributeStringSetColor(attrString, NSAccessibilityUnderlineColorTextAttribute, nsColor(underlineColor), range);
     1127            AXAttributeStringSetColor(attrString, NSAccessibilityUnderlineColorTextAttribute, nsColor(decorationStyles.underlineColor), range);
    11291128        }
    11301129       
    11311130        if ((decor & TextDecorationLineThrough) != 0) {
    11321131            AXAttributeStringSetNumber(attrString, NSAccessibilityStrikethroughTextAttribute, [NSNumber numberWithBool:YES], range);
    1133             AXAttributeStringSetColor(attrString, NSAccessibilityStrikethroughColorTextAttribute, nsColor(linethroughColor), range);
     1132            AXAttributeStringSetColor(attrString, NSAccessibilityStrikethroughColorTextAttribute, nsColor(decorationStyles.linethroughColor), range);
    11341133        }
    11351134    }
  • trunk/Source/WebCore/rendering/RenderObject.cpp

    r205927 r205985  
    3737#include "GeometryUtilities.h"
    3838#include "GraphicsContext.h"
    39 #include "HTMLAnchorElement.h"
    4039#include "HTMLElement.h"
    4140#include "HTMLImageElement.h"
     
    16441643}
    16451644
    1646 static Color decorationColor(const RenderStyle* style)
    1647 {
    1648     Color result;
    1649     // Check for text decoration color first.
    1650     result = style->visitedDependentColor(CSSPropertyWebkitTextDecorationColor);
    1651     if (result.isValid())
    1652         return result;
    1653     if (style->textStrokeWidth() > 0) {
    1654         // Prefer stroke color if possible but not if it's fully transparent.
    1655         result = style->visitedDependentColor(CSSPropertyWebkitTextStrokeColor);
    1656         if (result.alpha())
    1657             return result;
    1658     }
    1659    
    1660     result = style->visitedDependentColor(CSSPropertyWebkitTextFillColor);
    1661     return result;
    1662 }
    1663 
    1664 void RenderObject::getTextDecorationColorsAndStyles(int decorations, Color& underlineColor, Color& overlineColor, Color& linethroughColor,
    1665     TextDecorationStyle& underlineStyle, TextDecorationStyle& overlineStyle, TextDecorationStyle& linethroughStyle, bool firstlineStyle) const
    1666 {
    1667     const RenderObject* current = this;
    1668     const RenderStyle* styleToUse = nullptr;
    1669     TextDecoration currDecs = TextDecorationNone;
    1670     Color resultColor;
    1671     do {
    1672         styleToUse = firstlineStyle ? &current->firstLineStyle() : &current->style();
    1673         currDecs = styleToUse->textDecoration();
    1674         resultColor = decorationColor(styleToUse);
    1675         // Parameter 'decorations' is cast as an int to enable the bitwise operations below.
    1676         if (currDecs) {
    1677             if (currDecs & TextDecorationUnderline) {
    1678                 decorations &= ~TextDecorationUnderline;
    1679                 underlineColor = resultColor;
    1680                 underlineStyle = styleToUse->textDecorationStyle();
    1681             }
    1682             if (currDecs & TextDecorationOverline) {
    1683                 decorations &= ~TextDecorationOverline;
    1684                 overlineColor = resultColor;
    1685                 overlineStyle = styleToUse->textDecorationStyle();
    1686             }
    1687             if (currDecs & TextDecorationLineThrough) {
    1688                 decorations &= ~TextDecorationLineThrough;
    1689                 linethroughColor = resultColor;
    1690                 linethroughStyle = styleToUse->textDecorationStyle();
    1691             }
    1692         }
    1693         if (current->isRubyText())
    1694             return;
    1695         current = current->parent();
    1696         if (current && current->isAnonymousBlock() && downcast<RenderBlock>(*current).continuation())
    1697             current = downcast<RenderBlock>(*current).continuation();
    1698     } while (current && decorations && (!current->node() || (!is<HTMLAnchorElement>(*current->node()) && !current->node()->hasTagName(fontTag))));
    1699 
    1700     // If we bailed out, use the element we bailed out at (typically a <font> or <a> element).
    1701     if (decorations && current) {
    1702         styleToUse = firstlineStyle ? &current->firstLineStyle() : &current->style();
    1703         resultColor = decorationColor(styleToUse);
    1704         if (decorations & TextDecorationUnderline) {
    1705             underlineColor = resultColor;
    1706             underlineStyle = styleToUse->textDecorationStyle();
    1707         }
    1708         if (decorations & TextDecorationOverline) {
    1709             overlineColor = resultColor;
    1710             overlineStyle = styleToUse->textDecorationStyle();
    1711         }
    1712         if (decorations & TextDecorationLineThrough) {
    1713             linethroughColor = resultColor;
    1714             linethroughStyle = styleToUse->textDecorationStyle();
    1715         }
    1716     }
    1717 }
    1718 
    17191645#if ENABLE(DASHBOARD_SUPPORT)
    17201646void RenderObject::addAnnotatedRegions(Vector<AnnotatedRegionValue>& regions)
  • trunk/Source/WebCore/rendering/RenderObject.h

    r205927 r205985  
    651651   
    652652    virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const;
    653 
    654     void getTextDecorationColorsAndStyles(int decorations, Color& underlineColor, Color& overlineColor, Color& linethroughColor,
    655         TextDecorationStyle& underlineStyle, TextDecorationStyle& overlineStyle, TextDecorationStyle& linethroughStyle, bool firstlineStyle = false) const;
    656653
    657654    // Return the RenderLayerModelObject in the container chain which is responsible for painting this object, or nullptr
  • trunk/Source/WebCore/rendering/TextDecorationPainter.cpp

    r201777 r205985  
    2626#include "FontCascade.h"
    2727#include "GraphicsContext.h"
     28#include "HTMLAnchorElement.h"
     29#include "HTMLFontElement.h"
    2830#include "InlineTextBoxStyle.h"
     31#include "RenderBlock.h"
    2932#include "RenderStyle.h"
    3033#include "RenderText.h"
     
    244247    , m_wavyOffset(wavyOffsetFromDecoration())
    245248    , m_isPrinting(renderer.document().printing())
     249    , m_styles(stylesForRenderer(renderer, m_decoration, isFirstLine))
    246250    , m_lineStyle(isFirstLine ? renderer.firstLineStyle() : renderer.style())
    247251{
    248     renderer.getTextDecorationColorsAndStyles(m_decoration, m_underlineColor, m_overlineColor, m_linethroughColor, m_underlineStyle, m_overlineStyle,
    249         m_linethroughStyle);
    250     if (isFirstLine) {
    251         renderer.getTextDecorationColorsAndStyles(m_decoration, m_underlineColor, m_overlineColor, m_linethroughColor,
    252             m_underlineStyle, m_overlineStyle, m_linethroughStyle, true);
    253     }
    254252}
    255253
     
    265263    FloatPoint localOrigin = boxOrigin;
    266264
    267     auto paintDecoration = [&](TextDecoration decoration, TextDecorationStyle style, Color color, StrokeStyle strokeStyle,
    268         const FloatPoint& start, const FloatPoint& end, int offset) {
     265    auto paintDecoration = [&](TextDecoration decoration, TextDecorationStyle style, Color color, const FloatPoint& start, const FloatPoint& end, int offset) {
    269266        m_context.setStrokeColor(color);
     267
     268        auto strokeStyle = textDecorationStyleToStrokeStyle(style);
    270269
    271270        if (style == TextDecorationStyleWavy)
     
    288287
    289288    bool linesAreOpaque = !m_isPrinting
    290         && (!(m_decoration & TextDecorationUnderline) || m_underlineColor.alpha() == 255)
    291         && (!(m_decoration & TextDecorationOverline) || m_overlineColor.alpha() == 255)
    292         && (!(m_decoration & TextDecorationLineThrough) || m_linethroughColor.alpha() == 255);
     289        && (!(m_decoration & TextDecorationUnderline) || m_styles.underlineColor.alpha() == 255)
     290        && (!(m_decoration & TextDecorationOverline) || m_styles.overlineColor.alpha() == 255)
     291        && (!(m_decoration & TextDecorationLineThrough) || m_styles.linethroughColor.alpha() == 255);
    293292
    294293    int extraOffset = 0;
     
    329328        if (m_decoration & TextDecorationUnderline) {
    330329            const int offset = computeUnderlineOffset(m_lineStyle.textUnderlinePosition(), m_lineStyle.fontMetrics(), m_inlineTextBox, textDecorationThickness);
    331             int wavyOffset = m_underlineStyle == TextDecorationStyleWavy ? m_wavyOffset : 0;
     330            int wavyOffset = m_styles.underlineStyle == TextDecorationStyleWavy ? m_wavyOffset : 0;
    332331            FloatPoint start = localOrigin + FloatSize(0, offset + wavyOffset);
    333332            FloatPoint end = localOrigin + FloatSize(m_width, offset + wavyOffset);
    334             paintDecoration(TextDecorationUnderline, m_underlineStyle, m_underlineColor, textDecorationStyleToStrokeStyle(m_underlineStyle), start, end, offset);
     333            paintDecoration(TextDecorationUnderline, m_styles.underlineStyle, m_styles.underlineColor, start, end, offset);
    335334        }
    336335        if (m_decoration & TextDecorationOverline) {
    337             int wavyOffset = m_overlineStyle == TextDecorationStyleWavy ? m_wavyOffset : 0;
     336            int wavyOffset = m_styles.overlineStyle == TextDecorationStyleWavy ? m_wavyOffset : 0;
    338337            FloatPoint start = localOrigin - FloatSize(0, wavyOffset);
    339338            FloatPoint end = localOrigin + FloatSize(m_width, -wavyOffset);
    340             paintDecoration(TextDecorationOverline, m_overlineStyle, m_overlineColor, textDecorationStyleToStrokeStyle(m_overlineStyle), start, end, 0);
     339            paintDecoration(TextDecorationOverline, m_styles.overlineStyle, m_styles.overlineColor, start, end, 0);
    341340        }
    342341        if (m_decoration & TextDecorationLineThrough) {
    343342            FloatPoint start = localOrigin + FloatSize(0, 2 * m_baseline / 3);
    344343            FloatPoint end = localOrigin + FloatSize(m_width, 2 * m_baseline / 3);
    345             paintDecoration(TextDecorationLineThrough, m_linethroughStyle, m_linethroughColor, textDecorationStyleToStrokeStyle(m_linethroughStyle), start, end, 0);
     344            paintDecoration(TextDecorationLineThrough, m_styles.linethroughStyle, m_styles.linethroughColor, start, end, 0);
    346345        }
    347346    } while (shadow);
     
    353352}
    354353
     354static Color decorationColor(const RenderStyle& style)
     355{
     356    // Check for text decoration color first.
     357    Color result = style.visitedDependentColor(CSSPropertyWebkitTextDecorationColor);
     358    if (result.isValid())
     359        return result;
     360    if (style.textStrokeWidth() > 0) {
     361        // Prefer stroke color if possible but not if it's fully transparent.
     362        result = style.visitedDependentColor(CSSPropertyWebkitTextStrokeColor);
     363        if (result.alpha())
     364            return result;
     365    }
     366   
     367    return style.visitedDependentColor(CSSPropertyWebkitTextFillColor);
     368}
     369
     370static void collectStylesForRenderer(TextDecorationPainter::Styles& result, const RenderObject& renderer, unsigned requestedDecorations, bool firstLineStyle)
     371{
     372    unsigned remainingDecoration = requestedDecorations;
     373    auto extractDecorations = [&] (const RenderStyle& style, unsigned decorations) {
     374        auto color = decorationColor(style);
     375        auto decorationStyle = style.textDecorationStyle();
     376
     377        if (decorations & TextDecorationUnderline) {
     378            remainingDecoration &= ~TextDecorationUnderline;
     379            result.underlineColor = color;
     380            result.underlineStyle = decorationStyle;
     381        }
     382        if (decorations & TextDecorationOverline) {
     383            remainingDecoration &= ~TextDecorationOverline;
     384            result.overlineColor = color;
     385            result.overlineStyle = decorationStyle;
     386        }
     387        if (decorations & TextDecorationLineThrough) {
     388            remainingDecoration &= ~TextDecorationLineThrough;
     389            result.linethroughColor = color;
     390            result.linethroughStyle = decorationStyle;
     391        }
     392
     393    };
     394
     395    auto* current = &renderer;
     396    do {
     397        auto& style = firstLineStyle ? current->firstLineStyle() : current->style();
     398        extractDecorations(style, style.textDecoration());
     399
     400        if (current->isRubyText())
     401            return;
     402
     403        current = current->parent();
     404        if (current && current->isAnonymousBlock() && downcast<RenderBlock>(*current).continuation())
     405            current = downcast<RenderBlock>(*current).continuation();
     406
     407        if (!remainingDecoration)
     408            break;
     409
     410    } while (current && !is<HTMLAnchorElement>(current->node()) && !is<HTMLFontElement>(current->node()));
     411
     412    // If we bailed out, use the element we bailed out at (typically a <font> or <a> element).
     413    if (remainingDecoration     && current) {
     414        auto& style = firstLineStyle ? current->firstLineStyle() : current->style();
     415        extractDecorations(style, remainingDecoration);
     416    }
     417}
     418
     419auto TextDecorationPainter::stylesForRenderer(const RenderObject& renderer, unsigned requestedDecorations, bool firstLineStyle) -> Styles
     420{
     421    Styles result;
     422    collectStylesForRenderer(result, renderer, requestedDecorations, false);
     423    if (firstLineStyle)
     424        collectStylesForRenderer(result, renderer, requestedDecorations, true);
     425    return result;
     426}
     427
    355428} // namespace WebCore
  • trunk/Source/WebCore/rendering/TextDecorationPainter.h

    r205519 r205985  
    3333class GraphicsContext;
    3434class InlineTextBox;
     35class RenderObject;
    3536class RenderStyle;
    3637class RenderText;
     
    5051
    5152    void paintTextDecoration(const TextRun&, const FloatPoint& textOrigin, const FloatPoint& boxOrigin);
     53
     54    struct Styles {
     55        Color underlineColor;
     56        Color overlineColor;
     57        Color linethroughColor;
     58        TextDecorationStyle underlineStyle;
     59        TextDecorationStyle overlineStyle;
     60        TextDecorationStyle linethroughStyle;
     61    };
     62    static Styles stylesForRenderer(const RenderObject&, unsigned requestedDecorations, bool firstLineStyle = false);
    5263       
    5364private:
     
    6475    const FontCascade* m_font { nullptr };
    6576   
    66     Color m_underlineColor;
    67     Color m_overlineColor;
    68     Color m_linethroughColor;
    69     TextDecorationStyle m_underlineStyle;
    70     TextDecorationStyle m_overlineStyle;
    71     TextDecorationStyle m_linethroughStyle;
     77    Styles m_styles;
    7278    const RenderStyle& m_lineStyle;
    7379};
Note: See TracChangeset for help on using the changeset viewer.