2010-02-12 Nikolas Zimmermann <nzimmermann@rim.com>
authorzimmermann@webkit.org <zimmermann@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 12 Feb 2010 22:18:46 +0000 (22:18 +0000)
committerzimmermann@webkit.org <zimmermann@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 12 Feb 2010 22:18:46 +0000 (22:18 +0000)
        Reviewed by Dirk Schulze.

        Repaint bug on Text selection in foreignObject
        https://bugs.webkit.org/show_bug.cgi?id=16939

        Tests: svg/overflow/overflow-on-foreignObject.svg
               svg/text/foreignObject-text-clipping-bug.xml

        Selecting text contained in <foreignObject> leads to artefacts. Same for zooming/panning.
        RenderForeignObject contained old legacy code returning FloatRect() for repaintRectInLocalCoordinates,
        which is obviously wrong. Fixing that leads to even more problems, as the underlying RenderBlock
        did not reflect the x/y translation set on the <foreignObject>. This is problematic, as laying out
        positioned objects in the XHTML subtree depends on proper size/location values of the frameRect.

        Correctly clip on overflow="hidden". overflow="scroll" & friends are not yet supported, see lengthy
        comment in RenderSVGBlock why we either need RenderLayer for RenderForeignObject or need to rework
        overflow handling to avoid RenderLayer.

        SVGForeignObjectElement uses a hacky custom solution to synchronize CSS width/height properties with
        the SVG width/height attributes. Remove all of that code and just implement calcWidth/calcHeight in
        RenderForeignObject, grabbing the right values from SVGForeignObjectElement::width/height upon layout.

        * rendering/RenderForeignObject.cpp:
        (WebCore::RenderForeignObject::paint): Clip properly to the actual bounds of the foreignObject, respecting that x/y translation is handled by RenderBlock now.
        (WebCore::RenderForeignObject::clippedOverflowRectForRepaint): Added missing function, forward to SVGRenderBase just like all other SVG renderers.
        (WebCore::RenderForeignObject::computeRectForRepaint): Remove manual implementation, forward to SVGRenderBase.
        (WebCore::RenderForeignObject::localToParentTransform): Respect x/y translation here _after_ applying localTransform().
        (WebCore::RenderForeignObject::calcWidth): Override RenderBlock::calcWidth to grab width() from SVGForeignObjectElement.
        (WebCore::RenderForeignObject::calcHeight): Override RenderBlock::calcHeight to grab height() from SVGForeignObjectElement.
        (WebCore::RenderForeignObject::layout): Calculate viewport once and cache it. Push x/y location down to RenderBlock - analogous to RenderSVGText.
        (WebCore::RenderForeignObject::nodeAtFloatPoint): Adapt to x/y translation changes (map through localTransform, not localToParentTransform). Respect overflow clipping.
        (WebCore::RenderForeignObject::mapLocalToContainer): Set useTransforms=true, to avoid assertions when selecting text in foreign objects.
        * rendering/RenderForeignObject.h:
        (WebCore::RenderForeignObject::objectBoundingBox): Return cached m_viewport.
        (WebCore::RenderForeignObject::strokeBoundingBox): Ditto.
        (WebCore::RenderForeignObject::repaintRectInLocalCoordinates): Ditto.
        * rendering/RenderSVGBlock.cpp:
        (WebCore::RenderSVGBlock::setStyle): Cleanup code, move setHasOverflowClip() overrides in updateBoxModelInfoFromStyle where it belongs.
        (WebCore::RenderSVGBlock::updateBoxModelInfoFromStyle): Added to force setting setHasOverflowClip(false).
        * rendering/RenderSVGBlock.h:
        * svg/SVGForeignObjectElement.cpp: Kill a lot of custom code - it was just plain wrong to utilize CSS to push width/height information down to RenderBlock.
        (WebCore::SVGForeignObjectElement::svgAttributeChanged):

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

53 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/mac-leopard/svg/custom/foreign-object-skew-expected.checksum
LayoutTests/platform/mac-leopard/svg/custom/foreign-object-skew-expected.png
LayoutTests/platform/mac/svg/custom/baseval-animval-equality-expected.txt
LayoutTests/platform/mac/svg/custom/dominant-baseline-hanging-expected.txt
LayoutTests/platform/mac/svg/custom/dynamic-svg-document-creation-expected.txt
LayoutTests/platform/mac/svg/custom/fill-SVGPaint-interface-expected.txt
LayoutTests/platform/mac/svg/custom/foreign-object-skew-expected.txt
LayoutTests/platform/mac/svg/custom/foreignObject-crash-on-hover-expected.txt
LayoutTests/platform/mac/svg/custom/getPresentationAttribute-expected.txt
LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-1-expected.checksum
LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-1-expected.png
LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-1-expected.txt
LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-2-expected.checksum
LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-2-expected.png
LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-2-expected.txt
LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-3-expected.checksum
LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-3-expected.png
LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-3-expected.txt
LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-4-expected.checksum
LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-4-expected.png
LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-4-expected.txt
LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-5-expected.checksum
LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-5-expected.png
LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-5-expected.txt
LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-6-expected.checksum
LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-6-expected.png
LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-6-expected.txt
LayoutTests/platform/mac/svg/custom/use-on-g-containing-foreignObject-and-image-expected.txt
LayoutTests/platform/mac/svg/custom/use-on-non-svg-namespaced-element-expected.checksum
LayoutTests/platform/mac/svg/custom/use-on-non-svg-namespaced-element-expected.png
LayoutTests/platform/mac/svg/custom/use-on-non-svg-namespaced-element-expected.txt
LayoutTests/platform/mac/svg/hixie/mixed/008-expected.txt
LayoutTests/platform/mac/svg/overflow/overflow-on-foreignObject-expected.checksum [new file with mode: 0644]
LayoutTests/platform/mac/svg/overflow/overflow-on-foreignObject-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/svg/overflow/overflow-on-foreignObject-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/svg/text/foreignObject-repaint-expected.txt
LayoutTests/platform/mac/svg/text/foreignObject-text-clipping-bug-expected.checksum [new file with mode: 0644]
LayoutTests/platform/mac/svg/text/foreignObject-text-clipping-bug-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/svg/text/foreignObject-text-clipping-bug-expected.txt [new file with mode: 0644]
LayoutTests/svg/custom/baseval-animval-equality.svg
LayoutTests/svg/custom/dominant-baseline-hanging.svg
LayoutTests/svg/custom/dynamic-svg-document-creation.svg
LayoutTests/svg/custom/fill-SVGPaint-interface.svg
LayoutTests/svg/custom/getPresentationAttribute.svg
LayoutTests/svg/overflow/overflow-on-foreignObject.svg [new file with mode: 0644]
LayoutTests/svg/text/foreignObject-text-clipping-bug.xml [new file with mode: 0644]
WebCore/ChangeLog
WebCore/rendering/RenderForeignObject.cpp
WebCore/rendering/RenderForeignObject.h
WebCore/rendering/RenderSVGBlock.cpp
WebCore/rendering/RenderSVGBlock.h
WebCore/svg/SVGForeignObjectElement.cpp

