Title: [105613] trunk
Revision
105613
Author
[email protected]
Date
2012-01-23 04:48:12 -0800 (Mon, 23 Jan 2012)

Log Message

SVG animation repaint issue with image and dynamic clipPath
https://bugs.webkit.org/show_bug.cgi?id=76559

Reviewed by Zoltan Herczeg.

Source/WebCore:

Based on patch by Kelly Norton <[email protected]>. I extended the patch
to correctly handle relative length resolution as well.

RenderSVGImage doesn't react on setNeedsBoundariesUpdate() calls
and thus fails to update its boundaries in some cases.

The logic is also inconsistent, compared to the other renderers.
Fix that properly, by reusing the method used in RenderSVGViewportContainer.
Call calculateImageViewport() immediately, after initializing the LayoutRepainter.
Previously we resolved the image viewport in RenderSVGImage::updateFromElement. This is
wrong, as it queries the frameRect() of the RenderSVGRoot in a state, where the renderer
still needs layout, leading to wrong results.

I turned Kellys manual testcase into a predictable test, see svg/repaint/image-with-clip-path.svg
Relative sized image handling is tested in svg/custom/relative-sized-image.xhtml now.

Tests: svg/custom/relative-sized-image.xhtml
       svg/repaint/image-with-clip-path.svg

* rendering/svg/RenderSVGImage.cpp:
(WebCore::RenderSVGImage::RenderSVGImage):
(WebCore::RenderSVGImage::updateImageViewport):
(WebCore::RenderSVGImage::layout):
* rendering/svg/RenderSVGImage.h:
(WebCore::RenderSVGImage::setNeedsBoundariesUpdate):
* svg/SVGImageElement.cpp:
(WebCore::SVGImageElement::svgAttributeChanged):

LayoutTests:

Update results after fixing RenderSVGImage repainting.

* platform/chromium-win/svg/W3C-SVG-1.1/masking-path-04-b-expected.txt:
* platform/chromium/test_expectations.txt:
* platform/mac/svg/W3C-SVG-1.1/masking-path-04-b-expected.png:
* platform/mac/svg/W3C-SVG-1.1/masking-path-04-b-expected.txt:
* platform/mac/svg/custom/relative-sized-image-expected.png: Added.
* platform/mac/svg/custom/relative-sized-image-expected.txt: Added.
* platform/mac/svg/repaint/image-with-clip-path-expected.png: Added.
* svg/custom/relative-sized-image.xhtml: Added.
* svg/repaint/image-with-clip-path-expected.txt: Added.
* svg/repaint/image-with-clip-path.svg: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (105612 => 105613)


--- trunk/LayoutTests/ChangeLog	2012-01-23 12:42:42 UTC (rev 105612)
+++ trunk/LayoutTests/ChangeLog	2012-01-23 12:48:12 UTC (rev 105613)
@@ -1,5 +1,25 @@
 2012-01-23  Nikolas Zimmermann  <[email protected]>
 
+        SVG animation repaint issue with image and dynamic clipPath
+        https://bugs.webkit.org/show_bug.cgi?id=76559
+
+        Reviewed by Zoltan Herczeg.
+
+        Update results after fixing RenderSVGImage repainting.
+
+        * platform/chromium-win/svg/W3C-SVG-1.1/masking-path-04-b-expected.txt:
+        * platform/chromium/test_expectations.txt:
+        * platform/mac/svg/W3C-SVG-1.1/masking-path-04-b-expected.png:
+        * platform/mac/svg/W3C-SVG-1.1/masking-path-04-b-expected.txt:
+        * platform/mac/svg/custom/relative-sized-image-expected.png: Added.
+        * platform/mac/svg/custom/relative-sized-image-expected.txt: Added.
+        * platform/mac/svg/repaint/image-with-clip-path-expected.png: Added.
+        * svg/custom/relative-sized-image.xhtml: Added.
+        * svg/repaint/image-with-clip-path-expected.txt: Added.
+        * svg/repaint/image-with-clip-path.svg: Added.
+
+2012-01-23  Nikolas Zimmermann  <[email protected]>
+
         <feImage> has problems referencing local elements
         https://bugs.webkit.org/show_bug.cgi?id=76800
 

