Clean up text decoration drawing code
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 Nov 2018 04:32:44 +0000 (04:32 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 Nov 2018 04:32:44 +0000 (04:32 +0000)
https://bugs.webkit.org/show_bug.cgi?id=191245

Reviewed by Zalan Bujtas.

This is some general clean up of the text decorations code. There is no behavior change.

This patch modifies GraphicsContext::drawLineForText() & friends to accept a FloatRect instead of a FloatPoint + float width.
This is helpful because it allows for easier bounding box calculations.
This patch also removes some redundant computations that the skip:ink codepath was performing.
This patch also refactors the wavy decoration parameters to not use out params.

No new tests because there is no behavior change.

* platform/graphics/GraphicsContext.cpp:
(WebCore::GraphicsContext::computeUnderlineBoundsForText):
(WebCore::GraphicsContext::computeLineBoundsAndAntialiasingModeForText):
* platform/graphics/GraphicsContext.h:
* platform/graphics/GraphicsContextImpl.h:
* platform/graphics/cg/GraphicsContextCG.cpp:
(WebCore::GraphicsContext::drawLineForText):
(WebCore::GraphicsContext::drawLinesForText):
* platform/graphics/displaylists/DisplayListItems.cpp:
(WebCore::DisplayList::DrawLinesForText::apply const):
(WebCore::DisplayList::DrawLinesForText::localBounds const):
(WebCore::DisplayList::operator<<):
* platform/graphics/displaylists/DisplayListItems.h:
(WebCore::DisplayList::DrawLinesForText::create):
(WebCore::DisplayList::DrawLinesForText::thickness const):
(WebCore::DisplayList::DrawLinesForText::DrawLinesForText):
* platform/graphics/displaylists/DisplayListRecorder.cpp:
(WebCore::DisplayList::Recorder::drawLinesForText):
* platform/graphics/displaylists/DisplayListRecorder.h:
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::paintMarkedTextDecoration):
(WebCore::InlineTextBox::paintCompositionUnderline const):
* rendering/SimpleLineLayoutFunctions.cpp:
(WebCore::SimpleLineLayout::paintFlow):
* rendering/TextDecorationPainter.cpp:
(WebCore::strokeWavyTextDecoration):
(WebCore::translateIntersectionPointsToSkipInkBoundaries):
(WebCore::TextDecorationPainter::TextDecorationPainter):
(WebCore::TextDecorationPainter::paintTextDecoration):
(WebCore::drawSkipInkUnderline): Deleted.
* rendering/TextDecorationPainter.h:
(WebCore::TextDecorationPainter::setInlineTextBox):
(WebCore::TextDecorationPainter::setWidth):
(WebCore::TextDecorationPainter::setFont): Deleted.
(WebCore::TextDecorationPainter::setBaseline): Deleted.
* style/InlineTextBoxStyle.cpp:
(WebCore::getWavyStrokeParameters):
(WebCore::visualOverflowForDecorations):
* style/InlineTextBoxStyle.h:

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

23 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/GraphicsContext.cpp
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/GraphicsContextCairo.cpp
Source/WebCore/platform/graphics/cairo/GraphicsContextImplCairo.cpp
Source/WebCore/platform/graphics/cairo/GraphicsContextImplCairo.h
Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp
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/win/WebCoreTextRenderer.cpp
Source/WebCore/rendering/InlineTextBox.cpp
Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp
Source/WebCore/rendering/TextDecorationPainter.cpp
Source/WebCore/rendering/TextDecorationPainter.h
Source/WebCore/style/InlineTextBoxStyle.cpp
Source/WebCore/style/InlineTextBoxStyle.h

index 5af7dcd..6296243 100644 (file)
@@ -1,5 +1,61 @@
 2018-11-05  Myles C. Maxfield  <mmaxfield@apple.com>
 
+        Clean up text decoration drawing code
+        https://bugs.webkit.org/show_bug.cgi?id=191245
+
+        Reviewed by Zalan Bujtas.
+
+        This is some general clean up of the text decorations code. There is no behavior change.
+
+        This patch modifies GraphicsContext::drawLineForText() & friends to accept a FloatRect instead of a FloatPoint + float width.
+        This is helpful because it allows for easier bounding box calculations.
+        This patch also removes some redundant computations that the skip:ink codepath was performing.
+        This patch also refactors the wavy decoration parameters to not use out params.
+
+        No new tests because there is no behavior change.
+
+        * platform/graphics/GraphicsContext.cpp:
+        (WebCore::GraphicsContext::computeUnderlineBoundsForText):
+        (WebCore::GraphicsContext::computeLineBoundsAndAntialiasingModeForText):
+        * platform/graphics/GraphicsContext.h:
+        * platform/graphics/GraphicsContextImpl.h:
+        * platform/graphics/cg/GraphicsContextCG.cpp:
+        (WebCore::GraphicsContext::drawLineForText):
+        (WebCore::GraphicsContext::drawLinesForText):
+        * platform/graphics/displaylists/DisplayListItems.cpp:
+        (WebCore::DisplayList::DrawLinesForText::apply const):
+        (WebCore::DisplayList::DrawLinesForText::localBounds const):
+        (WebCore::DisplayList::operator<<):
+        * platform/graphics/displaylists/DisplayListItems.h:
+        (WebCore::DisplayList::DrawLinesForText::create):
+        (WebCore::DisplayList::DrawLinesForText::thickness const):
+        (WebCore::DisplayList::DrawLinesForText::DrawLinesForText):
+        * platform/graphics/displaylists/DisplayListRecorder.cpp:
+        (WebCore::DisplayList::Recorder::drawLinesForText):
+        * platform/graphics/displaylists/DisplayListRecorder.h:
+        * rendering/InlineTextBox.cpp:
+        (WebCore::InlineTextBox::paintMarkedTextDecoration):
+        (WebCore::InlineTextBox::paintCompositionUnderline const):
+        * rendering/SimpleLineLayoutFunctions.cpp:
+        (WebCore::SimpleLineLayout::paintFlow):
+        * rendering/TextDecorationPainter.cpp:
+        (WebCore::strokeWavyTextDecoration):
+        (WebCore::translateIntersectionPointsToSkipInkBoundaries):
+        (WebCore::TextDecorationPainter::TextDecorationPainter):
+        (WebCore::TextDecorationPainter::paintTextDecoration):
+        (WebCore::drawSkipInkUnderline): Deleted.
+        * rendering/TextDecorationPainter.h:
+        (WebCore::TextDecorationPainter::setInlineTextBox):
+        (WebCore::TextDecorationPainter::setWidth):
+        (WebCore::TextDecorationPainter::setFont): Deleted.
+        (WebCore::TextDecorationPainter::setBaseline): Deleted.
+        * style/InlineTextBoxStyle.cpp:
+        (WebCore::getWavyStrokeParameters):
+        (WebCore::visualOverflowForDecorations):
+        * style/InlineTextBoxStyle.h:
+
+2018-11-05  Myles C. Maxfield  <mmaxfield@apple.com>
+
         Fix the Windows build after r237835
         https://bugs.webkit.org/show_bug.cgi?id=191242
 
