Source/WebCore/ChangeLog

 12012-08-31 Dirk Schulze <krit@webkit.org>
 2
 3 Use -webkit-clip-path shapes to clip SVG elements
 4 https://bugs.webkit.org/show_bug.cgi?id=95620
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Additional information of the change such as approach, rationale. Please add per-function descriptions below (OOPS!).
 9
 10 Tests: svg/clip-path/clip-path-shape-circle-1-expected.svg
 11 svg/clip-path/clip-path-shape-circle-1.svg
 12 svg/clip-path/clip-path-shape-circle-2-expected.svg
 13 svg/clip-path/clip-path-shape-circle-2.svg
 14 svg/clip-path/clip-path-shape-ellipse-1-expected.svg
 15 svg/clip-path/clip-path-shape-ellipse-1.svg
 16 svg/clip-path/clip-path-shape-ellipse-2-expected.svg
 17 svg/clip-path/clip-path-shape-ellipse-2.svg
 18 svg/clip-path/clip-path-shape-polygon-1-expected.svg
 19 svg/clip-path/clip-path-shape-polygon-1.svg
 20 svg/clip-path/clip-path-shape-polygon-2-expected.svg
 21 svg/clip-path/clip-path-shape-polygon-2.svg
 22 svg/clip-path/clip-path-shape-polygon-3-expected.svg
 23 svg/clip-path/clip-path-shape-polygon-3.svg
 24 svg/clip-path/clip-path-shape-rounded-rect-1-expected.svg
 25 svg/clip-path/clip-path-shape-rounded-rect-1.svg
 26 svg/clip-path/clip-path-shape-rounded-rect-2-expected.svg
 27 svg/clip-path/clip-path-shape-rounded-rect-2.svg
 28
 29 * rendering/style/BasicShapes.cpp:
 30 (WebCore::BasicShapeRectangle::path):
 31 (WebCore):
 32 (WebCore::BasicShapeCircle::path):
 33 (WebCore::BasicShapeEllipse::path):
 34 (WebCore::BasicShapePolygon::path):
 35 * rendering/style/BasicShapes.h:
 36 (WebCore):
 37 (WebCore::BasicShape::~BasicShape):
 38 (BasicShape):
 39 (WebCore::BasicShape::windRule):
 40 (WebCore::BasicShape::BasicShape):
 41 (BasicShapeRectangle):
 42 (WebCore::BasicShapeRectangle::type):
 43 (WebCore::BasicShapeRectangle::BasicShapeRectangle):
 44 (BasicShapeCircle):
 45 (WebCore::BasicShapeCircle::type):
 46 (WebCore::BasicShapeCircle::BasicShapeCircle):
 47 (BasicShapeEllipse):
 48 (WebCore::BasicShapeEllipse::type):
 49 (WebCore::BasicShapeEllipse::BasicShapeEllipse):
 50 (BasicShapePolygon):
 51 (WebCore::BasicShapePolygon::windRule):
 52 (WebCore::BasicShapePolygon::type):
 53 (WebCore::BasicShapePolygon::BasicShapePolygon):
 54 * rendering/svg/SVGRenderingContext.cpp:
 55 (WebCore::SVGRenderingContext::prepareToRenderSVGContent):
 56
1572012-08-30 Dirk Schulze <krit@webkit.org>
258
359 Introduce new CSS property for clip-path

Source/WebCore/rendering/style/BasicShapes.cpp

3030#include "config.h"
3131
3232#include "BasicShapes.h"
 33#include "FloatRect.h"
 34#include "LengthFunctions.h"
 35#include "Path.h"
