[Cherry-pick] Use -webkit-clip-path shapes to clip SVG elements
authorkrit@webkit.org <krit@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 2 Sep 2012 00:15:33 +0000 (00:15 +0000)
committerGerrit Code Review <gerrit2@kim11>
Wed, 27 Mar 2013 06:14:47 +0000 (15:14 +0900)
[Title] Use -webkit-clip-path shapes to clip SVG elements
[Issues] N/A
[Problem] N/A
[Solution] Cherry picked.
[Cherry-Picker] Sanghyup Lee <sh53.lee@samsung.com>

Use -webkit-clip-path shapes to clip SVG elements
https://bugs.webkit.org/show_bug.cgi?id=95620

Reviewed by Rob Buis.

Source/WebCore:

This patch adds a path segment for a BasicShape to a given Path object. This
path and it's wind rule are used to clip the context of the SVG element.

Tests: svg/clip-path/clip-path-shape-circle-1-expected.svg
       svg/clip-path/clip-path-shape-circle-1.svg
       svg/clip-path/clip-path-shape-circle-2-expected.svg
       svg/clip-path/clip-path-shape-circle-2.svg
       svg/clip-path/clip-path-shape-ellipse-1-expected.svg
       svg/clip-path/clip-path-shape-ellipse-1.svg
       svg/clip-path/clip-path-shape-ellipse-2-expected.svg
       svg/clip-path/clip-path-shape-ellipse-2.svg
       svg/clip-path/clip-path-shape-polygon-1-expected.svg
       svg/clip-path/clip-path-shape-polygon-1.svg
       svg/clip-path/clip-path-shape-polygon-2-expected.svg
       svg/clip-path/clip-path-shape-polygon-2.svg
       svg/clip-path/clip-path-shape-polygon-3-expected.svg
       svg/clip-path/clip-path-shape-polygon-3.svg
       svg/clip-path/clip-path-shape-rounded-rect-1-expected.svg
       svg/clip-path/clip-path-shape-rounded-rect-1.svg
       svg/clip-path/clip-path-shape-rounded-rect-2-expected.svg
       svg/clip-path/clip-path-shape-rounded-rect-2.svg

* rendering/style/BasicShapes.cpp: Added helper functions that apply path segments to a given path.
(WebCore::BasicShapeRectangle::path):
(WebCore::BasicShapeCircle::path):
(WebCore::BasicShapeEllipse::path):
(WebCore::BasicShapePolygon::path):
* rendering/style/BasicShapes.h: Make BasicShape virtualized again, since new virtual functions were added.
(WebCore::BasicShape::~BasicShape):
(BasicShape):
(WebCore::BasicShape::windRule): Will return the wind rule of the shape - nonzero by default.
(WebCore::BasicShape::BasicShape):
(BasicShapeRectangle):
(WebCore::BasicShapeRectangle::type): Removed member variable and return type per inheriting class directly.
(WebCore::BasicShapeRectangle::BasicShapeRectangle):
(BasicShapeCircle):
(WebCore::BasicShapeCircle::type): Ditto.
(WebCore::BasicShapeCircle::BasicShapeCircle):
(BasicShapeEllipse):
(WebCore::BasicShapeEllipse::type): Ditto.
(WebCore::BasicShapeEllipse::BasicShapeEllipse):
(BasicShapePolygon):
(WebCore::BasicShapePolygon::windRule):
(WebCore::BasicShapePolygon::type): Ditto.
(WebCore::BasicShapePolygon::BasicShapePolygon):
* rendering/svg/SVGRenderingContext.cpp: If -webkit-clip-path was defined, clip the context to the shape.
Right now -webkit-clip-path overrides clip-path, so that people don't use both at the same time. Current
clip-path property will be replaced, once -webkit-clip-path gets unprefixed.
(WebCore::SVGRenderingContext::prepareToRenderSVGContent):

LayoutTests:

New tests to check behavior of -webkit-clip-path on SVG elements.

