37c180a01fa4d23b8d42f5dba75a295e26555684
[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 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 bool isKnownAttribute(const QualifiedName& attributeName) { return AttributeOwnerProxy::isKnownAttribute(attributeName); }
83     static bool isAnimatedLengthAttribute(const QualifiedName& attributeName) { return AttributeOwnerProxy::isAnimatedLengthAttribute(attributeName); }
84     static void registerAttributes();
85
86     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
87     void parseAttribute(const QualifiedName&, const AtomicString&) override;
88     void svgAttributeChanged(const QualifiedName&) override;
89     void childrenChanged(const ChildChange&) override;
90
91     RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override;
92     bool rendererIsNeeded(const RenderStyle&) override { return true; }
93
94     bool needsPendingResourceHandling() const override { return false; }
95
96     bool selfHasRelativeLengths() const override;
97
98     void setOrient(SVGMarkerOrientType, const SVGAngleValue&);
99
100     static const AtomicString& orientTypeIdentifier();
101     static const AtomicString& orientAngleIdentifier();
102
103     AttributeOwnerProxy m_attributeOwnerProxy { *this };
104
105     class SVGAnimatedCustomOrientTypeAttribute : public SVGAnimatedEnumerationAttribute<SVGMarkerOrientType> {
106     public:
107         using Base = SVGAnimatedEnumerationAttribute<SVGMarkerOrientType>;
108
109         SVGAnimatedCustomOrientTypeAttribute(SVGMarkerOrientType baseValue)
110             : Base(baseValue)
111         {
112         }
113         void synchronize(Element& element, const QualifiedName& attributeName)
114         {
115             static const NeverDestroyed<String> autoString = MAKE_STATIC_STRING_IMPL("auto");
116             static const NeverDestroyed<String> autoStartReverseString = MAKE_STATIC_STRING_IMPL("auto-start-reverse");
117
118             if (!shouldSynchronize())
119                 return;
120             if (value() == SVGMarkerOrientAuto)
121                 element.setSynchronizedLazyAttribute(attributeName, autoString.get());
122             else if (value() == SVGMarkerOrientAutoStartReverse)
123                 element.setSynchronizedLazyAttribute(attributeName, autoStartReverseString.get());
124         }
125     };
126
127     using SVGAnimatedCustomAngleAttributeAccessor = SVGAnimatedPairAttributeAccessor<SVGMarkerElement, SVGAnimatedAngleAttribute, AnimatedAngle, SVGAnimatedCustomOrientTypeAttribute, AnimatedEnumeration>;
128
129     SVGAnimatedLengthAttribute m_refX { LengthModeWidth };
130     SVGAnimatedLengthAttribute m_refY { LengthModeHeight };
131     SVGAnimatedLengthAttribute m_markerWidth { LengthModeWidth, "3" };
132     SVGAnimatedLengthAttribute m_markerHeight { LengthModeHeight, "3" };
133     SVGAnimatedEnumerationAttribute<SVGMarkerUnitsType> m_markerUnits { SVGMarkerUnitsStrokeWidth };
134     SVGAnimatedAngleAttribute m_orientAngle;
135     SVGAnimatedCustomOrientTypeAttribute m_orientType { SVGMarkerOrientAngle };
136 };
137
138 } // namespace WebCore