SVG Mask should take 'color-interpolation' into account to determine the color space...
authorkrit@webkit.org <krit@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 2 Oct 2011 07:15:08 +0000 (07:15 +0000)
committerkrit@webkit.org <krit@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 2 Oct 2011 07:15:08 +0000 (07:15 +0000)
https://bugs.webkit.org/show_bug.cgi?id=69076

Source/WebCore:

Reviewed by Simon Fraser.

SVG Masks should take 'color-interpolation' into account to determine the color space of the mask image.
The behavior was changed in SVG 1.1 SE. The color space of the mask image gets defined by the computed value of the
'color-interpolation' property. This will switch the default color space from linearRGB to sRGB for mask images and
is a performance improvement for platforms without native support for linearRGB color space. The
color space transformation can be avoided.

Test: svg/custom/grayscale-gradient-mask-2.svg

* rendering/svg/RenderSVGResourceMasker.cpp:
(WebCore::RenderSVGResourceMasker::applyResource):
(WebCore::RenderSVGResourceMasker::drawContentIntoMaskImage):
* rendering/svg/RenderSVGResourceMasker.h:

LayoutTests:

Reviewed by Simon Fraser.

Added a new test case to check the behavior of SVG Masks on different values for the 'color-interpolation' property.
Since the default color space of the mask image changes from linearRGB to sRGB, a test needed an update.