* svg/clip-path/clip-path-shape-circle-1-expected.svg: Added.
* svg/clip-path/clip-path-shape-circle-1.svg: Added.
* svg/clip-path/clip-path-shape-circle-2-expected.svg: Added.
* svg/clip-path/clip-path-shape-circle-2.svg: Added.
* svg/clip-path/clip-path-shape-ellipse-1-expected.svg: Added.
* svg/clip-path/clip-path-shape-ellipse-1.svg: Added.
* svg/clip-path/clip-path-shape-ellipse-2-expected.svg: Added.
* svg/clip-path/clip-path-shape-ellipse-2.svg: Added.
* svg/clip-path/clip-path-shape-polygon-1-expected.svg: Added.
* svg/clip-path/clip-path-shape-polygon-1.svg: Added.
* svg/clip-path/clip-path-shape-polygon-2-expected.svg: Added.
* svg/clip-path/clip-path-shape-polygon-2.svg: Added.
* svg/clip-path/clip-path-shape-polygon-3-expected.svg: Added.
* svg/clip-path/clip-path-shape-polygon-3.svg: Added.
* svg/clip-path/clip-path-shape-rounded-rect-1-expected.svg: Added.
* svg/clip-path/clip-path-shape-rounded-rect-1.svg: Added.
* svg/clip-path/clip-path-shape-rounded-rect-2-expected.svg: Added.
* svg/clip-path/clip-path-shape-rounded-rect-2.svg: Added.

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

Conflicts:

LayoutTests/ChangeLog
Source/WebCore/ChangeLog

Change-Id: I0aabeb470a8c5915120a48745bc79747531ba8d3

21 files changed:
LayoutTests/svg/clip-path/clip-path-shape-circle-1-expected.svg [new file with mode: 0644]
LayoutTests/svg/clip-path/clip-path-shape-circle-1.svg [new file with mode: 0644]
LayoutTests/svg/clip-path/clip-path-shape-circle-2-expected.svg [new file with mode: 0644]
LayoutTests/svg/clip-path/clip-path-shape-circle-2.svg [new file with mode: 0644]
LayoutTests/svg/clip-path/clip-path-shape-ellipse-1-expected.svg [new file with mode: 0644]
LayoutTests/svg/clip-path/clip-path-shape-ellipse-1.svg [new file with mode: 0644]
LayoutTests/svg/clip-path/clip-path-shape-ellipse-2-expected.svg [new file with mode: 0644]
LayoutTests/svg/clip-path/clip-path-shape-ellipse-2.svg [new file with mode: 0644]
LayoutTests/svg/clip-path/clip-path-shape-polygon-1-expected.svg [new file with mode: 0644]
LayoutTests/svg/clip-path/clip-path-shape-polygon-1.svg [new file with mode: 0644]
LayoutTests/svg/clip-path/clip-path-shape-polygon-2-expected.svg [new file with mode: 0644]
LayoutTests/svg/clip-path/clip-path-shape-polygon-2.svg [new file with mode: 0644]
LayoutTests/svg/clip-path/clip-path-shape-polygon-3-expected.svg [new file with mode: 0644]
LayoutTests/svg/clip-path/clip-path-shape-polygon-3.svg [new file with mode: 0644]
LayoutTests/svg/clip-path/clip-path-shape-rounded-rect-1-expected.svg [new file with mode: 0644]
LayoutTests/svg/clip-path/clip-path-shape-rounded-rect-1.svg [new file with mode: 0644]
LayoutTests/svg/clip-path/clip-path-shape-rounded-rect-2-expected.svg [new file with mode: 0644]
LayoutTests/svg/clip-path/clip-path-shape-rounded-rect-2.svg [new file with mode: 0644]
Source/WebCore/rendering/style/BasicShapes.cpp
Source/WebCore/rendering/style/BasicShapes.h
Source/WebCore/rendering/svg/SVGRenderingContext.cpp

