Changeset 223804 in webkit


Ignore:
Timestamp:
Oct 20, 2017 7:33:53 PM (7 years ago)
Author:
commit-queue@webkit.org
Message:

SVGPathElement should cache the built-up Path of its non animating pathByteStream()
https://bugs.webkit.org/show_bug.cgi?id=178248

Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2017-10-20
Reviewed by Simon Fraser.

Instead of creating a Path object from the non animating pathByteStream()
every time we need to updatePathFromPathElement(), the Path object can be
cached once it is created and used for later calls.

  • html/canvas/Path2D.h: buildPathFromString() now returns a Path.
  • platform/graphics/Path.h:
  • platform/graphics/cairo/PathCairo.cpp:

(WebCore::Path::Path):
(WebCore::Path::operator=):

  • platform/graphics/cg/PathCG.cpp:

(WebCore::Path::Path):
(WebCore::Path::operator=):

  • platform/graphics/win/PathDirect2D.cpp:

(WebCore::Path::Path):
(WebCore::Path::operator=):
Define the move constructor and the move assignment operator for the the
Path class so a statement like "Path path = buildPathFromString()" won't
go through the copy constructor and the copy assignment operator.

  • rendering/style/BasicShapes.cpp:

(WebCore::SVGPathTranslatedByteStream::path const):

  • rendering/svg/RenderSVGResourceClipper.cpp:

(WebCore::RenderSVGResourceClipper::pathOnlyClipping):

  • rendering/svg/RenderSVGShape.cpp:

(WebCore::RenderSVGShape::updateShapeFromElement):

  • rendering/svg/RenderSVGTextPath.cpp:

(WebCore::RenderSVGTextPath::layoutPath const):

  • rendering/svg/SVGPathData.cpp:

(WebCore::pathFromCircleElement):
(WebCore::pathFromEllipseElement):
(WebCore::pathFromLineElement):
(WebCore::pathFromPathElement):
(WebCore::pathFromPolygonElement):
(WebCore::pathFromPolylineElement):
(WebCore::pathFromRectElement):
(WebCore::pathFromGraphicsElement):
(WebCore::updatePathFromCircleElement): Deleted.
(WebCore::updatePathFromEllipseElement): Deleted.
(WebCore::updatePathFromLineElement): Deleted.
(WebCore::updatePathFromPathElement): Deleted.
(WebCore::updatePathFromPolygonElement): Deleted.
(WebCore::updatePathFromPolylineElement): Deleted.
(WebCore::updatePathFromRectElement): Deleted.
(WebCore::updatePathFromGraphicsElement): Deleted.

  • rendering/svg/SVGPathData.h:
  • svg/SVGAnimateMotionElement.cpp:

(WebCore::SVGAnimateMotionElement::parseAttribute):
(WebCore::SVGAnimateMotionElement::updateAnimationPath):

  • svg/SVGGraphicsElement.cpp:

(WebCore::SVGGraphicsElement::toClipPath):

  • svg/SVGGraphicsElement.h:

Rename updatePathFromElement() to pathFromGraphicsElement().

  • svg/SVGPathElement.cpp:

(WebCore::SVGPathElement::parseAttribute): Clear the cache when
m_pathByteStream changes.
(WebCore::SVGPathElement::pathForByteStream const): Caches the m_cachedPath
if it is null.
(WebCore::SVGPathElement::pathSegListChanged): Clear the cache when
m_pathByteStream changes.

  • svg/SVGPathElement.h:
  • svg/SVGPathUtilities.cpp:

(WebCore::buildPathFromString):
(WebCore::buildPathFromByteStream):

  • svg/SVGPathUtilities.h:

Make thes buildPathFromString() and buildPathFromByteStream() return Paths.

  • svg/SVGUseElement.cpp:

(WebCore::SVGUseElement::toClipPath):

  • svg/SVGUseElement.h:

Make these toClipPath() return Path.

