Title: [158467] trunk
Revision
158467
Author
commit-qu...@webkit.org
Date
2013-11-01 16:46:54 -0700 (Fri, 01 Nov 2013)

Log Message

Initial implementation of text-decoration-skip ink
https://bugs.webkit.org/show_bug.cgi?id=121806

Patch by Myles C. Maxfield <mmaxfi...@apple.com> on 2013-11-01
Reviewed by Darin Adler.

Source/WebCore:

text-decoration-skip: ink is implemented by the following steps:
1. Before drawing any decorations, figure out the bounding box for the decorations that will be drawn
2. Create an ImageBuffer with these dimensions
3. Draw text into this ImageBuffer with a thicker stroke
4. Apply the ImageBuffer as a mask to the context
5. Draw decorations like normal
6. Clean up

Test: fast/css3-text/css3-text-decoration/text-decoration-skip/text-decoration-skip-ink.html

* platform/graphics/cg/GraphicsContextCG.cpp:
(WebCore::computeLineBoundsAndAntialiasingModeForText): Don't call GraphicsContext::roundToDevicePixels
when painting is disabled
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::paint): Pass the TextPainter to paintDecoration
(WebCore::computeUnderlineOffset): Small cleanup
(WebCore::getWavyStrokeControlPointDistance): Pulling out of strokeWavyTextDecoration()
(WebCore::getWavyStrokeStep): Ditto
(WebCore::strokeWavyTextDecoration): Use the previous 2 functions
(WebCore::getSingleDecorationBoundingBox): Pulling out repeated code into a function
(WebCore::getDecorationBoundingBox): Compute the bounding box for an underline which
hasn't been drawn yet
(WebCore::InlineTextBox::paintDecoration): Construct a mask and apply it to the GraphicsContext
* rendering/InlineTextBox.h: paintDecoration needs the TextPainter
* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::changeRequiresRepaintIfTextOrBorderOrOutline): Redraw the underline when
text-decoration-skip changes

LayoutTests:

Adding a test which draws a very large "p" with text-decoration-skip:ink. The
viewport is restricted to be just hugging the place where an underline would
intersect the descender of the "p". This should look the same as if there was
no underline at all (because of the skipping underline).

* fast/css3-text/css3-text-decoration/text-decoration-skip/text-decoration-skip-ink-expected.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-skip/text-decoration-skip-ink.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (158466 => 158467)


--- trunk/LayoutTests/ChangeLog	2013-11-01 23:38:54 UTC (rev 158466)
+++ trunk/LayoutTests/ChangeLog	2013-11-01 23:46:54 UTC (rev 158467)
@@ -1,3 +1,18 @@
+2013-11-01  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+        Initial implementation of text-decoration-skip ink
+        https://bugs.webkit.org/show_bug.cgi?id=121806
+
+        Reviewed by Darin Adler.
+
+        Adding a test which draws a very large "p" with text-decoration-skip:ink. The
+        viewport is restricted to be just hugging the place where an underline would
+        intersect the descender of the "p". This should look the same as if there was
+        no underline at all (because of the skipping underline).
+
+        * fast/css3-text/css3-text-decoration/text-decoration-skip/text-decoration-skip-ink-expected.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-skip/text-decoration-skip-ink.html: Added.
+
 2013-11-01  Hans Muller  <hmul...@adobe.com>
 
         [CSS Shapes] Fix typo in simple-polygon.js LayoutTest helper

Added: trunk/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-skip/text-decoration-skip-ink-expected.html (0 => 158467)


--- trunk/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-skip/text-decoration-skip-ink-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-skip/text-decoration-skip-ink-expected.html	2013-11-01 23:46:54 UTC (rev 158467)
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style>
+    #bigskew {
+      position: absolute;
+      left: -156px;
+      top: -400px;
+      font-style: italic;
+      font-size: 12pt;
+      font-family: helvetica;
+      -webkit-transform: scale(37);
+      -webkit-transform-origin: top left;
+    }
+  </style>
+</head>
+<body>
+  The following should be an underlined italicized "p" as viewed through a narrow slit around
+  the descender. The "p" is in 12pt size, but is blown up to much larger. This tests that
+  the text-decoration-skip: ink mask is calculated with more precision than user-space precision.
+  If we don't have enough precision, there won't be a nice crisp edge on the slope of the underline
+  where it gets masked off. This test would fail because there would be garbage giant pixel
+  aliasing near the character. If text-decoration-skip: ink isn't working at all, then the
+  underline will simply be drawn like normal, and won't match the expected case (where there
+  is no underline)
+    <div style="position: relative; overflow: hidden; width: 81px; height: 400px">
+      <div id="bigskew">lpl</div>
+    </div>
+
+</body>
+</html>
+

