Title: [120314] trunk
Revision
120314
Author
[email protected]
Date
2012-06-14 05:18:15 -0700 (Thu, 14 Jun 2012)

Log Message

[svg] SVGResources applied to Text with Incorrect Transformations in non-CG Implementations
https://bugs.webkit.org/show_bug.cgi?id=64966

Patch by Dominik Röttsches <[email protected]> on 2012-06-14
Reviewed by Nikolas Zimmermann.

Source/WebCore:

SVGInlineTextBox::paintTextWithShadows for non-CG implementations resets the scale aspect
of the currently applied CTM. This leads to patterns and gradients being incorrectly downscaled.
This way of resetting the CTM and drawing fonts "natively" scaled was introduced
in r77485 to fix a number of issues with SVG font scaling.
Unfortunately, this breaks scaling of patterns and gradients. To fix it,
we need to push the transformation back into the pattern/gradient space transformation.

Tests: svg/transforms/transformed-text-fill-gradient.html
       svg/transforms/transformed-text-fill-pattern.html

* rendering/svg/RenderSVGInlineText.cpp:
(WebCore::RenderSVGInlineText::computeNewScaledFontForStyle): Moving the scaling factor calculation out into SVGRenderingContext.
* rendering/svg/RenderSVGResourceContainer.cpp:
(WebCore::RenderSVGResourceContainer::shouldTransformOnTextPainting): Reusing the scaling factor calculation from SVGRenderingContext.
(WebCore):
* rendering/svg/RenderSVGResourceContainer.h:
(RenderSVGResourceContainer):
* rendering/svg/RenderSVGResourceGradient.cpp:
(WebCore::RenderSVGResourceGradient::applyResource): If needed, push down transformation into gradient space.
* rendering/svg/RenderSVGResourcePattern.cpp:
(WebCore::RenderSVGResourcePattern::applyResource): If needed, push transformation into pattern space.
* rendering/svg/SVGRenderingContext.cpp:
(WebCore::SVGRenderingContext::calculateScreenFontSizeScalingFactor): Common scaling factor calculation for RenderSVGInlineText and RenderSVGResourceContainer.
* rendering/svg/SVGRenderingContext.h:
(SVGRenderingContext):

LayoutTests:

For Pattern: RefTest that compare a scaled rectangle with a scaled block of Ahem characters.
The pattern or gradient should scale in the same way for the text and the rectangle.
This approach needs a clipping path hack to work around micro gaps between Ahem characters
due to rounding.
For Gradient: Scaling text at two different scale factors and adjusting font size to yield the same effective text size.
Gradient fill should be identical in both cases.

* platform/chromium/TestExpectations: Added 3 tests that need rebaselining for text gradient fills.
* svg/transforms/transformed-text-fill-gradient-expected.html: Added.
* svg/transforms/transformed-text-fill-gradient.html: Added.
* svg/transforms/transformed-text-fill-pattern-expected.html: Added.
* svg/transforms/transformed-text-fill-pattern.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (120313 => 120314)


--- trunk/LayoutTests/ChangeLog	2012-06-14 11:53:43 UTC (rev 120313)
+++ trunk/LayoutTests/ChangeLog	2012-06-14 12:18:15 UTC (rev 120314)
@@ -1,3 +1,23 @@
+2012-06-14  Dominik Röttsches  <[email protected]>
+
+        [svg] SVGResources applied to Text with Incorrect Transformations in non-CG Implementations
+        https://bugs.webkit.org/show_bug.cgi?id=64966
+
+        Reviewed by Nikolas Zimmermann.
+
+        For Pattern: RefTest that compare a scaled rectangle with a scaled block of Ahem characters.
+        The pattern or gradient should scale in the same way for the text and the rectangle.
+        This approach needs a clipping path hack to work around micro gaps between Ahem characters
+        due to rounding.
+        For Gradient: Scaling text at two different scale factors and adjusting font size to yield the same effective text size.
+        Gradient fill should be identical in both cases.
+
+        * platform/chromium/TestExpectations: Added 3 tests that need rebaselining for text gradient fills.
+        * svg/transforms/transformed-text-fill-gradient-expected.html: Added.
+        * svg/transforms/transformed-text-fill-gradient.html: Added.
+        * svg/transforms/transformed-text-fill-pattern-expected.html: Added.
+        * svg/transforms/transformed-text-fill-pattern.html: Added.
+
 2012-06-14  Jan Keromnes  <[email protected]>
 
         Web Inspector: Implement ExtensionPanel.show() method

