Elements with rendering disabled due to dimensions should not contribute to parent...
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 13 Jul 2014 06:35:21 +0000 (06:35 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 13 Jul 2014 06:35:21 +0000 (06:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=134184

Patch by Nikos Andronikos <nikos.andronikos-webkit@cisra.canon.com.au> on 2014-07-12
Reviewed by Dirk Schulze.

Source/WebCore:
SVG elements that have rendering disabled should not contribute to any ancestor elements bounding box.
Examples of elements with rendering disabled:
- basic shape with width <= 0 or height <= 0
- path with no path data (d attribute missing or empty)
- polyline or polygon element with no point data (points attribute missing or empty)

To achieve this a method (isRenderingDisabled) was added to RenderSVGShape and it's derived classes.
This is used to determine if an element is included when creating the union of child bounding boxes
in a container element.

Tests: svg/custom/GetBBox-path-nodata.html
       svg/custom/GetBBox-polygon-nodata.html
       svg/custom/GetBBox-polyline-nodata.html
       svg/custom/getBBox-container-hiddenchild.html

* rendering/svg/RenderSVGEllipse.cpp:
(WebCore::RenderSVGEllipse::isRenderingDisabled):
New method added. Checks bounding box to determine if rendering is disabled.
* rendering/svg/RenderSVGEllipse.h:
* rendering/svg/RenderSVGPath.cpp:
(WebCore::RenderSVGPath::isRenderingDisabled):
New method added. Checks bounding box to determine if rendering is disabled.
* rendering/svg/RenderSVGPath.h:
* rendering/svg/RenderSVGRect.cpp:
(WebCore::RenderSVGRect::isRenderingDisabled):
New method added. Checks bounding box to determine if rendering is disabled.
* rendering/svg/RenderSVGRect.h:
* rendering/svg/RenderSVGShape.h:
(WebCore::RenderSVGShape::isRenderingDisabled):
New method added. Always returns false so that derived classes that do not
implement this method retain the existing behaviour.
* rendering/svg/SVGRenderSupport.cpp:
(WebCore::SVGRenderSupport::computeContainerBoundingBoxes):
For each element potentially being included in the unioned bounding box of
a container, check isRenderingDisabled and skip that element if true.

* rendering/svg/RenderSVGEllipse.cpp:
(WebCore::RenderSVGEllipse::isRenderingDisabled):
* rendering/svg/RenderSVGEllipse.h:
* rendering/svg/RenderSVGPath.cpp:
(WebCore::RenderSVGPath::isRenderingDisabled):
* rendering/svg/RenderSVGPath.h:
* rendering/svg/RenderSVGRect.cpp:
(WebCore::RenderSVGRect::isRenderingDisabled):
* rendering/svg/RenderSVGRect.h:
* rendering/svg/RenderSVGShape.h:
* rendering/svg/SVGRenderSupport.cpp:
(WebCore::SVGRenderSupport::computeContainerBoundingBoxes):

LayoutTests:
Test, for each element type, that when rendering is disabled, that element does not contribute
to the bounding box for an ancestor element.

Added test to ensure zero width/height polyline and polygon do contribute to ancestor bounding box.

Updated expected results for 1 existing test (shapes-rect-02-t) as this test included zero
width and zero height rects and these were previously included in the repaint rect.

* platform/mac/svg/W3C-SVG-1.1/shapes-rect-02-t-expected.txt:
* svg/custom/GetBBox-path-nodata-expected.txt: Added.
* svg/custom/GetBBox-path-nodata.html: Added.
* svg/custom/GetBBox-polygon-nodata-expected.txt: Added.
* svg/custom/GetBBox-polygon-nodata.html: Added.
* svg/custom/GetBBox-polyline-nodata-expected.txt: Added.
* svg/custom/GetBBox-polyline-nodata.html: Added.
* svg/custom/getBBox-container-hiddenchild-expected.txt: Added.
* svg/custom/getBBox-container-hiddenchild.html: Added.
* svg/custom/getBBox-perpendicular-polygon-expected.txt: Added.
* svg/custom/getBBox-perpendicular-polygon.svg: Added.
* svg/custom/getBBox-perpendicular-polyline-expected.txt: Added.
* svg/custom/getBBox-perpendicular-polyline.svg: Added.

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

23 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/mac/svg/W3C-SVG-1.1/shapes-rect-02-t-expected.txt
LayoutTests/svg/custom/GetBBox-path-nodata-expected.txt [new file with mode: 0644]
LayoutTests/svg/custom/GetBBox-path-nodata.html [new file with mode: 0644]
LayoutTests/svg/custom/GetBBox-polygon-nodata-expected.txt [new file with mode: 0644]
LayoutTests/svg/custom/GetBBox-polygon-nodata.html [new file with mode: 0644]
LayoutTests/svg/custom/GetBBox-polyline-nodata-expected.txt [new file with mode: 0644]
LayoutTests/svg/custom/GetBBox-polyline-nodata.html [new file with mode: 0644]
LayoutTests/svg/custom/getBBox-container-hiddenchild-expected.txt [new file with mode: 0644]
LayoutTests/svg/custom/getBBox-container-hiddenchild.html [new file with mode: 0644]
LayoutTests/svg/custom/getBBox-perpendicular-polygon-expected.txt [new file with mode: 0644]
LayoutTests/svg/custom/getBBox-perpendicular-polygon.svg [new file with mode: 0644]
LayoutTests/svg/custom/getBBox-perpendicular-polyline-expected.txt [new file with mode: 0644]
LayoutTests/svg/custom/getBBox-perpendicular-polyline.svg [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/svg/RenderSVGEllipse.cpp
Source/WebCore/rendering/svg/RenderSVGEllipse.h
Source/WebCore/rendering/svg/RenderSVGPath.cpp
Source/WebCore/rendering/svg/RenderSVGPath.h
Source/WebCore/rendering/svg/RenderSVGRect.cpp
Source/WebCore/rendering/svg/RenderSVGRect.h
Source/WebCore/rendering/svg/RenderSVGShape.h
Source/WebCore/rendering/svg/SVGRenderSupport.cpp

index f0d2435..1e03299 100644 (file)
@@ -1,3 +1,32 @@
+2014-07-12  Nikos Andronikos  <nikos.andronikos-webkit@cisra.canon.com.au>
+
+        Elements with rendering disabled due to dimensions should not contribute to parent bounding box
+        https://bugs.webkit.org/show_bug.cgi?id=134184
+
+        Reviewed by Dirk Schulze.
+
+        Test, for each element type, that when rendering is disabled, that element does not contribute
+        to the bounding box for an ancestor element.
+
+        Added test to ensure zero width/height polyline and polygon do contribute to ancestor bounding box.
+
+        Updated expected results for 1 existing test (shapes-rect-02-t) as this test included zero
+        width and zero height rects and these were previously included in the repaint rect.
+
+        * platform/mac/svg/W3C-SVG-1.1/shapes-rect-02-t-expected.txt:
+        * svg/custom/GetBBox-path-nodata-expected.txt: Added.
+        * svg/custom/GetBBox-path-nodata.html: Added.
+        * svg/custom/GetBBox-polygon-nodata-expected.txt: Added.
+        * svg/custom/GetBBox-polygon-nodata.html: Added.
+        * svg/custom/GetBBox-polyline-nodata-expected.txt: Added.
+        * svg/custom/GetBBox-polyline-nodata.html: Added.
+        * svg/custom/getBBox-container-hiddenchild-expected.txt: Added.
+        * svg/custom/getBBox-container-hiddenchild.html: Added.
+        * svg/custom/getBBox-perpendicular-polygon-expected.txt: Added.
+        * svg/custom/getBBox-perpendicular-polygon.svg: Added.
+        * svg/custom/getBBox-perpendicular-polyline-expected.txt: Added.
+        * svg/custom/getBBox-perpendicular-polyline.svg: Added.
+
 2014-07-11  Jer Noble  <jer.noble@apple.com>
 
         [MSE] http/tests/media/media-source/mediasource-duration.html is failing.
index 9fd8aea..2b5f27f 100644 (file)
@@ -2,7 +2,7 @@ layer at (0,0) size 480x360
   RenderView at (0,0) size 480x360
 layer at (0,0) size 480x360
   RenderSVGRoot {svg} at (0,0) size 480x360
-    RenderSVGContainer {g} at (0,0) size 401x277
+    RenderSVGContainer {g} at (0,0) size 181x277
       RenderSVGRect {rect} at (0,45) size 51x82 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#FF0000]}] [x=0.00] [y=46.00] [width=50.00] [height=80.00]
       RenderSVGRect {rect} at (129,0) size 52x81 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#FF0000]}] [x=130.00] [y=0.00] [width=50.00] [height=80.00]
       RenderSVGRect {rect} at (249,45) size 2x82 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#FF0000]}] [x=250.00] [y=46.00] [width=0.00] [height=80.00]
diff --git a/LayoutTests/svg/custom/GetBBox-path-nodata-expected.txt b/LayoutTests/svg/custom/GetBBox-path-nodata-expected.txt
new file mode 100644 (file)
index 0000000..872d6de
--- /dev/null
@@ -0,0 +1,7 @@
+Bug 134184: getBBox on path with no d attribute should return (0,0,0,0) and should not contribute to parent bbox
+
+For this test to pass, you should see 'Passed' twice below.
+
+Passed; Passed;
+
+
diff --git a/LayoutTests/svg/custom/GetBBox-path-nodata.html b/LayoutTests/svg/custom/GetBBox-path-nodata.html
new file mode 100644 (file)
index 0000000..413e86c
--- /dev/null
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+  <script>
+    function check_rect_bbox(bbox, expected_bbox, test_name)
+    {
+        var result = true;
+        var result_str = "";
+
+        if (bbox.x == expected_bbox.x && bbox.y == expected_bbox.y && bbox.width == expected_bbox.width && bbox.height == expected_bbox.height) {                           
+            result_str = "Passed";
+           } else {
+            result_str += test_name + ": Failed";
+            result_str += "("+bbox.x+","+bbox.y+":"+bbox.width + "," + bbox.height+")";
+            result = false;
+        }
+        
+        var p_result = document.querySelector("#result");
+        p_result.appendChild(document.createTextNode(result_str + "; "));
+        return result;
+    }
+  
+    function run()
+    {
+        if (window.testRunner)
+            testRunner.dumpAsText();
+        
+        var p_bbox = document.querySelector("#p1").getBBox();
+        var g_bbox = document.querySelector("g").getBBox();
+        
+        var result = true;
+
+        result &= check_rect_bbox(p_bbox, {"x":0, "y":0, "width":0, "height":0}, "getBBox on path with no d attribute")
+        result &= check_rect_bbox(g_bbox, document.querySelector("#r1").getBBox(),"path doesn't contribute to parent bbox")
+        
+        if (!result) {
+            var visible_rect = document.querySelector("#r1");
+            visible_rect.setAttribute("fill", "red");
+        }
+   }
+  </script>
+
+<body onload="run()">
+<p>Bug <a href="https://bugs.webkit.org/show_bug.cgi?id=134184">134184</a>: getBBox on path with no d attribute should return (0,0,0,0) and should not contribute to parent bbox</p>
+<p>For this test to pass, you should see 'Passed' twice below.</a>
+<p id="result"></p>
+<svg xmlns="http://www.w3.org/2000/svg">
+<g>
+    <path id="p1" fill="none" stroke="red" />
+    <rect id="r1" x="50" y="50" width="50" height="50" fill="green" />
+</g>
+</svg>
+</body>
+</html>
diff --git a/LayoutTests/svg/custom/GetBBox-polygon-nodata-expected.txt b/LayoutTests/svg/custom/GetBBox-polygon-nodata-expected.txt
new file mode 100644 (file)
index 0000000..b2b9416
--- /dev/null
@@ -0,0 +1,7 @@
+Bug 134184: getBBox on polygon with no points attribute should return (0,0,0,0) and should not contribute to parent bbox
+
+For this test to pass, you should see 'Passed' twice below.
+
+Passed; Passed;
+
+
diff --git a/LayoutTests/svg/custom/GetBBox-polygon-nodata.html b/LayoutTests/svg/custom/GetBBox-polygon-nodata.html
new file mode 100644 (file)
index 0000000..5e5f766
--- /dev/null
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+  <script>
+    function check_rect_bbox(bbox, expected_bbox, test_name)
+    {
+        var result = true;
+        var result_str = "";
+
+        if (bbox.x == expected_bbox.x && bbox.y == expected_bbox.y && bbox.width == expected_bbox.width && bbox.height == expected_bbox.height) {                           
+            result_str = "Passed";
+           } else {
+            result_str += test_name + ": Failed";
+            result_str += "("+bbox.x+","+bbox.y+":"+bbox.width + "," + bbox.height+")";
+            result = false;
+        }
+        
+        var p_result = document.querySelector("#result");
+        p_result.appendChild(document.createTextNode(result_str + "; "));
+        return result;
+    }
+  
+    function run()
+    {
+        if (window.testRunner)
+            testRunner.dumpAsText();
+        
+        var p_bbox = document.querySelector("#p1").getBBox();
+        var g_bbox = document.querySelector("g").getBBox();
+        
+        var result = true;
+
+        result &= check_rect_bbox(p_bbox, {"x":0, "y":0, "width":0, "height":0}, "getBBox on polygon with no points attribute")
+        result &= check_rect_bbox(g_bbox, document.querySelector("#r1").getBBox(),"polygon doesn't contribute to parent bbox")
+        
+        if (!result) {
+            var visible_rect = document.querySelector("#r1");
+            visible_rect.setAttribute("fill", "red");
+        }
+   }
+  </script>
+
+<body onload="run()">
+<p>Bug <a href="https://bugs.webkit.org/show_bug.cgi?id=134184">134184</a>: getBBox on polygon with no points attribute should return (0,0,0,0) and should not contribute to parent bbox</p>
+<p>For this test to pass, you should see 'Passed' twice below.</a>
+<p id="result"></p>
+<svg xmlns="http://www.w3.org/2000/svg">
+<g>
+    <polygon id="p1" fill="none" stroke="red" />
+    <rect id="r1" x="50" y="50" width="50" height="50" fill="green" />
+</g>
+</svg>
+</body>
+</html>
diff --git a/LayoutTests/svg/custom/GetBBox-polyline-nodata-expected.txt b/LayoutTests/svg/custom/GetBBox-polyline-nodata-expected.txt
new file mode 100644 (file)
index 0000000..03d146a
--- /dev/null
@@ -0,0 +1,7 @@
+Bug 134184: getBBox on polyline with no points attribute should return (0,0,0,0) and should not contribute to parent bbox
+
+For this test to pass, you should see 'Passed' twice below.
+
+Passed; Passed;
+
+
diff --git a/LayoutTests/svg/custom/GetBBox-polyline-nodata.html b/LayoutTests/svg/custom/GetBBox-polyline-nodata.html
new file mode 100644 (file)
index 0000000..c730932
--- /dev/null
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+  <script>
+    function check_rect_bbox(bbox, expected_bbox, test_name)
+    {
+        var result = true;
+        var result_str = "";
+
+        if (bbox.x == expected_bbox.x && bbox.y == expected_bbox.y && bbox.width == expected_bbox.width && bbox.height == expected_bbox.height) {                           
+            result_str = "Passed";
+           } else {
+            result_str += test_name + ": Failed";
+            result_str += "("+bbox.x+","+bbox.y+":"+bbox.width + "," + bbox.height+")";
+            result = false;
+        }
+        
+        var p_result = document.querySelector("#result");
+        p_result.appendChild(document.createTextNode(result_str + "; "));
+        return result;
+    }
+  
+    function run()
+    {
+        if (window.testRunner)
+            testRunner.dumpAsText();
+        
+        var p_bbox = document.querySelector("#p1").getBBox();
+        var g_bbox = document.querySelector("g").getBBox();
+        
+        var result = true;
+
+        result &= check_rect_bbox(p_bbox, {"x":0, "y":0, "width":0, "height":0}, "getBBox on polyline with no points attribute")
+        result &= check_rect_bbox(g_bbox, document.querySelector("#r1").getBBox(),"polyline doesn't contribute to parent bbox")
+        
+        if (!result) {
+            var visible_rect = document.querySelector("#r1");
+            visible_rect.setAttribute("fill", "red");
+        }
+   }
+  </script>
+
+<body onload="run()">
+<p>Bug <a href="https://bugs.webkit.org/show_bug.cgi?id=134184">134184</a>: getBBox on polyline with no points attribute should return (0,0,0,0) and should not contribute to parent bbox</p>
+<p>For this test to pass, you should see 'Passed' twice below.</a>
+<p id="result"></p>
+<svg xmlns="http://www.w3.org/2000/svg">
+<g>
+    <path id="p1" fill="none" stroke="red" />
+    <rect id="r1" x="50" y="50" width="50" height="50" fill="green" />
+</g>
+</svg>
+</body>
+</html>
diff --git a/LayoutTests/svg/custom/getBBox-container-hiddenchild-expected.txt b/LayoutTests/svg/custom/getBBox-container-hiddenchild-expected.txt
new file mode 100644 (file)
index 0000000..af2d847
--- /dev/null
@@ -0,0 +1,8 @@
+CONSOLE MESSAGE: line 56: Error: Invalid negative value for <rect> attribute width="-1"
+Bug 134184: Bounding box of hidden child is unioned with other elements of group
+
+For this test to pass, you should see 'Passed' below.
+
+Passed;
+
+
diff --git a/LayoutTests/svg/custom/getBBox-container-hiddenchild.html b/LayoutTests/svg/custom/getBBox-container-hiddenchild.html
new file mode 100644 (file)
index 0000000..c282b0f
--- /dev/null
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+  <script>
+    function check_rect_bbox(bbox, test_name)
+    {
+        var result_str = "";
+        var visible_rect = document.querySelector("#r1");
+        var expected_bbox = visible_rect.getBBox();
+
+        if (bbox.x == expected_bbox.x && bbox.y == expected_bbox.y && bbox.width == expected_bbox.width && bbox.height == expected_bbox.height) {                           
+            result_str = "Passed";
+           } else {
+            result_str += test_name + ": Failed";
+            result_str += "("+bbox.x+","+bbox.y+":"+bbox.width + "," + bbox.height+")";
+            visible_rect.setAttribute("fill", "red");
+     
+            var bbox_rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
+            bbox_rect.setAttribute("x", bbox.x);
+            bbox_rect.setAttribute("y", bbox.y);
+            bbox_rect.setAttribute("width", bbox.width);
+            bbox_rect.setAttribute("height", bbox.height);
+            bbox_rect.setAttribute("fill", "none");
+            bbox_rect.setAttribute("stroke", "red");
+            bbox_rect.setAttribute("stroke-dasharray", "5 5");
+            document.querySelector("svg").appendChild(bbox_rect);
+        }
+        
+        var p_result = document.querySelector("#result");
+        p_result.appendChild(document.createTextNode(result_str + "; "));
+    }
+  
+    function run()
+    {
+        if (window.testRunner)
+            testRunner.dumpAsText();
+        
+        var g_bbox = document.querySelector("#g1").getBBox();
+        check_rect_bbox(g_bbox, "Group with hidden child");
+    }
+  </script>
+
+<body onload="run()">
+<p>Bug <a href="https://bugs.webkit.org/show_bug.cgi?id=134184">134184</a>: Bounding box of hidden child is unioned with other elements of group</p>
+<p>For this test to pass, you should see 'Passed' below.</a>
+<p id="result"></p>
+<svg xmlns="http://www.w3.org/2000/svg">
+<g id="g1">
+    <rect id="r1" x="50" y="50" width="50" height="50" fill="green" />
+    <rect id="r2" x="20" y="20" width="20" height="0" fill="red" />
+    <rect id="r3" x="120" y="20" width="20" height="20" fill="blue" style="display:none" />
+    <ellipse id="c1" cx="20" cy="120" rx="0" ry="20" fill="black" />
+    <!-- test the fall-back case as well as the normal case -->
+    <ellipse id="c2" cx="120" cy="20" rx="0" ry="20" stroke="black" vector-effect="non-scaling-stroke" />
+    <rect id="r4" x="20" y="120" width="20" height="0" fill="none" stroke="black" vector-effect="non-scaling-stroke" />
+    <g>
+        <rect id="r4" x="120" y="120" width="-1" height="100" fill="cyan" />
+    </g>
+</g>
+</svg>
+</body>
+</html>
diff --git a/LayoutTests/svg/custom/getBBox-perpendicular-polygon-expected.txt b/LayoutTests/svg/custom/getBBox-perpendicular-polygon-expected.txt
new file mode 100644 (file)
index 0000000..ae7b88f
--- /dev/null
@@ -0,0 +1 @@
+100 100 PASS
diff --git a/LayoutTests/svg/custom/getBBox-perpendicular-polygon.svg b/LayoutTests/svg/custom/getBBox-perpendicular-polygon.svg
new file mode 100644 (file)
index 0000000..f57358d
--- /dev/null
@@ -0,0 +1,25 @@
+<!-- Test the bounding box calculated for two perpendicular lines of length 100px created with the polygon element -->
+<!-- If the bounding box is 100x100, we consider this test passing. -->
+<svg xmlns="http://www.w3.org/2000/svg" onload="init()">
+  <script type="text/javascript">
+  <![CDATA[
+    function init()
+    {
+        if (window.testRunner)
+            testRunner.dumpAsText();
+        var txt = document.getElementById("text");
+        size = document.getElementById("shape").getBBox();
+        var passState = "FAIL";
+        if(size.width == 100 && size.height == 100)
+            passState = "PASS";
+        var textNode = document.createTextNode(size.width + " " + size.height + " " + passState);
+        txt.appendChild(textNode);
+    }
+  ]]>
+  </script>
+  <g id="shape">
+    <polygon stroke="#666666" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" points="5,5 5,105" fill-rule="nonzero" />
+    <polygon stroke="#666666" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" points="5,5 105,5" fill-rule="nonzero" />
+  </g>
+  <text id="text" x="50" y="50" />
+</svg>
diff --git a/LayoutTests/svg/custom/getBBox-perpendicular-polyline-expected.txt b/LayoutTests/svg/custom/getBBox-perpendicular-polyline-expected.txt
new file mode 100644 (file)
index 0000000..ae7b88f
--- /dev/null
@@ -0,0 +1 @@
+100 100 PASS
diff --git a/LayoutTests/svg/custom/getBBox-perpendicular-polyline.svg b/LayoutTests/svg/custom/getBBox-perpendicular-polyline.svg
new file mode 100644 (file)
index 0000000..e04c436
--- /dev/null
@@ -0,0 +1,25 @@
+<!-- Test the bounding box calculated for two perpendicular lines of length 100px created with the polyline element -->
+<!-- If the bounding box is 100x100, we consider this test passing. -->
+<svg xmlns="http://www.w3.org/2000/svg" onload="init()">
+  <script type="text/javascript">
+  <![CDATA[
+    function init()
+    {
+        if (window.testRunner)
+            testRunner.dumpAsText();
+        var txt = document.getElementById("text");
+        size = document.getElementById("shape").getBBox();
+        var passState = "FAIL";
+        if(size.width == 100 && size.height == 100)
+            passState = "PASS";
+        var textNode = document.createTextNode(size.width + " " + size.height + " " + passState);
+        txt.appendChild(textNode);
+    }
+  ]]>
+  </script>
+  <g id="shape">
+    <polyline stroke="#666666" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" points="5,5 5,105" fill-rule="nonzero" />
+    <polyline stroke="#666666" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" points="5,5 105,5" fill-rule="nonzero" />
+  </g>
+  <text id="text" x="50" y="50" />
+</svg>
index 29634d5..d51b97e 100644 (file)
@@ -1,3 +1,59 @@
+2014-07-12  Nikos Andronikos  <nikos.andronikos-webkit@cisra.canon.com.au>
+
+        Elements with rendering disabled due to dimensions should not contribute to parent bounding box
+        https://bugs.webkit.org/show_bug.cgi?id=134184
+
+        Reviewed by Dirk Schulze.
+
+        SVG elements that have rendering disabled should not contribute to any ancestor elements bounding box.
+        Examples of elements with rendering disabled:
+        - basic shape with width <= 0 or height <= 0
+        - path with no path data (d attribute missing or empty)
+        - polyline or polygon element with no point data (points attribute missing or empty)
+
+        To achieve this a method (isRenderingDisabled) was added to RenderSVGShape and it's derived classes.
+        This is used to determine if an element is included when creating the union of child bounding boxes
+        in a container element.
+
+        Tests: svg/custom/GetBBox-path-nodata.html
+               svg/custom/GetBBox-polygon-nodata.html
+               svg/custom/GetBBox-polyline-nodata.html
+               svg/custom/getBBox-container-hiddenchild.html
+
+        * rendering/svg/RenderSVGEllipse.cpp:
+        (WebCore::RenderSVGEllipse::isRenderingDisabled):
+        New method added. Checks bounding box to determine if rendering is disabled.
+        * rendering/svg/RenderSVGEllipse.h:
+        * rendering/svg/RenderSVGPath.cpp:
+        (WebCore::RenderSVGPath::isRenderingDisabled):
+        New method added. Checks bounding box to determine if rendering is disabled.
+        * rendering/svg/RenderSVGPath.h:
+        * rendering/svg/RenderSVGRect.cpp:
+        (WebCore::RenderSVGRect::isRenderingDisabled):
+        New method added. Checks bounding box to determine if rendering is disabled.
+        * rendering/svg/RenderSVGRect.h:
+        * rendering/svg/RenderSVGShape.h:
+        (WebCore::RenderSVGShape::isRenderingDisabled):
+        New method added. Always returns false so that derived classes that do not
+        implement this method retain the existing behaviour.
+        * rendering/svg/SVGRenderSupport.cpp:
+        (WebCore::SVGRenderSupport::computeContainerBoundingBoxes):
+        For each element potentially being included in the unioned bounding box of
+        a container, check isRenderingDisabled and skip that element if true.
+
+        * rendering/svg/RenderSVGEllipse.cpp:
+        (WebCore::RenderSVGEllipse::isRenderingDisabled):
+        * rendering/svg/RenderSVGEllipse.h:
+        * rendering/svg/RenderSVGPath.cpp:
+        (WebCore::RenderSVGPath::isRenderingDisabled):
+        * rendering/svg/RenderSVGPath.h:
+        * rendering/svg/RenderSVGRect.cpp:
+        (WebCore::RenderSVGRect::isRenderingDisabled):
+        * rendering/svg/RenderSVGRect.h:
+        * rendering/svg/RenderSVGShape.h:
+        * rendering/svg/SVGRenderSupport.cpp:
+        (WebCore::SVGRenderSupport::computeContainerBoundingBoxes):
+
 2014-07-12  Benjamin Poulain  <benjamin@webkit.org>
 
         Rename selectorListContainsUncommonAttributeSelector() to selectorListContainsAttributeSelector()
index 7878089..141d5a4 100644 (file)
@@ -153,4 +153,10 @@ bool RenderSVGEllipse::shapeDependentFillContains(const FloatPoint& point, const
     return xrX * xrX + yrY * yrY <= 1.0;
 }
 
+bool RenderSVGEllipse::isRenderingDisabled() const
+{
+    // A radius of zero disables rendering of the element, and results in an empty bounding box.
+    return m_fillBoundingBox.isEmpty();
+}
+
 }
index 6fda194..d62a560 100644 (file)
@@ -41,6 +41,7 @@ private:
 
     virtual void updateShapeFromElement();
     virtual bool isEmpty() const { return m_usePathFallback ? RenderSVGShape::isEmpty() : m_fillBoundingBox.isEmpty(); };
+    virtual bool isRenderingDisabled() const override;
     virtual void fillShape(GraphicsContext*) const;
     virtual void strokeShape(GraphicsContext*) const;
     virtual bool shapeDependentStrokeContains(const FloatPoint&);
index 0e1f1a0..71a162b 100644 (file)
@@ -159,4 +159,11 @@ void RenderSVGPath::updateZeroLengthSubpaths()
     subpathData.pathIsDone();
 }
 
+bool RenderSVGPath::isRenderingDisabled() const
+{
+    // For a polygon, polyline or path, rendering is disabled if there is no path data.
+    // No path data is possible in the case of a missing or empty 'd' or 'points' attribute.
+    return path().isEmpty();
+}
+
 }
