Source/WebCore/ChangeLog

 12018-07-12 Antoine Quint <graouts@apple.com>
 2
 3 Dark Mode: document markers are difficult to see
 4 https://bugs.webkit.org/show_bug.cgi?id=187632
 5 <rdar://problem/41099719>
 6
 7 Reviewed by NOBODY (OOPS!).
 8
 9 We update the way we draw the document markers for macOS and use more constrasting colors in dark mode.
 10 Paving the way for future improvements, we move the drawLineForDocumentMarker() method from GraphicsContext
 11 to RenderTheme and implement a first version in RenderThemeMac. The circles used for the underline are now
 12 drawn directly with Core Graphics and we no longer use an image resource. To allow both GraphicsContext
 13 and RenderTheme to have different versions of the drawLineForDocumentMarker() method, the DocumentMarkerLineStyle
 14 enum is now an "enum class".
 15
 16 * platform/graphics/GraphicsContext.h:
 17 * platform/graphics/GraphicsContextImpl.h:
 18 * platform/graphics/cairo/CairoOperations.cpp:
 19 (WebCore::Cairo::drawLineForDocumentMarker):
 20 * platform/graphics/cairo/CairoOperations.h:
 21 * platform/graphics/cairo/GraphicsContextImplCairo.cpp:
 22 (WebCore::GraphicsContextImplCairo::drawLineForDocumentMarker):
 23 * platform/graphics/cairo/GraphicsContextImplCairo.h:
 24 * platform/graphics/cocoa/GraphicsContextCocoa.mm:
 25 (WebCore::GraphicsContext::drawLineForDocumentMarker):
 26 * platform/graphics/displaylists/DisplayListItems.h:
 27 (WebCore::DisplayList::DrawLineForDocumentMarker::create):
 28 (WebCore::DisplayList::DrawLineForDocumentMarker::DrawLineForDocumentMarker):
 29 * platform/graphics/displaylists/DisplayListRecorder.cpp:
 30 (WebCore::DisplayList::Recorder::drawLineForDocumentMarker):
 31 * platform/graphics/displaylists/DisplayListRecorder.h:
 32 * platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.cpp:
 33 (Nicosia::CairoOperationRecorder::drawLineForDocumentMarker):
 34 * platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.h:
 35 * platform/graphics/win/GraphicsContextCGWin.cpp:
 36 (WebCore::GraphicsContext::drawLineForDocumentMarker):
 37 * rendering/InlineTextBox.cpp:
 38 (WebCore::InlineTextBox::paintPlatformDocumentMarker): Call drawLineForDocumentMarker() on the RenderTheme on
 39 macOS and on GraphicsContext in all other cases.
 40 * rendering/RenderTheme.cpp:
 41 (WebCore::RenderTheme::drawLineForDocumentMarker):
 42 * rendering/RenderTheme.h:
 43 * rendering/RenderThemeMac.h:
 44 * rendering/RenderThemeMac.mm:
 45 (WebCore::colorWithComponents):
 46 (WebCore::colorForStyle): Provide different colors for light and dark modes.
 47 (WebCore::RenderThemeMac::drawLineForDocumentMarker): A new macOS-specific version of drawLineForDocumentMarker()
 48 where we paint circles using Core Graphics directly.
 49
1502018-07-11 Antoine Quint <graouts@apple.com>
251
352 [Web Animations] Make WPT test at interfaces/KeyframeEffect/processing-a-keyframes-argument-001.html pass reliably

Source/WebCore/platform/graphics/GraphicsContext.h

@@enum StrokeStyle {
109109 WavyStroke,
110110};
111111
 112enum class DocumentMarkerLineStyle {
 113 TextCheckingDictationPhraseWithAlternatives,
 114 Spelling,
 115 Grammar,
 116 AutocorrectionReplacement,
 117 DictationAlternatives
 118};
 119
112120namespace DisplayList {
113121class Recorder;
114122}

