2010-07-16 Nikolas Zimmermann <nzimmermann@rim.com>
authorzimmermann@webkit.org <zimmermann@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Jul 2010 08:26:24 +0000 (08:26 +0000)
committerzimmermann@webkit.org <zimmermann@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Jul 2010 08:26:24 +0000 (08:26 +0000)
        Reviewed by Dirk Schulze.

        relative positioning does not work for radialGradient after window resize
        https://bugs.webkit.org/show_bug.cgi?id=41249

        Redesign the way resources are invalidated. No longer utilize the DOM tree, specifically SVGStyledElement::svgAttributeChanged(), to invalidate
        all resources in the ancestor chain (including itself) when any attribute changes. rect.setAttribute("foo", "bar") should never invalidate the
        resources. Also the old approach didn't work correctly if the root layout changed (eg. window size change) - we failed to invalidate the resources,
        thus leading to wrong renderings.

        Instead of calling setNeedsLayout(true) from the SVG*Element classes, call RenderSVGResource::markForLayoutAndParentResourceInvalidation(), which
        does the same thing and invalidates all resources in the ancestor chain (removing the cached results from the HashMaps). This only happens from
        the various svgAttributeChanged() methods, if we know which attribute changed, and what action has to be taken.

        All SVG renderers now invalidate their own resources on layout() if the layout changed (selfNeedsLayout()=true). The resources will be recreated
        and cached during the following paint() call.

        Tests: svg/custom/marker-child-changes-css.svg
               svg/custom/relative-sized-content-with-resources.xhtml

        * rendering/RenderForeignObject.cpp:
        (WebCore::RenderForeignObject::layout): If our layout changed, invalidate our resources, by calling RenderSVGResource::invalidateAllResourcesOfRenderer().
        * rendering/RenderPath.cpp:
        (WebCore::RenderPath::layout): Ditto.
        * rendering/RenderSVGContainer.cpp:
        (WebCore::RenderSVGContainer::layout): Ditto.
        * rendering/RenderSVGImage.cpp:
        (WebCore::RenderSVGImage::layout): Ditto.
        * rendering/RenderSVGModelObject.cpp:
        (WebCore::RenderSVGModelObject::styleDidChange): Added, to invalidate resources on CSS changes, covered by new svg/custom/marker-child-changes-css.svg test.
        * rendering/RenderSVGModelObject.h:
        * rendering/RenderSVGResource.cpp:
        (WebCore::RenderSVGResource::markForLayoutAndResourceInvalidation): Add new "needsBoundaries" parameter, calling setNeedsBoundaries() on the target render object,
                                                                            simplifying all RenderSVGResource* code.
        (WebCore::RenderSVGResource::markForLayoutAndParentResourceInvalidation): New static method used from DOM tree to invalidate all cached resources in the ancestor chain
                                                                                  for a render object. Also marks the renderer for layout, if needed.
        * rendering/RenderSVGResource.h:
        * rendering/RenderSVGResourceClipper.cpp: Simplify code, remove no longer needed hacks, as invalidation is now carried out by render tree.
        (WebCore::RenderSVGResourceClipper::RenderSVGResourceClipper): Add m_invalidationBlocked hack, to avoid invalidations, while we're mutating the render styles (which is a hack!).
        (WebCore::RenderSVGResourceClipper::invalidateClients): Don't do anything if m_invalidationBlocked=true.
        (WebCore::RenderSVGResourceClipper::invalidateClient): Ditto.
        (WebCore::RenderSVGResourceClipper::createClipData): Set m_invalidationBlocked before mutating render styles, as they are restored immediately after creating the clip image.
        (WebCore::RenderSVGResourceClipper::resourceBoundingBox): Remove no longer needed hack to initialize ClipperData earlier than applyResource() would do.
        * rendering/RenderSVGResourceClipper.h:
        * rendering/RenderSVGResourceFilter.cpp:
        (WebCore::RenderSVGResourceFilter::invalidateClients): Simplify code using markForLayoutAndResourceInvalidation.
        (WebCore::RenderSVGResourceFilter::invalidateClient): Remove wrong assertion.
        * rendering/RenderSVGResourceGradient.cpp:
        (WebCore::RenderSVGResourceGradient::invalidateClients): Simplify code using markForLayoutAndResourceInvalidation.
        (WebCore::RenderSVGResourceGradient::invalidateClient): Remove wrong assertion.
        * rendering/RenderSVGResourceMarker.cpp:
        (WebCore::RenderSVGResourceMarker::invalidateClients): Simplify code using markForLayoutAndResourceInvalidation.
        (WebCore::RenderSVGResourceMarker::invalidateClient): Remove wrong assertion.
        * rendering/RenderSVGResourceMasker.cpp:
        (WebCore::RenderSVGResourceMasker::invalidateClients): Simplify code using markForLayoutAndResourceInvalidation.
        (WebCore::RenderSVGResourceMasker::invalidateClient): Remove wrong assertion.
        (WebCore::RenderSVGResourceMasker::resourceBoundingBox): Remove no longer needed hack to initializer MaskerData earlier than applyResource() would do.
        * rendering/RenderSVGResourcePattern.cpp:
        (WebCore::RenderSVGResourcePattern::invalidateClients): Simplify code using markForLayoutAndResourceInvalidation.
        (WebCore::RenderSVGResourcePattern::invalidateClient): Remove wrong assertion.
        * rendering/RenderSVGText.cpp:
        (WebCore::RenderSVGText::layout): If our layout changed, invalidate our resources, by calling RenderSVGResource::invalidateAllResourcesOfRenderer().
        * svg/SVGAnimateMotionElement.cpp:
        (WebCore::SVGAnimateMotionElement::applyResultsToTarget): Call RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer) instead of renderer->setNeedsLayout(true).
        * svg/SVGAnimateTransformElement.cpp:
        (WebCore::SVGAnimateTransformElement::applyResultsToTarget): Ditto.
        * svg/SVGCircleElement.cpp:
        (WebCore::SVGCircleElement::svgAttributeChanged): Ditto.
        * svg/SVGEllipseElement.cpp:
        (WebCore::SVGEllipseElement::svgAttributeChanged): Ditto.
        * svg/SVGFEImageElement.cpp:
        (WebCore::SVGFEImageElement::notifyFinished): Ditto.
        * svg/SVGForeignObjectElement.cpp:
        (WebCore::SVGForeignObjectElement::svgAttributeChanged): Ditto.
        * svg/SVGGElement.cpp:
        (WebCore::SVGGElement::svgAttributeChanged): Ditto.
        * svg/SVGImageElement.cpp:
        (WebCore::SVGImageElement::svgAttributeChanged): Ditto.
        * svg/SVGLineElement.cpp:
        (WebCore::SVGLineElement::svgAttributeChanged): Ditto.
        * svg/SVGPathElement.cpp:
        (WebCore::SVGPathElement::svgAttributeChanged): Ditto.
        * svg/SVGPolyElement.cpp:
        (WebCore::SVGPolyElement::svgAttributeChanged): Ditto.
        * svg/SVGRectElement.cpp:
        (WebCore::SVGRectElement::svgAttributeChanged): Ditto.
        * svg/SVGSVGElement.cpp:
        (WebCore::SVGSVGElement::setCurrentScale): Ditto.
        (WebCore::SVGSVGElement::svgAttributeChanged): Ditto.
        (WebCore::SVGSVGElement::inheritViewAttributes): Ditto.
        * svg/SVGStopElement.cpp:
        (WebCore::SVGStopElement::SVGStopElement): Changed m_offset initialization from 0.0f to 0.
        (WebCore::SVGStopElement::svgAttributeChanged): Add missing implementation, calling RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer) on offsetAttr changes.
        * svg/SVGStopElement.h:
        * svg/SVGStyledElement.cpp:
        (WebCore::SVGStyledElement::svgAttributeChanged): Don't call invalidateResourceInAncestorChain() on every attribute change, do it in all classes inheriting from us,
                                                          for specific attributes. Also stop calling RenderSVGResource::invalidateAllResourcesOfRenderer(), all handled in the render tree now.
        (WebCore::SVGStyledElement::invalidateResourceClients): Early exit, if document is still parsing.
        * svg/SVGStyledElement.h:
        * svg/SVGTRefElement.cpp:
        (WebCore::SVGTRefElement::svgAttributeChanged): Call RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer) instead of renderer->setNeedsLayout(true).
        * svg/SVGTextElement.cpp:
        (WebCore::SVGTextElement::svgAttributeChanged): Ditto.
        * svg/SVGTextPathElement.cpp:
        (WebCore::SVGTextPathElement::svgAttributeChanged): Ditto.
        * svg/SVGTextPositioningElement.cpp:
        (WebCore::SVGTextPositioningElement::svgAttributeChanged): Ditto.
        * svg/SVGUseElement.cpp:
        (WebCore::SVGUseElement::svgAttributeChanged): Ditto.
        (WebCore::SVGUseElement::updateContainerSizes): Ditto.
        (WebCore::SVGUseElement::updateContainerOffsets): Ditto.

