[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

andreas.kling at nokia.com andreas.kling at nokia.com
Wed Dec 22 14:29:25 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 5a20f1c3d707562cbcc488a86b4e42a5d684f01b
Author: andreas.kling at nokia.com <andreas.kling at nokia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Oct 11 19:19:05 2010 +0000

    2010-10-11  Andreas Kling  <kling at webkit.org>
    
            Reviewed by Dirk Schulze.
    
            SVG: Remove "create" methods and use port-specific "add" counterparts
            https://bugs.webkit.org/show_bug.cgi?id=46052
    
            Circles and ellipses will be significantly faster on platforms that
            implement Path::addEllipse() in a sane fashion.
    
            Also, a lot of Path copying has been factored out by changing functions
            that would return Paths to take Path& arguments instead (toPathData, toClipPath)
    
            * mathml/RenderMathMLRoot.cpp:
            (WebCore::RenderMathMLRoot::paint):
            * mathml/RenderMathMLSquareRoot.cpp:
            (WebCore::RenderMathMLSquareRoot::paint):
            * platform/graphics/GraphicsContext.cpp:
            (WebCore::GraphicsContext::addRoundedRectClip):
            (WebCore::GraphicsContext::clipOutRoundedRect):
            * platform/graphics/Path.cpp:
            (WebCore::pathLengthApplierFunction):
            (WebCore::Path::addRoundedRect):
            * platform/graphics/Path.h:
            * platform/graphics/cairo/ContextShadowCairo.cpp:
            (WebCore::ContextShadow::drawRectShadowWithoutTiling):
            (WebCore::ContextShadow::drawRectShadow):
            * platform/graphics/cairo/GraphicsContextCairo.cpp:
            (WebCore::GraphicsContext::drawFocusRing):
            (WebCore::GraphicsContext::drawTiledShadow):
            (WebCore::GraphicsContext::fillRoundedRect):
            * platform/graphics/cg/GraphicsContextCG.cpp:
            (WebCore::GraphicsContext::fillRoundedRect):
            * platform/graphics/qt/GraphicsContextQt.cpp:
            (WebCore::GraphicsContext::fillRoundedRect):
            * rendering/RenderBoxModelObject.cpp:
            (WebCore::RenderBoxModelObject::paintBorder):
            (WebCore::RenderBoxModelObject::paintBoxShadow):
            * rendering/RenderEmbeddedObject.cpp:
            (WebCore::RenderEmbeddedObject::getReplacementTextGeometry):
            * rendering/RenderSVGResourceClipper.cpp:
            (WebCore::RenderSVGResourceClipper::pathOnlyClipping):
            * rendering/svg/RenderSVGPath.cpp:
            (WebCore::RenderSVGPath::layout):
            * rendering/svg/RenderSVGTextPath.cpp:
            (WebCore::RenderSVGTextPath::layoutPath):
            * rendering/svg/SVGInlineTextBox.cpp:
            (WebCore::SVGInlineTextBox::paintDecorationWithStyle):
            * svg/SVGAnimateMotionElement.cpp:
            (WebCore::SVGAnimateMotionElement::animationPath):
            * svg/SVGCircleElement.cpp:
            (WebCore::SVGCircleElement::toPathData):
            * svg/SVGCircleElement.h:
            * svg/SVGEllipseElement.cpp:
            (WebCore::SVGEllipseElement::toPathData):
            * svg/SVGEllipseElement.h:
            * svg/SVGLineElement.cpp:
            (WebCore::SVGLineElement::toPathData):
            * svg/SVGLineElement.h:
            * svg/SVGPathElement.cpp:
            (WebCore::SVGPathElement::getTotalLength):
            (WebCore::SVGPathElement::getPointAtLength):
            (WebCore::SVGPathElement::toPathData):
            * svg/SVGPathElement.h:
            * svg/SVGPolygonElement.cpp:
            (WebCore::SVGPolygonElement::toPathData):
            * svg/SVGPolygonElement.h:
            * svg/SVGPolylineElement.cpp:
            (WebCore::SVGPolylineElement::toPathData):
            * svg/SVGPolylineElement.h:
            * svg/SVGRectElement.cpp:
            (WebCore::SVGRectElement::toPathData):
            * svg/SVGRectElement.h:
            * svg/SVGStyledTransformableElement.cpp:
            (WebCore::SVGStyledTransformableElement::toClipPath):
            * svg/SVGStyledTransformableElement.h:
            (WebCore::SVGStyledTransformableElement::toPathData):
            * svg/SVGUseElement.cpp:
            (WebCore::SVGUseElement::toClipPath):
            * svg/SVGUseElement.h:
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@69517 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 89fdaab..910b3ee 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,84 @@
+2010-10-11  Andreas Kling  <kling at webkit.org>
+
+        Reviewed by Dirk Schulze.
+
+        SVG: Remove "create" methods and use port-specific "add" counterparts
+        https://bugs.webkit.org/show_bug.cgi?id=46052
+
+        Circles and ellipses will be significantly faster on platforms that
+        implement Path::addEllipse() in a sane fashion.
+
+        Also, a lot of Path copying has been factored out by changing functions
+        that would return Paths to take Path& arguments instead (toPathData, toClipPath)
+
+        * mathml/RenderMathMLRoot.cpp:
+        (WebCore::RenderMathMLRoot::paint):
+        * mathml/RenderMathMLSquareRoot.cpp:
+        (WebCore::RenderMathMLSquareRoot::paint):
+        * platform/graphics/GraphicsContext.cpp:
+        (WebCore::GraphicsContext::addRoundedRectClip):
+        (WebCore::GraphicsContext::clipOutRoundedRect):
+        * platform/graphics/Path.cpp:
+        (WebCore::pathLengthApplierFunction):
+        (WebCore::Path::addRoundedRect):
+        * platform/graphics/Path.h:
+        * platform/graphics/cairo/ContextShadowCairo.cpp:
+        (WebCore::ContextShadow::drawRectShadowWithoutTiling):
+        (WebCore::ContextShadow::drawRectShadow):
+        * platform/graphics/cairo/GraphicsContextCairo.cpp:
+        (WebCore::GraphicsContext::drawFocusRing):
+        (WebCore::GraphicsContext::drawTiledShadow):
+        (WebCore::GraphicsContext::fillRoundedRect):
+        * platform/graphics/cg/GraphicsContextCG.cpp:
+        (WebCore::GraphicsContext::fillRoundedRect):
+        * platform/graphics/qt/GraphicsContextQt.cpp:
+        (WebCore::GraphicsContext::fillRoundedRect):
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::paintBorder):
+        (WebCore::RenderBoxModelObject::paintBoxShadow):
+        * rendering/RenderEmbeddedObject.cpp:
+        (WebCore::RenderEmbeddedObject::getReplacementTextGeometry):
+        * rendering/RenderSVGResourceClipper.cpp:
+        (WebCore::RenderSVGResourceClipper::pathOnlyClipping):
+        * rendering/svg/RenderSVGPath.cpp:
+        (WebCore::RenderSVGPath::layout):
+        * rendering/svg/RenderSVGTextPath.cpp:
+        (WebCore::RenderSVGTextPath::layoutPath):
+        * rendering/svg/SVGInlineTextBox.cpp:
+        (WebCore::SVGInlineTextBox::paintDecorationWithStyle):
+        * svg/SVGAnimateMotionElement.cpp:
+        (WebCore::SVGAnimateMotionElement::animationPath):
+        * svg/SVGCircleElement.cpp:
+        (WebCore::SVGCircleElement::toPathData):
+        * svg/SVGCircleElement.h:
+        * svg/SVGEllipseElement.cpp:
+        (WebCore::SVGEllipseElement::toPathData):
+        * svg/SVGEllipseElement.h:
+        * svg/SVGLineElement.cpp:
+        (WebCore::SVGLineElement::toPathData):
+        * svg/SVGLineElement.h:
+        * svg/SVGPathElement.cpp:
+        (WebCore::SVGPathElement::getTotalLength):
+        (WebCore::SVGPathElement::getPointAtLength):
+        (WebCore::SVGPathElement::toPathData):
+        * svg/SVGPathElement.h:
+        * svg/SVGPolygonElement.cpp:
+        (WebCore::SVGPolygonElement::toPathData):
+        * svg/SVGPolygonElement.h:
+        * svg/SVGPolylineElement.cpp:
+        (WebCore::SVGPolylineElement::toPathData):
+        * svg/SVGPolylineElement.h:
+        * svg/SVGRectElement.cpp:
+        (WebCore::SVGRectElement::toPathData):
+        * svg/SVGRectElement.h:
+        * svg/SVGStyledTransformableElement.cpp:
+        (WebCore::SVGStyledTransformableElement::toClipPath):
+        * svg/SVGStyledTransformableElement.h:
+        (WebCore::SVGStyledTransformableElement::toPathData):
+        * svg/SVGUseElement.cpp:
+        (WebCore::SVGUseElement::toClipPath):
+        * svg/SVGUseElement.h:
+
 2010-10-01  Oliver Hunt  <oliver at apple.com>
 
         Reviewed by Gavin Barraclough.
