Dark Mode: document markers are difficult to see
authorgraouts@webkit.org <graouts@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Jul 2018 20:34:24 +0000 (20:34 +0000)
committergraouts@webkit.org <graouts@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Jul 2018 20:34:24 +0000 (20:34 +0000)
https://bugs.webkit.org/show_bug.cgi?id=187632
<rdar://problem/41099719>

Reviewed by Simon Fraser.

We update the way we draw the document markers for macOS and use more constrasting colors in dark mode.
Paving the way for future improvements, we move the drawLineForDocumentMarker() method from GraphicsContext
to RenderTheme and implement a first version in RenderThemeMac. The circles used for the underline are now
drawn directly with Core Graphics and we no longer use an image resource. To allow both GraphicsContext
and RenderTheme to have different versions of the drawLineForDocumentMarker() method, the DocumentMarkerLineStyle
enum is now an "enum class".

No new test due to webkit.org/b/105616, webkit.org/b/187655 was raised to track the creation of new tests
when it becomes possible again.

* platform/graphics/GraphicsContext.h:
* platform/graphics/GraphicsContextImpl.h:
* platform/graphics/cairo/CairoOperations.cpp:
(WebCore::Cairo::drawLineForDocumentMarker):
* platform/graphics/cairo/CairoOperations.h:
* platform/graphics/cairo/GraphicsContextImplCairo.cpp:
(WebCore::GraphicsContextImplCairo::drawLineForDocumentMarker):
* platform/graphics/cairo/GraphicsContextImplCairo.h:
* platform/graphics/cocoa/GraphicsContextCocoa.mm:
(WebCore::GraphicsContext::drawLineForDocumentMarker):
* platform/graphics/displaylists/DisplayListItems.h:
(WebCore::DisplayList::DrawLineForDocumentMarker::create):
(WebCore::DisplayList::DrawLineForDocumentMarker::DrawLineForDocumentMarker):
* platform/graphics/displaylists/DisplayListRecorder.cpp:
(WebCore::DisplayList::Recorder::drawLineForDocumentMarker):
* platform/graphics/displaylists/DisplayListRecorder.h:
* platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.cpp:
(Nicosia::CairoOperationRecorder::drawLineForDocumentMarker):
* platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.h:
* platform/graphics/win/GraphicsContextCGWin.cpp:
(WebCore::GraphicsContext::drawLineForDocumentMarker):
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::paintPlatformDocumentMarker): Call drawLineForDocumentMarker() on the RenderTheme on
macOS and on GraphicsContext in all other cases.
* rendering/RenderTheme.cpp:
(WebCore::RenderTheme::drawLineForDocumentMarker):
* rendering/RenderTheme.h:
* rendering/RenderThemeMac.h:
* rendering/RenderThemeMac.mm:
(WebCore::colorForStyle): Provide different colors for light and dark modes.
(WebCore::RenderThemeMac::drawLineForDocumentMarker): A new macOS-specific version of drawLineForDocumentMarker()
where we paint circles using Core Graphics directly.

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

19 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/GraphicsContext.h
Source/WebCore/platform/graphics/GraphicsContextImpl.h
Source/WebCore/platform/graphics/cairo/CairoOperations.cpp
Source/WebCore/platform/graphics/cairo/CairoOperations.h
Source/WebCore/platform/graphics/cairo/GraphicsContextImplCairo.cpp
Source/WebCore/platform/graphics/cairo/GraphicsContextImplCairo.h
Source/WebCore/platform/graphics/cocoa/GraphicsContextCocoa.mm
Source/WebCore/platform/graphics/displaylists/DisplayListItems.h
Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp
Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h
Source/WebCore/platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.cpp
Source/WebCore/platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.h
Source/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
Source/WebCore/rendering/InlineTextBox.cpp
Source/WebCore/rendering/RenderTheme.cpp
Source/WebCore/rendering/RenderTheme.h
Source/WebCore/rendering/RenderThemeMac.h
Source/WebCore/rendering/RenderThemeMac.mm

