Add new renderer for SVGRectElement.
authorreni@webkit.org <reni@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 30 Nov 2011 15:49:02 +0000 (15:49 +0000)
committerreni@webkit.org <reni@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 30 Nov 2011 15:49:02 +0000 (15:49 +0000)
https://bugs.webkit.org/show_bug.cgi?id=65769

Source/WebCore:

Reviewed by Nikolas Zimmermann.

This patch introduces a new common base class called RenderSVGShape which
replaces the RenderSVGPath. This new base class has the same purpose
as the replaced class and has specialized descendants for common
shapes (like Rectangles and Circles), which allows faster painting
of these shapes when certain conditions are fulfilled. On some
benchmark programs we have seen 5% speedup.

The biggest motivation of this refactor is taking advantage
of faster primitive drawing in the most common and frequent
cases. However in some rare cases, like painting rounded
rects, we need to fallback to the original code path, which
is fully kept in the RenderSVGShape base class. Some other
cases, like dashed strokes, can be painted but mouse pointer
events cannot be handled by the descendant classes. A different
fallback mechanism is used in such cases which redirects
only the pointer event handling to the base class.

Tests: svg/custom/pointer-events-on-rounded-rect.xhtml
       svg/custom/pointer-events-with-linecaps-and-miterlimits.xhtml

* CMakeLists.txt:
* GNUmakefile.list.am:
* WebCore.gypi:
* WebCore.pro:
* WebCore.vcproj/WebCore.vcproj:
* platform/graphics/FloatRect.cpp:
(WebCore::FloatRect::contains):
* platform/graphics/FloatRect.h:
(WebCore::FloatRect::contains):
* rendering/RenderObject.h:
(WebCore::RenderObject::isSVGRect):
(WebCore::RenderObject::isSVGShape):
* rendering/RenderTreeAsText.cpp:
(WebCore::write):
* rendering/svg/RenderSVGAllInOne.cpp:
* rendering/svg/RenderSVGModelObject.cpp:
(WebCore::isGraphicsElement):
* rendering/svg/RenderSVGPath.cpp:
(WebCore::RenderSVGPath::RenderSVGPath):
(WebCore::RenderSVGPath::inflateWithStrokeAndMarkerBounds): Unite the markerBounds with strokeBoundingBox.
* rendering/svg/RenderSVGPath.h:
* rendering/svg/RenderSVGRect.cpp: Added.
(WebCore::RenderSVGRect::RenderSVGRect):
(WebCore::RenderSVGRect::~RenderSVGRect):
(WebCore::RenderSVGRect::createShape):
(WebCore::RenderSVGRect::objectBoundingBox):
(WebCore::RenderSVGRect::strokeBoundingBox):
(WebCore::RenderSVGRect::fillShape):
(WebCore::RenderSVGRect::strokeShape):
(WebCore::RenderSVGRect::shapeDependentStrokeContains):
(WebCore::RenderSVGRect::shapeDependentFillContains):
* rendering/svg/RenderSVGRect.h: Added.
(WebCore::RenderSVGRect::isSVGRect):
(WebCore::RenderSVGRect::renderName):
(WebCore::RenderSVGRect::isEmpty):
* rendering/svg/RenderSVGResource.h:
(WebCore::RenderSVGResource::postApplyResource): A new shape argument was added to allow shape specific faster painting.
* rendering/svg/RenderSVGResourceClipper.cpp:
(WebCore::RenderSVGResourceClipper::drawContentIntoMaskImage):
(WebCore::RenderSVGResourceClipper::calculateClipContentRepaintRect):
(WebCore::RenderSVGResourceClipper::hitTestClipContent):
* rendering/svg/RenderSVGResourceContainer.cpp:
(WebCore::RenderSVGResourceContainer::transformOnNonScalingStroke):
* rendering/svg/RenderSVGResourceFilter.cpp:
(WebCore::RenderSVGResourceFilter::postApplyResource):
* rendering/svg/RenderSVGResourceFilter.h:
* rendering/svg/RenderSVGResourceGradient.cpp:
(WebCore::RenderSVGResourceGradient::applyResource):
* rendering/svg/RenderSVGResourceGradient.h:
* rendering/svg/RenderSVGResourcePattern.cpp:
(WebCore::RenderSVGResourcePattern::postApplyResource):
* rendering/svg/RenderSVGResourcePattern.h:
* rendering/svg/RenderSVGResourceSolidColor.cpp:
(WebCore::RenderSVGResourceSolidColor::postApplyResource):
* rendering/svg/RenderSVGResourceSolidColor.h:
* rendering/svg/RenderSVGShape.cpp: Copied from Source/WebCore/rendering/svg/RenderSVGPath.cpp.
(WebCore::RenderSVGShape::RenderSVGShape):
(WebCore::RenderSVGShape::~RenderSVGShape):
(WebCore::RenderSVGShape::createShape):
(WebCore::RenderSVGShape::isEmpty):
(WebCore::RenderSVGShape::fillShape):
(WebCore::RenderSVGShape::objectBoundingBox):
(WebCore::RenderSVGShape::strokeBoundingBox):
(WebCore::RenderSVGShape::strokeShape):
(WebCore::RenderSVGShape::shapeDependentStrokeContains):
The purpose of this virtual function allows decendants to use their own fast checks.
(WebCore::RenderSVGShape::shapeDependentFillContains):
The purpose of this virtual function allows decendants to use their own fast checks.
(WebCore::RenderSVGShape::fillContains):
(WebCore::RenderSVGShape::strokeContains):
(WebCore::RenderSVGShape::layout):
(WebCore::RenderSVGShape::shouldStrokeZeroLengthSubpath):
(WebCore::RenderSVGShape::zeroLengthSubpathRect):
(WebCore::RenderSVGShape::setupSquareCapPath):
(WebCore::RenderSVGShape::setupNonScalingStrokePath):
(WebCore::RenderSVGShape::fillAndStrokePath):
(WebCore::RenderSVGShape::paint):
(WebCore::RenderSVGShape::addFocusRingRects):
(WebCore::RenderSVGShape::nodeAtFloatPoint):
(WebCore::RenderSVGShape::calculateMarkerBoundsIfNeeded):
(WebCore::RenderSVGShape::updateCachedBoundaries):
(WebCore::RenderSVGShape::strokeWidth):
* rendering/svg/RenderSVGShape.h: Copied from Source/WebCore/rendering/svg/RenderSVGPath.h.
(WebCore::BoundingRectStrokeStyleApplier::BoundingRectStrokeStyleApplier):
(WebCore::BoundingRectStrokeStyleApplier::strokeStyle):
(WebCore::RenderSVGShape::setNeedsShapeUpdate):
(WebCore::RenderSVGShape::setNeedsBoundariesUpdate):
(WebCore::RenderSVGShape::setNeedsTransformUpdate):
(WebCore::RenderSVGShape::isPaintingFallback):
(WebCore::RenderSVGShape::path):
(WebCore::RenderSVGShape::setIsPaintingFallback):
(WebCore::RenderSVGShape::setStrokeAndMarkerBoundingBox):
(WebCore::RenderSVGShape::hasPath):
(WebCore::RenderSVGShape::repaintRectInLocalCoordinates):
(WebCore::RenderSVGShape::localToParentTransform):
(WebCore::RenderSVGShape::localTransform):
(WebCore::RenderSVGShape::isSVGShape):
(WebCore::RenderSVGShape::renderName):
(WebCore::RenderSVGShape::isRoundedRect):
(WebCore::RenderSVGShape::inflateWithMarkerBounds):
(WebCore::toRenderSVGShape):
* rendering/svg/SVGInlineTextBox.cpp:
(WebCore::SVGInlineTextBox::releasePaintingResource):
* rendering/svg/SVGRenderSupport.cpp:
(WebCore::SVGRenderSupport::finishRenderSVGContent):
(WebCore::SVGRenderSupport::layoutChildren):
* rendering/svg/SVGRenderTreeAsText.cpp:
(WebCore::writeStyle):
(WebCore::operator<<):
(WebCore::write):
* rendering/svg/SVGRenderTreeAsText.h:
* rendering/svg/SVGTextRunRenderingContext.cpp:
(WebCore::SVGTextRunRenderingContext::drawSVGGlyphs):
* svg/SVGCircleElement.cpp:
(WebCore::SVGCircleElement::svgAttributeChanged):
* svg/SVGEllipseElement.cpp:
(WebCore::SVGEllipseElement::svgAttributeChanged):
* svg/SVGLineElement.cpp:
(WebCore::SVGLineElement::svgAttributeChanged):
* svg/SVGPathElement.cpp:
(WebCore::SVGPathElement::svgAttributeChanged):
(WebCore::SVGPathElement::pathSegListChanged):
(WebCore::SVGPathElement::createRenderer):
* svg/SVGPathElement.h:
* svg/SVGPolyElement.cpp:
(WebCore::SVGPolyElement::svgAttributeChanged):
* svg/SVGRectElement.cpp:
(WebCore::SVGRectElement::svgAttributeChanged):
(WebCore::SVGRectElement::createRenderer):
* svg/SVGRectElement.h:

LayoutTests:

Add new tests to check the new shape based rendering mechanism of SVGRectElement.

Reviewed by Nikolas Zimmermann.

* svg/custom/pointer-events-on-rounded-rect-expected.txt: Added.
* svg/custom/pointer-events-on-rounded-rect.xhtml: Added.
* svg/custom/pointer-events-with-linecaps-and-miterlimits-expected.txt: Added.
* svg/custom/pointer-events-with-linecaps-and-miterlimits.xhtml: Added.

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

51 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/mac-snowleopard/svg/W3C-SVG-1.1/coords-units-02-b-expected.png
LayoutTests/platform/mac/svg/custom/percentage-rect-expected.png
LayoutTests/svg/custom/pointer-events-on-rounded-rect-expected.txt [new file with mode: 0644]
LayoutTests/svg/custom/pointer-events-on-rounded-rect.xhtml [new file with mode: 0644]
LayoutTests/svg/custom/pointer-events-with-linecaps-and-miterlimits-expected.txt [new file with mode: 0644]
LayoutTests/svg/custom/pointer-events-with-linecaps-and-miterlimits.xhtml [new file with mode: 0644]
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/Target.pri
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.vcproj/WebCore.vcproj
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/platform/graphics/FloatRect.cpp
Source/WebCore/platform/graphics/FloatRect.h
Source/WebCore/rendering/RenderObject.h
Source/WebCore/rendering/RenderTreeAsText.cpp
Source/WebCore/rendering/svg/RenderSVGAllInOne.cpp
Source/WebCore/rendering/svg/RenderSVGModelObject.cpp
Source/WebCore/rendering/svg/RenderSVGPath.cpp [changed mode: 0644->0755]
Source/WebCore/rendering/svg/RenderSVGPath.h [changed mode: 0644->0755]
Source/WebCore/rendering/svg/RenderSVGRect.cpp [new file with mode: 0755]
Source/WebCore/rendering/svg/RenderSVGRect.h [new file with mode: 0644]
Source/WebCore/rendering/svg/RenderSVGResource.h
Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp
Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp
Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
Source/WebCore/rendering/svg/RenderSVGResourceFilter.h
Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp
Source/WebCore/rendering/svg/RenderSVGResourceGradient.h
Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp
Source/WebCore/rendering/svg/RenderSVGResourcePattern.h
Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.cpp
Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.h
Source/WebCore/rendering/svg/RenderSVGShape.cpp [new file with mode: 0755]
Source/WebCore/rendering/svg/RenderSVGShape.h [new file with mode: 0755]
Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
Source/WebCore/rendering/svg/SVGRenderSupport.cpp
Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp [changed mode: 0644->0755]
Source/WebCore/rendering/svg/SVGRenderTreeAsText.h
Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp
Source/WebCore/svg/SVGCircleElement.cpp
Source/WebCore/svg/SVGEllipseElement.cpp
Source/WebCore/svg/SVGLengthContext.cpp [changed mode: 0644->0755]
Source/WebCore/svg/SVGLineElement.cpp
Source/WebCore/svg/SVGPathElement.cpp
Source/WebCore/svg/SVGPathElement.h
Source/WebCore/svg/SVGPolyElement.cpp
Source/WebCore/svg/SVGRectElement.cpp
Source/WebCore/svg/SVGRectElement.h

index dda3b6f..f1ac622 100644 (file)
@@ -1,3 +1,17 @@
+2011-11-30  Renata Hodovan  <reni@webkit.org>
+
+        Add new renderer for SVGRectElement.
+        https://bugs.webkit.org/show_bug.cgi?id=65769
+
+        Add new tests to check the new shape based rendering mechanism of SVGRectElement.
+
+        Reviewed by Nikolas Zimmermann.
+
+        * svg/custom/pointer-events-on-rounded-rect-expected.txt: Added.
+        * svg/custom/pointer-events-on-rounded-rect.xhtml: Added.
+        * svg/custom/pointer-events-with-linecaps-and-miterlimits-expected.txt: Added.
+        * svg/custom/pointer-events-with-linecaps-and-miterlimits.xhtml: Added.
+
 2011-11-30  Philippe Normand  <pnormand@igalia.com>
 
         Unreviewed, GTK rebaseline of some of the previously unskipped