diff --git a/WebCore/mathml/RenderMathMLRoot.cpp b/WebCore/mathml/RenderMathMLRoot.cpp
index da303c9..99b5dc6 100644
--- a/WebCore/mathml/RenderMathMLRoot.cpp
+++ b/WebCore/mathml/RenderMathMLRoot.cpp
@@ -190,9 +190,9 @@ void RenderMathMLRoot::paint(PaintInfo& info, int tx, int ty)
     info.context->setLineCap(SquareCap);
     
     Path line;
-    
-    line = line.createLine(bottomLeft, topLeft);
-    
+    line.moveTo(bottomLeft);
+    line.addLineTo(topLeft);
+
     info.context->beginPath();
     info.context->addPath(line);
     info.context->strokePath();
diff --git a/WebCore/mathml/RenderMathMLSquareRoot.cpp b/WebCore/mathml/RenderMathMLSquareRoot.cpp
index 86add7a..d2e7049 100644
--- a/WebCore/mathml/RenderMathMLSquareRoot.cpp
+++ b/WebCore/mathml/RenderMathMLSquareRoot.cpp
@@ -156,8 +156,8 @@ void RenderMathMLSquareRoot::paint(PaintInfo& info, int tx, int ty)
     info.context->setLineCap(SquareCap);
     
     Path line;
-    
-    line = line.createLine(bottomLeft, topLeft);
+    line.moveTo(bottomLeft);
+    line.addLineTo(topLeft);
     
     info.context->beginPath();
     info.context->addPath(line);
diff --git a/WebCore/platform/graphics/GraphicsContext.cpp b/WebCore/platform/graphics/GraphicsContext.cpp
index 2c94bec..859f38a 100644
--- a/WebCore/platform/graphics/GraphicsContext.cpp
+++ b/WebCore/platform/graphics/GraphicsContext.cpp
@@ -500,7 +500,9 @@ void GraphicsContext::addRoundedRectClip(const IntRect& rect, const IntSize& top
     if (paintingDisabled())
         return;
 
-    clip(Path::createRoundedRectangle(rect, topLeft, topRight, bottomLeft, bottomRight));
+    Path path;
+    path.addRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight);
+    clip(path);
 }
 
 void GraphicsContext::clipOutRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight,
@@ -509,7 +511,9 @@ void GraphicsContext::clipOutRoundedRect(const IntRect& rect, const IntSize& top
     if (paintingDisabled())
         return;
 
-    clipOut(Path::createRoundedRectangle(rect, topLeft, topRight, bottomLeft, bottomRight));
+    Path path;
+    path.addRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight);
+    clipOut(path);
 }
 
 void GraphicsContext::clipToImageBuffer(ImageBuffer* buffer, const FloatRect& rect)
diff --git a/WebCore/platform/graphics/Path.cpp b/WebCore/platform/graphics/Path.cpp
index 4e2de53..0a24ab2 100644
--- a/WebCore/platform/graphics/Path.cpp
+++ b/WebCore/platform/graphics/Path.cpp
@@ -35,8 +35,9 @@
 #include <math.h>
 #include <wtf/MathExtras.h>
 
-static const float QUARTER = 0.552f; // approximation of control point positions on a bezier
-                              // to simulate a quarter of a circle.
+// Approximation of control point positions on a bezier to simulate a quarter of a circle.
+static const float gCircleControlPoint = 1 - 0.552;
+
 namespace WebCore {
 
 #if !PLATFORM(OPENVG) && !PLATFORM(QT)
@@ -47,7 +48,7 @@ static void pathLengthApplierFunction(void* info, const PathElement* element)
         return;
     traversalState.m_previous = traversalState.m_current;
     FloatPoint* points = element->points;
-    float segmentLength = 0.0f;
+    float segmentLength = 0;
     switch (element->type) {
         case PathElementMoveToPoint:
             segmentLength = traversalState.moveTo(points[0]);
@@ -75,10 +76,8 @@ static void pathLengthApplierFunction(void* info, const PathElement* element)
         if (traversalState.m_action == PathTraversalState::TraversalPointAtLength) {
             float offset = traversalState.m_desiredLength - traversalState.m_totalLength;
             traversalState.m_current.move(offset * cosf(slope), offset * sinf(slope));
-        } else {
-            static const float rad2deg = 180.0f / piFloat;
-            traversalState.m_normalAngle = slope * rad2deg;
-        }
+        } else
+            traversalState.m_normalAngle = rad2deg(slope);
 
         traversalState.m_success = true;
     }
@@ -110,167 +109,83 @@ float Path::normalAngleAtLength(float length, bool& ok)
 }
 #endif
 
