Index: third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp |
diff --git a/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp b/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp |
index 74ab1cdcb364fac4aa096e894b0cafe327e13678..8782e0b7c67e0e0a1aee1efedb9b4b85148ef5ab 100644 |
--- a/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp |
+++ b/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp |
@@ -22,6 +22,327 @@ |
namespace blink { |
+static int computeUnderlineOffset(const TextUnderlinePosition underlinePosition, |
+ const FontMetrics& fontMetrics, |
+ const InlineTextBox* inlineTextBox, |
+ const float textDecorationThickness) { |
+ // Compute the gap between the font and the underline. Use at least one |
+ // pixel gap, if underline is thick then use a bigger gap. |
+ int gap = 0; |
+ |
+ // Underline position of zero means draw underline on Baseline Position, |
+ // in Blink we need at least 1-pixel gap to adding following check. |
+ // Positive underline Position means underline should be drawn above baselin e |
+ // and negative value means drawing below baseline, negating the value as in |
+ // Blink |
+ // downward Y-increases. |
+ |
+ if (fontMetrics.underlinePosition()) |
+ gap = -fontMetrics.underlinePosition(); |
+ else |
+ gap = std::max<int>(1, ceilf(textDecorationThickness / 2.f)); |
+ |
+ // FIXME: We support only horizontal text for now. |
+ switch (underlinePosition) { |
+ case TextUnderlinePositionAuto: |
+ return fontMetrics.ascent() + |
+ gap; // Position underline near the alphabetic baseline. |
+ case TextUnderlinePositionUnder: { |
+ // Position underline relative to the under edge of the lowest element's |
+ // content box. |
+ const LayoutUnit offset = |
+ inlineTextBox->root().maxLogicalTop() - inlineTextBox->logicalTop(); |
+ if (offset > 0) |
+ return (inlineTextBox->logicalHeight() + gap + offset).toInt(); |
+ return (inlineTextBox->logicalHeight() + gap).toInt(); |
+ } |
+ } |
+ |
+ NOTREACHED(); |
+ return fontMetrics.ascent() + gap; |
+} |
+ |
+static bool shouldSetDecorationAntialias( |
+ const Vector<AppliedTextDecoration>& decorations) { |
+ for (const AppliedTextDecoration& decoration : decorations) { |
+ TextDecorationStyle decorationStyle = decoration.style(); |
+ if (decorationStyle == TextDecorationStyleDotted || |
+ decorationStyle == TextDecorationStyleDashed) |
+ return true; |
+ } |
+ return false; |
+} |
+ |
+static StrokeStyle textDecorationStyleToStrokeStyle( |
+ TextDecorationStyle decorationStyle) { |
+ StrokeStyle strokeStyle = SolidStroke; |
+ switch (decorationStyle) { |
+ case TextDecorationStyleSolid: |
+ strokeStyle = SolidStroke; |
+ break; |
+ case TextDecorationStyleDouble: |
+ strokeStyle = DoubleStroke; |
+ break; |
+ case TextDecorationStyleDotted: |
+ strokeStyle = DottedStroke; |
+ break; |
+ case TextDecorationStyleDashed: |
+ strokeStyle = DashedStroke; |
+ break; |
+ case TextDecorationStyleWavy: |
+ strokeStyle = WavyStroke; |
+ break; |
+ } |
+ |
+ return strokeStyle; |
+} |
+ |
+static void adjustStepToDecorationLength(float& step, |
+ float& controlPointDistance, |
+ float length) { |
+ DCHECK_GT(step, 0); |
+ |
+ if (length <= 0) |
+ return; |
+ |
+ unsigned stepCount = static_cast<unsigned>(length / step); |
+ |
+ // Each Bezier curve starts at the same pixel that the previous one |
+ // ended. We need to subtract (stepCount - 1) pixels when calculating the |
+ // length covered to account for that. |
+ float uncoveredLength = length - (stepCount * step - (stepCount - 1)); |
+ float adjustment = uncoveredLength / stepCount; |
+ step += adjustment; |
+ controlPointDistance += adjustment; |
+} |
+ |
+class AppliedDecorationPainter final { |
+ STACK_ALLOCATED(); |
+ |
+ public: |
+ AppliedDecorationPainter(GraphicsContext& context, |
+ FloatPoint startPoint, |
+ float width, |
+ const AppliedTextDecoration& decoration, |
+ float thickness, |
+ float doubleOffset, |
+ int wavyOffsetFactor, |
+ bool antialiasDecoration) |
+ : m_context(context), |
+ m_startPoint(startPoint), |
+ m_width(width), |
+ m_decoration(decoration), |
+ m_thickness(thickness), |
+ m_doubleOffset(doubleOffset), |
+ m_wavyOffsetFactor(wavyOffsetFactor), |
+ m_shouldAntialias(antialiasDecoration){}; |
+ |
+ void paint(); |
+ FloatRect decorationBounds(); |
+ |
+ private: |
+ void strokeWavyTextDecoration(); |
+ |
+ Path prepareWavyStrokePath(); |
+ Path prepareDottedDashedStrokePath(); |
+ |
+ GraphicsContext& m_context; |
+ FloatPoint m_startPoint; |
+ float m_width; |
+ const AppliedTextDecoration& m_decoration; |
+ float m_thickness; |
+ const float m_doubleOffset; |
+ const int m_wavyOffsetFactor; |
+ bool m_shouldAntialias; |
+}; |
+ |
+Path AppliedDecorationPainter::prepareDottedDashedStrokePath() { |
+ // These coordinate transforms need to match what's happening in |
+ // GraphicsContext's drawLineForText and drawLine. |
+ int y = floorf(m_startPoint.y() + std::max<float>(m_thickness / 2.0f, 0.5f)); |
+ Path strokePath; |
+ FloatPoint roundedStartPoint(m_startPoint.x(), y); |
+ FloatPoint roundedEndPoint(roundedStartPoint + FloatPoint(m_width, 0)); |
+ m_context.adjustLineToPixelBoundaries(roundedStartPoint, roundedEndPoint, |
+ roundf(m_thickness), |
+ m_context.getStrokeStyle()); |
+ strokePath.moveTo(roundedStartPoint); |
+ strokePath.addLineTo(roundedEndPoint); |
+ return strokePath; |
+} |
+ |
+FloatRect AppliedDecorationPainter::decorationBounds() { |
+ StrokeData strokeData; |
+ strokeData.setThickness(m_thickness); |
+ |
+ switch (m_decoration.style()) { |
+ case TextDecorationStyleDotted: |
+ case TextDecorationStyleDashed: { |
+ strokeData.setStyle( |
+ textDecorationStyleToStrokeStyle(m_decoration.style())); |
+ return prepareDottedDashedStrokePath().strokeBoundingRect( |
+ strokeData, Path::BoundsType::Exact); |
+ } |
+ case TextDecorationStyleWavy: |
+ return prepareWavyStrokePath().strokeBoundingRect( |
+ strokeData, Path::BoundsType::Exact); |
+ break; |
+ case TextDecorationStyleDouble: |
+ if (m_doubleOffset > 0) { |
+ return FloatRect(m_startPoint.x(), m_startPoint.y(), m_width, |
+ m_doubleOffset + m_thickness); |
+ } |
+ return FloatRect(m_startPoint.x(), m_startPoint.y() + m_doubleOffset, |
+ m_width, -m_doubleOffset + m_thickness); |
+ break; |
+ case TextDecorationStyleSolid: |
+ return FloatRect(m_startPoint.x(), m_startPoint.y(), m_width, |
+ m_thickness); |
+ default: |
+ break; |
+ } |
+ NOTREACHED(); |
+ return FloatRect(); |
+} |
+ |
+void AppliedDecorationPainter::paint() { |
+ m_context.setStrokeStyle( |
+ textDecorationStyleToStrokeStyle(m_decoration.style())); |
+ m_context.setStrokeColor(m_decoration.color()); |
+ |
+ switch (m_decoration.style()) { |
+ case TextDecorationStyleWavy: |
+ strokeWavyTextDecoration(); |
+ break; |
+ case TextDecorationStyleDotted: |
+ case TextDecorationStyleDashed: |
+ m_context.setShouldAntialias(m_shouldAntialias); |
+ // Fall through |
+ default: |
+ m_context.drawLineForText(m_startPoint, m_width); |
+ |
+ if (m_decoration.style() == TextDecorationStyleDouble) { |
+ m_context.drawLineForText(m_startPoint + FloatPoint(0, m_doubleOffset), |
+ m_width); |
+ } |
+ } |
+} |
+ |
+void AppliedDecorationPainter::strokeWavyTextDecoration() { |
+ m_context.setShouldAntialias(true); |
+ m_context.strokePath(prepareWavyStrokePath()); |
+} |
+ |
+/* |
+ * Prepare a path for a cubic Bezier curve and repeat the same pattern long the |
+ * the decoration's axis. The start point (p1), controlPoint1, controlPoint2 |
+ * and end point (p2) of the Bezier curve form a diamond shape: |
+ * |
+ * step |
+ * |-----------| |
+ * |
+ * controlPoint1 |
+ * + |
+ * |
+ * |
+ * . . |
+ * . . |
+ * . . |
+ * (x1, y1) p1 + . + p2 (x2, y2) - <--- Decoration's axis |
+ * . . | |
+ * . . | |
+ * . . | controlPointDistance |
+ * | |
+ * | |
+ * + - |
+ * controlPoint2 |
+ * |
+ * |-----------| |
+ * step |
+ */ |
+Path AppliedDecorationPainter::prepareWavyStrokePath() { |
+ FloatPoint p1(m_startPoint + |
+ FloatPoint(0, m_doubleOffset * m_wavyOffsetFactor)); |
+ FloatPoint p2(m_startPoint + |
+ FloatPoint(m_width, m_doubleOffset * m_wavyOffsetFactor)); |
+ |
+ m_context.adjustLineToPixelBoundaries(p1, p2, m_thickness, |
+ m_context.getStrokeStyle()); |
+ |
+ Path path; |
+ path.moveTo(p1); |
+ |
+ // Distance between decoration's axis and Bezier curve's control points. |
+ // The height of the curve is based on this distance. Use a minimum of 6 |
+ // pixels distance since |
+ // the actual curve passes approximately at half of that distance, that is 3 |
+ // pixels. |
+ // The minimum height of the curve is also approximately 3 pixels. Increases |
+ // the curve's height |
+ // as strockThickness increases to make the curve looks better. |
+ float controlPointDistance = 3 * std::max<float>(2, m_thickness); |
+ |
+ // Increment used to form the diamond shape between start point (p1), control |
+ // points and end point (p2) along the axis of the decoration. Makes the |
+ // curve wider as strockThickness increases to make the curve looks better. |
+ float step = 2 * std::max<float>(2, m_thickness); |
+ |
+ bool isVerticalLine = (p1.x() == p2.x()); |
+ |
+ if (isVerticalLine) { |
+ DCHECK(p1.x() == p2.x()); |
+ |
+ float xAxis = p1.x(); |
+ float y1; |
+ float y2; |
+ |
+ 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 { |
+ DCHECK(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)); |
+ } |
+ } |
+ return path; |
+} |
+ |
typedef WTF::HashMap<const InlineTextBox*, TextBlobPtr> |
InlineTextBoxBlobCacheMap; |
static InlineTextBoxBlobCacheMap* gTextBlobCache; |
@@ -288,11 +609,14 @@ void InlineTextBoxPainter::paint(const PaintInfo& paintInfo, |
if (styleToUse.textDecorationsInEffect() != TextDecorationNone && |
!paintSelectedTextOnly) { |
GraphicsContextStateSaver stateSaver(context, false); |
+ |
TextPainter::updateGraphicsContext( |
context, textStyle, m_inlineTextBox.isHorizontal(), stateSaver); |
+ |
if (combinedText) |
context.concatCTM(TextPainter::rotation(boxRect, TextPainter::Clockwise)); |
- paintDecorations(paintInfo, boxOrigin, styleToUse.appliedTextDecorations()); |
+ paintDecorations(textPainter, paintInfo, boxOrigin, |
+ styleToUse.appliedTextDecorations()); |
if (combinedText) |
context.concatCTM( |
TextPainter::rotation(boxRect, TextPainter::Counterclockwise)); |
@@ -683,240 +1007,8 @@ void InlineTextBoxPainter::expandToIncludeNewlineForSelection( |
rect.expand(outsets); |
} |
-static int computeUnderlineOffset(const TextUnderlinePosition underlinePosition, |
- const FontMetrics& fontMetrics, |
- const InlineTextBox* inlineTextBox, |
- const float textDecorationThickness) { |
- // Compute the gap between the font and the underline. Use at least one |
- // pixel gap, if underline is thick then use a bigger gap. |
- int gap = 0; |
- |
- // Underline position of zero means draw underline on Baseline Position, |
- // in Blink we need at least 1-pixel gap to adding following check. |
- // Positive underline Position means underline should be drawn above baselin e |
- // and negative value means drawing below baseline, negating the value as in |
- // Blink downward Y-increases. |
- |
- if (fontMetrics.underlinePosition()) |
- gap = -fontMetrics.underlinePosition(); |
- else |
- gap = std::max<int>(1, ceilf(textDecorationThickness / 2.f)); |
- |
- // FIXME: We support only horizontal text for now. |
- switch (underlinePosition) { |
- case TextUnderlinePositionAuto: |
- return fontMetrics.ascent() + |
- gap; // Position underline near the alphabetic baseline. |
- case TextUnderlinePositionUnder: { |
- // Position underline relative to the under edge of the lowest element's |
- // content box. |
- const LayoutUnit offset = |
- inlineTextBox->root().maxLogicalTop() - inlineTextBox->logicalTop(); |
- if (offset > 0) |
- return (inlineTextBox->logicalHeight() + gap + offset).toInt(); |
- return (inlineTextBox->logicalHeight() + gap).toInt(); |
- } |
- } |
- |
- ASSERT_NOT_REACHED(); |
- return fontMetrics.ascent() + gap; |
-} |
- |
-static bool shouldSetDecorationAntialias( |
- const Vector<AppliedTextDecoration>& decorations) { |
- for (const AppliedTextDecoration& decoration : decorations) { |
- TextDecorationStyle decorationStyle = decoration.style(); |
- if (decorationStyle == TextDecorationStyleDotted || |
- decorationStyle == TextDecorationStyleDashed) |
- return true; |
- } |
- return false; |
-} |
- |
-static StrokeStyle textDecorationStyleToStrokeStyle( |
- TextDecorationStyle decorationStyle) { |
- StrokeStyle strokeStyle = SolidStroke; |
- switch (decorationStyle) { |
- case TextDecorationStyleSolid: |
- strokeStyle = SolidStroke; |
- break; |
- case TextDecorationStyleDouble: |
- strokeStyle = DoubleStroke; |
- break; |
- case TextDecorationStyleDotted: |
- strokeStyle = DottedStroke; |
- break; |
- case TextDecorationStyleDashed: |
- strokeStyle = DashedStroke; |
- break; |
- case TextDecorationStyleWavy: |
- strokeStyle = WavyStroke; |
- break; |
- } |
- |
- return strokeStyle; |
-} |
- |
-static void adjustStepToDecorationLength(float& step, |
- float& controlPointDistance, |
- float length) { |
- DCHECK_GT(step, 0); |
- |
- if (length <= 0) |
- return; |
- |
- unsigned stepCount = static_cast<unsigned>(length / step); |
- |
- // Each Bezier curve starts at the same pixel that the previous one |
- // ended. We need to subtract (stepCount - 1) pixels when calculating the |
- // length covered to account for that. |
- float uncoveredLength = length - (stepCount * step - (stepCount - 1)); |
- float adjustment = uncoveredLength / stepCount; |
- step += adjustment; |
- controlPointDistance += adjustment; |
-} |
- |
-/* |
- * Draw one cubic Bezier curve and repeat the same pattern long the the |
- * decoration's axis. The start point (p1), controlPoint1, controlPoint2 and |
- * end point (p2) of the Bezier curve form a diamond shape: |
- * |
- * step |
- * |-----------| |
- * |
- * controlPoint1 |
- * + |
- * |
- * |
- * . . |
- * . . |
- * . . |
- * (x1, y1) p1 + . + p2 (x2, y2) - <--- Decoration's axis |
- * . . | |
- * . . | |
- * . . | controlPointDistance |
- * | |
- * | |
- * + - |
- * controlPoint2 |
- * |
- * |-----------| |
- * step |
- */ |
-static void strokeWavyTextDecoration(GraphicsContext& context, |
- FloatPoint p1, |
- FloatPoint p2, |
- float strokeThickness) { |
- context.adjustLineToPixelBoundaries(p1, p2, strokeThickness, |
- context.getStrokeStyle()); |
- |
- Path path; |
- path.moveTo(p1); |
- |
- // Distance between decoration's axis and Bezier curve's control points. |
- // The height of the curve is based on this distance. Use a minimum of 6 |
- // pixels distance since the actual curve passes approximately at half of that |
- // distance, that is 3 pixels. The minimum height of the curve is also |
- // approximately 3 pixels. Increases the curve's height |
- // as strockThickness increases to make the curve looks better. |
- float controlPointDistance = 3 * std::max<float>(2, strokeThickness); |
- |
- // Increment used to form the diamond shape between start point (p1), control |
- // points and end point (p2) along the axis of the decoration. Makes the |
- // curve wider as strockThickness increases to make the curve looks better. |
- float step = 2 * std::max<float>(2, strokeThickness); |
- |
- bool isVerticalLine = (p1.x() == p2.x()); |
- |
- if (isVerticalLine) { |
- DCHECK(p1.x() == p2.x()); |
- |
- float xAxis = p1.x(); |
- float y1; |
- float y2; |
- |
- 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 { |
- DCHECK(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)); |
- } |
- } |
- |
- context.setShouldAntialias(true); |
- context.strokePath(path); |
-} |
- |
-static void paintAppliedDecoration(GraphicsContext& context, |
- FloatPoint start, |
- float width, |
- float doubleOffset, |
- int wavyOffsetFactor, |
- AppliedTextDecoration decoration, |
- float thickness, |
- bool antialiasDecoration, |
- bool isPrinting) { |
- context.setStrokeStyle(textDecorationStyleToStrokeStyle(decoration.style())); |
- context.setStrokeColor(decoration.color()); |
- |
- switch (decoration.style()) { |
- case TextDecorationStyleWavy: |
- strokeWavyTextDecoration( |
- context, start + FloatPoint(0, doubleOffset * wavyOffsetFactor), |
- start + FloatPoint(width, doubleOffset * wavyOffsetFactor), |
- thickness); |
- break; |
- case TextDecorationStyleDotted: |
- case TextDecorationStyleDashed: |
- context.setShouldAntialias(antialiasDecoration); |
- // Fall through |
- default: |
- context.drawLineForText(FloatPoint(start), width, isPrinting); |
- |
- if (decoration.style() == TextDecorationStyleDouble) |
- context.drawLineForText(start + FloatPoint(0, doubleOffset), width, |
- isPrinting); |
- } |
-} |
- |
void InlineTextBoxPainter::paintDecorations( |
+ TextPainter& textPainter, |
const PaintInfo& paintInfo, |
const LayoutPoint& boxOrigin, |
const Vector<AppliedTextDecoration>& decorations) { |
@@ -944,15 +1036,13 @@ void InlineTextBoxPainter::paintDecorations( |
localOrigin.move(m_inlineTextBox.logicalWidth() - width, LayoutUnit()); |
} |
- // Use a special function for underlines to get the positioning exactly right. |
- bool isPrinting = paintInfo.isPrinting(); |
- |
LayoutObject& textBoxLayoutObject = inlineLayoutObject(); |
+ |
const ComputedStyle& styleToUse = |
textBoxLayoutObject.styleRef(m_inlineTextBox.isFirstLineStyle()); |
const SimpleFontData* fontData = styleToUse.font().primaryFont(); |
DCHECK(fontData); |
- float baseline = fontData ? fontData->getFontMetrics().ascent() : 0; |
+ float baseline = fontData ? fontData->getFontMetrics().floatAscent() : 0; |
// Set the thick of the line to be 10% (or something else ?)of the computed |
// font size and not less than 1px. Using computedFontSize should take care |
@@ -977,29 +1067,55 @@ void InlineTextBoxPainter::paintDecorations( |
// Offset between lines - always non-zero, so lines never cross each other. |
float doubleOffset = textDecorationThickness + 1.f; |
+ bool skipIntercepts = |
+ styleToUse.getTextDecorationSkip() & TextDecorationSkipInk; |
for (const AppliedTextDecoration& decoration : decorations) { |
TextDecoration lines = decoration.lines(); |
- if (lines & TextDecorationUnderline && fontData) { |
+ if ((lines & TextDecorationUnderline) && fontData) { |
const int underlineOffset = computeUnderlineOffset( |
styleToUse.getTextUnderlinePosition(), fontData->getFontMetrics(), |
&m_inlineTextBox, textDecorationThickness); |
- paintAppliedDecoration( |
+ AppliedDecorationPainter decorationPainter( |
context, FloatPoint(localOrigin) + FloatPoint(0, underlineOffset), |
- width.toFloat(), doubleOffset, 1, decoration, textDecorationThickness, |
- antialiasDecoration, isPrinting); |
+ width.toFloat(), decoration, textDecorationThickness, doubleOffset, 1, |
+ antialiasDecoration); |
+ if (skipIntercepts) { |
+ textPainter.clipDecorationsStripe( |
+ -baseline + decorationPainter.decorationBounds().y() - |
+ FloatPoint(localOrigin).y(), |
+ decorationPainter.decorationBounds().height(), |
+ textDecorationThickness); |
+ } |
+ decorationPainter.paint(); |
} |
if (lines & TextDecorationOverline) { |
- paintAppliedDecoration( |
- context, FloatPoint(localOrigin), width.toFloat(), -doubleOffset, 1, |
- decoration, textDecorationThickness, antialiasDecoration, isPrinting); |
+ AppliedDecorationPainter decorationPainter( |
+ context, FloatPoint(localOrigin), width.toFloat(), decoration, |
+ textDecorationThickness, -doubleOffset, 1, antialiasDecoration); |
+ if (skipIntercepts) { |
+ textPainter.clipDecorationsStripe( |
+ -baseline + decorationPainter.decorationBounds().y() - |
+ FloatPoint(localOrigin).y(), |
+ decorationPainter.decorationBounds().height(), |
+ textDecorationThickness); |
+ } |
+ decorationPainter.paint(); |
} |
if (lines & TextDecorationLineThrough) { |
const float lineThroughOffset = 2 * baseline / 3; |
- paintAppliedDecoration( |
+ AppliedDecorationPainter decorationPainter( |
context, FloatPoint(localOrigin) + FloatPoint(0, lineThroughOffset), |
- width.toFloat(), doubleOffset, 0, decoration, textDecorationThickness, |
- antialiasDecoration, isPrinting); |
+ width.toFloat(), decoration, textDecorationThickness, doubleOffset, 0, |
+ antialiasDecoration); |
+ if (skipIntercepts) { |
+ textPainter.clipDecorationsStripe( |
+ -baseline + decorationPainter.decorationBounds().y() - |
+ FloatPoint(localOrigin).y(), |
+ decorationPainter.decorationBounds().height(), |
+ textDecorationThickness); |
+ } |
+ decorationPainter.paint(); |
} |
} |
} |
@@ -1081,7 +1197,7 @@ void InlineTextBoxPainter::paintCompositionUnderline( |
boxOrigin.x() + start, |
(boxOrigin.y() + m_inlineTextBox.logicalHeight() - lineThickness) |
.toFloat()), |
- width, m_inlineTextBox.getLineLayoutItem().document().printing()); |
+ width); |
} |
void InlineTextBoxPainter::paintTextMatchMarkerForeground( |