Modified: trunk/LayoutTests/platform/chromium/TestExpectations (120313 => 120314)


--- trunk/LayoutTests/platform/chromium/TestExpectations	2012-06-14 11:53:43 UTC (rev 120313)
+++ trunk/LayoutTests/platform/chromium/TestExpectations	2012-06-14 12:18:15 UTC (rev 120314)
@@ -3725,3 +3725,8 @@
 BUGWK88832 XP : http/tests/xmlhttprequest/origin-exact-matching.html = PASS TIMEOUT
 
 BUGWK88856 : fast/events/constructors/speech-recognition-event-constructor.html = TEXT
+
+// Need rebaselining because of text gradient fill rendering fix.
+BUGWK64966 : svg/W3C-SVG-1.1/pservers-grad-08-b.svg = IMAGE
+BUGWK64966 : svg/custom/js-late-gradient-and-object-creation.svg = IMAGE
+BUGWK64966 : svg/custom/text-rotated-gradient.svg = IMAGE
\ No newline at end of file

Added: trunk/LayoutTests/svg/transforms/transformed-text-fill-gradient-expected.html (0 => 120314)


--- trunk/LayoutTests/svg/transforms/transformed-text-fill-gradient-expected.html	                        (rev 0)
+++ trunk/LayoutTests/svg/transforms/transformed-text-fill-gradient-expected.html	2012-06-14 12:18:15 UTC (rev 120314)
@@ -0,0 +1,14 @@
+<html><body><svg width="600" height="600" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+   <lineargradient x1="0" x2="1" id="gradient">
+     <stop stop-color="#f00" offset="0"></stop>
+     <stop stop-color="#0f0" offset="0.5"></stop>
+     <stop stop-color="#00f" offset="1"></stop>
+   </lineargradient>
+ </defs>
+ <g transform="scale(6)" y="50">
+   <text y="10" font-size="10" fill="url(#gradient)">Text needs to have identical gradient.</text>
+ </g>
+</svg>
+</body>
+</html>

Added: trunk/LayoutTests/svg/transforms/transformed-text-fill-gradient.html (0 => 120314)


--- trunk/LayoutTests/svg/transforms/transformed-text-fill-gradient.html	                        (rev 0)
+++ trunk/LayoutTests/svg/transforms/transformed-text-fill-gradient.html	2012-06-14 12:18:15 UTC (rev 120314)
@@ -0,0 +1,14 @@
+<html><body><svg width="600" height="600" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+   <lineargradient x1="0" x2="1" id="gradient">
+     <stop stop-color="#f00" offset="0"></stop>
+     <stop stop-color="#0f0" offset="0.5"></stop>
+     <stop stop-color="#00f" offset="1"></stop>
+   </lineargradient>
+ </defs>
+ <g transform="scale(3)" y="50">
+   <text y="20" font-size="20" fill="url(#gradient)">Text needs to have identical gradient.</text>
+ </g>
+</svg>
+</body>
+</html>

Added: trunk/LayoutTests/svg/transforms/transformed-text-fill-pattern-expected.html (0 => 120314)


