Title: [120464] trunk
Revision
120464
Author
[email protected]
Date
2012-06-15 08:37:12 -0700 (Fri, 15 Jun 2012)

Log Message

SVG Composite of Offset filters incorrectly clips
https://bugs.webkit.org/show_bug.cgi?id=77660

Reviewed by Dirk Schulze.

Source/WebCore:

Prior to this patch, when a group of filtered objects was used as input to another filter,
the filter only operated on the stroke boundary of the group, and hence excluded the results
of filtering elements within the group, or extraneously included regions clipped from the
elements in the group.

This patch modifies the strokeBoundingBox of SVG container elements to
be the union of the repaint rects for the children. This modifes the
results returned for sizing filters and for absoluteRects, which will cause
inline layout around the group to factor in the resources applied to
the group's children.

The relevant spec entry is this, in Section 3.7 of the SVG 1.1 spec: "...the result must be
as though the paint operations had been applied to an intermediate canvas initialized to
transparent black, of a size determined by the rules given in Filter Effects then filtered
by the processes defined in Filter Effects." In this case the "paint operations" is implied
to include the result of applying "paint" but no resources to the group, which in turn would
have resources applied to the children of the group. This makes the most sense, as the current,
incorrect behavior makes it extremely diffucult to understand the actions of filters on
groups of filtered content.

Tests: svg/filters/container-with-filters-expected.svg
       svg/filters/container-with-filters.svg

* rendering/svg/RenderSVGContainer.cpp:
(WebCore::RenderSVGContainer::updateCachedBoundaries):
* rendering/svg/RenderSVGRoot.cpp:
(WebCore::RenderSVGRoot::updateCachedBoundaries):
* rendering/svg/SVGRenderSupport.cpp:
(WebCore::SVGRenderSupport::computeContainerBoundingBoxes):

LayoutTests:

* svg/filters/container-with-filters-expected.svg: Added.
* svg/filters/container-with-filters.svg: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (120463 => 120464)


--- trunk/LayoutTests/ChangeLog	2012-06-15 15:29:44 UTC (rev 120463)
+++ trunk/LayoutTests/ChangeLog	2012-06-15 15:37:12 UTC (rev 120464)
@@ -1,3 +1,13 @@
+2012-06-15  Stephen Chenney  <[email protected]>
+
+        SVG Composite of Offset filters incorrectly clips
+        https://bugs.webkit.org/show_bug.cgi?id=77660
+
+        Reviewed by Dirk Schulze.
+
+        * svg/filters/container-with-filters-expected.svg: Added.
+        * svg/filters/container-with-filters.svg: Added.
+
 2012-06-15  Ilya Tikhonovsky  <[email protected]>
 
         Web Inspector: CRASH: getProfile is crashing for unknown profiles.

Added: trunk/LayoutTests/svg/filters/container-with-filters-expected.svg (0 => 120464)


--- trunk/LayoutTests/svg/filters/container-with-filters-expected.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/filters/container-with-filters-expected.svg	2012-06-15 15:37:12 UTC (rev 120464)
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
+    <rect x="10" y="10" width="100" height="100" fill="none" stroke="black" />
+    <rect x="10" y="10" width="100" height="100" fill="rgb(0,128,0)" stroke="none" />
+</svg>

Added: trunk/LayoutTests/svg/filters/container-with-filters.svg (0 => 120464)


--- trunk/LayoutTests/svg/filters/container-with-filters.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/filters/container-with-filters.svg	2012-06-15 15:37:12 UTC (rev 120464)
@@ -0,0 +1,21 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
+    <defs>
+        <filter id="offset1">
+            <feOffset in="SourceGraphic" dx="10" dy="10" />
+        </filter>
+
+        <filter id="offset2">
+            <feOffset in="SourceGraphic" dx="-10" dy="-10" />
+        </filter>
+
+    </defs>
+
+    <rect x="10" y="10" width="100" height="100" fill="none" stroke="black" />
+
+    <g filter="url(#offset2)">
+        <g filter="url(#offset1)">
+            <rect x="10" y="10" width="100" height="100" fill="rgb(0,128,0)" />
+        </g>
+    </g>
+
+</svg>

Modified: trunk/Source/WebCore/ChangeLog (120463 => 120464)