index 4a4d680..51d0d8a 100644 (file)
@@ -1,3 +1,54 @@
+2018-07-13  Antoine Quint  <graouts@apple.com>
+
+        Dark Mode: document markers are difficult to see
+        https://bugs.webkit.org/show_bug.cgi?id=187632
+        <rdar://problem/41099719>
+
+        Reviewed by Simon Fraser.
+
+        We update the way we draw the document markers for macOS and use more constrasting colors in dark mode.
+        Paving the way for future improvements, we move the drawLineForDocumentMarker() method from GraphicsContext
+        to RenderTheme and implement a first version in RenderThemeMac. The circles used for the underline are now
+        drawn directly with Core Graphics and we no longer use an image resource. To allow both GraphicsContext
+        and RenderTheme to have different versions of the drawLineForDocumentMarker() method, the DocumentMarkerLineStyle
+        enum is now an "enum class".
+
+        No new test due to webkit.org/b/105616, webkit.org/b/187655 was raised to track the creation of new tests
+        when it becomes possible again.
+
+        * platform/graphics/GraphicsContext.h:
+        * platform/graphics/GraphicsContextImpl.h:
+        * platform/graphics/cairo/CairoOperations.cpp:
+        (WebCore::Cairo::drawLineForDocumentMarker):
+        * platform/graphics/cairo/CairoOperations.h:
+        * platform/graphics/cairo/GraphicsContextImplCairo.cpp:
+        (WebCore::GraphicsContextImplCairo::drawLineForDocumentMarker):
+        * platform/graphics/cairo/GraphicsContextImplCairo.h:
+        * platform/graphics/cocoa/GraphicsContextCocoa.mm:
+        (WebCore::GraphicsContext::drawLineForDocumentMarker):
+        * platform/graphics/displaylists/DisplayListItems.h:
+        (WebCore::DisplayList::DrawLineForDocumentMarker::create):
+        (WebCore::DisplayList::DrawLineForDocumentMarker::DrawLineForDocumentMarker):
+        * platform/graphics/displaylists/DisplayListRecorder.cpp:
+        (WebCore::DisplayList::Recorder::drawLineForDocumentMarker):
+        * platform/graphics/displaylists/DisplayListRecorder.h:
+        * platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.cpp:
+        (Nicosia::CairoOperationRecorder::drawLineForDocumentMarker):
+        * platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.h:
+        * platform/graphics/win/GraphicsContextCGWin.cpp:
+        (WebCore::GraphicsContext::drawLineForDocumentMarker):
+        * rendering/InlineTextBox.cpp:
+        (WebCore::InlineTextBox::paintPlatformDocumentMarker): Call drawLineForDocumentMarker() on the RenderTheme on
+        macOS and on GraphicsContext in all other cases.
+        * rendering/RenderTheme.cpp:
+        (WebCore::RenderTheme::drawLineForDocumentMarker):
+        * rendering/RenderTheme.h:
+        * rendering/RenderThemeMac.h:
+        * rendering/RenderThemeMac.mm:
+        (WebCore::colorForStyle): Provide different colors for light and dark modes.
+        (WebCore::RenderThemeMac::drawLineForDocumentMarker): A new macOS-specific version of drawLineForDocumentMarker()
+        where we paint circles using Core Graphics directly.
+
 2018-07-13  Charlie Turner  <cturner@igalia.com>
 
         [GStreamer] Use smart pointers for GstByteReader
index d6ac81d..d385447 100644 (file)
@@ -109,6 +109,14 @@ enum StrokeStyle {
     WavyStroke,
 };
 
+enum class DocumentMarkerLineStyle : uint8_t {
+    TextCheckingDictationPhraseWithAlternatives,
+    Spelling,
+    Grammar,
+    AutocorrectionReplacement,
+    DictationAlternatives
+};
+
 namespace DisplayList {
 class Recorder;
 }
@@ -411,15 +419,6 @@ public:
     FloatRect computeUnderlineBoundsForText(const FloatPoint&, float width, bool printing);
     WEBCORE_EXPORT void drawLineForText(const FloatPoint&, float width, bool printing, bool doubleLines = false, StrokeStyle = SolidStroke);
     void drawLinesForText(const FloatPoint&, const DashArray& widths, bool printing, bool doubleLines = false, StrokeStyle = SolidStroke);