index 5d66fb8..0b5769c 100644 (file)
@@ -1083,18 +1083,18 @@ void GraphicsContext::platformStrokeEllipse(const FloatRect& ellipse)
 }
 #endif
 
-FloatRect GraphicsContext::computeUnderlineBoundsForText(const FloatPoint& point, float width, bool printing)
+FloatRect GraphicsContext::computeUnderlineBoundsForText(const FloatRect& rect, bool printing)
 {
     Color dummyColor;
-    return computeLineBoundsAndAntialiasingModeForText(point, width, printing, dummyColor);
+    return computeLineBoundsAndAntialiasingModeForText(rect, printing, dummyColor);
 }
 
-FloatRect GraphicsContext::computeLineBoundsAndAntialiasingModeForText(const FloatPoint& point, float width, bool printing, Color& color)
+FloatRect GraphicsContext::computeLineBoundsAndAntialiasingModeForText(const FloatRect& rect, bool printing, Color& color)
 {
-    FloatPoint origin = point;
-    float thickness = std::max(strokeThickness(), 0.5f);
+    FloatPoint origin = rect.location();
+    float thickness = std::max(rect.height(), 0.5f);
     if (printing)
-        return FloatRect(origin, FloatSize(width, thickness));
+        return FloatRect(origin, FloatSize(rect.width(), thickness));
 
     AffineTransform transform = getCTM(GraphicsContext::DefinitelyIncludeDeviceScale);
     // Just compute scale in x dimension, assuming x and y scales are equal.
@@ -1108,12 +1108,12 @@ FloatRect GraphicsContext::computeLineBoundsAndAntialiasingModeForText(const Flo
         color = color.colorWithAlphaMultipliedBy(shade);
     }
 
-    FloatPoint devicePoint = transform.mapPoint(point);
+    FloatPoint devicePoint = transform.mapPoint(rect.location());
     // Visual overflow might occur here due to integral roundf/ceilf. visualOverflowForDecorations adjusts the overflow value for underline decoration.
     FloatPoint deviceOrigin = FloatPoint(roundf(devicePoint.x()), ceilf(devicePoint.y()));
     if (auto inverse = transform.inverse())
         origin = inverse.value().mapPoint(deviceOrigin);
-    return FloatRect(origin, FloatSize(width, thickness));
+    return FloatRect(origin, FloatSize(rect.width(), thickness));
 }
 
 void GraphicsContext::applyState(const GraphicsContextState& state)
index 8619053..d2b39b3 100644 (file)
@@ -418,9 +418,9 @@ public:
     };
     FloatRect roundToDevicePixels(const FloatRect&, RoundingMode = RoundAllSides);
 
-    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);
+    FloatRect computeUnderlineBoundsForText(const FloatRect&, bool printing);
+    WEBCORE_EXPORT void drawLineForText(const FloatRect&, bool printing, bool doubleLines = false, StrokeStyle = SolidStroke);
+    void drawLinesForText(const FloatPoint&, float thickness, const DashArray& widths, bool printing, bool doubleLines = false, StrokeStyle = SolidStroke);
     void drawDotsForDocumentMarker(const FloatRect&, DocumentMarkerLineStyle);
 
     WEBCORE_EXPORT void beginTransparencyLayer(float opacity);
@@ -626,7 +626,7 @@ private:
 
     void platformFillRoundedRect(const FloatRoundedRect&, const Color&);
 
-    FloatRect computeLineBoundsAndAntialiasingModeForText(const FloatPoint&, float width, bool printing, Color&);
+    FloatRect computeLineBoundsAndAntialiasingModeForText(const FloatRect&, bool printing, Color&);
 
     float dashedLineCornerWidthForStrokeWidth(float) const;
     float dashedLinePatternWidthForStrokeWidth(float) const;
index d48b924..5036892 100644 (file)
@@ -78,7 +78,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 drawLinesForText(const FloatPoint&, float thickness, const DashArray& widths, bool printing, bool doubleLines) = 0;
     virtual void drawDotsForDocumentMarker(const FloatRect&, DocumentMarkerLineStyle) = 0;
     virtual void drawEllipse(const FloatRect&) = 0;
     virtual void drawPath(const Path&) = 0;
index f65ee25..3d9c48d 100644 (file)
@@ -1023,7 +1023,7 @@ void drawLine(PlatformContextCairo& platformContext, const FloatPoint& point1, c
         cairo_set_antialias(cairoContext, CAIRO_ANTIALIAS_DEFAULT);
 }
 