-Path Path::createRoundedRectangle(const FloatRect& rectangle, const FloatSize& roundingRadii)
+void Path::addRoundedRect(const FloatRect& rect, const FloatSize& roundingRadii)
 {
-    Path path;
-    float x = rectangle.x();
-    float y = rectangle.y();
-    float width = rectangle.width();
-    float height = rectangle.height();
-    float rx = roundingRadii.width();
-    float ry = roundingRadii.height();
-    if (width <= 0.0f || height <= 0.0f)
-        return path;
+    if (rect.isEmpty())
+        return;
+
+    FloatSize radius(roundingRadii);
+    FloatSize halfSize(rect.width() / 2, rect.height() / 2);
 
-    float dx = rx, dy = ry;
     // If rx is greater than half of the width of the rectangle
     // then set rx to half of the width (required in SVG spec)
-    if (dx > width * 0.5f)
-        dx = width * 0.5f;
+    if (radius.width() > halfSize.width())
+        radius.setWidth(halfSize.width());
 
     // If ry is greater than half of the height of the rectangle
     // then set ry to half of the height (required in SVG spec)
-    if (dy > height * 0.5f)
-        dy = height * 0.5f;
+    if (radius.height() > halfSize.height())
+        radius.setHeight(halfSize.height());
 
-    path.moveTo(FloatPoint(x + dx, y));
+    moveTo(FloatPoint(rect.x() + radius.width(), rect.y()));
 
-    if (dx < width * 0.5f)
-        path.addLineTo(FloatPoint(x + width - rx, y));
+    if (radius.width() < halfSize.width())
+        addLineTo(FloatPoint(rect.x() + rect.width() - roundingRadii.width(), rect.y()));
 
-    path.addBezierCurveTo(FloatPoint(x + width - dx * (1 - QUARTER), y), FloatPoint(x + width, y + dy * (1 - QUARTER)), FloatPoint(x + width, y + dy));
+    addBezierCurveTo(FloatPoint(rect.x() + rect.width() - radius.width() * gCircleControlPoint, rect.y()), FloatPoint(rect.x() + rect.width(), rect.y() + radius.height() * gCircleControlPoint), FloatPoint(rect.x() + rect.width(), rect.y() + radius.height()));
 
-    if (dy < height * 0.5)
-        path.addLineTo(FloatPoint(x + width, y + height - dy));
+    if (radius.height() < halfSize.height())
+        addLineTo(FloatPoint(rect.x() + rect.width(), rect.y() + rect.height() - radius.height()));
 
-    path.addBezierCurveTo(FloatPoint(x + width, y + height - dy * (1 - QUARTER)), FloatPoint(x + width - dx * (1 - QUARTER), y + height), FloatPoint(x + width - dx, y + height));
+    addBezierCurveTo(FloatPoint(rect.x() + rect.width(), rect.y() + rect.height() - radius.height() * gCircleControlPoint), FloatPoint(rect.x() + rect.width() - radius.width() * gCircleControlPoint, rect.y() + rect.height()), FloatPoint(rect.x() + rect.width() - radius.width(), rect.y() + rect.height()));
 
-    if (dx < width * 0.5)
-        path.addLineTo(FloatPoint(x + dx, y + height));
+    if (radius.width() < halfSize.width())
+        addLineTo(FloatPoint(rect.x() + radius.width(), rect.y() + rect.height()));
 
-    path.addBezierCurveTo(FloatPoint(x + dx * (1 - QUARTER), y + height), FloatPoint(x, y + height - dy * (1 - QUARTER)), FloatPoint(x, y + height - dy));
+    addBezierCurveTo(FloatPoint(rect.x() + radius.width() * gCircleControlPoint, rect.y() + rect.height()), FloatPoint(rect.x(), rect.y() + rect.height() - radius.height() * gCircleControlPoint), FloatPoint(rect.x(), rect.y() + rect.height() - radius.height()));
 
-    if (dy < height * 0.5)
-        path.addLineTo(FloatPoint(x, y + dy));
+    if (radius.height() < halfSize.height())
+        addLineTo(FloatPoint(rect.x(), rect.y() + radius.height()));
 
-    path.addBezierCurveTo(FloatPoint(x, y + dy * (1 - QUARTER)), FloatPoint(x + dx * (1 - QUARTER), y), FloatPoint(x + dx, y));
+    addBezierCurveTo(FloatPoint(rect.x(), rect.y() + radius.height() * gCircleControlPoint), FloatPoint(rect.x() + radius.width() * gCircleControlPoint, rect.y()), FloatPoint(rect.x() + radius.width(), rect.y()));
 
-    path.closeSubpath();
-
-    return path;
+    closeSubpath();
 }
 