2010-07-16  Nikolas Zimmermann  <nzimmermann@rim.com>

        Reviewed by Dirk Schulze.

        relative positioning does not work for radialGradient after window resize
        https://bugs.webkit.org/show_bug.cgi?id=41249

        * platform/mac/svg/custom/marker-child-changes-css-expected.checksum: Added.
        * platform/mac/svg/custom/marker-child-changes-css-expected.png: Added.
        * platform/mac/svg/custom/marker-child-changes-css-expected.txt: Added.
        * platform/mac/svg/custom/relative-sized-content-with-resources-expected.checksum: Added.
        * platform/mac/svg/custom/relative-sized-content-with-resources-expected.png: Added.
        * platform/mac/svg/custom/relative-sized-content-with-resources-expected.txt: Added.
        * svg/custom/marker-child-changes-css.svg: Added.
        * svg/custom/relative-sized-content-with-resources.xhtml: Added.

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

48 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/mac/svg/custom/marker-child-changes-css-expected.checksum [new file with mode: 0644]
LayoutTests/platform/mac/svg/custom/marker-child-changes-css-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/svg/custom/marker-child-changes-css-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/svg/custom/relative-sized-content-with-resources-expected.checksum [new file with mode: 0644]
LayoutTests/platform/mac/svg/custom/relative-sized-content-with-resources-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/svg/custom/relative-sized-content-with-resources-expected.txt [new file with mode: 0644]
LayoutTests/svg/custom/marker-child-changes-css.svg [new file with mode: 0644]
LayoutTests/svg/custom/relative-sized-content-with-resources.xhtml [new file with mode: 0644]
WebCore/ChangeLog
WebCore/rendering/RenderForeignObject.cpp
WebCore/rendering/RenderPath.cpp
WebCore/rendering/RenderSVGContainer.cpp
WebCore/rendering/RenderSVGImage.cpp
WebCore/rendering/RenderSVGModelObject.cpp
WebCore/rendering/RenderSVGModelObject.h
WebCore/rendering/RenderSVGResource.cpp
WebCore/rendering/RenderSVGResource.h
WebCore/rendering/RenderSVGResourceClipper.cpp
WebCore/rendering/RenderSVGResourceClipper.h
WebCore/rendering/RenderSVGResourceFilter.cpp
WebCore/rendering/RenderSVGResourceGradient.cpp
WebCore/rendering/RenderSVGResourceMarker.cpp
WebCore/rendering/RenderSVGResourceMasker.cpp
WebCore/rendering/RenderSVGResourcePattern.cpp
WebCore/rendering/RenderSVGText.cpp
WebCore/svg/SVGAnimateMotionElement.cpp
WebCore/svg/SVGAnimateTransformElement.cpp
WebCore/svg/SVGCircleElement.cpp
WebCore/svg/SVGEllipseElement.cpp
WebCore/svg/SVGFEImageElement.cpp
WebCore/svg/SVGForeignObjectElement.cpp
WebCore/svg/SVGGElement.cpp
WebCore/svg/SVGImageElement.cpp
WebCore/svg/SVGLineElement.cpp
WebCore/svg/SVGPathElement.cpp
WebCore/svg/SVGPolyElement.cpp
WebCore/svg/SVGRectElement.cpp
WebCore/svg/SVGSVGElement.cpp
WebCore/svg/SVGStopElement.cpp
WebCore/svg/SVGStopElement.h
WebCore/svg/SVGStyledElement.cpp
WebCore/svg/SVGStyledElement.h
WebCore/svg/SVGTRefElement.cpp
WebCore/svg/SVGTextElement.cpp
WebCore/svg/SVGTextPathElement.cpp
WebCore/svg/SVGTextPositioningElement.cpp
WebCore/svg/SVGUseElement.cpp

index 84a5985..8ccbbf2 100644 (file)
@@ -1,3 +1,19 @@
+2010-07-16  Nikolas Zimmermann  <nzimmermann@rim.com>
+
+        Reviewed by Dirk Schulze.
+
+        relative positioning does not work for radialGradient after window resize
+        https://bugs.webkit.org/show_bug.cgi?id=41249
+
+        * platform/mac/svg/custom/marker-child-changes-css-expected.checksum: Added.
+        * platform/mac/svg/custom/marker-child-changes-css-expected.png: Added.
+        * platform/mac/svg/custom/marker-child-changes-css-expected.txt: Added.
+        * platform/mac/svg/custom/relative-sized-content-with-resources-expected.checksum: Added.
+        * platform/mac/svg/custom/relative-sized-content-with-resources-expected.png: Added.
+        * platform/mac/svg/custom/relative-sized-content-with-resources-expected.txt: Added.
+        * svg/custom/marker-child-changes-css.svg: Added.
+        * svg/custom/relative-sized-content-with-resources.xhtml: Added.
+
 2010-07-16  Cosmin Truta  <ctruta@chromium.org>
 
         Reviewed by Eric Seidel.