Added: trunk/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-skip/text-decoration-skip-ink.html (0 => 158467)


--- trunk/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-skip/text-decoration-skip-ink.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-skip/text-decoration-skip-ink.html	2013-11-01 23:46:54 UTC (rev 158467)
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style>
+    #bigskew {
+      position: absolute;
+      left: -156px;
+      top: -400px;
+      font-style: italic;
+      font-size: 12pt;
+      font-family: helvetica;
+      text-decoration: underline;
+      -webkit-text-decoration-skip: ink;
+      -webkit-transform: scale(37);
+      -webkit-transform-origin: top left;
+    }
+  </style>
+</head>
+<body>
+  The following should be an underlined italicized "p" as viewed through a narrow slit around
+  the descender. The "p" is in 12pt size, but is blown up to much larger. This tests that
+  the text-decoration-skip: ink mask is calculated with more precision than user-space precision.
+  If we don't have enough precision, there won't be a nice crisp edge on the slope of the underline
+  where it gets masked off. This test would fail because there would be garbage giant pixel
+  aliasing near the character. If text-decoration-skip: ink isn't working at all, then the
+  underline will simply be drawn like normal, and won't match the expected case (where there
+  is no underline)
+    <div style="position: relative; overflow: hidden; width: 81px; height: 400px">
+      <div id="bigskew">lpl</div>
+    </div>
+
+</body>
+</html>
+

Modified: trunk/Source/WebCore/ChangeLog (158466 => 158467)


--- trunk/Source/WebCore/ChangeLog	2013-11-01 23:38:54 UTC (rev 158466)
+++ trunk/Source/WebCore/ChangeLog	2013-11-01 23:46:54 UTC (rev 158467)
@@ -1,3 +1,38 @@
+2013-11-01  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+        Initial implementation of text-decoration-skip ink
+        https://bugs.webkit.org/show_bug.cgi?id=121806
+
+        Reviewed by Darin Adler.
+
+        text-decoration-skip: ink is implemented by the following steps:
+        1. Before drawing any decorations, figure out the bounding box for the decorations that will be drawn
+        2. Create an ImageBuffer with these dimensions
+        3. Draw text into this ImageBuffer with a thicker stroke
+        4. Apply the ImageBuffer as a mask to the context
+        5. Draw decorations like normal
+        6. Clean up
+
+        Test: fast/css3-text/css3-text-decoration/text-decoration-skip/text-decoration-skip-ink.html
+
+        * platform/graphics/cg/GraphicsContextCG.cpp:
+        (WebCore::computeLineBoundsAndAntialiasingModeForText): Don't call GraphicsContext::roundToDevicePixels
+        when painting is disabled
+        * rendering/InlineTextBox.cpp:
+        (WebCore::InlineTextBox::paint): Pass the TextPainter to paintDecoration
+        (WebCore::computeUnderlineOffset): Small cleanup
+        (WebCore::getWavyStrokeControlPointDistance): Pulling out of strokeWavyTextDecoration()
+        (WebCore::getWavyStrokeStep): Ditto
+        (WebCore::strokeWavyTextDecoration): Use the previous 2 functions
+        (WebCore::getSingleDecorationBoundingBox): Pulling out repeated code into a function
+        (WebCore::getDecorationBoundingBox): Compute the bounding box for an underline which
+        hasn't been drawn yet
+        (WebCore::InlineTextBox::paintDecoration): Construct a mask and apply it to the GraphicsContext
+        * rendering/InlineTextBox.h: paintDecoration needs the TextPainter
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::changeRequiresRepaintIfTextOrBorderOrOutline): Redraw the underline when
+        text-decoration-skip changes
+
 2013-11-01  Andreas Kling  <akl...@apple.com>
 
         CSS 'initial' and 'inherit' value constructors should return PassRef.

Modified: trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp (158466 => 158467)


--- trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp	2013-11-01 23:38:54 UTC (rev 158466)
+++ trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp	2013-11-01 23:46:54 UTC (rev 158467)
@@ -1246,7 +1246,7 @@
     // See http://bugs.webkit.org/show_bug.cgi?id=4255 for details of why 0.5 is the right minimum thickness to use.
     FloatRect initialBounds(point, FloatSize(width, max(context.strokeThickness(), 0.5f)));
 