--- trunk/Source/WebCore/ChangeLog	2012-06-15 15:29:44 UTC (rev 120463)
+++ trunk/Source/WebCore/ChangeLog	2012-06-15 15:37:12 UTC (rev 120464)
@@ -1,3 +1,40 @@
+2012-06-15  Stephen Chenney  <[email protected]>
+
+        SVG Composite of Offset filters incorrectly clips
+        https://bugs.webkit.org/show_bug.cgi?id=77660
+
+        Reviewed by Dirk Schulze.
+
+        Prior to this patch, when a group of filtered objects was used as input to another filter,
+        the filter only operated on the stroke boundary of the group, and hence excluded the results
+        of filtering elements within the group, or extraneously included regions clipped from the
+        elements in the group.
+
+        This patch modifies the strokeBoundingBox of SVG container elements to
+        be the union of the repaint rects for the children. This modifes the
+        results returned for sizing filters and for absoluteRects, which will cause
+        inline layout around the group to factor in the resources applied to
+        the group's children.
+
+        The relevant spec entry is this, in Section 3.7 of the SVG 1.1 spec: "...the result must be
+        as though the paint operations had been applied to an intermediate canvas initialized to
+        transparent black, of a size determined by the rules given in Filter Effects then filtered
+        by the processes defined in Filter Effects." In this case the "paint operations" is implied
+        to include the result of applying "paint" but no resources to the group, which in turn would
+        have resources applied to the children of the group. This makes the most sense, as the current,
+        incorrect behavior makes it extremely diffucult to understand the actions of filters on
+        groups of filtered content.
+
+        Tests: svg/filters/container-with-filters-expected.svg
+               svg/filters/container-with-filters.svg
+
+        * rendering/svg/RenderSVGContainer.cpp:
+        (WebCore::RenderSVGContainer::updateCachedBoundaries):
+        * rendering/svg/RenderSVGRoot.cpp:
+        (WebCore::RenderSVGRoot::updateCachedBoundaries):
+        * rendering/svg/SVGRenderSupport.cpp:
+        (WebCore::SVGRenderSupport::computeContainerBoundingBoxes):
+
 2012-06-15  David Kilzer  <[email protected]>
 
         Sort ENABLE(INSPECTOR) section of WebCore.exp.in

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGContainer.cpp (120463 => 120464)


--- trunk/Source/WebCore/rendering/svg/RenderSVGContainer.cpp	2012-06-15 15:29:44 UTC (rev 120463)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGContainer.cpp	2012-06-15 15:37:12 UTC (rev 120464)
@@ -163,11 +163,6 @@
 
 void RenderSVGContainer::updateCachedBoundaries()
 {
-    m_objectBoundingBox = FloatRect();
-    m_objectBoundingBoxValid = false;
-    m_strokeBoundingBox = FloatRect();
-    m_repaintBoundingBox = FloatRect();
-
     SVGRenderSupport::computeContainerBoundingBoxes(this, m_objectBoundingBox, m_objectBoundingBoxValid, m_strokeBoundingBox, m_repaintBoundingBox);
     SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingBox);
 }

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp (120463 => 120464)


--- trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp	2012-06-15 15:29:44 UTC (rev 120463)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp	2012-06-15 15:37:12 UTC (rev 120464)
@@ -404,11 +404,6 @@
 
 void RenderSVGRoot::updateCachedBoundaries()
 {
-    m_objectBoundingBox = FloatRect();
-    m_objectBoundingBoxValid = false;
-    m_strokeBoundingBox = FloatRect();
-    m_repaintBoundingBox = FloatRect();
-
     SVGRenderSupport::computeContainerBoundingBoxes(this, m_objectBoundingBox, m_objectBoundingBoxValid, m_strokeBoundingBox, m_repaintBoundingBox);
     SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingBox);
     m_repaintBoundingBox.inflate(borderAndPaddingWidth());

Modified: trunk/Source/WebCore/rendering/svg/SVGRenderSupport.cpp (120463 => 120464)


--- trunk/Source/WebCore/rendering/svg/SVGRenderSupport.cpp	2012-06-15 15:29:44 UTC (rev 120463)
+++ trunk/Source/WebCore/rendering/svg/SVGRenderSupport.cpp	2012-06-15 15:37:12 UTC (rev 120464)
@@ -121,6 +121,13 @@
 
 void SVGRenderSupport::computeContainerBoundingBoxes(const RenderObject* container, FloatRect& objectBoundingBox, bool& objectBoundingBoxValid, FloatRect& strokeBoundingBox, FloatRect& repaintBoundingBox)
 {
+    objectBoundingBox = FloatRect();
+    objectBoundingBoxValid = false;
+    strokeBoundingBox = FloatRect();
+
+    // When computing the strokeBoundingBox, we use the repaintRects of the container's children so that the container's stroke includes
+    // the resources applied to the children (such as clips and filters). This allows filters applied to containers to correctly bound
+    // the children, and also improves inlining of SVG content, as the stroke bound is used in that situation also.
     for (RenderObject* current = container->firstChild(); current; current = current->nextSibling()) {
         if (current->isSVGHiddenContainer())
             continue;
@@ -128,14 +135,14 @@
         const AffineTransform& transform = current->localToParentTransform();
         if (transform.isIdentity()) {
             updateObjectBoundingBox(objectBoundingBox, objectBoundingBoxValid, current, current->objectBoundingBox());
-            strokeBoundingBox.unite(current->strokeBoundingBox());
-            repaintBoundingBox.unite(current->repaintRectInLocalCoordinates());
+            strokeBoundingBox.unite(current->repaintRectInLocalCoordinates());
         } else {
             updateObjectBoundingBox(objectBoundingBox, objectBoundingBoxValid, current, transform.mapRect(current->objectBoundingBox()));
-            strokeBoundingBox.unite(transform.mapRect(current->strokeBoundingBox()));
-            repaintBoundingBox.unite(transform.mapRect(current->repaintRectInLocalCoordinates()));
+            strokeBoundingBox.unite(transform.mapRect(current->repaintRectInLocalCoordinates()));
         }
     }
+
+    repaintBoundingBox = strokeBoundingBox;
 }
 
 bool SVGRenderSupport::paintInfoIntersectsRepaintRect(const FloatRect& localRepaintRect, const AffineTransform& localTransform, const PaintInfo& paintInfo)
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to