diff --git a/LayoutTests/platform/mac/svg/custom/marker-child-changes-css-expected.checksum b/LayoutTests/platform/mac/svg/custom/marker-child-changes-css-expected.checksum
new file mode 100644 (file)
index 0000000..374c765
--- /dev/null
@@ -0,0 +1 @@
+fbb0a4464cb404cec2fa22a55477ff2e
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/custom/marker-child-changes-css-expected.png b/LayoutTests/platform/mac/svg/custom/marker-child-changes-css-expected.png
new file mode 100644 (file)
index 0000000..c902c27
Binary files /dev/null and b/LayoutTests/platform/mac/svg/custom/marker-child-changes-css-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/custom/marker-child-changes-css-expected.txt b/LayoutTests/platform/mac/svg/custom/marker-child-changes-css-expected.txt
new file mode 100644 (file)
index 0000000..10d17e0
--- /dev/null
@@ -0,0 +1,13 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderSVGRoot {svg} at (122,127) size 66x66
+    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGResourceMarker {marker} [id="markerStart"] [markerUnits=strokeWidth] [ref at (5,5)] [angle=0.00]
+        RenderPath {rect} at (0,0) size 2x2 [fill={[type=SOLID] [color=#FF0000]}] [data="M0.00,0.00 L10.00,0.00 L10.00,10.00 L0.00,10.00 Z"]
+      RenderSVGResourceMarker {marker} [id="markerMiddle"] [markerUnits=strokeWidth] [ref at (5,5)] [angle=0.00]
+        RenderPath {circle} at (0,0) size 2x2 [fill={[type=SOLID] [color=#008000]}] [data="M10.00,5.00 L9.99,5.31 L9.96,5.63 L9.91,5.94 L9.84,6.24 L9.76,6.55 L9.65,6.84 L9.52,7.13 L9.38,7.41 L9.22,7.68 L9.05,7.94 L8.85,8.19 L8.64,8.42 L8.42,8.64 L8.19,8.85 L7.94,9.05 L7.68,9.22 L7.41,9.38 L7.13,9.52 L6.84,9.65 L6.55,9.76 L6.24,9.84 L5.94,9.91 L5.63,9.96 L5.31,9.99 L5.00,10.00 L4.69,9.99 L4.37,9.96 L4.06,9.91 L3.76,9.84 L3.45,9.76 L3.16,9.65 L2.87,9.52 L2.59,9.38 L2.32,9.22 L2.06,9.05 L1.81,8.85 L1.58,8.64 L1.36,8.42 L1.15,8.19 L0.95,7.94 L0.78,7.68 L0.62,7.41 L0.48,7.13 L0.35,6.84 L0.24,6.55 L0.16,6.24 L0.09,5.94 L0.04,5.63 L0.01,5.31 L0.00,5.00 L0.01,4.69 L0.04,4.37 L0.09,4.06 L0.16,3.76 L0.24,3.45 L0.35,3.16 L0.48,2.87 L0.62,2.59 L0.78,2.32 L0.95,2.06 L1.15,1.81 L1.36,1.58 L1.58,1.36 L1.81,1.15 L2.06,0.95 L2.32,0.78 L2.59,0.62 L2.87,0.48 L3.16,0.35 L3.45,0.24 L3.76,0.16 L4.06,0.09 L4.37,0.04 L4.69,0.01 L5.00,0.00 L5.31,0.01 L5.63,0.04 L5.94,0.09 L6.24,0.16 L6.55,0.24 L6.84,0.35 L7.13,0.48 L7.41,0.62 L7.68,0.78 L7.94,0.95 L8.19,1.15 L8.42,1.36 L8.64,1.58 L8.85,1.81 L9.05,2.06 L9.22,2.32 L9.38,2.59 L9.52,2.87 L9.65,3.16 L9.76,3.45 L9.84,3.76 L9.91,4.06 L9.96,4.37 L9.99,4.69 Z"]
+      RenderSVGResourceMarker {marker} [id="markerEnd"] [markerUnits=strokeWidth] [ref at (5,5)] [angle=0.00]
+        RenderPath {path} at (0,0) size 2x2 [fill={[type=SOLID] [color=#0000FF]}] [data="M5.00,0.00 L10.00,10.00 L0.00,10.00 Z"]
+    RenderSVGContainer {g} at (122,127) size 66x66
+      RenderPath {path} at (122,127) size 66x66 [stroke={[type=SOLID] [color=#000000] [stroke width=8.00]}] [start marker=markerStart] [middle marker=markerMiddle] [end marker=markerEnd] [data="M130.00,135.00 L180.00,135.00 L180.00,185.00"]
diff --git a/LayoutTests/platform/mac/svg/custom/relative-sized-content-with-resources-expected.checksum b/LayoutTests/platform/mac/svg/custom/relative-sized-content-with-resources-expected.checksum
new file mode 100644 (file)
index 0000000..5514089
--- /dev/null
@@ -0,0 +1 @@
+161763b9765935dcf1c17ba5dfb82f75
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/custom/relative-sized-content-with-resources-expected.png b/LayoutTests/platform/mac/svg/custom/relative-sized-content-with-resources-expected.png
new file mode 100644 (file)
index 0000000..c21b95d
Binary files /dev/null and b/LayoutTests/platform/mac/svg/custom/relative-sized-content-with-resources-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/custom/relative-sized-content-with-resources-expected.txt b/LayoutTests/platform/mac/svg/custom/relative-sized-content-with-resources-expected.txt
new file mode 100644 (file)
index 0000000..b606f05
--- /dev/null
@@ -0,0 +1,18 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x478
+  RenderBlock {html} at (0,0) size 800x478
+    RenderBody {body} at (8,16) size 784x454
+      RenderBlock {p} at (0,0) size 784x36
+        RenderText {#text} at (0,0) size 749x36
+          text run at (0,0) width 749: "The svg area contained in the div element (red box), should fill out the whole area with a circle, which contains a radial"
+          text run at (0,18) width 127: "gradient in its center"
+      RenderBlock {div} at (0,52) size 402x402 [border: (1px solid #FF0000)]
+        RenderSVGRoot {svg} at (48,108) size 322x322
+          RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+            RenderSVGResourceRadialGradient {radialGradient} [id="grad"] [gradientUnits=userSpaceOnUse] [center=(200,200)] [focal=(200,200)] [radius=160.00]
+              RenderSVGGradientStop {stop} [offset=0.00] [color=#000000]
+              RenderSVGGradientStop {stop} [offset=1.00] [color=#FFFFFF]
+          RenderPath {circle} at (48,108) size 322x322 [stroke={[type=SOLID] [color=#808080]}] [fill={[type=RADIAL-GRADIENT] [id="grad"]}] [data="M360.00,200.00 L359.68,210.05 L358.74,220.05 L357.17,229.98 L354.97,239.79 L352.17,249.44 L348.76,258.90 L344.77,268.12 L340.21,277.08 L335.09,285.73 L329.44,294.05 L323.28,301.99 L316.63,309.53 L309.53,316.63 L301.99,323.28 L294.05,329.44 L285.73,335.09 L277.08,340.21 L268.12,344.77 L258.90,348.76 L249.44,352.17 L239.79,354.97 L229.98,357.17 L220.05,358.74 L210.05,359.68 L200.00,360.00 L189.95,359.68 L179.95,358.74 L170.02,357.17 L160.21,354.97 L150.56,352.17 L141.10,348.76 L131.88,344.77 L122.92,340.21 L114.27,335.09 L105.95,329.44 L98.01,323.28 L90.47,316.63 L83.37,309.53 L76.72,301.99 L70.56,294.05 L64.91,285.73 L59.79,277.08 L55.23,268.12 L51.24,258.90 L47.83,249.44 L45.03,239.79 L42.83,229.98 L41.26,220.05 L40.32,210.05 L40.00,200.00 L40.32,189.95 L41.26,179.95 L42.83,170.02 L45.03,160.21 L47.83,150.56 L51.24,141.10 L55.23,131.88 L59.79,122.92 L64.91,114.27 L70.56,105.95 L76.72,98.01 L83.37,90.47 L90.47,83.37 L98.01,76.72 L105.95,70.56 L114.27,64.91 L122.92,59.79 L131.88,55.23 L141.10,51.24 L150.56,47.83 L160.21,45.03 L170.02,42.83 L179.95,41.26 L189.95,40.32 L200.00,40.00 L210.05,40.32 L220.05,41.26 L229.98,42.83 L239.79,45.03 L249.44,47.83 L258.90,51.24 L268.12,55.23 L277.08,59.79 L285.73,64.91 L294.05,70.56 L301.99,76.72 L309.53,83.37 L316.64,90.47 L323.28,98.01 L329.44,105.95 L335.09,114.27 L340.21,122.92 L344.77,131.88 L348.76,141.10 L352.17,150.56 L354.97,160.21 L357.17,170.02 L358.74,179.95 L359.68,189.95 Z"]
+        RenderText {#text} at (0,0) size 0x0
+caret: position 145 of child 0 {#text} of child 1 {p} of body
diff --git a/LayoutTests/svg/custom/marker-child-changes-css.svg b/LayoutTests/svg/custom/marker-child-changes-css.svg
new file mode 100644 (file)
index 0000000..2b734fe
--- /dev/null
@@ -0,0 +1,42 @@
+<svg width="800" height="600" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<defs>
+    <marker id="markerStart" viewBox="0 0 10 10" markerWidth="2" markerHeight="2" refX="5" refY="5" markerUnits="strokeWidth">
+        <rect id="rect" width="10" height="10" fill="none" stroke="none"/>
+    </marker>
+    <marker id="markerMiddle" viewBox="0 0 10 10" markerWidth="2" markerHeight="2" refX="5" refY="5" markerUnits="strokeWidth">
+        <circle cx="5" cy="5" r="5" fill="green" stroke="none"/>
+    </marker>
+    <marker id="markerEnd" viewBox="0 0 10 10" markerWidth="2" markerHeight="2" refX="5" refY="5" markerUnits="strokeWidth">
+        <path d="M 5 0 L 10 10 L 0 10 Z" fill="blue" stroke="none"/>
+    </marker>
+</defs>
+
+<script>
+if (window.layoutTestController)
+    layoutTestController.waitUntilDone();
+
+window.setTimeout("clickNow()", 0);
+
+function clickNow() {
+    if (window.eventSender) {
+        eventSender.mouseMoveTo(150, 135);
+        eventSender.mouseDown();
+        eventSender.mouseUp();
+    }
+
+    if (window.layoutTestController) {
+        layoutTestController.notifyDone();
+    }
+}
+
+function mouseHandler(evt)
+{
+    var rect = document.getElementById("rect");
+       rect.style.fill = "red";
+}
+</script>
+
+<g onclick="mouseHandler()">
+    <path fill="none" stroke="black" stroke-width="8" marker-start="url(#markerStart)" marker-mid="url(#markerMiddle)" marker-end="url(#markerEnd)" d="M 130 135 L 180 135 L 180 185"/>
+</g>
+</svg>
diff --git a/LayoutTests/svg/custom/relative-sized-content-with-resources.xhtml b/LayoutTests/svg/custom/relative-sized-content-with-resources.xhtml
new file mode 100644 (file)
index 0000000..f1a1faf
--- /dev/null
@@ -0,0 +1,35 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<body>
+    <p>The svg area contained in the div element (red box), should fill out the whole area with a circle, which contains a radial gradient in its center</p>
+    <div id="contentBox" style="width: 100px; height: 400px; border: 1px solid red;">
+        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onclick="resizeBox()">
+            <defs>
+                <radialGradient id="grad" cx="50%" cy="50%" r="40%" gradientUnits="userSpaceOnUse">
+                    <stop offset="0" stop-color="black" />
+                    <stop offset="1" stop-color="white" />
+                </radialGradient>
+             </defs>
+
+             <circle cx="50%" cy="50%" r="40%" stroke="gray" fill="url(#grad)"/>
+        </svg>
+    </div>
+    <script type="JavaScript">
+        if (window.layoutTestController)
+            layoutTestController.waitUntilDone();
+
+        if (window.eventSender) {
+            window.setTimeout(function() {
+                eventSender.mouseMoveTo(50, 200);
+                eventSender.mouseDown();
+                eventSender.mouseUp();
+            }, 0);
+        }
+
+        function resizeBox() {
+            document.getElementById("contentBox").style.setProperty("width", "400px");
+            if (window.layoutTestController)
+                layoutTestController.notifyDone();
+        }
+    </script>
+</body>
+</html>
index 313f4c5..1bc9f29 100644 (file)
@@ -1,3 +1,117 @@
+2010-07-16  Nikolas Zimmermann  <nzimmermann@rim.com>
+
+        Reviewed by Dirk Schulze.
+
+        relative positioning does not work for radialGradient after window resize
+        https://bugs.webkit.org/show_bug.cgi?id=41249
+
+        Redesign the way resources are invalidated. No longer utilize the DOM tree, specifically SVGStyledElement::svgAttributeChanged(), to invalidate
+        all resources in the ancestor chain (including itself) when any attribute changes. rect.setAttribute("foo", "bar") should never invalidate the
+        resources. Also the old approach didn't work correctly if the root layout changed (eg. window size change) - we failed to invalidate the resources,
+        thus leading to wrong renderings.
+
+        Instead of calling setNeedsLayout(true) from the SVG*Element classes, call RenderSVGResource::markForLayoutAndParentResourceInvalidation(), which
+        does the same thing and invalidates all resources in the ancestor chain (removing the cached results from the HashMaps). This only happens from
+        the various svgAttributeChanged() methods, if we know which attribute changed, and what action has to be taken.
+
+        All SVG renderers now invalidate their own resources on layout() if the layout changed (selfNeedsLayout()=true). The resources will be recreated
+        and cached during the following paint() call.
+
+        Tests: svg/custom/marker-child-changes-css.svg
+               svg/custom/relative-sized-content-with-resources.xhtml
+
+        * rendering/RenderForeignObject.cpp:
+        (WebCore::RenderForeignObject::layout): If our layout changed, invalidate our resources, by calling RenderSVGResource::invalidateAllResourcesOfRenderer().
+        * rendering/RenderPath.cpp:
+        (WebCore::RenderPath::layout): Ditto.
+        * rendering/RenderSVGContainer.cpp:
+        (WebCore::RenderSVGContainer::layout): Ditto.
+        * rendering/RenderSVGImage.cpp:
+        (WebCore::RenderSVGImage::layout): Ditto.
+        * rendering/RenderSVGModelObject.cpp:
+        (WebCore::RenderSVGModelObject::styleDidChange): Added, to invalidate resources on CSS changes, covered by new svg/custom/marker-child-changes-css.svg test.
+        * rendering/RenderSVGModelObject.h:
+        * rendering/RenderSVGResource.cpp:
+        (WebCore::RenderSVGResource::markForLayoutAndResourceInvalidation): Add new "needsBoundaries" parameter, calling setNeedsBoundaries() on the target render object,
+                                                                            simplifying all RenderSVGResource* code.
+        (WebCore::RenderSVGResource::markForLayoutAndParentResourceInvalidation): New static method used from DOM tree to invalidate all cached resources in the ancestor chain
+                                                                                  for a render object. Also marks the renderer for layout, if needed. 
+        * rendering/RenderSVGResource.h:
+        * rendering/RenderSVGResourceClipper.cpp: Simplify code, remove no longer needed hacks, as invalidation is now carried out by render tree.
+        (WebCore::RenderSVGResourceClipper::RenderSVGResourceClipper): Add m_invalidationBlocked hack, to avoid invalidations, while we're mutating the render styles (which is a hack!).
+        (WebCore::RenderSVGResourceClipper::invalidateClients): Don't do anything if m_invalidationBlocked=true.
+        (WebCore::RenderSVGResourceClipper::invalidateClient): Ditto.
+        (WebCore::RenderSVGResourceClipper::createClipData): Set m_invalidationBlocked before mutating render styles, as they are restored immediately after creating the clip image.
+        (WebCore::RenderSVGResourceClipper::resourceBoundingBox): Remove no longer needed hack to initialize ClipperData earlier than applyResource() would do.
+        * rendering/RenderSVGResourceClipper.h:
+        * rendering/RenderSVGResourceFilter.cpp:
+        (WebCore::RenderSVGResourceFilter::invalidateClients): Simplify code using markForLayoutAndResourceInvalidation.
+        (WebCore::RenderSVGResourceFilter::invalidateClient): Remove wrong assertion.
+        * rendering/RenderSVGResourceGradient.cpp:
+        (WebCore::RenderSVGResourceGradient::invalidateClients): Simplify code using markForLayoutAndResourceInvalidation.
+        (WebCore::RenderSVGResourceGradient::invalidateClient): Remove wrong assertion.
+        * rendering/RenderSVGResourceMarker.cpp:
+        (WebCore::RenderSVGResourceMarker::invalidateClients): Simplify code using markForLayoutAndResourceInvalidation.
+        (WebCore::RenderSVGResourceMarker::invalidateClient): Remove wrong assertion.
+        * rendering/RenderSVGResourceMasker.cpp:
+        (WebCore::RenderSVGResourceMasker::invalidateClients): Simplify code using markForLayoutAndResourceInvalidation.
+        (WebCore::RenderSVGResourceMasker::invalidateClient): Remove wrong assertion.
+        (WebCore::RenderSVGResourceMasker::resourceBoundingBox): Remove no longer needed hack to initializer MaskerData earlier than applyResource() would do.
+        * rendering/RenderSVGResourcePattern.cpp:
+        (WebCore::RenderSVGResourcePattern::invalidateClients): Simplify code using markForLayoutAndResourceInvalidation.
+        (WebCore::RenderSVGResourcePattern::invalidateClient): Remove wrong assertion.
+        * rendering/RenderSVGText.cpp:
+        (WebCore::RenderSVGText::layout): If our layout changed, invalidate our resources, by calling RenderSVGResource::invalidateAllResourcesOfRenderer().
+        * svg/SVGAnimateMotionElement.cpp:
+        (WebCore::SVGAnimateMotionElement::applyResultsToTarget): Call RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer) instead of renderer->setNeedsLayout(true).
+        * svg/SVGAnimateTransformElement.cpp:
+        (WebCore::SVGAnimateTransformElement::applyResultsToTarget): Ditto.
+        * svg/SVGCircleElement.cpp:
+        (WebCore::SVGCircleElement::svgAttributeChanged): Ditto.
+        * svg/SVGEllipseElement.cpp:
+        (WebCore::SVGEllipseElement::svgAttributeChanged): Ditto.
+        * svg/SVGFEImageElement.cpp:
+        (WebCore::SVGFEImageElement::notifyFinished): Ditto.
+        * svg/SVGForeignObjectElement.cpp:
+        (WebCore::SVGForeignObjectElement::svgAttributeChanged): Ditto.
+        * svg/SVGGElement.cpp:
+        (WebCore::SVGGElement::svgAttributeChanged): Ditto.
+        * svg/SVGImageElement.cpp:
+        (WebCore::SVGImageElement::svgAttributeChanged): Ditto.
+        * svg/SVGLineElement.cpp:
+        (WebCore::SVGLineElement::svgAttributeChanged): Ditto.
+        * svg/SVGPathElement.cpp:
+        (WebCore::SVGPathElement::svgAttributeChanged): Ditto.
+        * svg/SVGPolyElement.cpp:
+        (WebCore::SVGPolyElement::svgAttributeChanged): Ditto.
+        * svg/SVGRectElement.cpp:
+        (WebCore::SVGRectElement::svgAttributeChanged): Ditto.
+        * svg/SVGSVGElement.cpp:
+        (WebCore::SVGSVGElement::setCurrentScale): Ditto.
+        (WebCore::SVGSVGElement::svgAttributeChanged): Ditto.
+        (WebCore::SVGSVGElement::inheritViewAttributes): Ditto.
+        * svg/SVGStopElement.cpp:
+        (WebCore::SVGStopElement::SVGStopElement): Changed m_offset initialization from 0.0f to 0.
+        (WebCore::SVGStopElement::svgAttributeChanged): Add missing implementation, calling RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer) on offsetAttr changes.
+        * svg/SVGStopElement.h:
+        * svg/SVGStyledElement.cpp:
+        (WebCore::SVGStyledElement::svgAttributeChanged): Don't call invalidateResourceInAncestorChain() on every attribute change, do it in all classes inheriting from us,
+                                                          for specific attributes. Also stop calling RenderSVGResource::invalidateAllResourcesOfRenderer(), all handled in the render tree now.
+        (WebCore::SVGStyledElement::invalidateResourceClients): Early exit, if document is still parsing.
+        * svg/SVGStyledElement.h:
+        * svg/SVGTRefElement.cpp:
+        (WebCore::SVGTRefElement::svgAttributeChanged): Call RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer) instead of renderer->setNeedsLayout(true).
+        * svg/SVGTextElement.cpp:
+        (WebCore::SVGTextElement::svgAttributeChanged): Ditto.
+        * svg/SVGTextPathElement.cpp:
+        (WebCore::SVGTextPathElement::svgAttributeChanged): Ditto.
+        * svg/SVGTextPositioningElement.cpp:
+        (WebCore::SVGTextPositioningElement::svgAttributeChanged): Ditto.
+        * svg/SVGUseElement.cpp:
+        (WebCore::SVGUseElement::svgAttributeChanged): Ditto.
+        (WebCore::SVGUseElement::updateContainerSizes): Ditto.
+        (WebCore::SVGUseElement::updateContainerOffsets): Ditto.
+
 2010-07-16  Cosmin Truta  <ctruta@chromium.org>
 
         Reviewed by Eric Seidel.
index 5a1d972..8b84f97 100644 (file)
@@ -26,6 +26,7 @@
 #include "RenderForeignObject.h"
 
 #include "GraphicsContext.h"
+#include "RenderSVGResource.h"
 #include "RenderView.h"
 #include "SVGForeignObjectElement.h"
 #include "SVGRenderSupport.h"
@@ -118,6 +119,10 @@ void RenderForeignObject::layout()
     setLocation(roundedIntPoint(viewportLocation));
     RenderBlock::layout();
 
+    // Invalidate all resources of this client, if we changed something.
+    if (m_everHadLayout && selfNeedsLayout())
+        RenderSVGResource::invalidateAllResourcesOfRenderer(this);
+
     repainter.repaintAfterLayout();
     setNeedsLayout(false);
 }
index 760c7aa..dd79397 100644 (file)
@@ -111,6 +111,10 @@ void RenderPath::layout()
         m_needsTransformUpdate = false;
     }
 
+    // Invalidate all resources of this client, if we changed something.
+    if (m_everHadLayout && selfNeedsLayout())
+        RenderSVGResource::invalidateAllResourcesOfRenderer(this);
+
     // At this point LayoutRepainter already grabbed the old bounds,
     // recalculate them now so repaintAfterLayout() uses the new bounds
     if (needsPathUpdate || m_needsBoundariesUpdate) {
index f84a835..f82ec95 100644 (file)
@@ -57,6 +57,10 @@ void RenderSVGContainer::layout()
 
     SVGRenderSupport::layoutChildren(this, selfNeedsLayout());
 
+    // Invalidate all resources of this client, if we changed something.
+    if (m_everHadLayout && selfNeedsLayout())
+        RenderSVGResource::invalidateAllResourcesOfRenderer(this);
+
     repainter.repaintAfterLayout();
     setNeedsLayout(false);
 }
index a6fe6f6..44b68b1 100644 (file)
@@ -66,11 +66,15 @@ void RenderSVGImage::layout()
     calcWidth();
     calcHeight();
 
+    // FIXME: Optimize caching the repaint rects.
     m_localBounds = FloatRect(image->x().value(image), image->y().value(image), image->width().value(image), image->height().value(image));
     m_cachedLocalRepaintRect = FloatRect();
 
+    // Invalidate all resources of this client, if we changed something.
+    if (m_everHadLayout && selfNeedsLayout())
+        RenderSVGResource::invalidateAllResourcesOfRenderer(this);
+
     repainter.repaintAfterLayout();
-    
     setNeedsLayout(false);
 }
 
index 3d22e7a..49404cb 100644 (file)
@@ -87,6 +87,14 @@ void RenderSVGModelObject::destroy()
     RenderObject::destroy();
 }
 
+void RenderSVGModelObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+    RenderObject::styleDidChange(diff, oldStyle);
+
+    if (style() && (diff == StyleDifferenceLayout || diff == StyleDifferenceRepaint))
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(this, false);
+}
+
 bool RenderSVGModelObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, int, int, int, int, HitTestAction)
 {
     ASSERT_NOT_REACHED();
index 82c08c0..741cd61 100644 (file)
@@ -61,6 +61,7 @@ public:
     virtual void destroy();
 
     virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
+    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
 
 private:
     // This method should never be called, SVG uses a different nodeAtPoint method
index 0aa7182..b4f499e 100644 (file)
@@ -184,21 +184,17 @@ RenderSVGResourceSolidColor* RenderSVGResource::sharedSolidPaintingResource()
     return s_sharedSolidPaintingResource;
 }
 
-void RenderSVGResource::markForLayoutAndResourceInvalidation(RenderObject* object)
+void RenderSVGResource::markForLayoutAndResourceInvalidation(RenderObject* object, bool needsBoundariesUpdate)
 {
     ASSERT(object);
     ASSERT(object->node());
     ASSERT(object->node()->isSVGElement());
 
-    // Mark the renderer for layout
-    object->setNeedsLayout(true);
+    // Eventually mark the renderer needing a boundaries update
+    if (needsBoundariesUpdate)
+        object->setNeedsBoundariesUpdate();
 
-    // Notify any resources in the ancestor chain, that we've been invalidated
-    SVGElement* element = static_cast<SVGElement*>(object->node());
-    if (!element->isStyled())
-        return;
-
-    static_cast<SVGStyledElement*>(element)->invalidateResourcesInAncestorChain();
+    markForLayoutAndParentResourceInvalidation(object);
 }
 
 static inline void invalidatePaintingResource(SVGPaint* paint, RenderObject* object)
@@ -254,6 +250,22 @@ void RenderSVGResource::invalidateAllResourcesOfRenderer(RenderObject* object)
         invalidatePaintingResource(svgStyle->strokePaint(), object);
 }
 
+void RenderSVGResource::markForLayoutAndParentResourceInvalidation(RenderObject* object, bool needsLayout)
+{
+    ASSERT(object);
+    if (needsLayout)
+        object->setNeedsLayout(true);
+
+    // Invalidate resources in ancestor chain, if needed.
+    RenderObject* current = object->parent();
+    while (current) {
+        if (current->isSVGResourceContainer()) 
+            current->toRenderSVGResourceContainer()->invalidateClients();
+
+        current = current->parent();
+    }
+}
+
 }
 
 #endif
index 34ff14e..b3ea6fb 100644 (file)
@@ -80,12 +80,13 @@ public:
     static RenderSVGResourceSolidColor* sharedSolidPaintingResource();
 
     static void invalidateAllResourcesOfRenderer(RenderObject*);
+    static void markForLayoutAndParentResourceInvalidation(RenderObject*, bool needsLayout = true);
 
 private:
     static void adjustColorForPseudoRules(const RenderStyle*, bool useFillPaint, Color&);
     
 protected:
-    void markForLayoutAndResourceInvalidation(RenderObject*);
+    void markForLayoutAndResourceInvalidation(RenderObject*, bool needsBoundariesUpdate = true);
 };
 
 }
index 5116ea7..e923f7e 100644 (file)
@@ -49,6 +49,7 @@ RenderSVGResourceType RenderSVGResourceClipper::s_resourceType = ClipperResource
 
 RenderSVGResourceClipper::RenderSVGResourceClipper(SVGClipPathElement* node)
     : RenderSVGResourceContainer(node)
+    , m_invalidationBlocked(false)
 {
 }
 
@@ -60,12 +61,13 @@ RenderSVGResourceClipper::~RenderSVGResourceClipper()
 
 void RenderSVGResourceClipper::invalidateClients()
 {
+    if (m_invalidationBlocked)
+        return;
+
     HashMap<RenderObject*, ClipperData*>::const_iterator end = m_clipper.end();
-    for (HashMap<RenderObject*, ClipperData*>::const_iterator it = m_clipper.begin(); it != end; ++it) {
-        RenderObject* renderer = it->first;
-        renderer->setNeedsBoundariesUpdate();
-        renderer->setNeedsLayout(true);
-    }
+    for (HashMap<RenderObject*, ClipperData*>::const_iterator it = m_clipper.begin(); it != end; ++it)
+        markForLayoutAndResourceInvalidation(it->first);
+
     deleteAllValues(m_clipper);
     m_clipper.clear();
     m_clipBoundaries = FloatRect();
@@ -73,12 +75,10 @@ void RenderSVGResourceClipper::invalidateClients()
 
 void RenderSVGResourceClipper::invalidateClient(RenderObject* object)
 {
-    ASSERT(object);
+    if (m_invalidationBlocked)
+        return;
 
-    // FIXME: The HashSet should always contain the object on calling invalidateClient. A race condition
-    // during the parsing can causes a call of invalidateClient right before the call of applyResource.
-    // We return earlier for the moment. This bug should be fixed in:
-    // https://bugs.webkit.org/show_bug.cgi?id=35181
+    ASSERT(object);
     if (!m_clipper.contains(object))
         return;
 
@@ -242,6 +242,10 @@ bool RenderSVGResourceClipper::createClipData(ClipperData* clipperData, const Fl
         svgStyle->setStrokeOpacity(1.0f);
         svgStyle->setFilterResource(String());
         svgStyle->setMaskerResource(String());
+
+        // The setStyle() call results in a styleDidChange() call, which in turn invalidations the resources.
+        // As we're mutating the resource on purpose, block updates until we've resetted the style again.
+        m_invalidationBlocked = true;
         renderer->setStyle(newRenderStyle.release());
 
         // In the case of a <use> element, we obtained its renderere above, to retrieve its clipRule.
@@ -250,6 +254,7 @@ bool RenderSVGResourceClipper::createClipData(ClipperData* clipperData, const Fl
         SVGRenderSupport::renderSubtreeToImage(clipperData->clipMaskImage.get(), isUseElement ? childNode->renderer() : renderer);
 
         renderer->setStyle(oldRenderStyle.release());
+        m_invalidationBlocked = false;
     }
 
     maskContext->restore();
@@ -317,10 +322,6 @@ bool RenderSVGResourceClipper::childElementReferencesResource(const SVGRenderSty
 
 FloatRect RenderSVGResourceClipper::resourceBoundingBox(RenderObject* object)
 {
-    // Save the reference to the calling object for relayouting it on changing resource properties.
-    if (!m_clipper.contains(object))
-        m_clipper.set(object, new ClipperData);
-
     // Resource was not layouted yet. Give back the boundingBox of the object.
     if (selfNeedsLayout())
         return object->objectBoundingBox();
index 6064be1..7128aa1 100644 (file)
@@ -70,6 +70,7 @@ private:
 
     virtual bool childElementReferencesResource(const SVGRenderStyle*, const String&) const;
 
+    bool m_invalidationBlocked;
     FloatRect m_clipBoundaries;
     HashMap<RenderObject*, ClipperData*> m_clipper;
 };
index 19a6ccb..a6358f0 100644 (file)
@@ -67,11 +67,9 @@ RenderSVGResourceFilter::~RenderSVGResourceFilter()
 void RenderSVGResourceFilter::invalidateClients()
 {
     HashMap<RenderObject*, FilterData*>::const_iterator end = m_filter.end();
-    for (HashMap<RenderObject*, FilterData*>::const_iterator it = m_filter.begin(); it != end; ++it) {
-        RenderObject* renderer = it->first;
-        renderer->setNeedsBoundariesUpdate();
-        renderer->setNeedsLayout(true);
-    }
+    for (HashMap<RenderObject*, FilterData*>::const_iterator it = m_filter.begin(); it != end; ++it)
+        markForLayoutAndResourceInvalidation(it->first);
+
     deleteAllValues(m_filter);
     m_filter.clear();
 }
@@ -79,11 +77,6 @@ void RenderSVGResourceFilter::invalidateClients()
 void RenderSVGResourceFilter::invalidateClient(RenderObject* object)
 {
     ASSERT(object);
-
-    // FIXME: The HashMap should always contain the object on calling invalidateClient. A race condition
-    // during the parsing can causes a call of invalidateClient right before the call of applyResource.
-    // We return earlier for the moment. This bug should be fixed in:
-    // https://bugs.webkit.org/show_bug.cgi?id=35181
     if (!m_filter.contains(object))
         return;
 
index 74f5b13..c176a92 100644 (file)
@@ -51,7 +51,7 @@ void RenderSVGResourceGradient::invalidateClients()
 {
     const HashMap<RenderObject*, GradientData*>::const_iterator end = m_gradient.end();
     for (HashMap<RenderObject*, GradientData*>::const_iterator it = m_gradient.begin(); it != end; ++it)
-        markForLayoutAndResourceInvalidation(it->first);
+        markForLayoutAndResourceInvalidation(it->first, false);
 
     deleteAllValues(m_gradient);
     m_gradient.clear();
@@ -60,16 +60,11 @@ void RenderSVGResourceGradient::invalidateClients()
 void RenderSVGResourceGradient::invalidateClient(RenderObject* object)
 {
     ASSERT(object);
-
-    // FIXME: The HashMap should always contain the object on calling invalidateClient. A race condition
-    // during the parsing can causes a call of invalidateClient right before the call of applyResource.
-    // We return earlier for the moment. This bug should be fixed in:
-    // https://bugs.webkit.org/show_bug.cgi?id=35181
     if (!m_gradient.contains(object))
         return;
 
     delete m_gradient.take(object);
-    markForLayoutAndResourceInvalidation(object);
+    markForLayoutAndResourceInvalidation(object, false);
 }
 
 #if PLATFORM(CG)
index ce331a7..4f0cace 100644 (file)
@@ -62,11 +62,8 @@ void RenderSVGResourceMarker::addClient(const RenderObject* object)
 void RenderSVGResourceMarker::invalidateClients()
 {
     const HashSet<const RenderObject*>::const_iterator end = m_marker.end();
-    for (HashSet<const RenderObject*>::const_iterator it = m_marker.begin(); it != end; ++it) {
-        RenderObject* renderer = const_cast<RenderObject*>(*it);
-        renderer->setNeedsBoundariesUpdate();
-        renderer->setNeedsLayout(true);
-    }
+    for (HashSet<const RenderObject*>::const_iterator it = m_marker.begin(); it != end; ++it)
+        markForLayoutAndResourceInvalidation(const_cast<RenderObject*>(*it));
 
     m_marker.clear();
 }
@@ -74,11 +71,6 @@ void RenderSVGResourceMarker::invalidateClients()
 void RenderSVGResourceMarker::invalidateClient(RenderObject* object)
 {
     ASSERT(object);
-
-    // FIXME: The HashSet should always contain the object on calling invalidateClient. A race condition
-    // during the parsing can causes a call of invalidateClient right before the call of applyResource.
-    // We return earlier for the moment. This bug should be fixed in:
-    // https://bugs.webkit.org/show_bug.cgi?id=35181
     if (!m_marker.contains(object))
         return;
 
index 5052e86..83a64b5 100644 (file)
@@ -58,11 +58,8 @@ RenderSVGResourceMasker::~RenderSVGResourceMasker()
 void RenderSVGResourceMasker::invalidateClients()
 {
     HashMap<RenderObject*, MaskerData*>::const_iterator end = m_masker.end();
-    for (HashMap<RenderObject*, MaskerData*>::const_iterator it = m_masker.begin(); it != end; ++it) {
-        RenderObject* renderer = it->first;
-        renderer->setNeedsBoundariesUpdate();
-        renderer->setNeedsLayout(true);
-    }
+    for (HashMap<RenderObject*, MaskerData*>::const_iterator it = m_masker.begin(); it != end; ++it)
+        markForLayoutAndResourceInvalidation(it->first);
 
     deleteAllValues(m_masker);
     m_masker.clear();
@@ -72,11 +69,6 @@ void RenderSVGResourceMasker::invalidateClients()
 void RenderSVGResourceMasker::invalidateClient(RenderObject* object)
 {
     ASSERT(object);
-
-    // FIXME: The HashMap should always contain the object on calling invalidateClient. A race condition
-    // during the parsing can causes a call of invalidateClient right before the call of applyResource.
-    // We return earlier for the moment. This bug should be fixed in:
-    // https://bugs.webkit.org/show_bug.cgi?id=35181
     if (!m_masker.contains(object))
         return;
 
@@ -228,10 +220,6 @@ void RenderSVGResourceMasker::calculateMaskContentRepaintRect()
 
 FloatRect RenderSVGResourceMasker::resourceBoundingBox(RenderObject* object)
 {
-    // Save the reference to the calling object for relayouting it on changing resource properties.
-    if (!m_masker.contains(object))
-        m_masker.set(object, new MaskerData);
-
     // Resource was not layouted yet. Give back clipping rect of the mask.
     SVGMaskElement* maskElement = static_cast<SVGMaskElement*>(node());
     FloatRect objectBoundingBox = object->objectBoundingBox();
index aeab15e..a2234c8 100644 (file)
@@ -48,7 +48,7 @@ void RenderSVGResourcePattern::invalidateClients()
 {
     const HashMap<RenderObject*, PatternData*>::const_iterator end = m_pattern.end();
     for (HashMap<RenderObject*, PatternData*>::const_iterator it = m_pattern.begin(); it != end; ++it)
-        markForLayoutAndResourceInvalidation(it->first);
+        markForLayoutAndResourceInvalidation(it->first, false);
 
     deleteAllValues(m_pattern);
     m_pattern.clear();
@@ -57,16 +57,11 @@ void RenderSVGResourcePattern::invalidateClients()
 void RenderSVGResourcePattern::invalidateClient(RenderObject* object)
 {
     ASSERT(object);
-
-    // FIXME: The HashMap should always contain the object on calling invalidateClient. A race condition
-    // during the parsing can causes a call of invalidateClient right before the call of applyResource.
-    // We return earlier for the moment. This bug should be fixed in:
-    // https://bugs.webkit.org/show_bug.cgi?id=35181
     if (!m_pattern.contains(object))
         return;
 
     delete m_pattern.take(object);
-    markForLayoutAndResourceInvalidation(object);
+    markForLayoutAndResourceInvalidation(object, false);
 }
 
 bool RenderSVGResourcePattern::childElementReferencesResource(const SVGRenderStyle* style, const String& referenceId) const
index 5d2b6b3..58348db 100644 (file)
@@ -98,6 +98,10 @@ void RenderSVGText::layout()
     ASSERT(childrenInline());
     forceLayoutInlineChildren();
 
+    // Invalidate all resources of this client, if we changed something.
+    if (m_everHadLayout && selfNeedsLayout())
+        RenderSVGResource::invalidateAllResourcesOfRenderer(this);
+
     repainter.repaintAfterLayout();
     setNeedsLayout(false);
 }
index 9a0da7f..c18d40c 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "Attribute.h"
 #include "RenderObject.h"
+#include "RenderSVGResource.h"
 #include "SVGElementInstance.h"
 #include "SVGMPathElement.h"
 #include "SVGParserUtilities.h"
@@ -214,9 +215,12 @@ void SVGAnimateMotionElement::applyResultsToTarget()
 {
     // We accumulate to the target element transform list so there is not much to do here.
     SVGElement* targetElement = this->targetElement();
-    if (targetElement && targetElement->renderer())
-        targetElement->renderer()->setNeedsLayout(true);
-    
+    if (!targetElement)
+        return;
+
+    if (RenderObject* renderer = targetElement->renderer())
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
+
     // ...except in case where we have additional instances in <use> trees.
     const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement();
     const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
@@ -228,7 +232,7 @@ void SVGAnimateMotionElement::applyResultsToTarget()
         transform->setMatrix(t->a(), t->b(), t->c(), t->d(), t->e(), t->f());
         if (RenderObject* renderer = shadowTreeElement->renderer()) {
             renderer->setNeedsTransformUpdate();
-            renderer->setNeedsLayout(true);
+            RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         }
     }
 }
@@ -248,5 +252,3 @@ float SVGAnimateMotionElement::calculateDistance(const String& fromString, const
 }
 
 #endif // ENABLE(SVG)
-
-// vim:ts=4:noet
index 1a305bb..6ca9447 100644 (file)
@@ -30,6 +30,7 @@
 #include "AffineTransform.h"
 #include "Attribute.h"
 #include "RenderObject.h"
+#include "RenderSVGResource.h"
 #include "SVGAngle.h"
 #include "SVGElementInstance.h"
 #include "SVGGradientElement.h"
@@ -172,9 +173,12 @@ void SVGAnimateTransformElement::applyResultsToTarget()
         return;
     // We accumulate to the target element transform list so there is not much to do here.
     SVGElement* targetElement = this->targetElement();
+    if (!targetElement)
+        return;
+
     if (RenderObject* renderer = targetElement->renderer()) {
         renderer->setNeedsTransformUpdate();
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
     }
 
     // ...except in case where we have additional instances in <use> trees.
@@ -192,7 +196,7 @@ void SVGAnimateTransformElement::applyResultsToTarget()
             static_cast<SVGGradientElement*>(shadowTreeElement)->setGradientTransformBaseValue(transformList.get());
         if (RenderObject* renderer = shadowTreeElement->renderer()) {
             renderer->setNeedsTransformUpdate();
-            renderer->setNeedsLayout(true);
+            RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         }
     }
 }
index c90b8e3..f8c9ccd 100644 (file)
@@ -26,6 +26,7 @@
 #include "Attribute.h"
 #include "FloatPoint.h"
 #include "RenderPath.h"
+#include "RenderSVGResource.h"
 #include "SVGLength.h"
 #include "SVGNames.h"
 
@@ -84,20 +85,20 @@ void SVGCircleElement::svgAttributeChanged(const QualifiedName& attrName)
 
     if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
         renderer->setNeedsTransformUpdate();
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
     }
 
     if (isLengthAttribute) {
         renderer->setNeedsPathUpdate();
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
     }
 
     if (SVGTests::isKnownAttribute(attrName)
         || SVGLangSpace::isKnownAttribute(attrName)
         || SVGExternalResourcesRequired::isKnownAttribute(attrName))
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
 }
 
 void SVGCircleElement::synchronizeProperty(const QualifiedName& attrName)
index 5509c2d..963b4b0 100644 (file)
@@ -26,6 +26,7 @@
 #include "Attribute.h"
 #include "FloatPoint.h"
 #include "RenderPath.h"
+#include "RenderSVGResource.h"
 #include "SVGLength.h"
 #include "SVGNames.h"
 
@@ -90,20 +91,20 @@ void SVGEllipseElement::svgAttributeChanged(const QualifiedName& attrName)
 
     if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
         renderer->setNeedsTransformUpdate();
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
     }
 
     if (isLengthAttribute) {
         renderer->setNeedsPathUpdate();
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
     }
 
     if (SVGTests::isKnownAttribute(attrName)
         || SVGLangSpace::isKnownAttribute(attrName)
         || SVGExternalResourcesRequired::isKnownAttribute(attrName))
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
 }
 
 void SVGEllipseElement::synchronizeProperty(const QualifiedName& attrName)
index 84f8734..1f7164f 100644 (file)
@@ -29,6 +29,7 @@
 #include "DocLoader.h"
 #include "Document.h"
 #include "RenderObject.h"
+#include "RenderSVGResource.h"
 #include "SVGLength.h"
 #include "SVGNames.h"
 #include "SVGPreserveAspectRatio.h"
@@ -107,7 +108,16 @@ void SVGFEImageElement::synchronizeProperty(const QualifiedName& attrName)
 
 void SVGFEImageElement::notifyFinished(CachedResource*)
 {
-    SVGStyledElement::invalidateResourcesInAncestorChain();
+    if (!inDocument())
+        return;
+
+    Element* parent = parentElement();
+    ASSERT(parent);
+
+    if (!parent->hasTagName(SVGNames::filterTag) || !parent->renderer())
+        return;
+
+    RenderSVGResource::markForLayoutAndParentResourceInvalidation(parent->renderer());
 }
 
 PassRefPtr<FilterEffect> SVGFEImageElement::build(SVGFilterBuilder*)
index d6bf1cf..7ffe1c6 100644 (file)
@@ -28,6 +28,7 @@
 #include "Attribute.h"
 #include "CSSPropertyNames.h"
 #include "RenderForeignObject.h"
+#include "RenderSVGResource.h"
 #include "SVGLength.h"
 #include "SVGNames.h"
 #include <wtf/Assertions.h>
@@ -90,7 +91,7 @@ void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName)
 
     if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
         renderer->setNeedsTransformUpdate();
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
     }
 
@@ -98,7 +99,7 @@ void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName)
         || SVGTests::isKnownAttribute(attrName)
         || SVGLangSpace::isKnownAttribute(attrName)
         || SVGExternalResourcesRequired::isKnownAttribute(attrName))
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
 }
 
 void SVGForeignObjectElement::synchronizeProperty(const QualifiedName& attrName)
index eceac41..a830096 100644 (file)
@@ -24,6 +24,7 @@
 #include "SVGGElement.h"
 
 #include "RenderSVGHiddenContainer.h"
+#include "RenderSVGResource.h"
 #include "RenderSVGTransformableContainer.h"
 
 namespace WebCore {
@@ -62,14 +63,14 @@ void SVGGElement::svgAttributeChanged(const QualifiedName& attrName)
 
     if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
         renderer->setNeedsTransformUpdate();
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
     }
 
     if (SVGTests::isKnownAttribute(attrName)
         || SVGLangSpace::isKnownAttribute(attrName)
         || SVGExternalResourcesRequired::isKnownAttribute(attrName))
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
 }
 
 void SVGGElement::synchronizeProperty(const QualifiedName& attrName)
index 711e9f3..75f05cf 100644 (file)
@@ -27,6 +27,7 @@
 #include "Attribute.h"
 #include "CSSPropertyNames.h"
 #include "RenderSVGImage.h"
+#include "RenderSVGResource.h"
 #include "SVGDocument.h"
 #include "SVGLength.h"
 #include "SVGPreserveAspectRatio.h"
@@ -105,7 +106,7 @@ void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName)
 
     if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
         renderer->setNeedsTransformUpdate();
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
     }
 
@@ -114,7 +115,7 @@ void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName)
         || SVGTests::isKnownAttribute(attrName)
         || SVGLangSpace::isKnownAttribute(attrName)
         || SVGExternalResourcesRequired::isKnownAttribute(attrName))
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
 }
 
 void SVGImageElement::synchronizeProperty(const QualifiedName& attrName)
index c6e5e04..0898319 100644 (file)
@@ -26,6 +26,7 @@
 #include "Attribute.h"
 #include "FloatPoint.h"
 #include "RenderPath.h"
+#include "RenderSVGResource.h"
 #include "SVGLength.h"
 #include "SVGNames.h"
 
@@ -86,20 +87,20 @@ void SVGLineElement::svgAttributeChanged(const QualifiedName& attrName)
 
     if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
         renderer->setNeedsTransformUpdate();
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
     }
 
     if (isLengthAttribute) {
         renderer->setNeedsPathUpdate();
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
     }
 
     if (SVGTests::isKnownAttribute(attrName)
         || SVGLangSpace::isKnownAttribute(attrName)
         || SVGExternalResourcesRequired::isKnownAttribute(attrName))
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
 }
 
 void SVGLineElement::synchronizeProperty(const QualifiedName& attrName)