-Path Path::createRoundedRectangle(const FloatRect& rectangle, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius)
+void Path::addRoundedRect(const FloatRect& rect, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius)
 {
-    Path path;
-
-    float width = rectangle.width();
-    float height = rectangle.height();
-    if (width <= 0.0 || height <= 0.0)
-        return path;
+    if (rect.isEmpty())
+        return;
 
-    if (width < topLeftRadius.width() + topRightRadius.width()
-            || width < bottomLeftRadius.width() + bottomRightRadius.width()
-            || height < topLeftRadius.height() + bottomLeftRadius.height()
-            || height < topRightRadius.height() + bottomRightRadius.height())
+    if (rect.width() < topLeftRadius.width() + topRightRadius.width()
+            || rect.width() < bottomLeftRadius.width() + bottomRightRadius.width()
+            || rect.height() < topLeftRadius.height() + bottomLeftRadius.height()
+            || rect.height() < topRightRadius.height() + bottomRightRadius.height()) {
         // If all the radii cannot be accommodated, return a rect.
-        return createRectangle(rectangle);
-
-    float x = rectangle.x();
-    float y = rectangle.y();
-
-    path.moveTo(FloatPoint(x + topLeftRadius.width(), y));
-
-    path.addLineTo(FloatPoint(x + width - topRightRadius.width(), y));
-
-    path.addBezierCurveTo(FloatPoint(x + width - topRightRadius.width() * (1 - QUARTER), y), FloatPoint(x + width, y + topRightRadius.height() * (1 - QUARTER)), FloatPoint(x + width, y + topRightRadius.height()));
-
-    path.addLineTo(FloatPoint(x + width, y + height - bottomRightRadius.height()));
-
-    path.addBezierCurveTo(FloatPoint(x + width, y + height - bottomRightRadius.height() * (1 - QUARTER)), FloatPoint(x + width - bottomRightRadius.width() * (1 - QUARTER), y + height), FloatPoint(x + width - bottomRightRadius.width(), y + height));
-
-    path.addLineTo(FloatPoint(x + bottomLeftRadius.width(), y + height));
-
-    path.addBezierCurveTo(FloatPoint(x + bottomLeftRadius.width() * (1 - QUARTER), y + height), FloatPoint(x, y + height - bottomLeftRadius.height() * (1 - QUARTER)), FloatPoint(x, y + height - bottomLeftRadius.height()));
-
-    path.addLineTo(FloatPoint(x, y + topLeftRadius.height()));
-
-    path.addBezierCurveTo(FloatPoint(x, y + topLeftRadius.height() * (1 - QUARTER)), FloatPoint(x + topLeftRadius.width() * (1 - QUARTER), y), FloatPoint(x + topLeftRadius.width(), y));
-
-    path.closeSubpath();
-
-    return path;
-}
-
-Path Path::createRectangle(const FloatRect& rectangle)
-{
-    Path path;
-    float x = rectangle.x();
-    float y = rectangle.y();
-    float width = rectangle.width();
-    float height = rectangle.height();
-    if (width <= 0.0f || height <= 0.0f)
-        return path;
-    
-    path.moveTo(FloatPoint(x, y));
-    path.addLineTo(FloatPoint(x + width, y));
-    path.addLineTo(FloatPoint(x + width, y + height));
-    path.addLineTo(FloatPoint(x, y + height));
-    path.closeSubpath();
-
-    return path;
-}
-
-Path Path::createEllipse(const FloatPoint& center, float rx, float ry)
-{
-    float cx = center.x();
-    float cy = center.y();
-    Path path;
-    if (rx <= 0.0f || ry <= 0.0f)
-        return path;
-
-    float x = cx;
-    float y = cy;
-
-    unsigned step = 0, num = 100;
-    bool running = true;
-    while (running)
-    {
-        if (step == num)
-        {
-            running = false;
-            break;
-        }
-
-        float angle = static_cast<float>(step) / static_cast<float>(num) * 2.0f * piFloat;
-        x = cx + cosf(angle) * rx;
-        y = cy + sinf(angle) * ry;
-
-        step++;
-        if (step == 1)
-            path.moveTo(FloatPoint(x, y));
-        else
-            path.addLineTo(FloatPoint(x, y));
+        addRect(rect);
+        return;
     }
 
-    path.closeSubpath();
-
-    return path;
-}
-
-Path Path::createCircle(const FloatPoint& center, float r)
-{
-    return createEllipse(center, r, r);
-}
-
-Path Path::createLine(const FloatPoint& start, const FloatPoint& end)
-{
-    Path path;
-
-    path.moveTo(start);
-    path.addLineTo(end);
-
-    return path;
+    moveTo(FloatPoint(rect.x() + topLeftRadius.width(), rect.y()));
+
+    addLineTo(FloatPoint(rect.x() + rect.width() - topRightRadius.width(), rect.y()));
+    addBezierCurveTo(FloatPoint(rect.x() + rect.width() - topRightRadius.width() * gCircleControlPoint, rect.y()),
+                     FloatPoint(rect.x() + rect.width(), rect.y() + topRightRadius.height() * gCircleControlPoint),
+                     FloatPoint(rect.x() + rect.width(), rect.y() + topRightRadius.height()));
+    addLineTo(FloatPoint(rect.x() + rect.width(), rect.y() + rect.height() - bottomRightRadius.height()));
+    addBezierCurveTo(FloatPoint(rect.x() + rect.width(), rect.y() + rect.height() - bottomRightRadius.height() * gCircleControlPoint),
+                     FloatPoint(rect.x() + rect.width() - bottomRightRadius.width() * gCircleControlPoint, rect.y() + rect.height()),
+                     FloatPoint(rect.x() + rect.width() - bottomRightRadius.width(), rect.y() + rect.height()));
+    addLineTo(FloatPoint(rect.x() + bottomLeftRadius.width(), rect.y() + rect.height()));
+    addBezierCurveTo(FloatPoint(rect.x() + bottomLeftRadius.width() * gCircleControlPoint, rect.y() + rect.height()),
+                     FloatPoint(rect.x(), rect.y() + rect.height() - bottomLeftRadius.height() * gCircleControlPoint),
+                     FloatPoint(rect.x(), rect.y() + rect.height() - bottomLeftRadius.height()));
+    addLineTo(FloatPoint(rect.x(), rect.y() + topLeftRadius.height()));
+    addBezierCurveTo(FloatPoint(rect.x(), rect.y() + topLeftRadius.height() * gCircleControlPoint),
+                     FloatPoint(rect.x() + topLeftRadius.width() * gCircleControlPoint, rect.y()),
+                     FloatPoint(rect.x() + topLeftRadius.width(), rect.y()));
+
+    closeSubpath();
 }
 
 }