-    if (printing || !context.getCTM(GraphicsContext::DefinitelyIncludeDeviceScale).preservesAxisAlignment())
+    if (printing || context.paintingDisabled() || !context.getCTM(GraphicsContext::DefinitelyIncludeDeviceScale).preservesAxisAlignment())
         return initialBounds;
 
     // On screen, use a minimum thickness of 1.0 in user space (later rounded to an integral number in device space).

Modified: trunk/Source/WebCore/rendering/InlineTextBox.cpp (158466 => 158467)


--- trunk/Source/WebCore/rendering/InlineTextBox.cpp	2013-11-01 23:38:54 UTC (rev 158466)
+++ trunk/Source/WebCore/rendering/InlineTextBox.cpp	2013-11-01 23:46:54 UTC (rev 158467)
@@ -33,6 +33,7 @@
 #include "Frame.h"
 #include "GraphicsContext.h"
 #include "HitTestResult.h"
+#include "ImageBuffer.h"
 #include "Page.h"
 #include "PaintInfo.h"
 #include "RenderedDocumentMarker.h"
@@ -580,7 +581,7 @@
         updateGraphicsContext(*context, textPaintStyle);
         if (combinedText)
             context->concatCTM(rotation(boxRect, Clockwise));
-        paintDecoration(context, boxOrigin, textDecorations, lineStyle.textDecorationStyle(), textShadow);
+        paintDecoration(*context, boxOrigin, textDecorations, lineStyle.textDecorationStyle(), textShadow, textPainter);
         if (combinedText)
             context->concatCTM(rotation(boxRect, Counterclockwise));
     }
@@ -778,9 +779,7 @@
     case TextUnderlinePositionUnder: {
         // Position underline relative to the under edge of the lowest element's content box.
         const float offset = inlineTextBox->root().maxLogicalTop() - inlineTextBox->logicalTop();
-        if (offset > 0)
-            return inlineTextBox->logicalHeight() + gap + offset;
-        return inlineTextBox->logicalHeight() + gap;
+        return inlineTextBox->logicalHeight() + gap + std::max<float>(offset, 0);
     }
     }
 
@@ -806,6 +805,21 @@
     controlPointDistance += adjustment;
 }
 
+static void getWavyStrokeParameters(float strokeThickness, float& controlPointDistance, float& step)
+{
+    // 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.
+    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.
+    step = 2 * std::max<float>(2, strokeThickness);
+}
+
 /*
  * 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
@@ -833,25 +847,17 @@
  *             |-----------|
  *                 step
  */
-static void strokeWavyTextDecoration(GraphicsContext* context, FloatPoint& p1, FloatPoint& p2, float strokeThickness)
+static void strokeWavyTextDecoration(GraphicsContext& context, FloatPoint& p1, FloatPoint& p2, float strokeThickness)
 {
-    context->adjustLineToPixelBoundaries(p1, p2, strokeThickness, context->strokeStyle());
+    context.adjustLineToPixelBoundaries(p1, p2, strokeThickness, context.strokeStyle());
 
     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 * max<float>(2, strokeThickness);
+    float controlPointDistance;
+    float step;
+    getWavyStrokeParameters(strokeThickness, controlPointDistance, step);
 
-    // 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 * max<float>(2, strokeThickness);
-
     bool isVerticalLine = (p1.x() == p2.x());
 
     if (isVerticalLine) {
@@ -906,13 +912,66 @@
         }
     }
 
-    context->setShouldAntialias(true);
-    context->strokePath(path);
+    context.setShouldAntialias(true);
+    context.strokePath(path);
 }
