Title: [106882] trunk
Revision
106882
Author
[email protected]
Date
2012-02-06 17:30:50 -0800 (Mon, 06 Feb 2012)

Log Message

RenderSVGShape::strokeContains will fail for some strokes
https://bugs.webkit.org/show_bug.cgi?id=76931

Patch by Stephen Chenney <[email protected]> on 2012-02-06
Reviewed by Darin Adler.

Source/WebCore:

Adding support for rounded zero-length endcaps for SVG path hit
testing.

Tests: svg/hittest/zero-length-butt-cap-path.xhtml
       svg/hittest/zero-length-round-cap-path.xhtml
       svg/hittest/zero-length-square-cap-path.xhtml

* rendering/svg/RenderSVGShape.cpp:
(WebCore::RenderSVGShape::strokeContains):

LayoutTests:

New tests for hit testing against an SVG path of zero length with
endcaps.

* svg/hittest/zero-length-butt-cap-path-expected.txt: Added.
* svg/hittest/zero-length-butt-cap-path.xhtml: Added.
* svg/hittest/zero-length-round-cap-path-expected.txt: Added.
* svg/hittest/zero-length-round-cap-path.xhtml: Added.
* svg/hittest/zero-length-square-cap-path-expected.txt: Added.
* svg/hittest/zero-length-square-cap-path.xhtml: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (106881 => 106882)


--- trunk/LayoutTests/ChangeLog	2012-02-07 01:09:43 UTC (rev 106881)
+++ trunk/LayoutTests/ChangeLog	2012-02-07 01:30:50 UTC (rev 106882)
@@ -1,3 +1,20 @@
+2012-02-06  Stephen Chenney  <[email protected]>
+
+        RenderSVGShape::strokeContains will fail for some strokes
+        https://bugs.webkit.org/show_bug.cgi?id=76931
+
+        Reviewed by Darin Adler.
+
+        New tests for hit testing against an SVG path of zero length with
+        endcaps.
+
+        * svg/hittest/zero-length-butt-cap-path-expected.txt: Added.
+        * svg/hittest/zero-length-butt-cap-path.xhtml: Added.
+        * svg/hittest/zero-length-round-cap-path-expected.txt: Added.
+        * svg/hittest/zero-length-round-cap-path.xhtml: Added.
+        * svg/hittest/zero-length-square-cap-path-expected.txt: Added.
+        * svg/hittest/zero-length-square-cap-path.xhtml: Added.
+
 2012-02-06  Philip Rogers  <[email protected]>
 
         Fix color animations by value

Added: trunk/LayoutTests/svg/hittest/zero-length-butt-cap-path-expected.txt (0 => 106882)


--- trunk/LayoutTests/svg/hittest/zero-length-butt-cap-path-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/svg/hittest/zero-length-butt-cap-path-expected.txt	2012-02-07 01:30:50 UTC (rev 106882)
@@ -0,0 +1 @@
+PASSED; PASSED; PASSED; PASSED; PASSED; PASSED; PASSED; PASSED;

Added: trunk/LayoutTests/svg/hittest/zero-length-butt-cap-path.xhtml (0 => 106882)


