Changeset 127383 in webkit


Ignore:
Timestamp:
Sep 1, 2012 5:15:33 PM (12 years ago)
Author:
krit@webkit.org
Message:

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.
Location:
trunk
Files:
18 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r127382 r127383  
     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 Rob Buis.
     7
     8        New tests to check behavior of -webkit-clip-path on SVG elements.
     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-09-01  Xianzhu Wang  <wangxianzhu@chromium.org>
    230
  • trunk/Source/WebCore/ChangeLog

    r127381 r127383  
     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 Rob Buis.
     7
     8        This patch adds a path segment for a BasicShape to a given Path object. This
     9        path and it's wind rule are used to clip the context of the SVG element.
     10
     11        Tests: svg/clip-path/clip-path-shape-circle-1-expected.svg
     12               svg/clip-path/clip-path-shape-circle-1.svg
     13               svg/clip-path/clip-path-shape-circle-2-expected.svg
     14               svg/clip-path/clip-path-shape-circle-2.svg
     15               svg/clip-path/clip-path-shape-ellipse-1-expected.svg
     16               svg/clip-path/clip-path-shape-ellipse-1.svg
     17               svg/clip-path/clip-path-shape-ellipse-2-expected.svg
     18               svg/clip-path/clip-path-shape-ellipse-2.svg
     19               svg/clip-path/clip-path-shape-polygon-1-expected.svg
     20               svg/clip-path/clip-path-shape-polygon-1.svg
     21               svg/clip-path/clip-path-shape-polygon-2-expected.svg
     22               svg/clip-path/clip-path-shape-polygon-2.svg
     23               svg/clip-path/clip-path-shape-polygon-3-expected.svg
     24               svg/clip-path/clip-path-shape-polygon-3.svg
     25               svg/clip-path/clip-path-shape-rounded-rect-1-expected.svg
     26               svg/clip-path/clip-path-shape-rounded-rect-1.svg
     27               svg/clip-path/clip-path-shape-rounded-rect-2-expected.svg
     28               svg/clip-path/clip-path-shape-rounded-rect-2.svg
     29
     30        * rendering/style/BasicShapes.cpp: Added helper functions that apply path segments to a given path.
     31        (WebCore::BasicShapeRectangle::path):
     32        (WebCore::BasicShapeCircle::path):
     33        (WebCore::BasicShapeEllipse::path):
     34        (WebCore::BasicShapePolygon::path):
     35        * rendering/style/BasicShapes.h: Make BasicShape virtualized again, since new virtual functions were added.
     36        (WebCore::BasicShape::~BasicShape):
     37        (BasicShape):
     38        (WebCore::BasicShape::windRule): Will return the wind rule of the shape - nonzero by default.
     39        (WebCore::BasicShape::BasicShape):
     40        (BasicShapeRectangle):
     41        (WebCore::BasicShapeRectangle::type): Removed member variable and return type per inheriting class directly.
     42        (WebCore::BasicShapeRectangle::BasicShapeRectangle):
     43        (BasicShapeCircle):
     44        (WebCore::BasicShapeCircle::type): Ditto.
     45        (WebCore::BasicShapeCircle::BasicShapeCircle):
     46        (BasicShapeEllipse):
     47        (WebCore::BasicShapeEllipse::type): Ditto.
     48        (WebCore::BasicShapeEllipse::BasicShapeEllipse):
     49        (BasicShapePolygon):
     50        (WebCore::BasicShapePolygon::windRule):
     51        (WebCore::BasicShapePolygon::type): Ditto.
     52        (WebCore::BasicShapePolygon::BasicShapePolygon):
     53        * rendering/svg/SVGRenderingContext.cpp: If -webkit-clip-path was defined, clip the context to the shape.
     54        Right now -webkit-clip-path overrides clip-path, so that people don't use both at the same time. Current
     55        clip-path property will be replaced, once -webkit-clip-path gets unprefixed.
     56        (WebCore::SVGRenderingContext::prepareToRenderSVGContent):
     57
    1582012-09-01  Ned Holbrook  <nholbrook@apple.com>
    259
  • trunk/Source/WebCore/rendering/style/BasicShapes.cpp

    r127155 r127383  
    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);
    50         return;
    51     }
    52     ASSERT_NOT_REACHED();
     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())));
    5348}
    5449
     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));
    5561}
     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)
     83        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())));
     90    }
     91    path.closeSubpath();
     92}
     93}
  • trunk/Source/WebCore/rendering/style/BasicShapes.h

    r127155 r127383  
    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,
     
    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
     
    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    { }
     
    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;
     
    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;
     
    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); }
     
    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
  • trunk/Source/WebCore/rendering/svg/SVGRenderingContext.cpp

    r126993 r127383  
    2828#include "SVGRenderingContext.h"
    2929
     30#include "BasicShapes.h"
    3031#include "Frame.h"
    3132#include "FrameView.h"
     
    123124    }
    124125
     126    BasicShape* clipShape = style->clipPath();
     127    if (clipShape) {
     128        // FIXME: Investigate if it is better to store and update a Path object in RenderStyle.
     129        // https://bugs.webkit.org/show_bug.cgi?id=95619
     130        Path clipPath;
     131        clipShape->path(clipPath, object->objectBoundingBox());
     132        m_paintInfo->context->clipPath(clipPath, clipShape->windRule());
     133    }
     134
    125135    SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(m_object);
    126136    if (!resources) {
     
    140150    }
    141151
    142     if (RenderSVGResourceClipper* clipper = resources->clipper()) {
     152    RenderSVGResourceClipper* clipper = resources->clipper();
     153    if (!clipShape && clipper) {
    143154        if (!clipper->applyResource(m_object, style, m_paintInfo->context, ApplyToDefaultMode))
    144155            return;
Note: See TracChangeset for help on using the changeset viewer.