--- trunk/LayoutTests/svg/transforms/transformed-text-fill-pattern-expected.html	                        (rev 0)
+++ trunk/LayoutTests/svg/transforms/transformed-text-fill-pattern-expected.html	2012-06-14 12:18:15 UTC (rev 120314)
@@ -0,0 +1,25 @@
+<html><body><svg width="1000" height="600" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+   <pattern id="hatch" patternUnits="userSpaceOnUse" x="0" y="0" width="10" height="10">
+     <g style="fill:none; stroke:black; stroke-width:1">
+       <path d="M0,0 l10,10"/>
+       <path d="M10,0 l-10,10"/>
+     </g>
+   </pattern>
+   <clipPath id="clipHack">
+     <rect x="3" y="0" width="24" height="600"></rect>
+     <rect x="33" y="10" width="24" height="600"></rect>
+     <rect x="63" y="0" width="24" height="600"></rect>
+     <rect x="93" y="0" width="24" height="600"></rect>
+     <rect x="123" y="0" width="24" height="600"></rect>
+   </clipPath>
+ </defs>
+ <g transform="scale(4)" clip-path="url(#clipHack)">
+  <rect y="26" width="150" height="30" fill="url(#hatch)">
+ </g>
+ <g transform="scale(6)" clip-path="url(#clipHack)">
+  <rect y="66" x="0" width="150" height="30" fill="url(#hatch)">
+ </g>
+</svg>
+</body>
+</html>

Added: trunk/LayoutTests/svg/transforms/transformed-text-fill-pattern.html (0 => 120314)


--- trunk/LayoutTests/svg/transforms/transformed-text-fill-pattern.html	                        (rev 0)
+++ trunk/LayoutTests/svg/transforms/transformed-text-fill-pattern.html	2012-06-14 12:18:15 UTC (rev 120314)
@@ -0,0 +1,39 @@
+<html><body><svg width="1000" height="600" xmlns="http://www.w3.org/2000/svg">
+ <!-- The pattern needs to scale with the text in the same way it scales with rectangles. -->
+ <defs>
+   <pattern id="hatch" patternUnits="userSpaceOnUse" x="0" y="0" width="10" height="10">
+     <g style="fill:none; stroke:black; stroke-width:1">
+       <path d="M0,0 l10,10"/>
+       <path d="M10,0 l-10,10"/>
+     </g>
+   </pattern>
+   <style type="text/css"><![CDATA[
+    @font-face {
+        font-family: Ahem;
+        src: url(../../resources/Ahem.ttf);
+    }
+    .ahemblock {
+        font-family: Ahem;
+        font-size: 30px;
+    }
+    ]]>
+   </style>
+   <!-- Masking away the micro-gaps between the Ahem characters that may occur due to rounding
+        which causes this test to fail on platforms that run reftests with zero tolerance. -->
+   <clipPath id="clipHack">
+     <rect x="3" y="0" width="24" height="600"></rect>
+     <rect x="33" y="10" width="24" height="600"></rect>
+     <rect x="63" y="0" width="24" height="600"></rect>
+     <rect x="93" y="0" width="24" height="600"></rect>
+     <rect x="123" y="0" width="24" height="600"></rect>
+   </clipPath>
+ </defs>
+ <g transform="scale(4)" clip-path="url(#clipHack)">
+  <text class="ahemblock"  y="50" fill="url(#hatch)">AAAAA</text>
+ </g>
+ <g transform="scale(6)" clip-path="url(#clipHack)">
+  <text class="ahemblock" y="90" x="0" fill="url(#hatch)">AAAAA</text>
+ </g>
+</svg>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (120313 => 120314)