--- trunk/LayoutTests/svg/hittest/zero-length-butt-cap-path.xhtml	                        (rev 0)
+++ trunk/LayoutTests/svg/hittest/zero-length-butt-cap-path.xhtml	2012-02-07 01:30:50 UTC (rev 106882)
@@ -0,0 +1,57 @@
+<html xmlns='http://www.w3.org/1999/xhtml'>
+  <head>
+    <style>
+      body {
+          margin: 0px;
+          padding: 0px;
+          border: 1px solid black;
+      }
+    </style>
+  </head>
+  <body>
+    <svg id="background" xmlns="http://www.w3.org/2000/svg" width="100" height="100">
+      <path id="square" d='M50,50 z' stroke='green' stroke-width='100' stroke-linecap='butt'/>
+    </svg>
+    <script><![CDATA[
+      if (window.layoutTestController) {
+        window.layoutTestController.dumpAsText();
+      }
+
+      var resultString = "";
+
+      var hitElementExpected1 = document.elementFromPoint(5, 50);
+      var hitSuccess1 = hitElementExpected1 && hitElementExpected1 == document.getElementById("background");
+      resultString += hitSuccess1 ? "PASSED; " : "FAIL, hit " + hitElementExpected1 + " @ 5, 50; ";
+
+      var hitElementExpected2 = document.elementFromPoint(95, 50);
+      var hitSuccess2 = hitElementExpected2 && hitElementExpected2 == document.getElementById("background");
+      resultString += hitSuccess2 ? "PASSED; " : "FAIL, hit " + hitElementExpected2 + " @ 95, 50; ";
+
+      var hitElementExpected3 = document.elementFromPoint(50, 5);
+      var hitSuccess3 = hitElementExpected3 && hitElementExpected3 == document.getElementById("background");
+      resultString += hitSuccess3 ? "PASSED; " : "FAIL, hit " + hitElementExpected3 + " @ 50, 5; ";
+
+      var hitElementExpected4 = document.elementFromPoint(50, 95);
+      var hitSuccess4 = hitElementExpected4 && hitElementExpected4 == document.getElementById("background");
+      resultString += hitSuccess4 ? "PASSED; " : "FAIL, hit " + hitElementExpected4 + " @ 50, 95; ";
+
+      hitElementExpected1 = document.elementFromPoint(5, 5);
+      hitSuccess1 = hitElementExpected1 && hitElementExpected1 == document.getElementById("background");
+      resultString += hitSuccess1 ? "PASSED; " : "FAIL, hit " + hitElementExpected1 + " @ 5, 5; ";
+
+      hitElementExpected2 = document.elementFromPoint(95, 5);
+      hitSuccess2 = hitElementExpected2 && hitElementExpected2 == document.getElementById("background");
+      resultString += hitSuccess2 ? "PASSED; " : "FAIL, hit " + hitElementExpected2 + " @ 95, 5; ";
+
+      hitElementExpected3 = document.elementFromPoint(5, 95);
+      hitSuccess3 = hitElementExpected3 && hitElementExpected3 == document.getElementById("background");
+      resultString += hitSuccess3 ? "PASSED; " : "FAIL, hit " + hitElementExpected3 + " @ 5, 95; ";
+
+      hitElementExpected4 = document.elementFromPoint(95, 95);
+      hitSuccess4 = hitElementExpected4 && hitElementExpected4 == document.getElementById("background");
+      resultString += hitSuccess4 ? "PASSED; " : "FAIL, hit " + hitElementExpected4 + " @ 95, 95; ";
+
+      document.body.innerHTML = resultString;
+    ]]></script>
+  </body>
+</html>

Added: trunk/LayoutTests/svg/hittest/zero-length-round-cap-path-expected.txt (0 => 106882)


--- trunk/LayoutTests/svg/hittest/zero-length-round-cap-path-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/svg/hittest/zero-length-round-cap-path-expected.txt	2012-02-07 01:30:50 UTC (rev 106882)
@@ -0,0 +1 @@
+PASSED; PASSED; PASSED; PASSED; PASSED; PASSED; PASSED; PASSED;

Added: trunk/LayoutTests/svg/hittest/zero-length-round-cap-path.xhtml (0 => 106882)