-    enum DocumentMarkerLineStyle {
-#if PLATFORM(IOS)
-        TextCheckingDictationPhraseWithAlternativesLineStyle,
-#endif
-        DocumentMarkerSpellingLineStyle,
-        DocumentMarkerGrammarLineStyle,
-        DocumentMarkerAutocorrectionReplacementLineStyle,
-        DocumentMarkerDictationAlternativesLineStyle
-    };
     static void updateDocumentMarkerResources();
     void drawLineForDocumentMarker(const FloatPoint&, float width, DocumentMarkerLineStyle);
 
index 8686d2b..6bcf768 100644 (file)
@@ -79,7 +79,7 @@ public:
     virtual void drawRect(const FloatRect&, float borderThickness) = 0;
     virtual void drawLine(const FloatPoint&, const FloatPoint&) = 0;
     virtual void drawLinesForText(const FloatPoint&, const DashArray& widths, bool printing, bool doubleLines, float strokeThickness) = 0;
-    virtual void drawLineForDocumentMarker(const FloatPoint&, float width, GraphicsContext::DocumentMarkerLineStyle) = 0;
+    virtual void drawLineForDocumentMarker(const FloatPoint&, float width, DocumentMarkerLineStyle) = 0;
     virtual void drawEllipse(const FloatRect&) = 0;
     virtual void drawPath(const Path&) = 0;
 
index b7ae4e8..c4ecd91 100644 (file)
@@ -1049,18 +1049,18 @@ void drawLinesForText(PlatformContextCairo& platformContext, const FloatPoint& p
     cairo_restore(cr);
 }
 