index 17f50eb..1c6228b 100644 (file)
Binary files a/LayoutTests/platform/mac-snowleopard/svg/W3C-SVG-1.1/coords-units-02-b-expected.png and b/LayoutTests/platform/mac-snowleopard/svg/W3C-SVG-1.1/coords-units-02-b-expected.png differ
index b8d71d4..fd209db 100644 (file)
Binary files a/LayoutTests/platform/mac/svg/custom/percentage-rect-expected.png and b/LayoutTests/platform/mac/svg/custom/percentage-rect-expected.png differ
diff --git a/LayoutTests/svg/custom/pointer-events-on-rounded-rect-expected.txt b/LayoutTests/svg/custom/pointer-events-on-rounded-rect-expected.txt
new file mode 100644 (file)
index 0000000..615bae0
--- /dev/null
@@ -0,0 +1 @@
+PASSED: fallbackRect had pointer
diff --git a/LayoutTests/svg/custom/pointer-events-on-rounded-rect.xhtml b/LayoutTests/svg/custom/pointer-events-on-rounded-rect.xhtml
new file mode 100644 (file)
index 0000000..c63d122
--- /dev/null
@@ -0,0 +1,66 @@
+<html xmlns='http://www.w3.org/1999/xhtml'>
+<body style="margin: 0px; padding: 0px">
+
+<svg xmlns="http://www.w3.org/2000/svg" style="position:absolute;">
+<defs>
+
+<style type="text/css"><![CDATA[
+rect#roundedRect {
+    fill: none;
+    stroke: green;
+    stroke-width: 20px;
+    stroke-linejoin: bevel;
+}
+rect:hover {
+    stroke: red;
+}
+]]></style>
+</defs>
+
+<rect id="fallback" x="30" y="30" width="420" height="320" fill="yellow" onclick="passed()"/>
+<rect id="roundedRect" x="40" y="40" rx="30" ry="30" width="400" height="300" pointer-events="visibleStroke" onclick="failed()"/>
+<text id="text" x="30" y="370"></text>
+
+<script type="text/ecmascript">
+    <![CDATA[
+
+var fallback = document.getElementById("fallback");
+var roundedRect = document.getElementById("roundedRect");
+var text = document.getElementById("text");
+
+    fallback.addEventListener("mousedown", passed, false);
+    roundedRect.addEventListener("mousedown", failed, false);
+
+function stop() {
+    fallback.removeEventListener("mousedown", failed, false);
+    roundedRect.removeEventListener("mousedown", passed, false);
+
+    if (window.layoutTestController)
+    layoutTestController.notifyDone();
+}
+
+function failed() {
+    text.textContent = 'FAILED: strokeRect had pointer';
+    stop();
+}
+
+function passed() {
+   text.textContent = 'PASSED: fallbackRect had pointer';
+   stop();
+}
+
+if (window.layoutTestController) {
+   layoutTestController.waitUntilDone();
+   layoutTestController.dumpAsText();
+}
+
+if (window.eventSender) {
+    eventSender.mouseMoveTo(31, 31);
+    eventSender.mouseDown();
+}
+]]>
+</script>
+
+</svg>
+</body>
+</html>
\ No newline at end of file
diff --git a/LayoutTests/svg/custom/pointer-events-with-linecaps-and-miterlimits-expected.txt b/LayoutTests/svg/custom/pointer-events-with-linecaps-and-miterlimits-expected.txt
new file mode 100644 (file)
index 0000000..615bae0
--- /dev/null
@@ -0,0 +1 @@
+PASSED: fallbackRect had pointer
diff --git a/LayoutTests/svg/custom/pointer-events-with-linecaps-and-miterlimits.xhtml b/LayoutTests/svg/custom/pointer-events-with-linecaps-and-miterlimits.xhtml
new file mode 100644 (file)
index 0000000..9226b70
--- /dev/null
@@ -0,0 +1,68 @@
+<html xmlns='http://www.w3.org/1999/xhtml'>
+<body style="margin: 0px; padding: 0px">
+
+<svg xmlns="http://www.w3.org/2000/svg" style="position:absolute;">
+<defs>
+
+<style type="text/css"><![CDATA[
+rect#strokedRect {
+    fill: none;
+    stroke: blue;
+    stroke-width: 20px;
+    stroke-linecap: square;
+    stroke-miterlimit: 1;
+}
+rect#strokedRect:hover {
+    stroke: red;
+}
+]]></style>
+</defs>
+
+<rect id="fallback" x="0" y="0" width="210" height="210" fill="green" onclick="passed()"/>
+<rect id="strokedRect" x="10" y="10" width="190" height="190" pointer-events="visibleStroke" onclick="failed()"/>
+<text id="text" x="0" y="230"></text>
+
+<script type="text/ecmascript">
+    <![CDATA[
+
+var fallback = document.getElementById("fallback");
+var strokedRect = document.getElementById("strokedRect");
+var text = document.getElementById("text");
+
+fallback.addEventListener("mousedown", passed, false);
+strokedRect.addEventListener("mousedown", failed, false);
+
+function stop() {
+    fallback.removeEventListener("mousedown", failed, false);
+    strokedRect.removeEventListener("mousedown", passed, false);
+
+if (window.layoutTestController)
+    layoutTestController.notifyDone();
+}
+
+function failed() {
+    text.textContent = 'FAILED: strokeRect had pointer';
+    stop();
+}
+
+function passed() {
+    text.textContent = 'PASSED: fallbackRect had pointer';
+    stop();
+}
+
+if (window.layoutTestController) {
+    layoutTestController.waitUntilDone();
+    layoutTestController.dumpAsText();
+}
+
+if (window.eventSender) {
+    eventSender.mouseMoveTo(1, 1);
+    eventSender.mouseDown();
+}
+
+]]>
+</script>
+</svg>
+
+</body>
+</html>
index d80714b..3f4463f 100644 (file)
@@ -1618,6 +1618,7 @@ IF (ENABLE_SVG)
         rendering/svg/RenderSVGInlineText.cpp
         rendering/svg/RenderSVGModelObject.cpp
         rendering/svg/RenderSVGPath.cpp
+        rendering/svg/RenderSVGRect.cpp
         rendering/svg/RenderSVGResource.cpp
         rendering/svg/RenderSVGResourceClipper.cpp
         rendering/svg/RenderSVGResourceContainer.cpp
@@ -1632,6 +1633,7 @@ IF (ENABLE_SVG)
         rendering/svg/RenderSVGResourceSolidColor.cpp
         rendering/svg/RenderSVGRoot.cpp
         rendering/svg/RenderSVGShadowTreeRootContainer.cpp
+        rendering/svg/RenderSVGShape.cpp
         rendering/svg/RenderSVGTSpan.cpp
         rendering/svg/RenderSVGText.cpp
         rendering/svg/RenderSVGTextPath.cpp
index 3a1a537..792d366 100644 (file)
@@ -1,3 +1,161 @@
+2011-11-30  Renata Hodovan  <reni@webkit.org>
+
+        Add new renderer for SVGRectElement.
+        https://bugs.webkit.org/show_bug.cgi?id=65769
+
+        Reviewed by Nikolas Zimmermann.
+
+        This patch introduces a new common base class called RenderSVGShape which
+        replaces the RenderSVGPath. This new base class has the same purpose
+        as the replaced class and has specialized descendants for common
+        shapes (like Rectangles and Circles), which allows faster painting
+        of these shapes when certain conditions are fulfilled. On some
+        benchmark programs we have seen 5% speedup.
+
+        The biggest motivation of this refactor is taking advantage
+        of faster primitive drawing in the most common and frequent
+        cases. However in some rare cases, like painting rounded
+        rects, we need to fallback to the original code path, which
+        is fully kept in the RenderSVGShape base class. Some other
+        cases, like dashed strokes, can be painted but mouse pointer
+        events cannot be handled by the descendant classes. A different
+        fallback mechanism is used in such cases which redirects
+        only the pointer event handling to the base class.
+
+        Tests: svg/custom/pointer-events-on-rounded-rect.xhtml
+               svg/custom/pointer-events-with-linecaps-and-miterlimits.xhtml
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * WebCore.gypi:
+        * WebCore.pro:
+        * WebCore.vcproj/WebCore.vcproj:
+        * platform/graphics/FloatRect.cpp:
+        (WebCore::FloatRect::contains):
+        * platform/graphics/FloatRect.h:
+        (WebCore::FloatRect::contains):
+        * rendering/RenderObject.h:
+        (WebCore::RenderObject::isSVGRect):
+        (WebCore::RenderObject::isSVGShape):
+        * rendering/RenderTreeAsText.cpp:
+        (WebCore::write):
+        * rendering/svg/RenderSVGAllInOne.cpp:
+        * rendering/svg/RenderSVGModelObject.cpp:
+        (WebCore::isGraphicsElement):
+        * rendering/svg/RenderSVGPath.cpp:
+        (WebCore::RenderSVGPath::RenderSVGPath):
+        (WebCore::RenderSVGPath::inflateWithStrokeAndMarkerBounds): Unite the markerBounds with strokeBoundingBox.
+        * rendering/svg/RenderSVGPath.h:
+        * rendering/svg/RenderSVGRect.cpp: Added.
+        (WebCore::RenderSVGRect::RenderSVGRect):
+        (WebCore::RenderSVGRect::~RenderSVGRect):
+        (WebCore::RenderSVGRect::createShape):
+        (WebCore::RenderSVGRect::objectBoundingBox):
+        (WebCore::RenderSVGRect::strokeBoundingBox):
+        (WebCore::RenderSVGRect::fillShape):
+        (WebCore::RenderSVGRect::strokeShape):
+        (WebCore::RenderSVGRect::shapeDependentStrokeContains):
+        (WebCore::RenderSVGRect::shapeDependentFillContains):
+        * rendering/svg/RenderSVGRect.h: Added.
+        (WebCore::RenderSVGRect::isSVGRect):
+        (WebCore::RenderSVGRect::renderName):
+        (WebCore::RenderSVGRect::isEmpty):
+        * rendering/svg/RenderSVGResource.h:
+        (WebCore::RenderSVGResource::postApplyResource): A new shape argument was added to allow shape specific faster painting.
+        * rendering/svg/RenderSVGResourceClipper.cpp:
+        (WebCore::RenderSVGResourceClipper::drawContentIntoMaskImage):
+        (WebCore::RenderSVGResourceClipper::calculateClipContentRepaintRect):
+        (WebCore::RenderSVGResourceClipper::hitTestClipContent):
+        * rendering/svg/RenderSVGResourceContainer.cpp:
+        (WebCore::RenderSVGResourceContainer::transformOnNonScalingStroke):
+        * rendering/svg/RenderSVGResourceFilter.cpp:
+        (WebCore::RenderSVGResourceFilter::postApplyResource):
+        * rendering/svg/RenderSVGResourceFilter.h:
+        * rendering/svg/RenderSVGResourceGradient.cpp:
+        (WebCore::RenderSVGResourceGradient::applyResource):
+        * rendering/svg/RenderSVGResourceGradient.h:
+        * rendering/svg/RenderSVGResourcePattern.cpp:
+        (WebCore::RenderSVGResourcePattern::postApplyResource):
+        * rendering/svg/RenderSVGResourcePattern.h:
+        * rendering/svg/RenderSVGResourceSolidColor.cpp:
+        (WebCore::RenderSVGResourceSolidColor::postApplyResource):
+        * rendering/svg/RenderSVGResourceSolidColor.h:
+        * rendering/svg/RenderSVGShape.cpp: Copied from Source/WebCore/rendering/svg/RenderSVGPath.cpp.
+        (WebCore::RenderSVGShape::RenderSVGShape):
+        (WebCore::RenderSVGShape::~RenderSVGShape):
+        (WebCore::RenderSVGShape::createShape):
+        (WebCore::RenderSVGShape::isEmpty):
+        (WebCore::RenderSVGShape::fillShape):
+        (WebCore::RenderSVGShape::objectBoundingBox):
+        (WebCore::RenderSVGShape::strokeBoundingBox):
+        (WebCore::RenderSVGShape::strokeShape):
+        (WebCore::RenderSVGShape::shapeDependentStrokeContains):
+        The purpose of this virtual function allows decendants to use their own fast checks.
+        (WebCore::RenderSVGShape::shapeDependentFillContains):
+        The purpose of this virtual function allows decendants to use their own fast checks.
+        (WebCore::RenderSVGShape::fillContains):
+        (WebCore::RenderSVGShape::strokeContains):
+        (WebCore::RenderSVGShape::layout):
+        (WebCore::RenderSVGShape::shouldStrokeZeroLengthSubpath):
+        (WebCore::RenderSVGShape::zeroLengthSubpathRect):
+        (WebCore::RenderSVGShape::setupSquareCapPath):
+        (WebCore::RenderSVGShape::setupNonScalingStrokePath):
+        (WebCore::RenderSVGShape::fillAndStrokePath):
+        (WebCore::RenderSVGShape::paint):
+        (WebCore::RenderSVGShape::addFocusRingRects):
+        (WebCore::RenderSVGShape::nodeAtFloatPoint):
+        (WebCore::RenderSVGShape::calculateMarkerBoundsIfNeeded):
+        (WebCore::RenderSVGShape::updateCachedBoundaries):
+        (WebCore::RenderSVGShape::strokeWidth):
+        * rendering/svg/RenderSVGShape.h: Copied from Source/WebCore/rendering/svg/RenderSVGPath.h.
+        (WebCore::BoundingRectStrokeStyleApplier::BoundingRectStrokeStyleApplier):
+        (WebCore::BoundingRectStrokeStyleApplier::strokeStyle):
+        (WebCore::RenderSVGShape::setNeedsShapeUpdate):
+        (WebCore::RenderSVGShape::setNeedsBoundariesUpdate):
+        (WebCore::RenderSVGShape::setNeedsTransformUpdate):
+        (WebCore::RenderSVGShape::isPaintingFallback):
+        (WebCore::RenderSVGShape::path):
+        (WebCore::RenderSVGShape::setIsPaintingFallback):
+        (WebCore::RenderSVGShape::setStrokeAndMarkerBoundingBox):
+        (WebCore::RenderSVGShape::hasPath):
+        (WebCore::RenderSVGShape::repaintRectInLocalCoordinates):
+        (WebCore::RenderSVGShape::localToParentTransform):
+        (WebCore::RenderSVGShape::localTransform):
+        (WebCore::RenderSVGShape::isSVGShape):
+        (WebCore::RenderSVGShape::renderName):
+        (WebCore::RenderSVGShape::isRoundedRect):
+        (WebCore::RenderSVGShape::inflateWithMarkerBounds):
+        (WebCore::toRenderSVGShape):
+        * rendering/svg/SVGInlineTextBox.cpp:
+        (WebCore::SVGInlineTextBox::releasePaintingResource):
+        * rendering/svg/SVGRenderSupport.cpp:
+        (WebCore::SVGRenderSupport::finishRenderSVGContent):
+        (WebCore::SVGRenderSupport::layoutChildren):
+        * rendering/svg/SVGRenderTreeAsText.cpp:
+        (WebCore::writeStyle):
+        (WebCore::operator<<):
+        (WebCore::write):
+        * rendering/svg/SVGRenderTreeAsText.h:
+        * rendering/svg/SVGTextRunRenderingContext.cpp:
+        (WebCore::SVGTextRunRenderingContext::drawSVGGlyphs):
+        * svg/SVGCircleElement.cpp:
+        (WebCore::SVGCircleElement::svgAttributeChanged):
+        * svg/SVGEllipseElement.cpp:
+        (WebCore::SVGEllipseElement::svgAttributeChanged):
+        * svg/SVGLineElement.cpp:
+        (WebCore::SVGLineElement::svgAttributeChanged):
+        * svg/SVGPathElement.cpp:
+        (WebCore::SVGPathElement::svgAttributeChanged):
+        (WebCore::SVGPathElement::pathSegListChanged):
+        (WebCore::SVGPathElement::createRenderer):
+        * svg/SVGPathElement.h:
+        * svg/SVGPolyElement.cpp:
+        (WebCore::SVGPolyElement::svgAttributeChanged):
+        * svg/SVGRectElement.cpp:
+        (WebCore::SVGRectElement::svgAttributeChanged):
+        (WebCore::SVGRectElement::createRenderer):
+        * svg/SVGRectElement.h:
+
 2011-11-30  Adam Roben  <aroben@apple.com>
 
         Another Clang build fix after r101507