--- trunk/Source/WebCore/ChangeLog	2012-06-14 11:53:43 UTC (rev 120313)
+++ trunk/Source/WebCore/ChangeLog	2012-06-14 12:18:15 UTC (rev 120314)
@@ -1,3 +1,36 @@
+2012-06-14  Dominik Röttsches  <[email protected]>
+
+        [svg] SVGResources applied to Text with Incorrect Transformations in non-CG Implementations
+        https://bugs.webkit.org/show_bug.cgi?id=64966
+
+        Reviewed by Nikolas Zimmermann.
+
+        SVGInlineTextBox::paintTextWithShadows for non-CG implementations resets the scale aspect
+        of the currently applied CTM. This leads to patterns and gradients being incorrectly downscaled.
+        This way of resetting the CTM and drawing fonts "natively" scaled was introduced
+        in r77485 to fix a number of issues with SVG font scaling.
+        Unfortunately, this breaks scaling of patterns and gradients. To fix it,
+        we need to push the transformation back into the pattern/gradient space transformation.
+
+        Tests: svg/transforms/transformed-text-fill-gradient.html
+               svg/transforms/transformed-text-fill-pattern.html
+
+        * rendering/svg/RenderSVGInlineText.cpp:
+        (WebCore::RenderSVGInlineText::computeNewScaledFontForStyle): Moving the scaling factor calculation out into SVGRenderingContext.
+        * rendering/svg/RenderSVGResourceContainer.cpp:
+        (WebCore::RenderSVGResourceContainer::shouldTransformOnTextPainting): Reusing the scaling factor calculation from SVGRenderingContext.
+        (WebCore):
+        * rendering/svg/RenderSVGResourceContainer.h:
+        (RenderSVGResourceContainer):
+        * rendering/svg/RenderSVGResourceGradient.cpp:
+        (WebCore::RenderSVGResourceGradient::applyResource): If needed, push down transformation into gradient space.
+        * rendering/svg/RenderSVGResourcePattern.cpp:
+        (WebCore::RenderSVGResourcePattern::applyResource): If needed, push transformation into pattern space.
+        * rendering/svg/SVGRenderingContext.cpp:
+        (WebCore::SVGRenderingContext::calculateScreenFontSizeScalingFactor): Common scaling factor calculation for RenderSVGInlineText and RenderSVGResourceContainer.
+        * rendering/svg/SVGRenderingContext.h:
+        (SVGRenderingContext):
+
 2012-06-14  Yoshifumi Inoue  <[email protected]>
 
         [Form] Replace InputNumber type to Decimal type and drop InputNumber

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp (120313 => 120314)


--- trunk/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp	2012-06-14 11:53:43 UTC (rev 120313)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp	2012-06-14 12:18:15 UTC (rev 120314)
@@ -232,9 +232,7 @@
     ASSERT(styleResolver);
 
     // Alter font-size to the right on-screen value to avoid scaling the glyphs themselves, except when GeometricPrecision is specified
-    AffineTransform ctm;
-    SVGRenderingContext::calculateTransformationToOutermostSVGCoordinateSystem(renderer, ctm);
-    scalingFactor = narrowPrecisionToFloat(sqrt((pow(ctm.xScale(), 2) + pow(ctm.yScale(), 2)) / 2));
+    scalingFactor = SVGRenderingContext::calculateScreenFontSizeScalingFactor(renderer);
     if (scalingFactor == 1 || !scalingFactor || style->fontDescription().textRenderingMode() == GeometricPrecision) {
         scalingFactor = 1;
         scaledFont = style->font();

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp (120313 => 120314)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp	2012-06-14 11:53:43 UTC (rev 120313)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp	2012-06-14 12:18:15 UTC (rev 120314)
@@ -24,6 +24,7 @@
 
 #include "RenderSVGRoot.h"
 #include "RenderView.h"
+#include "SVGRenderingContext.h"
 #include "SVGResourcesCache.h"
 #include "SVGStyledTransformableElement.h"
 
@@ -170,6 +171,26 @@
     }
 }
 