@@public:
411419 FloatRect computeUnderlineBoundsForText(const FloatPoint&, float width, bool printing);
412420 WEBCORE_EXPORT void drawLineForText(const FloatPoint&, float width, bool printing, bool doubleLines = false, StrokeStyle = SolidStroke);
413421 void drawLinesForText(const FloatPoint&, const DashArray& widths, bool printing, bool doubleLines = false, StrokeStyle = SolidStroke);
414  enum DocumentMarkerLineStyle {
415 #if PLATFORM(IOS)
416  TextCheckingDictationPhraseWithAlternativesLineStyle,
417 #endif
418  DocumentMarkerSpellingLineStyle,
419  DocumentMarkerGrammarLineStyle,
420  DocumentMarkerAutocorrectionReplacementLineStyle,
421  DocumentMarkerDictationAlternativesLineStyle
422  };
423422 static void updateDocumentMarkerResources();
424423 void drawLineForDocumentMarker(const FloatPoint&, float width, DocumentMarkerLineStyle);
425424

Source/WebCore/platform/graphics/GraphicsContextImpl.h

@@public:
7979 virtual void drawRect(const FloatRect&, float borderThickness) = 0;
8080 virtual void drawLine(const FloatPoint&, const FloatPoint&) = 0;
8181 virtual void drawLinesForText(const FloatPoint&, const DashArray& widths, bool printing, bool doubleLines, float strokeThickness) = 0;
82  virtual void drawLineForDocumentMarker(const FloatPoint&, float width, GraphicsContext::DocumentMarkerLineStyle) = 0;
 82 virtual void drawLineForDocumentMarker(const FloatPoint&, float width, DocumentMarkerLineStyle) = 0;
8383 virtual void drawEllipse(const FloatRect&) = 0;
8484 virtual void drawPath(const Path&) = 0;
8585

Source/WebCore/platform/graphics/cairo/CairoOperations.cpp

@@void drawLinesForText(PlatformContextCairo& platformContext, const FloatPoint& p
10491049 cairo_restore(cr);
10501050}
10511051
1052 void drawLineForDocumentMarker(PlatformContextCairo& platformContext, const FloatPoint& origin, float width, GraphicsContext::DocumentMarkerLineStyle style)
 1052void drawLineForDocumentMarker(PlatformContextCairo& platformContext, const FloatPoint& origin, float width, DocumentMarkerLineStyle style)