index d420c56..9761094 100644 (file)
@@ -3329,6 +3329,8 @@ webcore_sources += \
        Source/WebCore/rendering/svg/RenderSVGModelObject.h \
        Source/WebCore/rendering/svg/RenderSVGPath.cpp \
        Source/WebCore/rendering/svg/RenderSVGPath.h \
+       Source/WebCore/rendering/svg/RenderSVGRect.cpp \
+       Source/WebCore/rendering/svg/RenderSVGRect.h \
        Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp \
        Source/WebCore/rendering/svg/RenderSVGResourceClipper.h \
        Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp \
@@ -3357,6 +3359,8 @@ webcore_sources += \
        Source/WebCore/rendering/svg/RenderSVGRoot.h \
        Source/WebCore/rendering/svg/RenderSVGShadowTreeRootContainer.cpp \
        Source/WebCore/rendering/svg/RenderSVGShadowTreeRootContainer.h \
+       Source/WebCore/rendering/svg/RenderSVGShape.cpp \
+       Source/WebCore/rendering/svg/RenderSVGShape.h \
        Source/WebCore/rendering/svg/RenderSVGTSpan.cpp \
        Source/WebCore/rendering/svg/RenderSVGTSpan.h \
        Source/WebCore/rendering/svg/RenderSVGText.cpp \
index ce1137e..cb3ee63 100644 (file)
@@ -2397,6 +2397,7 @@ HEADERS += \
     rendering/svg/RenderSVGInlineText.h \
     rendering/svg/RenderSVGModelObject.h \
     rendering/svg/RenderSVGPath.h \
+    rendering/svg/RenderSVGRect.h \
     rendering/svg/RenderSVGResource.h \
     rendering/svg/RenderSVGResourceClipper.h \
     rendering/svg/RenderSVGResourceContainer.h \
@@ -2411,6 +2412,7 @@ HEADERS += \
     rendering/svg/RenderSVGResourceSolidColor.h \
     rendering/svg/RenderSVGRoot.h \
     rendering/svg/RenderSVGShadowTreeRootContainer.h \
+    rendering/svg/RenderSVGShape.h \
     rendering/svg/RenderSVGTSpan.h \
     rendering/svg/RenderSVGText.h \
     rendering/svg/RenderSVGTextPath.h \
@@ -3321,6 +3323,8 @@ contains(DEFINES, ENABLE_SVG=1) {
         rendering/style/SVGRenderStyleDefs.cpp \
         rendering/PointerEventsHitRules.cpp \
         rendering/svg/RenderSVGPath.cpp \
+        rendering/svg/RenderSVGRect.cpp \
+        rendering/svg/RenderSVGShape.cpp \
         svg/animation/SMILTime.cpp \
         svg/animation/SMILTimeContainer.cpp \
         svg/animation/SVGSMILElement.cpp \
index 23749af..01f9a4d 100644 (file)
             'rendering/svg/RenderSVGModelObject.h',
             'rendering/svg/RenderSVGPath.cpp',
             'rendering/svg/RenderSVGPath.h',
+            'rendering/svg/RenderSVGRect.cpp',
+            'rendering/svg/RenderSVGRect.h',
             'rendering/svg/RenderSVGResource.cpp',
             'rendering/svg/RenderSVGResource.h',
             'rendering/svg/RenderSVGResourceClipper.cpp',
             'rendering/svg/RenderSVGRoot.h',
             'rendering/svg/RenderSVGShadowTreeRootContainer.cpp',
             'rendering/svg/RenderSVGShadowTreeRootContainer.h',
+            'rendering/svg/RenderSVGShape.cpp',
+            'rendering/svg/RenderSVGShape.h',
             'rendering/svg/RenderSVGTSpan.cpp',
             'rendering/svg/RenderSVGTSpan.h',
             'rendering/svg/RenderSVGText.cpp',
index 7a3144c..28bdb93 100755 (executable)
                                        >
                                </File>
                                <File
+                                       RelativePath="..\rendering\svg\RenderSVGRect.cpp"
+                                       >
+                                       <FileConfiguration
+                                               Name="Debug|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                                       <FileConfiguration
+                                               Name="Release|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                                       <FileConfiguration
+                                               Name="Debug_Cairo_CFLite|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                                       <FileConfiguration
+                                               Name="Release_Cairo_CFLite|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                                       <FileConfiguration
+                                               Name="Debug_All|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                                       <FileConfiguration
+                                               Name="Production|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                               </File>
+                               <File
+                                       RelativePath="..\rendering\svg\RenderSVGRect.h"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\rendering\svg\RenderSVGShape.cpp"
+                                       >
+                                       <FileConfiguration
+                                               Name="Debug|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                                       <FileConfiguration
+                                               Name="Release|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                                       <FileConfiguration
+                                               Name="Debug_Cairo_CFLite|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                                       <FileConfiguration
+                                               Name="Release_Cairo_CFLite|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                                       <FileConfiguration
+                                               Name="Debug_All|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                                       <FileConfiguration
+                                               Name="Production|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                               </File>
+                               <File
+                                       RelativePath="..\rendering\svg\RenderSVGShape.h"
+                                       >
+                               </File>
+                               <File
                                        RelativePath="..\rendering\svg\RenderSVGText.cpp"
                                        >
                                        <FileConfiguration
index d08cfa4..b92a270 100644 (file)
                A0EE0DF6144F825500F80B0D /* WebGLDebugRendererInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = A0EE0DF2144F825500F80B0D /* WebGLDebugRendererInfo.h */; };
                A0EE0DF7144F825500F80B0D /* WebGLDebugShaders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A0EE0DF3144F825500F80B0D /* WebGLDebugShaders.cpp */; };
                A0EE0DF8144F825500F80B0D /* WebGLDebugShaders.h in Headers */ = {isa = PBXBuildFile; fileRef = A0EE0DF4144F825500F80B0D /* WebGLDebugShaders.h */; };
+               A10BB5851484E3A700B2E87A /* RenderSVGRect.h in Headers */ = {isa = PBXBuildFile; fileRef = A10BB5831484E3A700B2E87A /* RenderSVGRect.h */; };
+               A10BB58B1484E3B300B2E87A /* RenderSVGShape.h in Headers */ = {isa = PBXBuildFile; fileRef = A10BB5891484E3B300B2E87A /* RenderSVGShape.h */; };
                A10DC76A14747BAB005E2471 /* StyleGridData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A10DC76814747BAB005E2471 /* StyleGridData.cpp */; };
                A10DC76B14747BAB005E2471 /* StyleGridData.h in Headers */ = {isa = PBXBuildFile; fileRef = A10DC76914747BAB005E2471 /* StyleGridData.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A120ACA413F998CA00FE4AC7 /* LayoutRepainter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A120ACA113F9984600FE4AC7 /* LayoutRepainter.cpp */; };
                A0EE0DF2144F825500F80B0D /* WebGLDebugRendererInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebGLDebugRendererInfo.h; path = canvas/WebGLDebugRendererInfo.h; sourceTree = "<group>"; };
                A0EE0DF3144F825500F80B0D /* WebGLDebugShaders.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebGLDebugShaders.cpp; path = canvas/WebGLDebugShaders.cpp; sourceTree = "<group>"; };
                A0EE0DF4144F825500F80B0D /* WebGLDebugShaders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebGLDebugShaders.h; path = canvas/WebGLDebugShaders.h; sourceTree = "<group>"; };
+               A10BB5821484E3A700B2E87A /* RenderSVGRect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGRect.cpp; sourceTree = "<group>"; };
+               A10BB5831484E3A700B2E87A /* RenderSVGRect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGRect.h; sourceTree = "<group>"; };
+               A10BB5881484E3B300B2E87A /* RenderSVGShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGShape.cpp; sourceTree = "<group>"; };
+               A10BB5891484E3B300B2E87A /* RenderSVGShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGShape.h; sourceTree = "<group>"; };
                A10DC76814747BAB005E2471 /* StyleGridData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StyleGridData.cpp; path = style/StyleGridData.cpp; sourceTree = "<group>"; };
                A10DC76914747BAB005E2471 /* StyleGridData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StyleGridData.h; path = style/StyleGridData.h; sourceTree = "<group>"; };
                A120ACA013F9983700FE4AC7 /* LayoutRepainter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LayoutRepainter.h; sourceTree = "<group>"; };
                                4367088C12D9CA4A00044234 /* RenderSVGModelObject.h */,
                                ADDF1AD41257CD9A0003A759 /* RenderSVGPath.cpp */,
                                ADDF1AD51257CD9A0003A759 /* RenderSVGPath.h */,
+                               A10BB5821484E3A700B2E87A /* RenderSVGRect.cpp */,
+                               A10BB5831484E3A700B2E87A /* RenderSVGRect.h */,
                                4367088D12D9CA4A00044234 /* RenderSVGResource.cpp */,
                                4367088E12D9CA4A00044234 /* RenderSVGResource.h */,
                                4367088F12D9CA4A00044234 /* RenderSVGResourceClipper.cpp */,
                                436708A612D9CA4B00044234 /* RenderSVGRoot.h */,
                                436708A712D9CA4B00044234 /* RenderSVGShadowTreeRootContainer.cpp */,
                                436708A812D9CA4B00044234 /* RenderSVGShadowTreeRootContainer.h */,
+                               A10BB5881484E3B300B2E87A /* RenderSVGShape.cpp */,
+                               A10BB5891484E3B300B2E87A /* RenderSVGShape.h */,
                                0854B0061255E4E600B9CDD0 /* RenderSVGText.cpp */,
                                0854B0071255E4E600B9CDD0 /* RenderSVGText.h */,
                                0854B0081255E4E600B9CDD0 /* RenderSVGTextPath.cpp */,
                                0854B0171255E4E600B9CDD0 /* RenderSVGInlineText.h in Headers */,
                                436708CB12D9CA4B00044234 /* RenderSVGModelObject.h in Headers */,
                                ADDF1AD71257CD9A0003A759 /* RenderSVGPath.h in Headers */,
+                               A10BB5851484E3A700B2E87A /* RenderSVGRect.h in Headers */,
                                436708CD12D9CA4B00044234 /* RenderSVGResource.h in Headers */,
                                436708CF12D9CA4B00044234 /* RenderSVGResourceClipper.h in Headers */,
                                436708D112D9CA4B00044234 /* RenderSVGResourceContainer.h in Headers */,
                                436708E312D9CA4B00044234 /* RenderSVGResourceSolidColor.h in Headers */,
                                436708E512D9CA4B00044234 /* RenderSVGRoot.h in Headers */,
                                436708E712D9CA4B00044234 /* RenderSVGShadowTreeRootContainer.h in Headers */,
+                               A10BB58B1484E3B300B2E87A /* RenderSVGShape.h in Headers */,
                                0854B0191255E4E600B9CDD0 /* RenderSVGText.h in Headers */,
                                0854B01B1255E4E600B9CDD0 /* RenderSVGTextPath.h in Headers */,
                                436708E912D9CA4B00044234 /* RenderSVGTransformableContainer.h in Headers */,
index b84a892..6d4a220 100644 (file)
@@ -68,6 +68,13 @@ bool FloatRect::contains(const FloatRect& other) const
         && y() <= other.y() && maxY() >= other.maxY();
 }
 