--- trunk/LayoutTests/svg/hittest/zero-length-round-cap-path.xhtml	                        (rev 0)
+++ trunk/LayoutTests/svg/hittest/zero-length-round-cap-path.xhtml	2012-02-07 01:30:50 UTC (rev 106882)
@@ -0,0 +1,57 @@
+<html xmlns='http://www.w3.org/1999/xhtml'>
+  <head>
+    <style>
+      body {
+          margin: 0px;
+          padding: 0px;
+          border: 1px solid black;
+      }
+    </style>
+  </head>
+  <body>
+    <svg id="background" xmlns="http://www.w3.org/2000/svg" width="100" height="100">
+      <path id="circle" d='M50,50 z' stroke='green' stroke-width='100' stroke-linecap='round'/>
+    </svg>
+    <script><![CDATA[
+      if (window.layoutTestController) {
+        window.layoutTestController.dumpAsText();
+      }
+
+      var resultString = "";
+
+      var hitElementExpected1 = document.elementFromPoint(5, 50);
+      var hitSuccess1 = hitElementExpected1 && hitElementExpected1 == document.getElementById("circle");
+      resultString += hitSuccess1 ? "PASSED; " : "FAIL, hit " + hitElementExpected1 + " @ 5, 50; ";
+
+      var hitElementExpected2 = document.elementFromPoint(95, 50);
+      var hitSuccess2 = hitElementExpected2 && hitElementExpected2 == document.getElementById("circle");
+      resultString += hitSuccess2 ? "PASSED; " : "FAIL, hit " + hitElementExpected2 + " @ 95, 50; ";
+
+      var hitElementExpected3 = document.elementFromPoint(50, 5);
+      var hitSuccess3 = hitElementExpected3 && hitElementExpected3 == document.getElementById("circle");
+      resultString += hitSuccess3 ? "PASSED; " : "FAIL, hit " + hitElementExpected3 + " @ 50, 5; ";
+
+      var hitElementExpected4 = document.elementFromPoint(50, 95);
+      var hitSuccess4 = hitElementExpected4 && hitElementExpected4 == document.getElementById("circle");
+      resultString += hitSuccess4 ? "PASSED; " : "FAIL, hit " + hitElementExpected4 + " @ 50, 95; ";
+
+      hitElementExpected1 = document.elementFromPoint(5, 5);
+      hitSuccess1 = hitElementExpected1 && hitElementExpected1 == document.getElementById("background");
+      resultString += hitSuccess1 ? "PASSED; " : "FAIL, hit " + hitElementExpected1 + " @ 5, 5; ";
+
+      hitElementExpected2 = document.elementFromPoint(95, 5);
+      hitSuccess2 = hitElementExpected2 && hitElementExpected2 == document.getElementById("background");
+      resultString += hitSuccess2 ? "PASSED; " : "FAIL, hit " + hitElementExpected2 + " @ 95, 5; ";
+
+      hitElementExpected3 = document.elementFromPoint(5, 95);
+      hitSuccess3 = hitElementExpected3 && hitElementExpected3 == document.getElementById("background");
+      resultString += hitSuccess3 ? "PASSED; " : "FAIL, hit " + hitElementExpected3 + " @ 5, 95; ";
+
+      hitElementExpected4 = document.elementFromPoint(95, 95);
+      hitSuccess4 = hitElementExpected4 && hitElementExpected4 == document.getElementById("background");
+      resultString += hitSuccess4 ? "PASSED; " : "FAIL, hit " + hitElementExpected4 + " @ 95, 95; ";
+
+      document.body.innerHTML = resultString;
+    ]]></script>
+  </body>
+</html>

Added: trunk/LayoutTests/svg/hittest/zero-length-square-cap-path-expected.txt (0 => 106882)


--- trunk/LayoutTests/svg/hittest/zero-length-square-cap-path-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/svg/hittest/zero-length-square-cap-path-expected.txt	2012-02-07 01:30:50 UTC (rev 106882)
@@ -0,0 +1 @@
+PASSED; PASSED; PASSED; PASSED; PASSED; PASSED; PASSED; PASSED;

Added: trunk/LayoutTests/svg/hittest/zero-length-square-cap-path.xhtml (0 => 106882)


--- trunk/LayoutTests/svg/hittest/zero-length-square-cap-path.xhtml	                        (rev 0)
+++ trunk/LayoutTests/svg/hittest/zero-length-square-cap-path.xhtml	2012-02-07 01:30:50 UTC (rev 106882)
@@ -0,0 +1,57 @@
+<html xmlns='http://www.w3.org/1999/xhtml'>
+  <head>
+    <style>
+      body {
+          margin: 0px;
+          padding: 0px;
+          border: 1px solid black;
+      }
+    </style>
+  </head>
+  <body>
+    <svg id="background" xmlns="http://www.w3.org/2000/svg" width="100" height="100">
+      <path id="square" d='M50,50 z' stroke='green' stroke-width='100' stroke-linecap='square'/>
+    </svg>
+    <script><![CDATA[
+      if (window.layoutTestController) {
+        window.layoutTestController.dumpAsText();
+      }
+
+      var resultString = "";
+
+      var hitElementExpected1 = document.elementFromPoint(5, 50);
+      var hitSuccess1 = hitElementExpected1 && hitElementExpected1 == document.getElementById("square");
+      resultString += hitSuccess1 ? "PASSED; " : "FAIL, hit " + hitElementExpected1 + " @ 5, 50; ";
+
+      var hitElementExpected2 = document.elementFromPoint(95, 50);
+      var hitSuccess2 = hitElementExpected2 && hitElementExpected2 == document.getElementById("square");
+      resultString += hitSuccess2 ? "PASSED; " : "FAIL, hit " + hitElementExpected2 + " @ 95, 50; ";
+
+      var hitElementExpected3 = document.elementFromPoint(50, 5);
+      var hitSuccess3 = hitElementExpected3 && hitElementExpected3 == document.getElementById("square");
+      resultString += hitSuccess3 ? "PASSED; " : "FAIL, hit " + hitElementExpected3 + " @ 50, 5; ";
+
+      var hitElementExpected4 = document.elementFromPoint(50, 95);
+      var hitSuccess4 = hitElementExpected4 && hitElementExpected4 == document.getElementById("square");
+      resultString += hitSuccess4 ? "PASSED; " : "FAIL, hit " + hitElementExpected4 + " @ 50, 95; ";
+
+      hitElementExpected1 = document.elementFromPoint(5, 5);
+      hitSuccess1 = hitElementExpected1 && hitElementExpected1 == document.getElementById("square");
+      resultString += hitSuccess1 ? "PASSED; " : "FAIL, hit " + hitElementExpected1 + " @ 5, 5; ";
+
+      hitElementExpected2 = document.elementFromPoint(95, 5);
+      hitSuccess2 = hitElementExpected2 && hitElementExpected2 == document.getElementById("square");
+      resultString += hitSuccess2 ? "PASSED; " : "FAIL, hit " + hitElementExpected2 + " @ 95, 5; ";
+
+      hitElementExpected3 = document.elementFromPoint(5, 95);
+      hitSuccess3 = hitElementExpected3 && hitElementExpected3 == document.getElementById("square");
+      resultString += hitSuccess3 ? "PASSED; " : "FAIL, hit " + hitElementExpected3 + " @ 5, 95; ";
+
+      hitElementExpected4 = document.elementFromPoint(95, 95);
+      hitSuccess4 = hitElementExpected4 && hitElementExpected4 == document.getElementById("square");
+      resultString += hitSuccess4 ? "PASSED; " : "FAIL, hit " + hitElementExpected4 + " @ 95, 95; ";
+
+      document.body.innerHTML = resultString;
+    ]]></script>
+  </body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (106881 => 106882)


