Changeset 237844 in webkit
- Timestamp:
- Nov 5, 2018 8:32:44 PM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 23 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r237843 r237844 1 2018-11-05 Myles C. Maxfield <mmaxfield@apple.com> 2 3 Clean up text decoration drawing code 4 https://bugs.webkit.org/show_bug.cgi?id=191245 5 6 Reviewed by Zalan Bujtas. 7 8 This is some general clean up of the text decorations code. There is no behavior change. 9 10 This patch modifies GraphicsContext::drawLineForText() & friends to accept a FloatRect instead of a FloatPoint + float width. 11 This is helpful because it allows for easier bounding box calculations. 12 This patch also removes some redundant computations that the skip:ink codepath was performing. 13 This patch also refactors the wavy decoration parameters to not use out params. 14 15 No new tests because there is no behavior change. 16 17 * platform/graphics/GraphicsContext.cpp: 18 (WebCore::GraphicsContext::computeUnderlineBoundsForText): 19 (WebCore::GraphicsContext::computeLineBoundsAndAntialiasingModeForText): 20 * platform/graphics/GraphicsContext.h: 21 * platform/graphics/GraphicsContextImpl.h: 22 * platform/graphics/cg/GraphicsContextCG.cpp: 23 (WebCore::GraphicsContext::drawLineForText): 24 (WebCore::GraphicsContext::drawLinesForText): 25 * platform/graphics/displaylists/DisplayListItems.cpp: 26 (WebCore::DisplayList::DrawLinesForText::apply const): 27 (WebCore::DisplayList::DrawLinesForText::localBounds const): 28 (WebCore::DisplayList::operator<<): 29 * platform/graphics/displaylists/DisplayListItems.h: 30 (WebCore::DisplayList::DrawLinesForText::create): 31 (WebCore::DisplayList::DrawLinesForText::thickness const): 32 (WebCore::DisplayList::DrawLinesForText::DrawLinesForText): 33 * platform/graphics/displaylists/DisplayListRecorder.cpp: 34 (WebCore::DisplayList::Recorder::drawLinesForText): 35 * platform/graphics/displaylists/DisplayListRecorder.h: 36 * rendering/InlineTextBox.cpp: 37 (WebCore::InlineTextBox::paintMarkedTextDecoration): 38 (WebCore::InlineTextBox::paintCompositionUnderline const): 39 * rendering/SimpleLineLayoutFunctions.cpp: 40 (WebCore::SimpleLineLayout::paintFlow): 41 * rendering/TextDecorationPainter.cpp: 42 (WebCore::strokeWavyTextDecoration): 43 (WebCore::translateIntersectionPointsToSkipInkBoundaries): 44 (WebCore::TextDecorationPainter::TextDecorationPainter): 45 (WebCore::TextDecorationPainter::paintTextDecoration): 46 (WebCore::drawSkipInkUnderline): Deleted. 47 * rendering/TextDecorationPainter.h: 48 (WebCore::TextDecorationPainter::setInlineTextBox): 49 (WebCore::TextDecorationPainter::setWidth): 50 (WebCore::TextDecorationPainter::setFont): Deleted. 51 (WebCore::TextDecorationPainter::setBaseline): Deleted. 52 * style/InlineTextBoxStyle.cpp: 53 (WebCore::getWavyStrokeParameters): 54 (WebCore::visualOverflowForDecorations): 55 * style/InlineTextBoxStyle.h: 56 1 57 2018-11-05 Myles C. Maxfield <mmaxfield@apple.com> 2 58 -
trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp
r237266 r237844 1084 1084 #endif 1085 1085 1086 FloatRect GraphicsContext::computeUnderlineBoundsForText(const Float Point& point, float width, bool printing)1086 FloatRect GraphicsContext::computeUnderlineBoundsForText(const FloatRect& rect, bool printing) 1087 1087 { 1088 1088 Color dummyColor; 1089 return computeLineBoundsAndAntialiasingModeForText( point, width, printing, dummyColor);1090 } 1091 1092 FloatRect GraphicsContext::computeLineBoundsAndAntialiasingModeForText(const Float Point& point, float width, bool printing, Color& color)1093 { 1094 FloatPoint origin = point;1095 float thickness = std::max( strokeThickness(), 0.5f);1089 return computeLineBoundsAndAntialiasingModeForText(rect, printing, dummyColor); 1090 } 1091 1092 FloatRect GraphicsContext::computeLineBoundsAndAntialiasingModeForText(const FloatRect& rect, bool printing, Color& color) 1093 { 1094 FloatPoint origin = rect.location(); 1095 float thickness = std::max(rect.height(), 0.5f); 1096 1096 if (printing) 1097 return FloatRect(origin, FloatSize( width, thickness));1097 return FloatRect(origin, FloatSize(rect.width(), thickness)); 1098 1098 1099 1099 AffineTransform transform = getCTM(GraphicsContext::DefinitelyIncludeDeviceScale); … … 1109 1109 } 1110 1110 1111 FloatPoint devicePoint = transform.mapPoint( point);1111 FloatPoint devicePoint = transform.mapPoint(rect.location()); 1112 1112 // Visual overflow might occur here due to integral roundf/ceilf. visualOverflowForDecorations adjusts the overflow value for underline decoration. 1113 1113 FloatPoint deviceOrigin = FloatPoint(roundf(devicePoint.x()), ceilf(devicePoint.y())); 1114 1114 if (auto inverse = transform.inverse()) 1115 1115 origin = inverse.value().mapPoint(deviceOrigin); 1116 return FloatRect(origin, FloatSize( width, thickness));1116 return FloatRect(origin, FloatSize(rect.width(), thickness)); 1117 1117 } 1118 1118 -
trunk/Source/WebCore/platform/graphics/GraphicsContext.h
r237765 r237844 419 419 FloatRect roundToDevicePixels(const FloatRect&, RoundingMode = RoundAllSides); 420 420 421 FloatRect computeUnderlineBoundsForText(const Float Point&, float width, bool printing);422 WEBCORE_EXPORT void drawLineForText(const Float Point&, float width, bool printing, bool doubleLines = false, StrokeStyle = SolidStroke);423 void drawLinesForText(const FloatPoint&, const DashArray& widths, bool printing, bool doubleLines = false, StrokeStyle = SolidStroke);421 FloatRect computeUnderlineBoundsForText(const FloatRect&, bool printing); 422 WEBCORE_EXPORT void drawLineForText(const FloatRect&, bool printing, bool doubleLines = false, StrokeStyle = SolidStroke); 423 void drawLinesForText(const FloatPoint&, float thickness, const DashArray& widths, bool printing, bool doubleLines = false, StrokeStyle = SolidStroke); 424 424 void drawDotsForDocumentMarker(const FloatRect&, DocumentMarkerLineStyle); 425 425 … … 627 627 void platformFillRoundedRect(const FloatRoundedRect&, const Color&); 628 628 629 FloatRect computeLineBoundsAndAntialiasingModeForText(const Float Point&, float width, bool printing, Color&);629 FloatRect computeLineBoundsAndAntialiasingModeForText(const FloatRect&, bool printing, Color&); 630 630 631 631 float dashedLineCornerWidthForStrokeWidth(float) const; -
trunk/Source/WebCore/platform/graphics/GraphicsContextImpl.h
r237765 r237844 79 79 virtual void drawRect(const FloatRect&, float borderThickness) = 0; 80 80 virtual void drawLine(const FloatPoint&, const FloatPoint&) = 0; 81 virtual void drawLinesForText(const FloatPoint&, const DashArray& widths, bool printing, bool doubleLines, float strokeThickness) = 0;81 virtual void drawLinesForText(const FloatPoint&, float thickness, const DashArray& widths, bool printing, bool doubleLines) = 0; 82 82 virtual void drawDotsForDocumentMarker(const FloatRect&, DocumentMarkerLineStyle) = 0; 83 83 virtual void drawEllipse(const FloatRect&) = 0; -
trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp
r237765 r237844 1024 1024 } 1025 1025 1026 void drawLinesForText(PlatformContextCairo& platformContext, const FloatPoint& point, const DashArray& widths, bool printing, bool doubleUnderlines, const Color& color, float strokeThickness)1026 void drawLinesForText(PlatformContextCairo& platformContext, const FloatPoint& point, float strokeThickness, const DashArray& widths, bool printing, bool doubleUnderlines, const Color& color) 1027 1027 { 1028 1028 Color modifiedColor = color; -
trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.h
r237765 r237844 145 145 void drawRect(PlatformContextCairo&, const FloatRect&, float, const Color&, StrokeStyle, const Color&); 146 146 void drawLine(PlatformContextCairo&, const FloatPoint&, const FloatPoint&, StrokeStyle, const Color&, float, bool); 147 void drawLinesForText(PlatformContextCairo&, const FloatPoint&, const DashArray&, bool, bool, const Color&, float);147 void drawLinesForText(PlatformContextCairo&, const FloatPoint&, float thickness, const DashArray&, bool, bool, const Color&); 148 148 void drawDotsForDocumentMarker(PlatformContextCairo&, const FloatRect&, DocumentMarkerLineStyle); 149 149 void drawEllipse(PlatformContextCairo&, const FloatRect&, const Color&, StrokeStyle, const Color&, float); -
trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
r237765 r237844 316 316 } 317 317 318 void GraphicsContext::drawLineForText(const Float Point& origin, float width, bool printing, bool doubleUnderlines, StrokeStyle)319 { 320 drawLinesForText( origin, DashArray { width, 0 }, printing, doubleUnderlines);321 } 322 323 void GraphicsContext::drawLinesForText(const FloatPoint& point, const DashArray& widths, bool printing, bool doubleUnderlines, StrokeStyle)318 void GraphicsContext::drawLineForText(const FloatRect& rect, bool printing, bool doubleUnderlines, StrokeStyle) 319 { 320 drawLinesForText(rect.location(), rect.height(), DashArray { rect.width(), 0 }, printing, doubleUnderlines); 321 } 322 323 void GraphicsContext::drawLinesForText(const FloatPoint& point, float thickness, const DashArray& widths, bool printing, bool doubleUnderlines, StrokeStyle) 324 324 { 325 325 if (paintingDisabled()) … … 330 330 331 331 if (m_impl) { 332 m_impl->drawLinesForText(point, widths, printing, doubleUnderlines, strokeThickness());333 return; 334 } 335 336 ASSERT(hasPlatformContext()); 337 Cairo::drawLinesForText(*platformContext(), point, widths, printing, doubleUnderlines, m_state.strokeColor, m_state.strokeThickness);332 m_impl->drawLinesForText(point, thickness, widths, printing, doubleUnderlines); 333 return; 334 } 335 336 ASSERT(hasPlatformContext()); 337 Cairo::drawLinesForText(*platformContext(), point, thickness, widths, printing, doubleUnderlines, m_state.strokeColor); 338 338 } 339 339 -
trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextImplCairo.cpp
r237765 r237844 297 297 } 298 298 299 void GraphicsContextImplCairo::drawLinesForText(const FloatPoint& point, const DashArray& widths, bool printing, bool doubleUnderlines, float strokeThickness) 300 { 301 UNUSED_PARAM(strokeThickness); 302 auto& state = graphicsContext().state(); 303 Cairo::drawLinesForText(m_platformContext, point, widths, printing, doubleUnderlines, state.strokeColor, state.strokeThickness); 299 void GraphicsContextImplCairo::drawLinesForText(const FloatPoint& point, float thickness, const DashArray& widths, bool printing, bool doubleUnderlines) 300 { 301 auto& state = graphicsContext().state(); 302 Cairo::drawLinesForText(m_platformContext, point, thickness, widths, printing, doubleUnderlines, state.strokeColor); 304 303 } 305 304 -
trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextImplCairo.h
r237765 r237844 80 80 void drawRect(const FloatRect&, float) override; 81 81 void drawLine(const FloatPoint&, const FloatPoint&) override; 82 void drawLinesForText(const FloatPoint&, const DashArray&, bool, bool, float) override;82 void drawLinesForText(const FloatPoint&, float thickness, const DashArray&, bool, bool) override; 83 83 void drawDotsForDocumentMarker(const FloatRect&, DocumentMarkerLineStyle) override; 84 84 void drawEllipse(const FloatRect&) override; -
trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
r237405 r237844 1571 1571 } 1572 1572 1573 void GraphicsContext::drawLineForText(const Float Point& point, float width, bool printing, bool doubleLines, StrokeStyle strokeStyle)1573 void GraphicsContext::drawLineForText(const FloatRect& rect, bool printing, bool doubleLines, StrokeStyle strokeStyle) 1574 1574 { 1575 1575 DashArray widths; 1576 widths.append( width);1576 widths.append(rect.width()); 1577 1577 widths.append(0); 1578 drawLinesForText( point, widths, printing, doubleLines, strokeStyle);1579 } 1580 1581 void GraphicsContext::drawLinesForText(const FloatPoint& point, const DashArray& widths, bool printing, bool doubleLines, StrokeStyle strokeStyle)1578 drawLinesForText(rect.location(), rect.height(), widths, printing, doubleLines, strokeStyle); 1579 } 1580 1581 void GraphicsContext::drawLinesForText(const FloatPoint& point, float thickness, const DashArray& widths, bool printing, bool doubleLines, StrokeStyle strokeStyle) 1582 1582 { 1583 1583 if (paintingDisabled()) … … 1588 1588 1589 1589 if (m_impl) { 1590 m_impl->drawLinesForText(point, widths, printing, doubleLines, strokeThickness());1590 m_impl->drawLinesForText(point, thickness, widths, printing, doubleLines); 1591 1591 return; 1592 1592 } … … 1594 1594 Color localStrokeColor(strokeColor()); 1595 1595 1596 FloatRect bounds = computeLineBoundsAndAntialiasingModeForText( point, widths.last(), printing, localStrokeColor);1596 FloatRect bounds = computeLineBoundsAndAntialiasingModeForText(FloatRect(point, FloatSize(widths.last(), thickness)), printing, localStrokeColor); 1597 1597 bool fillColorIsNotEqualToStrokeColor = fillColor() != localStrokeColor; 1598 1598 -
trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp
r237765 r237844 594 594 void DrawLinesForText::apply(GraphicsContext& context) const 595 595 { 596 context.drawLinesForText(point(), m_ widths, m_printing, m_doubleLines);596 context.drawLinesForText(point(), m_thickness, m_widths, m_printing, m_doubleLines); 597 597 } 598 598 … … 604 604 return FloatRect(); 605 605 606 FloatRect result(point(), FloatSize(m_widths.last(), m_ strokeWidth));606 FloatRect result(point(), FloatSize(m_widths.last(), m_thickness)); 607 607 result.inflate(1); // Account for pixel snapping. FIXME: This isn't perfect, as it doesn't take the CTM into account. 608 608 return result; … … 615 615 ts.dumpProperty("local-anchor", item.localAnchor()); 616 616 ts.dumpProperty("point", item.point()); 617 ts.dumpProperty("thickness", item.thickness()); 617 618 ts.dumpProperty("double", item.doubleLines()); 618 619 ts.dumpProperty("widths", item.widths()); -
trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h
r237765 r237844 792 792 class DrawLinesForText : public DrawingItem { 793 793 public: 794 static Ref<DrawLinesForText> create(const FloatPoint& blockLocation, const FloatSize& localAnchor, const DashArray& widths, bool printing, bool doubleLines, float strokeWidth)795 { 796 return adoptRef(*new DrawLinesForText(blockLocation, localAnchor, widths, printing, doubleLines, strokeWidth));794 static Ref<DrawLinesForText> create(const FloatPoint& blockLocation, const FloatSize& localAnchor, float thickness, const DashArray& widths, bool printing, bool doubleLines) 795 { 796 return adoptRef(*new DrawLinesForText(blockLocation, localAnchor, thickness, widths, printing, doubleLines)); 797 797 } 798 798 … … 801 801 const FloatSize& localAnchor() const { return m_localAnchor; } 802 802 FloatPoint point() const { return m_blockLocation + m_localAnchor; } 803 float thickness() const { return m_thickness; } 803 804 const DashArray& widths() const { return m_widths; } 804 805 bool isPrinting() const { return m_printing; } … … 806 807 807 808 private: 808 DrawLinesForText(const FloatPoint& blockLocation, const FloatSize& localAnchor, const DashArray& widths, bool printing, bool doubleLines, float strokeWidth)809 DrawLinesForText(const FloatPoint& blockLocation, const FloatSize& localAnchor, float thickness, const DashArray& widths, bool printing, bool doubleLines) 809 810 : DrawingItem(ItemType::DrawLinesForText) 810 811 , m_blockLocation(blockLocation) 811 812 , m_localAnchor(localAnchor) 812 813 , m_widths(widths) 813 , m_ strokeWidth(strokeWidth)814 , m_thickness(thickness) 814 815 , m_printing(printing) 815 816 , m_doubleLines(doubleLines) … … 824 825 FloatSize m_localAnchor; 825 826 DashArray m_widths; 826 float m_ strokeWidth;827 float m_thickness; 827 828 bool m_printing; 828 829 bool m_doubleLines; -
trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp
r237765 r237844 231 231 } 232 232 233 void Recorder::drawLinesForText(const FloatPoint& point, const DashArray& widths, bool printing, bool doubleLines, float strokeThickness)234 { 235 DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawLinesForText::create(FloatPoint(), toFloatSize(point), widths, printing, doubleLines, strokeThickness)));233 void Recorder::drawLinesForText(const FloatPoint& point, float thickness, const DashArray& widths, bool printing, bool doubleLines) 234 { 235 DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawLinesForText::create(FloatPoint(), toFloatSize(point), thickness, widths, printing, doubleLines))); 236 236 updateItemExtent(newItem); 237 237 } -
trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h
r237765 r237844 98 98 void drawRect(const FloatRect&, float borderThickness) override; 99 99 void drawLine(const FloatPoint&, const FloatPoint&) override; 100 void drawLinesForText(const FloatPoint&, const DashArray& widths, bool printing, bool doubleLines, float strokeThickness) override;100 void drawLinesForText(const FloatPoint&, float thickness, const DashArray& widths, bool printing, bool doubleLines) override; 101 101 void drawDotsForDocumentMarker(const FloatRect&, DocumentMarkerLineStyle) override; 102 102 void drawEllipse(const FloatRect&) override; -
trunk/Source/WebCore/platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.cpp
r237765 r237844 632 632 } 633 633 634 void CairoOperationRecorder::drawLinesForText(const FloatPoint& point, const DashArray& widths, bool printing, bool doubleUnderlines, float strokeThickness)635 { 636 struct DrawLinesForText final : PaintingOperation, OperationData<FloatPoint, DashArray, bool, bool, Color, float> {634 void CairoOperationRecorder::drawLinesForText(const FloatPoint& point, float thickness, const DashArray& widths, bool printing, bool doubleUnderlines) 635 { 636 struct DrawLinesForText final : PaintingOperation, OperationData<FloatPoint, float, DashArray, bool, bool, Color> { 637 637 virtual ~DrawLinesForText() = default; 638 638 … … 648 648 }; 649 649 650 UNUSED_PARAM(strokeThickness); 651 auto& state = graphicsContext().state(); 652 append(createCommand<DrawLinesForText>(point, widths, printing, doubleUnderlines, state.strokeColor, state.strokeThickness)); 650 auto& state = graphicsContext().state(); 651 append(createCommand<DrawLinesForText>(point, thickness, widths, printing, doubleUnderlines, state.strokeColor)); 653 652 } 654 653 -
trunk/Source/WebCore/platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.h
r237765 r237844 73 73 void drawRect(const WebCore::FloatRect&, float) override; 74 74 void drawLine(const WebCore::FloatPoint&, const WebCore::FloatPoint&) override; 75 void drawLinesForText(const WebCore::FloatPoint&, const DashArray&, bool, bool, float) override;75 void drawLinesForText(const WebCore::FloatPoint&, float thickness, const DashArray&, bool, bool) override; 76 76 void drawDotsForDocumentMarker(const WebCore::FloatRect&, WebCore::DocumentMarkerLineStyle) override; 77 77 void drawEllipse(const WebCore::FloatRect&) override; -
trunk/Source/WebCore/platform/win/WebCoreTextRenderer.cpp
r195180 r237844 73 73 74 74 context.setStrokeColor(color); 75 context.drawLineForText( underlinePoint, underlinedWidth, false);75 context.drawLineForText(FloatRect(underlinePoint, FloatSize(underlinedWidth, font.size() / 16)), false); 76 76 } 77 77 } -
trunk/Source/WebCore/rendering/InlineTextBox.cpp
r237834 r237844 1091 1091 1092 1092 // 2. Paint 1093 TextDecorationPainter decorationPainter { context, lineStyle().textDecorationsInEffect(), renderer(), isFirstLine(), markedText.style.textDecorationStyles };1093 TextDecorationPainter decorationPainter { context, lineStyle().textDecorationsInEffect(), renderer(), isFirstLine(), lineFont(), markedText.style.textDecorationStyles }; 1094 1094 decorationPainter.setInlineTextBox(this); 1095 decorationPainter.setFont(lineFont());1096 1095 decorationPainter.setWidth(snappedSelectionRect.width()); 1097 decorationPainter.setBaseline(lineStyle().fontMetrics().ascent());1098 1096 decorationPainter.setIsHorizontal(isHorizontal()); 1099 1097 if (markedText.style.textShadow) { … … 1201 1199 context.setStrokeColor(underlineColor); 1202 1200 context.setStrokeThickness(lineThickness); 1203 context.drawLineForText(Float Point(boxOrigin.x() + start, boxOrigin.y() + logicalHeight() - lineThickness), width, renderer().document().printing());1201 context.drawLineForText(FloatRect(boxOrigin.x() + start, boxOrigin.y() + logicalHeight() - lineThickness, width, lineThickness), renderer().document().printing()); 1204 1202 } 1205 1203 -
trunk/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp
r234619 r237844 98 98 const RenderText* textRenderer = childrenOfType<RenderText>(flow).first(); 99 99 if (textRenderer) { 100 textDecorationPainter.emplace(paintInfo.context(), style.textDecorationsInEffect(), *textRenderer, false); 101 textDecorationPainter->setFont(style.fontCascade()); 102 textDecorationPainter->setBaseline(style.fontMetrics().ascent()); 100 textDecorationPainter.emplace(paintInfo.context(), style.textDecorationsInEffect(), *textRenderer, false, style.fontCascade()); 103 101 } 104 102 } -
trunk/Source/WebCore/rendering/TextDecorationPainter.cpp
r235560 r237844 82 82 * step 83 83 */ 84 static void strokeWavyTextDecoration(GraphicsContext& context, const Float Point& start, const FloatPoint& end, float strokeThickness, float fontSize)85 { 86 FloatPoint p1 = start;87 FloatPoint p2 = end;88 context.adjustLineToPixelBoundaries(p1, p2, strokeThickness, context.strokeStyle());84 static void strokeWavyTextDecoration(GraphicsContext& context, const FloatRect& rect, float fontSize) 85 { 86 FloatPoint p1 = rect.minXMinYCorner(); 87 FloatPoint p2 = rect.maxXMinYCorner(); 88 context.adjustLineToPixelBoundaries(p1, p2, rect.height(), context.strokeStyle()); 89 89 90 90 Path path; 91 91 path.moveTo(p1); 92 92 93 float controlPointDistance; 94 float step; 95 getWavyStrokeParameters(fontSize, controlPointDistance, step); 96 97 bool isVerticalLine = (p1.x() == p2.x()); 98 99 if (isVerticalLine) { 100 ASSERT(p1.x() == p2.x()); 101 102 float xAxis = p1.x(); 103 float y1; 104 float y2; 105 106 if (p1.y() < p2.y()) { 107 y1 = p1.y(); 108 y2 = p2.y(); 109 } else { 110 y1 = p2.y(); 111 y2 = p1.y(); 112 } 113 114 adjustStepToDecorationLength(step, controlPointDistance, y2 - y1); 115 FloatPoint controlPoint1(xAxis + controlPointDistance, 0); 116 FloatPoint controlPoint2(xAxis - controlPointDistance, 0); 117 118 for (float y = y1; y + 2 * step <= y2;) { 119 controlPoint1.setY(y + step); 120 controlPoint2.setY(y + step); 121 y += 2 * step; 122 path.addBezierCurveTo(controlPoint1, controlPoint2, FloatPoint(xAxis, y)); 123 } 124 } else { 125 ASSERT(p1.y() == p2.y()); 126 127 float yAxis = p1.y(); 128 float x1; 129 float x2; 130 131 if (p1.x() < p2.x()) { 132 x1 = p1.x(); 133 x2 = p2.x(); 134 } else { 135 x1 = p2.x(); 136 x2 = p1.x(); 137 } 138 139 adjustStepToDecorationLength(step, controlPointDistance, x2 - x1); 140 FloatPoint controlPoint1(0, yAxis + controlPointDistance); 141 FloatPoint controlPoint2(0, yAxis - controlPointDistance); 142 143 for (float x = x1; x + 2 * step <= x2;) { 144 controlPoint1.setX(x + step); 145 controlPoint2.setX(x + step); 146 x += 2 * step; 147 path.addBezierCurveTo(controlPoint1, controlPoint2, FloatPoint(x, yAxis)); 148 } 93 auto wavyStrokeParameters = getWavyStrokeParameters(fontSize); 94 95 ASSERT(p1.y() == p2.y()); 96 97 float yAxis = p1.y(); 98 float x1 = std::min(p1.x(), p2.x()); 99 float x2 = std::max(p1.x(), p2.x()); 100 101 adjustStepToDecorationLength(wavyStrokeParameters.step, wavyStrokeParameters.controlPointDistance, x2 - x1); 102 FloatPoint controlPoint1(0, yAxis + wavyStrokeParameters.controlPointDistance); 103 FloatPoint controlPoint2(0, yAxis - wavyStrokeParameters.controlPointDistance); 104 105 for (float x = x1; x + 2 * wavyStrokeParameters.step <= x2;) { 106 controlPoint1.setX(x + wavyStrokeParameters.step); 107 controlPoint2.setX(x + wavyStrokeParameters.step); 108 x += 2 * wavyStrokeParameters.step; 109 path.addBezierCurveTo(controlPoint1, controlPoint2, FloatPoint(x, yAxis)); 149 110 } 150 111 151 112 context.setShouldAntialias(true); 113 auto strokeThickness = context.strokeThickness(); 114 context.setStrokeThickness(rect.height()); 152 115 context.strokePath(path); 116 context.setStrokeThickness(strokeThickness); 153 117 } 154 118 … … 203 167 204 168 return result; 205 }206 207 static void drawSkipInkUnderline(GraphicsContext& context, const FontCascade& font, const TextRun& textRun, const FloatPoint& textOrigin, const FloatPoint& localOrigin,208 float underlineOffset, float width, bool isPrinting, bool doubleLines, StrokeStyle strokeStyle)209 {210 FloatPoint adjustedLocalOrigin = localOrigin;211 adjustedLocalOrigin.move(0, underlineOffset);212 FloatRect underlineBoundingBox = context.computeUnderlineBoundsForText(adjustedLocalOrigin, width, isPrinting);213 DashArray intersections = font.dashesForIntersectionsWithRect(textRun, textOrigin, underlineBoundingBox);214 DashArray a = translateIntersectionPointsToSkipInkBoundaries(intersections, underlineBoundingBox.height(), width);215 ASSERT(!(a.size() % 2));216 context.drawLinesForText(adjustedLocalOrigin, a, isPrinting, doubleLines, strokeStyle);217 169 } 218 170 #endif … … 248 200 } 249 201 250 TextDecorationPainter::TextDecorationPainter(GraphicsContext& context, OptionSet<TextDecoration> decorations, const RenderText& renderer, bool isFirstLine, std::optional<Styles> styles)202 TextDecorationPainter::TextDecorationPainter(GraphicsContext& context, OptionSet<TextDecoration> decorations, const RenderText& renderer, bool isFirstLine, const FontCascade& font, std::optional<Styles> styles) 251 203 : m_context { context } 252 204 , m_decorations { decorations } 253 205 , m_wavyOffset { wavyOffsetFromDecoration() } 254 206 , m_isPrinting { renderer.document().printing() } 207 , m_font { font } 255 208 , m_styles { styles ? *WTFMove(styles) : stylesForRenderer(renderer, decorations, isFirstLine, PseudoId::None) } 256 209 , m_lineStyle { isFirstLine ? renderer.firstLineStyle() : renderer.style() } … … 264 217 UNUSED_PARAM(textOrigin); 265 218 #endif 266 ASSERT(m_font);219 const auto& fontMetrics = m_lineStyle.fontMetrics(); 267 220 float textDecorationThickness = textDecorationStrokeThickness(m_lineStyle.computedFontPixelSize()); 268 m_context.setStrokeThickness(textDecorationThickness);269 221 FloatPoint localOrigin = boxOrigin; 270 222 271 auto paintDecoration = [&] ( OptionSet<TextDecoration> decoration, TextDecorationStyle style, const Color& color, const FloatPoint& start, const FloatPoint& end, int offset) {223 auto paintDecoration = [&] (TextDecoration decoration, TextDecorationStyle style, const Color& color, const FloatRect& rect) { 272 224 m_context.setStrokeColor(color); 273 225 … … 275 227 276 228 if (style == TextDecorationStyle::Wavy) 277 strokeWavyTextDecoration(m_context, start, end, textDecorationThickness, m_lineStyle.computedFontPixelSize());229 strokeWavyTextDecoration(m_context, rect, m_lineStyle.computedFontPixelSize()); 278 230 else if (decoration == TextDecoration::Underline || decoration == TextDecoration::Overline) { 279 231 #if ENABLE(CSS3_TEXT_DECORATION_SKIP_INK) 280 232 if ((m_lineStyle.textDecorationSkip() == TextDecorationSkip::Ink || m_lineStyle.textDecorationSkip() == TextDecorationSkip::Auto) && m_isHorizontal) { 281 if (!m_context.paintingDisabled()) 282 drawSkipInkUnderline(m_context, *m_font, textRun, textOrigin, localOrigin, offset, m_width, m_isPrinting, style == TextDecorationStyle::Double, strokeStyle); 233 if (!m_context.paintingDisabled()) { 234 FloatRect underlineBoundingBox = m_context.computeUnderlineBoundsForText(rect, m_isPrinting); 235 DashArray intersections = m_font.dashesForIntersectionsWithRect(textRun, textOrigin, underlineBoundingBox); 236 DashArray boundaries = translateIntersectionPointsToSkipInkBoundaries(intersections, underlineBoundingBox.height(), rect.width()); 237 ASSERT(!(boundaries.size() % 2)); 238 // We don't use underlineBoundingBox here because drawLinesForText() will run computeUnderlineBoundsForText() internally. 239 m_context.drawLinesForText(rect.location(), rect.height(), boundaries, m_isPrinting, style == TextDecorationStyle::Double, strokeStyle); 240 } 283 241 } else 284 242 // FIXME: Need to support text-decoration-skip: none. 285 243 #endif 286 m_context.drawLineForText( start, m_width, m_isPrinting, style == TextDecorationStyle::Double, strokeStyle);244 m_context.drawLineForText(rect, m_isPrinting, style == TextDecorationStyle::Double, strokeStyle); 287 245 288 246 } else { 289 247 ASSERT(decoration == TextDecoration::LineThrough); 290 m_context.drawLineForText( start, m_width, m_isPrinting, style == TextDecorationStyle::Double, strokeStyle);248 m_context.drawLineForText(rect, m_isPrinting, style == TextDecorationStyle::Double, strokeStyle); 291 249 } 292 250 }; … … 299 257 bool clipping = !areLinesOpaque && m_shadow && m_shadow->next(); 300 258 if (clipping) { 301 FloatRect clipRect(localOrigin, FloatSize(m_width, m_baseline+ 2));259 FloatRect clipRect(localOrigin, FloatSize(m_width, fontMetrics.ascent() + 2)); 302 260 for (const ShadowData* shadow = m_shadow; shadow; shadow = shadow->next()) { 303 261 int shadowExtent = shadow->paintingExtent(); 304 FloatRect shadowRect(localOrigin, FloatSize(m_width, m_baseline+ 2));262 FloatRect shadowRect(localOrigin, FloatSize(m_width, fontMetrics.ascent() + 2)); 305 263 shadowRect.inflate(shadowExtent); 306 264 int shadowX = m_isHorizontal ? shadow->x() : shadow->y(); … … 312 270 m_context.save(); 313 271 m_context.clip(clipRect); 314 extraOffset += m_baseline+ 2;272 extraOffset += fontMetrics.ascent() + 2; 315 273 localOrigin.move(0, extraOffset); 316 274 } … … 338 296 int offset = computeUnderlineOffset(m_lineStyle.textUnderlinePosition(), m_lineStyle.fontMetrics(), m_inlineTextBox, textDecorationThickness); 339 297 float wavyOffset = m_styles.underlineStyle == TextDecorationStyle::Wavy ? m_wavyOffset : 0; 340 Float Point start = localOrigin + FloatSize(0, offset + wavyOffset);341 FloatPoint end = localOrigin + FloatSize(m_width, offset + wavyOffset);342 paintDecoration(TextDecoration::Underline, m_styles.underlineStyle, m_styles.underlineColor, start, end, offset);298 FloatRect rect(localOrigin, FloatSize(m_width, textDecorationThickness)); 299 rect.move(0, offset + wavyOffset); 300 paintDecoration(TextDecoration::Underline, m_styles.underlineStyle, m_styles.underlineColor, rect); 343 301 } 344 302 if (m_decorations.contains(TextDecoration::Overline)) { 345 303 float wavyOffset = m_styles.overlineStyle == TextDecorationStyle::Wavy ? m_wavyOffset : 0; 346 Float Point start = localOrigin - FloatSize(0, wavyOffset);347 FloatPoint end = localOrigin + FloatSize(m_width, -wavyOffset);348 paintDecoration(TextDecoration::Overline, m_styles.overlineStyle, m_styles.overlineColor, start, end, 0);304 FloatRect rect(localOrigin, FloatSize(m_width, textDecorationThickness)); 305 rect.move(0, -wavyOffset); 306 paintDecoration(TextDecoration::Overline, m_styles.overlineStyle, m_styles.overlineColor, rect); 349 307 } 350 308 if (m_decorations.contains(TextDecoration::LineThrough)) { 351 Float Point start = localOrigin + FloatSize(0, 2 * m_baseline / 3);352 FloatPoint end = localOrigin + FloatSize(m_width, 2 * m_baseline/ 3);353 paintDecoration(TextDecoration::LineThrough, m_styles.linethroughStyle, m_styles.linethroughColor, start, end, 0);309 FloatRect rect(localOrigin, FloatSize(m_width, textDecorationThickness)); 310 rect.move(0, 2 * fontMetrics.floatAscent() / 3); 311 paintDecoration(TextDecoration::LineThrough, m_styles.linethroughStyle, m_styles.linethroughColor, rect); 354 312 } 355 313 } while (shadow); -
trunk/Source/WebCore/rendering/TextDecorationPainter.h
r232229 r237844 43 43 public: 44 44 struct Styles; 45 TextDecorationPainter(GraphicsContext&, OptionSet<TextDecoration> decorations, const RenderText&, bool isFirstLine, std::optional<Styles> = std::nullopt);45 TextDecorationPainter(GraphicsContext&, OptionSet<TextDecoration> decorations, const RenderText&, bool isFirstLine, const FontCascade&, std::optional<Styles> = std::nullopt); 46 46 47 47 void setInlineTextBox(const InlineTextBox* inlineTextBox) { m_inlineTextBox = inlineTextBox; } 48 void setFont(const FontCascade& font) { m_font = &font; }49 48 void setIsHorizontal(bool isHorizontal) { m_isHorizontal = isHorizontal; } 50 49 void setWidth(float width) { m_width = width; } 51 void setBaseline(float baseline) { m_baseline = baseline; }52 50 void setTextShadow(const ShadowData* textShadow) { m_shadow = textShadow; } 53 51 void setShadowColorFilter(const FilterOperations* colorFilter) { m_shadowColorFilter = colorFilter; } … … 73 71 float m_wavyOffset; 74 72 float m_width { 0 }; 75 float m_baseline { 0 };76 73 FloatPoint m_boxOrigin; 77 74 bool m_isPrinting; … … 80 77 const FilterOperations* m_shadowColorFilter { nullptr }; 81 78 const InlineTextBox* m_inlineTextBox { nullptr }; 82 const FontCascade * m_font { nullptr };79 const FontCascade& m_font; 83 80 84 81 Styles m_styles; -
trunk/Source/WebCore/style/InlineTextBoxStyle.cpp
r237835 r237844 84 84 } 85 85 86 void getWavyStrokeParameters(float fontSize, float& controlPointDistance, float& step)86 WavyStrokeParameters getWavyStrokeParameters(float fontSize) 87 87 { 88 // Distance between decoration's axis and Bezier curve's control points. 89 // The height of the curve is based on this distance. Increases the curve's height 90 // as fontSize increases to make the curve look better. 91 controlPointDistance = 0.09375 * fontSize; 92 93 // Increment used to form the diamond shape between start point (p1), control 94 // points and end point (p2) along the axis of the decoration. The curve gets 95 // wider as font size increases. 96 step = fontSize / 4.5; 88 WavyStrokeParameters result; 89 // More information is in the WavyStrokeParameters definition. 90 result.controlPointDistance = fontSize * 1.5 / 16; 91 result.step = fontSize / 4.5; 92 return result; 97 93 } 98 94 … … 111 107 112 108 float strokeThickness = textDecorationStrokeThickness(lineStyle.computedFontPixelSize()); 113 float controlPointDistance = 0; 114 float step; 109 WavyStrokeParameters wavyStrokeParameters; 115 110 float wavyOffset = 0; 116 111 … … 120 115 121 116 if (decorationStyle == TextDecorationStyle::Wavy) { 122 getWavyStrokeParameters(lineStyle.computedFontPixelSize(), controlPointDistance, step);117 wavyStrokeParameters = getWavyStrokeParameters(lineStyle.computedFontPixelSize()); 123 118 wavyOffset = wavyOffsetFromDecoration(); 124 119 overflowResult.left = strokeThickness; … … 132 127 underlineOffset += computeUnderlineOffset(lineStyle.textUnderlinePosition(), lineStyle.fontMetrics(), inlineTextBox, strokeThickness); 133 128 if (decorationStyle == TextDecorationStyle::Wavy) { 134 extendIntToFloat(overflowResult.bottom, underlineOffset + wavyOffset + controlPointDistance + strokeThickness - height);135 extendIntToFloat(overflowResult.top, -(underlineOffset + wavyOffset - controlPointDistance - strokeThickness));129 extendIntToFloat(overflowResult.bottom, underlineOffset + wavyOffset + wavyStrokeParameters.controlPointDistance + strokeThickness - height); 130 extendIntToFloat(overflowResult.top, -(underlineOffset + wavyOffset - wavyStrokeParameters.controlPointDistance - strokeThickness)); 136 131 } else { 137 132 extendIntToFloat(overflowResult.bottom, underlineOffset + strokeThickness - height); … … 141 136 if (decoration & TextDecoration::Overline) { 142 137 if (decorationStyle == TextDecorationStyle::Wavy) { 143 extendIntToFloat(overflowResult.bottom, -wavyOffset + controlPointDistance + strokeThickness - height);144 extendIntToFloat(overflowResult.top, wavyOffset + controlPointDistance + strokeThickness);138 extendIntToFloat(overflowResult.bottom, -wavyOffset + wavyStrokeParameters.controlPointDistance + strokeThickness - height); 139 extendIntToFloat(overflowResult.top, wavyOffset + wavyStrokeParameters.controlPointDistance + strokeThickness); 145 140 } else { 146 141 extendIntToFloat(overflowResult.bottom, strokeThickness - height); … … 151 146 float baseline = lineStyle.fontMetrics().floatAscent(); 152 147 if (decorationStyle == TextDecorationStyle::Wavy) { 153 extendIntToFloat(overflowResult.bottom, 2 * baseline / 3 + controlPointDistance + strokeThickness - height);154 extendIntToFloat(overflowResult.top, -(2 * baseline / 3 - controlPointDistance - strokeThickness));148 extendIntToFloat(overflowResult.bottom, 2 * baseline / 3 + wavyStrokeParameters.controlPointDistance + strokeThickness - height); 149 extendIntToFloat(overflowResult.top, -(2 * baseline / 3 - wavyStrokeParameters.controlPointDistance - strokeThickness)); 155 150 } else { 156 151 extendIntToFloat(overflowResult.bottom, 2 * baseline / 3 + strokeThickness - height); -
trunk/Source/WebCore/style/InlineTextBoxStyle.h
r237835 r237844 45 45 } 46 46 47 struct WavyStrokeParameters { 48 // Distance between decoration's axis and Bezier curve's control points. 49 // The height of the curve is based on this distance. Increases the curve's height 50 // as fontSize increases to make the curve look better. 51 float controlPointDistance { 0 }; 52 53 // Increment used to form the diamond shape between start point (p1), control 54 // points and end point (p2) along the axis of the decoration. The curve gets 55 // wider as font size increases. 56 float step { 0 }; 57 }; 58 WavyStrokeParameters getWavyStrokeParameters(float fontSize); 47 59 GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, const InlineTextBox*); 48 void getWavyStrokeParameters(float fontSize, float& controlPointDistance, float& step);49 60 int computeUnderlineOffset(TextUnderlinePosition, const FontMetrics&, const InlineTextBox*, int textDecorationThickness); 50 61
Note: See TracChangeset
for help on using the changeset viewer.