diff --git a/LayoutTests/svg/clip-path/clip-path-shape-circle-1-expected.svg b/LayoutTests/svg/clip-path/clip-path-shape-circle-1-expected.svg
new file mode 100644 (file)
index 0000000..541cf5b
--- /dev/null
@@ -0,0 +1,8 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<defs>
+    <clipPath id="clip">
+        <circle cx="100" cy="100" r="100"/>
+    </clipPath>
+</defs>
+<rect width="200" height="200" fill="green" clip-path="url(#clip)"/>
+</svg>
\ No newline at end of file
diff --git a/LayoutTests/svg/clip-path/clip-path-shape-circle-1.svg b/LayoutTests/svg/clip-path/clip-path-shape-circle-1.svg
new file mode 100644 (file)
index 0000000..57d3326
--- /dev/null
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<rect width="200" height="200" fill="green" style="-webkit-clip-path: circle(50%, 50%, 50%)"/>
+</svg>
\ No newline at end of file
diff --git a/LayoutTests/svg/clip-path/clip-path-shape-circle-2-expected.svg b/LayoutTests/svg/clip-path/clip-path-shape-circle-2-expected.svg
new file mode 100644 (file)
index 0000000..a1813db
--- /dev/null
@@ -0,0 +1,8 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<defs>
+    <clipPath id="clip">
+        <circle cx="100" cy="75" r="75"/>
+    </clipPath>
+</defs>
+<rect width="200" height="150" fill="green" clip-path="url(#clip)"/>
+</svg>
\ No newline at end of file
diff --git a/LayoutTests/svg/clip-path/clip-path-shape-circle-2.svg b/LayoutTests/svg/clip-path/clip-path-shape-circle-2.svg
new file mode 100644 (file)
index 0000000..4533e03
--- /dev/null
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<rect width="200" height="150" fill="green" style="-webkit-clip-path: circle(100px, 75px, 75px)"/>
+</svg>
\ No newline at end of file
diff --git a/LayoutTests/svg/clip-path/clip-path-shape-ellipse-1-expected.svg b/LayoutTests/svg/clip-path/clip-path-shape-ellipse-1-expected.svg
new file mode 100644 (file)
index 0000000..1996c54
--- /dev/null
@@ -0,0 +1,8 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<defs>
+    <clipPath id="clip">
+        <ellipse cx="100" cy="75" rx="100" ry="75"/>
+    </clipPath>
+</defs>
+<rect width="200" height="150" fill="green" clip-path="url(#clip)"/>
+</svg>
\ No newline at end of file
diff --git a/LayoutTests/svg/clip-path/clip-path-shape-ellipse-1.svg b/LayoutTests/svg/clip-path/clip-path-shape-ellipse-1.svg
new file mode 100644 (file)
index 0000000..24292e6
--- /dev/null
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<rect width="200" height="150" fill="green" style="-webkit-clip-path: ellipse(50%, 50%, 50%, 50%)"/>
+</svg>
\ No newline at end of file
diff --git a/LayoutTests/svg/clip-path/clip-path-shape-ellipse-2-expected.svg b/LayoutTests/svg/clip-path/clip-path-shape-ellipse-2-expected.svg
new file mode 100644 (file)
index 0000000..1996c54
--- /dev/null
@@ -0,0 +1,8 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<defs>
+    <clipPath id="clip">
+        <ellipse cx="100" cy="75" rx="100" ry="75"/>
+    </clipPath>
+</defs>
+<rect width="200" height="150" fill="green" clip-path="url(#clip)"/>
+</svg>
\ No newline at end of file
diff --git a/LayoutTests/svg/clip-path/clip-path-shape-ellipse-2.svg b/LayoutTests/svg/clip-path/clip-path-shape-ellipse-2.svg
new file mode 100644 (file)
index 0000000..09e1e5c
--- /dev/null
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<rect width="200" height="200" fill="green" style="-webkit-clip-path: ellipse(100px, 75px, 100px, 75px)"/>
+</svg>
\ No newline at end of file
diff --git a/LayoutTests/svg/clip-path/clip-path-shape-polygon-1-expected.svg b/LayoutTests/svg/clip-path/clip-path-shape-polygon-1-expected.svg
new file mode 100644 (file)
index 0000000..551a5f5
--- /dev/null
@@ -0,0 +1,8 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<defs>
+    <clipPath id="clip" clip-rule="nonzero">
+        <polygon points="0,0 100,200 200,0 0,200 100,0 200,200 0,0"/>
+    </clipPath>
+</defs>
+<rect width="200" height="200" fill="green" clip-path="url(#clip)"/>
+</svg>
\ No newline at end of file
diff --git a/LayoutTests/svg/clip-path/clip-path-shape-polygon-1.svg b/LayoutTests/svg/clip-path/clip-path-shape-polygon-1.svg
new file mode 100644 (file)
index 0000000..cd92706
--- /dev/null
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<rect width="200" height="200" fill="green" style="-webkit-clip-path: polygon(nonzero, 0 0, 100px 200px, 200px 0, 0 200px, 100px 0, 200px 200px, 0 0)"/>
+</svg>
\ No newline at end of file
diff --git a/LayoutTests/svg/clip-path/clip-path-shape-polygon-2-expected.svg b/LayoutTests/svg/clip-path/clip-path-shape-polygon-2-expected.svg
new file mode 100644 (file)
index 0000000..3fe05b6
--- /dev/null
@@ -0,0 +1,8 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<defs>
+    <clipPath id="clip" clip-rule="evenodd">
+        <polygon points="0,0 100,200 200,0 0,200 100,0 200,200 0,0"/>
+    </clipPath>
+</defs>
+<rect width="200" height="200" fill="green" clip-path="url(#clip)"/>
+</svg>
\ No newline at end of file
diff --git a/LayoutTests/svg/clip-path/clip-path-shape-polygon-2.svg b/LayoutTests/svg/clip-path/clip-path-shape-polygon-2.svg
new file mode 100644 (file)
index 0000000..e573fda
--- /dev/null
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<rect width="200" height="200" fill="green" style="-webkit-clip-path: polygon(evenodd, 0 0, 100px 200px, 200px 0, 0 200px, 100px 0, 200px 200px, 0 0)"/>
+</svg>
\ No newline at end of file
diff --git a/LayoutTests/svg/clip-path/clip-path-shape-polygon-3-expected.svg b/LayoutTests/svg/clip-path/clip-path-shape-polygon-3-expected.svg
new file mode 100644 (file)
index 0000000..4be712b
--- /dev/null
@@ -0,0 +1,8 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<defs>
+    <clipPath id="clip">
+        <polygon points="0,0 100,200 200,0 0,200 100,0 200,200 0,0"/>
+    </clipPath>
+</defs>
+<rect width="200" height="200" fill="green" clip-path="url(#clip)"/>
+</svg>
\ No newline at end of file
diff --git a/LayoutTests/svg/clip-path/clip-path-shape-polygon-3.svg b/LayoutTests/svg/clip-path/clip-path-shape-polygon-3.svg
new file mode 100644 (file)
index 0000000..ea2bb4c
--- /dev/null
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<rect width="200" height="200" fill="green" style="-webkit-clip-path: polygon(0 0, 100px 200px, 200px 0, 0 200px, 100px 0, 200px 200px, 0 0)"/>
+</svg>
\ No newline at end of file
diff --git a/LayoutTests/svg/clip-path/clip-path-shape-rounded-rect-1-expected.svg b/LayoutTests/svg/clip-path/clip-path-shape-rounded-rect-1-expected.svg
new file mode 100644 (file)
index 0000000..823897b
--- /dev/null
@@ -0,0 +1,8 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<defs>
+    <clipPath id="clip">
+        <rect x="20" y="20" width="160" height="160" rx="20" ry="20"/>
+    </clipPath>
+</defs>
+<rect width="200" height="200" fill="green" clip-path="url(#clip)"/>
+</svg>
\ No newline at end of file
diff --git a/LayoutTests/svg/clip-path/clip-path-shape-rounded-rect-1.svg b/LayoutTests/svg/clip-path/clip-path-shape-rounded-rect-1.svg
new file mode 100644 (file)
index 0000000..5d3b059
--- /dev/null
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<rect width="200" height="200" fill="green" style="-webkit-clip-path: rectangle(10%, 10%, 80%, 80%, 10%, 10%)"/>
+</svg>
\ No newline at end of file
diff --git a/LayoutTests/svg/clip-path/clip-path-shape-rounded-rect-2-expected.svg b/LayoutTests/svg/clip-path/clip-path-shape-rounded-rect-2-expected.svg
new file mode 100644 (file)
index 0000000..823897b
--- /dev/null
@@ -0,0 +1,8 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<defs>
+    <clipPath id="clip">
+        <rect x="20" y="20" width="160" height="160" rx="20" ry="20"/>
+    </clipPath>
+</defs>
+<rect width="200" height="200" fill="green" clip-path="url(#clip)"/>
+</svg>
\ No newline at end of file
diff --git a/LayoutTests/svg/clip-path/clip-path-shape-rounded-rect-2.svg b/LayoutTests/svg/clip-path/clip-path-shape-rounded-rect-2.svg
new file mode 100644 (file)
index 0000000..f8312d4
--- /dev/null
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<rect width="200" height="200" fill="green" style="-webkit-clip-path: rectangle(20px, 20px, 160px, 160px, 20px, 20px)"/>
+</svg>
\ No newline at end of file
index 2c2b350..b5151f4 100644 (file)
 #include "config.h"
 
 #include "BasicShapes.h"
