Reviewed by Oliver.
authorrwlbuis <rwlbuis@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 Dec 2006 10:36:15 +0000 (10:36 +0000)
committerrwlbuis <rwlbuis@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 Dec 2006 10:36:15 +0000 (10:36 +0000)
        http://bugs.webkit.org/show_bug.cgi?id=11726
        SVG Image do not take into account clip/overflow when hit testing

        Take into account the overflowRect when hit-testing <svg> container.

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

14 files changed:
LayoutTests/ChangeLog
LayoutTests/svg/W3C-SVG-1.1/masking-path-03-b-expected.checksum
LayoutTests/svg/W3C-SVG-1.1/masking-path-03-b-expected.txt
LayoutTests/svg/W3C-SVG-1.1/struct-group-02-b-expected.txt
LayoutTests/svg/W3C-SVG-1.1/struct-image-02-b-expected.txt
LayoutTests/svg/custom/baseval-animval-equality-expected.txt
LayoutTests/svg/custom/image-clipped-hit-expected.checksum [new file with mode: 0644]
LayoutTests/svg/custom/image-clipped-hit-expected.png [new file with mode: 0644]
LayoutTests/svg/custom/image-clipped-hit-expected.txt [new file with mode: 0644]
LayoutTests/svg/custom/image-clipped-hit.svg [new file with mode: 0644]
LayoutTests/svg/custom/svg-overflow-types-expected.txt
WebCore/ChangeLog
WebCore/rendering/RenderSVGContainer.cpp
WebCore/rendering/RenderSVGContainer.h

index 5fda06b2faa34dea4d151c44cd0446277f4a697c..4f49609fa1c3c1d98cff331e99b9766d8c0c9450 100644 (file)
@@ -1,3 +1,25 @@
+2006-12-14  Rob Buis  <buis@kde.org>
+
+        Reviewed by Oliver.
+
+        Testcase for:
+        http://bugs.webkit.org/show_bug.cgi?id=11726
+        SVG Image do not take into account clip/overflow when hit testing
+
+        Also updated testcases with changed (improved!) results due to this
+        patch.
+
+        * svg/W3C-SVG-1.1/masking-path-03-b-expected.checksum:
+        * svg/W3C-SVG-1.1/masking-path-03-b-expected.txt:
+        * svg/W3C-SVG-1.1/struct-group-02-b-expected.txt:
+        * svg/W3C-SVG-1.1/struct-image-02-b-expected.txt:
+        * svg/custom/baseval-animval-equality-expected.txt:
+        * svg/custom/image-clipped-hit-expected.checksum: Added.
+        * svg/custom/image-clipped-hit-expected.png: Added.
+        * svg/custom/image-clipped-hit-expected.txt: Added.
+        * svg/custom/image-clipped-hit.svg: Added.
+        * svg/custom/svg-overflow-types-expected.txt:
+
 2006-12-13  Geoffrey Garen  <ggaren@apple.com>
 
         Updated results to match Justin Garcia's addition of rangeCount to