diff --git a/WebCore/platform/graphics/Path.h b/WebCore/platform/graphics/Path.h
index 8260a38..86ba831 100644
--- a/WebCore/platform/graphics/Path.h
+++ b/WebCore/platform/graphics/Path.h
@@ -137,18 +137,13 @@ namespace WebCore {
         void addArc(const FloatPoint&, float radius, float startAngle, float endAngle, bool anticlockwise);
         void addRect(const FloatRect&);
         void addEllipse(const FloatRect&);
+        void addRoundedRect(const FloatRect&, const FloatSize& roundingRadii);
+        void addRoundedRect(const FloatRect&, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius);
 
         void translate(const FloatSize&);
 
         PlatformPathPtr platformPath() const { return m_path; }
 
-        static Path createRoundedRectangle(const FloatRect&, const FloatSize& roundingRadii);
-        static Path createRoundedRectangle(const FloatRect&, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius);
-        static Path createRectangle(const FloatRect&);
-        static Path createEllipse(const FloatPoint& center, float rx, float ry);
-        static Path createCircle(const FloatPoint& center, float r);
-        static Path createLine(const FloatPoint&, const FloatPoint&);
-
         void apply(void* info, PathApplierFunction) const;
         void transform(const AffineTransform&);
 
diff --git a/WebCore/platform/graphics/cairo/ContextShadowCairo.cpp b/WebCore/platform/graphics/cairo/ContextShadowCairo.cpp
index 6f5be28..8299b6a 100644
--- a/WebCore/platform/graphics/cairo/ContextShadowCairo.cpp
+++ b/WebCore/platform/graphics/cairo/ContextShadowCairo.cpp
@@ -134,8 +134,10 @@ void ContextShadow::drawRectShadowWithoutTiling(PlatformContext context, const I
     if (!m_layerContext)
         return;
 
-    appendWebCorePathToCairoContext(m_layerContext, Path::createRoundedRectangle(shadowRect, topLeftRadius, topRightRadius,
-                                                                                 bottomLeftRadius, bottomRightRadius));
+    Path path;
+    path.addRoundedRect(shadowRect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
+
+    appendWebCorePathToCairoContext(m_layerContext, path);
     cairo_set_source_rgba(m_layerContext, 0, 0, 0, alpha);
     cairo_fill(m_layerContext);
 
@@ -240,8 +242,9 @@ void ContextShadow::drawRectShadow(GraphicsContext* context, const IntRect& rect
 
     // Draw the rectangle.
     IntRect templateRect = IntRect(m_blurDistance, m_blurDistance, shadowTemplateSize.width() - radiusTwice, shadowTemplateSize.height() - radiusTwice);
-    appendWebCorePathToCairoContext(m_layerContext, Path::createRoundedRectangle(templateRect, topLeftRadius, topRightRadius,
-                                                                                 bottomLeftRadius, bottomRightRadius));
+    Path path;
+    path.addRoundedRect(templateRect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
+    appendWebCorePathToCairoContext(m_layerContext, path);
 
     cairo_set_source_rgba(m_layerContext, 0, 0, 0, context->getAlpha());
     cairo_fill(m_layerContext);
@@ -263,8 +266,9 @@ void ContextShadow::drawRectShadow(GraphicsContext* context, const IntRect& rect
     shadowRect.inflate(-radiusTwice);
     if (!shadowRect.isEmpty()) {
         cairo_save(cr);
-        appendWebCorePathToCairoContext(cr, Path::createRoundedRectangle(shadowRect, topLeftRadius,
-                                                                              topRightRadius, bottomLeftRadius, bottomRightRadius));
+        path.clear();
+        path.addRoundedRect(shadowRect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
+        appendWebCorePathToCairoContext(cr, path);
         setSourceRGBAFromColor(cr, m_color);
         cairo_fill(cr);
         cairo_restore(cr);
diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
index e94dfba..a4b644c 100644
--- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
+++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
@@ -703,8 +703,13 @@ void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int
     setPlatformStrokeStyle(DottedStroke);
 #else
     int radius = (width - 1) / 2;
-    for (unsigned i = 0; i < rectCount; i++)
-        appendWebCorePathToCairoContext(cr, Path::createRoundedRectangle(rects[i], FloatSize(radius, radius)));
+    Path path;
+    for (unsigned i = 0; i < rectCount; ++i) {
+        if (i > 0)
+            path.clear();
+        path.addRoundedRect(rects[i], FloatSize(radius, radius));
+        appendWebCorePathToCairoContext(cr, path);
+    }
 
     // Force the alpha to 50%.  This matches what the Mac does with outline rings.
     Color ringColor(color.red(), color.green(), color.blue(), 127);
@@ -1275,7 +1280,10 @@ void GraphicsContext::drawTiledShadow(const IntRect& rect, const FloatSize& topL
     // Draw shadow into a new ImageBuffer.
     cairo_t* smallBufferContext = smallBuffer->context()->platformContext();
     copyContextProperties(cr, smallBufferContext);
-    appendWebCorePathToCairoContext(smallBuffer->context()->platformContext(), Path::createRoundedRectangle(smallRect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius));
+
+    Path path;
+    path.addRoundedRect(smallRect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
+    appendWebCorePathToCairoContext(smallBuffer->context()->platformContext(), path);
     setPlatformFill(this, smallBufferContext, m_common);
 
     OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(smallBufferSize);
@@ -1294,7 +1302,9 @@ void GraphicsContext::drawTiledShadow(const IntRect& rect, const FloatSize& topL
     shadowRect.inflate(-radiusTwice);
     if (!shadowRect.isEmpty()) {
         cairo_save(cr);
-        appendWebCorePathToCairoContext(cr, Path::createRoundedRectangle(shadowRect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius));
+        path.clear();
+        path.addRoundedRect(shadowRect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
+        appendWebCorePathToCairoContext(cr, path);
         setColor(cr, shadowColor);
         cairo_fill(cr);
         cairo_restore(cr);
@@ -1373,7 +1383,9 @@ void GraphicsContext::fillRoundedRect(const IntRect& r, const IntSize& topLeft,
 
     cairo_t* cr = m_data->cr;
     cairo_save(cr);
-    appendWebCorePathToCairoContext(cr, Path::createRoundedRectangle(r, topLeft, topRight, bottomLeft, bottomRight));
+    Path path;
+    path.addRoundedRect(r, topLeft, topRight, bottomLeft, bottomRight);
+    appendWebCorePathToCairoContext(cr, path);
     setColor(cr, color);
     drawPathShadow(this, m_common, true, false);
     cairo_fill(cr);
diff --git a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
index bd8e850..06c0f00 100644
--- a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
+++ b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
@@ -667,7 +667,9 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef
     if (oldFillColor != color || oldColorSpace != colorSpace)
         setCGFillColor(context, color, colorSpace);
 
-    addPath(Path::createRoundedRectangle(rect, topLeft, topRight, bottomLeft, bottomRight));
+    Path path;
+    path.addRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight);
+    addPath(path);
     fillPath();
 
     if (oldFillColor != color || oldColorSpace != colorSpace)
diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index 7775721..6d6c1fc 100644
--- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -729,7 +729,8 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef
     if (paintingDisabled() || !color.isValid())
         return;
 
-    Path path = Path::createRoundedRectangle(rect, topLeft, topRight, bottomLeft, bottomRight);
+    Path path;
+    path.addRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight);
     QPainter* p = m_data->p();
     if (m_data->hasShadow()) {
         p->translate(m_data->shadow.offset());
diff --git a/WebCore/rendering/RenderBoxModelObject.cpp b/WebCore/rendering/RenderBoxModelObject.cpp
index 02a2847..9b8cab9 100644
--- a/WebCore/rendering/RenderBoxModelObject.cpp
+++ b/WebCore/rendering/RenderBoxModelObject.cpp
@@ -1061,7 +1061,7 @@ void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, int tx,
         graphicsContext->addRoundedRectClip(borderRect, topLeft, topRight, bottomLeft, bottomRight);
         graphicsContext->clipOutRoundedRect(innerBorderRect, innerTopLeftRadius, innerTopRightRadius, innerBottomLeftRadius, innerBottomRightRadius);
 
-        roundedPath = Path::createRoundedRectangle(borderRect, topLeft, topRight, bottomLeft, bottomRight);
+        roundedPath.addRoundedRect(borderRect, topLeft, topRight, bottomLeft, bottomRight);
         graphicsContext->addPath(roundedPath);
     }
 
@@ -1752,24 +1752,29 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
 
             context->save();
 
-            if (hasBorderRadius)
-                context->clip(Path::createRoundedRectangle(rect, topLeft, topRight, bottomLeft, bottomRight));
-            else
+            Path path;
+            if (hasBorderRadius) {
+                path.addRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight);
+                context->clip(path);
+                path.clear();
+            } else
                 context->clip(rect);
 
             IntSize extraOffset(2 * w + max(0, shadowOffset.width()) + shadowBlur - 2 * shadowSpread + 1, 0);
             context->translate(extraOffset.width(), extraOffset.height());
             shadowOffset -= extraOffset;
 
-            context->beginPath();
-            context->addPath(Path::createRectangle(outerRect));
+            path.addRect(outerRect);
 
             if (hasBorderRadius) {
                 if (shadowSpread > 0)
                     uniformlyExpandBorderRadii(-shadowSpread, topLeft, topRight, bottomLeft, bottomRight);
-                context->addPath(Path::createRoundedRectangle(holeRect, topLeft, topRight, bottomLeft, bottomRight));
+                path.addRoundedRect(holeRect, topLeft, topRight, bottomLeft, bottomRight);
             } else
-                context->addPath(Path::createRectangle(holeRect));
+                path.addRect(holeRect);
+
+            context->beginPath();
+            context->addPath(path);
 
             context->setFillRule(RULE_EVENODD);
             context->setFillColor(fillColor, s->colorSpace());
diff --git a/WebCore/rendering/RenderEmbeddedObject.cpp b/WebCore/rendering/RenderEmbeddedObject.cpp
index aa301e2..16613a5 100644
--- a/WebCore/rendering/RenderEmbeddedObject.cpp
+++ b/WebCore/rendering/RenderEmbeddedObject.cpp
@@ -206,7 +206,7 @@ bool RenderEmbeddedObject::getReplacementTextGeometry(int tx, int ty, FloatRect&
     float y = (contentRect.size().height() / 2 - replacementTextRect.size().height() / 2) + contentRect.location().y();
     replacementTextRect.setLocation(FloatPoint(x, y));
     
-    path = Path::createRoundedRectangle(replacementTextRect, FloatSize(replacementTextRoundedRectRadius, replacementTextRoundedRectRadius));
+    path.addRoundedRect(replacementTextRect, FloatSize(replacementTextRoundedRectRadius, replacementTextRoundedRectRadius));
 
     return true;
 }
diff --git a/WebCore/rendering/RenderSVGResourceClipper.cpp b/WebCore/rendering/RenderSVGResourceClipper.cpp
index a09afb2..2659d64 100644
--- a/WebCore/rendering/RenderSVGResourceClipper.cpp
+++ b/WebCore/rendering/RenderSVGResourceClipper.cpp
@@ -136,7 +136,7 @@ bool RenderSVGResourceClipper::pathOnlyClipping(GraphicsContext* context, const
             return false;
         // Fallback to masking, if there is more than one clipping path.
         if (clipPath.isEmpty()) {
-            clipPath = styled->toClipPath();
+            styled->toClipPath(clipPath);
             clipRule = svgStyle->clipRule();
         } else
             return false;
diff --git a/WebCore/rendering/svg/RenderSVGPath.cpp b/WebCore/rendering/svg/RenderSVGPath.cpp
index ada360a..483303f 100644
--- a/WebCore/rendering/svg/RenderSVGPath.cpp
+++ b/WebCore/rendering/svg/RenderSVGPath.cpp
@@ -112,7 +112,8 @@ void RenderSVGPath::layout()
 
     bool needsPathUpdate = m_needsPathUpdate;
     if (needsPathUpdate) {
-        m_path = element->toPathData();
+        m_path.clear();
+        element->toPathData(m_path);
         m_needsPathUpdate = false;
         updateCachedBoundariesInParents = true;
     }
diff --git a/WebCore/rendering/svg/RenderSVGTextPath.cpp b/WebCore/rendering/svg/RenderSVGTextPath.cpp
index 5d977f9..64ebc6d 100644
--- a/WebCore/rendering/svg/RenderSVGTextPath.cpp
+++ b/WebCore/rendering/svg/RenderSVGTextPath.cpp
@@ -53,7 +53,8 @@ Path RenderSVGTextPath::layoutPath() const
     
     SVGPathElement* pathElement = static_cast<SVGPathElement*>(targetElement);
     
-    Path pathData = pathElement->toPathData();
+    Path pathData;
+    pathElement->toPathData(pathData);
     // Spec:  The transform attribute on the referenced 'path' element represents a
     // supplemental transformation relative to the current user coordinate system for
     // the current 'text' element, including any adjustments to the current user coordinate
diff --git a/WebCore/rendering/svg/SVGInlineTextBox.cpp b/WebCore/rendering/svg/SVGInlineTextBox.cpp
index 8352ee5..72f15dd 100644
--- a/WebCore/rendering/svg/SVGInlineTextBox.cpp
+++ b/WebCore/rendering/svg/SVGInlineTextBox.cpp
@@ -490,11 +490,18 @@ void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, ETextD
 
     // The initial y value refers to overline position.
     float thickness = thicknessForDecoration(decoration, font);
+
+    if (fragment.width <= 0 && thickness <= 0)
+        return;
+
     float y = fragment.y - font.ascent() + positionOffsetForDecoration(decoration, font, thickness);
 
+    Path path;
+    path.addRect(FloatRect(fragment.x, y, fragment.width, thickness));
+
     context->save();
     context->beginPath();
-    context->addPath(Path::createRectangle(FloatRect(fragment.x, y, fragment.width, thickness)));
+    context->addPath(path);
 
     if (acquirePaintingResource(context, decorationRenderer, decorationStyle))
         releasePaintingResource(context);
diff --git a/WebCore/svg/SVGAnimateMotionElement.cpp b/WebCore/svg/SVGAnimateMotionElement.cpp
index b50a993..26151ed 100644
--- a/WebCore/svg/SVGAnimateMotionElement.cpp
+++ b/WebCore/svg/SVGAnimateMotionElement.cpp
@@ -112,9 +112,10 @@ Path SVGAnimateMotionElement::animationPath() const
         if (child->hasTagName(SVGNames::mpathTag)) {
             SVGMPathElement* mPath = static_cast<SVGMPathElement*>(child);
             SVGPathElement* pathElement = mPath->pathElement();
+            Path path;
             if (pathElement)
-                return pathElement->toPathData();
-            return Path();
+                pathElement->toPathData(path);
+            return path;
         }
     }
     if (hasAttribute(SVGNames::pathAttr))
diff --git a/WebCore/svg/SVGCircleElement.cpp b/WebCore/svg/SVGCircleElement.cpp
index 4ed4efe..eb38b87 100644
--- a/WebCore/svg/SVGCircleElement.cpp
+++ b/WebCore/svg/SVGCircleElement.cpp
@@ -121,9 +121,16 @@ void SVGCircleElement::synchronizeProperty(const QualifiedName& attrName)
         synchronizeExternalResourcesRequired();
 }
 
-Path SVGCircleElement::toPathData() const
+void SVGCircleElement::toPathData(Path& path) const
 {
-    return Path::createCircle(FloatPoint(cx().value(this), cy().value(this)), r().value(this));
+    ASSERT(path.isEmpty());
+
+    float radius = r().value(this);
+
+    if (radius <= 0)
+        return;
+
+    path.addEllipse(FloatRect(cx().value(this) - radius, cy().value(this) - radius, radius * 2, radius * 2));
 }
 
 bool SVGCircleElement::selfHasRelativeLengths() const
diff --git a/WebCore/svg/SVGCircleElement.h b/WebCore/svg/SVGCircleElement.h
index dd11792..4eb9262 100644
--- a/WebCore/svg/SVGCircleElement.h
+++ b/WebCore/svg/SVGCircleElement.h
@@ -45,7 +45,7 @@ namespace WebCore {
         virtual void svgAttributeChanged(const QualifiedName&);
         virtual void synchronizeProperty(const QualifiedName&);
 
-        virtual Path toPathData() const;
+        virtual void toPathData(Path&) const;
 
         virtual bool selfHasRelativeLengths() const;
 
diff --git a/WebCore/svg/SVGEllipseElement.cpp b/WebCore/svg/SVGEllipseElement.cpp
index 16743ed..7615a24 100644
--- a/WebCore/svg/SVGEllipseElement.cpp
+++ b/WebCore/svg/SVGEllipseElement.cpp
@@ -130,10 +130,19 @@ void SVGEllipseElement::synchronizeProperty(const QualifiedName& attrName)
         synchronizeExternalResourcesRequired();
 }
 
-Path SVGEllipseElement::toPathData() const
+void SVGEllipseElement::toPathData(Path& path) const
 {
-    return Path::createEllipse(FloatPoint(cx().value(this), cy().value(this)),
-                                          rx().value(this), ry().value(this));
+    ASSERT(path.isEmpty());
+
+    float radiusX = rx().value(this);
+    if (radiusX <= 0)
+        return;
+
+    float radiusY = ry().value(this);
+    if (radiusY <= 0)
+        return;
+
+    path.addEllipse(FloatRect(cx().value(this) - radiusX, cy().value(this) - radiusY, radiusX * 2, radiusY * 2));
 }
  
 bool SVGEllipseElement::selfHasRelativeLengths() const
diff --git a/WebCore/svg/SVGEllipseElement.h b/WebCore/svg/SVGEllipseElement.h
index bee815c..cad329e 100644
--- a/WebCore/svg/SVGEllipseElement.h
+++ b/WebCore/svg/SVGEllipseElement.h
@@ -45,7 +45,7 @@ namespace WebCore {
         virtual void svgAttributeChanged(const QualifiedName&);
         virtual void synchronizeProperty(const QualifiedName&);
 
-        virtual Path toPathData() const;
+        virtual void toPathData(Path&) const;
 
         virtual bool selfHasRelativeLengths() const;
 
diff --git a/WebCore/svg/SVGLineElement.cpp b/WebCore/svg/SVGLineElement.cpp
index 229dfa9..4ee5f0d 100644
--- a/WebCore/svg/SVGLineElement.cpp
+++ b/WebCore/svg/SVGLineElement.cpp
@@ -126,10 +126,12 @@ void SVGLineElement::synchronizeProperty(const QualifiedName& attrName)
         synchronizeExternalResourcesRequired();
 }
 
-Path SVGLineElement::toPathData() const
+void SVGLineElement::toPathData(Path& path) const
 {
-    return Path::createLine(FloatPoint(x1().value(this), y1().value(this)),
-                            FloatPoint(x2().value(this), y2().value(this)));
+    ASSERT(path.isEmpty());
+
+    path.moveTo(FloatPoint(x1().value(this), y1().value(this)));
+    path.addLineTo(FloatPoint(x2().value(this), y2().value(this)));
 }
 
 bool SVGLineElement::selfHasRelativeLengths() const
diff --git a/WebCore/svg/SVGLineElement.h b/WebCore/svg/SVGLineElement.h
index 21007f0..55a268c 100644
--- a/WebCore/svg/SVGLineElement.h
+++ b/WebCore/svg/SVGLineElement.h
@@ -47,7 +47,7 @@ namespace WebCore {
         virtual void svgAttributeChanged(const QualifiedName&);
         virtual void synchronizeProperty(const QualifiedName&);
 
-        virtual Path toPathData() const;
+        virtual void toPathData(Path&) const;
 
         virtual bool supportsMarkers() const { return true; }
 
diff --git a/WebCore/svg/SVGPathElement.cpp b/WebCore/svg/SVGPathElement.cpp
index d1fc11b..920e947 100644
--- a/WebCore/svg/SVGPathElement.cpp
+++ b/WebCore/svg/SVGPathElement.cpp
@@ -57,14 +57,18 @@ PassRefPtr<SVGPathElement> SVGPathElement::create(const QualifiedName& tagName,
 float SVGPathElement::getTotalLength()
 {
     // FIXME: this may wish to use the pathSegList instead of the pathdata if that's cheaper to build (or cached)
-    return toPathData().length();
+    Path path;
+    toPathData(path);
+    return path.length();
 }
 
 FloatPoint SVGPathElement::getPointAtLength(float length)
 {
     // FIXME: this may wish to use the pathSegList instead of the pathdata if that's cheaper to build (or cached)
     bool ok = false;
-    return toPathData().pointAtLength(length, ok);
+    Path path;
+    toPathData(path);
+    return path.pointAtLength(length, ok);
 }
 
 unsigned long SVGPathElement::getPathSegAtLength(float length)
@@ -262,12 +266,12 @@ SVGPathSegList* SVGPathElement::animatedNormalizedPathSegList() const
     return 0;
 }
 
-Path SVGPathElement::toPathData() const
+void SVGPathElement::toPathData(Path& path) const
 {
-    Path result;
+    ASSERT(path.isEmpty());
+
     SVGPathParserFactory* factory = SVGPathParserFactory::self();
-    factory->buildPathFromSVGPathSegList(pathSegList(), result);
-    return result;
+    factory->buildPathFromSVGPathSegList(pathSegList(), path);
 }
 
 }
diff --git a/WebCore/svg/SVGPathElement.h b/WebCore/svg/SVGPathElement.h
index cc4e7bd..394983d 100644
--- a/WebCore/svg/SVGPathElement.h
+++ b/WebCore/svg/SVGPathElement.h
@@ -89,7 +89,7 @@ namespace WebCore {
         virtual SVGPathSegList* animatedPathSegList() const;
         virtual SVGPathSegList* animatedNormalizedPathSegList() const;
 
-        virtual Path toPathData() const;
+        virtual void toPathData(Path&) const;
 
     private:
         SVGPathElement(const QualifiedName&, Document*);
diff --git a/WebCore/svg/SVGPolygonElement.cpp b/WebCore/svg/SVGPolygonElement.cpp
index 57e2d53..38f5bce 100644
--- a/WebCore/svg/SVGPolygonElement.cpp
+++ b/WebCore/svg/SVGPolygonElement.cpp
@@ -37,22 +37,21 @@ PassRefPtr<SVGPolygonElement> SVGPolygonElement::create(const QualifiedName& tag
     return adoptRef(new SVGPolygonElement(tagName, document));
 }
 
-Path SVGPolygonElement::toPathData() const
+void SVGPolygonElement::toPathData(Path& path) const
 {
-    Path polyData;
+    ASSERT(path.isEmpty());
 
     int len = points()->numberOfItems();
     if (len < 1)
-        return polyData;
+        return;
     
     ExceptionCode ec = 0;
-    polyData.moveTo(points()->getItem(0, ec));
+    path.moveTo(points()->getItem(0, ec));
 
     for (int i = 1; i < len; ++i)
-        polyData.addLineTo(points()->getItem(i, ec));
+        path.addLineTo(points()->getItem(i, ec));
 
-    polyData.closeSubpath();
-    return polyData;
+    path.closeSubpath();
 }
 
 }
diff --git a/WebCore/svg/SVGPolygonElement.h b/WebCore/svg/SVGPolygonElement.h
index 7a5bda8..5c88d11 100644
--- a/WebCore/svg/SVGPolygonElement.h
+++ b/WebCore/svg/SVGPolygonElement.h
@@ -33,7 +33,7 @@ namespace WebCore {
     private:
         SVGPolygonElement(const QualifiedName&, Document*);
 
-        virtual Path toPathData() const;
+        virtual void toPathData(Path&) const;
     };
 
 } // namespace WebCore
diff --git a/WebCore/svg/SVGPolylineElement.cpp b/WebCore/svg/SVGPolylineElement.cpp
index 7ec8431..c9750b2 100644
--- a/WebCore/svg/SVGPolylineElement.cpp
+++ b/WebCore/svg/SVGPolylineElement.cpp
@@ -37,21 +37,19 @@ PassRefPtr<SVGPolylineElement> SVGPolylineElement::create(const QualifiedName& t
     return adoptRef(new SVGPolylineElement(tagName, document));
 }
 
-Path SVGPolylineElement::toPathData() const
+void SVGPolylineElement::toPathData(Path& path) const
 {
-    Path polyData;
+    ASSERT(path.isEmpty());
 
     int len = points()->numberOfItems();
     if (len < 1)
-        return polyData;
+        return;
 
     ExceptionCode ec = 0;
-    polyData.moveTo(points()->getItem(0, ec));
+    path.moveTo(points()->getItem(0, ec));
 
     for (int i = 1; i < len; ++i)
-        polyData.addLineTo(points()->getItem(i, ec));
-    
-    return polyData;
+        path.addLineTo(points()->getItem(i, ec));
 }
 
 }
diff --git a/WebCore/svg/SVGPolylineElement.h b/WebCore/svg/SVGPolylineElement.h
index d3fe555..dfcfcda 100644
--- a/WebCore/svg/SVGPolylineElement.h
+++ b/WebCore/svg/SVGPolylineElement.h
@@ -33,7 +33,7 @@ namespace WebCore {
     private:
         SVGPolylineElement(const QualifiedName&, Document*);
 
-        virtual Path toPathData() const;
+        virtual void toPathData(Path&) const;
     };
 
 } // namespace WebCore
diff --git a/WebCore/svg/SVGRectElement.cpp b/WebCore/svg/SVGRectElement.cpp
index 9b6830e..46ed8de 100644
--- a/WebCore/svg/SVGRectElement.cpp
+++ b/WebCore/svg/SVGRectElement.cpp
@@ -147,19 +147,37 @@ void SVGRectElement::synchronizeProperty(const QualifiedName& attrName)
         synchronizeExternalResourcesRequired();
 }
 
-Path SVGRectElement::toPathData() const
+void SVGRectElement::toPathData(Path& path) const
 {
-    FloatRect rect(x().value(this), y().value(this), width().value(this), height().value(this));
+    ASSERT(path.isEmpty());
+
+    float widthValue = width().value(this);
+    if (widthValue <= 0)
+        return;
+
+    float heightValue = height().value(this);
+    if (heightValue <= 0)
+        return;
+
+    float xValue = x().value(this);
+    float yValue = y().value(this);
+
+    FloatRect rect(xValue, yValue, widthValue, heightValue);
 
     bool hasRx = hasAttribute(SVGNames::rxAttr);
     bool hasRy = hasAttribute(SVGNames::ryAttr);
     if (hasRx || hasRy) {
-        float _rx = hasRx ? rx().value(this) : ry().value(this);
-        float _ry = hasRy ? ry().value(this) : rx().value(this);
-        return Path::createRoundedRectangle(rect, FloatSize(_rx, _ry));
+        float rxValue = rx().value(this);
+        float ryValue = ry().value(this);
+        if (!hasRx)
+            rxValue = ryValue;
+        else if (!hasRy)
+            ryValue = rxValue;
+        path.addRoundedRect(rect, FloatSize(rxValue, ryValue));
+        return;
     }
 
-    return Path::createRectangle(rect);
+    path.addRect(rect);
 }
 
 bool SVGRectElement::selfHasRelativeLengths() const
diff --git a/WebCore/svg/SVGRectElement.h b/WebCore/svg/SVGRectElement.h
index 382078d..668366b 100644
--- a/WebCore/svg/SVGRectElement.h
+++ b/WebCore/svg/SVGRectElement.h
@@ -45,7 +45,7 @@ namespace WebCore {
         virtual void svgAttributeChanged(const QualifiedName&);
         virtual void synchronizeProperty(const QualifiedName&);
 
-        virtual Path toPathData() const;
+        virtual void toPathData(Path&) const;
 
         virtual bool selfHasRelativeLengths() const;
 
diff --git a/WebCore/svg/SVGStyledTransformableElement.cpp b/WebCore/svg/SVGStyledTransformableElement.cpp
index 4419443..9b34203 100644
--- a/WebCore/svg/SVGStyledTransformableElement.cpp
+++ b/WebCore/svg/SVGStyledTransformableElement.cpp
@@ -111,12 +111,11 @@ RenderObject* SVGStyledTransformableElement::createRenderer(RenderArena* arena,
     return new (arena) RenderSVGPath(this);
 }
 
-Path SVGStyledTransformableElement::toClipPath() const
+void SVGStyledTransformableElement::toClipPath(Path& path) const
 {
-    Path pathData = toPathData();
+    toPathData(path);
     // FIXME: How do we know the element has done a layout?
-    pathData.transform(animatedLocalTransform());
-    return pathData;
+    path.transform(animatedLocalTransform());
 }
 
 }
diff --git a/WebCore/svg/SVGStyledTransformableElement.h b/WebCore/svg/SVGStyledTransformableElement.h
index 290f7f8..5349cfa 100644
--- a/WebCore/svg/SVGStyledTransformableElement.h
+++ b/WebCore/svg/SVGStyledTransformableElement.h
@@ -49,8 +49,8 @@ public:
     bool isKnownAttribute(const QualifiedName&);
 
     // "base class" methods for all the elements which render as paths
-    virtual Path toPathData() const { return Path(); }
-    virtual Path toClipPath() const;
+    virtual void toPathData(Path&) const { }
+    virtual void toClipPath(Path&) const;
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
 
 protected:
diff --git a/WebCore/svg/SVGUseElement.cpp b/WebCore/svg/SVGUseElement.cpp
index 782efa8..12786ee 100644
--- a/WebCore/svg/SVGUseElement.cpp
+++ b/WebCore/svg/SVGUseElement.cpp
@@ -624,25 +624,24 @@ static bool isDirectReference(Node* n)
            n->hasTagName(SVGNames::textTag);
 }
 
-Path SVGUseElement::toClipPath() const
+void SVGUseElement::toClipPath(Path& path) const
 {
+    ASSERT(path.isEmpty());
+
     Node* n = m_targetElementInstance ? m_targetElementInstance->shadowTreeElement() : 0;
     if (!n)
-        return Path();
+        return;
 
     if (n->isSVGElement() && static_cast<SVGElement*>(n)->isStyledTransformable()) {
         if (!isDirectReference(n))
             // Spec: Indirect references are an error (14.3.5)
             document()->accessSVGExtensions()->reportError("Not allowed to use indirect reference in <clip-path>");
         else {
-            Path clipPath = static_cast<SVGStyledTransformableElement*>(n)->toClipPath();
-            clipPath.translate(FloatSize(x().value(this), y().value(this)));
-            clipPath.transform(animatedLocalTransform());
-            return clipPath;
+            static_cast<SVGStyledTransformableElement*>(n)->toClipPath(path);
+            path.translate(FloatSize(x().value(this), y().value(this)));
+            path.transform(animatedLocalTransform());
         }
     }
-
-    return Path();
 }
 
 RenderObject* SVGUseElement::rendererClipChild() const
diff --git a/WebCore/svg/SVGUseElement.h b/WebCore/svg/SVGUseElement.h
index 9366d25..b8ba71d 100644
--- a/WebCore/svg/SVGUseElement.h
+++ b/WebCore/svg/SVGUseElement.h
@@ -67,7 +67,7 @@ namespace WebCore {
         virtual void attach();
         virtual void detach();
 
-        virtual Path toClipPath() const;
+        virtual void toClipPath(Path&) const;
 
         static void removeDisallowedElementsFromSubtree(Node* element);
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list