+#include "FloatRect.h"
+#include "LengthFunctions.h"
+#include "Path.h"
 
 namespace WebCore {
 
-void BasicShape::destroy()
+void BasicShapeRectangle::path(Path& path, const FloatRect& boundingBox)
 {
-    switch (m_type) {
-    case BASIC_SHAPE_RECTANGLE:
-        delete static_cast<BasicShapeRectangle*>(this);
-        return;
-    case BASIC_SHAPE_CIRCLE:
-        delete static_cast<BasicShapeCircle*>(this);
-        return;
-    case BASIC_SHAPE_ELLIPSE:
-        delete static_cast<BasicShapeEllipse*>(this);
-        return;
-    case BASIC_SHAPE_POLYGON:
-        delete static_cast<BasicShapePolygon*>(this);
+    ASSERT(path.isEmpty());
+    path.addRoundedRect(FloatRect(floatValueForLength(m_x, boundingBox.width()) + boundingBox.x(),
+                                  floatValueForLength(m_y, boundingBox.height()) + boundingBox.y(),
+                                  floatValueForLength(m_width, boundingBox.width()),
+                                  floatValueForLength(m_height, boundingBox.height())),
+                        FloatSize(m_cornerRadiusX.isUndefined() ? 0 : floatValueForLength(m_cornerRadiusX, boundingBox.width()),
+                                  m_cornerRadiusY.isUndefined() ? 0 : floatValueForLength(m_cornerRadiusY, boundingBox.height())));
+}
+
+void BasicShapeCircle::path(Path& path, const FloatRect& boundingBox)
+{
+    ASSERT(path.isEmpty());
+    float diagonal = sqrtf((boundingBox.width() * boundingBox.width() + boundingBox.height() * boundingBox.height()) / 2);
+    float centerX = floatValueForLength(m_centerX, boundingBox.width());
+    float centerY = floatValueForLength(m_centerY, boundingBox.height());
+    float radius = floatValueForLength(m_radius, diagonal);
+    path.addEllipse(FloatRect(centerX - radius + boundingBox.x(),
+                              centerY - radius + boundingBox.y(),
+                              radius * 2,
+                              radius * 2));
+}
+
+void BasicShapeEllipse::path(Path& path, const FloatRect& boundingBox)
+{
+    ASSERT(path.isEmpty());
+    float centerX = floatValueForLength(m_centerX, boundingBox.width());
+    float centerY = floatValueForLength(m_centerY, boundingBox.height());
+    float radiusX = floatValueForLength(m_radiusX, boundingBox.width());
+    float radiusY = floatValueForLength(m_radiusY, boundingBox.height());
+    path.addEllipse(FloatRect(centerX - radiusX + boundingBox.x(),
+                              centerY - radiusY + boundingBox.y(),
+                              radiusX * 2,
+                              radiusY * 2));
+}
+
+void BasicShapePolygon::path(Path& path, const FloatRect& boundingBox)
+{
+    ASSERT(path.isEmpty());
+    ASSERT(!(m_values.size() % 2));
+    size_t length = m_values.size();
+    
+    if (!length)
         return;
+
+    path.moveTo(FloatPoint(floatValueForLength(m_values.at(0), boundingBox.width()),
+                           floatValueForLength(m_values.at(1), boundingBox.width())));
+    for (size_t i = 2; i < length; i = i + 2) {
+        path.addLineTo(FloatPoint(floatValueForLength(m_values.at(i), boundingBox.width()),
+                                  floatValueForLength(m_values.at(i + 1), boundingBox.width())));
     }
-    ASSERT_NOT_REACHED();
+    path.closeSubpath();
 }
-
 }
index 1d79df7..9c104da 100644 (file)
 
 namespace WebCore {
 
-class BasicShape : public WTF::RefCountedBase {
+class FloatRect;
+class Path;
+
+class BasicShape : public RefCounted<BasicShape> {
 public:
+    virtual ~BasicShape() { }
+
     enum Type {
         BASIC_SHAPE_RECTANGLE = 1,
         BASIC_SHAPE_CIRCLE = 2,
         BASIC_SHAPE_ELLIPSE = 3,
         BASIC_SHAPE_POLYGON = 4
     };
-    
-    void deref() 
-    {
-        if (derefBase())
-            destroy();
-    }
 
-    Type type() const { return m_type; }
+    virtual void path(Path&, const FloatRect&) = 0;
+    virtual WindRule windRule() const { return RULE_NONZERO; }
 
+    virtual Type type() const = 0;
 protected:
-    BasicShape(Type type)
-        : m_type(type)
-    { }
-    
-private:
-    void destroy();
-    Type m_type;
+    BasicShape() { }
 };
 
 class BasicShapeRectangle : public BasicShape {
@@ -81,11 +76,13 @@ public:
     void setHeight(Length height) { m_height = height; }
     void setCornerRadiusX(Length radiusX) { m_cornerRadiusX = radiusX; }
     void setCornerRadiusY(Length radiusY) { m_cornerRadiusY = radiusY; }
-    
+
+    virtual void path(Path&, const FloatRect&);
+
+    virtual Type type() const { return BASIC_SHAPE_RECTANGLE; }
 private:
     BasicShapeRectangle()
-        : BasicShape(BASIC_SHAPE_RECTANGLE)
-        , m_cornerRadiusX(Undefined)
+        : m_cornerRadiusX(Undefined)
         , m_cornerRadiusY(Undefined)
     { }
 
@@ -109,10 +106,11 @@ public:
     void setCenterY(Length centerY) { m_centerY = centerY; }
     void setRadius(Length radius) { m_radius = radius; }
 
+    virtual void path(Path&, const FloatRect&);
+
+    virtual Type type() const { return BASIC_SHAPE_CIRCLE; }
 private:
-    BasicShapeCircle() 
-        : BasicShape(BASIC_SHAPE_CIRCLE)
-    { }
+    BasicShapeCircle() { }
 
     Length m_centerX;
     Length m_centerY;
@@ -133,10 +131,11 @@ public:
     void setRadiusX(Length radiusX) { m_radiusX = radiusX; }
     void setRadiusY(Length radiusY) { m_radiusY = radiusY; }
 
+    virtual void path(Path&, const FloatRect&);
+
+    virtual Type type() const { return BASIC_SHAPE_ELLIPSE; } 
 private:
-    BasicShapeEllipse() 
-        : BasicShape(BASIC_SHAPE_ELLIPSE)
-    { }
+    BasicShapeEllipse() { }
 
     Length m_centerX;
     Length m_centerY;
@@ -148,7 +147,6 @@ class BasicShapePolygon : public BasicShape {
 public:
     static PassRefPtr<BasicShapePolygon> create() { return adoptRef(new BasicShapePolygon); }
 
-    WindRule windRule() const { return m_windRule; }
     const Vector<Length>& values() const { return m_values; }
     Length getXAt(unsigned i) const { return m_values.at(2 * i); }
     Length getYAt(unsigned i) const { return m_values.at(2 * i + 1); }
@@ -156,10 +154,13 @@ public:
     void setWindRule(WindRule windRule) { m_windRule = windRule; }
     void appendPoint(Length x, Length y) { m_values.append(x); m_values.append(y); }
 
+    virtual void path(Path&, const FloatRect&);
+    virtual WindRule windRule() const { return m_windRule; }
+
+    virtual Type type() const { return BASIC_SHAPE_POLYGON; }
 private:
     BasicShapePolygon()
-        : BasicShape(BASIC_SHAPE_POLYGON)
-        , m_windRule(RULE_NONZERO)
+        : m_windRule(RULE_NONZERO)
     { }
 
     WindRule m_windRule;
index e2adb30..9124d47 100644 (file)
@@ -27,6 +27,7 @@
 #if ENABLE(SVG)
 #include "SVGRenderingContext.h"
 
+#include "BasicShapes.h"
 #include "Frame.h"
 #include "FrameView.h"
 #include "RenderSVGResource.h"
@@ -122,6 +123,15 @@ void SVGRenderingContext::prepareToRenderSVGContent(RenderObject* object, PaintI
         }
     }
 
+    BasicShape* clipShape = style->clipPath();
+    if (clipShape) {
+        // FIXME: Investigate if it is better to store and update a Path object in RenderStyle.
+        // https://bugs.webkit.org/show_bug.cgi?id=95619
+        Path clipPath;
+        clipShape->path(clipPath, object->objectBoundingBox());
+        m_paintInfo->context->clipPath(clipPath, clipShape->windRule());
+    }
+
     SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(m_object);
     if (!resources) {
 #if ENABLE(FILTERS)
@@ -139,7 +149,8 @@ void SVGRenderingContext::prepareToRenderSVGContent(RenderObject* object, PaintI
         }
     }
 
-    if (RenderSVGResourceClipper* clipper = resources->clipper()) {
+    RenderSVGResourceClipper* clipper = resources->clipper();
+    if (!clipShape && clipper) {
         if (!clipper->applyResource(m_object, style, m_paintInfo->context, ApplyToDefaultMode))
             return;
     }