index 40996d1..9c9a243 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "Attribute.h"
 #include "RenderPath.h"
+#include "RenderSVGResource.h"
 #include "SVGNames.h"
 #include "SVGParserUtilities.h"
 #include "SVGPathSegArc.h"
@@ -199,13 +200,13 @@ void SVGPathElement::svgAttributeChanged(const QualifiedName& attrName)
 
     if (attrName == SVGNames::dAttr) {
         renderer->setNeedsPathUpdate();
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
     }
 
     if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
         renderer->setNeedsTransformUpdate();
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
     }
 
@@ -213,7 +214,7 @@ void SVGPathElement::svgAttributeChanged(const QualifiedName& attrName)
         || SVGTests::isKnownAttribute(attrName)
         || SVGLangSpace::isKnownAttribute(attrName)
         || SVGExternalResourcesRequired::isKnownAttribute(attrName))
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
 }
 
 void SVGPathElement::synchronizeProperty(const QualifiedName& attrName)
index 6f88b22..2996dd7 100644 (file)
@@ -27,6 +27,7 @@
 #include "Document.h"
 #include "FloatPoint.h"
 #include "RenderPath.h"
+#include "RenderSVGResource.h"
 #include "SVGNames.h"
 #include "SVGParserUtilities.h"
 #include "SVGPointList.h"
