Define the type of SVGPropertyOwnerRegistry for all SVG elements
[WebKit-https.git] / Source / WebCore / svg / SVGMarkerElement.h
1 /*
2  * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3  * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
4  * Copyright (C) 2018-2019 Apple Inc. All rights reserved.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21
22 #pragma once
23
24 #include "SVGAnimatedAngle.h"
25 #include "SVGAnimatedBoolean.h"
26 #include "SVGAnimatedEnumeration.h"
27 #include "SVGAnimatedLength.h"
28 #include "SVGAnimatedPreserveAspectRatio.h"
29 #include "SVGAnimatedRect.h"
30 #include "SVGElement.h"
31 #include "SVGExternalResourcesRequired.h"
32 #include "SVGFitToViewBox.h"
33 #include "SVGMarkerTypes.h"
34
35 namespace WebCore {
36
37 class SVGMarkerElement final : public SVGElement, public SVGExternalResourcesRequired, public SVGFitToViewBox {
38     WTF_MAKE_ISO_ALLOCATED(SVGMarkerElement);
39 public:
40     // Forward declare enumerations in the W3C naming scheme, for IDL generation.
41     enum {
42         SVG_MARKERUNITS_UNKNOWN = SVGMarkerUnitsUnknown,
43         SVG_MARKERUNITS_USERSPACEONUSE = SVGMarkerUnitsUserSpaceOnUse,
44         SVG_MARKERUNITS_STROKEWIDTH = SVGMarkerUnitsStrokeWidth
45     };
46
47     enum {
48         SVG_MARKER_ORIENT_UNKNOWN = SVGMarkerOrientUnknown,
49         SVG_MARKER_ORIENT_AUTO = SVGMarkerOrientAuto,
50         SVG_MARKER_ORIENT_ANGLE = SVGMarkerOrientAngle,
51         SVG_MARKER_ORIENT_AUTOSTARTREVERSE = SVGMarkerOrientAutoStartReverse
52     };
53
54     static Ref<SVGMarkerElement> create(const QualifiedName&, Document&);
55
56     AffineTransform viewBoxToViewTransform(float viewWidth, float viewHeight) const;
57
58     void setOrientToAuto();
59     void setOrientToAngle(SVGAngle&);
60
61     const SVGLengthValue& refX() const { return m_refX.currentValue(attributeOwnerProxy()); }
62     const SVGLengthValue& refY() const { return m_refY.currentValue(attributeOwnerProxy()); }
63     const SVGLengthValue& markerWidth() const { return m_markerWidth.currentValue(attributeOwnerProxy()); }
64     const SVGLengthValue& markerHeight() const { return m_markerHeight.currentValue(attributeOwnerProxy()); }
65     SVGMarkerUnitsType markerUnits() const { return m_markerUnits.currentValue(attributeOwnerProxy()); }
66     const SVGAngleValue& orientAngle() const { return m_orientAngle.currentValue(attributeOwnerProxy()); }
67     SVGMarkerOrientType orientType() const { return m_orientType.currentValue(attributeOwnerProxy()); }
68
69     RefPtr<SVGAnimatedLength> refXAnimated() { return m_refX.animatedProperty(attributeOwnerProxy()); }
70     RefPtr<SVGAnimatedLength> refYAnimated() { return m_refY.animatedProperty(attributeOwnerProxy()); }
71     RefPtr<SVGAnimatedLength> markerWidthAnimated() { return m_markerWidth.animatedProperty(attributeOwnerProxy()); }
72     RefPtr<SVGAnimatedLength> markerHeightAnimated() { return m_markerHeight.animatedProperty(attributeOwnerProxy()); }
73     RefPtr<SVGAnimatedEnumeration> markerUnitsAnimated() { return m_markerUnits.animatedProperty(attributeOwnerProxy()); }
74     RefPtr<SVGAnimatedAngle> orientAngleAnimated() { return m_orientAngle.animatedProperty(attributeOwnerProxy()); }
75     RefPtr<SVGAnimatedEnumeration> orientTypeAnimated() { return m_orientType.animatedProperty(attributeOwnerProxy()); }
76
77 private:
78     SVGMarkerElement(const QualifiedName&, Document&);
79
80     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGMarkerElement, SVGElement, SVGExternalResourcesRequired, SVGFitToViewBox>;
81     static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
82     static void registerAttributes();
83     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
84
85     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGMarkerElement, SVGElement, SVGExternalResourcesRequired, SVGFitToViewBox>;
86     const SVGPropertyRegistry& propertyRegistry() const final { return m_propertyRegistry; }
87
88     static bool isAnimatedLengthAttribute(const QualifiedName& attributeName) { return AttributeOwnerProxy::isAnimatedLengthAttribute(attributeName); }
89     static bool isKnownAttribute(const QualifiedName& attributeName)
90     {
91         return AttributeOwnerProxy::isKnownAttribute(attributeName) || PropertyRegistry::isKnownAttribute(attributeName);
92     }
93
94     void parseAttribute(const QualifiedName&, const AtomicString&) override;
95     void svgAttributeChanged(const QualifiedName&) override;
96     void childrenChanged(const ChildChange&) override;
97
98     RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override;
99     bool rendererIsNeeded(const RenderStyle&) override { return true; }
100
101     bool needsPendingResourceHandling() const override { return false; }
102
103     bool selfHasRelativeLengths() const override;
104
105     void setOrient(SVGMarkerOrientType, const SVGAngleValue&);
106
107     static const AtomicString& orientTypeIdentifier();
108     static const AtomicString& orientAngleIdentifier();
109
110     AttributeOwnerProxy m_attributeOwnerProxy { *this };
111
112     class SVGAnimatedCustomOrientTypeAttribute : public SVGAnimatedEnumerationAttribute<SVGMarkerOrientType> {
113     public:
114         using Base = SVGAnimatedEnumerationAttribute<SVGMarkerOrientType>;
115
116         SVGAnimatedCustomOrientTypeAttribute(SVGMarkerOrientType baseValue)
117             : Base(baseValue)
118         {
119         }
120         void synchronize(Element& element, const QualifiedName& attributeName)
121         {
122             static const NeverDestroyed<String> autoString = MAKE_STATIC_STRING_IMPL("auto");
123             static const NeverDestroyed<String> autoStartReverseString = MAKE_STATIC_STRING_IMPL("auto-start-reverse");
124
125             if (!shouldSynchronize())
126                 return;
127             if (value() == SVGMarkerOrientAuto)
128                 element.setSynchronizedLazyAttribute(attributeName, autoString.get());
129             else if (value() == SVGMarkerOrientAutoStartReverse)
130                 element.setSynchronizedLazyAttribute(attributeName, autoStartReverseString.get());
131         }
132     };
133
134     using SVGAnimatedCustomAngleAttributeAccessor = SVGAnimatedPairAttributeAccessor<SVGMarkerElement, SVGAnimatedAngleAttribute, AnimatedAngle, SVGAnimatedCustomOrientTypeAttribute, AnimatedEnumeration>;
135
136     PropertyRegistry m_propertyRegistry { *this };
137     SVGAnimatedLengthAttribute m_refX { LengthModeWidth };
138     SVGAnimatedLengthAttribute m_refY { LengthModeHeight };
139     SVGAnimatedLengthAttribute m_markerWidth { LengthModeWidth, "3" };
140     SVGAnimatedLengthAttribute m_markerHeight { LengthModeHeight, "3" };
141     SVGAnimatedEnumerationAttribute<SVGMarkerUnitsType> m_markerUnits { SVGMarkerUnitsStrokeWidth };
142     SVGAnimatedAngleAttribute m_orientAngle;
143     SVGAnimatedCustomOrientTypeAttribute m_orientType { SVGMarkerOrientAngle };
144 };
145
146 } // namespace WebCore