Title: [96712] trunk
Revision
96712
Author
[email protected]
Date
2011-10-05 09:20:32 -0700 (Wed, 05 Oct 2011)

Log Message

SVG 1.1: ineffectual transform attribute for ClipPath
https://bugs.webkit.org/show_bug.cgi?id=55361

Source/WebCore: 

Reviewed by Nikolas Zimmermann.
        
Respect 'transform' attribute/property for <clip-path>.
If the masking code path is used the mask context gets transformed, otherwise the path itself.

Tests: svg/clip-path/clip-path-transform-1.svg
       svg/clip-path/clip-path-transform-2.svg
       svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting.html

* rendering/svg/RenderSVGResourceClipper.cpp:
(WebCore::RenderSVGResourceClipper::pathOnlyClipping): Transform the clip path.
(WebCore::RenderSVGResourceClipper::applyClippingToContext):
(WebCore::RenderSVGResourceClipper::drawContentIntoMaskImage): Transform the context of the mask image.
(WebCore::RenderSVGResourceClipper::calculateClipContentRepaintRect): Repaint rect must get concatenated with the current animated transformation.
(WebCore::RenderSVGResourceClipper::hitTestClipContent): Point for hit testing must be transformed by the current animated transformation.
* rendering/svg/RenderSVGResourceClipper.h:

LayoutTests: 

Reviewed by Nikolas Zimmermann.
        
Test that the clip path gets concatenated with the current animated transformation and
that hit testing is affected correctly.

* platform/mac/svg/clip-path/clip-path-transform-1-expected.png: Added.
* platform/mac/svg/clip-path/clip-path-transform-1-expected.txt: Added.
* platform/mac/svg/clip-path/clip-path-transform-2-expected.png: Added.
* platform/mac/svg/clip-path/clip-path-transform-2-expected.txt: Added.
* svg/clip-path/clip-path-transform-1.svg: Added. Test clipping to path with transform.
* svg/clip-path/clip-path-transform-2.svg: Added. Test masking with transform.
* svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting-expected.png: Added.
* svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting-expected.txt: Added.
* svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting.html: Added.
* svg/dynamic-updates/script-tests/SVGClipPathElement-transform-influences-hitTesting.js: Added.
(executeBackgroundTest):
(executeTest):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (96711 => 96712)


--- trunk/LayoutTests/ChangeLog	2011-10-05 16:14:25 UTC (rev 96711)
+++ trunk/LayoutTests/ChangeLog	2011-10-05 16:20:32 UTC (rev 96712)
@@ -1,3 +1,26 @@
+2011-10-05  Dirk Schulze  <[email protected]>
+
+        SVG 1.1: ineffectual transform attribute for ClipPath
+        https://bugs.webkit.org/show_bug.cgi?id=55361
+
+        Reviewed by Nikolas Zimmermann.
+        
+        Test that the clip path gets concatenated with the current animated transformation and
+        that hit testing is affected correctly.
+
+        * platform/mac/svg/clip-path/clip-path-transform-1-expected.png: Added.
+        * platform/mac/svg/clip-path/clip-path-transform-1-expected.txt: Added.
+        * platform/mac/svg/clip-path/clip-path-transform-2-expected.png: Added.
+        * platform/mac/svg/clip-path/clip-path-transform-2-expected.txt: Added.
+        * svg/clip-path/clip-path-transform-1.svg: Added. Test clipping to path with transform.
+        * svg/clip-path/clip-path-transform-2.svg: Added. Test masking with transform.
+        * svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting-expected.png: Added.
+        * svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting-expected.txt: Added.
+        * svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting.html: Added.
+        * svg/dynamic-updates/script-tests/SVGClipPathElement-transform-influences-hitTesting.js: Added.
+        (executeBackgroundTest):
+        (executeTest):
+
 2011-10-05  Pavel Feldman  <[email protected]>
 
         Web Inspector: move elements panel update semantics from ElementsPanel to ElementsTreeOutline.

Added: trunk/LayoutTests/platform/mac/svg/clip-path/clip-path-transform-1-expected.png


(Binary files differ)
Property changes on: trunk/LayoutTests/platform/mac/svg/clip-path/clip-path-transform-1-expected.png ___________________________________________________________________

Added: svn:mime-type

Added: trunk/LayoutTests/platform/mac/svg/clip-path/clip-path-transform-1-expected.txt (0 => 96712)


