1/*
2 * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
4 * Copyright (C) 2018 Apple Inc. All rights reserved.
5 * Copyright (C) 2018 Adobe Systems Incorporated. All rights reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 */
22
23#include "config.h"
24#include "SVGGeometryElement.h"
25
26#include "DOMPoint.h"
27#include "RenderSVGResource.h"
28#include "RenderSVGShape.h"
29#include "SVGDocumentExtensions.h"
30#include "SVGPathUtilities.h"
31#include "SVGPoint.h"
32#include <wtf/IsoMallocInlines.h>
33
34namespace WebCore {
35
36WTF_MAKE_ISO_ALLOCATED_IMPL(SVGGeometryElement);
37
38SVGGeometryElement::SVGGeometryElement(const QualifiedName& tagName, Document& document)
39 : SVGGraphicsElement(tagName, document)
40{
41 static std::once_flag onceFlag;
42 std::call_once(onceFlag, [] {
43 PropertyRegistry::registerProperty<SVGNames::pathLengthAttr, &SVGGeometryElement::m_pathLength>();
44 });
45}
46
47float SVGGeometryElement::getTotalLength() const
48{
49 document().updateLayoutIgnorePendingStylesheets();
50
51 auto* renderer = downcast<RenderSVGShape>(this->renderer());
52 if (!renderer)
53 return 0;
54
55 return renderer->getTotalLength();
56}
57
58Ref<SVGPoint> SVGGeometryElement::getPointAtLength(float distance) const
59{
60 FloatPoint point { };
61
62 document().updateLayoutIgnorePendingStylesheets();
63
64 auto* renderer = downcast<RenderSVGShape>(this->renderer());
65 if (renderer)
66 renderer->getPointAtLength(point, distance);
67
68 return SVGPoint::create(point);
69}
70
71bool SVGGeometryElement::isPointInFill(DOMPointInit&& pointInit)
72{
73 document().updateLayoutIgnorePendingStylesheets();
74
75 auto* renderer = downcast<RenderSVGShape>(this->renderer());
76 if (!renderer)
77 return false;
78
79 FloatPoint point {static_cast<float>(pointInit.x), static_cast<float>(pointInit.y)};
80 return renderer->isPointInFill(point);
81}
82
83bool SVGGeometryElement::isPointInStroke(DOMPointInit&& pointInit)
84{
85 document().updateLayoutIgnorePendingStylesheets();
86
87 auto* renderer = downcast<RenderSVGShape>(this->renderer());
88 if (!renderer)
89 return false;
90
91 FloatPoint point {static_cast<float>(pointInit.x), static_cast<float>(pointInit.y)};
92 return renderer->isPointInStroke(point);
93}
94
95void SVGGeometryElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
96{
97 if (name == SVGNames::pathLengthAttr) {
98 m_pathLength->setBaseValInternal(value.toFloat());
99 if (m_pathLength->baseVal() < 0)
100 document().accessSVGExtensions().reportError("A negative value for path attribute <pathLength> is not allowed");
101 return;
102 }
103
104 SVGGraphicsElement::parseAttribute(name, value);
105}
106
107void SVGGeometryElement::svgAttributeChanged(const QualifiedName& attrName)
108{
109 if (attrName == SVGNames::pathLengthAttr) {
110 InstanceInvalidationGuard guard(*this);
111 if (auto* renderer = this->renderer())
112 RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer);
113 return;
114 }
115
116 SVGGraphicsElement::svgAttributeChanged(attrName);
117}
118
119}
120