Title: [163921] trunk
Revision
163921
Author
mmaxfi...@apple.com
Date
2014-02-11 17:54:19 -0800 (Tue, 11 Feb 2014)

Log Message

Position and thickness of underline as text size changes
https://bugs.webkit.org/show_bug.cgi?id=16768

Source/WebCore:

Reviewed by Dean Jackson.

This patch adopts the iOS codepath for underlines. It also reorganizes
drawLineForText to avoid a costly global state save & restore.

Test: fast/css3-text/css3-text-decoration/text-decoration-thickness.html

* platform/graphics/cg/GraphicsContextCG.cpp:
(WebCore::computeLineBoundsAndAntialiasingModeForText):
(WebCore::GraphicsContext::computeLineBoundsForText):
(WebCore::GraphicsContext::drawLineForText):
(WebCore::GraphicsContext::drawLinesForText):
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::paintDecoration):

LayoutTests:

This test draws underlined text at a very large font size. It then positions and clips
the text so that the underline should fill a box if the underline grows in proportion
to text size. The comparison is to a box that has its background color set.

Reviewed by Dean Jackson.

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

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (163920 => 163921)


--- trunk/LayoutTests/ChangeLog	2014-02-12 01:53:03 UTC (rev 163920)
+++ trunk/LayoutTests/ChangeLog	2014-02-12 01:54:19 UTC (rev 163921)
@@ -1,3 +1,17 @@
+2014-02-11  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+        Position and thickness of underline as text size changes
+        https://bugs.webkit.org/show_bug.cgi?id=16768
+
+        This test draws underlined text at a very large font size. It then positions and clips
+        the text so that the underline should fill a box if the underline grows in proportion
+        to text size. The comparison is to a box that has its background color set.
+
+        Reviewed by Dean Jackson.
+
+        * fast/css3-text/css3-text-decoration/text-decoration-thickness-expected.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-thickness.html: Added.
+
 2014-02-10  Myles C. Maxfield  <mmaxfi...@apple.com>
 
         Convert position:sticky and position:fixed properties to position:static and position:absolute upon copy

Added: trunk/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-thickness-expected.html (0 => 163921)


--- trunk/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-thickness-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-thickness-expected.html	2014-02-12 01:54:19 UTC (rev 163921)
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+</style>
+</head>
+<body>
+This test draws underlined text at a very large font size. It then positions and clips
+the text so that the underline should fill a box if the underline grows in proportion
+to text size. The comparison is to a box that has its background color set.
+<div style="position: relative; width: 600px; height: 600px; background: #000">
+</div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-thickness.html (0 => 163921)


--- trunk/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-thickness.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-thickness.html	2014-02-12 01:54:19 UTC (rev 163921)
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test draws underlined text at a very large font size. It then positions and clips
+the text so that the underline should fill a box if the underline grows in proportion
+to text size. The comparison is to a box that has its background color set.
+<div style="position: relative; width: 600px; height: 600px; overflow: hidden;">
+<div style="font-family: Ahem; text-decoration: underline; font-size: 10000px; position: absolute; left: 0px; top: -8650px;">&nbsp;</div>
+</div>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (163920 => 163921)


--- trunk/Source/WebCore/ChangeLog	2014-02-12 01:53:03 UTC (rev 163920)
+++ trunk/Source/WebCore/ChangeLog	2014-02-12 01:54:19 UTC (rev 163921)
@@ -1,3 +1,23 @@
+2014-02-11  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+        Position and thickness of underline as text size changes
+        https://bugs.webkit.org/show_bug.cgi?id=16768
+
+        Reviewed by Dean Jackson.
+
+        This patch adopts the iOS codepath for underlines. It also reorganizes
+        drawLineForText to avoid a costly global state save & restore.
+
+        Test: fast/css3-text/css3-text-decoration/text-decoration-thickness.html
+
+        * platform/graphics/cg/GraphicsContextCG.cpp:
+        (WebCore::computeLineBoundsAndAntialiasingModeForText):
+        (WebCore::GraphicsContext::computeLineBoundsForText):
+        (WebCore::GraphicsContext::drawLineForText):
+        (WebCore::GraphicsContext::drawLinesForText):
+        * rendering/InlineTextBox.cpp:
+        (WebCore::InlineTextBox::paintDecoration):
+
 2014-02-11  Ryosuke Niwa  <rn...@webkit.org>
 
         Frame::rectForSelection shouldn't instantiate FrameSelection

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


--- trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp	2014-02-12 01:53:03 UTC (rev 163920)
+++ trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp	2014-02-12 01:54:19 UTC (rev 163921)
@@ -1346,9 +1346,6 @@
     return FloatRect(roundedOrigin, roundedLowerRight - roundedOrigin);
 }
 