+bool FloatRect::contains(const FloatPoint& point, ContainsMode containsMode) const
+{
+    if (containsMode == InsideOrOnStroke)
+        return contains(point.x(), point.y());
+    return x() < point.x() && maxX() > point.x() && y() < point.y() && maxY() > y();
+}
+
 void FloatRect::intersect(const FloatRect& other)
 {
     float l = max(x(), other.x());
index 4241716..7de346f 100644 (file)
@@ -70,6 +70,11 @@ class IntPoint;
 
 class FloatRect {
 public:
+    enum ContainsMode {
+        InsideOrOnStroke,
+        InsideButNotOnStroke
+    };
+
     FloatRect() { }
     FloatRect(const FloatPoint& location, const FloatSize& size)
         : m_location(location), m_size(size) { }
@@ -142,6 +147,7 @@ public:
 
     bool intersects(const FloatRect&) const;
     bool contains(const FloatRect&) const;
+    bool contains(const FloatPoint&, ContainsMode = InsideOrOnStroke) const;
 
     void intersect(const FloatRect&);
     void unite(const FloatRect&);
@@ -151,7 +157,6 @@ public:
     // is really checking for containment of 1x1 rect, but that doesn't make sense with floats.
     bool contains(float px, float py) const
         { return px >= x() && px <= maxX() && py >= y() && py <= maxY(); }
-    bool contains(const FloatPoint& point) const { return contains(point.x(), point.y()); }
 
     void inflateX(float dx) {
         m_location.setX(m_location.x() - dx);
index 00b2bbf..0c5d3c4 100644 (file)
@@ -389,6 +389,8 @@ public:
     virtual bool isSVGGradientStop() const { return false; }
     virtual bool isSVGHiddenContainer() const { return false; }
     virtual bool isSVGPath() const { return false; }
+    virtual bool isSVGRect() const { return false; }
+    virtual bool isSVGShape() const { return false; }
     virtual bool isSVGText() const { return false; }
     virtual bool isSVGTextPath() const { return false; }
     virtual bool isSVGInline() const { return false; }
index 275e9b5..7c1f93f 100644 (file)
@@ -516,8 +516,8 @@ static void writeTextRun(TextStream& ts, const RenderText& o, const InlineTextBo
 void write(TextStream& ts, const RenderObject& o, int indent, RenderAsTextBehavior behavior)
 {
 #if ENABLE(SVG)
-    if (o.isSVGPath()) {
-        write(ts, *toRenderSVGPath(&o), indent);
+    if (o.isSVGShape()) {
+        write(ts, *toRenderSVGShape(&o), indent);
         return;
     }
     if (o.isSVGGradientStop()) {
index 3424288..8fd3c51 100644 (file)
@@ -35,6 +35,7 @@
 #include "RenderSVGInlineText.cpp"
 #include "RenderSVGModelObject.cpp"
 #include "RenderSVGPath.cpp"
+#include "RenderSVGRect.cpp"
 #include "RenderSVGResource.cpp"
 #include "RenderSVGResourceClipper.cpp"
 #include "RenderSVGResourceContainer.cpp"
@@ -49,6 +50,7 @@
 #include "RenderSVGResourceSolidColor.cpp"
 #include "RenderSVGRoot.cpp"
 #include "RenderSVGShadowTreeRootContainer.cpp"
+#include "RenderSVGShape.cpp"
 #include "RenderSVGTSpan.cpp"
 #include "RenderSVGText.cpp"
 #include "RenderSVGTextPath.cpp"
index d8b1121..68cc1ff 100644 (file)
@@ -158,7 +158,7 @@ static bool intersectsAllowingEmpty(const FloatRect& r, const FloatRect& other)
 // image, line, path, polygon, polyline, rect, text and use.
 static bool isGraphicsElement(RenderObject* renderer)
 {
-    return renderer->isSVGPath() || renderer->isSVGText() || renderer->isSVGImage() || renderer->isSVGShadowTreeRootContainer();
+    return renderer->isSVGShape() || renderer->isSVGText() || renderer->isSVGImage() || renderer->isSVGShadowTreeRootContainer();
 }
 
 bool RenderSVGModelObject::checkIntersection(RenderObject* renderer, const FloatRect& rect)
old mode 100644 (file)
new mode 100755 (executable)
index 3eaad97..edad439
@@ -6,6 +6,8 @@
  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
  * Copyright (C) 2009 Jeff Schiller <codedread@gmail.com>
+ * Copyright (C) 2011 Renata Hodovan <reni@webkit.org>
+ * Copyright (C) 2011 University of Szeged
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 #if ENABLE(SVG)
 #include "RenderSVGPath.h"
 
-#include "FloatPoint.h"
-#include "FloatQuad.h"
-#include "GraphicsContext.h"
-#include "HitTestRequest.h"
-#include "LayoutRepainter.h"
-#include "PointerEventsHitRules.h"
-#include "RenderSVGContainer.h"
-#include "RenderSVGResourceMarker.h"
-#include "RenderSVGResourceSolidColor.h"
-#include "SVGPathData.h"
-#include "SVGRenderSupport.h"
-#include "SVGResources.h"
-#include "SVGResourcesCache.h"
+#include "SVGPathElement.h"
 #include "SVGStyledTransformableElement.h"
-#include "SVGTransformList.h"
-#include "SVGURIReference.h"
-#include "StrokeStyleApplier.h"
-#include <wtf/MathExtras.h>
 
 namespace WebCore {
 
-class BoundingRectStrokeStyleApplier : public StrokeStyleApplier {
-public:
-    BoundingRectStrokeStyleApplier(const RenderObject* object, RenderStyle* style)
-        : m_object(object)
-        , m_style(style)
-    {
-        ASSERT(style);
-        ASSERT(object);
-    }
-
-    void strokeStyle(GraphicsContext* gc)
-    {
-        SVGRenderSupport::applyStrokeStyleToContext(gc, m_style, m_object);
-    }
-
-private:
-    const RenderObject* m_object;
-    RenderStyle* m_style;
-};
-
 RenderSVGPath::RenderSVGPath(SVGStyledTransformableElement* node)
-    : RenderSVGModelObject(node)
-    , m_needsBoundariesUpdate(false) // default is false, the cached rects are empty from the beginning
-    , m_needsPathUpdate(true) // default is true, so we grab a Path object once from SVGStyledTransformableElement
-    , m_needsTransformUpdate(true) // default is true, so we grab a AffineTransform object once from SVGStyledTransformableElement
+    : RenderSVGShape(node)
 {
 }
 
@@ -81,318 +44,6 @@ RenderSVGPath::~RenderSVGPath()
 {
 }
 
-bool RenderSVGPath::fillContains(const FloatPoint& point, bool requiresFill, WindRule fillRule)
-{
-    if (!m_fillBoundingBox.contains(point))
-        return false;
-
-    Color fallbackColor;
-    if (requiresFill && !RenderSVGResource::fillPaintingResource(this, style(), fallbackColor))
-        return false;
-
-    return m_path.contains(point, fillRule);
-}
-
-bool RenderSVGPath::strokeContains(const FloatPoint& point, bool requiresStroke)
-{
-    if (!m_strokeAndMarkerBoundingBox.contains(point))
-        return false;
-
-    Color fallbackColor;
-    if (requiresStroke && !RenderSVGResource::strokePaintingResource(this, style(), fallbackColor))
-        return false;
-
-    if (shouldStrokeZeroLengthSubpath())
-        return zeroLengthSubpathRect().contains(point);
-
-    BoundingRectStrokeStyleApplier strokeStyle(this, style());
-    return m_path.strokeContains(&strokeStyle, point);
-}
-
-void RenderSVGPath::layout()
-{
-    LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && selfNeedsLayout());
-    SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
-
-    bool updateCachedBoundariesInParents = false;
-
-    bool needsPathUpdate = m_needsPathUpdate;
-    if (needsPathUpdate) {
-        m_path.clear();
-        updatePathFromGraphicsElement(element, m_path);
-        m_needsPathUpdate = false;
-        updateCachedBoundariesInParents = true;
-    }
-
-    if (m_needsTransformUpdate) {
-        m_localTransform = element->animatedLocalTransform();
-        m_needsTransformUpdate = false;
-        updateCachedBoundariesInParents = true;
-    }
-
-    if (m_needsBoundariesUpdate)
-        updateCachedBoundariesInParents = true;
-
-    // Invalidate all resources of this client if our layout changed.
-    if (m_everHadLayout && selfNeedsLayout()) {
-        SVGResourcesCache::clientLayoutChanged(this);
-        m_markerLayoutInfo.clear();
-    }
-
-    // At this point LayoutRepainter already grabbed the old bounds,
-    // recalculate them now so repaintAfterLayout() uses the new bounds.
-    if (needsPathUpdate || m_needsBoundariesUpdate) {
-        updateCachedBoundaries();
-        m_needsBoundariesUpdate = false;
-    }
-
-    // If our bounds changed, notify the parents.
-    if (updateCachedBoundariesInParents)
-        RenderSVGModelObject::setNeedsBoundariesUpdate();
-
-    repainter.repaintAfterLayout();
-    setNeedsLayout(false);
-}
-
-bool RenderSVGPath::shouldStrokeZeroLengthSubpath() const
-{
-    // Spec(11.4): Any zero length subpath shall not be stroked if the ‘stroke-linecap’ property has a value of butt
-    // but shall be stroked if the ‘stroke-linecap’ property has a value of round or square
-    return style()->svgStyle()->hasStroke() && style()->svgStyle()->capStyle() != ButtCap && !m_fillBoundingBox.width() && !m_fillBoundingBox.height();
-}
-
-FloatRect RenderSVGPath::zeroLengthSubpathRect() const
-{
-    SVGElement* svgElement = static_cast<SVGElement*>(node());
-    SVGLengthContext lengthContext(svgElement);
-    float strokeWidth = style()->svgStyle()->strokeWidth().value(lengthContext);
-    return FloatRect(m_fillBoundingBox.x() - strokeWidth / 2, m_fillBoundingBox.y() - strokeWidth / 2, strokeWidth, strokeWidth);
-}
-
-void RenderSVGPath::setupSquareCapPath(Path*& usePath, int& applyMode)
-{
-    // Spec(11.4): Any zero length subpath shall not be stroked if the ‘stroke-linecap’ property has a value of butt
-    // but shall be stroked if the ‘stroke-linecap’ property has a value of round or square
-    DEFINE_STATIC_LOCAL(Path, tempPath, ());
-
-    applyMode = ApplyToFillMode;
-    usePath = &tempPath;
-    usePath->clear();
-    if (style()->svgStyle()->capStyle() == SquareCap)
-        usePath->addRect(zeroLengthSubpathRect());
-    else
-        usePath->addEllipse(zeroLengthSubpathRect());
-}
-
-bool RenderSVGPath::setupNonScalingStrokePath(Path*& usePath, GraphicsContextStateSaver& stateSaver)
-{
-    DEFINE_STATIC_LOCAL(Path, tempPath, ());
-
-    SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
-    AffineTransform nonScalingStrokeTransform = element->getScreenCTM(SVGLocatable::DisallowStyleUpdate);
-    if (!nonScalingStrokeTransform.isInvertible())
-        return false;
-
-    tempPath = m_path;
-    usePath = &tempPath;
-    tempPath.transform(nonScalingStrokeTransform);
-
-    stateSaver.save();
-    stateSaver.context()->concatCTM(nonScalingStrokeTransform.inverse());
-    return true;
-}
-
-void RenderSVGPath::fillAndStrokePath(GraphicsContext* context)
-{
-    RenderStyle* style = this->style();
-
-    Color fallbackColor;
-    if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(this, style, fallbackColor)) {
-        if (fillPaintingResource->applyResource(this, style, context, ApplyToFillMode))
-            fillPaintingResource->postApplyResource(this, context, ApplyToFillMode, &m_path);
-        else if (fallbackColor.isValid()) {
-            RenderSVGResourceSolidColor* fallbackResource = RenderSVGResource::sharedSolidPaintingResource();
-            fallbackResource->setColor(fallbackColor);
-            if (fallbackResource->applyResource(this, style, context, ApplyToFillMode))
-                fallbackResource->postApplyResource(this, context, ApplyToFillMode, &m_path);
-        }
-    }
-
-    fallbackColor = Color();
-    RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(this, style, fallbackColor);
-    if (!strokePaintingResource)
-        return;
-
-    Path* usePath = &m_path;
-    int applyMode = ApplyToStrokeMode;
-
-    bool nonScalingStroke = style->svgStyle()->vectorEffect() == VE_NON_SCALING_STROKE;
-
-    GraphicsContextStateSaver stateSaver(*context, false);
-
-    // Spec(11.4): Any zero length subpath shall not be stroked if the ‘stroke-linecap’ property has a value of butt
-    // but shall be stroked if the ‘stroke-linecap’ property has a value of round or square
-    // FIXME: this does not work for zero-length subpaths, only when total path is zero-length
-    if (shouldStrokeZeroLengthSubpath())
-        setupSquareCapPath(usePath, applyMode);
-    else if (nonScalingStroke) {
-       if (!setupNonScalingStrokePath(usePath, stateSaver))
-           return;
-    }
-
-    if (strokePaintingResource->applyResource(this, style, context, applyMode))
-        strokePaintingResource->postApplyResource(this, context, applyMode, usePath);
-    else if (fallbackColor.isValid()) {
-        RenderSVGResourceSolidColor* fallbackResource = RenderSVGResource::sharedSolidPaintingResource();
-        fallbackResource->setColor(fallbackColor);
-        if (fallbackResource->applyResource(this, style, context, applyMode))
-            fallbackResource->postApplyResource(this, context, applyMode, usePath);
-    }
-}
-
-void RenderSVGPath::paint(PaintInfo& paintInfo, const LayoutPoint&)
-{
-    if (paintInfo.context->paintingDisabled() || style()->visibility() == HIDDEN || m_path.isEmpty())
-        return;
-
-    FloatRect boundingBox = repaintRectInLocalCoordinates();
-    if (!SVGRenderSupport::paintInfoIntersectsRepaintRect(boundingBox, m_localTransform, paintInfo))
-        return;
-
-    PaintInfo childPaintInfo(paintInfo);
-    bool drawsOutline = style()->outlineWidth() && (childPaintInfo.phase == PaintPhaseOutline || childPaintInfo.phase == PaintPhaseSelfOutline);
-    if (drawsOutline || childPaintInfo.phase == PaintPhaseForeground) {
-        GraphicsContextStateSaver stateSaver(*childPaintInfo.context);
-        childPaintInfo.applyTransform(m_localTransform);
-
-        if (childPaintInfo.phase == PaintPhaseForeground) {
-            PaintInfo savedInfo(childPaintInfo);
-
-            if (SVGRenderSupport::prepareToRenderSVGContent(this, childPaintInfo)) {
-                const SVGRenderStyle* svgStyle = style()->svgStyle();
-                if (svgStyle->shapeRendering() == SR_CRISPEDGES)
-                    childPaintInfo.context->setShouldAntialias(false);
-
-                fillAndStrokePath(childPaintInfo.context);
-
-                if (svgStyle->hasMarkers())
-                    m_markerLayoutInfo.drawMarkers(childPaintInfo);
-            }
-
-            SVGRenderSupport::finishRenderSVGContent(this, childPaintInfo, savedInfo.context);
-        }
-
-        if (drawsOutline)
-            paintOutline(childPaintInfo.context, IntRect(boundingBox));
-    }
-}
-
-// This method is called from inside paintOutline() since we call paintOutline()
-// while transformed to our coord system, return local coords
-void RenderSVGPath::addFocusRingRects(Vector<LayoutRect>& rects, const LayoutPoint&) 
-{
-    LayoutRect rect = enclosingLayoutRect(repaintRectInLocalCoordinates());
-    if (!rect.isEmpty())
-        rects.append(rect);
-}
-
-bool RenderSVGPath::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
-{
-    // We only draw in the forground phase, so we only hit-test then.
-    if (hitTestAction != HitTestForeground)
-        return false;
-
-    FloatPoint localPoint = m_localTransform.inverse().mapPoint(pointInParent);
-
-    if (!SVGRenderSupport::pointInClippingArea(this, localPoint))
-        return false;
-
-    PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_PATH_HITTESTING, request, style()->pointerEvents());
-    bool isVisible = (style()->visibility() == VISIBLE);
-    if (isVisible || !hitRules.requireVisible) {
-        const SVGRenderStyle* svgStyle = style()->svgStyle();
-        WindRule fillRule = svgStyle->fillRule();
-        if (request.svgClipContent())
-            fillRule = svgStyle->clipRule();
-        if ((hitRules.canHitStroke && (svgStyle->hasStroke() || !hitRules.requireStroke) && strokeContains(localPoint, hitRules.requireStroke))
-            || (hitRules.canHitFill && (svgStyle->hasFill() || !hitRules.requireFill) && fillContains(localPoint, hitRules.requireFill, fillRule))) {
-            updateHitTestResult(result, roundedLayoutPoint(localPoint));
-            return true;
-        }
-    }
-    return false;
-}
-
-FloatRect RenderSVGPath::calculateMarkerBoundsIfNeeded()
-{
-    SVGElement* svgElement = static_cast<SVGElement*>(node());
-    ASSERT(svgElement && svgElement->document());
-    if (!svgElement->isStyled())
-        return FloatRect();
-
-    SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(svgElement);
-    if (!styledElement->supportsMarkers())
-        return FloatRect();
-
-    const SVGRenderStyle* svgStyle = style()->svgStyle();
-    ASSERT(svgStyle->hasMarkers());
-
-    SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this);
-    if (!resources)
-        return FloatRect();
-
-    RenderSVGResourceMarker* markerStart = resources->markerStart();
-    RenderSVGResourceMarker* markerMid = resources->markerMid();
-    RenderSVGResourceMarker* markerEnd = resources->markerEnd();
-    if (!markerStart && !markerMid && !markerEnd)
-        return FloatRect();
-
-    SVGLengthContext lengthContext(svgElement);
-    return m_markerLayoutInfo.calculateBoundaries(markerStart, markerMid, markerEnd, svgStyle->strokeWidth().value(lengthContext), m_path);
-}
-
-void RenderSVGPath::updateCachedBoundaries()
-{
-    if (m_path.isEmpty()) {
-        m_fillBoundingBox = FloatRect();
-        m_strokeAndMarkerBoundingBox = FloatRect();
-        m_repaintBoundingBox = FloatRect();
-        return;
-    }
-
-    // Cache _unclipped_ fill bounding box, used for calculations in resources
-    m_fillBoundingBox = m_path.fastBoundingRect();
-
-    // Spec(11.4): Any zero length subpath shall not be stroked if the ‘stroke-linecap’ property has a value of butt
-    // but shall be stroked if the ‘stroke-linecap’ property has a value of round or square
-    if (shouldStrokeZeroLengthSubpath()) {
-        m_strokeAndMarkerBoundingBox = zeroLengthSubpathRect();
-        // Cache smallest possible repaint rectangle
-        m_repaintBoundingBox = m_strokeAndMarkerBoundingBox;
-        SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingBox);
-        return;
-    }
-
-    // Cache _unclipped_ stroke bounding box, used for calculations in resources (includes marker boundaries)
-    m_strokeAndMarkerBoundingBox = m_fillBoundingBox;
-
-    const SVGRenderStyle* svgStyle = style()->svgStyle();
-    if (svgStyle->hasStroke()) {
-        BoundingRectStrokeStyleApplier strokeStyle(this, style());
-        m_strokeAndMarkerBoundingBox.unite(m_path.strokeBoundingRect(&strokeStyle));
-    }
-
-    if (svgStyle->hasMarkers()) {
-        FloatRect markerBounds = calculateMarkerBoundsIfNeeded();
-        if (!markerBounds.isEmpty())
-            m_strokeAndMarkerBoundingBox.unite(markerBounds);
-    }
-
-    // Cache smallest possible repaint rectangle
-    m_repaintBoundingBox = m_strokeAndMarkerBoundingBox;
-    SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingBox);
-}
-
 }
 
 #endif // ENABLE(SVG)
old mode 100644 (file)
new mode 100755 (executable)
index 98e608d..77e99e5
@@ -4,6 +4,8 @@
  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
  * Copyright (C) 2006 Apple Computer, Inc
  * Copyright (C) 2009 Google, Inc.
+ * Copyright (C) 2011 Renata Hodovan <reni@webkit.org>
+ * Copyright (C) 2011 University of Szeged
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 #define RenderSVGPath_h
 
 #if ENABLE(SVG)
-#include "AffineTransform.h"
-#include "FloatRect.h"
-#include "RenderSVGModelObject.h"
-#include "SVGMarkerLayoutInfo.h"
+#include "RenderSVGShape.h"
 
 namespace WebCore {
 
-class FloatPoint;
-class GraphicsContextStateSaver;
-class RenderSVGContainer;
-class SVGStyledTransformableElement;
-
-class RenderSVGPath : public RenderSVGModelObject {
+class RenderSVGPath : public RenderSVGShape {
 public:
     explicit RenderSVGPath(SVGStyledTransformableElement*);
     virtual ~RenderSVGPath();
 
-    const Path& path() const { return m_path; }
-    void setNeedsPathUpdate() { m_needsPathUpdate = true; }
-    virtual void setNeedsBoundariesUpdate() { m_needsBoundariesUpdate = true; }
-    virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
-
 private:
-    // Hit-detection seperated for the fill and the stroke
-    bool fillContains(const FloatPoint&, bool requiresFill = true, WindRule fillRule = RULE_NONZERO);
-    bool strokeContains(const FloatPoint&, bool requiresStroke = true);
-
-    virtual FloatRect objectBoundingBox() const { return m_fillBoundingBox; }
-    virtual FloatRect strokeBoundingBox() const { return m_strokeAndMarkerBoundingBox; }
-    virtual FloatRect repaintRectInLocalCoordinates() const { return m_repaintBoundingBox; }
-    virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
-
     virtual bool isSVGPath() const { return true; }
     virtual const char* renderName() const { return "RenderSVGPath"; }
-
-    virtual void layout();
-    virtual void paint(PaintInfo&, const LayoutPoint&);
-    virtual void addFocusRingRects(Vector<LayoutRect>&, const LayoutPoint&);
-
-    virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
-
-    FloatRect calculateMarkerBoundsIfNeeded();
-    void updateCachedBoundaries();
-
-    void setupSquareCapPath(Path*& usePath, int& applyMode);
-    bool setupNonScalingStrokePath(Path*& usePath, GraphicsContextStateSaver&);
-    bool shouldStrokeZeroLengthSubpath() const;
-    FloatRect zeroLengthSubpathRect() const;
-
-private:
-    virtual AffineTransform localTransform() const { return m_localTransform; }
-    void fillAndStrokePath(GraphicsContext*);
-
-    bool m_needsBoundariesUpdate : 1;
-    bool m_needsPathUpdate : 1;
-    bool m_needsTransformUpdate : 1;
-
-    mutable Path m_path;
-    FloatRect m_fillBoundingBox;
-    FloatRect m_strokeAndMarkerBoundingBox;
-    FloatRect m_repaintBoundingBox;
-    SVGMarkerLayoutInfo m_markerLayoutInfo;
-    AffineTransform m_localTransform;
 };
 
-inline RenderSVGPath* toRenderSVGPath(RenderObject* object)
-{
-    ASSERT(!object || object->isSVGPath());
-    return static_cast<RenderSVGPath*>(object);
-}
-
-inline const RenderSVGPath* toRenderSVGPath(const RenderObject* object)
-{
-    ASSERT(!object || object->isSVGPath());
-    return static_cast<const RenderSVGPath*>(object);
-}
-
-// This will catch anyone doing an unnecessary cast.
-void toRenderSVGPath(const RenderSVGPath*);
-
 }
 
 #endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGRect.cpp b/Source/WebCore/rendering/svg/RenderSVGRect.cpp
new file mode 100755 (executable)
index 0000000..8d585c5
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2011 University of Szeged
+ * Copyright (C) 2011 Renata Hodovan <reni@webkit.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(SVG)
+#include "RenderSVGRect.h"
+
+#include "SVGNames.h"
+#include "SVGRectElement.h"
+#include <wtf/Platform.h>
+
+namespace WebCore {
+
+RenderSVGRect::RenderSVGRect(SVGRectElement* node)
+    : RenderSVGShape(node)
+{
+}
+
+RenderSVGRect::~RenderSVGRect()
+{
+}
+
+void RenderSVGRect::createShape()
+{
+    // Before creating a new object we need to clear the cached bounding box
+    // to avoid using garbage.
+    m_boundingBox = FloatRect();
+    m_innerStrokeRect = FloatRect();
+    m_outerStrokeRect = FloatRect();
+    SVGRectElement* rect = static_cast<SVGRectElement*>(node());
+    ASSERT(rect);
+
+    bool nonScalingStroke = style()->svgStyle()->vectorEffect() == VE_NON_SCALING_STROKE;
+    // Fallback to RenderSVGShape if rect has rounded corners.
+    if (rect->hasAttribute(SVGNames::rxAttr) || rect->hasAttribute(SVGNames::ryAttr) || nonScalingStroke) {
+       RenderSVGShape::createShape();
+       setIsPaintingFallback(true);
+       return;
+    }
+
+    SVGLengthContext lengthContext(rect);
+    FloatSize boundingBoxSize(rect->width().value(lengthContext), rect->height().value(lengthContext));
+    if (boundingBoxSize.isEmpty())
+        return;
+
+    m_boundingBox = FloatRect(FloatPoint(rect->x().value(lengthContext), rect->y().value(lengthContext)), boundingBoxSize);
+
+    // To decide if the stroke contains a point we create two rects which represent the inner and
+    // the outer stroke borders. A stroke contains the point, if the point is between them.
+    m_innerStrokeRect = m_boundingBox;
+    m_outerStrokeRect = m_boundingBox;
+
+    if (style()->svgStyle()->hasStroke()) {
+        float strokeWidth = this->strokeWidth();
+        m_innerStrokeRect.inflate(-strokeWidth / 2);
+        m_outerStrokeRect.inflate(strokeWidth / 2);
+    }
+}
+
+FloatRect RenderSVGRect::objectBoundingBox() const
+{
+    if (isPaintingFallback())
+        return RenderSVGShape::objectBoundingBox();
+    return m_boundingBox;
+}
+
+FloatRect RenderSVGRect::strokeBoundingBox() const
+{
+    if (isPaintingFallback())
+        return RenderSVGShape::strokeBoundingBox();
+    return m_outerStrokeRect;
+}
+
+void RenderSVGRect::fillShape(GraphicsContext* context) const
+{
+    if (!isPaintingFallback()) {
+#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(MAC_OS_X))
+        // FIXME: CG implementation of GraphicsContextCG::fillRect has an own
+        // shadow drawing method, which draws an extra shadow.
+        // This is a workaround for switching off the extra shadow.
+        // https://bugs.webkit.org/show_bug.cgi?id=68899
+        if (context->hasShadow()) {
+            GraphicsContextStateSaver stateSaver(*context);
+            context->clearShadow();
+            context->fillRect(m_boundingBox);
+            return;
+        }
+#endif
+        context->fillRect(m_boundingBox);
+        return;
+    }
+    RenderSVGShape::fillShape(context);
+}
+
+void RenderSVGRect::strokeShape(GraphicsContext* context) const
+{
+    if (!isPaintingFallback()) {
+        context->strokeRect(m_boundingBox, strokeWidth());
+        return;
+    }
+    RenderSVGShape::strokeShape(context);
+}
+
+bool RenderSVGRect::shapeDependentStrokeContains(const FloatPoint& point) const
+{
+    return m_outerStrokeRect.contains(point, FloatRect::InsideOrOnStroke) && !m_innerStrokeRect.contains(point, FloatRect::InsideButNotOnStroke);
+}
+
+bool RenderSVGRect::shapeDependentFillContains(const FloatPoint& point, const WindRule fillRule) const
+{
+    if (isPaintingFallback())
+        return RenderSVGShape::shapeDependentFillContains(point, fillRule);
+    return m_boundingBox.contains(point.x(), point.y());
+}
+
+}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGRect.h b/Source/WebCore/rendering/svg/RenderSVGRect.h
new file mode 100644 (file)
index 0000000..48ef29f
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011 University of Szeged
+ * Copyright (C) 2011 Renata Hodovan <reni@webkit.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RenderSVGRect_h
+#define RenderSVGRect_h
+
+#if ENABLE(SVG)
+#include "RenderSVGPath.h"
+#include "SVGRectElement.h"
+
+namespace WebCore {
+
+class RenderSVGRect : public RenderSVGShape {
+public:
+    explicit RenderSVGRect(SVGRectElement*);
+    virtual ~RenderSVGRect();
+
+private:
+    virtual bool isSVGRect() const { return true; }
+    virtual const char* renderName() const { return "RenderSVGPath"; }
+
+    virtual void createShape();
+    virtual bool isEmpty() const { return hasPath() ? RenderSVGShape::isEmpty() : m_boundingBox.isEmpty(); };
+    virtual void fillShape(GraphicsContext*) const;
+    virtual void strokeShape(GraphicsContext*) const;
+    virtual FloatRect objectBoundingBox() const;
+    virtual FloatRect strokeBoundingBox() const;
+    virtual bool shapeDependentStrokeContains(const FloatPoint&) const;
+    virtual bool shapeDependentFillContains(const FloatPoint&, const WindRule) const;
+
+private:
+    FloatRect m_boundingBox;
+    FloatRect m_innerStrokeRect;
+    FloatRect m_outerStrokeRect;
+};
+
+}
+
+#endif // ENABLE(SVG)
+#endif
index a67ba73..e020154 100644 (file)
@@ -21,6 +21,7 @@
 #define RenderSVGResource_h
 
 #if ENABLE(SVG)
+#include "RenderSVGShape.h"
 #include "RenderStyleConstants.h"
 #include "SVGDocumentExtensions.h"
 
@@ -61,7 +62,7 @@ public:
     virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true) = 0;
 
     virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode) = 0;