* platform/mac/svg/custom/grayscale-gradient-mask-2-expected.png: Added.
* platform/mac/svg/custom/grayscale-gradient-mask-2-expected.txt: Added.
* platform/mac/svg/custom/grayscale-gradient-mask-expected.png:
* platform/mac/svg/custom/grayscale-gradient-mask-expected.txt:
* svg/custom/grayscale-gradient-mask-2.svg: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@96470 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/platform/mac/svg/custom/grayscale-gradient-mask-2-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/svg/custom/grayscale-gradient-mask-2-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/svg/custom/grayscale-gradient-mask-expected.png
LayoutTests/svg/custom/grayscale-gradient-mask-2.svg [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp
Source/WebCore/rendering/svg/RenderSVGResourceMasker.h

index 6d48eb6..b765184 100644 (file)
@@ -1,3 +1,19 @@
+2011-10-02  Dirk Schulze  <krit@webkit.org>
+
+        SVG Mask should take 'color-interpolation' into account to determine the color space of the mask image
+        https://bugs.webkit.org/show_bug.cgi?id=69076
+
+        Reviewed by Simon Fraser.
+        
+        Added a new test case to check the behavior of SVG Masks on different values for the 'color-interpolation' property.
+        Since the default color space of the mask image changes from linearRGB to sRGB, a test needed an update.
+
+        * platform/mac/svg/custom/grayscale-gradient-mask-2-expected.png: Added.
+        * platform/mac/svg/custom/grayscale-gradient-mask-2-expected.txt: Added.
+        * platform/mac/svg/custom/grayscale-gradient-mask-expected.png:
+        * platform/mac/svg/custom/grayscale-gradient-mask-expected.txt:
+        * svg/custom/grayscale-gradient-mask-2.svg: Added.
+
 2011-10-01  Adam Barth  <abarth@webkit.org>
 
         Tweak expectations for leopard some more.
diff --git a/LayoutTests/platform/mac/svg/custom/grayscale-gradient-mask-2-expected.png b/LayoutTests/platform/mac/svg/custom/grayscale-gradient-mask-2-expected.png
new file mode 100644 (file)
index 0000000..cd8e0f7
Binary files /dev/null and b/LayoutTests/platform/mac/svg/custom/grayscale-gradient-mask-2-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/custom/grayscale-gradient-mask-2-expected.txt b/LayoutTests/platform/mac/svg/custom/grayscale-gradient-mask-2-expected.txt
new file mode 100644 (file)
index 0000000..306aa31
--- /dev/null
@@ -0,0 +1,21 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderSVGRoot {svg} at (0,143) size 781x294
+    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGResourceLinearGradient {linearGradient} [id="Gradient"] [gradientUnits=userSpaceOnUse] [start=(0,0)] [end=(800,0)]
+        RenderSVGGradientStop {stop} [offset=0.00] [color=#FFFFFF]
+        RenderSVGGradientStop {stop} [offset=1.00] [color=#000000]
+    RenderSVGResourceMasker {mask} [id="Mask1"] [maskUnits=userSpaceOnUse] [maskContentUnits=userSpaceOnUse]
+      RenderSVGPath {rect} at (0,143) size 781x99 [fill={[type=LINEAR-GRADIENT] [id="Gradient"]}] [x=0.00] [y=0.00] [width=800.00] [height=100.00]
+    RenderSVGResourceMasker {mask} [id="Mask2"] [maskUnits=userSpaceOnUse] [maskContentUnits=userSpaceOnUse]
+      RenderSVGPath {rect} at (0,241) size 781x99 [fill={[type=LINEAR-GRADIENT] [id="Gradient"]}] [x=0.00] [y=100.00] [width=800.00] [height=100.00]
+    RenderSVGResourceMasker {mask} [id="Mask3"] [maskUnits=userSpaceOnUse] [maskContentUnits=userSpaceOnUse]
+      RenderSVGPath {rect} at (0,339) size 781x98 [fill={[type=LINEAR-GRADIENT] [id="Gradient"]}] [x=0.00] [y=200.00] [width=800.00] [height=100.00]
+    RenderSVGPath {rect} at (0,143) size 781x294 [fill={[type=SOLID] [color=#FF8080]}] [x=0.00] [y=0.00] [width=800.00] [height=300.00]
+    RenderSVGPath {rect} at (0,143) size 781x99 [fill={[type=SOLID] [color=#0000FF]}] [x=0.00] [y=0.00] [width=800.00] [height=100.00]
+      [masker="Mask1"] RenderSVGResourceMasker {mask} at (0,0) size 800x100
+    RenderSVGPath {rect} at (0,241) size 781x99 [fill={[type=SOLID] [color=#0000FF]}] [x=0.00] [y=100.00] [width=800.00] [height=100.00]
+      [masker="Mask2"] RenderSVGResourceMasker {mask} at (0,100) size 800x100
+    RenderSVGPath {rect} at (0,339) size 781x98 [fill={[type=SOLID] [color=#0000FF]}] [x=0.00] [y=200.00] [width=800.00] [height=100.00]
+      [masker="Mask3"] RenderSVGResourceMasker {mask} at (0,200) size 800x100
index 9aa8c7e..0cb22a8 100644 (file)
Binary files a/LayoutTests/platform/mac/svg/custom/grayscale-gradient-mask-expected.png and b/LayoutTests/platform/mac/svg/custom/grayscale-gradient-mask-expected.png differ
diff --git a/LayoutTests/svg/custom/grayscale-gradient-mask-2.svg b/LayoutTests/svg/custom/grayscale-gradient-mask-2.svg
new file mode 100644 (file)
index 0000000..1879cae
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg viewBox="0 0 820 320" version="1.1" xmlns="http://www.w3.org/2000/svg">
+  <desc>Example mask01 - blue text masked with gradient against red background
+  </desc>
+  <defs>
+    <linearGradient id="Gradient" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="800" y2="0">
+      <stop offset="0" stop-color="white" stop-opacity="1"/> <!-- this end is filled -->
+      <stop offset="1" stop-color="black" stop-opacity="1"/>
+    </linearGradient>
+  </defs>
+  <mask id="Mask1" maskUnits="userSpaceOnUse" x="0" y="0" width="800" height="100">
+     <rect x="0" y="0" width="800" height="100" fill="url(#Gradient)"/>
+  </mask>
+  <mask id="Mask2" maskUnits="userSpaceOnUse" x="0" y="100" width="800" height="100" color-interpolation="linearRGB">
+     <rect x="0" y="100" width="800" height="100" fill="url(#Gradient)"/>
+  </mask>
+  <mask id="Mask3" maskUnits="userSpaceOnUse" x="0" y="200" width="800" height="100" color-interpolation="sRGB">
+     <rect x="0" y="200" width="800" height="100" fill="url(#Gradient)"/>
+  </mask>
+  <rect x="0" y="0" width="800" height="300" fill="#FF8080"/>
+  <rect x="0" y="0" width="800" height="100" fill="blue" mask="url(#Mask1)"/>
+  <rect x="0" y="100" width="800" height="100" fill="blue" mask="url(#Mask2)"/>
+  <rect x="0" y="200" width="800" height="100" fill="blue" mask="url(#Mask3)"/>
+</svg>
\ No newline at end of file
index e546709..99806d2 100644 (file)
@@ -1,3 +1,23 @@
+2011-10-02  Dirk Schulze  <krit@webkit.org>
+
+        SVG Mask should take 'color-interpolation' into account to determine the color space of the mask image
+        https://bugs.webkit.org/show_bug.cgi?id=69076
+
+        Reviewed by Simon Fraser.
+        
+        SVG Masks should take 'color-interpolation' into account to determine the color space of the mask image.
+        The behavior was changed in SVG 1.1 SE. The color space of the mask image gets defined by the computed value of the
+        'color-interpolation' property. This will switch the default color space from linearRGB to sRGB for mask images and
+        is a performance improvement for platforms without native support for linearRGB color space. The
+        color space transformation can be avoided.
+
+        Test: svg/custom/grayscale-gradient-mask-2.svg
+
+        * rendering/svg/RenderSVGResourceMasker.cpp:
+        (WebCore::RenderSVGResourceMasker::applyResource):
+        (WebCore::RenderSVGResourceMasker::drawContentIntoMaskImage):
+        * rendering/svg/RenderSVGResourceMasker.h:
+
 2011-10-01  Vangelis Kokkevis  <vangelis@chromium.org>
 
         [chromium] Fixing draw matrix for composited layers. This
index b110168..37d202d 100644 (file)
@@ -106,7 +106,11 @@ bool RenderSVGResourceMasker::applyResource(RenderObject* object, RenderStyle*,
         if (!maskElement)
             return false;
 
-        if (!SVGImageBufferTools::createImageBuffer(absoluteTargetRect, clampedAbsoluteTargetRect, maskerData->maskImage, ColorSpaceLinearRGB))
+        ASSERT(style());
+        const SVGRenderStyle* svgStyle = style()->svgStyle();
+        ASSERT(svgStyle);
+        ColorSpace colorSpace = svgStyle->colorInterpolation() == CI_LINEARRGB ? ColorSpaceLinearRGB : ColorSpaceDeviceRGB;
+        if (!SVGImageBufferTools::createImageBuffer(absoluteTargetRect, clampedAbsoluteTargetRect, maskerData->maskImage, colorSpace))
             return false;
 
         GraphicsContext* maskImageContext = maskerData->maskImage->context();
@@ -117,7 +121,7 @@ bool RenderSVGResourceMasker::applyResource(RenderObject* object, RenderStyle*,
         maskImageContext->translate(-clampedAbsoluteTargetRect.x(), -clampedAbsoluteTargetRect.y());
         maskImageContext->concatCTM(absoluteTransform);
 
-        drawContentIntoMaskImage(maskerData, maskElement, object);
+        drawContentIntoMaskImage(maskerData, colorSpace, maskElement, object);
     }
 
     if (!maskerData->maskImage)
@@ -127,7 +131,7 @@ bool RenderSVGResourceMasker::applyResource(RenderObject* object, RenderStyle*,
     return true;
 }
 
-void RenderSVGResourceMasker::drawContentIntoMaskImage(MaskerData* maskerData, const SVGMaskElement* maskElement, RenderObject* object)
+void RenderSVGResourceMasker::drawContentIntoMaskImage(MaskerData* maskerData, ColorSpace colorSpace, const SVGMaskElement* maskElement, RenderObject* object)
 {
     GraphicsContext* maskImageContext = maskerData->maskImage->context();
     ASSERT(maskImageContext);
@@ -155,7 +159,9 @@ void RenderSVGResourceMasker::drawContentIntoMaskImage(MaskerData* maskerData, c
     maskImageContext->restore();
 
 #if !USE(CG)
-    maskerData->maskImage->transformColorSpace(ColorSpaceDeviceRGB, ColorSpaceLinearRGB);
+    maskerData->maskImage->transformColorSpace(ColorSpaceDeviceRGB, colorSpace);
+#else
+    UNUSED_PARAM(colorSpace);
 #endif
 
     // Create the luminance mask.
index f4e831d..8336e0d 100644 (file)
@@ -57,7 +57,7 @@ public:
     static RenderSVGResourceType s_resourceType;
 
 private:
-    void drawContentIntoMaskImage(MaskerData*, const SVGMaskElement*, RenderObject*);
+    void drawContentIntoMaskImage(MaskerData*, ColorSpace, const SVGMaskElement*, RenderObject*);
     void calculateMaskContentRepaintRect();
 
     FloatRect m_maskContentBoundaries;