-// FIXME: We should look to consolidate the iOS and non-iOS implementations of
-// computeLineBoundsAndAntialiasingModeForText() and computeLineBoundsForText().
-#if PLATFORM(IOS)
 static FloatRect computeLineBoundsAndAntialiasingModeForText(GraphicsContext& initialContext, const FloatPoint& point, float width, bool printing, bool& shouldAntialias, Color& color)
 {
     CGContextRef context = initialContext.platformContext();
@@ -1387,7 +1384,6 @@
         CGPoint devicePoint = CGPointApplyAffineTransform(point, t);
         CGPoint deviceOrigin = CGPointMake(roundf(devicePoint.x), ceilf(devicePoint.y) + dy);
         origin = CGPointApplyAffineTransform(deviceOrigin, CGAffineTransformInvert(t));
-        thickness /= scale;
     }
     return FloatRect(origin.x, origin.y, width, thickness);
 }
@@ -1398,44 +1394,7 @@
     Color dummyColor;
     return computeLineBoundsAndAntialiasingModeForText(*this, point, width, printing, dummyBool, dummyColor);
 }
-#else
-static FloatRect computeLineBoundsAndAntialiasingModeForText(GraphicsContext& context, const FloatPoint& point, float width, bool printing, bool& shouldAntialias)
-{
-    shouldAntialias = true;
 
-    if (width <= 0)
-        return FloatRect();
-
-    // Use a minimum thickness of 0.5 in user space.
-    // 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, std::max(context.strokeThickness(), 0.5f)));
-
-    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).
-    FloatRect adjustedBounds = initialBounds;
-    adjustedBounds.setHeight(std::max(initialBounds.height(), 1.0f));
-
-    // FIXME: This should be done a better way.
-    // We try to round all parameters to integer boundaries in device space. If rounding pixels in device space
-    // makes our thickness more than double, then there must be a shrinking-scale factor and rounding to pixels
-    // in device space will make the underlines too thick.
-    FloatRect lineRect = context.roundToDevicePixels(adjustedBounds, GraphicsContext::RoundAllSides);
-    if (lineRect.height() < initialBounds.height() * 2) {
-        shouldAntialias = false;
-        return lineRect;
-    }
-    return initialBounds;
-}
-
-FloatRect GraphicsContext::computeLineBoundsForText(const FloatPoint& point, float width, bool printing)
-{
-    bool dummy;
-    return computeLineBoundsAndAntialiasingModeForText(*this, point, width, printing, dummy);
-}
-#endif
-
 void GraphicsContext::drawLineForText(const FloatPoint& point, float width, bool printing)
 {
     if (paintingDisabled())
@@ -1444,41 +1403,25 @@
     if (width <= 0)
         return;
 
-#if !PLATFORM(IOS)
+    Color localStrokeColor(strokeColor());
+
     bool shouldAntialiasLine;
-    FloatRect bounds = computeLineBoundsAndAntialiasingModeForText(*this, point, width, printing, shouldAntialiasLine);
+    FloatRect bounds = computeLineBoundsAndAntialiasingModeForText(*this, point, width, printing, shouldAntialiasLine, localStrokeColor);
+    bool fillColorIsNotEqualToStrokeColor = fillColor() != localStrokeColor;
 
-    bool savedShouldAntialias = shouldAntialias();
-    bool restoreAntialiasMode = savedShouldAntialias != shouldAntialiasLine;
+#if PLATFORM(IOS)
+    if (m_state.shouldUseContextColors)
+#endif
+        if (fillColorIsNotEqualToStrokeColor)
+            setCGFillColor(platformContext(), localStrokeColor, strokeColorSpace());
 
-    if (restoreAntialiasMode)
-        CGContextSetShouldAntialias(platformContext(), shouldAntialiasLine);
-
-    bool fillColorIsNotEqualToStrokeColor = fillColor() != strokeColor();
-    if (fillColorIsNotEqualToStrokeColor)
-        setCGFillColor(platformContext(), strokeColor(), strokeColorSpace());
     CGContextFillRect(platformContext(), bounds);
-    if (fillColorIsNotEqualToStrokeColor)
-        setCGFillColor(platformContext(), fillColor(), fillColorSpace());
-    CGContextSetShouldAntialias(platformContext(), savedShouldAntialias);
 
-    if (restoreAntialiasMode)
-        CGContextSetShouldAntialias(platformContext(), true);
-#else
-    CGContextRef context = platformContext();
-    CGContextSaveGState(context);
-
-    Color color(strokeColor());
-    
-    bool shouldAntialiasLine;
-    FloatRect rect = computeLineBoundsAndAntialiasingModeForText(*this, point, width, printing, shouldAntialiasLine, color);
-
+#if PLATFORM(IOS)
     if (m_state.shouldUseContextColors)
-        setCGFillColor(context, color, strokeColorSpace());
-    CGContextFillRect(context, rect);
-
-    CGContextRestoreGState(context);
 #endif
+        if (fillColorIsNotEqualToStrokeColor)
+            setCGFillColor(platformContext(), fillColor(), fillColorSpace());
 }
 
 void GraphicsContext::drawLinesForText(const FloatPoint& point, const DashArray& widths, bool printing)
