Title: [147170] trunk
Revision
147170
Author
[email protected]
Date
2013-03-28 15:25:23 -0700 (Thu, 28 Mar 2013)

Log Message

[css3-text] Add platform support for "wavy" text decoration style
https://bugs.webkit.org/show_bug.cgi?id=92868

Patch by Lamarque V. Souza <[email protected]> on 2013-03-28
Reviewed by Benjamin Poulain.

Source/WebCore:

This patch uses GraphicsContext::strokePath() to implement
wavy decoration for the CSS3 property "text-decoration-style".

No new tests as this is covered with existing tests.

* rendering/InlineTextBox.cpp:
(WebCore::textDecorationStyleToStrokeStyle): Remove obsolete comment.
(WebCore::adjustStepToDecorationLength): Add function to adjust
variables used to calculate the lenght of Bezier curves.
(WebCore::strokeWavyTextDecoration): Add function to stroke wavy
decoration based on cubic Bezier curve.
(WebCore::InlineTextBox::paintDecoration): Call
strokeWavyTextDecoration when necessary.

LayoutTests:

Rebaseline chromium-linux expectation for
fast/css3-text/css3-text-decoration/text-decoration-style.html.

* platform/chromium-linux/fast/css3-text/css3-text-decoration/text-decoration-style-expected.png: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (147169 => 147170)


--- trunk/LayoutTests/ChangeLog	2013-03-28 22:17:05 UTC (rev 147169)
+++ trunk/LayoutTests/ChangeLog	2013-03-28 22:25:23 UTC (rev 147170)
@@ -1,3 +1,15 @@
+2013-03-28  Lamarque V. Souza  <[email protected]>
+
+        [css3-text] Add platform support for "wavy" text decoration style
+        https://bugs.webkit.org/show_bug.cgi?id=92868
+
+        Reviewed by Benjamin Poulain.
+
+        Rebaseline chromium-linux expectation for
+        fast/css3-text/css3-text-decoration/text-decoration-style.html.
+
+        * platform/chromium-linux/fast/css3-text/css3-text-decoration/text-decoration-style-expected.png: Added.
+
 2013-03-28  Nate Chapin  <[email protected]>
 
         Remove expected failure for https://bugs.webkit.org/show_bug.cgi?id=112542

Added: trunk/LayoutTests/platform/chromium-linux/fast/css3-text/css3-text-decoration/text-decoration-style-expected.png


(Binary files differ)
Property changes on: trunk/LayoutTests/platform/chromium-linux/fast/css3-text/css3-text-decoration/text-decoration-style-expected.png ___________________________________________________________________

Added: svn:mime-type

Modified: trunk/Source/WebCore/ChangeLog (147169 => 147170)


--- trunk/Source/WebCore/ChangeLog	2013-03-28 22:17:05 UTC (rev 147169)
+++ trunk/Source/WebCore/ChangeLog	2013-03-28 22:25:23 UTC (rev 147170)
@@ -1,3 +1,24 @@
+2013-03-28  Lamarque V. Souza  <[email protected]>
+
+        [css3-text] Add platform support for "wavy" text decoration style
+        https://bugs.webkit.org/show_bug.cgi?id=92868
+
+        Reviewed by Benjamin Poulain.
+
+        This patch uses GraphicsContext::strokePath() to implement
+        wavy decoration for the CSS3 property "text-decoration-style".
+
+        No new tests as this is covered with existing tests.
+
+        * rendering/InlineTextBox.cpp:
+        (WebCore::textDecorationStyleToStrokeStyle): Remove obsolete comment.
+        (WebCore::adjustStepToDecorationLength): Add function to adjust
+        variables used to calculate the lenght of Bezier curves.
+        (WebCore::strokeWavyTextDecoration): Add function to stroke wavy
+        decoration based on cubic Bezier curve.
+        (WebCore::InlineTextBox::paintDecoration): Call
+        strokeWavyTextDecoration when necessary.
+
 2013-03-28  Arnaud Renevier  <[email protected]>
 
         REGRESSION(r147149): breaks binding test on Mac. (Requested by mlam_ on #webkit).

Modified: trunk/Source/WebCore/rendering/InlineTextBox.cpp (147169 => 147170)


--- trunk/Source/WebCore/rendering/InlineTextBox.cpp	2013-03-28 22:17:05 UTC (rev 147169)
+++ trunk/Source/WebCore/rendering/InlineTextBox.cpp	2013-03-28 22:25:23 UTC (rev 147170)
@@ -954,7 +954,6 @@
         strokeStyle = DashedStroke;
         break;
     case TextDecorationStyleWavy:
-        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=92868 - Needs platform support.
         strokeStyle = WavyStroke;
         break;
 #endif // CSS3_TEXT
@@ -990,6 +989,130 @@
 }
 #endif // CSS3_TEXT
 