@@ -94,20 +95,20 @@ void SVGPolyElement::svgAttributeChanged(const QualifiedName& attrName)
 
     if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
         renderer->setNeedsTransformUpdate();
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
     }
 
     if (attrName == SVGNames::pointsAttr) {
         renderer->setNeedsPathUpdate();
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
     }
 
     if (SVGTests::isKnownAttribute(attrName)
         || SVGLangSpace::isKnownAttribute(attrName)
         || SVGExternalResourcesRequired::isKnownAttribute(attrName))
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
 }
 
 void SVGPolyElement::synchronizeProperty(const QualifiedName& attrName)
index 3e559ed..a848246 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "Attribute.h"
 #include "RenderPath.h"
+#include "RenderSVGResource.h"
 #include "SVGLength.h"
 #include "SVGNames.h"
 
@@ -101,20 +102,20 @@ void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName)
 
     if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
         renderer->setNeedsTransformUpdate();
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
     }
 
     if (isLengthAttribute) {
         renderer->setNeedsPathUpdate();
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
     }
 
     if (SVGTests::isKnownAttribute(attrName)
         || SVGLangSpace::isKnownAttribute(attrName)
         || SVGExternalResourcesRequired::isKnownAttribute(attrName))
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
 }
 
 void SVGRectElement::synchronizeProperty(const QualifiedName& attrName)
