Title: [224814] trunk/Source/WebCore
Revision
224814
Author
zandober...@gmail.com
Date
2017-11-14 05:45:09 -0800 (Tue, 14 Nov 2017)

Log Message

[Cairo] Move drawLinesForText operation from GraphicsContextCairo to CairoOperations
https://bugs.webkit.org/show_bug.cgi?id=179661

Reviewed by Carlos Garcia Campos.

Encapsulate the drawLinesForText() operation in the WebCore::Cairo
namespace. Apart from moving gist of the code from GraphicsContextCairo
to CairoOperations, we also (for the moment) have to duplicate the
GraphicsContext::computeLineBoundsAndAntialiasingModeForText() code.
This is necessary because the given method is private on the
GraphicsContext class, and relies on an underlying GraphicsContext
object to retrieve the current CTM and stroke thickness values.

The adjusted reimplementation uses PlatformContextCairo to retrieve
the CTM (just like Cairo's GraphicsContext::getCTM() does), and
requires the stroke thickness value to be passed in as an argument.
Similar modifications will be proposed for the existing
GraphicsContext::computeLineBoundsAndAntialiasingModeForText() code,
and once that's approved the duplicated code will be eliminated.

No new tests -- no change in behavior.

* platform/graphics/cairo/CairoOperations.cpp:
(WebCore::Cairo::computeLineBoundsAndAntialiasingModeForText):
(WebCore::Cairo::drawLinesForText):
* platform/graphics/cairo/CairoOperations.h:
* platform/graphics/cairo/GraphicsContextCairo.cpp:
(WebCore::GraphicsContext::drawLinesForText):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (224813 => 224814)


--- trunk/Source/WebCore/ChangeLog	2017-11-14 13:42:14 UTC (rev 224813)
+++ trunk/Source/WebCore/ChangeLog	2017-11-14 13:45:09 UTC (rev 224814)
@@ -1,5 +1,36 @@
 2017-11-14  Zan Dobersek  <zdober...@igalia.com>
 
+        [Cairo] Move drawLinesForText operation from GraphicsContextCairo to CairoOperations
+        https://bugs.webkit.org/show_bug.cgi?id=179661
+
+        Reviewed by Carlos Garcia Campos.
+
+        Encapsulate the drawLinesForText() operation in the WebCore::Cairo
+        namespace. Apart from moving gist of the code from GraphicsContextCairo
+        to CairoOperations, we also (for the moment) have to duplicate the
+        GraphicsContext::computeLineBoundsAndAntialiasingModeForText() code.
+        This is necessary because the given method is private on the
+        GraphicsContext class, and relies on an underlying GraphicsContext
+        object to retrieve the current CTM and stroke thickness values.
+
+        The adjusted reimplementation uses PlatformContextCairo to retrieve
+        the CTM (just like Cairo's GraphicsContext::getCTM() does), and
+        requires the stroke thickness value to be passed in as an argument.
+        Similar modifications will be proposed for the existing
+        GraphicsContext::computeLineBoundsAndAntialiasingModeForText() code,
+        and once that's approved the duplicated code will be eliminated.
+
+        No new tests -- no change in behavior.
+
+        * platform/graphics/cairo/CairoOperations.cpp:
+        (WebCore::Cairo::computeLineBoundsAndAntialiasingModeForText):
+        (WebCore::Cairo::drawLinesForText):
+        * platform/graphics/cairo/CairoOperations.h:
+        * platform/graphics/cairo/GraphicsContextCairo.cpp:
+        (WebCore::GraphicsContext::drawLinesForText):
+
+2017-11-14  Zan Dobersek  <zdober...@igalia.com>
+
         [Cairo] Move native image drawing operation to CairoOperations
         https://bugs.webkit.org/show_bug.cgi?id=179660
 

Modified: trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp (224813 => 224814)


--- trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp	2017-11-14 13:42:14 UTC (rev 224813)
+++ trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp	2017-11-14 13:45:09 UTC (rev 224814)
@@ -236,6 +236,36 @@
     return cairo_surface_get_content(surface) != CAIRO_CONTENT_COLOR;
 }
 
+// FIXME: Fix GraphicsContext::computeLineBoundsAndAntialiasingModeForText()
+// to be a static public function that operates on CTM and strokeThickness
+// arguments instead of using an underlying GraphicsContext object.
+FloatRect computeLineBoundsAndAntialiasingModeForText(PlatformContextCairo& platformContext, const FloatPoint& point, float width, bool printing, Color& color, float strokeThickness)
+{
+    FloatPoint origin = point;
+    float thickness = std::max(strokeThickness, 0.5f);
+    if (printing)
+        return FloatRect(origin, FloatSize(width, thickness));
+
+    AffineTransform transform = Cairo::State::getCTM(platformContext);
+    // Just compute scale in x dimension, assuming x and y scales are equal.
+    float scale = transform.b() ? sqrtf(transform.a() * transform.a() + transform.b() * transform.b()) : transform.a();
+    if (scale < 1.0) {
+        // This code always draws a line that is at least one-pixel line high,
+        // which tends to visually overwhelm text at small scales. To counter this
+        // effect, an alpha is applied to the underline color when text is at small scales.
+        static const float minimumUnderlineAlpha = 0.4f;
+        float shade = scale > minimumUnderlineAlpha ? scale : minimumUnderlineAlpha;
+        color = color.colorWithAlphaMultipliedBy(shade);
+    }
+
+    FloatPoint devicePoint = transform.mapPoint(point);
+    // Visual overflow might occur here due to integral roundf/ceilf. visualOverflowForDecorations adjusts the overflow value for underline decoration.
+    FloatPoint deviceOrigin = FloatPoint(roundf(devicePoint.x()), ceilf(devicePoint.y()));
+    if (auto inverse = transform.inverse())
+        origin = inverse.value().mapPoint(deviceOrigin);
+    return FloatRect(origin, FloatSize(width, thickness));
+};
+
 namespace State {
 
 void setStrokeThickness(PlatformContextCairo& platformContext, float strokeThickness)
@@ -626,6 +656,32 @@
     cairo_restore(cr);
 }
 
+void drawLinesForText(PlatformContextCairo& platformContext, const FloatPoint& point, const DashArray& widths, bool printing, bool doubleUnderlines, const Color& color, float strokeThickness)
+{
+    Color modifiedColor = color;
+    FloatRect bounds = computeLineBoundsAndAntialiasingModeForText(platformContext, point, widths.last(), printing, modifiedColor, strokeThickness);
+
+    Vector<FloatRect, 4> dashBounds;
+    ASSERT(!(widths.size() % 2));
+    dashBounds.reserveInitialCapacity(dashBounds.size() / 2);
+    for (size_t i = 0; i < widths.size(); i += 2)
+        dashBounds.append(FloatRect(FloatPoint(bounds.x() + widths[i], bounds.y()), FloatSize(widths[i+1] - widths[i], bounds.height())));
+
+    if (doubleUnderlines) {
+        // The space between double underlines is equal to the height of the underline
+        for (size_t i = 0; i < widths.size(); i += 2)
+            dashBounds.append(FloatRect(FloatPoint(bounds.x() + widths[i], bounds.y() + 2 * bounds.height()), FloatSize(widths[i+1] - widths[i], bounds.height())));
+    }
+
+    cairo_t* cr = platformContext.cr();
+    cairo_save(cr);
+
+    for (auto& dash : dashBounds)
+        fillRectWithColor(cr, dash, modifiedColor);
+
+    cairo_restore(cr);
+}
+
 void drawLineForDocumentMarker(PlatformContextCairo& platformContext, const FloatPoint& origin, float width, GraphicsContext::DocumentMarkerLineStyle style)
 {
     if (style != GraphicsContext::DocumentMarkerSpellingLineStyle

Modified: trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.h (224813 => 224814)


--- trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.h	2017-11-14 13:42:14 UTC (rev 224813)
+++ trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.h	2017-11-14 13:45:09 UTC (rev 224814)
@@ -99,6 +99,7 @@
 void drawPattern(PlatformContextCairo&, Image&, const FloatRect&, const FloatRect&, const AffineTransform&, const FloatPoint&, CompositeOperator, BlendMode);
 
 void drawRect(PlatformContextCairo&, const FloatRect&, float, const GraphicsContextState&);
+void drawLinesForText(PlatformContextCairo&, const FloatPoint&, const DashArray&, bool, bool, const Color&, float);
 void drawLineForDocumentMarker(PlatformContextCairo&, const FloatPoint&, float, GraphicsContext::DocumentMarkerLineStyle);
 void drawEllipse(PlatformContextCairo&, const FloatRect&, const GraphicsContextState&);
 

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


--- trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp	2017-11-14 13:42:14 UTC (rev 224813)
+++ trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp	2017-11-14 13:45:09 UTC (rev 224814)
@@ -503,29 +503,8 @@
         return;
     }
 
-    Color localStrokeColor(strokeColor());
-
-    FloatRect bounds = computeLineBoundsAndAntialiasingModeForText(point, widths.last(), printing, localStrokeColor);
-
-    Vector<FloatRect, 4> dashBounds;
-    ASSERT(!(widths.size() % 2));
-    dashBounds.reserveInitialCapacity(dashBounds.size() / 2);
-    for (size_t i = 0; i < widths.size(); i += 2)
-        dashBounds.append(FloatRect(FloatPoint(bounds.x() + widths[i], bounds.y()), FloatSize(widths[i+1] - widths[i], bounds.height())));
-
-    if (doubleUnderlines) {
-        // The space between double underlines is equal to the height of the underline
-        for (size_t i = 0; i < widths.size(); i += 2)
-            dashBounds.append(FloatRect(FloatPoint(bounds.x() + widths[i], bounds.y() + 2 * bounds.height()), FloatSize(widths[i+1] - widths[i], bounds.height())));
-    }
-
-    cairo_t* cr = platformContext()->cr();
-    cairo_save(cr);
-
-    for (auto& dash : dashBounds)
-        fillRectWithColor(cr, dash, localStrokeColor);
-
-    cairo_restore(cr);
+    ASSERT(hasPlatformContext());
+    Cairo::drawLinesForText(*platformContext(), point, widths, printing, doubleUnderlines, m_state.strokeColor, m_state.strokeThickness);
 }
 
 void GraphicsContext::updateDocumentMarkerResources()
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to