@@ -1489,9 +1432,11 @@
     if (widths.size() <= 0)
         return;
 
-#if !PLATFORM(IOS)
+    Color localStrokeColor(strokeColor());
+
     bool shouldAntialiasLine;
-    FloatRect bounds = computeLineBoundsAndAntialiasingModeForText(*this, point, widths.last(), printing, shouldAntialiasLine);
+    FloatRect bounds = computeLineBoundsAndAntialiasingModeForText(*this, point, widths.last(), printing, shouldAntialiasLine, localStrokeColor);
+    bool fillColorIsNotEqualToStrokeColor = fillColor() != localStrokeColor;
     
     Vector<CGRect, 4> dashBounds;
     ASSERT(!(widths.size() % 2));
@@ -1499,43 +1444,19 @@
     for (size_t i = 0; i < widths.size(); i += 2)
         dashBounds.append(CGRectMake(bounds.x() + widths[i], bounds.y(), widths[i+1] - widths[i], bounds.height()));
 
-    bool savedShouldAntialias = shouldAntialias();
-    bool restoreAntialiasMode = savedShouldAntialias != shouldAntialiasLine;
+#if PLATFORM(IOS)
+    if (m_state.shouldUseContextColors)
+#endif
+        if (fillColorIsNotEqualToStrokeColor)
+            setCGFillColor(platformContext(), localStrokeColor, strokeColorSpace());
 
-    if (restoreAntialiasMode)
-        CGContextSetShouldAntialias(platformContext(), shouldAntialiasLine);
-
-    bool fillColorIsNotEqualToStrokeColor = fillColor() != strokeColor();
-    if (fillColorIsNotEqualToStrokeColor)
-        setCGFillColor(platformContext(), strokeColor(), strokeColorSpace());
     CGContextFillRects(platformContext(), dashBounds.data(), dashBounds.size());
-    if (fillColorIsNotEqualToStrokeColor)
-        setCGFillColor(platformContext(), fillColor(), fillColorSpace());
-    CGContextSetShouldAntialias(platformContext(), savedShouldAntialias);
 
-    if (restoreAntialiasMode)
-        CGContextSetShouldAntialias(platformContext(), true);
-#else
-    CGContextRef context = platformContext();
-    CGContextSaveGState(context);
-
-    Color color(strokeColor());
-    
-    bool shouldAntialiasLine;
-    FloatRect rect = computeLineBoundsAndAntialiasingModeForText(*this, point, widths.last(), printing, shouldAntialiasLine, color);
-    
-    Vector<CGRect, 4> dashBounds;
-    ASSERT(!(widths.size() % 2));
-    dashBounds.reserveInitialCapacity(dashBounds.size() / 2);
-    for (size_t i = 0; i < widths.size(); i += 2)
-        dashBounds.append(CGRectMake(rect.x() + widths[i], rect.y(), widths[i+1] - widths[i], rect.height()));
-
+#if PLATFORM(IOS)
     if (m_state.shouldUseContextColors)
-        setCGFillColor(context, color, strokeColorSpace());
-    CGContextFillRects(context, dashBounds.data(), dashBounds.size());
-
-    CGContextRestoreGState(context);
 #endif
+        if (fillColorIsNotEqualToStrokeColor)
+            setCGFillColor(platformContext(), fillColor(), fillColorSpace());
 }
 
 void GraphicsContext::setURLForRect(const URL& link, const IntRect& destRect)

Modified: trunk/Source/WebCore/rendering/InlineTextBox.cpp (163920 => 163921)


--- trunk/Source/WebCore/rendering/InlineTextBox.cpp	2014-02-12 01:53:03 UTC (rev 163920)
+++ trunk/Source/WebCore/rendering/InlineTextBox.cpp	2014-02-12 01:54:19 UTC (rev 163921)
@@ -1059,9 +1059,7 @@
     
     // Use a special function for underlines to get the positioning exactly right.
     bool isPrinting = renderer().document().printing();
-#if !PLATFORM(IOS)
-    context.setStrokeThickness(textDecorationThickness);
-#else
+
     // On iOS we want to draw crisp decorations. The function drawLineForText takes the context's
     // strokeThickness and renders that at device pixel scale (i.e. a strokeThickness of 1 will
     // produce a 1 device pixel line, so thinner on retina than non-retina). We will also scale
@@ -1075,7 +1073,6 @@
     float fontSizeScaling = renderer().style().fontSize() / textDecorationBaseFontSize;
     float strokeThickness = roundf(textDecorationThickness * fontSizeScaling * pageScale);
     context.setStrokeThickness(strokeThickness);
-#endif
 
     bool linesAreOpaque = !isPrinting && (!(decoration & TextDecorationUnderline) || underline.alpha() == 255) && (!(decoration & TextDecorationOverline) || overline.alpha() == 255) && (!(decoration & TextDecorationLineThrough) || linethrough.alpha() == 255);
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to