--- trunk/LayoutTests/platform/mac/svg/clip-path/clip-path-transform-1-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac/svg/clip-path/clip-path-transform-1-expected.txt	2011-10-05 16:20:32 UTC (rev 96712)
@@ -0,0 +1,12 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderSVGRoot {svg} at (20,20) size 200x200
+    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGResourceClipper {clipPath} [id="clip"] [clipPathUnits=userSpaceOnUse]
+        RenderSVGPath {circle} at (0,0) size 20x20 [fill={[type=SOLID] [color=#000000]}] [cx=10.00] [cy=10.00] [r=10.00]
+        RenderSVGPath {circle} at (0,0) size 20x20 [fill={[type=SOLID] [color=#000000]}] [cx=10.00] [cy=10.00] [r=10.00]
+    RenderSVGPath {circle} at (21,21) size 198x198 [fill={[type=SOLID] [color=#FF0000]}] [cx=120.00] [cy=120.00] [r=99.00]
+    RenderSVGContainer {a} at (20,20) size 200x200
+      RenderSVGPath {rect} at (20,20) size 200x200 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=220.00] [height=220.00]
+        [clipPath="clip"] RenderSVGResourceClipper {clipPath} at (20,20) size 200x200

Added: trunk/LayoutTests/platform/mac/svg/clip-path/clip-path-transform-2-expected.png


(Binary files differ)
Property changes on: trunk/LayoutTests/platform/mac/svg/clip-path/clip-path-transform-2-expected.png ___________________________________________________________________

Added: svn:mime-type

Added: trunk/LayoutTests/platform/mac/svg/clip-path/clip-path-transform-2-expected.txt (0 => 96712)


--- trunk/LayoutTests/platform/mac/svg/clip-path/clip-path-transform-2-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac/svg/clip-path/clip-path-transform-2-expected.txt	2011-10-05 16:20:32 UTC (rev 96712)
@@ -0,0 +1,11 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderSVGRoot {svg} at (20,20) size 200x200
+    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGResourceClipper {clipPath} [id="clip"] [clipPathUnits=userSpaceOnUse]
+        RenderSVGPath {circle} at (0,0) size 20x20 [fill={[type=SOLID] [color=#000000]}] [cx=10.00] [cy=10.00] [r=10.00]
+    RenderSVGPath {circle} at (21,21) size 198x198 [fill={[type=SOLID] [color=#FF0000]}] [cx=120.00] [cy=120.00] [r=99.00]
+    RenderSVGContainer {a} at (20,20) size 200x200
+      RenderSVGPath {rect} at (20,20) size 200x200 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=220.00] [height=220.00]
+        [clipPath="clip"] RenderSVGResourceClipper {clipPath} at (20,20) size 200x200

Added: trunk/LayoutTests/svg/clip-path/clip-path-transform-1.svg (0 => 96712)


--- trunk/LayoutTests/svg/clip-path/clip-path-transform-1.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/clip-path/clip-path-transform-1.svg	2011-10-05 16:20:32 UTC (rev 96712)
@@ -0,0 +1,11 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<defs>
+<clipPath id="clip" clipPathUnits="userSpaceOnUse" transform="scale(10) translate(2, 2)">
+    <circle cx="10" cy="10" r="10"/>
+    <!-- second rect causes masking -->
+    <circle cx="10" cy="10" r="10"/>
+</clipPath>
+</defs>
+<circle cx="120" cy="120" r="99" fill="red"/>
+<a xlink:href="" width="220" height="220" fill="green" clip-path="url(#clip)"/></a>
+</svg>
\ No newline at end of file

Added: trunk/LayoutTests/svg/clip-path/clip-path-transform-2.svg (0 => 96712)


--- trunk/LayoutTests/svg/clip-path/clip-path-transform-2.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/clip-path/clip-path-transform-2.svg	2011-10-05 16:20:32 UTC (rev 96712)
@@ -0,0 +1,9 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<defs>
+<clipPath id="clip" clipPathUnits="userSpaceOnUse" transform="scale(10) translate(2, 2) ">
+    <circle cx="10" cy="10" r="10"/>
+</clipPath>
+</defs>
+<circle cx="120" cy="120" r="99" fill="red"/>
+<a xlink:href="" width="220" height="220" fill="green" clip-path="url(#clip)"/></a>
+</svg>
\ No newline at end of file

Added: trunk/LayoutTests/svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting-expected.png


(Binary files differ)
Property changes on: trunk/LayoutTests/svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting-expected.png ___________________________________________________________________

Added: svn:mime-type

Added: trunk/LayoutTests/svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting-expected.txt (0 => 96712)


--- trunk/LayoutTests/svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting-expected.txt	2011-10-05 16:20:32 UTC (rev 96712)
@@ -0,0 +1,13 @@
+SVG 1.1 dynamic update tests
+
+Tests hitTesting on clipped Elements. Clip-path gets transformed.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Hit thrown on not clipped area of rect.
+PASS Hit thrown on not clipped area of rect.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting.html (0 => 96712)


--- trunk/LayoutTests/svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting.html	                        (rev 0)
+++ trunk/LayoutTests/svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting.html	2011-10-05 16:20:32 UTC (rev 96712)
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href=""
+<script src=""
+<script src=""
+</head>
+<body>
+<h1>SVG 1.1 dynamic update tests</h1>
+<p id="description"></p>
+<div id="console"></div>
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/svg/dynamic-updates/script-tests/SVGClipPathElement-transform-influences-hitTesting.js (0 => 96712)


--- trunk/LayoutTests/svg/dynamic-updates/script-tests/SVGClipPathElement-transform-influences-hitTesting.js	                        (rev 0)
+++ trunk/LayoutTests/svg/dynamic-updates/script-tests/SVGClipPathElement-transform-influences-hitTesting.js	2011-10-05 16:20:32 UTC (rev 96712)
@@ -0,0 +1,44 @@
+// [Name] SVGClipPathElement-transform-influences-hitTesting.js
+// [Expected rendering result] green circle - and a series of PASS messages
+
+description("Tests hitTesting on clipped Elements. Clip-path gets transformed.")
+createSVGTestCase();
+
+var defsElement = createSVGElement("defs");
+rootSVGElement.appendChild(defsElement);
+
+var clipPathElement = createSVGElement("clipPath");
+clipPathElement.setAttribute("id", "clipper");
+
+var clipRectElement = createSVGElement("rect");
+clipRectElement.setAttribute("width", "5");
+clipRectElement.setAttribute("height", "5");
+clipRectElement.setAttribute("transform", "scale(20)");
+clipPathElement.appendChild(clipRectElement);
+
+defsElement.appendChild(clipPathElement);
+
+var foregroundRect = createSVGElement("rect");
+foregroundRect.setAttribute("width", "100");
+foregroundRect.setAttribute("height", "100");
+foregroundRect.setAttribute("fill", "green");
+foregroundRect.setAttribute("clip-path", "url(#clipper)");
+foregroundRect.setAttribute("onclick", "executeBackgroundTest()");
+rootSVGElement.appendChild(foregroundRect);
+
+// The clipPath gets scaled by 20. This should influence the hit testing,
+// since the area of the clipped content is affected as well. 
+function executeBackgroundTest() {
+    window.setTimeout("triggerUpdate(75,50)", 0);
+    startTest(foregroundRect, 25, 50);
+}
+
+function executeTest() {
+    testPassed("Hit thrown on not clipped area of rect.");
+
+    completeTest();
+}
+
+executeBackgroundTest();
+
+var successfullyParsed = true;

Modified: trunk/Source/WebCore/ChangeLog (96711 => 96712)


--- trunk/Source/WebCore/ChangeLog	2011-10-05 16:14:25 UTC (rev 96711)
+++ trunk/Source/WebCore/ChangeLog	2011-10-05 16:20:32 UTC (rev 96712)
@@ -1,3 +1,25 @@
+2011-10-05  Dirk Schulze  <[email protected]>
+
+        SVG 1.1: ineffectual transform attribute for ClipPath
+        https://bugs.webkit.org/show_bug.cgi?id=55361
+
+        Reviewed by Nikolas Zimmermann.
+        
+        Respect 'transform' attribute/property for <clip-path>.
+        If the masking code path is used the mask context gets transformed, otherwise the path itself.
+
+        Tests: svg/clip-path/clip-path-transform-1.svg
+               svg/clip-path/clip-path-transform-2.svg
+               svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting.html
+
+        * rendering/svg/RenderSVGResourceClipper.cpp:
+        (WebCore::RenderSVGResourceClipper::pathOnlyClipping): Transform the clip path.
+        (WebCore::RenderSVGResourceClipper::applyClippingToContext):
+        (WebCore::RenderSVGResourceClipper::drawContentIntoMaskImage): Transform the context of the mask image.
+        (WebCore::RenderSVGResourceClipper::calculateClipContentRepaintRect): Repaint rect must get concatenated with the current animated transformation.
+        (WebCore::RenderSVGResourceClipper::hitTestClipContent): Point for hit testing must be transformed by the current animated transformation.
+        * rendering/svg/RenderSVGResourceClipper.h:
+
 2011-10-05  Pavel Feldman  <[email protected]>
 
         Web Inspector: move elements panel update semantics from ElementsPanel to ElementsTreeOutline.

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp (96711 => 96712)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp	2011-10-05 16:14:25 UTC (rev 96711)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp	2011-10-05 16:20:32 UTC (rev 96712)
@@ -2,6 +2,7 @@
  * Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <[email protected]>
  * Copyright (C) 2004, 2005, 2006, 2007, 2008 Rob Buis <[email protected]>
  * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
+ * Copyright (C) 2011 Dirk Schulze <[email protected]>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -104,7 +105,7 @@
     return applyClippingToContext(object, object->objectBoundingBox(), object->repaintRectInLocalCoordinates(), context);
 }
 
-bool RenderSVGResourceClipper::pathOnlyClipping(GraphicsContext* context, const FloatRect& objectBoundingBox)
+bool RenderSVGResourceClipper::pathOnlyClipping(GraphicsContext* context, const AffineTransform& animatedLocalTransform, const FloatRect& objectBoundingBox)
 {
     // If the current clip-path gets clipped itself, we have to fallback to masking.
     if (!style()->svgStyle()->clipperResource().isEmpty())
@@ -148,6 +149,10 @@
         transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
         clipPath.transform(transform);
     }
+
+    // Transform path by animatedLocalTransform.
+    clipPath.transform(animatedLocalTransform);
+
     // The SVG specification wants us to clip everything, if clip-path doesn't have a child.
     if (clipPath.isEmpty())
         clipPath.addRect(FloatRect());
@@ -162,9 +167,10 @@
         m_clipper.set(object, new ClipperData);
 
     bool shouldCreateClipData = false;
+    AffineTransform animatedLocalTransform = static_cast<SVGClipPathElement*>(node())->animatedLocalTransform();
     ClipperData* clipperData = m_clipper.get(object);
     if (!clipperData->clipMaskImage) {
-        if (pathOnlyClipping(context, objectBoundingBox))
+        if (pathOnlyClipping(context, animatedLocalTransform, objectBoundingBox))
             return true;
         shouldCreateClipData = true;
     }
@@ -185,6 +191,7 @@
         // The save/restore pair is needed for clipToImageBuffer - it doesn't work without it on non-Cg platforms.
         GraphicsContextStateSaver stateSaver(*maskContext);
         maskContext->translate(-clampedAbsoluteTargetRect.x(), -clampedAbsoluteTargetRect.y());
+        maskContext->concatCTM(animatedLocalTransform);
         maskContext->concatCTM(absoluteTransform);
 
         // clipPath can also be clipped by another clipPath.
@@ -254,9 +261,9 @@
         svgStyle->setFillPaint(SVGRenderStyle::initialFillPaintType(), SVGRenderStyle::initialFillPaintColor(), SVGRenderStyle::initialFillPaintUri());
         svgStyle->setStrokePaint(SVGRenderStyle::initialStrokePaintType(), SVGRenderStyle::initialStrokePaintColor(), SVGRenderStyle::initialStrokePaintUri());
         svgStyle->setFillRule(newClipRule);
-        newRenderStyle.get()->setOpacity(1.0f);
-        svgStyle->setFillOpacity(1.0f);
-        svgStyle->setStrokeOpacity(1.0f);
+        newRenderStyle.get()->setOpacity(1);
+        svgStyle->setFillOpacity(1);
+        svgStyle->setStrokeOpacity(1);
         svgStyle->setFilterResource(String());
         svgStyle->setMaskerResource(String());
 
@@ -291,6 +298,7 @@
              continue;
         m_clipBoundaries.unite(renderer->localToParentTransform().mapRect(renderer->repaintRectInLocalCoordinates()));
     }
+    m_clipBoundaries = static_cast<SVGClipPathElement*>(node())->animatedLocalTransform().mapRect(m_clipBoundaries);
 }
 
 bool RenderSVGResourceClipper::hitTestClipContent(const FloatRect& objectBoundingBox, const FloatPoint& nodeAtPoint)
@@ -299,13 +307,16 @@
     if (!SVGRenderSupport::pointInClippingArea(this, point))
         return false;
 
-    if (static_cast<SVGClipPathElement*>(node())->clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+    SVGClipPathElement* clipPathElement = static_cast<SVGClipPathElement*>(node());
+    if (clipPathElement->clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
         AffineTransform transform;
         transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
         transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
         point = transform.inverse().mapPoint(point);
     }
 
+    point = clipPathElement->animatedLocalTransform().inverse().mapPoint(point);
+
     for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) {
         RenderObject* renderer = childNode->renderer();
         if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyled() || !renderer)

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceClipper.h (96711 => 96712)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceClipper.h	2011-10-05 16:14:25 UTC (rev 96711)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceClipper.h	2011-10-05 16:20:32 UTC (rev 96712)
@@ -65,7 +65,7 @@
     // clipPath can be clipped too, but don't have a boundingBox or repaintRect. So we can't call
     // applyResource directly and use the rects from the object, since they are empty for RenderSVGResources
     bool applyClippingToContext(RenderObject*, const FloatRect&, const FloatRect&, GraphicsContext*);
-    bool pathOnlyClipping(GraphicsContext*, const FloatRect&);
+    bool pathOnlyClipping(GraphicsContext*, const AffineTransform&, const FloatRect&);
     bool drawContentIntoMaskImage(ClipperData*, const FloatRect& objectBoundingBox);
     void calculateClipContentRepaintRect();
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to