index 419576f..231a6a4 100644 (file)
@@ -1,3 +1,62 @@
+2010-02-12  Nikolas Zimmermann  <nzimmermann@rim.com>
+
+        Reviewed by Dirk Schulze.
+
+        Repaint bug on Text selection in foreignObject
+        https://bugs.webkit.org/show_bug.cgi?id=16939
+
+        Update SVG tests that contain <foreignObject> - now that it's reporting proper repaint rects.
+        Some of our tests use <foreignObject> to draw XHTML text (logging facility) - all these tests
+        were missing width/height attributes on <foreignObject>, fix that otherwhise they won't show
+        up anymore - as expected.
+
+        * platform/mac-leopard/svg/custom/foreign-object-skew-expected.checksum:
+        * platform/mac-leopard/svg/custom/foreign-object-skew-expected.png:
+        * platform/mac/svg/custom/baseval-animval-equality-expected.txt:
+        * platform/mac/svg/custom/dominant-baseline-hanging-expected.txt:
+        * platform/mac/svg/custom/dynamic-svg-document-creation-expected.txt:
+        * platform/mac/svg/custom/fill-SVGPaint-interface-expected.txt:
+        * platform/mac/svg/custom/foreign-object-skew-expected.txt:
+        * platform/mac/svg/custom/foreignObject-crash-on-hover-expected.txt:
+        * platform/mac/svg/custom/getPresentationAttribute-expected.txt:
+        * platform/mac/svg/custom/use-on-disallowed-foreign-object-1-expected.checksum:
+        * platform/mac/svg/custom/use-on-disallowed-foreign-object-1-expected.png:
+        * platform/mac/svg/custom/use-on-disallowed-foreign-object-1-expected.txt:
+        * platform/mac/svg/custom/use-on-disallowed-foreign-object-2-expected.checksum:
+        * platform/mac/svg/custom/use-on-disallowed-foreign-object-2-expected.png:
+        * platform/mac/svg/custom/use-on-disallowed-foreign-object-2-expected.txt:
+        * platform/mac/svg/custom/use-on-disallowed-foreign-object-3-expected.checksum:
+        * platform/mac/svg/custom/use-on-disallowed-foreign-object-3-expected.png:
+        * platform/mac/svg/custom/use-on-disallowed-foreign-object-3-expected.txt:
+        * platform/mac/svg/custom/use-on-disallowed-foreign-object-4-expected.checksum:
+        * platform/mac/svg/custom/use-on-disallowed-foreign-object-4-expected.png:
+        * platform/mac/svg/custom/use-on-disallowed-foreign-object-4-expected.txt:
+        * platform/mac/svg/custom/use-on-disallowed-foreign-object-5-expected.checksum:
+        * platform/mac/svg/custom/use-on-disallowed-foreign-object-5-expected.png:
+        * platform/mac/svg/custom/use-on-disallowed-foreign-object-5-expected.txt:
+        * platform/mac/svg/custom/use-on-disallowed-foreign-object-6-expected.checksum:
+        * platform/mac/svg/custom/use-on-disallowed-foreign-object-6-expected.png:
+        * platform/mac/svg/custom/use-on-disallowed-foreign-object-6-expected.txt:
+        * platform/mac/svg/custom/use-on-g-containing-foreignObject-and-image-expected.txt:
+        * platform/mac/svg/custom/use-on-non-svg-namespaced-element-expected.checksum:
+        * platform/mac/svg/custom/use-on-non-svg-namespaced-element-expected.png:
+        * platform/mac/svg/custom/use-on-non-svg-namespaced-element-expected.txt:
+        * platform/mac/svg/hixie/mixed/008-expected.txt:
+        * platform/mac/svg/overflow/overflow-on-foreignObject-expected.checksum: Added.
+        * platform/mac/svg/overflow/overflow-on-foreignObject-expected.png: Added.
+        * platform/mac/svg/overflow/overflow-on-foreignObject-expected.txt: Added.
+        * platform/mac/svg/text/foreignObject-repaint-expected.txt:
+        * platform/mac/svg/text/foreignObject-text-clipping-bug-expected.checksum: Added.
+        * platform/mac/svg/text/foreignObject-text-clipping-bug-expected.png: Added.
+        * platform/mac/svg/text/foreignObject-text-clipping-bug-expected.txt: Added.
+        * svg/custom/baseval-animval-equality.svg:
+        * svg/custom/dominant-baseline-hanging.svg:
+        * svg/custom/dynamic-svg-document-creation.svg:
+        * svg/custom/fill-SVGPaint-interface.svg:
+        * svg/custom/getPresentationAttribute.svg:
+        * svg/overflow/overflow-on-foreignObject.svg: Added.
+        * svg/text/foreignObject-text-clipping-bug.xml: Added.
+
 2010-02-12  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Simon Fraser.
index b1a7cf9..daa6954 100644 (file)
Binary files a/LayoutTests/platform/mac-leopard/svg/custom/foreign-object-skew-expected.png and b/LayoutTests/platform/mac-leopard/svg/custom/foreign-object-skew-expected.png differ
index eb980eb..a846d2d 100644 (file)
@@ -2,39 +2,39 @@ layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
 layer at (0,0) size 600x400
   RenderSVGRoot {svg} at (0,0) size 600x400