--- trunk/Source/WebCore/ChangeLog	2012-02-07 01:09:43 UTC (rev 106881)
+++ trunk/Source/WebCore/ChangeLog	2012-02-07 01:30:50 UTC (rev 106882)
@@ -1,3 +1,20 @@
+2012-02-06  Stephen Chenney  <[email protected]>
+
+        RenderSVGShape::strokeContains will fail for some strokes
+        https://bugs.webkit.org/show_bug.cgi?id=76931
+
+        Reviewed by Darin Adler.
+
+        Adding support for rounded zero-length endcaps for SVG path hit
+        testing.
+
+        Tests: svg/hittest/zero-length-butt-cap-path.xhtml
+               svg/hittest/zero-length-round-cap-path.xhtml
+               svg/hittest/zero-length-square-cap-path.xhtml
+
+        * rendering/svg/RenderSVGShape.cpp:
+        (WebCore::RenderSVGShape::strokeContains):
+
 2012-02-06  Gregg Tavares  <[email protected]>
 
         Add webGLErrorsToConsoleEnabled Settings flag

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp (106881 => 106882)


--- trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp	2012-02-07 01:09:43 UTC (rev 106881)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp	2012-02-07 01:30:50 UTC (rev 106882)
@@ -136,13 +136,21 @@
     if (requiresStroke && !RenderSVGResource::strokePaintingResource(this, style(), fallbackColor))
         return false;
 
-    // FIXME: This is not correct for round linecaps. https://bugs.webkit.org/show_bug.cgi?id=76931
+    const SVGRenderStyle* svgStyle = style()->svgStyle();
     for (size_t i = 0; i < m_zeroLengthLinecapLocations.size(); ++i) {
-        if (zeroLengthSubpathRect(m_zeroLengthLinecapLocations[i], this->strokeWidth()).contains(point))
-            return true;
+        ASSERT(style()->svgStyle()->hasStroke());
+        float strokeWidth = this->strokeWidth();
+        if (style()->svgStyle()->capStyle() == SquareCap) {
+            if (zeroLengthSubpathRect(m_zeroLengthLinecapLocations[i], strokeWidth).contains(point))
+                return true;
+        } else {
+            ASSERT(style()->svgStyle()->capStyle() == RoundCap);
+            FloatPoint radiusVector(point.x() - m_zeroLengthLinecapLocations[i].x(), point.y() -  m_zeroLengthLinecapLocations[i].y());
+            if (radiusVector.lengthSquared() < strokeWidth * strokeWidth * .25f)
+                return true;
+        }
     }
 
-    const SVGRenderStyle* svgStyle = style()->svgStyle();
     if (!svgStyle->strokeDashArray().isEmpty() || svgStyle->strokeMiterLimit() != svgStyle->initialStrokeMiterLimit()
         || svgStyle->joinStyle() != svgStyle->initialJoinStyle() || svgStyle->capStyle() != svgStyle->initialCapStyle() || static_cast<SVGElement*>(node())->isStyled()) {
         if (!m_path)
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to