-void drawLinesForText(PlatformContextCairo& platformContext, const FloatPoint& point, const DashArray& widths, bool printing, bool doubleUnderlines, const Color& color, float strokeThickness)
+void drawLinesForText(PlatformContextCairo& platformContext, const FloatPoint& point, float strokeThickness, const DashArray& widths, bool printing, bool doubleUnderlines, const Color& color)
 {
     Color modifiedColor = color;
     FloatRect bounds = computeLineBoundsAndAntialiasingModeForText(platformContext, point, widths.last(), printing, modifiedColor, strokeThickness);
index cb78dfb..085e61a 100644 (file)
@@ -144,7 +144,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 drawLinesForText(PlatformContextCairo&, const FloatPoint&, float thickness, const DashArray&, bool, bool, const Color&);
 void drawDotsForDocumentMarker(PlatformContextCairo&, const FloatRect&, DocumentMarkerLineStyle);
 void drawEllipse(PlatformContextCairo&, const FloatRect&, const Color&, StrokeStyle, const Color&, float);
 
index 2f8b925..c34a99b 100644 (file)
@@ -315,12 +315,12 @@ void GraphicsContext::drawFocusRing(const Vector<FloatRect>& rects, float width,
     Cairo::drawFocusRing(*platformContext(), rects, width, color);
 }
 
-void GraphicsContext::drawLineForText(const FloatPoint& origin, float width, bool printing, bool doubleUnderlines, StrokeStyle)
+void GraphicsContext::drawLineForText(const FloatRect& rect, bool printing, bool doubleUnderlines, StrokeStyle)
 {
-    drawLinesForText(origin, DashArray { width, 0 }, printing, doubleUnderlines);
+    drawLinesForText(rect.location(), rect.height(), DashArray { rect.width(), 0 }, printing, doubleUnderlines);
 }
 
-void GraphicsContext::drawLinesForText(const FloatPoint& point, const DashArray& widths, bool printing, bool doubleUnderlines, StrokeStyle)
+void GraphicsContext::drawLinesForText(const FloatPoint& point, float thickness, const DashArray& widths, bool printing, bool doubleUnderlines, StrokeStyle)
 {
     if (paintingDisabled())
         return;
@@ -329,12 +329,12 @@ void GraphicsContext::drawLinesForText(const FloatPoint& point, const DashArray&
         return;
 
     if (m_impl) {
-        m_impl->drawLinesForText(point, widths, printing, doubleUnderlines, strokeThickness());
+        m_impl->drawLinesForText(point, thickness, widths, printing, doubleUnderlines);
         return;
     }
 
     ASSERT(hasPlatformContext());
-    Cairo::drawLinesForText(*platformContext(), point, widths, printing, doubleUnderlines, m_state.strokeColor, m_state.strokeThickness);
+    Cairo::drawLinesForText(*platformContext(), point, thickness, widths, printing, doubleUnderlines, m_state.strokeColor);
 }
 
 void GraphicsContext::drawDotsForDocumentMarker(const FloatRect& rect, DocumentMarkerLineStyle style)
index c77dfb7..6c20067 100644 (file)
@@ -296,11 +296,10 @@ void GraphicsContextImplCairo::drawLine(const FloatPoint& point1, const FloatPoi
     Cairo::drawLine(m_platformContext, point1, point2, state.strokeStyle, state.strokeColor, state.strokeThickness, state.shouldAntialias);
 }
 
-void GraphicsContextImplCairo::drawLinesForText(const FloatPoint& point, const DashArray& widths, bool printing, bool doubleUnderlines, float strokeThickness)
+void GraphicsContextImplCairo::drawLinesForText(const FloatPoint& point, float thickness, const DashArray& widths, bool printing, bool doubleUnderlines)
 {
-    UNUSED_PARAM(strokeThickness);
     auto& state = graphicsContext().state();
-    Cairo::drawLinesForText(m_platformContext, point, widths, printing, doubleUnderlines, state.strokeColor, state.strokeThickness);
+    Cairo::drawLinesForText(m_platformContext, point, thickness, widths, printing, doubleUnderlines, state.strokeColor);
 }
 
 void GraphicsContextImplCairo::drawDotsForDocumentMarker(const FloatRect& rect, DocumentMarkerLineStyle style)
index 2d74285..f1b02d3 100644 (file)
@@ -79,7 +79,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 drawLinesForText(const FloatPoint&, float thickness, const DashArray&, bool, bool) override;
     void drawDotsForDocumentMarker(const FloatRect&, DocumentMarkerLineStyle) override;
     void drawEllipse(const FloatRect&) override;
     void drawPath(const Path&) override;
index fe112dd..3749021 100644 (file)
@@ -1570,15 +1570,15 @@ FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect, RoundingMo
     return FloatRect(roundedOrigin, roundedLowerRight - roundedOrigin);
 }
 
-void GraphicsContext::drawLineForText(const FloatPoint& point, float width, bool printing, bool doubleLines, StrokeStyle strokeStyle)
+void GraphicsContext::drawLineForText(const FloatRect& rect, bool printing, bool doubleLines, StrokeStyle strokeStyle)
 {
     DashArray widths;
-    widths.append(width);
+    widths.append(rect.width());
     widths.append(0);
-    drawLinesForText(point, widths, printing, doubleLines, strokeStyle);
+    drawLinesForText(rect.location(), rect.height(), widths, printing, doubleLines, strokeStyle);
 }
 
-void GraphicsContext::drawLinesForText(const FloatPoint& point, const DashArray& widths, bool printing, bool doubleLines, StrokeStyle strokeStyle)
+void GraphicsContext::drawLinesForText(const FloatPoint& point, float thickness, const DashArray& widths, bool printing, bool doubleLines, StrokeStyle strokeStyle)
 {
     if (paintingDisabled())
         return;
@@ -1587,13 +1587,13 @@ void GraphicsContext::drawLinesForText(const FloatPoint& point, const DashArray&
         return;
 
     if (m_impl) {
-        m_impl->drawLinesForText(point, widths, printing, doubleLines, strokeThickness());
+        m_impl->drawLinesForText(point, thickness, widths, printing, doubleLines);
         return;
     }
 
     Color localStrokeColor(strokeColor());
 
-    FloatRect bounds = computeLineBoundsAndAntialiasingModeForText(point, widths.last(), printing, localStrokeColor);
+    FloatRect bounds = computeLineBoundsAndAntialiasingModeForText(FloatRect(point, FloatSize(widths.last(), thickness)), printing, localStrokeColor);
     bool fillColorIsNotEqualToStrokeColor = fillColor() != localStrokeColor;
     
     Vector<CGRect, 4> dashBounds;
index 7353d37..6f91cd0 100644 (file)
@@ -593,7 +593,7 @@ static TextStream& operator<<(TextStream& ts, const DrawLine& item)
 
 void DrawLinesForText::apply(GraphicsContext& context) const
 {
-    context.drawLinesForText(point(), m_widths, m_printing, m_doubleLines);
+    context.drawLinesForText(point(), m_thickness, m_widths, m_printing, m_doubleLines);
 }
 
 std::optional<FloatRect> DrawLinesForText::localBounds(const GraphicsContext&) const
@@ -603,7 +603,7 @@ std::optional<FloatRect> DrawLinesForText::localBounds(const GraphicsContext&) c
     if (!m_widths.size())
         return FloatRect();
 
-    FloatRect result(point(), FloatSize(m_widths.last(), m_strokeWidth));
+    FloatRect result(point(), FloatSize(m_widths.last(), m_thickness));
     result.inflate(1); // Account for pixel snapping. FIXME: This isn't perfect, as it doesn't take the CTM into account.
     return result;
 }
@@ -614,6 +614,7 @@ static TextStream& operator<<(TextStream& ts, const DrawLinesForText& item)
     ts.dumpProperty("block-location", item.blockLocation());
     ts.dumpProperty("local-anchor", item.localAnchor());
     ts.dumpProperty("point", item.point());
+    ts.dumpProperty("thickness", item.thickness());
     ts.dumpProperty("double", item.doubleLines());
     ts.dumpProperty("widths", item.widths());
     ts.dumpProperty("is-printing", item.isPrinting());
index 7c7eb6d..2b7d14c 100644 (file)
@@ -791,26 +791,27 @@ private:
 
 class DrawLinesForText : public DrawingItem {
 public:
-    static Ref<DrawLinesForText> create(const FloatPoint& blockLocation, const FloatSize& localAnchor, const DashArray& widths, bool printing, bool doubleLines, float strokeWidth)
+    static Ref<DrawLinesForText> create(const FloatPoint& blockLocation, const FloatSize& localAnchor, float thickness, const DashArray& widths, bool printing, bool doubleLines)
     {
-        return adoptRef(*new DrawLinesForText(blockLocation, localAnchor, widths, printing, doubleLines, strokeWidth));
+        return adoptRef(*new DrawLinesForText(blockLocation, localAnchor, thickness, widths, printing, doubleLines));
     }
 
     void setBlockLocation(const FloatPoint& blockLocation) { m_blockLocation = blockLocation; }
     const FloatPoint& blockLocation() const { return m_blockLocation; }
     const FloatSize& localAnchor() const { return m_localAnchor; }
     FloatPoint point() const { return m_blockLocation + m_localAnchor; }
+    float thickness() const { return m_thickness; }
     const DashArray& widths() const { return m_widths; }
     bool isPrinting() const { return m_printing; }
     bool doubleLines() const { return m_doubleLines; }
 
 private:
-    DrawLinesForText(const FloatPoint& blockLocation, const FloatSize& localAnchor, const DashArray& widths, bool printing, bool doubleLines, float strokeWidth)
+    DrawLinesForText(const FloatPoint& blockLocation, const FloatSize& localAnchor, float thickness, const DashArray& widths, bool printing, bool doubleLines)
         : DrawingItem(ItemType::DrawLinesForText)
         , m_blockLocation(blockLocation)
         , m_localAnchor(localAnchor)
         , m_widths(widths)
-        , m_strokeWidth(strokeWidth)
+        , m_thickness(thickness)
         , m_printing(printing)
         , m_doubleLines(doubleLines)
     {
@@ -823,7 +824,7 @@ private:
     FloatPoint m_blockLocation;
     FloatSize m_localAnchor;
     DashArray m_widths;
-    float m_strokeWidth;
+    float m_thickness;
     bool m_printing;
     bool m_doubleLines;
 };
index 5307f02..9039b78 100644 (file)
@@ -230,9 +230,9 @@ void Recorder::drawLine(const FloatPoint& point1, const FloatPoint& point2)
     updateItemExtent(newItem);
 }
 
-void Recorder::drawLinesForText(const FloatPoint& point, const DashArray& widths, bool printing, bool doubleLines, float strokeThickness)
+void Recorder::drawLinesForText(const FloatPoint& point, float thickness, const DashArray& widths, bool printing, bool doubleLines)
 {
-    DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawLinesForText::create(FloatPoint(), toFloatSize(point), widths, printing, doubleLines, strokeThickness)));
+    DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawLinesForText::create(FloatPoint(), toFloatSize(point), thickness, widths, printing, doubleLines)));
     updateItemExtent(newItem);
 }
 