-    virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short, const Path*) { }
+    virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short, const Path*, const RenderSVGShape*) { }
     virtual FloatRect resourceBoundingBox(RenderObject*) = 0;
 
     virtual RenderSVGResourceType resourceType() const = 0;
index 77aaae5..5d500f0 100644 (file)
@@ -246,7 +246,7 @@ bool RenderSVGResourceClipper::drawContentIntoMaskImage(ClipperData* clipperData
         }
 
         // Only shapes, paths and texts are allowed for clipping.
-        if (!renderer->isSVGPath() && !renderer->isSVGText())
+        if (!renderer->isSVGShape() && !renderer->isSVGText())
             continue;
 
         // Save the old RenderStyle of the current object for restoring after drawing
@@ -288,7 +288,7 @@ void RenderSVGResourceClipper::calculateClipContentRepaintRect()
         RenderObject* renderer = childNode->renderer();
         if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyled() || !renderer)
             continue;
-        if (!renderer->isSVGPath() && !renderer->isSVGText() && !renderer->isSVGShadowTreeRootContainer())
+        if (!renderer->isSVGShape() && !renderer->isSVGText() && !renderer->isSVGShadowTreeRootContainer())
             continue;
         RenderStyle* style = renderer->style();
         if (!style || style->display() == NONE || style->visibility() != VISIBLE)