+
+// Because finding the bounding box of an underline is structurally similar to finding
+// the bounding box of a strikethrough, we can pull out the computation and parameterize
+// by the location of the decoration (yOffset, underlineOffset, and doubleOffset).
+static FloatRect boundingBoxForSingleDecoration(GraphicsContext& context, float textDecorationThickness,
+    float width, FloatPoint localOrigin, TextDecorationStyle decorationStyle,
+    bool isPrinting, float yOffset, float underlineOffset, float doubleOffset)
+{
+    FloatRect boundingBox;
+
+    switch (decorationStyle) {
+    case TextDecorationStyleWavy: {
+        FloatPoint start(localOrigin.x(), localOrigin.y() + yOffset);
+        FloatPoint end = start + FloatSize(width, 0);
+        context.adjustLineToPixelBoundaries(start, end, textDecorationThickness, context.strokeStyle());
+
+        float controlPointDistance;
+        float step;
+        getWavyStrokeParameters(textDecorationThickness, controlPointDistance, step);
+
+        adjustStepToDecorationLength(step, controlPointDistance, width);
+
+        controlPointDistance += textDecorationThickness;
+        FloatPoint boundingBoxOrigin = start - FloatSize(0, controlPointDistance);
+        FloatSize boundingBoxSize = FloatSize(width, 2 * controlPointDistance);
+        boundingBox = FloatRect(boundingBoxOrigin, boundingBoxSize);
+        break;
+    }
+    default:
+        boundingBox = context.computeLineBoundsForText(localOrigin + FloatSize(0, underlineOffset), width, isPrinting);
+        if (decorationStyle == TextDecorationStyleDouble)
+            boundingBox.unite(context.computeLineBoundsForText(localOrigin + FloatSize(0, doubleOffset), width, isPrinting));
+    }
+    return boundingBox;
+}
+
+static FloatRect boundingBoxForAllActiveDecorations(InlineTextBox& inlineTextBox, GraphicsContext& context, TextDecoration decoration, float textDecorationThickness, float width, float doubleOffset, TextDecorationStyle decorationStyle, const FloatPoint localOrigin, const RenderStyle& lineStyle, bool isPrinting, int baseline)
+{
+    FloatRect boundingBox;
+    if (decoration & TextDecorationUnderline) {
+        int underlineOffset = computeUnderlineOffset(lineStyle.textUnderlinePosition(), lineStyle.fontMetrics(), &inlineTextBox, textDecorationThickness);
+        
+        boundingBox.unite(boundingBoxForSingleDecoration(context, textDecorationThickness, width, localOrigin, decorationStyle, isPrinting, underlineOffset + doubleOffset, underlineOffset, baseline + 1));
+    }
+    if (decoration & TextDecorationOverline)
+        boundingBox.unite(boundingBoxForSingleDecoration(context, textDecorationThickness, width, localOrigin, decorationStyle, isPrinting, -doubleOffset, 0, -doubleOffset));
+    if (decoration & TextDecorationLineThrough)
+        boundingBox.unite(boundingBoxForSingleDecoration(context, textDecorationThickness, width, localOrigin, decorationStyle, isPrinting, 2 * baseline / 3, 2 * baseline / 3, doubleOffset + 2 * baseline / 3));
+    return boundingBox;
+}
 #endif // CSS3_TEXT_DECORATION
 
-void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint& boxOrigin, TextDecoration deco, TextDecorationStyle decorationStyle, const ShadowData* shadow)
+void InlineTextBox::paintDecoration(GraphicsContext& context, const FloatPoint& boxOrigin, TextDecoration decoration, TextDecorationStyle decorationStyle, const ShadowData* shadow, TextPainter& textPainter)
 {
+#if !ENABLE(CSS3_TEXT_DECORATION)
+    UNUSED_PARAM(textPainter);
+#endif
     // FIXME: We should improve this rule and not always just assume 1.
     const float textDecorationThickness = 1.f;
 
@@ -930,15 +989,15 @@
     
     // Get the text decoration colors.
     Color underline, overline, linethrough;
-    renderer().getTextDecorationColors(deco, underline, overline, linethrough, true);
+    renderer().getTextDecorationColors(decoration, underline, overline, linethrough, true);
     if (isFirstLine())
-        renderer().getTextDecorationColors(deco, underline, overline, linethrough, true, true);
+        renderer().getTextDecorationColors(decoration, underline, overline, linethrough, true, true);
     
     // Use a special function for underlines to get the positioning exactly right.
     bool isPrinting = renderer().document().printing();
-    context->setStrokeThickness(textDecorationThickness);
+    context.setStrokeThickness(textDecorationThickness);
 
-    bool linesAreOpaque = !isPrinting && (!(deco & TextDecorationUnderline) || underline.alpha() == 255) && (!(deco & TextDecorationOverline) || overline.alpha() == 255) && (!(deco & TextDecorationLineThrough) || linethrough.alpha() == 255);
+    bool linesAreOpaque = !isPrinting && (!(decoration & TextDecorationUnderline) || underline.alpha() == 255) && (!(decoration & TextDecorationOverline) || overline.alpha() == 255) && (!(decoration & TextDecorationLineThrough) || linethrough.alpha() == 255);
 
     const RenderStyle& lineStyle = this->lineStyle();
     int baseline = lineStyle.fontMetrics().ascent();
@@ -957,8 +1016,8 @@
             clipRect.unite(shadowRect);
             extraOffset = max(extraOffset, max(0, shadowY) + shadowExtent);
         }