Location:
trunk/Source/WebCore
Files:
21 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r223802 r223804  
     12017-10-20  Said Abou-Hallawa  <sabouhallawa@apple.com>
     2
     3        SVGPathElement should cache the built-up Path of its non animating pathByteStream()
     4        https://bugs.webkit.org/show_bug.cgi?id=178248
     5
     6        Reviewed by Simon Fraser.
     7
     8        Instead of creating a Path object from the non animating pathByteStream()
     9        every time we need to updatePathFromPathElement(), the Path object can be
     10        cached once it is created and used for later calls.
     11
     12        * html/canvas/Path2D.h: buildPathFromString() now returns a Path.
     13
     14        * platform/graphics/Path.h:
     15        * platform/graphics/cairo/PathCairo.cpp:
     16        (WebCore::Path::Path):
     17        (WebCore::Path::operator=):
     18        * platform/graphics/cg/PathCG.cpp:
     19        (WebCore::Path::Path):
     20        (WebCore::Path::operator=):
     21        * platform/graphics/win/PathDirect2D.cpp:
     22        (WebCore::Path::Path):
     23        (WebCore::Path::operator=):
     24        Define the move constructor and the move assignment operator for the the
     25        Path class so a statement like "Path path = buildPathFromString()" won't
     26        go through the copy constructor and the copy assignment operator.
     27
     28        * rendering/style/BasicShapes.cpp:
     29        (WebCore::SVGPathTranslatedByteStream::path const):
     30        * rendering/svg/RenderSVGResourceClipper.cpp:
     31        (WebCore::RenderSVGResourceClipper::pathOnlyClipping):
     32        * rendering/svg/RenderSVGShape.cpp:
     33        (WebCore::RenderSVGShape::updateShapeFromElement):
     34        * rendering/svg/RenderSVGTextPath.cpp:
     35        (WebCore::RenderSVGTextPath::layoutPath const):
     36        * rendering/svg/SVGPathData.cpp:
     37        (WebCore::pathFromCircleElement):
     38        (WebCore::pathFromEllipseElement):
     39        (WebCore::pathFromLineElement):
     40        (WebCore::pathFromPathElement):
     41        (WebCore::pathFromPolygonElement):
     42        (WebCore::pathFromPolylineElement):
     43        (WebCore::pathFromRectElement):
     44        (WebCore::pathFromGraphicsElement):
     45        (WebCore::updatePathFromCircleElement): Deleted.
     46        (WebCore::updatePathFromEllipseElement): Deleted.
     47        (WebCore::updatePathFromLineElement): Deleted.
     48        (WebCore::updatePathFromPathElement): Deleted.
     49        (WebCore::updatePathFromPolygonElement): Deleted.
     50        (WebCore::updatePathFromPolylineElement): Deleted.
     51        (WebCore::updatePathFromRectElement): Deleted.
     52        (WebCore::updatePathFromGraphicsElement): Deleted.
     53        * rendering/svg/SVGPathData.h:
     54        * svg/SVGAnimateMotionElement.cpp:
     55        (WebCore::SVGAnimateMotionElement::parseAttribute):
     56        (WebCore::SVGAnimateMotionElement::updateAnimationPath):
     57        * svg/SVGGraphicsElement.cpp:
     58        (WebCore::SVGGraphicsElement::toClipPath):
     59        * svg/SVGGraphicsElement.h:
     60        Rename updatePathFromElement() to pathFromGraphicsElement().
     61
     62        * svg/SVGPathElement.cpp:
     63        (WebCore::SVGPathElement::parseAttribute): Clear the cache when
     64        m_pathByteStream changes.
     65        (WebCore::SVGPathElement::pathForByteStream const): Caches the m_cachedPath
     66        if it is null.
     67        (WebCore::SVGPathElement::pathSegListChanged): Clear the cache when
     68        m_pathByteStream changes.
     69
     70        * svg/SVGPathElement.h:
     71        * svg/SVGPathUtilities.cpp:
     72        (WebCore::buildPathFromString):
     73        (WebCore::buildPathFromByteStream):
     74        * svg/SVGPathUtilities.h:
     75        Make thes buildPathFromString() and buildPathFromByteStream() return Paths.
     76
     77        * svg/SVGUseElement.cpp:
     78        (WebCore::SVGUseElement::toClipPath):
     79        * svg/SVGUseElement.h:
     80        Make these toClipPath() return Path.
     81
    1822017-10-20  Ryosuke Niwa  <rniwa@webkit.org>
    283
  • trunk/Source/WebCore/html/canvas/Path2D.h

    r221598 r223804  
    5959    static Ref<Path2D> create(const String& pathData)
    6060    {
    61         Path path;
    62         buildPathFromString(pathData, path);
    63         return create(path);
     61        return create(buildPathFromString(pathData));
    6462    }
    6563
  • trunk/Source/WebCore/platform/graphics/Path.h

    r222113 r223804  
    116116
    117117        WEBCORE_EXPORT Path(const Path&);
     118        WEBCORE_EXPORT Path(Path&&);
    118119        WEBCORE_EXPORT Path& operator=(const Path&);
     120        WEBCORE_EXPORT Path& operator=(Path&&);
    119121       
    120122        static Path polygonPathFromPoints(const Vector<FloatPoint>&);
  • trunk/Source/WebCore/platform/graphics/cairo/PathCairo.cpp

    r222603 r223804  
    6161    cairo_append_path(cr, pathCopy);
    6262    cairo_path_destroy(pathCopy);
     63}
     64   
     65Path::Path(Path&& other)
     66{
     67    m_path = other.m_path;
     68    other.m_path = nullptr;
    6369}
    6470
     
    8894    }
    8995
     96    return *this;
     97}
     98   
     99Path& Path::operator=(Path&& other)
     100{
     101    if (this == &other)
     102        return *this;
     103    if (m_path)
     104        delete m_path;
     105    m_path = other.m_path;
     106    other.m_path = nullptr;
    90107    return *this;
    91108}
  • trunk/Source/WebCore/platform/graphics/cg/PathCG.cpp

    r222898 r223804  
    114114}
    115115
     116Path::Path(Path&& other)
     117{
     118    m_path = other.m_path;
     119    other.m_path = nullptr;
     120}
     121   
    116122Path& Path::operator=(const Path& other)
    117123{
    118     CGMutablePathRef path = other.m_path ? CGPathCreateMutableCopy(other.m_path) : 0;
     124    if (this == &other)
     125        return *this;
    119126    if (m_path)
    120127        CGPathRelease(m_path);
    121     m_path = path;
     128    m_path = other.m_path ? CGPathCreateMutableCopy(other.m_path) : nullptr;
     129    return *this;
     130}
     131
     132Path& Path::operator=(Path&& other)
     133{
     134    if (this == &other)
     135        return *this;
     136    if (m_path)
     137        CGPathRelease(m_path);
     138    m_path = other.m_path;
     139    other.m_path = nullptr;
    122140    return *this;
    123141}
  • trunk/Source/WebCore/platform/graphics/win/PathDirect2D.cpp

    r223728 r223804  
    159159    }
    160160}
    161 
    162 Path& Path::operator=(const Path& other)
     161   
     162Path::Path(Path&& other)
    163163{
    164164    m_path = other.m_path;
    165165    m_activePath = other.m_activePath;
    166166    m_activePathGeometry = other.m_activePathGeometry;
    167 
     167    other.m_path = nullptr;
     168    other.m_activePath = nullptr;
     169    other.m_activePathGeometry = nullptr;
     170}
     171
     172Path& Path::operator=(const Path& other)
     173{
     174    m_path = other.m_path;
     175    m_activePath = other.m_activePath;
     176    m_activePathGeometry = other.m_activePathGeometry;
     177    return *this;
     178}
     179
     180Path& Path::operator=(Path&& other)
     181{
     182    if (this == &other)
     183        return *this;
     184    m_path = other.m_path;
     185    m_activePath = other.m_activePath;
     186    m_activePathGeometry = other.m_activePathGeometry;
     187    other.m_path = nullptr;
     188    other.m_activePath = nullptr;
     189    other.m_activePathGeometry = nullptr;
    168190    return *this;
    169191}
  • trunk/Source/WebCore/rendering/style/BasicShapes.cpp

    r213603 r223804  
    7474    Path path() const
    7575    {
    76         Path path;
    77         buildPathFromByteStream(m_rawStream, path);
     76        Path path = buildPathFromByteStream(m_rawStream);
    7877        path.translate(toFloatSize(m_offset));
    7978        return path;
  • trunk/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp

    r223728 r223804  
    103103        // Fallback to masking, if there is more than one clipping path.
    104104        if (clipPath.isEmpty()) {
    105             styled.toClipPath(clipPath);
     105            clipPath = styled.toClipPath();
    106106            clipRule = svgStyle.clipRule();
    107107        } else
  • trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp

    r223728 r223804  
    7676void RenderSVGShape::updateShapeFromElement()
    7777{
    78     m_path = std::make_unique<Path>();
    79     ASSERT(RenderSVGShape::isEmpty());
    80 
    81     updatePathFromGraphicsElement(&graphicsElement(), path());
     78    m_path = std::make_unique<Path>(pathFromGraphicsElement(&graphicsElement()));
    8279    processMarkerPositions();
    8380
  • trunk/Source/WebCore/rendering/svg/RenderSVGTextPath.cpp

    r208863 r223804  
    5050    SVGPathElement& pathElement = downcast<SVGPathElement>(*targetElement);
    5151   
    52     Path pathData;
    53     updatePathFromGraphicsElement(&pathElement, pathData);
     52    Path path = pathFromGraphicsElement(&pathElement);
    5453
    5554    // Spec:  The transform attribute on the referenced 'path' element represents a
     
    5857    // system due to a possible transform attribute on the current 'text' element.
    5958    // http://www.w3.org/TR/SVG/text.html#TextPathElement
    60     pathData.transform(pathElement.animatedLocalTransform());
    61     return pathData;
     59    path.transform(pathElement.animatedLocalTransform());
     60    return path;
    6261}
    6362
  • trunk/Source/WebCore/rendering/svg/SVGPathData.cpp

    r208863 r223804  
    4040namespace WebCore {
    4141
    42 static void updatePathFromCircleElement(SVGElement* element, Path& path)
     42static Path pathFromCircleElement(SVGElement& element)
    4343{
    4444    ASSERT(is<SVGCircleElement>(element));
    4545
    46     SVGLengthContext lengthContext(element);
    47     RenderElement* renderer = element->renderer();
     46    RenderElement* renderer = element.renderer();
    4847    if (!renderer)
    49         return;
     48        return { };
     49
     50    Path path;
    5051    auto& style = renderer->style();
     52    SVGLengthContext lengthContext(&element);
    5153    float r = lengthContext.valueForLength(style.svgStyle().r());
    5254    if (r > 0) {
     
    5557        path.addEllipse(FloatRect(cx - r, cy - r, r * 2, r * 2));
    5658    }
     59    return path;
    5760}
    5861
    59 static void updatePathFromEllipseElement(SVGElement* element, Path& path)
     62static Path pathFromEllipseElement(SVGElement& element)
    6063{
    61     RenderElement* renderer = element->renderer();
     64    RenderElement* renderer = element.renderer();
    6265    if (!renderer)
    63         return;
     66        return { };
     67
    6468    auto& style = renderer->style();
    65     SVGLengthContext lengthContext(element);
     69    SVGLengthContext lengthContext(&element);
    6670    float rx = lengthContext.valueForLength(style.svgStyle().rx(), LengthModeWidth);
    6771    if (rx <= 0)
    68         return;
     72        return { };
     73
    6974    float ry = lengthContext.valueForLength(style.svgStyle().ry(), LengthModeHeight);
    7075    if (ry <= 0)
    71         return;
     76        return { };
     77
     78    Path path;
    7279    float cx = lengthContext.valueForLength(style.svgStyle().cx(), LengthModeWidth);
    7380    float cy = lengthContext.valueForLength(style.svgStyle().cy(), LengthModeHeight);
    7481    path.addEllipse(FloatRect(cx - rx, cy - ry, rx * 2, ry * 2));
     82    return path;
    7583}
    7684
    77 static void updatePathFromLineElement(SVGElement* element, Path& path)
     85static Path pathFromLineElement(SVGElement& element)
    7886{
    79     SVGLineElement* line = downcast<SVGLineElement>(element);
     87    Path path;
     88    const auto& line = downcast<SVGLineElement>(element);
    8089
    81     SVGLengthContext lengthContext(element);
    82     path.moveTo(FloatPoint(line->x1().value(lengthContext), line->y1().value(lengthContext)));
    83     path.addLineTo(FloatPoint(line->x2().value(lengthContext), line->y2().value(lengthContext)));
     90    SVGLengthContext lengthContext(&element);
     91    path.moveTo(FloatPoint(line.x1().value(lengthContext), line.y1().value(lengthContext)));
     92    path.addLineTo(FloatPoint(line.x2().value(lengthContext), line.y2().value(lengthContext)));
     93    return path;
    8494}
    8595
    86 static void updatePathFromPathElement(SVGElement* element, Path& path)
     96static Path pathFromPathElement(SVGElement& element)
    8797{
    88     buildPathFromByteStream(downcast<SVGPathElement>(element)->pathByteStream(), path);
     98    return downcast<SVGPathElement>(element).pathForByteStream();
    8999}
    90100
    91 static void updatePathFromPolygonElement(SVGElement* element, Path& path)
     101static Path pathFromPolygonElement(SVGElement& element)
    92102{
    93     auto& points = downcast<SVGPolygonElement>(element)->animatedPoints()->values();
     103    auto& points = downcast<SVGPolygonElement>(element).animatedPoints()->values();
    94104    if (points.isEmpty())
    95         return;
     105        return { };
    96106
     107    Path path;
    97108    path.moveTo(points.first());
    98109
     
    102113
    103114    path.closeSubpath();
     115    return path;
    104116}
    105117
    106 static void updatePathFromPolylineElement(SVGElement* element, Path& path)
     118static Path pathFromPolylineElement(SVGElement& element)
    107119{
    108     auto& points = downcast<SVGPolylineElement>(element)->animatedPoints()->values();
     120    auto& points = downcast<SVGPolylineElement>(element).animatedPoints()->values();
    109121    if (points.isEmpty())
    110         return;
     122        return { };
    111123
     124    Path path;
    112125    path.moveTo(points.first());
    113126
     
    115128    for (unsigned i = 1; i < size; ++i)
    116129        path.addLineTo(points.at(i));
     130    return path;
    117131}
    118132
    119 static void updatePathFromRectElement(SVGElement* element, Path& path)
     133static Path pathFromRectElement(SVGElement& element)
    120134{
    121     RenderElement* renderer = element->renderer();
     135    RenderElement* renderer = element.renderer();
    122136    if (!renderer)
    123         return;
     137        return { };
    124138
    125139    auto& style = renderer->style();
    126     SVGLengthContext lengthContext(element);
     140    SVGLengthContext lengthContext(&element);
    127141    float width = lengthContext.valueForLength(style.width(), LengthModeWidth);
    128142    if (width <= 0)
    129         return;
     143        return { };
     144
    130145    float height = lengthContext.valueForLength(style.height(), LengthModeHeight);
    131146    if (height <= 0)
    132         return;
     147        return { };
     148
     149    Path path;
    133150    float x = lengthContext.valueForLength(style.svgStyle().x(), LengthModeWidth);
    134151    float y = lengthContext.valueForLength(style.svgStyle().y(), LengthModeHeight);
     
    146163        // See bug https://bugs.webkit.org/show_bug.cgi?id=79932 which tracks this issue.
    147164        path.addRoundedRect(FloatRect(x, y, width, height), FloatSize(rx, ry), Path::PreferBezierRoundedRect);
    148         return;
     165        return path;
    149166    }
    150167
    151168    path.addRect(FloatRect(x, y, width, height));
     169    return path;
    152170}
    153171
    154 void updatePathFromGraphicsElement(SVGElement* element, Path& path)
     172Path pathFromGraphicsElement(SVGElement* element)
    155173{
    156174    ASSERT(element);
    157     ASSERT(path.isEmpty());
    158175
    159     typedef void (*PathUpdateFunction)(SVGElement*, Path&);
    160     static HashMap<AtomicStringImpl*, PathUpdateFunction>* map = 0;
     176    typedef Path (*PathFromFunction)(SVGElement&);
     177    static HashMap<AtomicStringImpl*, PathFromFunction>* map = 0;
    161178    if (!map) {
    162         map = new HashMap<AtomicStringImpl*, PathUpdateFunction>;
    163         map->set(SVGNames::circleTag.localName().impl(), updatePathFromCircleElement);
    164         map->set(SVGNames::ellipseTag.localName().impl(), updatePathFromEllipseElement);
    165         map->set(SVGNames::lineTag.localName().impl(), updatePathFromLineElement);
    166         map->set(SVGNames::pathTag.localName().impl(), updatePathFromPathElement);
    167         map->set(SVGNames::polygonTag.localName().impl(), updatePathFromPolygonElement);
    168         map->set(SVGNames::polylineTag.localName().impl(), updatePathFromPolylineElement);
    169         map->set(SVGNames::rectTag.localName().impl(), updatePathFromRectElement);
     179        map = new HashMap<AtomicStringImpl*, PathFromFunction>;
     180        map->set(SVGNames::circleTag.localName().impl(), pathFromCircleElement);
     181        map->set(SVGNames::ellipseTag.localName().impl(), pathFromEllipseElement);
     182        map->set(SVGNames::lineTag.localName().impl(), pathFromLineElement);
     183        map->set(SVGNames::pathTag.localName().impl(), pathFromPathElement);
     184        map->set(SVGNames::polygonTag.localName().impl(), pathFromPolygonElement);
     185        map->set(SVGNames::polylineTag.localName().impl(), pathFromPolylineElement);
     186        map->set(SVGNames::rectTag.localName().impl(), pathFromRectElement);
    170187    }
    171188
    172     if (PathUpdateFunction pathUpdateFunction = map->get(element->localName().impl()))
    173         (*pathUpdateFunction)(element, path);
     189    if (PathFromFunction pathFromFunction = map->get(element->localName().impl()))
     190        return (*pathFromFunction)(*element);
     191   
     192    return { };
    174193}
    175194
  • trunk/Source/WebCore/rendering/svg/SVGPathData.h

    r208668 r223804  
    2525class Path;
    2626
    27 void updatePathFromGraphicsElement(SVGElement*, Path&);
     27Path pathFromGraphicsElement(SVGElement*);
    2828
    2929} // namespace WebCore
  • trunk/Source/WebCore/svg/SVGAnimateMotionElement.cpp

    r222253 r223804  
    9797{
    9898    if (name == SVGNames::pathAttr) {
    99         m_path = Path();
    100         buildPathFromString(value, m_path);
     99        m_path = buildPathFromString(value);
    101100        updateAnimationPath();
    102101        return;
     
    126125        SVGPathElement* pathElement = mPath.pathElement();
    127126        if (pathElement) {
    128             updatePathFromGraphicsElement(pathElement, m_animationPath);
     127            m_animationPath = pathFromGraphicsElement(pathElement);
    129128            foundMPath = true;
    130129            break;
  • trunk/Source/WebCore/svg/SVGGraphicsElement.cpp

    r223728 r223804  
    200200}
    201201
    202 void SVGGraphicsElement::toClipPath(Path& path)
    203 {
    204     updatePathFromGraphicsElement(this, path);
     202Path SVGGraphicsElement::toClipPath()
     203{
     204    Path path = pathFromGraphicsElement(this);
    205205    // FIXME: How do we know the element has done a layout?
    206206    path.transform(animatedLocalTransform());
     207    return path;
    207208}
    208209
  • trunk/Source/WebCore/svg/SVGGraphicsElement.h

    r208863 r223804  
    5757
    5858    // "base class" methods for all the elements which render as paths
    59     virtual void toClipPath(Path&);
     59    virtual Path toClipPath();
    6060    RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override;
    6161
  • trunk/Source/WebCore/svg/SVGPathElement.cpp

    r223802 r223804  
    226226        if (!buildSVGPathByteStreamFromString(value, m_pathByteStream, UnalteredParsing))
    227227            document().accessSVGExtensions().reportError("Problem parsing d=\"" + value + "\"");
     228        m_cachedPath = std::nullopt;
    228229        return;
    229230    }
     
    304305
    305306    return *animatedPathByteStream;
     307}
     308   
     309Path SVGPathElement::pathForByteStream() const
     310{
     311    const auto& pathByteStreamToUse = pathByteStream();
     312
     313    if (&pathByteStreamToUse == &m_pathByteStream) {
     314        if (!m_cachedPath)
     315            m_cachedPath = buildPathFromByteStream(m_pathByteStream);
     316        return *m_cachedPath;
     317    }
     318   
     319    return buildPathFromByteStream(pathByteStreamToUse);
    306320}
    307321
     
    383397        } else
    384398            buildSVGPathByteStreamFromSVGPathSegListValues(m_pathSegList.value, m_pathByteStream, UnalteredParsing);
     399        m_cachedPath = std::nullopt;
    385400        break;
    386401    case PathSegUndefinedRole:
  • trunk/Source/WebCore/svg/SVGPathElement.h

    r223802 r223804  
    2121#pragma once
    2222
     23#include "Path.h"
    2324#include "SVGAnimatedBoolean.h"
    2425#include "SVGAnimatedNumber.h"
     
    5354class SVGPoint;
    5455
    55 class SVGPathElement final : public SVGGraphicsElement,
    56                              public SVGExternalResourcesRequired {
     56class SVGPathElement final : public SVGGraphicsElement, public SVGExternalResourcesRequired {
    5757public:
    5858    static Ref<SVGPathElement> create(const QualifiedName&, Document&);
     
    8989
    9090    const SVGPathByteStream& pathByteStream() const;
     91    Path pathForByteStream() const;
    9192
    9293    void pathSegListChanged(SVGPathSegRole, ListModification = ListModificationUnknown);
     
    132133private:
    133134    SVGPathByteStream m_pathByteStream;
     135    mutable std::optional<Path> m_cachedPath;
    134136    mutable SVGSynchronizableAnimatedProperty<SVGPathSegListValues> m_pathSegList;
    135137    WeakPtrFactory<SVGPathElement> m_weakPtrFactory;
  • trunk/Source/WebCore/svg/SVGPathUtilities.cpp

    r219964 r223804  
    4040namespace WebCore {
    4141
    42 bool buildPathFromString(const String& d, Path& result)
     42Path buildPathFromString(const String& d)
    4343{
    4444    if (d.isEmpty())
    45         return true;
    46 
    47     SVGPathBuilder builder(result);
     45        return { };
     46
     47    Path path;
     48    SVGPathBuilder builder(path);
    4849    SVGPathStringSource source(d);
    49     return SVGPathParser::parse(source, builder);
     50    SVGPathParser::parse(source, builder);
     51    return path;
    5052}
    5153
     
    131133}
    132134
    133 bool buildPathFromByteStream(const SVGPathByteStream& stream, Path& result)
    134 {
    135     if (stream.isEmpty())
    136         return true;
    137 
    138     SVGPathBuilder builder(result);
    139     SVGPathByteStreamSource source(stream);
    140     return SVGPathParser::parse(source, builder);
     135Path buildPathFromByteStream(const SVGPathByteStream& stream)
     136{
     137    if (stream.isEmpty())
     138        return { };
     139
     140    Path path;
     141    SVGPathBuilder builder(path);
     142    SVGPathByteStreamSource source(stream);
     143    SVGPathParser::parse(source, builder);
     144    return path;
    141145}
    142146
  • trunk/Source/WebCore/svg/SVGPathUtilities.h

    r219964 r223804  
    3434
    3535// String/SVGPathByteStream -> Path
    36 bool buildPathFromString(const String&, Path&);
    37 bool buildPathFromByteStream(const SVGPathByteStream&, Path&);
     36Path buildPathFromString(const String&);
     37Path buildPathFromByteStream(const SVGPathByteStream&);
    3838
    3939// Path -> String
  • trunk/Source/WebCore/svg/SVGUseElement.cpp

    r223802 r223804  
    286286}
    287287
    288 void SVGUseElement::toClipPath(Path& path)
    289 {
    290     ASSERT(path.isEmpty());
    291 
     288Path SVGUseElement::toClipPath()
     289{
    292290    auto* targetClone = this->targetClone();
    293291    if (!is<SVGGraphicsElement>(targetClone))
    294         return;
     292        return { };
    295293
    296294    if (!isDirectReference(*targetClone)) {
    297295        // Spec: Indirect references are an error (14.3.5)
    298296        document().accessSVGExtensions().reportError(ASCIILiteral("Not allowed to use indirect reference in <clip-path>"));
    299         return;
    300     }
    301 
    302     downcast<SVGGraphicsElement>(*targetClone).toClipPath(path);
     297        return { };
     298    }
     299
     300    Path path = downcast<SVGGraphicsElement>(*targetClone).toClipPath();
    303301    SVGLengthContext lengthContext(this);
    304302    // FIXME: Find a way to do this without manual resolution of x/y here. It's potentially incorrect.
    305303    path.translate(FloatSize(x().value(lengthContext), y().value(lengthContext)));
    306304    path.transform(animatedLocalTransform());
     305    return path;
    307306}
    308307
  • trunk/Source/WebCore/svg/SVGUseElement.h

    r223802 r223804  
    6565    void willRecalcStyle(Style::Change) override;
    6666    RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override;
    67     void toClipPath(Path&) override;
     67    Path toClipPath() override;
    6868    bool haveLoadedRequiredResources() override;
    6969    void finishParsingChildren() override;
Note: See TracChangeset for help on using the changeset viewer.