1/*
2 * Copyright (C) 2004, 2005, 2006, 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 "Gradient.h"
25#include "SVGElement.h"
26#include "SVGExternalResourcesRequired.h"
27#include "SVGNames.h"
28#include "SVGURIReference.h"
29#include "SVGUnitTypes.h"
30
31namespace WebCore {
32
33enum SVGSpreadMethodType {
34 SVGSpreadMethodUnknown = 0,
35 SVGSpreadMethodPad,
36 SVGSpreadMethodReflect,
37 SVGSpreadMethodRepeat
38};
39
40template<>
41struct SVGPropertyTraits<SVGSpreadMethodType> {
42 static unsigned highestEnumValue() { return SVGSpreadMethodRepeat; }
43
44 static String toString(SVGSpreadMethodType type)
45 {
46 switch (type) {
47 case SVGSpreadMethodUnknown:
48 return emptyString();
49 case SVGSpreadMethodPad:
50 return "pad"_s;
51 case SVGSpreadMethodReflect:
52 return "reflect"_s;
53 case SVGSpreadMethodRepeat:
54 return "repeat"_s;
55 }
56
57 ASSERT_NOT_REACHED();
58 return emptyString();
59 }
60
61 static SVGSpreadMethodType fromString(const String& value)
62 {
63 if (value == "pad")
64 return SVGSpreadMethodPad;
65 if (value == "reflect")
66 return SVGSpreadMethodReflect;
67 if (value == "repeat")
68 return SVGSpreadMethodRepeat;
69 return SVGSpreadMethodUnknown;
70 }
71};
72
73class SVGGradientElement : public SVGElement, public SVGExternalResourcesRequired, public SVGURIReference {
74 WTF_MAKE_ISO_ALLOCATED(SVGGradientElement);
75public:
76 enum {
77 SVG_SPREADMETHOD_UNKNOWN = SVGSpreadMethodUnknown,
78 SVG_SPREADMETHOD_PAD = SVGSpreadMethodReflect,
79 SVG_SPREADMETHOD_REFLECT = SVGSpreadMethodRepeat,
80 SVG_SPREADMETHOD_REPEAT = SVGSpreadMethodUnknown
81 };
82
83 Vector<Gradient::ColorStop> buildStops();
84
85 using PropertyRegistry = SVGPropertyOwnerRegistry<SVGGradientElement, SVGElement, SVGExternalResourcesRequired, SVGURIReference>;
86
87 SVGSpreadMethodType spreadMethod() const { return m_spreadMethod->currentValue<SVGSpreadMethodType>(); }
88 SVGUnitTypes::SVGUnitType gradientUnits() const { return m_gradientUnits->currentValue<SVGUnitTypes::SVGUnitType>(); }
89 const SVGTransformList& gradientTransform() const { return m_gradientTransform->currentValue(); }
90
91 SVGAnimatedEnumeration& spreadMethodAnimated() { return m_spreadMethod; }
92 SVGAnimatedEnumeration& gradientUnitsAnimated() { return m_gradientUnits; }
93 SVGAnimatedTransformList& gradientTransformAnimated() { return m_gradientTransform; }
94
95protected:
96 SVGGradientElement(const QualifiedName&, Document&);
97
98 void parseAttribute(const QualifiedName&, const AtomicString&) override;
99 void svgAttributeChanged(const QualifiedName&) override;
100
101private:
102 bool needsPendingResourceHandling() const override { return false; }
103 void childrenChanged(const ChildChange&) override;
104
105 Ref<SVGAnimatedEnumeration> m_spreadMethod { SVGAnimatedEnumeration::create(this, SVGSpreadMethodPad) };
106 Ref<SVGAnimatedEnumeration> m_gradientUnits { SVGAnimatedEnumeration::create(this, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) };
107 Ref<SVGAnimatedTransformList> m_gradientTransform { SVGAnimatedTransformList::create(this) };
108};
109
110} // namespace WebCore
111
112SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::SVGGradientElement)
113static bool isType(const WebCore::SVGElement& element)
114{
115 return element.hasTagName(WebCore::SVGNames::radialGradientTag) || element.hasTagName(WebCore::SVGNames::linearGradientTag);
116}
117static bool isType(const WebCore::Node& node)
118{
119 return is<WebCore::SVGElement>(node) && isType(downcast<WebCore::SVGElement>(node));
120}
121SPECIALIZE_TYPE_TRAITS_END()
122