index 6d88c37..c513b98 100644 (file)
@@ -35,6 +35,7 @@
 #include "FloatRect.h"
 #include "FrameView.h"
 #include "HTMLNames.h"
+#include "RenderSVGResource.h"
 #include "RenderSVGRoot.h"
 #include "RenderSVGViewportContainer.h"
 #include "SMILTimeContainer.h"
@@ -204,8 +205,8 @@ void SVGSVGElement::setCurrentScale(float scale)
     }
 
     m_scale = scale;
-    if (renderer())
-        renderer()->setNeedsLayout(true);
+    if (RenderObject* object = renderer())
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(object);
 }
 
 FloatPoint SVGSVGElement::currentTranslate() const
@@ -320,7 +321,7 @@ void SVGSVGElement::svgAttributeChanged(const QualifiedName& attrName)
         || SVGExternalResourcesRequired::isKnownAttribute(attrName)
         || SVGZoomAndPan::isKnownAttribute(attrName)
         || SVGStyledLocatableElement::isKnownAttribute(attrName))
-        renderer()->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer());
 }
 
 void SVGSVGElement::synchronizeProperty(const QualifiedName& attrName)
@@ -579,7 +580,9 @@ void SVGSVGElement::inheritViewAttributes(SVGViewElement* viewElement)
 
     if (viewElement->hasAttribute(SVGNames::zoomAndPanAttr))
         currentView()->setZoomAndPan(viewElement->zoomAndPan());