-        context->save();
-        context->clip(clipRect);
+        context.save();
+        context.clip(clipRect);
         extraOffset += baseline + 2;
         localOrigin.move(0, extraOffset);
         setClip = true;
@@ -976,18 +1035,46 @@
             }
             int shadowX = isHorizontal() ? shadow->x() : shadow->y();
             int shadowY = isHorizontal() ? shadow->y() : -shadow->x();
-            context->setShadow(FloatSize(shadowX, shadowY - extraOffset), shadow->radius(), shadow->color(), colorSpace);
+            context.setShadow(FloatSize(shadowX, shadowY - extraOffset), shadow->radius(), shadow->color(), colorSpace);
             setShadow = true;
             shadow = shadow->next();
         }
 
 #if ENABLE(CSS3_TEXT_DECORATION)
         // Offset between lines - always non-zero, so lines never cross each other.
-        float doubleOffset = textDecorationThickness + 1.f;
+        float doubleOffset = textDecorationThickness + 1;
+        
+        bool clipDecorationToMask = lineStyle.textDecorationSkip() == TextDecorationSkipInk;
+        
+        GraphicsContextStateSaver stateSaver(context, false);
+        
+        if (clipDecorationToMask) {
+            const float skipInkGapWidth = 1;
+
+            stateSaver.save();
+
+            FloatRect underlineRect = boundingBoxForAllActiveDecorations(*this, context, decoration, textDecorationThickness, width, doubleOffset, decorationStyle, localOrigin, lineStyle, isPrinting, baseline);
+            IntRect enclosingDeviceRect = enclosingIntRect(underlineRect);
+            OwnPtr<ImageBuffer> imageBuffer = context.createCompatibleBuffer(enclosingDeviceRect.size());
+
+            if (imageBuffer.get()) {
+                GraphicsContext& maskContext = *imageBuffer->context();
+                maskContext.setFillColor(Color::black, ColorSpaceDeviceRGB);
+                maskContext.setLineJoin(RoundJoin);
+                maskContext.translate(FloatPoint() - enclosingDeviceRect.location());
+
+                maskContext.fillRect(enclosingDeviceRect);
+                maskContext.setCompositeOperation(CompositeClear);
+    
+                textPainter.paintTextInContext(maskContext, skipInkGapWidth);
+
+                context.clipToImageBuffer(imageBuffer.get(), enclosingDeviceRect);
+            }
+        }
 #endif // CSS3_TEXT_DECORATION
-        context->setStrokeStyle(textDecorationStyleToStrokeStyle(decorationStyle));
-        if (deco & TextDecorationUnderline) {
-            context->setStrokeColor(underline, colorSpace);
+        context.setStrokeStyle(textDecorationStyleToStrokeStyle(decorationStyle));
+        if (decoration & TextDecorationUnderline) {
+            context.setStrokeColor(underline, colorSpace);
 #if ENABLE(CSS3_TEXT_DECORATION)
             TextUnderlinePosition underlinePosition = lineStyle.textUnderlinePosition();
             const int underlineOffset = computeUnderlineOffset(underlinePosition, lineStyle.fontMetrics(), this, textDecorationThickness);
@@ -1000,18 +1087,18 @@
                 break;
             }
             default:
-                context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + underlineOffset), width, isPrinting);
+                context.drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + underlineOffset), width, isPrinting);
 
                 if (decorationStyle == TextDecorationStyleDouble)
-                    context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + underlineOffset + doubleOffset), width, isPrinting);
+                    context.drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + underlineOffset + doubleOffset), width, isPrinting);
             }
 #else
             // Leave one pixel of white between the baseline and the underline.
-            context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + baseline + 1), width, isPrinting);
+            context.drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + baseline + 1), width, isPrinting);
 #endif // CSS3_TEXT_DECORATION
         }
-        if (deco & TextDecorationOverline) {
-            context->setStrokeColor(overline, colorSpace);
+        if (decoration & TextDecorationOverline) {
+            context.setStrokeColor(overline, colorSpace);
 #if ENABLE(CSS3_TEXT_DECORATION)
             switch (decorationStyle) {
             case TextDecorationStyleWavy: {
@@ -1022,16 +1109,20 @@
             }
             default:
 #endif // CSS3_TEXT_DECORATION
-                context->drawLineForText(localOrigin, width, isPrinting);
+                context.drawLineForText(localOrigin, width, isPrinting);
 #if ENABLE(CSS3_TEXT_DECORATION)
                 if (decorationStyle == TextDecorationStyleDouble)
-                    context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() - doubleOffset), width, isPrinting);
+                    context.drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() - doubleOffset), width, isPrinting);
             }
 #endif // CSS3_TEXT_DECORATION
         }