index 1b79437..b69d44e 100644 (file)
@@ -97,7 +97,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 drawLinesForText(const FloatPoint&, float thickness, const DashArray& widths, bool printing, bool doubleLines) override;
     void drawDotsForDocumentMarker(const FloatRect&, DocumentMarkerLineStyle) override;
     void drawEllipse(const FloatRect&) override;
     void drawPath(const Path&) override;
index 578495f..2b1aecf 100644 (file)
@@ -631,9 +631,9 @@ void CairoOperationRecorder::drawLine(const FloatPoint& point1, const FloatPoint
     append(createCommand<DrawLine>(point1, point2, state.strokeStyle, state.strokeColor, state.strokeThickness, state.shouldAntialias));
 }
 
-void CairoOperationRecorder::drawLinesForText(const FloatPoint& point, const DashArray& widths, bool printing, bool doubleUnderlines, float strokeThickness)
+void CairoOperationRecorder::drawLinesForText(const FloatPoint& point, float thickness, const DashArray& widths, bool printing, bool doubleUnderlines)
 {
-    struct DrawLinesForText final : PaintingOperation, OperationData<FloatPoint, DashArray, bool, bool, Color, float> {
+    struct DrawLinesForText final : PaintingOperation, OperationData<FloatPoint, float, DashArray, bool, bool, Color> {
         virtual ~DrawLinesForText() = default;
 
         void execute(PaintingOperationReplay& replayer) override
@@ -647,9 +647,8 @@ void CairoOperationRecorder::drawLinesForText(const FloatPoint& point, const Das
         }
     };
 
-    UNUSED_PARAM(strokeThickness);
     auto& state = graphicsContext().state();
-    append(createCommand<DrawLinesForText>(point, widths, printing, doubleUnderlines, state.strokeColor, state.strokeThickness));
+    append(createCommand<DrawLinesForText>(point, thickness, widths, printing, doubleUnderlines, state.strokeColor));
 }
 
 void CairoOperationRecorder::drawDotsForDocumentMarker(const FloatRect& rect, DocumentMarkerLineStyle style)
index 6d6fac3..dbd6723 100644 (file)
@@ -72,7 +72,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 drawLinesForText(const WebCore::FloatPoint&, float thickness, const DashArray&, bool, bool) override;
     void drawDotsForDocumentMarker(const WebCore::FloatRect&, WebCore::DocumentMarkerLineStyle) override;
     void drawEllipse(const WebCore::FloatRect&) override;
     void drawPath(const WebCore::Path&) override;
index 76f90c1..9722bef 100644 (file)
@@ -72,7 +72,7 @@ static void doDrawTextAtPoint(GraphicsContext& context, const String& text, cons
         underlinePoint.move(beforeWidth, 1);
 
         context.setStrokeColor(color);
-        context.drawLineForText(underlinePoint, underlinedWidth, false);
+        context.drawLineForText(FloatRect(underlinePoint, FloatSize(underlinedWidth, font.size() / 16)), false);
     }
 }
 