-void drawLineForDocumentMarker(PlatformContextCairo& platformContext, const FloatPoint& origin, float width, GraphicsContext::DocumentMarkerLineStyle style)
+void drawLineForDocumentMarker(PlatformContextCairo& platformContext, const FloatPoint& origin, float width, DocumentMarkerLineStyle style)
 {
-    if (style != GraphicsContext::DocumentMarkerSpellingLineStyle
-        && style != GraphicsContext::DocumentMarkerGrammarLineStyle)
+    if (style != DocumentMarkerLineStyle::Spelling
+        && style != DocumentMarkerLineStyle::Grammar)
         return;
 
     cairo_t* cr = platformContext.cr();
     cairo_save(cr);
 
-    if (style == GraphicsContext::DocumentMarkerSpellingLineStyle)
+    if (style == DocumentMarkerLineStyle::Spelling)
         cairo_set_source_rgb(cr, 1, 0, 0);
-    else if (style == GraphicsContext::DocumentMarkerGrammarLineStyle)
+    else if (style == DocumentMarkerLineStyle::Grammar)
         cairo_set_source_rgb(cr, 0, 1, 0);
 
     drawErrorUnderline(cr, origin.x(), origin.y(), width, cMisspellingLineThickness);
index 634cc0a..39b52a7 100644 (file)
@@ -145,7 +145,7 @@ WEBCORE_EXPORT void drawSurface(PlatformContextCairo&, cairo_surface_t*, const F
 void drawRect(PlatformContextCairo&, const FloatRect&, float, const Color&, StrokeStyle, const Color&);
 void drawLine(PlatformContextCairo&, const FloatPoint&, const FloatPoint&, StrokeStyle, const Color&, float, bool);
 void drawLinesForText(PlatformContextCairo&, const FloatPoint&, const DashArray&, bool, bool, const Color&, float);
-void drawLineForDocumentMarker(PlatformContextCairo&, const FloatPoint&, float, GraphicsContext::DocumentMarkerLineStyle);
+void drawLineForDocumentMarker(PlatformContextCairo&, const FloatPoint&, float, DocumentMarkerLineStyle);
 void drawEllipse(PlatformContextCairo&, const FloatRect&, const Color&, StrokeStyle, const Color&, float);
 
 void drawFocusRing(PlatformContextCairo&, const Path&, float, const Color&);
index c3d14c9..e06e403 100644 (file)
@@ -301,7 +301,7 @@ void GraphicsContextImplCairo::drawLinesForText(const FloatPoint& point, const D
     Cairo::drawLinesForText(m_platformContext, point, widths, printing, doubleUnderlines, state.strokeColor, state.strokeThickness);
 }
 
-void GraphicsContextImplCairo::drawLineForDocumentMarker(const FloatPoint& origin, float width, GraphicsContext::DocumentMarkerLineStyle style)
+void GraphicsContextImplCairo::drawLineForDocumentMarker(const FloatPoint& origin, float width, DocumentMarkerLineStyle style)
 {
     Cairo::drawLineForDocumentMarker(m_platformContext, origin, width, style);
 }
index 79ca12d..997cbdd 100644 (file)
@@ -80,7 +80,7 @@ public:
     void drawRect(const FloatRect&, float) override;
     void drawLine(const FloatPoint&, const FloatPoint&) override;
     void drawLinesForText(const FloatPoint&, const DashArray&, bool, bool, float) override;
-    void drawLineForDocumentMarker(const FloatPoint&, float, GraphicsContext::DocumentMarkerLineStyle) override;
+    void drawLineForDocumentMarker(const FloatPoint&, float, DocumentMarkerLineStyle) override;
     void drawEllipse(const FloatRect&) override;
     void drawPath(const Path&) override;
 
index 3fe2081..b5a9d66 100644 (file)
@@ -245,7 +245,7 @@ void GraphicsContext::drawLineForDocumentMarker(const FloatPoint& point, float w
     CGPatternRef dotPattern;
 #endif
     switch (style) {
-    case DocumentMarkerSpellingLineStyle: {
+    case DocumentMarkerLineStyle::Spelling: {
         // Constants for spelling pattern color.
         static bool usingDotForSpelling = false;
 #if !PLATFORM(IOS)
@@ -260,7 +260,7 @@ void GraphicsContext::drawLineForDocumentMarker(const FloatPoint& point, float w
         usingDot = usingDotForSpelling;
         break;
     }
-    case DocumentMarkerGrammarLineStyle: {
+    case DocumentMarkerLineStyle::Grammar: {
 #if !PLATFORM(IOS)
         // Constants for grammar pattern color.
         static bool usingDotForGrammar = false;
@@ -277,8 +277,8 @@ void GraphicsContext::drawLineForDocumentMarker(const FloatPoint& point, float w
     }
 #if PLATFORM(MAC)
     // To support correction panel.
-    case DocumentMarkerAutocorrectionReplacementLineStyle:
-    case DocumentMarkerDictationAlternativesLineStyle: {
+    case DocumentMarkerLineStyle::AutocorrectionReplacement:
+    case DocumentMarkerLineStyle::DictationAlternatives: {
         // Constants for spelling pattern color.
         static bool usingDotForSpelling = false;
         if (!correctionImage)
@@ -290,7 +290,7 @@ void GraphicsContext::drawLineForDocumentMarker(const FloatPoint& point, float w
     }
 #endif
 #if PLATFORM(IOS)
-    case TextCheckingDictationPhraseWithAlternativesLineStyle: {
+    case DocumentMarkerLineStyle::TextCheckingDictationPhraseWithAlternatives: {
         static bool usingDotForDictationPhraseWithAlternatives = false;
         static CGPatternRef dictationPhraseWithAlternativesPattern = createDotPattern(usingDotForDictationPhraseWithAlternatives, "DictationPhraseWithAlternativesDot").leakRef();
         dotPattern = dictationPhraseWithAlternativesPattern;
index 9f09910..f00ea7e 100644 (file)
@@ -830,7 +830,7 @@ private:
 
 class DrawLineForDocumentMarker : public DrawingItem {
 public:
-    static Ref<DrawLineForDocumentMarker> create(const FloatPoint& point, float width, GraphicsContext::DocumentMarkerLineStyle style)
+    static Ref<DrawLineForDocumentMarker> create(const FloatPoint& point, float width, DocumentMarkerLineStyle style)
     {
         return adoptRef(*new DrawLineForDocumentMarker(point, width, style));
     }
@@ -839,7 +839,7 @@ public:
     float width() const { return m_width; }
 
 private:
-    DrawLineForDocumentMarker(const FloatPoint& point, float width, GraphicsContext::DocumentMarkerLineStyle style)
+    DrawLineForDocumentMarker(const FloatPoint& point, float width, DocumentMarkerLineStyle style)
         : DrawingItem(ItemType::DrawLineForDocumentMarker)
         , m_point(point)
         , m_width(width)
@@ -853,7 +853,7 @@ private:
 
     FloatPoint m_point;
     float m_width;
-    GraphicsContext::DocumentMarkerLineStyle m_style;
+    DocumentMarkerLineStyle m_style;
 };
 
 class DrawEllipse : public DrawingItem {
index a17c591..ea27326 100644 (file)
@@ -236,7 +236,7 @@ void Recorder::drawLinesForText(const FloatPoint& point, const DashArray& widths
     updateItemExtent(newItem);
 }
 
-void Recorder::drawLineForDocumentMarker(const FloatPoint& point, float width, GraphicsContext::DocumentMarkerLineStyle style)
+void Recorder::drawLineForDocumentMarker(const FloatPoint& point, float width, DocumentMarkerLineStyle style)
 {
     DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawLineForDocumentMarker::create(point, width, style)));
     updateItemExtent(newItem);
index 7de7d46..c5ac709 100644 (file)
@@ -98,7 +98,7 @@ private:
     void drawRect(const FloatRect&, float borderThickness) override;
     void drawLine(const FloatPoint&, const FloatPoint&) override;
     void drawLinesForText(const FloatPoint&, const DashArray& widths, bool printing, bool doubleLines, float strokeThickness) override;
-    void drawLineForDocumentMarker(const FloatPoint&, float width, GraphicsContext::DocumentMarkerLineStyle) override;
+    void drawLineForDocumentMarker(const FloatPoint&, float width, DocumentMarkerLineStyle) override;
     void drawEllipse(const FloatRect&) override;
     void drawPath(const Path&) override;
 
index e4793ec..9a954e2 100644 (file)
@@ -652,9 +652,9 @@ void CairoOperationRecorder::drawLinesForText(const FloatPoint& point, const Das
     append(createCommand<DrawLinesForText>(point, widths, printing, doubleUnderlines, state.strokeColor, state.strokeThickness));
 }
 
-void CairoOperationRecorder::drawLineForDocumentMarker(const FloatPoint& origin, float width, GraphicsContext::DocumentMarkerLineStyle style)
+void CairoOperationRecorder::drawLineForDocumentMarker(const FloatPoint& origin, float width, DocumentMarkerLineStyle style)
 {
-    struct DrawLineForDocumentMarker final : PaintingOperation, OperationData<FloatPoint, float, GraphicsContext::DocumentMarkerLineStyle> {
+    struct DrawLineForDocumentMarker final : PaintingOperation, OperationData<FloatPoint, float, DocumentMarkerLineStyle> {
         virtual ~DrawLineForDocumentMarker() = default;
 
         void execute(PaintingOperationReplay& replayer) override
index 36ce637..dc4849e 100644 (file)
@@ -73,7 +73,7 @@ private:
     void drawRect(const WebCore::FloatRect&, float) override;
     void drawLine(const WebCore::FloatPoint&, const WebCore::FloatPoint&) override;
     void drawLinesForText(const WebCore::FloatPoint&, const DashArray&, bool, bool, float) override;
-    void drawLineForDocumentMarker(const WebCore::FloatPoint&, float, WebCore::GraphicsContext::DocumentMarkerLineStyle) override;
+    void drawLineForDocumentMarker(const WebCore::FloatPoint&, float, WebCore::DocumentMarkerLineStyle) override;
     void drawEllipse(const WebCore::FloatRect&) override;
     void drawPath(const WebCore::Path&) override;
 
index c47884d..c68e606 100644 (file)
@@ -195,7 +195,7 @@ void GraphicsContext::drawLineForDocumentMarker(const FloatPoint& point, float w
     if (paintingDisabled())
         return;
 
-    if (style != DocumentMarkerSpellingLineStyle && style != DocumentMarkerGrammarLineStyle)
+    if (style != DocumentMarkerLineStyle::Spelling && style != DocumentMarkerLineStyle::Grammar)
         return;
 
     // These are the same for misspelling or bad grammar
@@ -218,7 +218,7 @@ void GraphicsContext::drawLineForDocumentMarker(const FloatPoint& point, float w
     CGContextRef context = platformContext();
     CGContextSaveGState(context);
 
-    const Color& patternColor = style == DocumentMarkerGrammarLineStyle ? grammarPatternColor() : spellingPatternColor();
+    const Color& patternColor = style == DocumentMarkerLineStyle::Grammar ? grammarPatternColor() : spellingPatternColor();
     setCGStrokeColor(context, patternColor);
 
     wkSetPatternPhaseInUserSpace(context, point);
index f725053..83fec6f 100644 (file)
@@ -689,21 +689,21 @@ void InlineTextBox::paintPlatformDocumentMarker(GraphicsContext& context, const
     auto lineStyleForMarkedTextType = [] (MarkedText::Type type) {
         switch (type) {
         case MarkedText::SpellingError:
-            return GraphicsContext::DocumentMarkerSpellingLineStyle;
+            return DocumentMarkerLineStyle::Spelling;
         case MarkedText::GrammarError:
-            return GraphicsContext::DocumentMarkerGrammarLineStyle;
+            return DocumentMarkerLineStyle::Grammar;
         case MarkedText::Correction:
-            return GraphicsContext::DocumentMarkerAutocorrectionReplacementLineStyle;
+            return DocumentMarkerLineStyle::AutocorrectionReplacement;
         case MarkedText::DictationAlternatives:
-            return GraphicsContext::DocumentMarkerDictationAlternativesLineStyle;
+            return DocumentMarkerLineStyle::DictationAlternatives;
 #if PLATFORM(IOS)
         case MarkedText::DictationPhraseWithAlternatives:
-            // FIXME: Rename TextCheckingDictationPhraseWithAlternativesLineStyle and remove the PLATFORM(IOS)-guard.
-            return GraphicsContext::TextCheckingDictationPhraseWithAlternativesLineStyle;
+            // FIXME: Rename DocumentMarkerLineStyle::TextCheckingDictationPhraseWithAlternatives and remove the PLATFORM(IOS)-guard.
+            return DocumentMarkerLineStyle::TextCheckingDictationPhraseWithAlternatives;
 #endif
         default:
             ASSERT_NOT_REACHED();
-            return GraphicsContext::DocumentMarkerSpellingLineStyle;
+            return DocumentMarkerLineStyle::Spelling;
         }
     };
 
@@ -724,7 +724,12 @@ void InlineTextBox::paintPlatformDocumentMarker(GraphicsContext& context, const
         // In larger fonts, though, place the underline up near the baseline to prevent a big gap.
         underlineOffset = baseline + 2;
     }
+
+#if PLATFORM(MAC)
+    RenderTheme::singleton().drawLineForDocumentMarker(renderer(), context, FloatPoint(boxOrigin.x() + start, boxOrigin.y() + underlineOffset), width, lineStyleForMarkedTextType(markedText.type));
+#else
     context.drawLineForDocumentMarker(FloatPoint(boxOrigin.x() + start, boxOrigin.y() + underlineOffset), width, lineStyleForMarkedTextType(markedText.type));
+#endif
 }
 
 auto InlineTextBox::computeStyleForUnmarkedMarkedText(const PaintInfo& paintInfo) const -> MarkedTextStyle
index 54bde70..0a4113a 100644 (file)
@@ -1412,4 +1412,8 @@ Color RenderTheme::platformTapHighlightColor() const
 
 #endif
 
+void RenderTheme::drawLineForDocumentMarker(const RenderText&, GraphicsContext&, const FloatPoint&, float, DocumentMarkerLineStyle)
+{
+}
+
 } // namespace WebCore
index f5eb05d..5232d49 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "ColorHash.h"
 #include "ControlStates.h"
+#include "GraphicsContext.h"
 #include "PaintInfo.h"
 #include "PopupMenuStyle.h"
 #include "ScrollTypes.h"
@@ -252,6 +253,8 @@ public:
     virtual void paintSystemPreviewBadge(Image&, const PaintInfo&, const FloatRect&);
 #endif
 
+    virtual void drawLineForDocumentMarker(const RenderText&, GraphicsContext&, const FloatPoint& origin, float width, DocumentMarkerLineStyle);
+
 protected:
     virtual FontCascadeDescription& cachedSystemFontDescription(CSSValueID systemFontID) const;
     virtual void updateCachedSystemFontDescription(CSSValueID systemFontID, FontCascadeDescription&) const = 0;
index 3969685..8f69b7c 100644 (file)
@@ -168,6 +168,8 @@ private:
     bool paintAttachment(const RenderObject&, const PaintInfo&, const IntRect&) final;
 #endif
 
+    void drawLineForDocumentMarker(const RenderText&, GraphicsContext&, const FloatPoint& origin, float width, DocumentMarkerLineStyle) final;
+
 private:
     String fileListNameForWidth(const FileList*, const FontCascade&, int width, bool multipleFilesAllowed) const final;
 
index 26da429..806f9c9 100644 (file)
@@ -25,6 +25,7 @@
 #import "BitmapImage.h"
 #import "CSSValueKeywords.h"
 #import "CSSValueList.h"
+#import "Color.h"
 #import "ColorMac.h"
 #import "Document.h"
 #import "Element.h"
@@ -35,6 +36,7 @@
 #import "FrameSelection.h"
 #import "FrameView.h"
 #import "GeometryUtilities.h"
+#import "GraphicsContext.h"
 #import "GraphicsContextCG.h"
 #import "HTMLAttachmentElement.h"
 #import "HTMLInputElement.h"
@@ -2776,6 +2778,50 @@ bool RenderThemeMac::paintAttachment(const RenderObject& renderer, const PaintIn
 
 #endif // ENABLE(ATTACHMENT_ELEMENT)
 
+static CGColorRef colorForStyle(DocumentMarkerLineStyle style, bool useDarkMode)
+{
+    switch (style) {
+    // Red.
+    case DocumentMarkerLineStyle::Spelling:
+        return cachedCGColor(useDarkMode ? Color { 255, 140, 140, 217 } : Color { 255, 59, 48, 191 });
+    // Blue.
+    case DocumentMarkerLineStyle::DictationAlternatives:
+    case DocumentMarkerLineStyle::TextCheckingDictationPhraseWithAlternatives:
+    case DocumentMarkerLineStyle::AutocorrectionReplacement:
+        return cachedCGColor(useDarkMode ? Color { 40, 145, 255, 217 } : Color { 0, 122, 255, 191 });
+    // Green.
+    case DocumentMarkerLineStyle::Grammar:
+        return cachedCGColor(useDarkMode ? Color { 50, 215, 75, 217 } : Color { 25, 175, 50, 191 });
+    }
+}
+
+void RenderThemeMac::drawLineForDocumentMarker(const RenderText& renderer, GraphicsContext& context, const FloatPoint& origin, float width, DocumentMarkerLineStyle style)
+{
+    if (context.paintingDisabled())
+        return;
+
+    auto circleColor = colorForStyle(style, renderer.page().useSystemAppearance() && renderer.page().useDarkAppearance());
+
+    // Center the underline and ensure we only draw entires dots.
+    FloatPoint offsetPoint = origin;
+    float widthMod = fmodf(width, cMisspellingLinePatternWidth);
+    if (cMisspellingLinePatternWidth - widthMod > cMisspellingLinePatternGapWidth) {
+        float gapIncludeWidth = 0;
+        if (width > cMisspellingLinePatternWidth)
+            gapIncludeWidth = cMisspellingLinePatternGapWidth;
+        offsetPoint.move(floor((widthMod + gapIncludeWidth) / 2), 0);
+        width -= widthMod;
+    }
+
+    CGContextRef ctx = context.platformContext();
+    CGContextStateSaver stateSaver { ctx };
+    CGContextSetFillColorWithColor(ctx, circleColor);
+    for (int x = 0; x < width; x += cMisspellingLinePatternWidth)
+        CGContextAddEllipseInRect(ctx, CGRectMake(offsetPoint.x() + x, offsetPoint.y(), cMisspellingLineThickness, cMisspellingLineThickness));
+    CGContextSetCompositeOperation(ctx, kCGCompositeSover);
+    CGContextFillPath(ctx);
+}
+
 } // namespace WebCore
 
 #endif // PLATFORM(MAC)