-    RenderForeignObject {foreignObject} at (0,0) size 785x198
-      RenderBlock {html} at (0,0) size 785x198
-        RenderBlock {div} at (0,0) size 785x198
-          RenderBlock (anonymous) at (0,0) size 785x18
+    RenderForeignObject {foreignObject} at (0,0) size 600x400
+      RenderBlock {html} at (0,0) size 600x198
+        RenderBlock {div} at (0,0) size 600x198
+          RenderBlock (anonymous) at (0,0) size 600x18
             RenderText {#text} at (0,0) size 560x18
               text run at (0,0) width 560: "This tests to make sure that baseVal and animVal are tied when animation is not enabled:"
-          RenderBlock {div} at (0,18) size 785x18
+          RenderBlock {div} at (0,18) size 600x18
             RenderText {#text} at (0,0) size 152x18
               text run at (0,0) width 152: "svg.x.baseVal.value = 0"
-          RenderBlock {div} at (0,36) size 785x18
+          RenderBlock {div} at (0,36) size 600x18
             RenderText {#text} at (0,0) size 155x18
               text run at (0,0) width 155: "svg.x.animVal.value = 0"
-          RenderBlock {div} at (0,54) size 785x18
+          RenderBlock {div} at (0,54) size 600x18
             RenderText {#text} at (0,0) size 205x18
               text run at (0,0) width 205: "setting svg.x.baseVal.value = 10"
-          RenderBlock {div} at (0,72) size 785x18
+          RenderBlock {div} at (0,72) size 600x18
             RenderText {#text} at (0,0) size 160x18
               text run at (0,0) width 160: "svg.x.baseVal.value = 10"
-          RenderBlock {div} at (0,90) size 785x18
+          RenderBlock {div} at (0,90) size 600x18
             RenderText {#text} at (0,0) size 163x18
               text run at (0,0) width 163: "svg.x.animVal.value = 10"
-          RenderBlock {div} at (0,108) size 785x18
+          RenderBlock {div} at (0,108) size 600x18
             RenderText {#text} at (0,0) size 122x18
               text run at (0,0) width 122: "SUCCESS (1 of 2)"
-          RenderBlock {div} at (0,126) size 785x18
+          RenderBlock {div} at (0,126) size 600x18
             RenderText {#text} at (0,0) size 200x18
               text run at (0,0) width 200: "setting svg.x.animVal.value = 5"
-          RenderBlock {div} at (0,144) size 785x18
+          RenderBlock {div} at (0,144) size 600x18
             RenderText {#text} at (0,0) size 152x18
               text run at (0,0) width 152: "svg.x.baseVal.value = 5"
-          RenderBlock {div} at (0,162) size 785x18
+          RenderBlock {div} at (0,162) size 600x18
             RenderText {#text} at (0,0) size 155x18
               text run at (0,0) width 155: "svg.x.animVal.value = 5"
-          RenderBlock {div} at (0,180) size 785x18
+          RenderBlock {div} at (0,180) size 600x18
             RenderText {#text} at (0,0) size 122x18
               text run at (0,0) width 122: "SUCCESS (2 of 2)"
index 31660f6..e6ae262 100644 (file)
@@ -24,7 +24,7 @@ layer at (0,0) size 400x400
       RenderSVGText {text} at (2,14) size 323x24 contains 1 chunk(s)
         RenderSVGInlineText {#text} at (0,-18) size 323x24
           chunk 1 text run 1 at (2.00,14.40) startOffset 0 endOffset 40 width 323.00: "This is hanging from the top-left corner"
-    RenderForeignObject {foreignObject} at (0,0) size 380x124
+    RenderForeignObject {foreignObject} at (10,45) size 380x150
       RenderBlock {html} at (0,0) size 380x124
         RenderBody {body} at (8,0) size 364x124
           RenderBlock {p} at (0,0) size 364x90
index 8272b4e..324e95c 100644 (file)
@@ -2,7 +2,7 @@ layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
 layer at (0,0) size 800x600
   RenderSVGRoot {svg} at (0,0) size 800x600
-    RenderForeignObject {foreignObject} at (0,0) size 800x180
+    RenderForeignObject {foreignObject} at (0,0) size 800x600
       RenderBlock {html} at (0,0) size 800x180
         RenderBlock {div} at (0,0) size 800x180
           RenderBlock (anonymous) at (0,0) size 800x18
index b184265..196aa56 100644 (file)
@@ -3,7 +3,7 @@ layer at (0,0) size 800x600
 layer at (0,0) size 800x600
   RenderSVGRoot {svg} at (0,0) size 800x600
     RenderSVGContainer {a} at (0,0) size 0x0
-    RenderForeignObject {foreignObject} at (0,0) size 800x18
+    RenderForeignObject {foreignObject} at (0,0) size 800x600
       RenderBlock {html} at (0,0) size 800x18
         RenderBlock {div} at (0,0) size 800x18
           RenderText {#text} at (0,0) size 554x18
index 6c5b4ea..7e45eaf 100644 (file)
@@ -2,7 +2,7 @@ layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
 layer at (0,0) size 800x600
   RenderSVGRoot {svg} at (0,0) size 800x600
-    RenderForeignObject {foreignObject} at (0,0) size 580x380
+    RenderForeignObject {foreignObject} at (10,10) size 580x380
       RenderBlock {xhtml:div} at (0,0) size 580x18
         RenderText {#text} at (0,0) size 78x18
           text run at (0,0) width 78: "This is a test"
index c21fa9b..4b27f44 100644 (file)
@@ -4,7 +4,7 @@ layer at (0,0) size 800x600
   RenderSVGRoot {svg} at (0,0) size 800x600
     RenderSVGContainer {g} at (49,49) size 302x302 [transform={m=((1.00,0.00)(0.00,1.00)) t=(50.00,50.00)}]
       RenderPath {polygon} at (49,49) size 302x302 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#ADD8E6]}] [data="M0.00,0.00 L300.00,0.00 L300.00,300.00 L0.00,300.00 Z"]
-      RenderForeignObject {foreignObject} at (0,0) size 280x280
+      RenderForeignObject {foreignObject} at (10,10) size 280x280
         RenderInline {html:b} at (0,0) size 108x18
           RenderText {#text} at (0,0) size 108x18
             text run at (0,0) width 108: "Absolute Lineto"
index 3f81ea9..22c45d0 100644 (file)
@@ -3,7 +3,7 @@ layer at (0,0) size 800x600
 layer at (0,0) size 800x600
   RenderSVGRoot {svg} at (0,0) size 800x600
     RenderSVGContainer {a} at (0,0) size 0x0
-    RenderForeignObject {foreignObject} at (0,0) size 800x36
+    RenderForeignObject {foreignObject} at (0,0) size 800x600
       RenderBlock {html} at (0,0) size 800x36
         RenderBlock {div} at (0,0) size 800x36
           RenderText {#text} at (0,0) size 791x36
index 7adf5d5..48f260c 100644 (file)
Binary files a/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-1-expected.png and b/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-1-expected.png differ
index 9a395cd..c723ac8 100644 (file)
@@ -2,7 +2,7 @@ layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
 layer at (0,0) size 800x600
   RenderSVGRoot {svg} at (0,0) size 800x600
-    RenderForeignObject {foreignObject} at (0,0) size 480x360
+    RenderForeignObject {foreignObject} at (10,10) size 480x360
       RenderBlock {xhtml:div} at (0,0) size 480x18
         RenderText {#text} at (0,0) size 244x18
           text run at (0,0) width 244: "You should only see this string ONCE"
index 7adf5d5..48f260c 100644 (file)
Binary files a/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-2-expected.png and b/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-2-expected.png differ
index d0a97bd..9d0ad33 100644 (file)
@@ -2,9 +2,9 @@ layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
 layer at (0,0) size 800x600
   RenderSVGRoot {svg} at (0,0) size 800x600
-    RenderSVGContainer {g} at (0,0) size 0x0
-      RenderSVGContainer {g} at (0,0) size 0x0
-        RenderForeignObject {foreignObject} at (0,0) size 580x380
+    RenderSVGContainer {g} at (108,109) size 692x491
+      RenderSVGContainer {g} at (108,109) size 692x491
+        RenderForeignObject {foreignObject} at (10,10) size 580x380
           RenderBlock {xhtml:div} at (0,0) size 580x18
             RenderText {#text} at (0,0) size 244x18
               text run at (0,0) width 244: "You should only see this string ONCE"
index 7adf5d5..48f260c 100644 (file)
Binary files a/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-3-expected.png and b/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-3-expected.png differ
index 17fd944..b3e6b59 100644 (file)
@@ -2,7 +2,7 @@ layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
 layer at (0,0) size 800x600
   RenderSVGRoot {svg} at (0,0) size 800x600
-    RenderForeignObject {foreignObject} at (0,0) size 580x380
+    RenderForeignObject {foreignObject} at (10,10) size 580x380
       RenderBlock {xhtml:div} at (0,0) size 580x18
         RenderText {#text} at (0,0) size 244x18
           text run at (0,0) width 244: "You should only see this string ONCE"
index 7adf5d5..48f260c 100644 (file)
Binary files a/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-4-expected.png and b/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-4-expected.png differ
index ef166a0..a42ee6b 100644 (file)
@@ -2,9 +2,9 @@ layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
 layer at (0,0) size 800x600
   RenderSVGRoot {svg} at (0,0) size 800x600
-    RenderSVGContainer {g} at (0,0) size 0x0
-      RenderSVGContainer {g} at (0,0) size 0x0
-        RenderForeignObject {foreignObject} at (0,0) size 580x380
+    RenderSVGContainer {g} at (108,109) size 692x491
+      RenderSVGContainer {g} at (108,109) size 692x491
+        RenderForeignObject {foreignObject} at (10,10) size 580x380
           RenderBlock {xhtml:div} at (0,0) size 580x18
             RenderText {#text} at (0,0) size 244x18
               text run at (0,0) width 244: "You should only see this string ONCE"
index 7adf5d5..48f260c 100644 (file)
Binary files a/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-5-expected.png and b/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-5-expected.png differ
index 017b0c8..74fd5c1 100644 (file)
@@ -3,7 +3,7 @@ layer at (0,0) size 800x600
 layer at (0,0) size 800x600
   RenderSVGRoot {svg} at (0,0) size 800x600
     RenderSVGHiddenContainer {defs} at (0,0) size 0x0
-    RenderForeignObject {foreignObject} at (0,0) size 580x380
+    RenderForeignObject {foreignObject} at (10,10) size 580x380
       RenderBlock {xhtml:div} at (0,0) size 580x18
         RenderText {#text} at (0,0) size 244x18
           text run at (0,0) width 244: "You should only see this string ONCE"
index 7adf5d5..48f260c 100644 (file)
Binary files a/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-6-expected.png and b/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-6-expected.png differ
index b38818e..765929c 100644 (file)
@@ -3,12 +3,12 @@ layer at (0,0) size 800x600
 layer at (0,0) size 800x600
   RenderSVGRoot {svg} at (0,0) size 800x600
     RenderSVGHiddenContainer {defs} at (0,0) size 0x0
-      RenderSVGViewportContainer {svg} at (0,0) size 0x0
-        RenderForeignObject {foreignObject} at (0,0) size 580x380
+      RenderSVGViewportContainer {svg} at (86,87) size 714x513
+        RenderForeignObject {foreignObject} at (10,10) size 580x380
           RenderBlock {xhtml:div} at (0,0) size 580x18
             RenderText {#text} at (0,0) size 244x18
               text run at (0,0) width 244: "You should only see this string ONCE"
-    RenderForeignObject {foreignObject} at (0,0) size 580x380
+    RenderForeignObject {foreignObject} at (10,10) size 580x380
       RenderBlock {xhtml:div} at (0,0) size 580x18
         RenderText {#text} at (0,0) size 244x18
           text run at (0,0) width 244: "You should only see this string ONCE"
index e2c566a..95b91c6 100644 (file)
@@ -3,8 +3,8 @@ layer at (0,0) size 800x600
 layer at (0,0) size 800x600
   RenderSVGRoot {svg} at (0,0) size 800x600
     RenderSVGHiddenContainer {defs} at (0,0) size 0x0
-      RenderSVGContainer {g} at (0,0) size 75x75
-        RenderForeignObject {foreignObject} at (0,0) size 580x380
+      RenderSVGContainer {g} at (0,0) size 600x400
+        RenderForeignObject {foreignObject} at (10,10) size 580x380
         RenderSVGImage {image} at (0,0) size 75x75
     RenderSVGContainer {use} at (25,25) size 75x75
       RenderSVGContainer {g} at (25,25) size 75x75 [transform={m=((1.00,0.00)(0.00,1.00)) t=(25.00,25.00)}]
index 7adf5d5..48f260c 100644 (file)
Binary files a/LayoutTests/platform/mac/svg/custom/use-on-non-svg-namespaced-element-expected.png and b/LayoutTests/platform/mac/svg/custom/use-on-non-svg-namespaced-element-expected.png differ
index 9a395cd..c723ac8 100644 (file)
@@ -2,7 +2,7 @@ layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
 layer at (0,0) size 800x600
   RenderSVGRoot {svg} at (0,0) size 800x600
-    RenderForeignObject {foreignObject} at (0,0) size 480x360
+    RenderForeignObject {foreignObject} at (10,10) size 480x360
       RenderBlock {xhtml:div} at (0,0) size 480x18
         RenderText {#text} at (0,0) size 244x18
           text run at (0,0) width 244: "You should only see this string ONCE"
index eae11a7..ab0ae32 100644 (file)
@@ -10,7 +10,7 @@ layer at (0,0) size 800x462
         RenderSVGRoot {svg} at (8,50) size 400x400
           RenderPath {rect} at (8,50) size 400x400 [fill={[type=SOLID] [color=#0000FF]}] [data="M0.00,0.00 L400.00,0.00 L400.00,400.00 L0.00,400.00 Z"]
           RenderPath {circle} at (8,50) size 400x400 [fill={[type=SOLID] [color=#000080]}] [data="M400.00,200.00 L399.61,212.56 L398.42,225.07 L396.46,237.48 L393.72,249.74 L390.21,261.80 L385.96,273.62 L380.97,285.16 L375.26,296.35 L368.87,307.17 L361.80,317.56 L354.10,327.48 L345.79,336.91 L336.91,345.79 L327.48,354.10 L317.56,361.80 L307.17,368.87 L296.35,375.26 L285.16,380.97 L273.62,385.96 L261.80,390.21 L249.74,393.72 L237.48,396.46 L225.07,398.42 L212.56,399.61 L200.00,400.00 L187.44,399.61 L174.93,398.42 L162.52,396.46 L150.26,393.72 L138.20,390.21 L126.38,385.96 L114.84,380.97 L103.65,375.26 L92.83,368.87 L82.44,361.80 L72.52,354.10 L63.09,345.79 L54.21,336.91 L45.90,327.48 L38.20,317.56 L31.13,307.17 L24.74,296.35 L19.03,285.16 L14.04,273.62 L9.79,261.80 L6.28,249.74 L3.54,237.48 L1.58,225.07 L0.39,212.56 L0.00,200.00 L0.39,187.44 L1.58,174.93 L3.54,162.52 L6.28,150.26 L9.79,138.20 L14.04,126.38 L19.03,114.84 L24.74,103.65 L31.13,92.83 L38.20,82.44 L45.90,72.52 L54.21,63.09 L63.09,54.21 L72.52,45.90 L82.44,38.20 L92.83,31.13 L103.65,24.74 L114.84,19.03 L126.38,14.04 L138.20,9.79 L150.26,6.28 L162.52,3.54 L174.93,1.58 L187.44,0.39 L200.00,0.00 L212.56,0.39 L225.07,1.58 L237.48,3.54 L249.74,6.28 L261.80,9.79 L273.62,14.04 L285.16,19.03 L296.35,24.74 L307.17,31.13 L317.56,38.20 L327.48,45.90 L336.91,54.21 L345.79,63.09 L354.10,72.52 L361.80,82.44 L368.87,92.83 L375.26,103.65 L380.97,114.84 L385.96,126.38 L390.21,138.20 L393.72,150.26 L396.46,162.52 L398.42,174.93 L399.61,187.44 Z"]
-          RenderForeignObject {foreignObject} at (0,0) size 400x50 [color=#FFFFFF]
+          RenderForeignObject {foreignObject} at (0,175) size 400x50 [color=#FFFFFF]
             RenderBlock {div} at (0,0) size 400x59
               RenderText {#text} at (139,0) size 121x59
                 text run at (139,0) width 121: "TEST"
diff --git a/LayoutTests/platform/mac/svg/overflow/overflow-on-foreignObject-expected.checksum b/LayoutTests/platform/mac/svg/overflow/overflow-on-foreignObject-expected.checksum
new file mode 100644 (file)
index 0000000..7b9eec8
--- /dev/null
@@ -0,0 +1 @@
+c8b4b909d47e6b5566e10ef877c5bf0c
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/overflow/overflow-on-foreignObject-expected.png b/LayoutTests/platform/mac/svg/overflow/overflow-on-foreignObject-expected.png
new file mode 100644 (file)
index 0000000..f9c52c7
Binary files /dev/null and b/LayoutTests/platform/mac/svg/overflow/overflow-on-foreignObject-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/overflow/overflow-on-foreignObject-expected.txt b/LayoutTests/platform/mac/svg/overflow/overflow-on-foreignObject-expected.txt
new file mode 100644 (file)
index 0000000..29bfeed
--- /dev/null
@@ -0,0 +1,7 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 500x500
+  RenderSVGRoot {svg} at (0,0) size 500x500
+    RenderForeignObject {foreignObject} at (100,100) size 300x300
+layer at (100,100) size 6006x6006 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600 outlineClip at (0,0) size 800x600
+  RenderBlock (positioned) {html:div} at (100,100) size 6006x6006 [bgcolor=#008000] [border: (3px solid #000000)]
index a36eb96..f72d5a4 100644 (file)
@@ -2,7 +2,7 @@ layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
 layer at (0,0) size 800x600
   RenderSVGRoot {svg} at (0,0) size 800x600
-    RenderForeignObject {foreignObject} at (0,0) size 500x300
+    RenderForeignObject {foreignObject} at (100,100) size 500x300
       RenderBlock {div} at (0,0) size 500x183
         RenderText {#text} at (0,0) size 487x183
           text run at (0,0) width 487: "Select this text using"
diff --git a/LayoutTests/platform/mac/svg/text/foreignObject-text-clipping-bug-expected.checksum b/LayoutTests/platform/mac/svg/text/foreignObject-text-clipping-bug-expected.checksum
new file mode 100644 (file)
index 0000000..8f52266
--- /dev/null
@@ -0,0 +1 @@
+8035b23690945290841305709c65fb2a
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/text/foreignObject-text-clipping-bug-expected.png b/LayoutTests/platform/mac/svg/text/foreignObject-text-clipping-bug-expected.png
new file mode 100644 (file)
index 0000000..474e8a3
Binary files /dev/null and b/LayoutTests/platform/mac/svg/text/foreignObject-text-clipping-bug-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/text/foreignObject-text-clipping-bug-expected.txt b/LayoutTests/platform/mac/svg/text/foreignObject-text-clipping-bug-expected.txt
new file mode 100644 (file)
index 0000000..cc84c4b
--- /dev/null
@@ -0,0 +1,23 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x292
+  RenderBlock {html} at (0,0) size 800x292
+    RenderBody {body} at (8,10) size 784x272
+      RenderBlock {p} at (0,0) size 784x18 [color=#000080]
+        RenderText {#text} at (0,0) size 455x18
+          text run at (0,0) width 455: "The word \"TEST \" should appear twice below, the same size each time."
+      RenderBlock (anonymous) at (0,28) size 784x124
+        RenderSVGRoot {svg} at (8,38) size 400x120
+          RenderPath {rect} at (18,48) size 390x110 [transform={m=((10.00,0.00)(0.00,10.00)) t=(0.00,0.00)}] [fill={[type=SOLID] [color=#D3D3D3]}] [data="M1.00,1.00 L61.00,1.00 L61.00,13.00 L1.00,13.00 Z"]
+          RenderForeignObject {foreignObject} at (1,1) size 60x10
+            RenderBlock {div} at (0,0) size 60x13 [color=#000080]
+              RenderText {#text} at (0,0) size 24x13
+                text run at (0,0) width 24: "TEST"
+        RenderText {#text} at (0,0) size 0x0
+layer at (18,182) size 390x115
+  RenderBlock (relative positioned) {div} at (0,162) size 390x110 [color=#000080] [bgcolor=#D3D3D3]
+    RenderBlock {div} at (0,0) size 390x115
+      RenderText {#text} at (0,0) size 239x115
+        text run at (0,0) width 239: "TEST"
+selection start: position 0 of child 0 {#text} of child 1 {p} of child 3 {body} of child 0 {html} of document
+selection end:   position 4 of child 0 {#text} of child 1 {div} of child 5 {div} of child 3 {body} of child 0 {html} of document
index 5a35e1b..193548e 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <svg xmlns="http://www.w3.org/2000/svg" id="svg" width="600" height="400">
-  <foreignObject>
+  <foreignObject width="100%" height="100%">
     <html xmlns="http://www.w3.org/1999/xhtml">
       <div id="log">
         This tests to make sure that baseVal and animVal are tied when animation is not enabled:
index 25fe1a6..233d1e5 100644 (file)
@@ -27,7 +27,7 @@
     <text x="2" font-size="20" dominant-baseline="hanging">This is hanging from the top-left corner</text>
   </g>
 
-  <foreignObject x="10" y="45" width="380">
+  <foreignObject x="10" y="45" width="380" height="150">
     <html xmlns="http://www.w3.org/1999/xhtml">
       <body>
         <p>
@@ -40,4 +40,4 @@
     </html>
   </foreignObject>
 
-</svg>
\ No newline at end of file
+</svg>
index 33cc0f6..54d8faa 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
 <svg onload="init()" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
-<foreignObject>
+<foreignObject width="100%" height="100%">
     <html xmlns="http://www.w3.org/1999/xhtml">
         <div id="log">
             This tests assures dynamic SVGDocument creation via DOMParser interface works.
index 7f50db9..d935e1e 100644 (file)
@@ -23,7 +23,7 @@
 </script>
 This test tests that the type of the fill css attribute is correctly reported as SVGPaint.
 See <a href="http://bugs.webkit.org/show_bug.cgi?id=14064">Bug 14064</a>.
-<foreignObject>
+<foreignObject width="100%" height="100%">
     <html xmlns="http://www.w3.org/1999/xhtml">
         <div id="log">
 This test tests that the type of the fill css attribute is correctly reported as SVGPaint.
index 01e0d43..f86dcc8 100644 (file)
@@ -31,7 +31,7 @@
 </script>
 This test tests that getPresentationAttribute succefully returns SVG presentation attributes, but not ones that are defined in the inline style and not non SVG css properties like border.
 See <a href="http://bugs.webkit.org/show_bug.cgi?id=13976">Bug 13976</a>.
-<foreignObject>
+<foreignObject width="100%" height="100%">
     <html xmlns="http://www.w3.org/1999/xhtml">
         <div id="log">
 This test tests that getPresentationAttribute succesfully returns SVG presentation attributes, but not ones that are defined in the inline style and not non SVG css properties like border.
diff --git a/LayoutTests/svg/overflow/overflow-on-foreignObject.svg b/LayoutTests/svg/overflow/overflow-on-foreignObject.svg
new file mode 100644 (file)
index 0000000..f27b5fc
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+ Verify default overflow rules on foreignObject
+ You should see a 300x300 green rectangle at 100x100 and no scrollbars.
+
+ NOTE: This is currently BROKEN in WebKit. We're clipping the viewport of <foreignObject> correctly,
+       though for each positioned object a RenderLayer is created, that has no knownledge of the
+       size of the <foreignObject> viewport - as <foreignObject> doesn't create a RenderLayer.
+       So for now, you'll see an unclipped content area, just as if overflow was visible.
+-->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:html="http://www.w3.org/1999/xhtml" width="500" height="500">
+    <foreignObject x="100" y="100" width="300" height="300">
+        <html:div style="border: solid; position: absolute; width:6000px; height:6000px;background-color: green;"/>
+    </foreignObject>
+</svg>
diff --git a/LayoutTests/svg/text/foreignObject-text-clipping-bug.xml b/LayoutTests/svg/text/foreignObject-text-clipping-bug.xml
new file mode 100644 (file)
index 0000000..c19db74
--- /dev/null
@@ -0,0 +1,28 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+    <head>
+        <title>foreignObject can be transformed</title>
+        <style type="text/css">
+        p, div { color: navy; margin: 10px 0; }
+        .test { fill: lightgray; font-size: 10px; }
+        .control { position: relative; left: 10px; top: 10px; width: 390px; height: 110px; background: lightgray; font-size: 100px; }
+        .controlText { font-size: 100px; }
+        </style>
+    </head>
+    <body>
+    <p>The word "TEST " should appear twice below, the same size each time.</p>
+    <svg xmlns="http://www.w3.org/2000/svg" width="400" height="120" class="test">
+        <rect x="1" y="1" width="60" height="12" transform="scale(10)"/>
+        <foreignObject x="1" y="1" width="60" height="10" transform="scale(10)">
+            <div xmlns="http://www.w3.org/1999/xhtml"> TEST </div>
+        </foreignObject>
+    </svg>
+    <div class="control">
+    <div class="controlText">TEST</div>
+    </div>
+    <script>
+    if (window.layoutTestController)
+        window.layoutTestController.dumpSelectionRect();
+    document.execCommand("SelectAll");
+    </script>
+    </body>
+</html>
index 5a13318..3c421a2 100644 (file)
@@ -1,3 +1,48 @@
+2010-02-12  Nikolas Zimmermann  <nzimmermann@rim.com>
+
+        Reviewed by Dirk Schulze.
+
+        Repaint bug on Text selection in foreignObject
+        https://bugs.webkit.org/show_bug.cgi?id=16939
+
+        Tests: svg/overflow/overflow-on-foreignObject.svg
+               svg/text/foreignObject-text-clipping-bug.xml
+
+        Selecting text contained in <foreignObject> leads to artefacts. Same for zooming/panning.
+        RenderForeignObject contained old legacy code returning FloatRect() for repaintRectInLocalCoordinates,
+        which is obviously wrong. Fixing that leads to even more problems, as the underlying RenderBlock
+        did not reflect the x/y translation set on the <foreignObject>. This is problematic, as laying out
+        positioned objects in the XHTML subtree depends on proper size/location values of the frameRect.
+
+        Correctly clip on overflow="hidden". overflow="scroll" & friends are not yet supported, see lengthy
+        comment in RenderSVGBlock why we either need RenderLayer for RenderForeignObject or need to rework
+        overflow handling to avoid RenderLayer.
+
+        SVGForeignObjectElement uses a hacky custom solution to synchronize CSS width/height properties with
+        the SVG width/height attributes. Remove all of that code and just implement calcWidth/calcHeight in
+        RenderForeignObject, grabbing the right values from SVGForeignObjectElement::width/height upon layout.
+
+        * rendering/RenderForeignObject.cpp:
+        (WebCore::RenderForeignObject::paint): Clip properly to the actual bounds of the foreignObject, respecting that x/y translation is handled by RenderBlock now.
+        (WebCore::RenderForeignObject::clippedOverflowRectForRepaint): Added missing function, forward to SVGRenderBase just like all other SVG renderers.
+        (WebCore::RenderForeignObject::computeRectForRepaint): Remove manual implementation, forward to SVGRenderBase.
+        (WebCore::RenderForeignObject::localToParentTransform): Respect x/y translation here _after_ applying localTransform().
+        (WebCore::RenderForeignObject::calcWidth): Override RenderBlock::calcWidth to grab width() from SVGForeignObjectElement.
+        (WebCore::RenderForeignObject::calcHeight): Override RenderBlock::calcHeight to grab height() from SVGForeignObjectElement.
+        (WebCore::RenderForeignObject::layout): Calculate viewport once and cache it. Push x/y location down to RenderBlock - analogous to RenderSVGText.
+        (WebCore::RenderForeignObject::nodeAtFloatPoint): Adapt to x/y translation changes (map through localTransform, not localToParentTransform). Respect overflow clipping.
+        (WebCore::RenderForeignObject::mapLocalToContainer): Set useTransforms=true, to avoid assertions when selecting text in foreign objects.
+        * rendering/RenderForeignObject.h:
+        (WebCore::RenderForeignObject::objectBoundingBox): Return cached m_viewport.
+        (WebCore::RenderForeignObject::strokeBoundingBox): Ditto.
+        (WebCore::RenderForeignObject::repaintRectInLocalCoordinates): Ditto.
+        * rendering/RenderSVGBlock.cpp:
+        (WebCore::RenderSVGBlock::setStyle): Cleanup code, move setHasOverflowClip() overrides in updateBoxModelInfoFromStyle where it belongs.
+        (WebCore::RenderSVGBlock::updateBoxModelInfoFromStyle): Added to force setting setHasOverflowClip(false).
+        * rendering/RenderSVGBlock.h:
+        * svg/SVGForeignObjectElement.cpp: Kill a lot of custom code - it was just plain wrong to utilize CSS to push width/height information down to RenderBlock.
+        (WebCore::SVGForeignObjectElement::svgAttributeChanged):
+
 2010-02-12  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Simon Fraser.
index 5bb4439..aa28ff0 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2006 Apple Computer, Inc.
  * Copyright (C) 2009 Google, Inc.
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved. 
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -27,9 +28,9 @@
 #include "GraphicsContext.h"
 #include "RenderView.h"
 #include "SVGForeignObjectElement.h"
-#include "SVGLength.h"
 #include "SVGRenderSupport.h"
-#include "SVGTransformList.h"
+#include "SVGSVGElement.h"
+#include "TransformState.h"
 
 namespace WebCore {
 
@@ -38,22 +39,18 @@ RenderForeignObject::RenderForeignObject(SVGForeignObjectElement* node)
 {
 }
 
-FloatPoint RenderForeignObject::translationForAttributes() const
-{
-    SVGForeignObjectElement* foreign = static_cast<SVGForeignObjectElement*>(node());
-    return FloatPoint(foreign->x().value(foreign), foreign->y().value(foreign));
-}
-
 void RenderForeignObject::paint(PaintInfo& paintInfo, int, int)
 {
     if (paintInfo.context->paintingDisabled())
         return;
 
-    // Copy the paint info so that modifications to the damage rect do not affect callers
-    PaintInfo childPaintInfo = paintInfo;
+    PaintInfo childPaintInfo(paintInfo);
     childPaintInfo.context->save();
-    applyTransformToPaintInfo(childPaintInfo, localToParentTransform());
-    childPaintInfo.context->clip(clipRect(0, 0));
+
+    applyTransformToPaintInfo(childPaintInfo, localTransform());
+
+    if (SVGRenderBase::isOverflowHidden(this))
+        childPaintInfo.context->clip(m_viewport);
 
     float opacity = style()->opacity();
     if (opacity < 1.0f)
@@ -67,32 +64,33 @@ void RenderForeignObject::paint(PaintInfo& paintInfo, int, int)
     childPaintInfo.context->restore();
 }
 
-FloatRect RenderForeignObject::objectBoundingBox() const
+IntRect RenderForeignObject::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
 {
-    return borderBoxRect();
+    return SVGRenderBase::clippedOverflowRectForRepaint(this, repaintContainer);
 }
 
-FloatRect RenderForeignObject::repaintRectInLocalCoordinates() const
+void RenderForeignObject::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& repaintRect, bool fixed)
 {
-    // HACK: to maintain historical LayoutTest results for now.
-    // RenderForeignObject is a RenderBlock (not a RenderSVGModelObject) so this
-    // should not affect repaint correctness.  But it should really be:
-    // return borderBoxRect();
-    return FloatRect();
+    SVGRenderBase::computeRectForRepaint(this, repaintContainer, repaintRect, fixed);
 }
 
-void RenderForeignObject::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed)
+const AffineTransform& RenderForeignObject::localToParentTransform() const
 {
-    rect = localToParentTransform().mapRect(rect);
-    style()->svgStyle()->inflateForShadow(rect);
-    RenderBlock::computeRectForRepaint(repaintContainer, rect, fixed);
+    m_localToParentTransform = localTransform();
+    m_localToParentTransform.translate(m_viewport.x(), m_viewport.y());
+    return m_localToParentTransform;
 }
 
-const AffineTransform& RenderForeignObject::localToParentTransform() const
+void RenderForeignObject::calcWidth()
 {
-    FloatPoint attributeTranslation(translationForAttributes());
-    m_localToParentTransform = localTransform().translateRight(attributeTranslation.x(), attributeTranslation.y());
-    return m_localToParentTransform;
+    // FIXME: Investigate in size rounding issues
+    setWidth(static_cast<int>(roundf(m_viewport.width())));
+}
+
+void RenderForeignObject::calcHeight()
+{
+    // FIXME: Investigate in size rounding issues
+    setHeight(static_cast<int>(roundf(m_viewport.height())));
 }
 
 void RenderForeignObject::layout()
@@ -101,18 +99,36 @@ void RenderForeignObject::layout()
     ASSERT(!view()->layoutStateEnabled()); // RenderSVGRoot disables layoutState for the SVG rendering tree.
 
     LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
-    m_localTransform = static_cast<SVGForeignObjectElement*>(node())->animatedLocalTransform();
 
+    SVGForeignObjectElement* foreign = static_cast<SVGForeignObjectElement*>(node());
+    m_localTransform = foreign->animatedLocalTransform();
+
+    // Cache viewport boundaries
+    FloatPoint viewportLocation(foreign->x().value(foreign), foreign->y().value(foreign));
+    m_viewport = FloatRect(viewportLocation, FloatSize(foreign->width().value(foreign), foreign->height().value(foreign)));
+
+    // Set box origin to the foreignObject x/y translation, so positioned objects in XHTML content get correct
+    // positions. A regular RenderBoxModelObject would pull this information from RenderStyle - in SVG those
+    // properties are ignored for non <svg> elements, so we mimic what happens when specifying them through CSS.
+
+    // FIXME: Investigate in location rounding issues - only affects RenderForeignObject & RenderSVGText
+    setLocation(roundedIntPoint(viewportLocation));
     RenderBlock::layout();
-    repainter.repaintAfterLayout();
 
+    repainter.repaintAfterLayout();
     setNeedsLayout(false);
 }
 
 bool RenderForeignObject::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
 {
-    FloatPoint localPoint = localToParentTransform().inverse().mapPoint(pointInParent);
-    return RenderBlock::nodeAtPoint(request, result, static_cast<int>(localPoint.x()), static_cast<int>(localPoint.y()), 0, 0, hitTestAction);
+    FloatPoint localPoint = localTransform().inverse().mapPoint(pointInParent);
+
+    // Early exit if local point is not contained in clipped viewport area
+    if (SVGRenderBase::isOverflowHidden(this) && !m_viewport.contains(localPoint))
+        return false;
+
+    IntPoint roundedLocalPoint = roundedIntPoint(localPoint);
+    return RenderBlock::nodeAtPoint(request, result, roundedLocalPoint.x(), roundedLocalPoint.y(), 0, 0, hitTestAction);
 }
 
 bool RenderForeignObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, int, int, int, int, HitTestAction)
@@ -121,11 +137,14 @@ bool RenderForeignObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, int
     return false;
 }
 
-void RenderForeignObject::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed , bool useTransforms, TransformState& transformState) const
+void RenderForeignObject::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState) const
 {
+    // When crawling up the hierachy starting from foreignObject child content, useTransforms may not be set to true.
+    if (!useTransforms)
+        useTransforms = true;
     SVGRenderBase::mapLocalToContainer(this, repaintContainer, fixed, useTransforms, transformState);
 }
 
-} // namespace WebCore
+}
 
-#endif // ENABLE(SVG) && ENABLE(SVG_FOREIGN_OBJECT)
+#endif
index f32069c..bb6b555 100644 (file)
@@ -21,8 +21,8 @@
 
 #ifndef RenderForeignObject_h
 #define RenderForeignObject_h
-#if ENABLE(SVG) && ENABLE(SVG_FOREIGN_OBJECT)
 
+#if ENABLE(SVG) && ENABLE(SVG_FOREIGN_OBJECT)
 #include "AffineTransform.h"
 #include "FloatPoint.h"
 #include "RenderSVGBlock.h"
@@ -39,15 +39,15 @@ public:
 
     virtual void paint(PaintInfo&, int parentX, int parentY);
 
-    virtual const AffineTransform& localToParentTransform() const;
-
+    virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
     virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
+
     virtual bool requiresLayer() const { return false; }
     virtual void layout();
 
-    virtual FloatRect objectBoundingBox() const;
-    virtual FloatRect strokeBoundingBox() const { return borderBoxRect(); }
-    virtual FloatRect repaintRectInLocalCoordinates() const;
+    virtual FloatRect objectBoundingBox() const { return m_viewport; }
+    virtual FloatRect strokeBoundingBox() const { return m_viewport; }
+    virtual FloatRect repaintRectInLocalCoordinates() const { return m_viewport; }
 
     virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
@@ -56,15 +56,18 @@ public:
     virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed , bool useTransforms, TransformState& transformState) const;
 
  private:
-    FloatPoint translationForAttributes() const;
+    virtual void calcWidth();
+    virtual void calcHeight();
 
+    virtual const AffineTransform& localToParentTransform() const;
     virtual AffineTransform localTransform() const { return m_localTransform; }
 
+    FloatRect m_viewport;
     AffineTransform m_localTransform;
     mutable AffineTransform m_localToParentTransform;
 };
 
-} // namespace WebCore
+}
 
-#endif // ENABLE(SVG) && ENABLE(SVG_FOREIGN_OBJECT)
-#endif // RenderForeignObject_h
+#endif
+#endif
index f065c44..99725d6 100644 (file)
@@ -1,8 +1,7 @@
 /*
- * This file is part of the WebKit project.
- *
  * Copyright (C) 2006 Apple Computer, Inc.
- *           (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -40,9 +39,7 @@ void RenderSVGBlock::setStyle(PassRefPtr<RenderStyle> style)
     RefPtr<RenderStyle> useStyle = style;
 
     // SVG text layout code expects us to be a block-level style element.   
-    if (useStyle->display() == NONE)
-        setChildrenInline(false);
-    else if (useStyle->isDisplayInlineType()) {
+    if (useStyle->isDisplayInlineType()) {
         RefPtr<RenderStyle> newStyle = RenderStyle::create();
         newStyle->inheritFrom(useStyle.get());
         newStyle->setDisplay(BLOCK);
@@ -50,14 +47,27 @@ void RenderSVGBlock::setStyle(PassRefPtr<RenderStyle> style)
     }
 
     RenderBlock::setStyle(useStyle.release());
-    setReplaced(false);
+}
+
+void RenderSVGBlock::updateBoxModelInfoFromStyle()
+{
+    RenderBlock::updateBoxModelInfoFromStyle();
 
-    //FIXME: Once overflow rules are supported by SVG we should
-    //probably map the CSS overflow rules rather than just ignoring
-    //them
+    // RenderSVGlock, used by Render(SVGText|ForeignObject), is not allowed to call setHasOverflowClip(true).
+    // RenderBlock assumes a layer to be present when the overflow clip functionality is requested. Both
+    // Render(SVGText|ForeignObject) return 'false' on 'requiresLayer'. Fine for RenderSVGText.
+    //
+    // If we want to support overflow rules for <foreignObject> we can choose between two solutions:
+    // a) make RenderForeignObject require layers and SVG layer aware
+    // b) reactor overflow logic out of RenderLayer (as suggested by dhyatt), which is a large task
+    //
+    // Until this is resolved, disable overflow support. Opera/FF don't support it as well at the moment (Feb 2010).
+    //
+    // Note: This does NOT affect overflow handling on outer/inner <svg> elements - this is handled
+    // manually by RenderSVGRoot - which owns the documents enclosing root layer and thus works fine.
     setHasOverflowClip(false);
 }
 
 }
 
-#endif // ENABLE(SVG)
+#endif
index 0b0d107..19cac62 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * This file is part of the WebKit project.
- *
  * Copyright (C) 2006 Apple Computer, Inc.
  *
  * This library is free software; you can redistribute it and/or
@@ -22,8 +20,8 @@
 
 #ifndef RenderSVGBlock_h
 #define RenderSVGBlock_h
-#if ENABLE(SVG)
 
+#if ENABLE(SVG)
 #include "RenderBlock.h"
 #include "SVGRenderSupport.h"
 
@@ -39,8 +37,9 @@ public:
 
 private:
     virtual void setStyle(PassRefPtr<RenderStyle>);
+    virtual void updateBoxModelInfoFromStyle();
 };
 
 }
-#endif // ENABLE(SVG)
-#endif // !RenderSVGBlock_h
+#endif
+#endif
index e9118ef..d28e2a4 100644 (file)
@@ -72,82 +72,21 @@ void SVGForeignObjectElement::parseMappedAttribute(MappedAttribute* attr)
     }
 }
 
-// TODO: Move this function in some SVG*Element base class, as SVGSVGElement / SVGImageElement will need the same logic!
-
-// This function mimics addCSSProperty and StyledElement::attributeChanged.
-// In HTML code, you'd always call addCSSProperty from your derived parseMappedAttribute()
-// function - though in SVG code we need to move this logic into svgAttributeChanged, in
-// order to support SVG DOM changes (which don't use the parseMappedAttribute/attributeChanged).
-// If we'd ignore SVG DOM, we could use _exactly_ the same logic as HTML.
-static inline void addCSSPropertyAndNotifyAttributeMap(StyledElement* element, const QualifiedName& name, int cssProperty, const String& value)
-{
-    ASSERT(element);
-
-    if (!element)
-        return;
-
-    NamedMappedAttrMap* attrs = element->mappedAttributes();
-    ASSERT(attrs);
-
-    if (!attrs)
-        return;
-
-    Attribute* attr = attrs->getAttributeItem(name);
-    if (!attr || !attr->isMappedAttribute())
-        return;
-
-    MappedAttribute* mappedAttr = static_cast<MappedAttribute*>(attr);
-
-    // This logic is only meant to be used for entries that have to be parsed and are mapped to eNone. Assert that.
-    MappedAttributeEntry entry;
-    bool needToParse = element->mapToEntry(mappedAttr->name(), entry);
-
-    ASSERT(needToParse);
-    ASSERT(entry == eNone);
-
-    if (!needToParse || entry != eNone) 
-        return;
-
-    if (mappedAttr->decl()) {
-        mappedAttr->setDecl(0);
-        attrs->declRemoved();
-    }
-
-    element->setNeedsStyleRecalc();
-    element->addCSSProperty(mappedAttr, cssProperty, value);
-
-    if (CSSMappedAttributeDeclaration* decl = mappedAttr->decl()) {
-        // Add the decl to the table in the appropriate spot.
-        element->setMappedAttributeDecl(entry, mappedAttr, decl);
-
-        decl->setMappedState(entry, mappedAttr->name(), mappedAttr->value());
-        decl->setParent(0);
-        decl->setNode(0);
-
-        attrs->declAdded();
-    }
-}
-
 void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName)
 {
     SVGStyledTransformableElement::svgAttributeChanged(attrName);
 
-    if (attrName == SVGNames::widthAttr) {
-        addCSSPropertyAndNotifyAttributeMap(this, attrName, CSSPropertyWidth, width().valueAsString());
-        return;
-    } else if (attrName == SVGNames::heightAttr) {
-        addCSSPropertyAndNotifyAttributeMap(this, attrName, CSSPropertyHeight, height().valueAsString());
-        return;
-    }
-
     if (!renderer())
         return;
 
-    if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr ||
-        SVGTests::isKnownAttribute(attrName) ||
-        SVGLangSpace::isKnownAttribute(attrName) ||
-        SVGExternalResourcesRequired::isKnownAttribute(attrName) ||
-        SVGStyledTransformableElement::isKnownAttribute(attrName))
+    if (attrName == SVGNames::xAttr
+        || attrName == SVGNames::yAttr
+        || attrName == SVGNames::widthAttr
+        || attrName == SVGNames::heightAttr
+        || SVGTests::isKnownAttribute(attrName)
+        || SVGLangSpace::isKnownAttribute(attrName)
+        || SVGExternalResourcesRequired::isKnownAttribute(attrName)
+        || SVGStyledTransformableElement::isKnownAttribute(attrName))
         renderer()->setNeedsLayout(true);
 }
 
@@ -190,6 +129,6 @@ bool SVGForeignObjectElement::childShouldCreateRenderer(Node* child) const
     return StyledElement::childShouldCreateRenderer(child);
 }
 
-} // namespace WebCore
+}
 
-#endif // ENABLE(SVG) && ENABLE(SVG_FOREIGN_OBJECT)
+#endif