+#if ENABLE(CSS3_TEXT)
+static void adjustStepToDecorationLength(float& step, float& controlPointDistance, float length)
+{
+    ASSERT(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->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);
+
+    // 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) {
+        ASSERT(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 {
+        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));
+        }
+    }
+
+    context->setShouldAntialias(true);
+    context->strokePath(path);
+}
+#endif // CSS3_TEXT
+
 void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint& boxOrigin, ETextDecoration deco, TextDecorationStyle decorationStyle, const ShadowData* shadow)
 {
     // FIXME: We should improve this rule and not always just assume 1.
@@ -1069,10 +1192,20 @@
 #if ENABLE(CSS3_TEXT)
             TextUnderlinePosition underlinePosition = styleToUse->textUnderlinePosition();
             const int underlineOffset = computeUnderlineOffset(underlinePosition, styleToUse->fontMetrics(), this, textDecorationThickness);
-            context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + underlineOffset), width, isPrinting);
 
-            if (decorationStyle == TextDecorationStyleDouble)
-                context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + underlineOffset + doubleOffset), width, isPrinting);
+            switch (decorationStyle) {
+            case TextDecorationStyleWavy: {
+                FloatPoint start(localOrigin.x(), localOrigin.y() + underlineOffset + doubleOffset);
+                FloatPoint end(localOrigin.x() + width, localOrigin.y() + underlineOffset + doubleOffset);
+                strokeWavyTextDecoration(context, start, end, textDecorationThickness);
+                break;
+            }
+            default:
+                context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + underlineOffset), width, isPrinting);
+
+                if (decorationStyle == TextDecorationStyleDouble)
+                    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);
@@ -1080,19 +1213,41 @@
         }
         if (deco & OVERLINE) {
             context->setStrokeColor(overline, colorSpace);
-            context->drawLineForText(localOrigin, width, isPrinting);
 #if ENABLE(CSS3_TEXT)
-            if (decorationStyle == TextDecorationStyleDouble)
-                context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() - doubleOffset), width, isPrinting);
+            switch (decorationStyle) {
+            case TextDecorationStyleWavy: {
+                FloatPoint start(localOrigin.x(), localOrigin.y() - doubleOffset);
+                FloatPoint end(localOrigin.x() + width, localOrigin.y() - doubleOffset);
+                strokeWavyTextDecoration(context, start, end, textDecorationThickness);
+                break;
+            }
+            default:
 #endif // CSS3_TEXT
+                context->drawLineForText(localOrigin, width, isPrinting);
+#if ENABLE(CSS3_TEXT)
+                if (decorationStyle == TextDecorationStyleDouble)
+                    context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() - doubleOffset), width, isPrinting);
+            }
+#endif // CSS3_TEXT
         }
         if (deco & LINE_THROUGH) {
             context->setStrokeColor(linethrough, colorSpace);
-            context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + 2 * baseline / 3), width, isPrinting);
 #if ENABLE(CSS3_TEXT)
-            if (decorationStyle == TextDecorationStyleDouble)
-                context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + doubleOffset + 2 * baseline / 3), width, isPrinting);
+            switch (decorationStyle) {
+            case TextDecorationStyleWavy: {
+                FloatPoint start(localOrigin.x(), localOrigin.y() + 2 * baseline / 3);
+                FloatPoint end(localOrigin.x() + width, localOrigin.y() + 2 * baseline / 3);
+                strokeWavyTextDecoration(context, start, end, textDecorationThickness);
+                break;
+            }
+            default:
 #endif // CSS3_TEXT
+                context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + 2 * baseline / 3), width, isPrinting);
+#if ENABLE(CSS3_TEXT)
+                if (decorationStyle == TextDecorationStyleDouble)
+                    context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + doubleOffset + 2 * baseline / 3), width, isPrinting);
+            }
+#endif // CSS3_TEXT
         }
     } while (shadow);
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to