-    renderer()->setNeedsLayout(true);
+    
+    if (RenderObject* object = renderer())
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(object);
 }
     
 void SVGSVGElement::documentWillBecomeInactive()
index 672b082..36d4338 100644 (file)
@@ -26,6 +26,7 @@
 #include "Attribute.h"
 #include "Document.h"
 #include "RenderSVGGradientStop.h"
+#include "RenderSVGResource.h"
 #include "SVGGradientElement.h"
 #include "SVGNames.h"
 
@@ -33,7 +34,7 @@ namespace WebCore {
 
 SVGStopElement::SVGStopElement(const QualifiedName& tagName, Document* doc)
     : SVGStyledElement(tagName, doc)
-    , m_offset(0.0f)
+    , m_offset(0)
 {
 }
 
@@ -53,6 +54,17 @@ void SVGStopElement::parseMappedAttribute(Attribute* attr)
         SVGStyledElement::parseMappedAttribute(attr);
 }
 
+void SVGStopElement::svgAttributeChanged(const QualifiedName& attrName)
+{
+    SVGStyledElement::svgAttributeChanged(attrName);
+
+    if (!renderer())
+        return;
+
+    if (attrName == SVGNames::offsetAttr)
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer());
+}
+
 void SVGStopElement::synchronizeProperty(const QualifiedName& attrName)
 {
     SVGStyledElement::synchronizeProperty(attrName);
index db5eff0..96c3294 100644 (file)
@@ -33,6 +33,7 @@ namespace WebCore {
         virtual ~SVGStopElement();
 
         virtual void parseMappedAttribute(Attribute*);
+        virtual void svgAttributeChanged(const QualifiedName&);
         virtual void synchronizeProperty(const QualifiedName&);
 
         Color stopColorIncludingOpacity() const;
index 6b55683..6c2993c 100644 (file)
@@ -246,14 +246,6 @@ void SVGStyledElement::svgAttributeChanged(const QualifiedName& attrName)
             object->toRenderSVGResourceContainer()->idChanged();
     }
 
-    if (!document()->parsing() && object) {
-        // If we're the child of a resource element, tell the resource (and eventually its resources) that we've changed.
-        invalidateResourcesInAncestorChain();
-
-        // If we're referencing resources, tell them we've changed.
-        RenderSVGResource::invalidateAllResourcesOfRenderer(object);
-    }
-
     // Invalidate all SVGElementInstances associated with us
     SVGElementInstance::invalidateAllInstancesOfElement(this);
 }
