1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "mozilla/dom/SVGGradientElement.h"
8 
9 #include "mozilla/ArrayUtils.h"
10 #include "mozilla/dom/SVGAnimatedTransformList.h"
11 #include "mozilla/dom/SVGGradientElementBinding.h"
12 #include "mozilla/dom/SVGRadialGradientElementBinding.h"
13 #include "mozilla/dom/SVGLengthBinding.h"
14 #include "mozilla/dom/SVGLinearGradientElementBinding.h"
15 #include "mozilla/dom/SVGUnitTypesBinding.h"
16 #include "nsCOMPtr.h"
17 #include "nsGkAtoms.h"
18 #include "nsSVGElement.h"
19 
20 NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(LinearGradient)
21 NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(RadialGradient)
22 
23 namespace mozilla {
24 namespace dom {
25 
26 using namespace SVGGradientElementBinding;
27 using namespace SVGUnitTypesBinding;
28 
29 //--------------------- Gradients------------------------
30 
31 nsSVGEnumMapping SVGGradientElement::sSpreadMethodMap[] = {
32     {&nsGkAtoms::pad, SVG_SPREADMETHOD_PAD},
33     {&nsGkAtoms::reflect, SVG_SPREADMETHOD_REFLECT},
34     {&nsGkAtoms::repeat, SVG_SPREADMETHOD_REPEAT},
35     {nullptr, 0}};
36 
37 nsSVGElement::EnumInfo SVGGradientElement::sEnumInfo[2] = {
38     {&nsGkAtoms::gradientUnits, sSVGUnitTypesMap,
39      SVG_UNIT_TYPE_OBJECTBOUNDINGBOX},
40     {&nsGkAtoms::spreadMethod, sSpreadMethodMap, SVG_SPREADMETHOD_PAD}};
41 
42 nsSVGElement::StringInfo SVGGradientElement::sStringInfo[2] = {
43     {&nsGkAtoms::href, kNameSpaceID_None, true},
44     {&nsGkAtoms::href, kNameSpaceID_XLink, true}};
45 
46 //----------------------------------------------------------------------
47 // Implementation
48 
SVGGradientElement(already_AddRefed<mozilla::dom::NodeInfo> & aNodeInfo)49 SVGGradientElement::SVGGradientElement(
50     already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
51     : SVGGradientElementBase(aNodeInfo) {}
52 
53 //----------------------------------------------------------------------
54 // nsSVGElement methods
55 
GetEnumInfo()56 nsSVGElement::EnumAttributesInfo SVGGradientElement::GetEnumInfo() {
57   return EnumAttributesInfo(mEnumAttributes, sEnumInfo, ArrayLength(sEnumInfo));
58 }
59 
GetStringInfo()60 nsSVGElement::StringAttributesInfo SVGGradientElement::GetStringInfo() {
61   return StringAttributesInfo(mStringAttributes, sStringInfo,
62                               ArrayLength(sStringInfo));
63 }
64 
GradientUnits()65 already_AddRefed<SVGAnimatedEnumeration> SVGGradientElement::GradientUnits() {
66   return mEnumAttributes[GRADIENTUNITS].ToDOMAnimatedEnum(this);
67 }
68 
69 already_AddRefed<SVGAnimatedTransformList>
GradientTransform()70 SVGGradientElement::GradientTransform() {
71   // We're creating a DOM wrapper, so we must tell GetAnimatedTransformList
72   // to allocate the SVGAnimatedTransformList if it hasn't already done so:
73   return SVGAnimatedTransformList::GetDOMWrapper(
74       GetAnimatedTransformList(DO_ALLOCATE), this);
75 }
76 
SpreadMethod()77 already_AddRefed<SVGAnimatedEnumeration> SVGGradientElement::SpreadMethod() {
78   return mEnumAttributes[SPREADMETHOD].ToDOMAnimatedEnum(this);
79 }
80 
Href()81 already_AddRefed<SVGAnimatedString> SVGGradientElement::Href() {
82   return mStringAttributes[HREF].IsExplicitlySet()
83              ? mStringAttributes[HREF].ToDOMAnimatedString(this)
84              : mStringAttributes[XLINK_HREF].ToDOMAnimatedString(this);
85 }
86 
87 //----------------------------------------------------------------------
88 // nsIContent methods
89 
NS_IMETHODIMP_(bool)90 NS_IMETHODIMP_(bool)
91 SVGGradientElement::IsAttributeMapped(const nsAtom* name) const {
92   static const MappedAttributeEntry* const map[] = {sColorMap,
93                                                     sGradientStopMap};
94 
95   return FindAttributeDependence(name, map) ||
96          SVGGradientElementBase::IsAttributeMapped(name);
97 }
98 
99 //---------------------Linear Gradients------------------------
100 
WrapNode(JSContext * aCx,JS::Handle<JSObject * > aGivenProto)101 JSObject* SVGLinearGradientElement::WrapNode(
102     JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
103   return SVGLinearGradientElementBinding::Wrap(aCx, this, aGivenProto);
104 }
105 
106 nsSVGElement::LengthInfo SVGLinearGradientElement::sLengthInfo[4] = {
107     {&nsGkAtoms::x1, 0, SVGLengthBinding::SVG_LENGTHTYPE_PERCENTAGE,
108      SVGContentUtils::X},
109     {&nsGkAtoms::y1, 0, SVGLengthBinding::SVG_LENGTHTYPE_PERCENTAGE,
110      SVGContentUtils::Y},
111     {&nsGkAtoms::x2, 100, SVGLengthBinding::SVG_LENGTHTYPE_PERCENTAGE,
112      SVGContentUtils::X},
113     {&nsGkAtoms::y2, 0, SVGLengthBinding::SVG_LENGTHTYPE_PERCENTAGE,
114      SVGContentUtils::Y},
115 };
116 
117 //----------------------------------------------------------------------
118 // Implementation
119 
SVGLinearGradientElement(already_AddRefed<mozilla::dom::NodeInfo> & aNodeInfo)120 SVGLinearGradientElement::SVGLinearGradientElement(
121     already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
122     : SVGLinearGradientElementBase(aNodeInfo) {}
123 
124 //----------------------------------------------------------------------
125 // nsIDOMNode methods
126 
NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGLinearGradientElement)127 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGLinearGradientElement)
128 
129 //----------------------------------------------------------------------
130 
131 already_AddRefed<SVGAnimatedLength> SVGLinearGradientElement::X1() {
132   return mLengthAttributes[ATTR_X1].ToDOMAnimatedLength(this);
133 }
134 
Y1()135 already_AddRefed<SVGAnimatedLength> SVGLinearGradientElement::Y1() {
136   return mLengthAttributes[ATTR_Y1].ToDOMAnimatedLength(this);
137 }
138 
X2()139 already_AddRefed<SVGAnimatedLength> SVGLinearGradientElement::X2() {
140   return mLengthAttributes[ATTR_X2].ToDOMAnimatedLength(this);
141 }
142 
Y2()143 already_AddRefed<SVGAnimatedLength> SVGLinearGradientElement::Y2() {
144   return mLengthAttributes[ATTR_Y2].ToDOMAnimatedLength(this);
145 }
146 
147 //----------------------------------------------------------------------
148 // nsSVGElement methods
149 
GetAnimatedTransformList(uint32_t aFlags)150 nsSVGAnimatedTransformList* SVGGradientElement::GetAnimatedTransformList(
151     uint32_t aFlags) {
152   if (!mGradientTransform && (aFlags & DO_ALLOCATE)) {
153     mGradientTransform = new nsSVGAnimatedTransformList();
154   }
155   return mGradientTransform;
156 }
157 
GetLengthInfo()158 nsSVGElement::LengthAttributesInfo SVGLinearGradientElement::GetLengthInfo() {
159   return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
160                               ArrayLength(sLengthInfo));
161 }
162 
163 //-------------------------- Radial Gradients ----------------------------
164 
WrapNode(JSContext * aCx,JS::Handle<JSObject * > aGivenProto)165 JSObject* SVGRadialGradientElement::WrapNode(
166     JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
167   return SVGRadialGradientElementBinding::Wrap(aCx, this, aGivenProto);
168 }
169 
170 nsSVGElement::LengthInfo SVGRadialGradientElement::sLengthInfo[6] = {
171     {&nsGkAtoms::cx, 50, SVGLengthBinding::SVG_LENGTHTYPE_PERCENTAGE,
172      SVGContentUtils::X},
173     {&nsGkAtoms::cy, 50, SVGLengthBinding::SVG_LENGTHTYPE_PERCENTAGE,
174      SVGContentUtils::Y},
175     {&nsGkAtoms::r, 50, SVGLengthBinding::SVG_LENGTHTYPE_PERCENTAGE,
176      SVGContentUtils::XY},
177     {&nsGkAtoms::fx, 50, SVGLengthBinding::SVG_LENGTHTYPE_PERCENTAGE,
178      SVGContentUtils::X},
179     {&nsGkAtoms::fy, 50, SVGLengthBinding::SVG_LENGTHTYPE_PERCENTAGE,
180      SVGContentUtils::Y},
181     {&nsGkAtoms::fr, 0, SVGLengthBinding::SVG_LENGTHTYPE_PERCENTAGE,
182      SVGContentUtils::XY},
183 };
184 
185 //----------------------------------------------------------------------
186 // Implementation
187 
SVGRadialGradientElement(already_AddRefed<mozilla::dom::NodeInfo> & aNodeInfo)188 SVGRadialGradientElement::SVGRadialGradientElement(
189     already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
190     : SVGRadialGradientElementBase(aNodeInfo) {}
191 
192 //----------------------------------------------------------------------
193 // nsIDOMNode methods
194 
NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGRadialGradientElement)195 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGRadialGradientElement)
196 
197 //----------------------------------------------------------------------
198 
199 already_AddRefed<SVGAnimatedLength> SVGRadialGradientElement::Cx() {
200   return mLengthAttributes[ATTR_CX].ToDOMAnimatedLength(this);
201 }
202 
Cy()203 already_AddRefed<SVGAnimatedLength> SVGRadialGradientElement::Cy() {
204   return mLengthAttributes[ATTR_CY].ToDOMAnimatedLength(this);
205 }
206 
R()207 already_AddRefed<SVGAnimatedLength> SVGRadialGradientElement::R() {
208   return mLengthAttributes[ATTR_R].ToDOMAnimatedLength(this);
209 }
210 
Fx()211 already_AddRefed<SVGAnimatedLength> SVGRadialGradientElement::Fx() {
212   return mLengthAttributes[ATTR_FX].ToDOMAnimatedLength(this);
213 }
214 
Fy()215 already_AddRefed<SVGAnimatedLength> SVGRadialGradientElement::Fy() {
216   return mLengthAttributes[ATTR_FY].ToDOMAnimatedLength(this);
217 }
218 
Fr()219 already_AddRefed<SVGAnimatedLength> SVGRadialGradientElement::Fr() {
220   return mLengthAttributes[ATTR_FR].ToDOMAnimatedLength(this);
221 }
222 
223 //----------------------------------------------------------------------
224 // nsSVGElement methods
225 
GetLengthInfo()226 nsSVGElement::LengthAttributesInfo SVGRadialGradientElement::GetLengthInfo() {
227   return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
228                               ArrayLength(sLengthInfo));
229 }
230 
231 }  // namespace dom
232 }  // namespace mozilla
233