@@ -318,7 +318,7 @@ bool RenderSVGResourceClipper::hitTestClipContent(const FloatRect& objectBoundin
         RenderObject* renderer = childNode->renderer();
         if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyled() || !renderer)
             continue;
-        if (!renderer->isSVGPath() && !renderer->isSVGText() && !renderer->isSVGShadowTreeRootContainer())
+        if (!renderer->isSVGShape() && !renderer->isSVGText() && !renderer->isSVGShadowTreeRootContainer())
             continue;
         IntPoint hitPoint;
         HitTestResult result(hitPoint);
index 29d35e9..ada6913 100644 (file)
@@ -184,7 +184,7 @@ void RenderSVGResourceContainer::registerResource()
 // FIXME: This does not belong here.
 AffineTransform RenderSVGResourceContainer::transformOnNonScalingStroke(RenderObject* object, const AffineTransform& resourceTransform)
 {
-    if (!object->isSVGPath())
+    if (!object->isSVGShape())
         return resourceTransform;
 
     SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(object->node());
index 01a205e..14ddf81 100644 (file)
@@ -256,7 +256,7 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,
     return true;
 }
 
-void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsContext*& context, unsigned short resourceMode, const Path*)
+void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsContext*& context, unsigned short resourceMode, const Path*, const RenderSVGShape*)
 {
     ASSERT(object);
     ASSERT(context);
@@ -286,7 +286,7 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo
     }
 
     FilterEffect* lastEffect = filterData->builder->lastEffect();
-    
+
     if (lastEffect && !filterData->boundaries.isEmpty() && !lastEffect->filterPrimitiveSubregion().isEmpty()) {
         // This is the real filtering of the object. It just needs to be called on the
         // initial filtering process. We just take the stored filter result on a
index 9ad7c7a..93bb6b3 100644 (file)
@@ -72,7 +72,7 @@ public:
     virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
 
     virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
-    virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode, const Path*);
+    virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode, const Path*, const RenderSVGShape*);
 
     virtual FloatRect resourceBoundingBox(RenderObject*);
 
index 9069934..437b186 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "GradientAttributes.h"
 #include "GraphicsContext.h"
+#include "RenderSVGShape.h"
 #include "RenderSVGText.h"
 #include "SVGImageBufferTools.h"
 #include "SVGRenderSupport.h"
@@ -231,7 +232,7 @@ bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle*
     return true;
 }
 
-void RenderSVGResourceGradient::postApplyResource(RenderObject* object, GraphicsContext*& context, unsigned short resourceMode, const Path* path)
+void RenderSVGResourceGradient::postApplyResource(RenderObject* object, GraphicsContext*& context, unsigned short resourceMode, const Path* path, const RenderSVGShape* shape)
 {
     ASSERT(context);
     ASSERT(resourceMode != ApplyToDefaultMode);
@@ -259,11 +260,19 @@ void RenderSVGResourceGradient::postApplyResource(RenderObject* object, Graphics
 #else
         UNUSED_PARAM(object);
 #endif
-    } else if (path) {
-        if (resourceMode & ApplyToFillMode)
-            context->fillPath(*path);
-        else if (resourceMode & ApplyToStrokeMode)
-            context->strokePath(*path);
+    } else {
+        if (resourceMode & ApplyToFillMode) {
+            if (path)
+                context->fillPath(*path);
+            else if (shape)
+                shape->fillShape(context);
+        }
+        if (resourceMode & ApplyToStrokeMode) {
+            if (path)
+                context->strokePath(*path);
+            else if (shape)
+                shape->strokeShape(context);
+        }
     }
 
     context->restore();
index c9fd936..b7e780c 100644 (file)
@@ -50,7 +50,7 @@ public:
     virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
 
     virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
-    virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode, const Path*);
+    virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode, const Path*, const RenderSVGShape*);
     virtual FloatRect resourceBoundingBox(RenderObject*) { return FloatRect(); }
 
 protected:
index 5dc15b6..4d09e11 100644 (file)
@@ -188,16 +188,22 @@ bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle*
     return true;
 }
 
-void RenderSVGResourcePattern::postApplyResource(RenderObject*, GraphicsContext*& context, unsigned short resourceMode, const Path* path)
+void RenderSVGResourcePattern::postApplyResource(RenderObject*, GraphicsContext*& context, unsigned short resourceMode, const Path* path, const RenderSVGShape* shape)
 {
     ASSERT(context);
     ASSERT(resourceMode != ApplyToDefaultMode);
 
-    if (path && !(resourceMode & ApplyToTextMode)) {
-        if (resourceMode & ApplyToFillMode)
+    if (resourceMode & ApplyToFillMode) {
+        if (path)
             context->fillPath(*path);
-        else if (resourceMode & ApplyToStrokeMode)
+        else if (shape)
+            shape->fillShape(context);
+    }
+    if (resourceMode & ApplyToStrokeMode) {
+        if (path)
             context->strokePath(*path);
+        else if (shape)
+            shape->strokeShape(context);
     }
 
     context->restore();
index 9e86486..4049242 100644 (file)
@@ -52,7 +52,7 @@ public:
     virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
 
     virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
-    virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode, const Path*);
+    virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode, const Path*, const RenderSVGShape*);
     virtual FloatRect resourceBoundingBox(RenderObject*) { return FloatRect(); }
 
     virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
index 5be2af6..63df751 100644 (file)
@@ -23,6 +23,7 @@
 #include "RenderSVGResourceSolidColor.h"
 
 #include "GraphicsContext.h"
+#include "RenderSVGShape.h"
 #include "RenderStyle.h"
 #include "SVGRenderSupport.h"
 
@@ -74,16 +75,22 @@ bool RenderSVGResourceSolidColor::applyResource(RenderObject* object, RenderStyl
     return true;
 }
 
-void RenderSVGResourceSolidColor::postApplyResource(RenderObject*, GraphicsContext*& context, unsigned short resourceMode, const Path* path)
+void RenderSVGResourceSolidColor::postApplyResource(RenderObject*, GraphicsContext*& context, unsigned short resourceMode, const Path* path, const RenderSVGShape* shape)
 {
     ASSERT(context);
     ASSERT(resourceMode != ApplyToDefaultMode);
 
-    if (path && !(resourceMode & ApplyToTextMode)) {
-        if (resourceMode & ApplyToFillMode)
+    if (resourceMode & ApplyToFillMode) {
+        if (path)
             context->fillPath(*path);
-        else if (resourceMode & ApplyToStrokeMode)
+        else if (shape)
+            shape->fillShape(context);
+    }
+    if (resourceMode & ApplyToStrokeMode) {
+        if (path)
             context->strokePath(*path);
+        else if (shape)
+            shape->strokeShape(context);
     }
 }
 
index 02ceb31..8bbfdcd 100644 (file)
@@ -36,7 +36,7 @@ public:
     virtual void removeClientFromCache(RenderObject*, bool = true) { }
 
     virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
-    virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode, const Path*);
+    virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode, const Path*, const RenderSVGShape*);
     virtual FloatRect resourceBoundingBox(RenderObject*) { return FloatRect(); }
 
     virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