index 05b1024e8ba244bb11d0690a636b1bba4c6c26e3..6e000ac6a7568d6913b9fc4428aae669beb52c2d 100644 (file)
@@ -1 +1 @@
-8aa4ab10cb39b335f46c9b5bd998dfcc
\ No newline at end of file
+4d86f26d761236e6f64795477fc0b2ed
\ No newline at end of file
index b1348faea80944ca8a5050483e48e232d2c7d32f..d5a5f2c6dc8a6cdd42e3d39aeceeb21c556da571 100644 (file)
@@ -27,25 +27,25 @@ layer at (0,0) size 480x360
               RenderSVGInlineText {#text} at (0,-43) size 217x53
                 text run at (0,-43) width 217: "Outer Clip"
         KCanvasItem {rect} at (112.50,97.50) size 255x165 [stroke={[type=SOLID] [color=#006600] [stroke width=5.00]}] [data="M115.00,100.00L365.00,100.00L365.00,260.00L115.00,260.00"]
-        KCanvasContainer {svg} at (-51,-18) size 352x194
-          KCanvasContainer {g} at (-51,-18) size 352x194
-            KCanvasContainer {g} at (49,-18) size 152x39 [transform={m=((1.00,0.00)(0.00,1.00)) t=(50.00,-15.00)}]
-              KCanvasItem {rect} at (49,-16) size 152x37 [stroke={[type=SOLID] [color=#6666FF] [stroke width=2.00]}] [fill={[type=SOLID] [color=#FFAAAA]}] [data="M0.00,0.00L150.00,0.00L150.00,35.00L0.00,35.00"]
+        KCanvasContainer {svg} at (64,82) size 352x194
+          KCanvasContainer {g} at (64,82) size 352x194
+            KCanvasContainer {g} at (164,82) size 152x39 [transform={m=((1.00,0.00)(0.00,1.00)) t=(50.00,-15.00)}]
+              KCanvasItem {rect} at (164,84) size 152x37 [stroke={[type=SOLID] [color=#6666FF] [stroke width=2.00]}] [fill={[type=SOLID] [color=#FFAAAA]}] [data="M0.00,0.00L150.00,0.00L150.00,35.00L0.00,35.00"]
               RenderSVGText {text} at (6,26) size 480x36
                 RenderSVGInlineText {#text} at (0,-29) size 138x36
                   text run at (0,-29) width 138: "Inner Clip"
-            KCanvasContainer {g} at (-51,59.50) size 152x39 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-50.00,62.50)}]
-              KCanvasItem {rect} at (-51,61.50) size 152x37 [stroke={[type=SOLID] [color=#6666FF] [stroke width=2.00]}] [fill={[type=SOLID] [color=#FFAAAA]}] [data="M0.00,0.00L150.00,0.00L150.00,35.00L0.00,35.00"]
+            KCanvasContainer {g} at (64,159.50) size 152x39 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-50.00,62.50)}]
+              KCanvasItem {rect} at (64,161.50) size 152x37 [stroke={[type=SOLID] [color=#6666FF] [stroke width=2.00]}] [fill={[type=SOLID] [color=#FFAAAA]}] [data="M0.00,0.00L150.00,0.00L150.00,35.00L0.00,35.00"]
               RenderSVGText {text} at (6,26) size 480x36
                 RenderSVGInlineText {#text} at (0,-29) size 138x36
                   text run at (0,-29) width 138: "Inner Clip"
-            KCanvasContainer {g} at (149,59.50) size 152x39 [transform={m=((1.00,0.00)(0.00,1.00)) t=(150.00,62.50)}]
-              KCanvasItem {rect} at (149,61.50) size 152x37 [stroke={[type=SOLID] [color=#6666FF] [stroke width=2.00]}] [fill={[type=SOLID] [color=#FFAAAA]}] [data="M0.00,0.00L150.00,0.00L150.00,35.00L0.00,35.00"]
+            KCanvasContainer {g} at (264,159.50) size 152x39 [transform={m=((1.00,0.00)(0.00,1.00)) t=(150.00,62.50)}]
+              KCanvasItem {rect} at (264,161.50) size 152x37 [stroke={[type=SOLID] [color=#6666FF] [stroke width=2.00]}] [fill={[type=SOLID] [color=#FFAAAA]}] [data="M0.00,0.00L150.00,0.00L150.00,35.00L0.00,35.00"]
               RenderSVGText {text} at (6,26) size 480x36
                 RenderSVGInlineText {#text} at (0,-29) size 138x36
                   text run at (0,-29) width 138: "Inner Clip"
-            KCanvasContainer {g} at (49,137) size 152x39 [transform={m=((1.00,0.00)(0.00,1.00)) t=(50.00,140.00)}]
-              KCanvasItem {rect} at (49,139) size 152x37 [stroke={[type=SOLID] [color=#6666FF] [stroke width=2.00]}] [fill={[type=SOLID] [color=#FFAAAA]}] [data="M0.00,0.00L150.00,0.00L150.00,35.00L0.00,35.00"]
+            KCanvasContainer {g} at (164,237) size 152x39 [transform={m=((1.00,0.00)(0.00,1.00)) t=(50.00,140.00)}]
+              KCanvasItem {rect} at (164,239) size 152x37 [stroke={[type=SOLID] [color=#6666FF] [stroke width=2.00]}] [fill={[type=SOLID] [color=#FFAAAA]}] [data="M0.00,0.00L150.00,0.00L150.00,35.00L0.00,35.00"]
               RenderSVGText {text} at (6,26) size 480x36
                 RenderSVGInlineText {#text} at (0,-29) size 138x36
                   text run at (0,-29) width 138: "Inner Clip"
index 417cfad522bdd83a0b794d683680d0ed7ca6be15..d13a82045bddecfdc0b1df86a89c1c88bf595d28 100644 (file)
@@ -2,12 +2,12 @@ layer at (0,0) size 480x360
   RenderView at (0,0) size 480x360
     KCanvasContainer {svg} at (0,0) size 479.50x359.50
       KCanvasContainer {g} at (0,0) size 240x180
-        KCanvasContainer {svg} at (0,0) size 240x180
-          KCanvasItem {rect} at (0,0) size 240x180 [fill={[type=SOLID] [color=#FF0000]}] [data="M0.00,0.00L240.00,0.00L240.00,180.00L0.00,180.00"]
+        KCanvasContainer {svg} at (240,180) size 240x180
+          KCanvasItem {rect} at (240,180) size 240x180 [fill={[type=SOLID] [color=#FF0000]}] [data="M0.00,0.00L240.00,0.00L240.00,180.00L0.00,180.00"]
         KCanvasContainer {svg} at (0,0) size 240x180
           KCanvasItem {rect} at (0,0) size 240x180 [fill={[type=SOLID] [color=#0000FF]}] [data="M0.00,0.00L240.00,0.00L240.00,180.00L0.00,180.00"]
-          KCanvasContainer {svg} at (0,0) size 120x90
-            KCanvasItem {rect} at (0,0) size 120x90 [fill={[type=SOLID] [color=#FFFF00]}] [data="M0.00,0.00L120.00,0.00L120.00,90.00L0.00,90.00"]
+          KCanvasContainer {svg} at (60,45) size 120x90
+            KCanvasItem {rect} at (60,45) size 120x90 [fill={[type=SOLID] [color=#FFFF00]}] [data="M0.00,0.00L120.00,0.00L120.00,90.00L0.00,90.00"]
       RenderSVGText {text} at (10,340) size 480x46
         RenderSVGInlineText {#text} at (0,-36) size 264x46
           text run at (0,-36) width 264: "$Revision: 1.1 $"
index 3ba44e3a8b6c750acd002f14918b1b45892c95bb..9b038c30f6a5a63d502abd34001aa095413c0002 100644 (file)
@@ -4,8 +4,8 @@ layer at (0,0) size 480x360
       KCanvasContainer {g} at (0,0) size 480x300
         KCanvasContainer {defs} at (0,0) size 240x225
           RenderImage {image} at (0,0) size 240x150
-          KCanvasContainer {svg} at (0,0) size 240x225
-            KCanvasItem {rect} at (0,0) size 240x225 [fill={[type=SOLID] [color=#FF0000]}] [data="M0.00,0.00L240.00,0.00L240.00,225.00L0.00,225.00"]
+          KCanvasContainer {svg} at (240,0) size 240x225
+            KCanvasItem {rect} at (240,0) size 240x225 [fill={[type=SOLID] [color=#FF0000]}] [data="M0.00,0.00L240.00,0.00L240.00,225.00L0.00,225.00"]
         KCanvasContainer {g} at (0,0) size 240x150
           KCanvasContainer {use} at (0,0) size 240x150
             KCanvasContainer {g} at (0,0) size 240x150
@@ -13,11 +13,11 @@ layer at (0,0) size 480x360
         KCanvasContainer {g} at (0,0) size 240x225
           KCanvasContainer {use} at (0,0) size 240x225
             KCanvasContainer {g} at (0,0) size 240x225
-              KCanvasContainer {svg} at (0,0) size 240x225
-                KCanvasItem {rect} at (0,0) size 240x225 [fill={[type=SOLID] [color=#FF0000]}] [data="M0.00,0.00L240.00,0.00L240.00,225.00L0.00,225.00"]
-        KCanvasContainer {svg} at (0,0) size 240x150
-          KCanvasContainer {g} at (0,0) size 240x150
-            KCanvasItem {rect} at (0,0) size 240x150 [fill={[type=SOLID] [color=#00FFFF]}] [data="M0.00,0.00L240.00,0.00L240.00,150.00L0.00,150.00"]
+              KCanvasContainer {svg} at (240,0) size 240x225
+                KCanvasItem {rect} at (240,0) size 240x225 [fill={[type=SOLID] [color=#FF0000]}] [data="M0.00,0.00L240.00,0.00L240.00,225.00L0.00,225.00"]
+        KCanvasContainer {svg} at (0,150) size 240x150
+          KCanvasContainer {g} at (0,150) size 240x150
+            KCanvasItem {rect} at (0,150) size 240x150 [fill={[type=SOLID] [color=#00FFFF]}] [data="M0.00,0.00L240.00,0.00L240.00,150.00L0.00,150.00"]
         KCanvasContainer {g} at (240,150) size 240x150
           KCanvasContainer {switch} at (240,150) size 240x150
             KCanvasItem {rect} at (240,150) size 240x150 [fill={[type=SOLID] [color=#008000]}] [data="M240.00,150.00L480.00,150.00L480.00,300.00L240.00,300.00"]
index 9da84f3589190385fd871f8c4104a50aafaa7a20..5f70a3d59ba243f8c39a9b5d85e218c93ae8902f 100644 (file)
@@ -1,6 +1,6 @@
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
-    KCanvasContainer {svg} at (0,0) size 0x0
+    KCanvasContainer {svg} at (5,0) size 0x0
       RenderForeignObject {foreignObject} at (0,0) size 800x198
         RenderBlock {html} at (0,0) size 800x198
           RenderBlock {div} at (0,0) size 800x198
diff --git a/LayoutTests/svg/custom/image-clipped-hit-expected.checksum b/LayoutTests/svg/custom/image-clipped-hit-expected.checksum
new file mode 100644 (file)
index 0000000..dd71405
--- /dev/null
@@ -0,0 +1 @@
+a302523f4c2819f84d934b0226973425
\ No newline at end of file
diff --git a/LayoutTests/svg/custom/image-clipped-hit-expected.png b/LayoutTests/svg/custom/image-clipped-hit-expected.png
new file mode 100644 (file)
index 0000000..314247c
Binary files /dev/null and b/LayoutTests/svg/custom/image-clipped-hit-expected.png differ
diff --git a/LayoutTests/svg/custom/image-clipped-hit-expected.txt b/LayoutTests/svg/custom/image-clipped-hit-expected.txt
new file mode 100644 (file)
index 0000000..ac13b6c
--- /dev/null
@@ -0,0 +1,9 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+    KCanvasContainer {svg} at (-75,0) size 282.85x249.90
+      KCanvasContainer {g} at (-75,0) size 282.85x249.90 [transform={m=((0.87,0.50)(-0.50,0.87)) t=(0.00,0.00)}]
+        KCanvasContainer {svg} at (141.51,125) size 282.85x249.90
+          RenderImage {image} at (0,0) size 240x150
+      RenderSVGText {text} at (90,130) size 800x18
+        RenderSVGInlineText {#text} at (0,-14) size 43x18
+          text run at (0,-14) width 43: "Passed"
diff --git a/LayoutTests/svg/custom/image-clipped-hit.svg b/LayoutTests/svg/custom/image-clipped-hit.svg
new file mode 100644 (file)
index 0000000..c159487
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">
+<svg version="1.1" baseProfile="basic" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="svg-root" width="100%" height="100%" onload="runTest()">
+   <script type="text/ecmascript"><![CDATA[
+      var states = [];
+      var clicked;
+      function testClickAt(x, y) {
+         eventSender.mouseMoveTo(x, y);
+         eventSender.mouseDown();
+         eventSender.mouseUp();
+         states.push(clicked);
+         clicked = false;
+      }
+      function checkResults() {
+         var testAgainst = [true, false];
+         for (var i = 0; i < testAgainst.length; i++) {
+            if (testAgainst[i] != states[i]) {
+               alert("was: " + states);
+               alert("shouldBe: " + testAgainst);
+               return false;
+            }
+         }
+         return true;
+      }
+      
+      function runTest() {
+         if (window.eventSender) {
+            testClickAt(219, 196); 
+            testClickAt(236, 300); 
+            document.getElementById("status").textContent = "Failed";
+            if (checkResults())
+                document.getElementById("status").textContent = "Passed";
+         } else {
+            // in manual mode
+            alert("Please use run-webkit-tests.");
+        }
+     }
+   ]]></script>
+   <g style="visibility:hidden" transform="rotate(30)">
+       <svg x="250" width="100" height="150" style="overflow:hidden">"
+               <image onmousedown="clicked=true;" id="image1PNG" x="0" y="0" width="240" height="150" xlink:href="resources/struct-image-01.png"/>
+       </svg>
+   </g>
+   <text id="status" x="90" y="130" onmousedown="clicked=true;">Unknown</text>
+</svg>
+
index 285eaca1bddb90c3303bb0369b96260b089563d4..09daaebd4c7f375cc7a25e13946b5993728a0c65 100644 (file)
@@ -9,21 +9,21 @@ layer at (0,0) size 800x600
         RenderSVGInlineText {#text} at (0,-14) size 108x18
           text run at (0,-14) width 108: "overflow: hidden"
       KCanvasItem {rect} at (200,0) size 200x200 [fill={[type=SOLID] [color=#008000]}] [data="M200.00,0.00L400.00,0.00L400.00,200.00L200.00,200.00"]
-      KCanvasContainer {svg} at (0,0) size 200x200
-        KCanvasItem {rect} at (0,0) size 200x200 [fill={[type=SOLID] [color=#FF0000]}] [data="M0.00,0.00L200.00,0.00L200.00,200.00L0.00,200.00"]
-        KCanvasItem {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [data="M0.00,0.00L100.00,0.00L100.00,100.00L0.00,100.00"]
+      KCanvasContainer {svg} at (200,0) size 200x200
+        KCanvasItem {rect} at (200,0) size 200x200 [fill={[type=SOLID] [color=#FF0000]}] [data="M0.00,0.00L200.00,0.00L200.00,200.00L0.00,200.00"]
+        KCanvasItem {rect} at (200,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [data="M0.00,0.00L100.00,0.00L100.00,100.00L0.00,100.00"]
       RenderSVGText {text} at (250,100) size 800x18
         RenderSVGInlineText {#text} at (0,-14) size 99x18
           text run at (0,-14) width 99: "overflow: scroll"
       KCanvasItem {rect} at (0,200) size 200x200 [fill={[type=SOLID] [color=#FF0000]}] [data="M0.00,200.00L200.00,200.00L200.00,400.00L0.00,400.00"]
-      KCanvasContainer {svg} at (0,0) size 200x200
-        KCanvasItem {rect} at (0,0) size 200x200 [fill={[type=SOLID] [color=#008000]}] [data="M0.00,0.00L200.00,0.00L200.00,200.00L0.00,200.00"]
+      KCanvasContainer {svg} at (0,200) size 200x200
+        KCanvasItem {rect} at (0,200) size 200x200 [fill={[type=SOLID] [color=#008000]}] [data="M0.00,0.00L200.00,0.00L200.00,200.00L0.00,200.00"]
       RenderSVGText {text} at (50,300) size 800x18
         RenderSVGInlineText {#text} at (0,-14) size 92x18
           text run at (0,-14) width 92: "overflow: auto"
       KCanvasItem {rect} at (200,200) size 200x200 [fill={[type=SOLID] [color=#FF0000]}] [data="M200.00,200.00L400.00,200.00L400.00,400.00L200.00,400.00"]
-      KCanvasContainer {svg} at (0,0) size 200x200
-        KCanvasItem {rect} at (0,0) size 200x200 [fill={[type=SOLID] [color=#008000]}] [data="M0.00,0.00L200.00,0.00L200.00,200.00L0.00,200.00"]
+      KCanvasContainer {svg} at (200,200) size 200x200
+        KCanvasItem {rect} at (200,200) size 200x200 [fill={[type=SOLID] [color=#008000]}] [data="M0.00,0.00L200.00,0.00L200.00,200.00L0.00,200.00"]
       RenderSVGText {text} at (250,300) size 800x18
         RenderSVGInlineText {#text} at (0,-14) size 106x18
           text run at (0,-14) width 106: "overflow: visible"
index 6d76f3fec318696df00c931d91cd93e6269181bd..a8b731b8c05b3e6266a7ed8e27d3757ccfdcc23f 100644 (file)
@@ -1,3 +1,17 @@
+2006-12-14  Rob Buis  <buis@kde.org>
+
+        Reviewed by Oliver.
+
+        http://bugs.webkit.org/show_bug.cgi?id=11726
+        SVG Image do not take into account clip/overflow when hit testing
+
+        Take into account the overflowRect when hit-testing <svg> container.
+
+        * rendering/RenderSVGContainer.cpp:
+        (WebCore::RenderSVGContainer::viewportTransform):
+        (WebCore::RenderSVGContainer::nodeAtPoint):
+        * rendering/RenderSVGContainer.h:
+
 2006-12-13  David Hyatt  <hyatt@apple.com>
 
         Fix for bug 11825, dragging elements via -khtml-user-drag is broken (affects Dashboard).  Make sure
index 77d6577dccad97171a763f0cc89fb5abeeb787af..48b68f67274378529140df2e878e1772d8bbd067 100644 (file)
@@ -247,7 +247,7 @@ AffineTransform RenderSVGContainer::viewportTransform() const
             viewportRect = FloatRect(viewport().x(), viewport().y(), width(), height());
         return getAspectRatio(viewBox(), viewportRect);
     }
-    return AffineTransform();
+    return AffineTransform().translate(viewport().x(), viewport().y());
 }
 
 IntRect RenderSVGContainer::getAbsoluteRepaintRect()
@@ -370,6 +370,26 @@ AffineTransform RenderSVGContainer::getAspectRatio(const FloatRect& logical, con
     return temp;
 }
 
+bool RenderSVGContainer::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction)
+{
+    SVGElement* svgelem = static_cast<SVGElement*>(element());
+    if (svgelem->hasTagName(SVGNames::svgTag)) {
+        int tx = _tx + m_x;
+        int ty = _ty + m_y;
+
+        // Check if we need to do anything at all.
+        IntRect overflowBox = overflowRect(false);
+        overflowBox.move(tx, ty);
+        AffineTransform totalTransform = absoluteTransform();
+        double localX, localY;
+        totalTransform.inverse().map(_x + _tx, _y + _ty, &localX, &localY);
+        if (!overflowBox.contains((int)localX, (int)localY))
+            return false;
+    }
+
+    return RenderContainer::nodeAtPoint(request, result, _x, _y, _tx, _ty, hitTestAction);
+}
+
 }
 
 // vim:ts=4:noet
index d979adc45f31a963defad0459f3c02799e52dc1f..1bda89d168145d5d4cfee1d1eedef51ca4830575 100644 (file)
@@ -94,6 +94,8 @@ public:
     
     AffineTransform viewportTransform() const;
     
+    virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
+
 private:
     void calcViewport(); 
     AffineTransform getAspectRatio(const FloatRect& logical, const FloatRect& physical) const;