@@ -266,27 +258,11 @@ void SVGStyledElement::synchronizeProperty(const QualifiedName& attrName)
         synchronizeClassName();
 }
 
-void SVGStyledElement::invalidateResourcesInAncestorChain() const
-{
-    Node* node = parentNode();
-    while (node) {
-        if (!node->isSVGElement())
-            break;
-
-        SVGElement* element = static_cast<SVGElement*>(node);
-        if (SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(element->isStyled() ? element : 0)) {
-            styledElement->invalidateResourceClients();
-
-            // If we found the first resource in the ancestor chain, immediately stop.
-            break;
-        }
-
-        node = node->parentNode();
-    }
-}
-
 void SVGStyledElement::invalidateResourceClients()
 {
+    if (document()->parsing())
+        return;
+
     RenderObject* object = renderer();
     if (!object)
         return;
index dcfc96a..4982908 100644 (file)
@@ -65,7 +65,6 @@ namespace WebCore {
         PassRefPtr<RenderStyle> resolveStyle(RenderStyle* parentStyle);
 
         void invalidateResourceClients();
-        void invalidateResourcesInAncestorChain() const;
 
         bool instanceUpdatesBlocked() const;
         void setInstanceUpdatesBlocked(bool);
index 4faa633..4c593ca 100644 (file)
@@ -24,6 +24,7 @@
 #include "SVGTRefElement.h"
 
 #include "RenderSVGInline.h"
+#include "RenderSVGResource.h"
 #include "SVGDocument.h"
 #include "SVGNames.h"
 #include "Text.h"
@@ -69,7 +70,7 @@ void SVGTRefElement::svgAttributeChanged(const QualifiedName& attrName)
         return;
 
     if (SVGURIReference::isKnownAttribute(attrName))
-        renderer()->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer());
 }
 
 void SVGTRefElement::synchronizeProperty(const QualifiedName& attrName)
index 0aba04b..7269adf 100644 (file)
@@ -26,6 +26,7 @@
 #include "AffineTransform.h"
 #include "Attribute.h"
 #include "FloatRect.h"
+#include "RenderSVGResource.h"
 #include "RenderSVGText.h"
 #include "SVGLengthList.h"
 #include "SVGRenderStyle.h"
@@ -120,7 +121,7 @@ void SVGTextElement::svgAttributeChanged(const QualifiedName& attrName)
 
     if (SVGTransformable::isKnownAttribute(attrName)) {
         renderer->setNeedsTransformUpdate();
-        renderer->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
     }
 }
 
index 288edfd..732185d 100644 (file)
@@ -25,6 +25,7 @@
 #include "AffineTransform.h"
 #include "Attribute.h"
 #include "FloatRect.h"
+#include "RenderSVGResource.h"
 #include "RenderSVGTextPath.h"
 #include "SVGLengthList.h"
 #include "SVGPathElement.h"
@@ -82,7 +83,7 @@ void SVGTextPathElement::svgAttributeChanged(const QualifiedName& attrName)
     if (attrName == SVGNames::startOffsetAttr
         || SVGTextContentElement::isKnownAttribute(attrName)
         || SVGURIReference::isKnownAttribute(attrName))
-        renderer()->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer());
 }
 
 void SVGTextPathElement::synchronizeProperty(const QualifiedName& attrName)
index ef47322..19f1fbc 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "Attribute.h"
 #include "RenderObject.h"
+#include "RenderSVGResource.h"
 #include "SVGLengthList.h"
 #include "SVGNames.h"
 #include "SVGNumberList.h"
@@ -75,7 +76,7 @@ void SVGTextPositioningElement::svgAttributeChanged(const QualifiedName& attrNam
         return;
 
     if (isKnownAttribute(attrName))
-        renderer()->setNeedsLayout(true);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer());
 }
 
 void SVGTextPositioningElement::synchronizeProperty(const QualifiedName& attrName)
index 5ca560a..e42a794 100644 (file)
@@ -32,6 +32,7 @@
 #include "HTMLNames.h"
 #include "NodeRenderStyle.h"
 #include "RegisteredEventListener.h"
+#include "RenderSVGResource.h"
 #include "RenderSVGShadowTreeRootContainer.h"
 #include "SVGElementInstance.h"
 #include "SVGElementInstanceList.h"
@@ -142,7 +143,8 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
     if (isXYAttribute || isWidthHeightAttribute)
         updateRelativeLengthsInformation();
 
-    if (!renderer())
+    RenderObject* object = renderer();
+    if (!object)
         return;
 
     if (SVGURIReference::isKnownAttribute(attrName)) {
@@ -173,8 +175,8 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
     }
 
     if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
-        renderer()->setNeedsTransformUpdate();
-        renderer()->setNeedsLayout(true);
+        object->setNeedsTransformUpdate();
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(object);
         return;
     }
 
@@ -256,8 +258,8 @@ void SVGUseElement::updateContainerSizes()
     // Update whole subtree, scanning for shadow container elements, that correspond to <svg>/<symbol> tags
     updateContainerSize(this, m_targetElementInstance.get());
 
-    if (renderer())
-        renderer()->setNeedsLayout(true);
+    if (RenderObject* object = renderer())
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(object);
 }
 
 static void updateContainerOffset(SVGElementInstance* targetInstance)
@@ -308,8 +310,8 @@ void SVGUseElement::updateContainerOffsets()
     // Update whole subtree, scanning for shadow container elements, marking a cloned use subtree
     updateContainerOffset(m_targetElementInstance.get());
 
-    if (renderer())
-        renderer()->setNeedsLayout(true);
+    if (RenderObject* object = renderer())
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(object);
 }
 
 void SVGUseElement::recalcStyle(StyleChange change)