3336
3437namespace WebCore {
3538
36 void BasicShape::destroy()
 39void BasicShapeRectangle::path(Path& path, const FloatRect& boundingBox)
3740{
38  switch (m_type) {
39  case BASIC_SHAPE_RECTANGLE:
40  delete static_cast<BasicShapeRectangle*>(this);
41  return;
42  case BASIC_SHAPE_CIRCLE:
43  delete static_cast<BasicShapeCircle*>(this);
44  return;
45  case BASIC_SHAPE_ELLIPSE:
46  delete static_cast<BasicShapeEllipse*>(this);
47  return;
48  case BASIC_SHAPE_POLYGON:
49  delete static_cast<BasicShapePolygon*>(this);
 41 ASSERT(path.isEmpty());
 42 path.addRoundedRect(FloatRect(floatValueForLength(m_x, boundingBox.width()) + boundingBox.x(),
 43 floatValueForLength(m_y, boundingBox.height()) + boundingBox.y(),
 44 floatValueForLength(m_width, boundingBox.width()),
 45 floatValueForLength(m_height, boundingBox.height())),
 46 FloatSize(m_cornerRadiusX.isUndefined() ? 0 : floatValueForLength(m_cornerRadiusX, boundingBox.width()),
 47 m_cornerRadiusY.isUndefined() ? 0 : floatValueForLength(m_cornerRadiusY, boundingBox.height())));
 48}
 49
 50void BasicShapeCircle::path(Path& path, const FloatRect& boundingBox)
 51{
 52 ASSERT(path.isEmpty());
 53 float diagonal = sqrtf((boundingBox.width() * boundingBox.width() + boundingBox.height() * boundingBox.height()) / 2);
 54 float centerX = floatValueForLength(m_centerX, boundingBox.width());
 55 float centerY = floatValueForLength(m_centerY, boundingBox.height());
 56 float radius = floatValueForLength(m_radius, diagonal);
 57 path.addEllipse(FloatRect(centerX - radius + boundingBox.x(),
 58 centerY - radius + boundingBox.y(),
 59 radius * 2,
 60 radius * 2));
 61}
 62
 63void BasicShapeEllipse::path(Path& path, const FloatRect& boundingBox)
 64{
 65 ASSERT(path.isEmpty());
 66 float centerX = floatValueForLength(m_centerX, boundingBox.width());
 67 float centerY = floatValueForLength(m_centerY, boundingBox.height());
 68 float radiusX = floatValueForLength(m_radiusX, boundingBox.width());
 69 float radiusY = floatValueForLength(m_radiusY, boundingBox.height());
 70 path.addEllipse(FloatRect(centerX - radiusX + boundingBox.x(),
 71 centerY - radiusY + boundingBox.y(),
 72 radiusX * 2,
 73 radiusY * 2));
 74}
 75
 76void BasicShapePolygon::path(Path& path, const FloatRect& boundingBox)
 77{
 78 ASSERT(path.isEmpty());
 79 ASSERT(!(m_values.size() % 2));
 80 size_t length = m_values.size();
 81
 82 if (!length)
5083 return;
 84
 85 path.moveTo(FloatPoint(floatValueForLength(m_values.at(0), boundingBox.width()),
 86 floatValueForLength(m_values.at(1), boundingBox.width())));
 87 for (size_t i = 2; i < length; i = i + 2) {
 88 path.addLineTo(FloatPoint(floatValueForLength(m_values.at(i), boundingBox.width()),
 89 floatValueForLength(m_values.at(i + 1), boundingBox.width())));
5190 }
52  ASSERT_NOT_REACHED();
 91 path.closeSubpath();
5392}
54 
5593}

Source/WebCore/rendering/style/BasicShapes.h

3838
3939namespace WebCore {
4040
41 class BasicShape : public WTF::RefCountedBase {
 41class FloatRect;
 42class Path;
 43
 44class BasicShape : public RefCounted<BasicShape> {
4245public:
 46 virtual ~BasicShape() { }
 47
4348 enum Type {
4449 BASIC_SHAPE_RECTANGLE = 1,
4550 BASIC_SHAPE_CIRCLE = 2,
4651 BASIC_SHAPE_ELLIPSE = 3,
4752 BASIC_SHAPE_POLYGON = 4
4853 };
49 
50  void deref()
51  {
52  if (derefBase())
53  destroy();
54  }
5554
56  Type type() const { return m_type; }
 55 virtual void path(Path&, const FloatRect&) = 0;
 56 virtual WindRule windRule() const { return RULE_NONZERO; }
5757
 58 virtual Type type() const = 0;
5859protected:
59  BasicShape(Type type)
60  : m_type(type)
61  { }
62 
63 private:
64  void destroy();
65  Type m_type;
 60 BasicShape() { }
6661};
6762
6863class BasicShapeRectangle : public BasicShape {

@@public:
8277 void setHeight(Length height) { m_height = height; }
8378 void setCornerRadiusX(Length radiusX) { m_cornerRadiusX = radiusX; }
8479 void setCornerRadiusY(Length radiusY) { m_cornerRadiusY = radiusY; }
85 
 80
 81 virtual void path(Path&, const FloatRect&);
 82
 83 virtual Type type() const { return BASIC_SHAPE_RECTANGLE; }
8684private:
8785 BasicShapeRectangle()
88  : BasicShape(BASIC_SHAPE_RECTANGLE)
89  , m_cornerRadiusX(Undefined)
 86 : m_cornerRadiusX(Undefined)
9087 , m_cornerRadiusY(Undefined)
9188 { }
9289

@@public:
110107 void setCenterY(Length centerY) { m_centerY = centerY; }
111108 void setRadius(Length radius) { m_radius = radius; }
112109
 110 virtual void path(Path&, const FloatRect&);
 111
 112 virtual Type type() const { return BASIC_SHAPE_CIRCLE; }
113113private:
114  BasicShapeCircle()
115  : BasicShape(BASIC_SHAPE_CIRCLE)
116  { }
 114 BasicShapeCircle() { }
117115
118116 Length m_centerX;
119117 Length m_centerY;

@@public:
134132 void setRadiusX(Length radiusX) { m_radiusX = radiusX; }
135133 void setRadiusY(Length radiusY) { m_radiusY = radiusY; }
136134
 135 virtual void path(Path&, const FloatRect&);
 136
 137 virtual Type type() const { return BASIC_SHAPE_ELLIPSE; }
137138private:
138  BasicShapeEllipse()
139  : BasicShape(BASIC_SHAPE_ELLIPSE)
140  { }
 139 BasicShapeEllipse() { }
141140
142141 Length m_centerX;
143142 Length m_centerY;

@@class BasicShapePolygon : public BasicShape {
149148public:
150149 static PassRefPtr<BasicShapePolygon> create() { return adoptRef(new BasicShapePolygon); }
151150
152  WindRule windRule() const { return m_windRule; }
153151 const Vector<Length>& values() const { return m_values; }
154152 Length getXAt(unsigned i) const { return m_values.at(2 * i); }
155153 Length getYAt(unsigned i) const { return m_values.at(2 * i + 1); }

@@public:
157155 void setWindRule(WindRule windRule) { m_windRule = windRule; }
158156 void appendPoint(Length x, Length y) { m_values.append(x); m_values.append(y); }
159157
 158 virtual void path(Path&, const FloatRect&);
 159 virtual WindRule windRule() const { return m_windRule; }
 160
 161 virtual Type type() const { return BASIC_SHAPE_POLYGON; }
160162private:
161163 BasicShapePolygon()
162  : BasicShape(BASIC_SHAPE_POLYGON)
163  , m_windRule(RULE_NONZERO)
 164 : m_windRule(RULE_NONZERO)
164165 { }
165166
166167 WindRule m_windRule;

Source/WebCore/rendering/svg/SVGRenderingContext.cpp

2727#if ENABLE(SVG)
2828#include "SVGRenderingContext.h"
2929
 30#include "BasicShapes.h"
3031#include "Frame.h"
3132#include "FrameView.h"
3233#include "RenderSVGResource.h"

@@void SVGRenderingContext::prepareToRenderSVGContent(RenderObject* object, PaintI
121122 m_renderingFlags |= EndShadowLayer;
122123 }
123124 }
 125
 126 if (BasicShape* clipShape = style->clipPath()) {
 127 // FIXME: Investigate if it is better to store and update a Path object in RenderStyle.
 128 // https://bugs.webkit.org/show_bug.cgi?id=95619
 129 Path clipPath;
 130 clipShape->path(clipPath, object->objectBoundingBox());
 131 m_paintInfo->context->clipPath(clipPath, clipShape->windRule());
 132 }
124133
125134 SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(m_object);
126135 if (!resources) {

@@void SVGRenderingContext::prepareToRenderSVGContent(RenderObject* object, PaintI
139148 }
140149 }
141150
142  if (RenderSVGResourceClipper* clipper = resources->clipper()) {
 151 RenderSVGResourceClipper* clipper = resources->clipper();
 152 if (clipper && !style->clipPath()) {
143153 if (!clipper->applyResource(m_object, style, m_paintInfo->context, ApplyToDefaultMode))
144154 return;
145155 }

LayoutTests/ChangeLog

 12012-08-31 Dirk Schulze <krit@webkit.org>
 2
 3 Use -webkit-clip-path shapes to clip SVG elements
 4 https://bugs.webkit.org/show_bug.cgi?id=95620
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Additional information of the change such as approach, rationale. Please add per-function descriptions below (OOPS!).
 9
 10 * svg/clip-path/clip-path-shape-circle-1-expected.svg: Added.
 11 * svg/clip-path/clip-path-shape-circle-1.svg: Added.
 12 * svg/clip-path/clip-path-shape-circle-2-expected.svg: Added.
 13 * svg/clip-path/clip-path-shape-circle-2.svg: Added.
 14 * svg/clip-path/clip-path-shape-ellipse-1-expected.svg: Added.
 15 * svg/clip-path/clip-path-shape-ellipse-1.svg: Added.
 16 * svg/clip-path/clip-path-shape-ellipse-2-expected.svg: Added.
 17 * svg/clip-path/clip-path-shape-ellipse-2.svg: Added.
 18 * svg/clip-path/clip-path-shape-polygon-1-expected.svg: Added.
 19 * svg/clip-path/clip-path-shape-polygon-1.svg: Added.
 20 * svg/clip-path/clip-path-shape-polygon-2-expected.svg: Added.
 21 * svg/clip-path/clip-path-shape-polygon-2.svg: Added.
 22 * svg/clip-path/clip-path-shape-polygon-3-expected.svg: Added.
 23 * svg/clip-path/clip-path-shape-polygon-3.svg: Added.
 24 * svg/clip-path/clip-path-shape-rounded-rect-1-expected.svg: Added.
 25 * svg/clip-path/clip-path-shape-rounded-rect-1.svg: Added.
 26 * svg/clip-path/clip-path-shape-rounded-rect-2-expected.svg: Added.
 27 * svg/clip-path/clip-path-shape-rounded-rect-2.svg: Added.
 28
1292012-08-30 Dirk Schulze <krit@webkit.org>
230
331 Introduce new CSS property for clip-path

LayoutTests/svg/clip-path/clip-path-shape-circle-1-expected.svg

 1<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 2<defs>
 3 <clipPath id="clip">
 4 <circle cx="100" cy="100" r="100"/>
 5 </clipPath>
 6</defs>
 7<rect width="200" height="200" fill="green" clip-path="url(#clip)"/>
 8</svg>

LayoutTests/svg/clip-path/clip-path-shape-circle-1.svg

 1<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 2<rect width="200" height="200" fill="green" style="-webkit-clip-path: circle(50%, 50%, 50%)"/>
 3</svg>

LayoutTests/svg/clip-path/clip-path-shape-circle-2-expected.svg

 1<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 2<defs>
 3 <clipPath id="clip">
 4 <circle cx="100" cy="75" r="75"/>
 5 </clipPath>
 6</defs>
 7<rect width="200" height="150" fill="green" clip-path="url(#clip)"/>
 8</svg>

LayoutTests/svg/clip-path/clip-path-shape-circle-2.svg

 1<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 2<rect width="200" height="150" fill="green" style="-webkit-clip-path: circle(100px, 75px, 75px)"/>
 3</svg>

LayoutTests/svg/clip-path/clip-path-shape-ellipse-1-expected.svg

 1<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 2<defs>
 3 <clipPath id="clip">
 4 <ellipse cx="100" cy="75" rx="100" ry="75"/>
 5 </clipPath>
 6</defs>
 7<rect width="200" height="150" fill="green" clip-path="url(#clip)"/>
 8</svg>

LayoutTests/svg/clip-path/clip-path-shape-ellipse-1.svg

 1<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 2<rect width="200" height="150" fill="green" style="-webkit-clip-path: ellipse(50%, 50%, 50%, 50%)"/>
 3</svg>

LayoutTests/svg/clip-path/clip-path-shape-ellipse-2-expected.svg

 1<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 2<defs>
 3 <clipPath id="clip">
 4 <ellipse cx="100" cy="75" rx="100" ry="75"/>
 5 </clipPath>
 6</defs>
 7<rect width="200" height="150" fill="green" clip-path="url(#clip)"/>
 8</svg>

LayoutTests/svg/clip-path/clip-path-shape-ellipse-2.svg

 1<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 2<rect width="200" height="200" fill="green" style="-webkit-clip-path: ellipse(100px, 75px, 100px, 75px)"/>
 3</svg>

LayoutTests/svg/clip-path/clip-path-shape-polygon-1-expected.svg

 1<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 2<defs>
 3 <clipPath id="clip" clip-rule="nonzero">
 4 <polygon points="0,0 100,200 200,0 0,200 100,0 200,200 0,0"/>
 5 </clipPath>
 6</defs>
 7<rect width="200" height="200" fill="green" clip-path="url(#clip)"/>
 8</svg>

LayoutTests/svg/clip-path/clip-path-shape-polygon-1.svg

 1<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 2<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)"/>
 3</svg>

LayoutTests/svg/clip-path/clip-path-shape-polygon-2-expected.svg

 1<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 2<defs>
 3 <clipPath id="clip" clip-rule="evenodd">
 4 <polygon points="0,0 100,200 200,0 0,200 100,0 200,200 0,0"/>
 5 </clipPath>
 6</defs>
 7<rect width="200" height="200" fill="green" clip-path="url(#clip)"/>
 8</svg>

LayoutTests/svg/clip-path/clip-path-shape-polygon-2.svg

 1<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 2<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)"/>
 3</svg>

LayoutTests/svg/clip-path/clip-path-shape-polygon-3-expected.svg

 1<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 2<defs>
 3 <clipPath id="clip">
 4 <polygon points="0,0 100,200 200,0 0,200 100,0 200,200 0,0"/>
 5 </clipPath>
 6</defs>
 7<rect width="200" height="200" fill="green" clip-path="url(#clip)"/>
 8</svg>

LayoutTests/svg/clip-path/clip-path-shape-polygon-3.svg

 1<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 2<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)"/>
 3</svg>

LayoutTests/svg/clip-path/clip-path-shape-rounded-rect-1-expected.svg

 1<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 2<defs>
 3 <clipPath id="clip">
 4 <rect x="20" y="20" width="160" height="160" rx="20" ry="20"/>
 5 </clipPath>
 6</defs>
 7<rect width="200" height="200" fill="green" clip-path="url(#clip)"/>
 8</svg>

LayoutTests/svg/clip-path/clip-path-shape-rounded-rect-1.svg

 1<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 2<rect width="200" height="200" fill="green" style="-webkit-clip-path: rectangle(10%, 10%, 80%, 80%, 10%, 10%)"/>
 3</svg>

LayoutTests/svg/clip-path/clip-path-shape-rounded-rect-2-expected.svg

 1<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 2<defs>
 3 <clipPath id="clip">
 4 <rect x="20" y="20" width="160" height="160" rx="20" ry="20"/>
 5 </clipPath>
 6</defs>
 7<rect width="200" height="200" fill="green" clip-path="url(#clip)"/>
 8</svg>

LayoutTests/svg/clip-path/clip-path-shape-rounded-rect-2.svg

 1<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 2<rect width="200" height="200" fill="green" style="-webkit-clip-path: rectangle(20px, 20px, 160px, 160px, 20px, 20px)"/>
 3</svg>