1/*
2 * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2018-2019 Apple Inc. All rights reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21#pragma once
22
23#include "SVGNames.h"
24#include "SVGTextContentElement.h"
25#include "SVGURIReference.h"
26
27namespace WebCore {
28
29enum SVGTextPathMethodType {
30 SVGTextPathMethodUnknown = 0,
31 SVGTextPathMethodAlign,
32 SVGTextPathMethodStretch
33};
34
35enum SVGTextPathSpacingType {
36 SVGTextPathSpacingUnknown = 0,
37 SVGTextPathSpacingAuto,
38 SVGTextPathSpacingExact
39};
40
41template<>
42struct SVGPropertyTraits<SVGTextPathMethodType> {
43 static unsigned highestEnumValue() { return SVGTextPathMethodStretch; }
44
45 static String toString(SVGTextPathMethodType type)
46 {
47 switch (type) {
48 case SVGTextPathMethodUnknown:
49 return emptyString();
50 case SVGTextPathMethodAlign:
51 return "align"_s;
52 case SVGTextPathMethodStretch:
53 return "stretch"_s;
54 }
55
56 ASSERT_NOT_REACHED();
57 return emptyString();
58 }
59
60 static SVGTextPathMethodType fromString(const String& value)
61 {
62 if (value == "align")
63 return SVGTextPathMethodAlign;
64 if (value == "stretch")
65 return SVGTextPathMethodStretch;
66 return SVGTextPathMethodUnknown;
67 }
68};
69
70template<>
71struct SVGPropertyTraits<SVGTextPathSpacingType> {
72 static unsigned highestEnumValue() { return SVGTextPathSpacingExact; }
73
74 static String toString(SVGTextPathSpacingType type)
75 {
76 switch (type) {
77 case SVGTextPathSpacingUnknown:
78 return emptyString();
79 case SVGTextPathSpacingAuto:
80 return "auto"_s;
81 case SVGTextPathSpacingExact:
82 return "exact"_s;
83 }
84
85 ASSERT_NOT_REACHED();
86 return emptyString();
87 }
88
89 static SVGTextPathSpacingType fromString(const String& value)
90 {
91 if (value == "auto")
92 return SVGTextPathSpacingAuto;
93 if (value == "exact")
94 return SVGTextPathSpacingExact;
95 return SVGTextPathSpacingUnknown;
96 }
97};
98
99class SVGTextPathElement final : public SVGTextContentElement, public SVGURIReference {
100 WTF_MAKE_ISO_ALLOCATED(SVGTextPathElement);
101public:
102 // Forward declare enumerations in the W3C naming scheme, for IDL generation.
103 enum {
104 TEXTPATH_METHODTYPE_UNKNOWN = SVGTextPathMethodUnknown,
105 TEXTPATH_METHODTYPE_ALIGN = SVGTextPathMethodAlign,
106 TEXTPATH_METHODTYPE_STRETCH = SVGTextPathMethodStretch,
107 TEXTPATH_SPACINGTYPE_UNKNOWN = SVGTextPathSpacingUnknown,
108 TEXTPATH_SPACINGTYPE_AUTO = SVGTextPathSpacingAuto,
109 TEXTPATH_SPACINGTYPE_EXACT = SVGTextPathSpacingExact
110 };
111
112 static Ref<SVGTextPathElement> create(const QualifiedName&, Document&);
113
114 const SVGLengthValue& startOffset() const { return m_startOffset->currentValue(); }
115 SVGTextPathMethodType method() const { return m_method->currentValue<SVGTextPathMethodType>(); }
116 SVGTextPathSpacingType spacing() const { return m_spacing->currentValue<SVGTextPathSpacingType>(); }
117
118 SVGAnimatedLength& startOffsetAnimated() { return m_startOffset; }
119 SVGAnimatedEnumeration& methodAnimated() { return m_method; }
120 SVGAnimatedEnumeration& spacingAnimated() { return m_spacing; }
121
122protected:
123 void didFinishInsertingNode() override;
124
125private:
126 SVGTextPathElement(const QualifiedName&, Document&);
127 virtual ~SVGTextPathElement();
128
129 using PropertyRegistry = SVGPropertyOwnerRegistry<SVGTextPathElement, SVGTextContentElement, SVGURIReference>;
130 const SVGPropertyRegistry& propertyRegistry() const final { return m_propertyRegistry; }
131
132 void parseAttribute(const QualifiedName&, const AtomicString&) override;
133 void svgAttributeChanged(const QualifiedName&) override;
134
135 RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override;
136 bool childShouldCreateRenderer(const Node&) const override;
137 bool rendererIsNeeded(const RenderStyle&) override;
138
139 void clearResourceReferences();
140 void buildPendingResource() override;
141 InsertedIntoAncestorResult insertedIntoAncestor(InsertionType, ContainerNode&) override;
142 void removedFromAncestor(RemovalType, ContainerNode&) override;
143
144 bool selfHasRelativeLengths() const override;
145
146 PropertyRegistry m_propertyRegistry { *this };
147 Ref<SVGAnimatedLength> m_startOffset { SVGAnimatedLength::create(this, LengthModeOther) };
148 Ref<SVGAnimatedEnumeration> m_method { SVGAnimatedEnumeration::create(this, SVGTextPathMethodAlign) };
149 Ref<SVGAnimatedEnumeration> m_spacing { SVGAnimatedEnumeration::create(this, SVGTextPathSpacingExact) };
150};
151
152} // namespace WebCore
153