+bool RenderSVGResourceContainer::shouldTransformOnTextPainting(RenderObject* object, AffineTransform& resourceTransform)
+{
+    ASSERT_UNUSED(object, object);
+#if USE(CG)
+    UNUSED_PARAM(resourceTransform);
+    return false;
+#else
+    ASSERT(object->isSVGText() || object->isSVGTextPath());
+
+    // In text drawing, the scaling part of the graphics context CTM is removed, compare SVGInlineTextBox::paintTextWithShadows.
+    // So, we use that scaling factor here, too, and then push it down to pattern or gradient space
+    // in order to keep the pattern or gradient correctly scaled.
+    float scalingFactor = SVGRenderingContext::calculateScreenFontSizeScalingFactor(object);
+    if (scalingFactor == 1)
+        return false;
+    resourceTransform.scale(scalingFactor);
+    return true;
+#endif
+}
+
 // FIXME: This does not belong here.
 AffineTransform RenderSVGResourceContainer::transformOnNonScalingStroke(RenderObject* object, const AffineTransform& resourceTransform)
 {

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h (120313 => 120314)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h	2012-06-14 11:53:43 UTC (rev 120313)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h	2012-06-14 12:18:15 UTC (rev 120314)
@@ -38,6 +38,7 @@
     virtual bool isSVGResourceContainer() const { return true; }
     virtual RenderSVGResourceContainer* toRenderSVGResourceContainer() { return this; }
 
+    static bool shouldTransformOnTextPainting(RenderObject*, AffineTransform&);
     static AffineTransform transformOnNonScalingStroke(RenderObject*, const AffineTransform& resourceTransform);
 
     void idChanged();

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp (120313 => 120314)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp	2012-06-14 11:53:43 UTC (rev 120313)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp	2012-06-14 12:18:15 UTC (rev 120314)
@@ -166,6 +166,13 @@
         calculateGradientTransform(gradientTransform);
 
         gradientData->userspaceTransform *= gradientTransform;
+        if (isPaintingText) {
+            // Depending on font scaling factor, we may need to rescale the gradient here since
+            // text painting removes the scale factor from the context.
+            AffineTransform additionalTextTransform;
+            if (shouldTransformOnTextPainting(object, additionalTextTransform))
+                gradientData->userspaceTransform *= additionalTextTransform;
+        }
         gradientData->gradient->setGradientSpaceTransform(gradientData->userspaceTransform);
     }
 

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp (120313 => 120314)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp	2012-06-14 11:53:43 UTC (rev 120313)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp	2012-06-14 12:18:15 UTC (rev 120314)
@@ -133,6 +133,12 @@
         if (!patternTransform.isIdentity())
             patternData->transform = patternTransform * patternData->transform;
 
+        // Account for text drawing resetting the context to non-scaled, see SVGInlineTextBox::paintTextWithShadows.
+        if (resourceMode & ApplyToTextMode) {
+            AffineTransform additionalTextTransformation;
+            if (shouldTransformOnTextPainting(object, additionalTextTransformation))
+                patternData->transform *= additionalTextTransformation;
+        }
         patternData->pattern->setPatternSpaceTransform(patternData->transform);
     }
 

Modified: trunk/Source/WebCore/rendering/svg/SVGRenderingContext.cpp (120313 => 120314)


--- trunk/Source/WebCore/rendering/svg/SVGRenderingContext.cpp	2012-06-14 11:53:43 UTC (rev 120313)
+++ trunk/Source/WebCore/rendering/svg/SVGRenderingContext.cpp	2012-06-14 12:18:15 UTC (rev 120314)
@@ -167,6 +167,15 @@
     return s_currentContentTransformation;
 }
 
+float SVGRenderingContext::calculateScreenFontSizeScalingFactor(const RenderObject* renderer)
+{
+    ASSERT(renderer);
+
+    AffineTransform ctm;
+    calculateTransformationToOutermostSVGCoordinateSystem(renderer, ctm);
+    return narrowPrecisionToFloat(sqrt((pow(ctm.xScale(), 2) + pow(ctm.yScale(), 2)) / 2));
+}
+
 void SVGRenderingContext::calculateTransformationToOutermostSVGCoordinateSystem(const RenderObject* renderer, AffineTransform& absoluteTransform)
 {
     const RenderObject* current = renderer;

Modified: trunk/Source/WebCore/rendering/svg/SVGRenderingContext.h (120313 => 120314)


--- trunk/Source/WebCore/rendering/svg/SVGRenderingContext.h	2012-06-14 11:53:43 UTC (rev 120313)
+++ trunk/Source/WebCore/rendering/svg/SVGRenderingContext.h	2012-06-14 12:18:15 UTC (rev 120314)
@@ -83,6 +83,7 @@
     static void renderSubtreeToImageBuffer(ImageBuffer*, RenderObject*, const AffineTransform&);
     static void clipToImageBuffer(GraphicsContext*, const AffineTransform& absoluteTransform, const FloatRect& targetRect, OwnPtr<ImageBuffer>&, bool safeToClear);
 
+    static float calculateScreenFontSizeScalingFactor(const RenderObject*);
     static void calculateTransformationToOutermostSVGCoordinateSystem(const RenderObject*, AffineTransform& absoluteTransform);
     static IntSize clampedAbsoluteSize(const IntSize&);
     static FloatRect clampedAbsoluteTargetRect(const FloatRect& absoluteTargetRect);
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to