-        if (deco & TextDecorationLineThrough) {
-            context->setStrokeColor(linethrough, colorSpace);
 #if ENABLE(CSS3_TEXT_DECORATION)
+        if (clipDecorationToMask)
+            stateSaver.restore();
+#endif
+        if (decoration & TextDecorationLineThrough) {
+            context.setStrokeColor(linethrough, colorSpace);
+#if ENABLE(CSS3_TEXT_DECORATION)
             switch (decorationStyle) {
             case TextDecorationStyleWavy: {
                 FloatPoint start(localOrigin.x(), localOrigin.y() + 2 * baseline / 3);
@@ -1041,19 +1132,19 @@
             }
             default:
 #endif // CSS3_TEXT_DECORATION
-                context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + 2 * baseline / 3), width, isPrinting);
+                context.drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + 2 * baseline / 3), width, isPrinting);
 #if ENABLE(CSS3_TEXT_DECORATION)
                 if (decorationStyle == TextDecorationStyleDouble)
-                    context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + doubleOffset + 2 * baseline / 3), width, isPrinting);
+                    context.drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + doubleOffset + 2 * baseline / 3), width, isPrinting);
             }
 #endif // CSS3_TEXT_DECORATION
         }
     } while (shadow);
 
     if (setClip)
-        context->restore();
+        context.restore();
     else if (setShadow)
-        context->clearShadow();
+        context.clearShadow();
 }
 
 static GraphicsContext::DocumentMarkerLineStyle lineStyleForMarkerType(DocumentMarker::MarkerType markerType)

Modified: trunk/Source/WebCore/rendering/InlineTextBox.h (158466 => 158467)


--- trunk/Source/WebCore/rendering/InlineTextBox.h	2013-11-01 23:38:54 UTC (rev 158466)
+++ trunk/Source/WebCore/rendering/InlineTextBox.h	2013-11-01 23:46:54 UTC (rev 158467)
@@ -32,6 +32,7 @@
 
 struct CompositionUnderline;
 class DocumentMarker;
+class TextPainter;
 
 const unsigned short cNoTruncation = USHRT_MAX;
 const unsigned short cFullTruncation = USHRT_MAX - 1;
@@ -169,7 +170,7 @@
 #endif
 
 private:
-    void paintDecoration(GraphicsContext*, const FloatPoint& boxOrigin, TextDecoration, TextDecorationStyle, const ShadowData*);
+    void paintDecoration(GraphicsContext&, const FloatPoint& boxOrigin, TextDecoration, TextDecorationStyle, const ShadowData*, TextPainter&);
     void paintSelection(GraphicsContext*, const FloatPoint& boxOrigin, const RenderStyle&, const Font&, Color textColor);
     void paintDocumentMarker(GraphicsContext*, const FloatPoint& boxOrigin, DocumentMarker*, const RenderStyle&, const Font&, bool grammar);
     void paintTextMatchMarker(GraphicsContext*, const FloatPoint& boxOrigin, DocumentMarker*, const RenderStyle&, const Font&);

Modified: trunk/Source/WebCore/rendering/style/RenderStyle.cpp (158466 => 158467)


--- trunk/Source/WebCore/rendering/style/RenderStyle.cpp	2013-11-01 23:38:54 UTC (rev 158466)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.cpp	2013-11-01 23:46:54 UTC (rev 158467)
@@ -791,6 +791,7 @@
 #if ENABLE(CSS3_TEXT_DECORATION)
         || rareNonInheritedData->m_textDecorationStyle != other->rareNonInheritedData->m_textDecorationStyle
         || rareNonInheritedData->m_textDecorationColor != other->rareNonInheritedData->m_textDecorationColor
+        || rareInheritedData->m_textDecorationSkip != other->rareInheritedData->m_textDecorationSkip
 #endif // CSS3_TEXT_DECORATION
         || rareInheritedData->textFillColor != other->rareInheritedData->textFillColor
         || rareInheritedData->textStrokeColor != other->rareInheritedData->textStrokeColor
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to