diff --git a/Source/WebCore/rendering/svg/RenderSVGShape.cpp b/Source/WebCore/rendering/svg/RenderSVGShape.cpp
new file mode 100755 (executable)
index 0000000..ef2d3f4
--- /dev/null
@@ -0,0 +1,461 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005, 2008 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005, 2007 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Google, Inc.
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2009 Jeff Schiller <codedread@gmail.com>
+ * Copyright (C) 2011 Renata Hodovan <reni@webkit.org>
+ * Copyright (C) 2011 University of Szeged
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(SVG)
+#include "RenderSVGShape.h"
+
+#include "FloatPoint.h"
+#include "FloatQuad.h"
+#include "GraphicsContext.h"
+#include "HitTestRequest.h"
+#include "LayoutRepainter.h"
+#include "PointerEventsHitRules.h"
+#include "RenderSVGContainer.h"
+#include "RenderSVGResourceMarker.h"
+#include "RenderSVGResourceSolidColor.h"
+#include "SVGPathData.h"
+#include "SVGPathElement.h"
+#include "SVGRenderSupport.h"
+#include "SVGResources.h"
+#include "SVGResourcesCache.h"
+#include "SVGStyledTransformableElement.h"
+#include "SVGTransformList.h"
+#include "SVGURIReference.h"
+#include "StrokeStyleApplier.h"
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+RenderSVGShape::RenderSVGShape(SVGStyledTransformableElement* node)
+    : RenderSVGModelObject(node)
+    , m_needsBoundariesUpdate(false) // Default is false, the cached rects are empty from the beginning.
+    , m_needsShapeUpdate(true) // Default is true, so we grab a Path object once from SVGStyledTransformableElement.
+    , m_needsTransformUpdate(true) // Default is true, so we grab a AffineTransform object once from SVGStyledTransformableElement.
+    , m_fillFallback(false)
+{
+}
+
+RenderSVGShape::RenderSVGShape(SVGStyledTransformableElement* node, Path* path, bool isFillFallback)
+    : RenderSVGModelObject(node)
+    , m_path(adoptPtr(path))
+    , m_fillFallback(isFillFallback)
+{
+}
+
+RenderSVGShape::~RenderSVGShape()
+{
+}
+
+void RenderSVGShape::createShape()
+{
+    ASSERT(!m_path);
+    m_path = adoptPtr(new Path);
+    ASSERT(isEmpty());
+
+    SVGPathElement* element = static_cast<SVGPathElement*>(node());
+    updatePathFromGraphicsElement(element, path());
+}
+
+bool RenderSVGShape::isEmpty() const
+{
+    return m_path->isEmpty();
+}
+
+void RenderSVGShape::fillShape(GraphicsContext* context) const
+{
+    context->fillPath(path());
+}
+
+FloatRect RenderSVGShape::objectBoundingBox() const
+{
+    return m_path->fastBoundingRect();
+}
+
+void RenderSVGShape::strokeShape(GraphicsContext* context) const
+{
+    context->strokePath(path());
+}
+
+bool RenderSVGShape::shapeDependentStrokeContains(const FloatPoint& point) const
+{
+    BoundingRectStrokeStyleApplier applier(this, style());
+    return m_path->strokeContains(&applier, point);
+}
+
+bool RenderSVGShape::shapeDependentFillContains(const FloatPoint& point, const WindRule fillRule) const
+{
+    return m_path->contains(point, fillRule);
+}
+
+bool RenderSVGShape::fillContains(const FloatPoint& point, bool requiresFill, const WindRule fillRule)
+{
+    if (!m_fillBoundingBox.contains(point))
+        return false;
+
+    Color fallbackColor;
+    if (requiresFill && !RenderSVGResource::fillPaintingResource(this, style(), fallbackColor))
+        return false;
+
+    return shapeDependentFillContains(point, fillRule);
+}
+
+bool RenderSVGShape::strokeContains(const FloatPoint& point, bool requiresStroke)
+{
+    if (!m_strokeAndMarkerBoundingBox.contains(point))
+        return false;
+
+    Color fallbackColor;
+    if (requiresStroke && !RenderSVGResource::strokePaintingResource(this, style(), fallbackColor))
+        return false;
+
+    if (shouldStrokeZeroLengthSubpath())
+        return zeroLengthSubpathRect().contains(point);
+
+    const SVGRenderStyle* svgStyle = style()->svgStyle();
+    if (!svgStyle->strokeDashArray().isEmpty() || svgStyle->strokeMiterLimit() != svgStyle->initialStrokeMiterLimit()
+        || svgStyle->joinStyle() != svgStyle->initialJoinStyle() || svgStyle->capStyle() != svgStyle->initialCapStyle() || static_cast<SVGElement*>(node())->isStyled()) {
+        if (!m_path)
+            RenderSVGShape::createShape();
+        return RenderSVGShape::shapeDependentStrokeContains(point);
+    }
+    return shapeDependentStrokeContains(point);
+}
+
+void RenderSVGShape::layout()
+{
+    LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && selfNeedsLayout());
+    SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
+
+    bool updateCachedBoundariesInParents = false;
+
+    bool needsShapeUpdate = m_needsShapeUpdate;
+    if (needsShapeUpdate) {
+        setIsPaintingFallback(false);
+        m_path.clear();
+        createShape();
+        m_needsShapeUpdate = false;
+        updateCachedBoundariesInParents = true;
+    }
+
+    if (m_needsTransformUpdate) {
+        m_localTransform = element->animatedLocalTransform();
+        m_needsTransformUpdate = false;
+        updateCachedBoundariesInParents = true;
+    }
+
+    if (m_needsBoundariesUpdate) {
+        setIsPaintingFallback(false);
+        m_path.clear();
+        createShape();
+        updateCachedBoundariesInParents = true;
+    }
+
+    // Invalidate all resources of this client if our layout changed.
+    if (m_everHadLayout && selfNeedsLayout()) {
+        SVGResourcesCache::clientLayoutChanged(this);
+        m_markerLayoutInfo.clear();
+    }
+
+    // At this point LayoutRepainter already grabbed the old bounds,
+    // recalculate them now so repaintAfterLayout() uses the new bounds.
+    if (needsShapeUpdate || m_needsBoundariesUpdate) {
+        updateCachedBoundaries();
+        m_needsBoundariesUpdate = false;
+    }
+
+    // If our bounds changed, notify the parents.
+    if (updateCachedBoundariesInParents)
+        RenderSVGModelObject::setNeedsBoundariesUpdate();
+
+    repainter.repaintAfterLayout();
+    setNeedsLayout(false);
+}
+
+bool RenderSVGShape::shouldStrokeZeroLengthSubpath() const
+{
+    // Spec(11.4): Any zero length subpath shall not be stroked if the ‘stroke-linecap’ property has a value of butt
+    // but shall be stroked if the ‘stroke-linecap’ property has a value of round or square
+    return style()->svgStyle()->hasStroke() && style()->svgStyle()->capStyle() != ButtCap && !m_fillBoundingBox.width() && !m_fillBoundingBox.height();
+}
+
+FloatRect RenderSVGShape::zeroLengthSubpathRect() const
+{
+    float strokeWidth = this->strokeWidth();
+    return FloatRect(m_fillBoundingBox.x() - strokeWidth / 2, m_fillBoundingBox.y() - strokeWidth / 2, strokeWidth, strokeWidth);
+}
+
+void RenderSVGShape::setupSquareCapPath(Path*& usePath, int& applyMode)
+{
+    // Spec(11.4): Any zero length subpath shall not be stroked if the ‘stroke-linecap’ property has a value of butt
+    // but shall be stroked if the ‘stroke-linecap’ property has a value of round or square
+    DEFINE_STATIC_LOCAL(Path, tempPath, ());
+
+    applyMode = ApplyToFillMode;
+    usePath = &tempPath;
+    usePath->clear();
+    if (style()->svgStyle()->capStyle() == SquareCap)
+        usePath->addRect(zeroLengthSubpathRect());
+    else
+        usePath->addEllipse(zeroLengthSubpathRect());
+}
+
+bool RenderSVGShape::setupNonScalingStrokePath(Path*& usePath, GraphicsContextStateSaver& stateSaver)
+{
+    DEFINE_STATIC_LOCAL(Path, tempPath, ());
+
+    SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
+    AffineTransform nonScalingStrokeTransform = element->getScreenCTM(SVGLocatable::DisallowStyleUpdate);
+    if (!nonScalingStrokeTransform.isInvertible())
+        return false;
+
+    tempPath = *m_path;
+    usePath = &tempPath;
+    tempPath.transform(nonScalingStrokeTransform);
+
+    stateSaver.save();
+    stateSaver.context()->concatCTM(nonScalingStrokeTransform.inverse());
+    return true;
+}
+
+void RenderSVGShape::fillAndStrokePath(GraphicsContext* context)
+{
+    RenderStyle* style = this->style();
+
+    Color fallbackColor;
+    if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(this, style, fallbackColor)) {
+        if (fillPaintingResource->applyResource(this, style, context, ApplyToFillMode))
+            fillPaintingResource->postApplyResource(this, context, ApplyToFillMode, 0, this);
+        else if (fallbackColor.isValid()) {
+            RenderSVGResourceSolidColor* fallbackResource = RenderSVGResource::sharedSolidPaintingResource();
+            fallbackResource->setColor(fallbackColor);
+            if (fallbackResource->applyResource(this, style, context, ApplyToFillMode))
+                fallbackResource->postApplyResource(this, context, ApplyToFillMode, 0, this);
+        }
+    }
+
+    fallbackColor = Color();
+    RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(this, style, fallbackColor);
+    if (!strokePaintingResource)
+        return;
+
+    Path* usePath = m_path.get();
+    int applyMode = ApplyToStrokeMode;
+
+    bool nonScalingStroke = style->svgStyle()->vectorEffect() == VE_NON_SCALING_STROKE;
+    OwnPtr<Path> savePath;
+
+    GraphicsContextStateSaver stateSaver(*context, false);
+
+    // Spec(11.4): Any zero length subpath shall not be stroked if the ‘stroke-linecap’ property has a value of butt
+    // but shall be stroked if the ‘stroke-linecap’ property has a value of round or square
+    // FIXME: this does not work for zero-length subpaths, only when total path is zero-length
+    if (shouldStrokeZeroLengthSubpath()) {
+        if (!m_path) {
+            RenderSVGShape::createShape();
+            setIsPaintingFallback(true);
+            usePath = m_path.get();
+        }
+        setupSquareCapPath(usePath, applyMode);
+    } else if (nonScalingStroke) {
+        if (!setupNonScalingStrokePath(usePath, stateSaver))
+            return;
+    }
+    if (strokePaintingResource->applyResource(this, style, context, applyMode)) {
+        strokePaintingResource->postApplyResource(this, context, applyMode, usePath, this);
+        if (savePath)
+            m_path = savePath.release();
+        return;
+    }
+    if (!fallbackColor.isValid()) {
+        if (savePath)
+            m_path = savePath.release();
+        return;
+    }
+    RenderSVGResourceSolidColor* fallbackResource = RenderSVGResource::sharedSolidPaintingResource();
+    fallbackResource->setColor(fallbackColor);
+    if (fallbackResource->applyResource(this, style, context, applyMode))
+        fallbackResource->postApplyResource(this, context, applyMode, usePath, this);
+    if (savePath)
+        m_path = savePath.release();
+}
+
+void RenderSVGShape::paint(PaintInfo& paintInfo, const IntPoint&)
+{
+    if (paintInfo.context->paintingDisabled() || style()->visibility() == HIDDEN || isEmpty())
+        return;
+    FloatRect boundingBox = repaintRectInLocalCoordinates();
+    if (!SVGRenderSupport::paintInfoIntersectsRepaintRect(boundingBox, m_localTransform, paintInfo))
+        return;
+
+    PaintInfo childPaintInfo(paintInfo);
+    bool drawsOutline = style()->outlineWidth() && (childPaintInfo.phase == PaintPhaseOutline || childPaintInfo.phase == PaintPhaseSelfOutline);
+    if (drawsOutline || childPaintInfo.phase == PaintPhaseForeground) {
+        GraphicsContextStateSaver stateSaver(*childPaintInfo.context);
+        childPaintInfo.applyTransform(m_localTransform);
+
+        if (childPaintInfo.phase == PaintPhaseForeground) {
+            PaintInfo savedInfo(childPaintInfo);
+
+            if (SVGRenderSupport::prepareToRenderSVGContent(this, childPaintInfo)) {
+                const SVGRenderStyle* svgStyle = style()->svgStyle();
+                if (svgStyle->shapeRendering() == SR_CRISPEDGES)
+                    childPaintInfo.context->setShouldAntialias(false);
+
+                fillAndStrokePath(childPaintInfo.context);
+
+                if (svgStyle->hasMarkers())
+                    m_markerLayoutInfo.drawMarkers(childPaintInfo);
+            }
+
+            SVGRenderSupport::finishRenderSVGContent(this, childPaintInfo, savedInfo.context);
+        }
+
+        if (drawsOutline)
+            paintOutline(childPaintInfo.context, IntRect(boundingBox));
+    }
+}
+
+// This method is called from inside paintOutline() since we call paintOutline()
+// while transformed to our coord system, return local coords
+void RenderSVGShape::addFocusRingRects(Vector<LayoutRect>& rects, const LayoutPoint&)
+{
+    LayoutRect rect = enclosingLayoutRect(repaintRectInLocalCoordinates());
+    if (!rect.isEmpty())
+        rects.append(rect);
+}
+
+bool RenderSVGShape::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
+{
+    // We only draw in the forground phase, so we only hit-test then.
+    if (hitTestAction != HitTestForeground)
+        return false;
+
+    FloatPoint localPoint = m_localTransform.inverse().mapPoint(pointInParent);
+
+    if (!SVGRenderSupport::pointInClippingArea(this, localPoint))
+        return false;
+
+    PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_PATH_HITTESTING, request, style()->pointerEvents());
+    bool isVisible = (style()->visibility() == VISIBLE);
+    if (isVisible || !hitRules.requireVisible) {
+        const SVGRenderStyle* svgStyle = style()->svgStyle();
+        WindRule fillRule = svgStyle->fillRule();
+        if (request.svgClipContent())
+            fillRule = svgStyle->clipRule();
+        if ((hitRules.canHitStroke && (svgStyle->hasStroke() || !hitRules.requireStroke) && strokeContains(localPoint, hitRules.requireStroke))
+            || (hitRules.canHitFill && (svgStyle->hasFill() || !hitRules.requireFill) && fillContains(localPoint, hitRules.requireFill, fillRule))) {
+            updateHitTestResult(result, roundedLayoutPoint(localPoint));
+            return true;
+        }
+    }
+    return false;
+}
+
+FloatRect RenderSVGShape::calculateMarkerBoundsIfNeeded()
+{
+    SVGElement* svgElement = static_cast<SVGElement*>(node());
+    ASSERT(svgElement && svgElement->document());
+    if (!svgElement->isStyled())
+        return FloatRect();
+
+    SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(svgElement);
+    if (!styledElement->supportsMarkers())
+        return FloatRect();
+
+    ASSERT(style()->svgStyle()->hasMarkers());
+
+    SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this);
+    if (!resources)
+        return FloatRect();
+
+    RenderSVGResourceMarker* markerStart = resources->markerStart();
+    RenderSVGResourceMarker* markerMid = resources->markerMid();
+    RenderSVGResourceMarker* markerEnd = resources->markerEnd();
+    if (!markerStart && !markerMid && !markerEnd)
+        return FloatRect();
+
+    return m_markerLayoutInfo.calculateBoundaries(markerStart, markerMid, markerEnd, strokeWidth(), path());
+}
+
+void RenderSVGShape::updateCachedBoundaries()
+{
+    if (isEmpty()) {
+        m_fillBoundingBox = FloatRect();
+        m_strokeAndMarkerBoundingBox = FloatRect();
+        m_repaintBoundingBox = FloatRect();
+        return;
+    }
+
+    // Cache _unclipped_ fill bounding box, used for calculations in resources
+    m_fillBoundingBox = objectBoundingBox();
+
+    // Spec(11.4): Any zero length subpath shall not be stroked if the ‘stroke-linecap’ property has a value of butt
+    // but shall be stroked if the ‘stroke-linecap’ property has a value of round or square
+    if (shouldStrokeZeroLengthSubpath()) {
+        m_strokeAndMarkerBoundingBox = zeroLengthSubpathRect();
+        // Cache smallest possible repaint rectangle
+        m_repaintBoundingBox = m_strokeAndMarkerBoundingBox;
+        SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingBox);
+        return;
+    }
+
+    // Cache _unclipped_ stroke bounding box, used for calculations in resources (includes marker boundaries)
+    m_strokeAndMarkerBoundingBox = m_fillBoundingBox;
+    if (hasPath())
+        inflateWithStrokeAndMarkerBounds();
+    // Cache smallest possible repaint rectangle
+    m_repaintBoundingBox = strokeBoundingBox();
+    SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingBox);
+}
+
+float RenderSVGShape::strokeWidth() const
+{
+    SVGElement* svgElement = static_cast<SVGElement*>(node());
+    SVGLengthContext lengthContext(svgElement);
+    return style()->svgStyle()->strokeWidth().value(lengthContext);
+}
+
+void RenderSVGShape::inflateWithStrokeAndMarkerBounds()
+{
+    const SVGRenderStyle* svgStyle = style()->svgStyle();
+    FloatRect strokeRect;
+    if (svgStyle->hasStroke()) {
+        BoundingRectStrokeStyleApplier strokeStyle(this, style());
+        m_strokeAndMarkerBoundingBox.unite(path().strokeBoundingRect(&strokeStyle));
+    }
+    if (svgStyle->hasMarkers()) {
+        FloatRect markerBounds = calculateMarkerBoundsIfNeeded();
+        if (!markerBounds.isEmpty())
+            m_strokeAndMarkerBoundingBox.unite(markerBounds);
+    }
+}
+
+}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGShape.h b/Source/WebCore/rendering/svg/RenderSVGShape.h
new file mode 100755 (executable)
index 0000000..3320236
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2006 Apple Computer, Inc
+ * Copyright (C) 2009 Google, Inc.
+ * Copyright (C) 2011 Renata Hodovan <reni@webkit.org>
+ * Copyright (C) 2011 University of Szeged
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef RenderSVGShape_h
+#define RenderSVGShape_h
+
+#if ENABLE(SVG)
+#include "AffineTransform.h"
+#include "FloatRect.h"
+#include "RenderSVGModelObject.h"
+#include "SVGMarkerLayoutInfo.h"
+#include "StrokeStyleApplier.h"
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+class FloatPoint;
+class GraphicsContextStateSaver;
+class RenderSVGContainer;
+class RenderSVGPath;
+class SVGStyledTransformableElement;
+
+class BoundingRectStrokeStyleApplier : public StrokeStyleApplier {
+public:
+    BoundingRectStrokeStyleApplier(const RenderObject* object, RenderStyle* style)
+        : m_object(object)
+        , m_style(style)
+    {
+        ASSERT(style);
+        ASSERT(object);
+    }
+
+    void strokeStyle(GraphicsContext* context)
+    {
+        SVGRenderSupport::applyStrokeStyleToContext(context, m_style, m_object);
+    }
+
+private:
+    const RenderObject* m_object;
+    RenderStyle* m_style;
+};
+
+class RenderSVGShape : public RenderSVGModelObject {
+public:
+    explicit RenderSVGShape(SVGStyledTransformableElement*);
+    RenderSVGShape(SVGStyledTransformableElement*, Path*, bool);
+    virtual ~RenderSVGShape();
+
+    void setNeedsShapeUpdate() { m_needsShapeUpdate = true; }
+    virtual void setNeedsBoundariesUpdate() { m_needsBoundariesUpdate = true; }
+    virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
+    virtual void fillShape(GraphicsContext*) const;
+    virtual void strokeShape(GraphicsContext*) const;
+    bool isPaintingFallback() const { return m_fillFallback; }
+
+    Path& path() const
+    {
+        ASSERT(m_path);
+        return *m_path;
+    }
+
+protected:
+    virtual void createShape();
+    virtual bool isEmpty() const;
+    virtual FloatRect objectBoundingBox() const;
+    virtual FloatRect strokeBoundingBox() const { return m_strokeAndMarkerBoundingBox; }
+    void setStrokeAndMarkerBoundingBox(FloatRect rect) { m_strokeAndMarkerBoundingBox = rect; }
+    virtual bool shapeDependentStrokeContains(const FloatPoint&) const;
+    virtual bool shapeDependentFillContains(const FloatPoint&, const WindRule) const;
+    float strokeWidth() const;
+    void setIsPaintingFallback(bool isFallback) { m_fillFallback = isFallback; }
+    FloatRect calculateMarkerBoundsIfNeeded();
+
+    bool hasPath() const { return m_path.get(); }
+
+private:
+    // Hit-detection separated for the fill and the stroke
+    bool fillContains(const FloatPoint&, bool requiresFill = true, const WindRule fillRule = RULE_NONZERO);
+    bool strokeContains(const FloatPoint&, bool requiresStroke = true);
+
+    virtual FloatRect repaintRectInLocalCoordinates() const { return m_repaintBoundingBox; }
+    virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
+    virtual AffineTransform localTransform() const { return m_localTransform; }
+
+    virtual bool isSVGShape() const { return true; }
+    virtual const char* renderName() const { return "RenderSVGShape"; }
+    virtual bool isRoundedRect() { return false; }
+
+    virtual void layout();
+    virtual void paint(PaintInfo&, const LayoutPoint&);
+    virtual void addFocusRingRects(Vector<LayoutRect>&, const LayoutPoint&);
+
+    virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
+
+    void updateCachedBoundaries();
+
+    void setupSquareCapPath(Path*&, int& applyMode);
+    bool setupNonScalingStrokePath(Path*&, GraphicsContextStateSaver&);
+    bool shouldStrokeZeroLengthSubpath() const;
+    FloatRect zeroLengthSubpathRect() const;
+
+    void fillAndStrokePath(GraphicsContext*);
+    void inflateWithStrokeAndMarkerBounds();
+
+private:
+    FloatRect m_fillBoundingBox;
+    FloatRect m_strokeAndMarkerBoundingBox;
+    FloatRect m_repaintBoundingBox;
+    SVGMarkerLayoutInfo m_markerLayoutInfo;
+    AffineTransform m_localTransform;
+    OwnPtr<Path> m_path;
+
+    bool m_needsBoundariesUpdate : 1;
+    bool m_needsShapeUpdate : 1;
+    bool m_needsTransformUpdate : 1;
+    bool m_fillFallback : 1;
+    bool m_strokeContainsFallBack : 1;
+};
+
+inline RenderSVGShape* toRenderSVGShape(RenderObject* object)
+{
+    ASSERT(!object || object->isSVGShape());
+    return static_cast<RenderSVGShape*>(object);
+}
+
+inline const RenderSVGShape* toRenderSVGShape(const RenderObject* object)
+{
+    ASSERT(!object || object->isSVGShape());
+    return static_cast<const RenderSVGShape*>(object);
+}
+
+// This will catch anyone doing an unnecessary cast.
+void toRenderSVGShape(const RenderSVGShape*);
+
+}
+
+#endif // ENABLE(SVG)
+#endif
index b18762f..23f26b5 100644 (file)
@@ -378,7 +378,7 @@ void SVGInlineTextBox::releasePaintingResource(GraphicsContext*& context, const
     RenderObject* parentRenderer = parent()->renderer();
     ASSERT(parentRenderer);
 
-    m_paintingResource->postApplyResource(parentRenderer, context, m_paintingResourceMode, path);
+    m_paintingResource->postApplyResource(parentRenderer, context, m_paintingResourceMode, path, /*RenderSVGShape*/ 0);
     m_paintingResource = 0;
 }
 
