Title: [158392] trunk/Source/WebCore
Revision
158392
Author
[email protected]
Date
2013-10-31 14:14:26 -0700 (Thu, 31 Oct 2013)

Log Message

Underline bounds cannot be queried before underline itself is drawn
https://bugs.webkit.org/show_bug.cgi?id=123310

Patch by Myles C. Maxfield <[email protected]> on 2013-10-31
Reviewed by Dean Jackson.

GraphicsContext's drawLineForText function is used to draw underlines,
strikethroughs, and overlines. Before drawing the line, this function
modifies the bounds given to it in order to make underlines crisp. However,
this means that it is impossible to know where an underline will be drawn
before drawing it. This patch pulls out this adjustment computation into
GraphicsContext::computeLineBoundsForText, then passes the result to
drawLineForText

Because there should be no observable difference, no tests need to be updated.

* platform/graphics/GraphicsContext.h: Signature of new computeLineBoundsForText
function
* platform/graphics/blackberry/PathBlackBerry.cpp:
(WebCore::GraphicsContext::computeLineBoundsForText): Implement new function
* platform/graphics/cairo/GraphicsContextCairo.cpp:
(WebCore::GraphicsContext::computeLineBoundsForText): Ditto
(WebCore::GraphicsContext::drawLineForText): Use computeLineBoundsForText
* platform/graphics/cg/GraphicsContextCG.cpp:
(WebCore::computeLineBoundsAndAntialiasingModeForText): Static function that
performs the actual bounds computation
(WebCore::GraphicsContext::computeLineBoundsForText): Calls
computeLineBoundsAndAntialiasingModeForText
(WebCore::GraphicsContext::drawLineForText): Use new function
* platform/graphics/wince/GraphicsContextWinCE.cpp:
(WebCore::GraphicsContext::computeLineBoundsForText): Implement new function

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (158391 => 158392)


--- trunk/Source/WebCore/ChangeLog	2013-10-31 21:03:15 UTC (rev 158391)
+++ trunk/Source/WebCore/ChangeLog	2013-10-31 21:14:26 UTC (rev 158392)
@@ -1,3 +1,36 @@
+2013-10-31  Myles C. Maxfield  <[email protected]>
+
+        Underline bounds cannot be queried before underline itself is drawn
+        https://bugs.webkit.org/show_bug.cgi?id=123310
+
+        Reviewed by Dean Jackson.
+
+        GraphicsContext's drawLineForText function is used to draw underlines,
+        strikethroughs, and overlines. Before drawing the line, this function
+        modifies the bounds given to it in order to make underlines crisp. However,
+        this means that it is impossible to know where an underline will be drawn
+        before drawing it. This patch pulls out this adjustment computation into
+        GraphicsContext::computeLineBoundsForText, then passes the result to
+        drawLineForText
+
+        Because there should be no observable difference, no tests need to be updated.
+
+        * platform/graphics/GraphicsContext.h: Signature of new computeLineBoundsForText
+        function
+        * platform/graphics/blackberry/PathBlackBerry.cpp:
+        (WebCore::GraphicsContext::computeLineBoundsForText): Implement new function
+        * platform/graphics/cairo/GraphicsContextCairo.cpp:
+        (WebCore::GraphicsContext::computeLineBoundsForText): Ditto
+        (WebCore::GraphicsContext::drawLineForText): Use computeLineBoundsForText
+        * platform/graphics/cg/GraphicsContextCG.cpp:
+        (WebCore::computeLineBoundsAndAntialiasingModeForText): Static function that
+        performs the actual bounds computation
+        (WebCore::GraphicsContext::computeLineBoundsForText): Calls
+        computeLineBoundsAndAntialiasingModeForText
+        (WebCore::GraphicsContext::drawLineForText): Use new function
+        * platform/graphics/wince/GraphicsContextWinCE.cpp:
+        (WebCore::GraphicsContext::computeLineBoundsForText): Implement new function
+
 2013-10-31  Beth Dakin  <[email protected]>
 
         Repro scrolling crash with scrollbars that use setPresentationValue on the 

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.h (158391 => 158392)


--- trunk/Source/WebCore/platform/graphics/GraphicsContext.h	2013-10-31 21:03:15 UTC (rev 158391)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.h	2013-10-31 21:14:26 UTC (rev 158392)
@@ -330,6 +330,7 @@
         };
         FloatRect roundToDevicePixels(const FloatRect&, RoundingMode = RoundAllSides);
 
+        FloatRect computeLineBoundsForText(const FloatPoint&, float width, bool printing);
         void drawLineForText(const FloatPoint&, float width, bool printing);
         enum DocumentMarkerLineStyle {
             DocumentMarkerSpellingLineStyle,

Modified: trunk/Source/WebCore/platform/graphics/blackberry/PathBlackBerry.cpp (158391 => 158392)


--- trunk/Source/WebCore/platform/graphics/blackberry/PathBlackBerry.cpp	2013-10-31 21:03:15 UTC (rev 158391)
+++ trunk/Source/WebCore/platform/graphics/blackberry/PathBlackBerry.cpp	2013-10-31 21:14:26 UTC (rev 158392)
@@ -263,6 +263,11 @@
     platformContext()->addDrawLineForDocumentMarker(pt, width, (BlackBerry::Platform::Graphics::DocumentMarkerLineStyle)style);
 }
 