Modified: trunk/LayoutTests/platform/chromium/test_expectations.txt (105612 => 105613)


--- trunk/LayoutTests/platform/chromium/test_expectations.txt	2012-01-23 12:42:42 UTC (rev 105612)
+++ trunk/LayoutTests/platform/chromium/test_expectations.txt	2012-01-23 12:48:12 UTC (rev 105613)
@@ -956,6 +956,11 @@
 BUGWK62974 : svg/custom/svg-fonts-with-no-element-reference.html = IMAGE+TEXT IMAGE
 BUGWK62974 MAC : svg/W3C-SVG-1.1/pservers-grad-08-b.svg = IMAGE
 
+// May need new baseline after 76559 lands.
+BUGWK76559 : svg/W3C-SVG-1.1/masking-path-04-b.svg = PASS FAIL
+BUGWK76559 : svg/custom/relative-sized-image.xhtml = IMAGE+TEXT
+BUGWK76559 : svg/repaint/image-with-clip-path.svg = IMAGE+TEXT
+
 // -----------------------------------------------------------------
 // End SVG Regressions
 // -----------------------------------------------------------------

Modified: trunk/LayoutTests/platform/chromium-win/svg/W3C-SVG-1.1/masking-path-04-b-expected.txt (105612 => 105613)


--- trunk/LayoutTests/platform/chromium-win/svg/W3C-SVG-1.1/masking-path-04-b-expected.txt	2012-01-23 12:42:42 UTC (rev 105612)
+++ trunk/LayoutTests/platform/chromium-win/svg/W3C-SVG-1.1/masking-path-04-b-expected.txt	2012-01-23 12:48:12 UTC (rev 105613)
@@ -13,8 +13,8 @@
         RenderSVGText {text} at (55,29) size 353x122 contains 1 chunk(s)
           RenderSVGInlineText {#text} at (0,0) size 353x122
             chunk 1 text run 1 at (55.00,130.00) startOffset 0 endOffset 9 width 353.00: "Clip Test"
-      RenderSVGContainer {g} at (45,170) size 358x121
-        RenderSVGImage {image} at (45,170) size 358x121
+      RenderSVGContainer {g} at (45,170) size 353x121
+        RenderSVGImage {image} at (45,170) size 353x121
           [clipPath="sample"] RenderSVGResourceClipper {clipPath} at (45,169) size 353x122
     RenderSVGText {text} at (10,304) size 261x46 contains 1 chunk(s)
       RenderSVGInlineText {#text} at (0,0) size 261x46

Modified: trunk/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-path-04-b-expected.png


(Binary files differ)

Modified: trunk/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-path-04-b-expected.txt (105612 => 105613)


--- trunk/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-path-04-b-expected.txt	2012-01-23 12:42:42 UTC (rev 105612)
+++ trunk/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-path-04-b-expected.txt	2012-01-23 12:48:12 UTC (rev 105613)
@@ -13,8 +13,8 @@
         RenderSVGText {text} at (55,29) size 353x122 contains 1 chunk(s)
           RenderSVGInlineText {#text} at (0,0) size 353x122
             chunk 1 text run 1 at (55.00,130.00) startOffset 0 endOffset 9 width 353.00: "Clip Test"
-      RenderSVGContainer {g} at (45,170) size 358x122
-        RenderSVGImage {image} at (45,170) size 358x122
+      RenderSVGContainer {g} at (45,170) size 353x122
+        RenderSVGImage {image} at (45,170) size 353x122
           [clipPath="sample"] RenderSVGResourceClipper {clipPath} at (45,169) size 353x123
     RenderSVGText {text} at (10,304) size 264x46 contains 1 chunk(s)
       RenderSVGInlineText {#text} at (0,0) size 264x46

Added: trunk/LayoutTests/platform/mac/svg/custom/relative-sized-image-expected.png


(Binary files differ)
Property changes on: trunk/LayoutTests/platform/mac/svg/custom/relative-sized-image-expected.png ___________________________________________________________________

Added: svn:mime-type

Added: trunk/LayoutTests/platform/mac/svg/custom/relative-sized-image-expected.txt (0 => 105613)


--- trunk/LayoutTests/platform/mac/svg/custom/relative-sized-image-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac/svg/custom/relative-sized-image-expected.txt	2012-01-23 12:48:12 UTC (rev 105613)
@@ -0,0 +1,13 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x478
+  RenderBlock {html} at (0,0) size 800x478
+    RenderBody {body} at (8,16) size 784x454
+      RenderBlock {p} at (0,0) size 784x36
+        RenderText {#text} at (0,0) size 772x36
+          text run at (0,0) width 772: "The svg area contained in the div element (red box), should fill out the whole area (blue rectangle), especially after resizing"
+          text run at (0,18) width 209: "the content box to a different size"
+      RenderBlock {div} at (0,52) size 402x402 [border: (1px solid #FF0000)]
+        RenderSVGRoot {svg} at (9,69) size 400x400
+          RenderSVGImage {image} at (9,69) size 400x400
+        RenderText {#text} at (0,0) size 0x0

Added: trunk/LayoutTests/platform/mac/svg/repaint/image-with-clip-path-expected.png


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

Added: svn:mime-type

Added: trunk/LayoutTests/svg/custom/relative-sized-image.xhtml (0 => 105613)


--- trunk/LayoutTests/svg/custom/relative-sized-image.xhtml	                        (rev 0)
+++ trunk/LayoutTests/svg/custom/relative-sized-image.xhtml	2012-01-23 12:48:12 UTC (rev 105613)
@@ -0,0 +1,20 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<body _onload_="window.setTimeout(resizeBox, 0)">
+    <p>The svg area contained in the div element (red box), should fill out the whole area (blue rectangle), especially after resizing the content box to a different size</p>
+    <div id="contentBox" style="width: 100px; height: 400px; border: 1px solid red;">
+        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+            <image xlink:href="" width="100%" height="100%" preserveAspectRatio="none"/>
+        </svg>
+    </div>
+    <script type="_javascript_">
+        if (window.layoutTestController)
+            layoutTestController.waitUntilDone();
+
+        function resizeBox() {
+            document.getElementById("contentBox").style.setProperty("width", "400px");
+            if (window.layoutTestController)
+                layoutTestController.notifyDone();
+        }
+    </script>
+</body>
+</html>

Added: trunk/LayoutTests/svg/repaint/image-with-clip-path-expected.txt (0 => 105613)


--- trunk/LayoutTests/svg/repaint/image-with-clip-path-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/svg/repaint/image-with-clip-path-expected.txt	2012-01-23 12:48:12 UTC (rev 105613)
@@ -0,0 +1,2 @@
+Bug 76559: All red should disappear
+

Added: trunk/LayoutTests/svg/repaint/image-with-clip-path.svg (0 => 105613)


--- trunk/LayoutTests/svg/repaint/image-with-clip-path.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/repaint/image-with-clip-path.svg	2012-01-23 12:48:12 UTC (rev 105613)
@@ -0,0 +1,49 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1000" height="600">
+    <text y="-10">Bug 76559: All red should disappear</text>
+    <g id="g" transform="translate(0, 0)">
+        <defs>
+            <clipPath id="p">
+                <rect id="r" x="-10" y="-10" width="20" height="20" />
+            </clipPath>
+        </defs>
+        <image x="-30" y="-30" width="60" height="60" clip-path="url(#p)"
+            xlink:href=""
+    </g>
+<script>
+    var green = "data:image/gif;base64,R0lGODlhAQABAIAAAAD/AAAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==";
+    var red = "data:image/gif;base64,R0lGODlhAQABAIAAAP8AAAAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==";
+
+    var r = document.querySelector('#r');
+    var g = document.querySelector('#g');
+    var i = document.querySelector('image');
+    var update = function(offset, size, img) {
+        r.setAttribute('x', -size / 2);
+        r.setAttribute('y', -size / 2);
+        r.setAttribute('width', size);
+        r.setAttribute('height', size);
+        g.setAttribute("transform","translate(" + offset + ",50)");
+        i.setAttributeNS('http://www.w3.org/1999/xlink', 'href', img);
+    };
+
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText(true);
+        layoutTestController.waitUntilDone();
+    }
+
+    setTimeout(function() {
+        update(50, 100, red);
+
+        setTimeout(function() {
+            if (window.layoutTestController)
+                layoutTestController.display();
+
+            update(200, 50, green);
+
+            setTimeout(function() {
+                if (window.layoutTestController)
+                    layoutTestController.notifyDone();
+            }, 0);
+        }, 0);
+    }, 0);
+</script>
+</svg>

Modified: trunk/Source/WebCore/ChangeLog (105612 => 105613)


--- trunk/Source/WebCore/ChangeLog	2012-01-23 12:42:42 UTC (rev 105612)
+++ trunk/Source/WebCore/ChangeLog	2012-01-23 12:48:12 UTC (rev 105613)
@@ -1,5 +1,40 @@
 2012-01-23  Nikolas Zimmermann  <[email protected]>
 
+        SVG animation repaint issue with image and dynamic clipPath
+        https://bugs.webkit.org/show_bug.cgi?id=76559
+
+        Reviewed by Zoltan Herczeg.
+
+        Based on patch by Kelly Norton <[email protected]>. I extended the patch
+        to correctly handle relative length resolution as well.
+
+        RenderSVGImage doesn't react on setNeedsBoundariesUpdate() calls
+        and thus fails to update its boundaries in some cases.
+
+        The logic is also inconsistent, compared to the other renderers.
+        Fix that properly, by reusing the method used in RenderSVGViewportContainer.
+        Call calculateImageViewport() immediately, after initializing the LayoutRepainter.
+        Previously we resolved the image viewport in RenderSVGImage::updateFromElement. This is
+        wrong, as it queries the frameRect() of the RenderSVGRoot in a state, where the renderer
+        still needs layout, leading to wrong results.
+
+        I turned Kellys manual testcase into a predictable test, see svg/repaint/image-with-clip-path.svg
+        Relative sized image handling is tested in svg/custom/relative-sized-image.xhtml now.
+
+        Tests: svg/custom/relative-sized-image.xhtml
+               svg/repaint/image-with-clip-path.svg
+
+        * rendering/svg/RenderSVGImage.cpp:
+        (WebCore::RenderSVGImage::RenderSVGImage):
+        (WebCore::RenderSVGImage::updateImageViewport):
+        (WebCore::RenderSVGImage::layout):
+        * rendering/svg/RenderSVGImage.h:
+        (WebCore::RenderSVGImage::setNeedsBoundariesUpdate):
+        * svg/SVGImageElement.cpp:
+        (WebCore::SVGImageElement::svgAttributeChanged):
+
+2012-01-23  Nikolas Zimmermann  <[email protected]>
+
         <feImage> has problems referencing local elements
         https://bugs.webkit.org/show_bug.cgi?id=76800
 

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGImage.cpp (105612 => 105613)


--- trunk/Source/WebCore/rendering/svg/RenderSVGImage.cpp	2012-01-23 12:42:42 UTC (rev 105612)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGImage.cpp	2012-01-23 12:48:12 UTC (rev 105613)
@@ -49,7 +49,7 @@
 
 RenderSVGImage::RenderSVGImage(SVGImageElement* impl)
     : RenderSVGModelObject(impl)
-    , m_updateCachedRepaintRect(true)
+    , m_needsBoundariesUpdate(true)
     , m_needsTransformUpdate(true)
     , m_imageResource(RenderImageResource::create())
 {
@@ -61,24 +61,39 @@
     m_imageResource->shutdown();
 }
 
+bool RenderSVGImage::updateImageViewport()
+{
+    SVGImageElement* image = static_cast<SVGImageElement*>(node());
+    FloatRect oldBoundaries = m_objectBoundingBox;
+
+    SVGLengthContext lengthContext(image);
+    m_objectBoundingBox = FloatRect(image->x().value(lengthContext), image->y().value(lengthContext), image->width().value(lengthContext), image->height().value(lengthContext));
+
+    if (oldBoundaries == m_objectBoundingBox)
+        return false;
+
+    m_imageResource->setContainerSizeForRenderer(enclosingIntRect(m_objectBoundingBox).size());
+    m_needsBoundariesUpdate = true;
+    return true;
+}
+
 void RenderSVGImage::layout()
 {
     ASSERT(needsLayout());
 
     LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && selfNeedsLayout());
-    SVGImageElement* image = static_cast<SVGImageElement*>(node());
-    m_imageResource->setContainerSizeForRenderer(enclosingIntRect(m_objectBoundingBox).size());
+    updateImageViewport();
 
-    bool transformOrBoundariesUpdate = m_needsTransformUpdate || m_updateCachedRepaintRect;
+    bool transformOrBoundariesUpdate = m_needsTransformUpdate || m_needsBoundariesUpdate;
     if (m_needsTransformUpdate) {
-        m_localTransform = image->animatedLocalTransform();
+        m_localTransform = static_cast<SVGImageElement*>(node())->animatedLocalTransform();
         m_needsTransformUpdate = false;
     }
 
-    if (m_updateCachedRepaintRect) {
+    if (m_needsBoundariesUpdate) {
         m_repaintBoundingBox = m_objectBoundingBox;
         SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingBox);
-        m_updateCachedRepaintRect = false;
+        m_needsBoundariesUpdate = false;
     }
 
     // Invalidate all resources of this client if our layout changed.
@@ -93,20 +108,6 @@
     setNeedsLayout(false);
 }
 
-void RenderSVGImage::updateFromElement()
-{
-    SVGImageElement* image = static_cast<SVGImageElement*>(node());
-
-    FloatRect oldBoundaries = m_objectBoundingBox;
-    SVGLengthContext lengthContext(image);
-    m_objectBoundingBox = FloatRect(image->x().value(lengthContext), image->y().value(lengthContext), image->width().value(lengthContext), image->height().value(lengthContext));
-    if (m_objectBoundingBox != oldBoundaries) {
-        m_updateCachedRepaintRect = true;
-        setNeedsLayout(true);
-    }
-    RenderSVGModelObject::updateFromElement();
-}
-
 void RenderSVGImage::paint(PaintInfo& paintInfo, const LayoutPoint&)
 {
     if (paintInfo.context->paintingDisabled() || style()->visibility() == HIDDEN || !m_imageResource->hasImage())

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGImage.h (105612 => 105613)


--- trunk/Source/WebCore/rendering/svg/RenderSVGImage.h	2012-01-23 12:42:42 UTC (rev 105612)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGImage.h	2012-01-23 12:48:12 UTC (rev 105613)
@@ -41,8 +41,9 @@
     RenderSVGImage(SVGImageElement*);
     virtual ~RenderSVGImage();
 
+    bool updateImageViewport();
+    virtual void setNeedsBoundariesUpdate() { m_needsBoundariesUpdate = true; }
     virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
-    virtual void updateFromElement();
 
     RenderImageResource* imageResource() { return m_imageResource.get(); }
     const RenderImageResource* imageResource() const { return m_imageResource.get(); }
@@ -67,8 +68,9 @@
     virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
 
     virtual AffineTransform localTransform() const { return m_localTransform; }
+    void calculateImageViewport();
 
-    bool m_updateCachedRepaintRect : 1;
+    bool m_needsBoundariesUpdate : 1;
     bool m_needsTransformUpdate : 1;
     AffineTransform m_localTransform;
     FloatRect m_objectBoundingBox;

Modified: trunk/Source/WebCore/svg/SVGImageElement.cpp (105612 => 105613)


--- trunk/Source/WebCore/svg/SVGImageElement.cpp	2012-01-23 12:42:42 UTC (rev 105612)
+++ trunk/Source/WebCore/svg/SVGImageElement.cpp	2012-01-23 12:48:12 UTC (rev 105613)
@@ -149,8 +149,8 @@
         return;
 
     if (isLengthAttribute) {
-        renderer->updateFromElement();
-        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, false);
+        if (toRenderSVGImage(renderer)->updateImageViewport())
+            RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
     }
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to