index 4bb2fd9..bbf84d3 100644 (file)
@@ -152,7 +152,7 @@ void SVGRenderSupport::finishRenderSVGContent(RenderObject* object, PaintInfo& p
     SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object);
     if (resources) {
         if (RenderSVGResourceFilter* filter = resources->filter()) {
-            filter->postApplyResource(object, paintInfo.context, ApplyToDefaultMode, /* path */0);
+            filter->postApplyResource(static_cast<RenderSVGShape*>(object), paintInfo.context, ApplyToDefaultMode, 0, 0);
             paintInfo.context = savedContext;
         }
     }
@@ -224,9 +224,9 @@ void SVGRenderSupport::layoutChildren(RenderObject* start, bool selfNeedsLayout)
             // When selfNeedsLayout is false and the layout size changed, we have to check whether this child uses relative lengths
             if (SVGElement* element = child->node()->isSVGElement() ? static_cast<SVGElement*>(child->node()) : 0) {
                 if (element->isStyled() && static_cast<SVGStyledElement*>(element)->hasRelativeLengths()) {
-                    // When the layout size changed and when using relative values tell the RenderSVGPath to update its Path object
-                    if (child->isSVGPath())
-                        toRenderSVGPath(child)->setNeedsPathUpdate();
+                    // When the layout size changed and when using relative values tell the RenderSVGShape to update its shape object
+                    if (child->isSVGShape())
+                        toRenderSVGShape(child)->setNeedsShapeUpdate();
 
                     needsLayout = true;
                 }
old mode 100644 (file)
new mode 100755 (executable)
index 76855fd..8db295f
@@ -55,6 +55,7 @@
 #include "RenderSVGResourceRadialGradient.h"
 #include "RenderSVGResourceSolidColor.h"
 #include "RenderSVGRoot.h"
+#include "RenderSVGShape.h"
 #include "RenderSVGText.h"
 #include "RenderTreeAsText.h"
 #include "SVGCircleElement.h"
@@ -273,18 +274,18 @@ static void writeStyle(TextStream& ts, const RenderObject& object)
         writeNameValuePair(ts, "transform", object.localTransform());
     writeIfNotDefault(ts, "image rendering", style->imageRendering(), RenderStyle::initialImageRendering());
     writeIfNotDefault(ts, "opacity", style->opacity(), RenderStyle::initialOpacity());
-    if (object.isSVGPath()) {
-        const RenderSVGPath& path = static_cast<const RenderSVGPath&>(object);
-        ASSERT(path.node());
-        ASSERT(path.node()->isSVGElement());
+    if (object.isSVGShape()) {
+        const RenderSVGShape& shape = static_cast<const RenderSVGShape&>(object);
+        ASSERT(shape.node());
+        ASSERT(shape.node()->isSVGElement());
 
         Color fallbackColor;
-        if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(const_cast<RenderSVGPath*>(&path), path.style(), fallbackColor)) {
+        if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(const_cast<RenderSVGShape*>(&shape), shape.style(), fallbackColor)) {
             TextStreamSeparator s(" ");
             ts << " [stroke={" << s;
             writeSVGPaintingResource(ts, strokePaintingResource);
 
-            SVGLengthContext lengthContext(static_cast<SVGElement*>(path.node()));
+            SVGLengthContext lengthContext(static_cast<SVGElement*>(shape.node()));
             double dashOffset = svgStyle->strokeDashOffset().value(lengthContext);
             double strokeWidth = svgStyle->strokeWidth().value(lengthContext);
             const Vector<SVGLength>& dashes = svgStyle->strokeDashArray();
@@ -306,7 +307,7 @@ static void writeStyle(TextStream& ts, const RenderObject& object)
             ts << "}]";
         }
 
-        if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(const_cast<RenderSVGPath*>(&path), path.style(), fallbackColor)) {
+        if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(const_cast<RenderSVGShape*>(&shape), shape.style(), fallbackColor)) {
             TextStreamSeparator s(" ");
             ts << " [fill={" << s;
             writeSVGPaintingResource(ts, fillPaintingResource);
@@ -330,12 +331,12 @@ static TextStream& writePositionAndStyle(TextStream& ts, const RenderObject& obj
     return ts;
 }
 
-static TextStream& operator<<(TextStream& ts, const RenderSVGPath& path)
+static TextStream& operator<<(TextStream& ts, const RenderSVGShape& shape)
 {
-    writePositionAndStyle(ts, path);
+    writePositionAndStyle(ts, shape);
 
-    ASSERT(path.node()->isSVGElement());
-    SVGElement* svgElement = static_cast<SVGElement*>(path.node());
+    ASSERT(shape.node()->isSVGElement());
+    SVGElement* svgElement = static_cast<SVGElement*>(shape.node());
     SVGLengthContext lengthContext(svgElement);
 
     if (svgElement->hasTagName(SVGNames::rectTag)) {
@@ -624,11 +625,11 @@ void writeSVGImage(TextStream& ts, const RenderSVGImage& image, int indent)
     writeResources(ts, image, indent);
 }
 
-void write(TextStream& ts, const RenderSVGPath& path, int indent)
+void write(TextStream& ts, const RenderSVGShape& shape, int indent)
 {
-    writeStandardPrefix(ts, path, indent);
-    ts << path << "\n";
-    writeResources(ts, path, indent);
+    writeStandardPrefix(ts, shape, indent);
+    ts << shape << "\n";
+    writeResources(ts, shape, indent);
 }
 
 void writeSVGGradientStop(TextStream& ts, const RenderSVGGradientStop& stop, int indent)
index f4faf7a..5458c0d 100644 (file)
@@ -41,14 +41,14 @@ class RenderObject;
 class RenderSVGGradientStop;
 class RenderSVGImage;
 class RenderSVGInlineText;
-class RenderSVGPath;
+class RenderSVGShape;
 class RenderSVGRoot;
 class RenderSVGText;
 class AffineTransform;
 class SVGUnitTypes;
 
 // functions used by the main RenderTreeAsText code
-void write(TextStream&, const RenderSVGPath&, int indent);
+void write(TextStream&, const RenderSVGShape&, int indent);
 void write(TextStream&, const RenderSVGRoot&, int indent);
 void writeSVGGradientStop(TextStream&, const RenderSVGGradientStop&, int indent);
 void writeSVGResourceContainer(TextStream&, const RenderObject&, int indent);
index 33acf92..224eb86 100644 (file)
@@ -160,7 +160,7 @@ void SVGTextRunRenderingContext::drawSVGGlyphs(GraphicsContext* context, const T
                 const RenderSVGInlineText* textRenderer = toRenderSVGInlineText(renderObject);
                 context->setStrokeThickness(context->strokeThickness() * textRenderer->scalingFactor());
             }
-            activePaintingResource->postApplyResource(parentRenderObject, context, resourceMode, &glyphPath);
+            activePaintingResource->postApplyResource(parentRenderObject, context, resourceMode, &glyphPath, 0);
          }
  
         context->restore();
index 27c4052..a6c26aa 100644 (file)
@@ -124,7 +124,7 @@ void SVGCircleElement::svgAttributeChanged(const QualifiedName& attrName)
         return;
 
     if (isLengthAttribute) {
-        renderer->setNeedsPathUpdate();
+        renderer->setNeedsShapeUpdate();
         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
     }
index f8ecb34..76ee9ac 100644 (file)
@@ -129,7 +129,7 @@ void SVGEllipseElement::svgAttributeChanged(const QualifiedName& attrName)
         return;
 
     if (isLengthAttribute) {
-        renderer->setNeedsPathUpdate();
+        renderer->setNeedsShapeUpdate();
         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
     }
old mode 100644 (file)
new mode 100755 (executable)
index da84223..4442676 100644 (file)
@@ -129,7 +129,7 @@ void SVGLineElement::svgAttributeChanged(const QualifiedName& attrName)
         return;
 
     if (isLengthAttribute) {
-        renderer->setNeedsPathUpdate();
+        renderer->setNeedsShapeUpdate();
         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
     }
index 410301a..62b904a 100644 (file)
@@ -271,7 +271,7 @@ void SVGPathElement::svgAttributeChanged(const QualifiedName& attrName)
         }
 
         if (renderer)
-            renderer->setNeedsPathUpdate();
+            renderer->setNeedsShapeUpdate();
     }
 
     if (renderer)
@@ -351,7 +351,7 @@ void SVGPathElement::pathSegListChanged(SVGPathSegRole role)
     if (!renderer)
         return;
 
-    renderer->setNeedsPathUpdate();
+    renderer->setNeedsShapeUpdate();
     RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
 }
 
@@ -374,6 +374,12 @@ FloatRect SVGPathElement::getBBox(StyleUpdateStrategy styleUpdateStrategy)
     return m_cachedBBoxRect;
 }
 
+RenderObject* SVGPathElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+    // By default, any subclass is expected to do path-based drawing
+    return new (arena) RenderSVGPath(this);
+}
+
 }
 
 #endif // ENABLE(SVG)
index 1733650..c6bf220 100644 (file)
@@ -123,6 +123,8 @@ private:
     virtual void synchronizeRequiredExtensions() { SVGTests::synchronizeRequiredExtensions(this); }
     virtual void synchronizeSystemLanguage() { SVGTests::synchronizeSystemLanguage(this); }
 
+    RenderObject* createRenderer(RenderArena*, RenderStyle*);
+
 private:
     OwnPtr<SVGPathByteStream> m_pathByteStream;
     mutable SVGSynchronizableAnimatedProperty<SVGPathSegList> m_pathSegList;
index 66c5258..a8b67c7 100644 (file)
@@ -124,7 +124,7 @@ void SVGPolyElement::svgAttributeChanged(const QualifiedName& attrName)
         return;
 
     if (attrName == SVGNames::pointsAttr) {
-        renderer->setNeedsPathUpdate();
+        renderer->setNeedsShapeUpdate();
         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
     }
index f436e34..eca03df 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "Attribute.h"
 #include "RenderSVGPath.h"
+#include "RenderSVGRect.h"
 #include "RenderSVGResource.h"
 #include "SVGElementInstance.h"
 #include "SVGLength.h"
@@ -32,6 +33,8 @@
 
 namespace WebCore {
 
+class RenderSVGRect;
+
 // Animated property definitions
 DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::xAttr, X, x)
 DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::yAttr, Y, y)
@@ -137,12 +140,12 @@ void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName)
     if (SVGTests::handleAttributeChange(this, attrName))
         return;
 
-    RenderSVGPath* renderer = static_cast<RenderSVGPath*>(this->renderer());
+    RenderSVGRect* renderer = static_cast<RenderSVGRect*>(this->renderer());
     if (!renderer)
         return;
 
     if (isLengthAttribute) {
-        renderer->setNeedsPathUpdate();
+        renderer->setNeedsShapeUpdate();
         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
     }
@@ -165,6 +168,11 @@ bool SVGRectElement::selfHasRelativeLengths() const
         || ry().isRelative();
 }
 
+RenderObject* SVGRectElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+    return new (arena) RenderSVGRect(this);
+}
+
 }
 
 #endif // ENABLE(SVG)
index a608b4d..2704689 100644 (file)
@@ -50,6 +50,8 @@ private:
 
     virtual bool selfHasRelativeLengths() const;
 
+    RenderObject* createRenderer(RenderArena*, RenderStyle*);
+
     BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGRectElement)
         DECLARE_ANIMATED_LENGTH(X, x)
         DECLARE_ANIMATED_LENGTH(Y, y)