+FloatRect GraphicsContext::computeLineBoundsForText(const FloatPoint& pt, float width, bool printing)
+{
+    return FloatRect(pt, FloatSize(width, strokeThickness()));
+}
+
 void GraphicsContext::drawLineForText(const FloatPoint& pt, float width, bool printing)
 {
     if (paintingDisabled())

Modified: trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp (158391 => 158392)


--- trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp	2013-10-31 21:03:15 UTC (rev 158391)
+++ trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp	2013-10-31 21:14:26 UTC (rev 158392)
@@ -614,8 +614,13 @@
     cairo_restore(cr);
 }
 
-void GraphicsContext::drawLineForText(const FloatPoint& origin, float width, bool)
+FloatRect GraphicsContext::computeLineBoundsForText(const FloatPoint& origin, float width, bool)
 {
+    return FloatRect(origin, FloatSize(width, strokeThickness()));
+}
+
+void GraphicsContext::drawLineForText(const FloatPoint& origin, float width, bool printing)
+{
     if (paintingDisabled())
         return;
 
@@ -624,7 +629,7 @@
 
     // This bumping of <1 stroke thicknesses matches the one in drawLineOnCairoContext.
     FloatPoint endPoint(origin + IntSize(width, 0));
-    FloatRect lineExtents(origin, FloatSize(width, strokeThickness()));
+    FloatRect lineExtents = computeLineBoundsForText(origin, width, printing);
 
     ShadowBlur& shadow = platformContext()->shadowBlur();
     if (GraphicsContext* shadowContext = shadow.beginShadowLayer(this, lineExtents)) {

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


--- trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp	2013-10-31 21:03:15 UTC (rev 158391)
+++ trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp	2013-10-31 21:14:26 UTC (rev 158392)
@@ -1235,6 +1235,42 @@
     return FloatRect(roundedOrigin, roundedLowerRight - roundedOrigin);
 }
 
+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, max(context.strokeThickness(), 0.5f)));
+
+    if (printing || !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(max(initialBounds.width(), 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);
+}
+
 void GraphicsContext::drawLineForText(const FloatPoint& point, float width, bool printing)
 {
     if (paintingDisabled())
@@ -1243,42 +1279,21 @@
     if (width <= 0)
         return;
 
-    float x = point.x();
-    float y = point.y();
-    float lineLength = width;
+    bool shouldAntialiasLine;
+    FloatRect bounds = computeLineBoundsAndAntialiasingModeForText(*this, point, width, printing, shouldAntialiasLine);
 
-    // 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.
-    float thickness = max(strokeThickness(), 0.5f);
+    bool savedShouldAntialias = shouldAntialias();
+    bool restoreAntialiasMode = savedShouldAntialias != shouldAntialiasLine;
 
-    bool restoreAntialiasMode = false;
+    if (restoreAntialiasMode)
+        CGContextSetShouldAntialias(platformContext(), shouldAntialiasLine);
 
-    if (!printing && getCTM(GraphicsContext::DefinitelyIncludeDeviceScale).preservesAxisAlignment()) {
-        // On screen, use a minimum thickness of 1.0 in user space (later rounded to an integral number in device space).
-        float adjustedThickness = max(thickness, 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.
-        CGRect lineRect = roundToDevicePixels(FloatRect(x, y, lineLength, adjustedThickness), RoundAllSides);
-        if (lineRect.size.height < thickness * 2.0) {
-            x = lineRect.origin.x;
-            y = lineRect.origin.y;
-            lineLength = lineRect.size.width;
-            thickness = lineRect.size.height;
-            if (shouldAntialias()) {
-                CGContextSetShouldAntialias(platformContext(), false);
-                restoreAntialiasMode = true;
-            }
-        }
-    }
-
     if (fillColor() != strokeColor())
         setCGFillColor(platformContext(), strokeColor(), strokeColorSpace());
-    CGContextFillRect(platformContext(), CGRectMake(x, y, lineLength, thickness));
+    CGContextFillRect(platformContext(), bounds);
     if (fillColor() != strokeColor())
         setCGFillColor(platformContext(), fillColor(), fillColorSpace());
+    CGContextSetShouldAntialias(platformContext(), savedShouldAntialias);
 
     if (restoreAntialiasMode)
         CGContextSetShouldAntialias(platformContext(), true);

Modified: trunk/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp (158391 => 158392)


--- trunk/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp	2013-10-31 21:03:15 UTC (rev 158391)
+++ trunk/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp	2013-10-31 21:14:26 UTC (rev 158392)
@@ -950,6 +950,11 @@
     DrawFocusRect(dc, &rect);
 }
 
+FloatRect GraphicsContext::computeLineBoundsForText(const FloatPoint& origin, float width, bool printing)
+{
+    return FloatRect(origin, FloatSize(width, strokeThickness()));
+}
+
 void GraphicsContext::drawLineForText(const FloatPoint& origin, float width, bool printing)
 {
     if (paintingDisabled())
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to