Teach TextDecorationPainter about pseudo styles
authordbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Oct 2017 18:55:14 +0000 (18:55 +0000)
committerdbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Oct 2017 18:55:14 +0000 (18:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=177882

Reviewed by Simon Fraser.

As a step towards implementing support for CSS pseudo elements ::spelling-error and ::grammar-error
(https://bugs.webkit.org/show_bug.cgi?id=175784) teach TextDecorationPainter about pseudo styles.

* rendering/TextDecorationPainter.cpp:
(WebCore::TextDecorationPainter::TextDecorationPainter): Modified to take an optional
pseudo style (defaults to NOPSEUDO - no pseudo style).
(WebCore::collectStylesForRenderer): Modified to take a pseudo style. Note that getCachedPseudoStyle()
is only defined on RenderText and RenderElement objects (i.e. it is not a virtual function on RenderObject).
So, we must explicitly type check the renderer and cast appropriately before calling it. We may want
to consider making it virtual in the future if we find there are more call sites that would benefit
from polymorphism.
(WebCore::TextDecorationPainter::stylesForRenderer): Modified to take an optional
pseudo style (defaults to NOPSEUDO - no pseudo style).
* rendering/TextDecorationPainter.h:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@222864 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/rendering/TextDecorationPainter.cpp
Source/WebCore/rendering/TextDecorationPainter.h

index 1868525..7284ee8 100644 (file)
@@ -1,3 +1,25 @@
+2017-10-04  Daniel Bates  <dabates@apple.com>
+
+        Teach TextDecorationPainter about pseudo styles
+        https://bugs.webkit.org/show_bug.cgi?id=177882
+
+        Reviewed by Simon Fraser.
+
+        As a step towards implementing support for CSS pseudo elements ::spelling-error and ::grammar-error
+        (https://bugs.webkit.org/show_bug.cgi?id=175784) teach TextDecorationPainter about pseudo styles.
+
+        * rendering/TextDecorationPainter.cpp:
+        (WebCore::TextDecorationPainter::TextDecorationPainter): Modified to take an optional
+        pseudo style (defaults to NOPSEUDO - no pseudo style).
+        (WebCore::collectStylesForRenderer): Modified to take a pseudo style. Note that getCachedPseudoStyle()
+        is only defined on RenderText and RenderElement objects (i.e. it is not a virtual function on RenderObject).
+        So, we must explicitly type check the renderer and cast appropriately before calling it. We may want
+        to consider making it virtual in the future if we find there are more call sites that would benefit
+        from polymorphism.
+        (WebCore::TextDecorationPainter::stylesForRenderer): Modified to take an optional
+        pseudo style (defaults to NOPSEUDO - no pseudo style).
+        * rendering/TextDecorationPainter.h:
+
 2017-10-04  Antti Koivisto  <antti@apple.com>
 
         Add assert verifying all renderers get destroyed
index 3675631..23f0c3e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * (C) 1999 Lars Knoll (knoll@kde.org)
  * (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2017 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -241,12 +241,12 @@ static StrokeStyle textDecorationStyleToStrokeStyle(TextDecorationStyle decorati
     return strokeStyle;
 }
 
-TextDecorationPainter::TextDecorationPainter(GraphicsContext& context, TextDecoration decoration, const RenderText& renderer, bool isFirstLine)
+TextDecorationPainter::TextDecorationPainter(GraphicsContext& context, TextDecoration decoration, const RenderText& renderer, bool isFirstLine, PseudoId pseudoId)
     : m_context { context }
     , m_decoration { decoration }
     , m_wavyOffset { wavyOffsetFromDecoration() }
     , m_isPrinting { renderer.document().printing() }
-    , m_styles { stylesForRenderer(renderer, m_decoration, isFirstLine) }
+    , m_styles { stylesForRenderer(renderer, m_decoration, isFirstLine, pseudoId) }
     , m_lineStyle { isFirstLine ? renderer.firstLineStyle() : renderer.style() }
 {
 }
@@ -367,7 +367,7 @@ static Color decorationColor(const RenderStyle& style)
     return style.visitedDependentColor(CSSPropertyWebkitTextFillColor);
 }
 
-static void collectStylesForRenderer(TextDecorationPainter::Styles& result, const RenderObject& renderer, unsigned requestedDecorations, bool firstLineStyle)
+static void collectStylesForRenderer(TextDecorationPainter::Styles& result, const RenderObject& renderer, unsigned requestedDecorations, bool firstLineStyle, PseudoId pseudoId)
 {
     unsigned remainingDecoration = requestedDecorations;
     auto extractDecorations = [&] (const RenderStyle& style, unsigned decorations) {
@@ -392,9 +392,18 @@ static void collectStylesForRenderer(TextDecorationPainter::Styles& result, cons
 
     };
 
+    auto styleForRenderer = [&] (const RenderObject& renderer) -> const RenderStyle& {
+        if (pseudoId != NOPSEUDO && renderer.style().hasPseudoStyle(pseudoId)) {
+            if (is<RenderText>(renderer))
+                return *downcast<RenderText>(renderer).getCachedPseudoStyle(pseudoId);
+            return *downcast<RenderElement>(renderer).getCachedPseudoStyle(pseudoId);
+        }
+        return firstLineStyle ? renderer.firstLineStyle() : renderer.style();
+    };
+
     auto* current = &renderer;
     do {
-        auto& style = firstLineStyle ? current->firstLineStyle() : current->style();
+        const auto& style = styleForRenderer(*current);
         extractDecorations(style, style.textDecoration());
 
         if (current->isRubyText())
@@ -410,18 +419,16 @@ static void collectStylesForRenderer(TextDecorationPainter::Styles& result, cons
     } 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);
-    }
+    if (remainingDecoration && current)
+        extractDecorations(styleForRenderer(*current), remainingDecoration);
 }
 
-auto TextDecorationPainter::stylesForRenderer(const RenderObject& renderer, unsigned requestedDecorations, bool firstLineStyle) -> Styles
+auto TextDecorationPainter::stylesForRenderer(const RenderObject& renderer, unsigned requestedDecorations, bool firstLineStyle, PseudoId pseudoId) -> Styles
 {
     Styles result;
-    collectStylesForRenderer(result, renderer, requestedDecorations, false);
+    collectStylesForRenderer(result, renderer, requestedDecorations, false, pseudoId);
     if (firstLineStyle)
-        collectStylesForRenderer(result, renderer, requestedDecorations, true);
+        collectStylesForRenderer(result, renderer, requestedDecorations, true, pseudoId);
     return result;
 }
 
index 4483ae3..b46be3d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * (C) 1999 Lars Knoll (knoll@kde.org)
  * (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2017 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -40,7 +40,7 @@ class TextRun;
     
 class TextDecorationPainter {
 public:
-    TextDecorationPainter(GraphicsContext&, TextDecoration, const RenderText&, bool isFirstLine);
+    TextDecorationPainter(GraphicsContext&, TextDecoration, const RenderText&, bool isFirstLine, PseudoId = NOPSEUDO);
     
     void setInlineTextBox(const InlineTextBox* inlineTextBox) { m_inlineTextBox = inlineTextBox; }
     void setFont(const FontCascade& font) { m_font = &font; }
@@ -59,7 +59,7 @@ public:
         TextDecorationStyle overlineStyle;
         TextDecorationStyle linethroughStyle;
     };
-    static Styles stylesForRenderer(const RenderObject&, unsigned requestedDecorations, bool firstLineStyle = false);
+    static Styles stylesForRenderer(const RenderObject&, unsigned requestedDecorations, bool firstLineStyle = false, PseudoId = NOPSEUDO);
         
 private:
     GraphicsContext& m_context;