index 9e71a71..5039e2a 100644 (file)
@@ -1090,11 +1090,9 @@ void InlineTextBox::paintMarkedTextDecoration(PaintInfo& paintInfo, const FloatR
     }
 
     // 2. Paint
-    TextDecorationPainter decorationPainter { context, lineStyle().textDecorationsInEffect(), renderer(), isFirstLine(), markedText.style.textDecorationStyles };
+    TextDecorationPainter decorationPainter { context, lineStyle().textDecorationsInEffect(), renderer(), isFirstLine(), lineFont(), markedText.style.textDecorationStyles };
     decorationPainter.setInlineTextBox(this);
-    decorationPainter.setFont(lineFont());
     decorationPainter.setWidth(snappedSelectionRect.width());
-    decorationPainter.setBaseline(lineStyle().fontMetrics().ascent());
     decorationPainter.setIsHorizontal(isHorizontal());
     if (markedText.style.textShadow) {
         decorationPainter.setTextShadow(&markedText.style.textShadow.value());
@@ -1200,7 +1198,7 @@ void InlineTextBox::paintCompositionUnderline(PaintInfo& paintInfo, const FloatP
     Color underlineColor = underline.compositionUnderlineColor == CompositionUnderlineColor::TextColor ? renderer().style().visitedDependentColorWithColorFilter(CSSPropertyWebkitTextFillColor) : renderer().style().colorByApplyingColorFilter(underline.color);
     context.setStrokeColor(underlineColor);
     context.setStrokeThickness(lineThickness);
-    context.drawLineForText(FloatPoint(boxOrigin.x() + start, boxOrigin.y() + logicalHeight() - lineThickness), width, renderer().document().printing());
+    context.drawLineForText(FloatRect(boxOrigin.x() + start, boxOrigin.y() + logicalHeight() - lineThickness, width, lineThickness), renderer().document().printing());
 }
 
 int InlineTextBox::caretMinOffset() const
index 7551a9f..d26c048 100644 (file)
@@ -97,9 +97,7 @@ void paintFlow(const RenderBlockFlow& flow, const Layout& layout, PaintInfo& pai
     if (!style.textDecorationsInEffect().isEmpty()) {
         const RenderText* textRenderer = childrenOfType<RenderText>(flow).first();
         if (textRenderer) {
-            textDecorationPainter.emplace(paintInfo.context(), style.textDecorationsInEffect(), *textRenderer, false);
-            textDecorationPainter->setFont(style.fontCascade());
-            textDecorationPainter->setBaseline(style.fontMetrics().ascent());
+            textDecorationPainter.emplace(paintInfo.context(), style.textDecorationsInEffect(), *textRenderer, false, style.fontCascade());
         }
     }
 
index 98e88dc..9b8595c 100644 (file)
@@ -81,75 +81,39 @@ static void adjustStepToDecorationLength(float& step, float& controlPointDistanc
  *             |-----------|
  *                 step
  */
-static void strokeWavyTextDecoration(GraphicsContext& context, const FloatPoint& start, const FloatPoint& end, float strokeThickness, float fontSize)
+static void strokeWavyTextDecoration(GraphicsContext& context, const FloatRect& rect, float fontSize)
 {
-    FloatPoint p1 = start;
-    FloatPoint p2 = end;
-    context.adjustLineToPixelBoundaries(p1, p2, strokeThickness, context.strokeStyle());
+    FloatPoint p1 = rect.minXMinYCorner();
+    FloatPoint p2 = rect.maxXMinYCorner();
+    context.adjustLineToPixelBoundaries(p1, p2, rect.height(), context.strokeStyle());
 
     Path path;
     path.moveTo(p1);
 
-    float controlPointDistance;
-    float step;
-    getWavyStrokeParameters(fontSize, controlPointDistance, step);
+    auto wavyStrokeParameters = getWavyStrokeParameters(fontSize);
 
-    bool isVerticalLine = (p1.x() == p2.x());
+    ASSERT(p1.y() == p2.y());
 
-    if (isVerticalLine) {
-        ASSERT(p1.x() == p2.x());
+    float yAxis = p1.y();
+    float x1 = std::min(p1.x(), p2.x());
+    float x2 = std::max(p1.x(), p2.x());
 
-        float xAxis = p1.x();
-        float y1;
-        float y2;
+    adjustStepToDecorationLength(wavyStrokeParameters.step, wavyStrokeParameters.controlPointDistance, x2 - x1);
+    FloatPoint controlPoint1(0, yAxis + wavyStrokeParameters.controlPointDistance);
+    FloatPoint controlPoint2(0, yAxis - wavyStrokeParameters.controlPointDistance);
 
-        if (p1.y() < p2.y()) {
-            y1 = p1.y();
-            y2 = p2.y();
-        } else {
-            y1 = p2.y();
-            y2 = p1.y();
-        }
-
-        adjustStepToDecorationLength(step, controlPointDistance, y2 - y1);
-        FloatPoint controlPoint1(xAxis + controlPointDistance, 0);
-        FloatPoint controlPoint2(xAxis - controlPointDistance, 0);
-
-        for (float y = y1; y + 2 * step <= y2;) {
-            controlPoint1.setY(y + step);
-            controlPoint2.setY(y + step);
-            y += 2 * step;
-            path.addBezierCurveTo(controlPoint1, controlPoint2, FloatPoint(xAxis, y));
-        }
-    } else {
-        ASSERT(p1.y() == p2.y());
-
-        float yAxis = p1.y();
-        float x1;
-        float x2;
-
-        if (p1.x() < p2.x()) {
-            x1 = p1.x();
-            x2 = p2.x();
-        } else {
-            x1 = p2.x();
-            x2 = p1.x();
-        }
-
-        adjustStepToDecorationLength(step, controlPointDistance, x2 - x1);
-        FloatPoint controlPoint1(0, yAxis + controlPointDistance);
-        FloatPoint controlPoint2(0, yAxis - controlPointDistance);
-
-        for (float x = x1; x + 2 * step <= x2;) {
-            controlPoint1.setX(x + step);
-            controlPoint2.setX(x + step);
-            x += 2 * step;
-            path.addBezierCurveTo(controlPoint1, controlPoint2, FloatPoint(x, yAxis));
-        }
+    for (float x = x1; x + 2 * wavyStrokeParameters.step <= x2;) {
+        controlPoint1.setX(x + wavyStrokeParameters.step);
+        controlPoint2.setX(x + wavyStrokeParameters.step);
+        x += 2 * wavyStrokeParameters.step;
+        path.addBezierCurveTo(controlPoint1, controlPoint2, FloatPoint(x, yAxis));
     }
 
     context.setShouldAntialias(true);
+    auto strokeThickness = context.strokeThickness();
+    context.setStrokeThickness(rect.height());
     context.strokePath(path);
+    context.setStrokeThickness(strokeThickness);
 }
 
 #if ENABLE(CSS3_TEXT_DECORATION_SKIP_INK)
@@ -203,18 +167,6 @@ static DashArray translateIntersectionPointsToSkipInkBoundaries(const DashArray&
     
     return result;
 }
-
-static void drawSkipInkUnderline(GraphicsContext& context, const FontCascade& font, const TextRun& textRun, const FloatPoint& textOrigin, const FloatPoint& localOrigin,
-    float underlineOffset, float width, bool isPrinting, bool doubleLines, StrokeStyle strokeStyle)
-{
-    FloatPoint adjustedLocalOrigin = localOrigin;
-    adjustedLocalOrigin.move(0, underlineOffset);
-    FloatRect underlineBoundingBox = context.computeUnderlineBoundsForText(adjustedLocalOrigin, width, isPrinting);
-    DashArray intersections = font.dashesForIntersectionsWithRect(textRun, textOrigin, underlineBoundingBox);
-    DashArray a = translateIntersectionPointsToSkipInkBoundaries(intersections, underlineBoundingBox.height(), width);
-    ASSERT(!(a.size() % 2));
-    context.drawLinesForText(adjustedLocalOrigin, a, isPrinting, doubleLines, strokeStyle);
-}
 #endif
 
 static StrokeStyle textDecorationStyleToStrokeStyle(TextDecorationStyle decorationStyle)
@@ -247,11 +199,12 @@ bool TextDecorationPainter::Styles::operator==(const Styles& other) const
         && underlineStyle == other.underlineStyle && overlineStyle == other.overlineStyle && linethroughStyle == other.linethroughStyle;
 }
 
-TextDecorationPainter::TextDecorationPainter(GraphicsContext& context, OptionSet<TextDecoration> decorations, const RenderText& renderer, bool isFirstLine, std::optional<Styles> styles)
+TextDecorationPainter::TextDecorationPainter(GraphicsContext& context, OptionSet<TextDecoration> decorations, const RenderText& renderer, bool isFirstLine, const FontCascade& font, std::optional<Styles> styles)
     : m_context { context }
     , m_decorations { decorations }
     , m_wavyOffset { wavyOffsetFromDecoration() }
     , m_isPrinting { renderer.document().printing() }
+    , m_font { font }
     , m_styles { styles ? *WTFMove(styles) : stylesForRenderer(renderer, decorations, isFirstLine, PseudoId::None) }
     , m_lineStyle { isFirstLine ? renderer.firstLineStyle() : renderer.style() }
 {
@@ -263,31 +216,36 @@ void TextDecorationPainter::paintTextDecoration(const TextRun& textRun, const Fl
     UNUSED_PARAM(textRun);
     UNUSED_PARAM(textOrigin);
 #endif
-    ASSERT(m_font);
+    const auto& fontMetrics = m_lineStyle.fontMetrics();
     float textDecorationThickness = textDecorationStrokeThickness(m_lineStyle.computedFontPixelSize());
-    m_context.setStrokeThickness(textDecorationThickness);
     FloatPoint localOrigin = boxOrigin;
 
-    auto paintDecoration = [&] (OptionSet<TextDecoration> decoration, TextDecorationStyle style, const Color& color, const FloatPoint& start, const FloatPoint& end, int offset) {
+    auto paintDecoration = [&] (TextDecoration decoration, TextDecorationStyle style, const Color& color, const FloatRect& rect) {
         m_context.setStrokeColor(color);
 
         auto strokeStyle = textDecorationStyleToStrokeStyle(style);
 
         if (style == TextDecorationStyle::Wavy)
-            strokeWavyTextDecoration(m_context, start, end, textDecorationThickness, m_lineStyle.computedFontPixelSize());
+            strokeWavyTextDecoration(m_context, rect, m_lineStyle.computedFontPixelSize());
         else if (decoration == TextDecoration::Underline || decoration == TextDecoration::Overline) {
 #if ENABLE(CSS3_TEXT_DECORATION_SKIP_INK)
             if ((m_lineStyle.textDecorationSkip() == TextDecorationSkip::Ink || m_lineStyle.textDecorationSkip() == TextDecorationSkip::Auto) && m_isHorizontal) {
-                if (!m_context.paintingDisabled())
-                    drawSkipInkUnderline(m_context, *m_font, textRun, textOrigin, localOrigin, offset, m_width, m_isPrinting, style == TextDecorationStyle::Double, strokeStyle);
+                if (!m_context.paintingDisabled()) {
+                    FloatRect underlineBoundingBox = m_context.computeUnderlineBoundsForText(rect, m_isPrinting);
+                    DashArray intersections = m_font.dashesForIntersectionsWithRect(textRun, textOrigin, underlineBoundingBox);
+                    DashArray boundaries = translateIntersectionPointsToSkipInkBoundaries(intersections, underlineBoundingBox.height(), rect.width());
+                    ASSERT(!(boundaries.size() % 2));
+                    // We don't use underlineBoundingBox here because drawLinesForText() will run computeUnderlineBoundsForText() internally.
+                    m_context.drawLinesForText(rect.location(), rect.height(), boundaries, m_isPrinting, style == TextDecorationStyle::Double, strokeStyle);
+                }
             } else
                 // FIXME: Need to support text-decoration-skip: none.
 #endif
-                m_context.drawLineForText(start, m_width, m_isPrinting, style == TextDecorationStyle::Double, strokeStyle);
+                m_context.drawLineForText(rect, m_isPrinting, style == TextDecorationStyle::Double, strokeStyle);
             
         } else {
             ASSERT(decoration == TextDecoration::LineThrough);
-            m_context.drawLineForText(start, m_width, m_isPrinting, style == TextDecorationStyle::Double, strokeStyle);
+            m_context.drawLineForText(rect, m_isPrinting, style == TextDecorationStyle::Double, strokeStyle);
         }
     };
 
@@ -298,10 +256,10 @@ void TextDecorationPainter::paintTextDecoration(const TextRun& textRun, const Fl
     int extraOffset = 0;
     bool clipping = !areLinesOpaque && m_shadow && m_shadow->next();
     if (clipping) {
-        FloatRect clipRect(localOrigin, FloatSize(m_width, m_baseline + 2));
+        FloatRect clipRect(localOrigin, FloatSize(m_width, fontMetrics.ascent() + 2));
         for (const ShadowData* shadow = m_shadow; shadow; shadow = shadow->next()) {
             int shadowExtent = shadow->paintingExtent();
-            FloatRect shadowRect(localOrigin, FloatSize(m_width, m_baseline + 2));
+            FloatRect shadowRect(localOrigin, FloatSize(m_width, fontMetrics.ascent() + 2));
             shadowRect.inflate(shadowExtent);
             int shadowX = m_isHorizontal ? shadow->x() : shadow->y();
             int shadowY = m_isHorizontal ? shadow->y() : -shadow->x();
@@ -311,7 +269,7 @@ void TextDecorationPainter::paintTextDecoration(const TextRun& textRun, const Fl
         }
         m_context.save();
         m_context.clip(clipRect);
-        extraOffset += m_baseline + 2;
+        extraOffset += fontMetrics.ascent() + 2;
         localOrigin.move(0, extraOffset);
     }
 
@@ -337,20 +295,20 @@ void TextDecorationPainter::paintTextDecoration(const TextRun& textRun, const Fl
         if (m_decorations.contains(TextDecoration::Underline)) {
             int offset = computeUnderlineOffset(m_lineStyle.textUnderlinePosition(), m_lineStyle.fontMetrics(), m_inlineTextBox, textDecorationThickness);
             float wavyOffset = m_styles.underlineStyle == TextDecorationStyle::Wavy ? m_wavyOffset : 0;
-            FloatPoint start = localOrigin + FloatSize(0, offset + wavyOffset);
-            FloatPoint end = localOrigin + FloatSize(m_width, offset + wavyOffset);
-            paintDecoration(TextDecoration::Underline, m_styles.underlineStyle, m_styles.underlineColor, start, end, offset);
+            FloatRect rect(localOrigin, FloatSize(m_width, textDecorationThickness));
+            rect.move(0, offset + wavyOffset);
+            paintDecoration(TextDecoration::Underline, m_styles.underlineStyle, m_styles.underlineColor, rect);
         }
         if (m_decorations.contains(TextDecoration::Overline)) {
             float wavyOffset = m_styles.overlineStyle == TextDecorationStyle::Wavy ? m_wavyOffset : 0;
-            FloatPoint start = localOrigin - FloatSize(0, wavyOffset);
-            FloatPoint end = localOrigin + FloatSize(m_width, -wavyOffset);
-            paintDecoration(TextDecoration::Overline, m_styles.overlineStyle, m_styles.overlineColor, start, end, 0);
+            FloatRect rect(localOrigin, FloatSize(m_width, textDecorationThickness));
+            rect.move(0, -wavyOffset);
+            paintDecoration(TextDecoration::Overline, m_styles.overlineStyle, m_styles.overlineColor, rect);
         }
         if (m_decorations.contains(TextDecoration::LineThrough)) {
-            FloatPoint start = localOrigin + FloatSize(0, 2 * m_baseline / 3);
-            FloatPoint end = localOrigin + FloatSize(m_width, 2 * m_baseline / 3);
-            paintDecoration(TextDecoration::LineThrough, m_styles.linethroughStyle, m_styles.linethroughColor, start, end, 0);
+            FloatRect rect(localOrigin, FloatSize(m_width, textDecorationThickness));
+            rect.move(0, 2 * fontMetrics.floatAscent() / 3);
+            paintDecoration(TextDecoration::LineThrough, m_styles.linethroughStyle, m_styles.linethroughColor, rect);
         }
     } while (shadow);
 
index 0294a46..a6d14b2 100644 (file)
@@ -42,13 +42,11 @@ class TextRun;
 class TextDecorationPainter {
 public:
     struct Styles;
-    TextDecorationPainter(GraphicsContext&, OptionSet<TextDecoration> decorations, const RenderText&, bool isFirstLine, std::optional<Styles> = std::nullopt);
+    TextDecorationPainter(GraphicsContext&, OptionSet<TextDecoration> decorations, const RenderText&, bool isFirstLine, const FontCascade&, std::optional<Styles> = std::nullopt);
     
     void setInlineTextBox(const InlineTextBox* inlineTextBox) { m_inlineTextBox = inlineTextBox; }
-    void setFont(const FontCascade& font) { m_font = &font; }
     void setIsHorizontal(bool isHorizontal) { m_isHorizontal = isHorizontal; }
     void setWidth(float width) { m_width = width; }
-    void setBaseline(float baseline) { m_baseline = baseline; }
     void setTextShadow(const ShadowData* textShadow) { m_shadow = textShadow; }
     void setShadowColorFilter(const FilterOperations* colorFilter) { m_shadowColorFilter = colorFilter; }
 
@@ -72,14 +70,13 @@ private:
     OptionSet<TextDecoration> m_decorations;
     float m_wavyOffset;
     float m_width { 0 };
-    float m_baseline { 0 };
     FloatPoint m_boxOrigin;
     bool m_isPrinting;
     bool m_isHorizontal { true };
     const ShadowData* m_shadow { nullptr };
     const FilterOperations* m_shadowColorFilter { nullptr };
     const InlineTextBox* m_inlineTextBox { nullptr };
-    const FontCascade* m_font { nullptr };
+    const FontCascade& m_font;
 
     Styles m_styles;
     const RenderStyle& m_lineStyle;
index ab1567f..587545a 100644 (file)
@@ -83,17 +83,13 @@ int computeUnderlineOffset(TextUnderlinePosition underlinePosition, const FontMe
     return fontMetrics.ascent() + gap;
 }
     
-void getWavyStrokeParameters(float fontSize, float& controlPointDistance, float& step)
+WavyStrokeParameters getWavyStrokeParameters(float fontSize)
 {
-    // Distance between decoration's axis and Bezier curve's control points.
-    // The height of the curve is based on this distance. Increases the curve's height
-    // as fontSize increases to make the curve look better.
-    controlPointDistance = 0.09375 * fontSize;
-
-    // Increment used to form the diamond shape between start point (p1), control
-    // points and end point (p2) along the axis of the decoration. The curve gets
-    // wider as font size increases.
-    step = fontSize / 4.5;
+    WavyStrokeParameters result;
+    // More information is in the WavyStrokeParameters definition.
+    result.controlPointDistance = fontSize * 1.5 / 16;
+    result.step = fontSize / 4.5;
+    return result;
 }
 
 static inline void extendIntToFloat(int& extendMe, float extendTo)
@@ -110,8 +106,7 @@ GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, const I
         return GlyphOverflow();
 
     float strokeThickness = textDecorationStrokeThickness(lineStyle.computedFontPixelSize());
-    float controlPointDistance = 0;
-    float step;
+    WavyStrokeParameters wavyStrokeParameters;
     float wavyOffset = 0;
         
     TextDecorationStyle decorationStyle = lineStyle.textDecorationStyle();
@@ -119,7 +114,7 @@ GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, const I
     GlyphOverflow overflowResult;
     
     if (decorationStyle == TextDecorationStyle::Wavy) {
-        getWavyStrokeParameters(lineStyle.computedFontPixelSize(), controlPointDistance, step);
+        wavyStrokeParameters = getWavyStrokeParameters(lineStyle.computedFontPixelSize());
         wavyOffset = wavyOffsetFromDecoration();
         overflowResult.left = strokeThickness;
         overflowResult.right = strokeThickness;
@@ -131,8 +126,8 @@ GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, const I
         int underlineOffset = 1;
         underlineOffset += computeUnderlineOffset(lineStyle.textUnderlinePosition(), lineStyle.fontMetrics(), inlineTextBox, strokeThickness);
         if (decorationStyle == TextDecorationStyle::Wavy) {
-            extendIntToFloat(overflowResult.bottom, underlineOffset + wavyOffset + controlPointDistance + strokeThickness - height);
-            extendIntToFloat(overflowResult.top, -(underlineOffset + wavyOffset - controlPointDistance - strokeThickness));
+            extendIntToFloat(overflowResult.bottom, underlineOffset + wavyOffset + wavyStrokeParameters.controlPointDistance + strokeThickness - height);
+            extendIntToFloat(overflowResult.top, -(underlineOffset + wavyOffset - wavyStrokeParameters.controlPointDistance - strokeThickness));
         } else {
             extendIntToFloat(overflowResult.bottom, underlineOffset + strokeThickness - height);
             extendIntToFloat(overflowResult.top, -underlineOffset);
@@ -140,8 +135,8 @@ GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, const I
     }
     if (decoration & TextDecoration::Overline) {
         if (decorationStyle == TextDecorationStyle::Wavy) {
-            extendIntToFloat(overflowResult.bottom, -wavyOffset + controlPointDistance + strokeThickness - height);
-            extendIntToFloat(overflowResult.top, wavyOffset + controlPointDistance + strokeThickness);
+            extendIntToFloat(overflowResult.bottom, -wavyOffset + wavyStrokeParameters.controlPointDistance + strokeThickness - height);
+            extendIntToFloat(overflowResult.top, wavyOffset + wavyStrokeParameters.controlPointDistance + strokeThickness);
         } else {
             extendIntToFloat(overflowResult.bottom, strokeThickness - height);
             // top is untouched
@@ -150,8 +145,8 @@ GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, const I
     if (decoration & TextDecoration::LineThrough) {
         float baseline = lineStyle.fontMetrics().floatAscent();
         if (decorationStyle == TextDecorationStyle::Wavy) {
-            extendIntToFloat(overflowResult.bottom, 2 * baseline / 3 + controlPointDistance + strokeThickness - height);
-            extendIntToFloat(overflowResult.top, -(2 * baseline / 3 - controlPointDistance - strokeThickness));
+            extendIntToFloat(overflowResult.bottom, 2 * baseline / 3 + wavyStrokeParameters.controlPointDistance + strokeThickness - height);
+            extendIntToFloat(overflowResult.top, -(2 * baseline / 3 - wavyStrokeParameters.controlPointDistance - strokeThickness));
         } else {
             extendIntToFloat(overflowResult.bottom, 2 * baseline / 3 + strokeThickness - height);
             extendIntToFloat(overflowResult.top, -(2 * baseline / 3));
index a8525a4..cb06fd1 100644 (file)
@@ -44,8 +44,19 @@ inline float wavyOffsetFromDecoration()
     return 1;
 }
 
+struct WavyStrokeParameters {
+    // Distance between decoration's axis and Bezier curve's control points.
+    // The height of the curve is based on this distance. Increases the curve's height
+    // as fontSize increases to make the curve look better.
+    float controlPointDistance { 0 };
+
+    // Increment used to form the diamond shape between start point (p1), control
+    // points and end point (p2) along the axis of the decoration. The curve gets
+    // wider as font size increases.
+    float step { 0 };
+};
+WavyStrokeParameters getWavyStrokeParameters(float fontSize);
 GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, const InlineTextBox*);
-void getWavyStrokeParameters(float fontSize, float& controlPointDistance, float& step);
 int computeUnderlineOffset(TextUnderlinePosition, const FontMetrics&, const InlineTextBox*, int textDecorationThickness);
     
 } // namespace WebCore