10531053{
1054  if (style != GraphicsContext::DocumentMarkerSpellingLineStyle
1055  && style != GraphicsContext::DocumentMarkerGrammarLineStyle)
 1054 if (style != DocumentMarkerLineStyle::Spelling
 1055 && style != DocumentMarkerLineStyle::Grammar)
10561056 return;
10571057
10581058 cairo_t* cr = platformContext.cr();
10591059 cairo_save(cr);
10601060
1061  if (style == GraphicsContext::DocumentMarkerSpellingLineStyle)
 1061 if (style == DocumentMarkerLineStyle::Spelling)
10621062 cairo_set_source_rgb(cr, 1, 0, 0);
1063  else if (style == GraphicsContext::DocumentMarkerGrammarLineStyle)
 1063 else if (style == DocumentMarkerLineStyle::Grammar)
10641064 cairo_set_source_rgb(cr, 0, 1, 0);
10651065
10661066 drawErrorUnderline(cr, origin.x(), origin.y(), width, cMisspellingLineThickness);

Source/WebCore/platform/graphics/cairo/CairoOperations.h

@@WEBCORE_EXPORT void drawSurface(PlatformContextCairo&, cairo_surface_t*, const F
145145void drawRect(PlatformContextCairo&, const FloatRect&, float, const Color&, StrokeStyle, const Color&);
146146void drawLine(PlatformContextCairo&, const FloatPoint&, const FloatPoint&, StrokeStyle, const Color&, float, bool);
147147void drawLinesForText(PlatformContextCairo&, const FloatPoint&, const DashArray&, bool, bool, const Color&, float);
148 void drawLineForDocumentMarker(PlatformContextCairo&, const FloatPoint&, float, GraphicsContext::DocumentMarkerLineStyle);
 148void drawLineForDocumentMarker(PlatformContextCairo&, const FloatPoint&, float, DocumentMarkerLineStyle);
149149void drawEllipse(PlatformContextCairo&, const FloatRect&, const Color&, StrokeStyle, const Color&, float);
150150
151151void drawFocusRing(PlatformContextCairo&, const Path&, float, const Color&);

Source/WebCore/platform/graphics/cairo/GraphicsContextImplCairo.cpp

@@void GraphicsContextImplCairo::drawLinesForText(const FloatPoint& point, const D
301301 Cairo::drawLinesForText(m_platformContext, point, widths, printing, doubleUnderlines, state.strokeColor, state.strokeThickness);
302302}
303303
304 void GraphicsContextImplCairo::drawLineForDocumentMarker(const FloatPoint& origin, float width, GraphicsContext::DocumentMarkerLineStyle style)
 304void GraphicsContextImplCairo::drawLineForDocumentMarker(const FloatPoint& origin, float width, DocumentMarkerLineStyle style)
305305{
306306 Cairo::drawLineForDocumentMarker(m_platformContext, origin, width, style);
307307}

Source/WebCore/platform/graphics/cairo/GraphicsContextImplCairo.h

@@public:
8080 void drawRect(const FloatRect&, float) override;
8181 void drawLine(const FloatPoint&, const FloatPoint&) override;
8282 void drawLinesForText(const FloatPoint&, const DashArray&, bool, bool, float) override;
83  void drawLineForDocumentMarker(const FloatPoint&, float, GraphicsContext::DocumentMarkerLineStyle) override;
 83 void drawLineForDocumentMarker(const FloatPoint&, float, DocumentMarkerLineStyle) override;
8484 void drawEllipse(const FloatRect&) override;
8585 void drawPath(const Path&) override;
8686

Source/WebCore/platform/graphics/cocoa/GraphicsContextCocoa.mm

@@void GraphicsContext::drawLineForDocumentMarker(const FloatPoint& point, float w
245245 CGPatternRef dotPattern;
246246#endif
247247 switch (style) {
248  case DocumentMarkerSpellingLineStyle: {
 248 case DocumentMarkerLineStyle::Spelling: {
249249 // Constants for spelling pattern color.
250250 static bool usingDotForSpelling = false;
251251#if !PLATFORM(IOS)

@@void GraphicsContext::drawLineForDocumentMarker(const FloatPoint& point, float w
260260 usingDot = usingDotForSpelling;
261261 break;
262262 }
263  case DocumentMarkerGrammarLineStyle: {
 263 case DocumentMarkerLineStyle::Grammar: {
264264#if !PLATFORM(IOS)
265265 // Constants for grammar pattern color.
266266 static bool usingDotForGrammar = false;

@@void GraphicsContext::drawLineForDocumentMarker(const FloatPoint& point, float w
277277 }
278278#if PLATFORM(MAC)
279279 // To support correction panel.
280  case DocumentMarkerAutocorrectionReplacementLineStyle:
281  case DocumentMarkerDictationAlternativesLineStyle: {
 280 case DocumentMarkerLineStyle::AutocorrectionReplacement:
 281 case DocumentMarkerLineStyle::DictationAlternatives: {
282282 // Constants for spelling pattern color.
283283 static bool usingDotForSpelling = false;
284284 if (!correctionImage)

@@void GraphicsContext::drawLineForDocumentMarker(const FloatPoint& point, float w
290290 }
291291#endif
292292#if PLATFORM(IOS)
293  case TextCheckingDictationPhraseWithAlternativesLineStyle: {
 293 case DocumentMarkerLineStyle::TextCheckingDictationPhraseWithAlternatives: {
294294 static bool usingDotForDictationPhraseWithAlternatives = false;
295295 static CGPatternRef dictationPhraseWithAlternativesPattern = createDotPattern(usingDotForDictationPhraseWithAlternatives, "DictationPhraseWithAlternativesDot").leakRef();
296296 dotPattern = dictationPhraseWithAlternativesPattern;

Source/WebCore/platform/graphics/displaylists/DisplayListItems.h

@@private:
830830
831831class DrawLineForDocumentMarker : public DrawingItem {
832832public:
833  static Ref<DrawLineForDocumentMarker> create(const FloatPoint& point, float width, GraphicsContext::DocumentMarkerLineStyle style)
 833 static Ref<DrawLineForDocumentMarker> create(const FloatPoint& point, float width, DocumentMarkerLineStyle style)
834834 {
835835 return adoptRef(*new DrawLineForDocumentMarker(point, width, style));
836836 }

@@public:
839839 float width() const { return m_width; }
840840
841841private:
842  DrawLineForDocumentMarker(const FloatPoint& point, float width, GraphicsContext::DocumentMarkerLineStyle style)
 842 DrawLineForDocumentMarker(const FloatPoint& point, float width, DocumentMarkerLineStyle style)
843843 : DrawingItem(ItemType::DrawLineForDocumentMarker)
844844 , m_point(point)
845845 , m_width(width)

@@private:
853853
854854 FloatPoint m_point;
855855 float m_width;
856  GraphicsContext::DocumentMarkerLineStyle m_style;
 856 DocumentMarkerLineStyle m_style;
857857};
858858
859859class DrawEllipse : public DrawingItem {

Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp

@@void Recorder::drawLinesForText(const FloatPoint& point, const DashArray& widths
236236 updateItemExtent(newItem);
237237}
238238
239 void Recorder::drawLineForDocumentMarker(const FloatPoint& point, float width, GraphicsContext::DocumentMarkerLineStyle style)
 239void Recorder::drawLineForDocumentMarker(const FloatPoint& point, float width, DocumentMarkerLineStyle style)
240240{
241241 DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawLineForDocumentMarker::create(point, width, style)));
242242 updateItemExtent(newItem);

Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h

@@private:
9898 void drawRect(const FloatRect&, float borderThickness) override;
9999 void drawLine(const FloatPoint&, const FloatPoint&) override;
100100 void drawLinesForText(const FloatPoint&, const DashArray& widths, bool printing, bool doubleLines, float strokeThickness) override;
101  void drawLineForDocumentMarker(const FloatPoint&, float width, GraphicsContext::DocumentMarkerLineStyle) override;
 101 void drawLineForDocumentMarker(const FloatPoint&, float width, DocumentMarkerLineStyle) override;
102102 void drawEllipse(const FloatRect&) override;
103103 void drawPath(const Path&) override;
104104

Source/WebCore/platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.cpp

@@void CairoOperationRecorder::drawLinesForText(const FloatPoint& point, const Das
652652 append(createCommand<DrawLinesForText>(point, widths, printing, doubleUnderlines, state.strokeColor, state.strokeThickness));
653653}
654654
655 void CairoOperationRecorder::drawLineForDocumentMarker(const FloatPoint& origin, float width, GraphicsContext::DocumentMarkerLineStyle style)
 655void CairoOperationRecorder::drawLineForDocumentMarker(const FloatPoint& origin, float width, DocumentMarkerLineStyle style)
656656{
657  struct DrawLineForDocumentMarker final : PaintingOperation, OperationData<FloatPoint, float, GraphicsContext::DocumentMarkerLineStyle> {
 657 struct DrawLineForDocumentMarker final : PaintingOperation, OperationData<FloatPoint, float, DocumentMarkerLineStyle> {
658658 virtual ~DrawLineForDocumentMarker() = default;
659659
660660 void execute(PaintingOperationReplay& replayer) override

Source/WebCore/platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.h

@@private:
7373 void drawRect(const WebCore::FloatRect&, float) override;
7474 void drawLine(const WebCore::FloatPoint&, const WebCore::FloatPoint&) override;
7575 void drawLinesForText(const WebCore::FloatPoint&, const DashArray&, bool, bool, float) override;
76  void drawLineForDocumentMarker(const WebCore::FloatPoint&, float, WebCore::GraphicsContext::DocumentMarkerLineStyle) override;
 76 void drawLineForDocumentMarker(const WebCore::FloatPoint&, float, WebCore::DocumentMarkerLineStyle) override;
7777 void drawEllipse(const WebCore::FloatRect&) override;
7878 void drawPath(const WebCore::Path&) override;
7979

Source/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp

@@void GraphicsContext::drawLineForDocumentMarker(const FloatPoint& point, float w
195195 if (paintingDisabled())
196196 return;
197197
198  if (style != DocumentMarkerSpellingLineStyle && style != DocumentMarkerGrammarLineStyle)
 198 if (style != DocumentMarkerLineStyle::Spelling && style != DocumentMarkerLineStyle::Grammar)
199199 return;
200200
201201 // These are the same for misspelling or bad grammar

@@void GraphicsContext::drawLineForDocumentMarker(const FloatPoint& point, float w
218218 CGContextRef context = platformContext();
219219 CGContextSaveGState(context);
220220
221  const Color& patternColor = style == DocumentMarkerGrammarLineStyle ? grammarPatternColor() : spellingPatternColor();
 221 const Color& patternColor = style == DocumentMarkerLineStyle::Grammar ? grammarPatternColor() : spellingPatternColor();
222222 setCGStrokeColor(context, patternColor);
223223
224224 wkSetPatternPhaseInUserSpace(context, point);

Source/WebCore/rendering/InlineTextBox.cpp

@@void InlineTextBox::paintPlatformDocumentMarker(GraphicsContext& context, const
689689 auto lineStyleForMarkedTextType = [] (MarkedText::Type type) {
690690 switch (type) {
691691 case MarkedText::SpellingError:
692  return GraphicsContext::DocumentMarkerSpellingLineStyle;
 692 return DocumentMarkerLineStyle::Spelling;
693693 case MarkedText::GrammarError:
694  return GraphicsContext::DocumentMarkerGrammarLineStyle;
 694 return DocumentMarkerLineStyle::Grammar;
695695 case MarkedText::Correction:
696  return GraphicsContext::DocumentMarkerAutocorrectionReplacementLineStyle;
 696 return DocumentMarkerLineStyle::AutocorrectionReplacement;
697697 case MarkedText::DictationAlternatives:
698  return GraphicsContext::DocumentMarkerDictationAlternativesLineStyle;
 698 return DocumentMarkerLineStyle::DictationAlternatives;
699699#if PLATFORM(IOS)
700700 case MarkedText::DictationPhraseWithAlternatives:
701  // FIXME: Rename TextCheckingDictationPhraseWithAlternativesLineStyle and remove the PLATFORM(IOS)-guard.
702  return GraphicsContext::TextCheckingDictationPhraseWithAlternativesLineStyle;
 701 // FIXME: Rename DocumentMarkerLineStyle::TextCheckingDictationPhraseWithAlternatives and remove the PLATFORM(IOS)-guard.
 702 return GraphicsContext::DocumentMarkerLineStyle::TextCheckingDictationPhraseWithAlternatives;
703703#endif
704704 default:
705705 ASSERT_NOT_REACHED();
706  return GraphicsContext::DocumentMarkerSpellingLineStyle;
 706 return DocumentMarkerLineStyle::Spelling;
707707 }
708708 };
709709

@@void InlineTextBox::paintPlatformDocumentMarker(GraphicsContext& context, const
724724 // In larger fonts, though, place the underline up near the baseline to prevent a big gap.
725725 underlineOffset = baseline + 2;
726726 }
 727
 728#if PLATFORM(MAC)
 729 RenderTheme::singleton().drawLineForDocumentMarker(renderer(), context, FloatPoint(boxOrigin.x() + start, boxOrigin.y() + underlineOffset), width, lineStyleForMarkedTextType(markedText.type));
 730#else
727731 context.drawLineForDocumentMarker(FloatPoint(boxOrigin.x() + start, boxOrigin.y() + underlineOffset), width, lineStyleForMarkedTextType(markedText.type));
 732#endif
728733}
729734
730735auto InlineTextBox::computeStyleForUnmarkedMarkedText(const PaintInfo& paintInfo) const -> MarkedTextStyle

Source/WebCore/rendering/RenderTheme.cpp

@@Color RenderTheme::platformTapHighlightColor() const
14121412
14131413#endif
14141414
 1415void RenderTheme::drawLineForDocumentMarker(const RenderText&, GraphicsContext&, const FloatPoint&, float, DocumentMarkerLineStyle)
 1416{
 1417}
 1418
14151419} // namespace WebCore

Source/WebCore/rendering/RenderTheme.h

2222
2323#include "ColorHash.h"
2424#include "ControlStates.h"
 25#include "GraphicsContext.h"
2526#include "PaintInfo.h"
2627#include "PopupMenuStyle.h"
2728#include "ScrollTypes.h"

@@public:
252253 virtual void paintSystemPreviewBadge(Image&, const PaintInfo&, const FloatRect&);
253254#endif
254255
 256 virtual void drawLineForDocumentMarker(const RenderText&, GraphicsContext&, const FloatPoint&, float, DocumentMarkerLineStyle);
 257
255258protected:
256259 virtual FontCascadeDescription& cachedSystemFontDescription(CSSValueID systemFontID) const;
257260 virtual void updateCachedSystemFontDescription(CSSValueID systemFontID, FontCascadeDescription&) const = 0;

Source/WebCore/rendering/RenderThemeMac.h

@@private:
168168 bool paintAttachment(const RenderObject&, const PaintInfo&, const IntRect&) final;
169169#endif
170170
 171 void drawLineForDocumentMarker(const RenderText&, GraphicsContext&, const FloatPoint&, float, DocumentMarkerLineStyle) final;
 172
171173private:
172174 String fileListNameForWidth(const FileList*, const FontCascade&, int width, bool multipleFilesAllowed) const final;
173175

Source/WebCore/rendering/RenderThemeMac.mm

3535#import "FrameSelection.h"
3636#import "FrameView.h"
3737#import "GeometryUtilities.h"
 38#import "GraphicsContext.h"
3839#import "GraphicsContextCG.h"
3940#import "HTMLAttachmentElement.h"
4041#import "HTMLInputElement.h"

@@bool RenderThemeMac::paintAttachment(const RenderObject& renderer, const PaintIn
27762777
27772778#endif // ENABLE(ATTACHMENT_ELEMENT)
27782779
 2780static RetainPtr<CGColorRef> colorWithComponents(int r, int g, int b, int a)
 2781{
 2782 CGFloat components[4] = { CGFloat(r / 255.0), CGFloat(g / 255.0), CGFloat(b / 255.0), CGFloat(a / 100.0) };
 2783 return adoptCF(CGColorCreate(sRGBColorSpaceRef(), components));
 2784}
 2785
 2786static RetainPtr<CGColorRef> colorForStyle(DocumentMarkerLineStyle style, bool useDarkMode)
 2787{
 2788 switch (style) {
 2789 // Red.
 2790 case DocumentMarkerLineStyle::Spelling:
 2791 return useDarkMode ? colorWithComponents(255, 140, 140, 85) : colorWithComponents(255, 59, 48, 75);
 2792 // Blue.
 2793 case DocumentMarkerLineStyle::DictationAlternatives:
 2794 case DocumentMarkerLineStyle::TextCheckingDictationPhraseWithAlternatives:
 2795 case DocumentMarkerLineStyle::AutocorrectionReplacement:
 2796 return useDarkMode ? colorWithComponents(40, 145, 255, 85) : colorWithComponents(0, 122, 255, 75);
 2797 // Green.
 2798 case DocumentMarkerLineStyle::Grammar:
 2799 return useDarkMode ? colorWithComponents(50, 215, 75, 85) : colorWithComponents(25, 175, 50, 75);
 2800 }
 2801}
 2802
 2803void RenderThemeMac::drawLineForDocumentMarker(const RenderText& renderer, GraphicsContext& context, const FloatPoint& origin, float width, DocumentMarkerLineStyle style)
 2804{
 2805 if (context.paintingDisabled())
 2806 return;
 2807
 2808 auto patternWidth = cMisspellingLinePatternWidth;
 2809 auto patternHeight = cMisspellingLineThickness;
 2810 auto dotSize = CGSizeMake(patternHeight, patternHeight);
 2811 auto circleColor = colorForStyle(style, renderer.page().useSystemAppearance() && renderer.page().useDarkAppearance());
 2812
 2813 // Make sure to draw only complete dots allowing slightly more considering that the pattern ends with a transparent pixel.
 2814 FloatPoint offsetPoint = origin;
 2815 float widthMod = fmodf(width, patternWidth);
 2816 if (patternWidth - widthMod > cMisspellingLinePatternGapWidth) {
 2817 float gapIncludeWidth = 0;
 2818 if (width > patternWidth)
 2819 gapIncludeWidth = cMisspellingLinePatternGapWidth;
 2820 offsetPoint.move(floor((widthMod + gapIncludeWidth) / 2), 0);
 2821 width -= widthMod;
 2822 }
 2823
 2824 CGContextRef ctx = context.platformContext();
 2825 CGContextStateSaver stateSaver { ctx };
 2826 CGContextSetFillColorWithColor(ctx, circleColor.get());
 2827 for (int numberOfDots = 0; numberOfDots * patternWidth < width; ++numberOfDots)
 2828 CGContextAddEllipseInRect(ctx, CGRectMake(offsetPoint.x() + numberOfDots * patternWidth, offsetPoint.y(), dotSize.width, dotSize.height));
 2829 CGContextSetCompositeOperation(ctx, kCGCompositeSover);
 2830 CGContextFillPath(ctx);
 2831}
 2832
27792833} // namespace WebCore
27802834
27812835#endif // PLATFORM(MAC)