index c2c81b1..89e9500 100644 (file)
@@ -50,6 +50,8 @@ private:
     FloatRect zeroLengthSubpathRect(const FloatPoint&, float) const;
     void updateZeroLengthSubpaths();
 
+    virtual bool isRenderingDisabled() const override;
+
     Vector<FloatPoint> m_zeroLengthLinecapLocations;
 };
 
index 8e575a9..9ef4324 100644 (file)
@@ -151,4 +151,10 @@ bool RenderSVGRect::shapeDependentFillContains(const FloatPoint& point, const Wi
     return m_fillBoundingBox.contains(point.x(), point.y());
 }
 
+bool RenderSVGRect::isRenderingDisabled() const
+{
+    // A width or height of zero disables rendering for the element, and results in an empty bounding box.
+    return m_fillBoundingBox.isEmpty();
+}
+
 }
index f56dd33..f02dfcf 100644 (file)
@@ -47,6 +47,7 @@ private:
 
     virtual void updateShapeFromElement();
     virtual bool isEmpty() const { return m_usePathFallback ? RenderSVGShape::isEmpty() : m_fillBoundingBox.isEmpty(); };
+    virtual bool isRenderingDisabled() const override;
     virtual void fillShape(GraphicsContext*) const;
     virtual void strokeShape(GraphicsContext*) const;
     virtual bool shapeDependentStrokeContains(const FloatPoint&);
index 8814034..7a37752 100644 (file)
@@ -57,6 +57,7 @@ public:
     virtual void setNeedsTransformUpdate() override final { m_needsTransformUpdate = true; }
     virtual void fillShape(GraphicsContext*) const;
     virtual void strokeShape(GraphicsContext*) const;
+    virtual bool isRenderingDisabled() const = 0;
 
     bool hasPath() const { return m_path.get(); }
     Path& path() const
index 36f7fe0..45d6228 100644 (file)
@@ -157,6 +157,10 @@ void SVGRenderSupport::computeContainerBoundingBoxes(const RenderElement& contai
         if (current->isSVGHiddenContainer())
             continue;
 
+        // Don't include elements in the union that do not render.
+        if (current->isSVGShape() && toRenderSVGShape(current)->isRenderingDisabled())
+            continue;
+
         const AffineTransform& transform = current->localToParentTransform();
         if (transform.isIdentity()) {
             updateObjectBoundingBox(objectBoundingBox, objectBoundingBoxValid, current, current->objectBoundingBox());