1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is the Mozilla SVG project.
16 : *
17 : * The Initial Developer of the Original Code is IBM Corporation.
18 : * Portions created by the Initial Developer are Copyright (C) 2004
19 : * the Initial Developer. All Rights Reserved.
20 : *
21 : * Contributor(s):
22 : *
23 : * Alternatively, the contents of this file may be used under the terms of
24 : * either of the GNU General Public License Version 2 or later (the "GPL"),
25 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 : * in which case the provisions of the GPL or the LGPL are applicable instead
27 : * of those above. If you wish to allow use of your version of this file only
28 : * under the terms of either the GPL or the LGPL, and not to allow others to
29 : * use your version of this file under the terms of the MPL, indicate your
30 : * decision by deleting the provisions above and replace them with the notice
31 : * and other provisions required by the GPL or the LGPL. If you do not delete
32 : * the provisions above, a recipient may use your version of this file under
33 : * the terms of any one of the MPL, the GPL or the LGPL.
34 : *
35 : * ***** END LICENSE BLOCK ***** */
36 :
37 : #include "mozilla/Util.h"
38 :
39 : #include "nsSVGAngle.h"
40 : #include "prdtoa.h"
41 : #include "nsTextFormatter.h"
42 : #include "nsSVGUtils.h"
43 : #include "nsSVGMarkerElement.h"
44 : #include "nsMathUtils.h"
45 : #include "nsContentUtils.h" // NS_ENSURE_FINITE
46 : #include "nsSMILValue.h"
47 : #include "SVGOrientSMILType.h"
48 :
49 : using namespace mozilla;
50 :
51 : /**
52 : * Mutable SVGAngle class for SVGSVGElement.createSVGAngle().
53 : *
54 : * Note that this class holds its own nsSVGAngle, which therefore can't be
55 : * animated. This means SVGMarkerElement::setOrientToAngle(angle) must copy
56 : * any DOMSVGAngle passed in. Perhaps this is wrong and inconsistent with
57 : * other parts of SVG, but it's how the code works for now.
58 : */
59 : class DOMSVGAngle : public nsIDOMSVGAngle
60 : {
61 : public:
62 : NS_DECL_ISUPPORTS
63 :
64 0 : DOMSVGAngle()
65 0 : { mVal.Init(); }
66 :
67 0 : NS_IMETHOD GetUnitType(PRUint16* aResult)
68 0 : { *aResult = mVal.mBaseValUnit; return NS_OK; }
69 :
70 0 : NS_IMETHOD GetValue(float* aResult)
71 0 : { *aResult = mVal.GetBaseValue(); return NS_OK; }
72 0 : NS_IMETHOD SetValue(float aValue)
73 : {
74 0 : NS_ENSURE_FINITE(aValue, NS_ERROR_ILLEGAL_VALUE);
75 0 : mVal.SetBaseValue(aValue, nsnull, true);
76 0 : return NS_OK;
77 : }
78 :
79 0 : NS_IMETHOD GetValueInSpecifiedUnits(float* aResult)
80 0 : { *aResult = mVal.mBaseVal; return NS_OK; }
81 0 : NS_IMETHOD SetValueInSpecifiedUnits(float aValue)
82 : {
83 0 : NS_ENSURE_FINITE(aValue, NS_ERROR_ILLEGAL_VALUE);
84 0 : mVal.mBaseVal = aValue;
85 0 : return NS_OK;
86 : }
87 :
88 0 : NS_IMETHOD SetValueAsString(const nsAString& aValue)
89 0 : { return mVal.SetBaseValueString(aValue, nsnull, false); }
90 0 : NS_IMETHOD GetValueAsString(nsAString& aValue)
91 0 : { mVal.GetBaseValueString(aValue); return NS_OK; }
92 :
93 0 : NS_IMETHOD NewValueSpecifiedUnits(PRUint16 unitType,
94 : float valueInSpecifiedUnits)
95 : {
96 0 : return mVal.NewValueSpecifiedUnits(unitType, valueInSpecifiedUnits, nsnull);
97 : }
98 :
99 0 : NS_IMETHOD ConvertToSpecifiedUnits(PRUint16 unitType)
100 0 : { return mVal.ConvertToSpecifiedUnits(unitType, nsnull); }
101 :
102 : private:
103 : nsSVGAngle mVal;
104 : };
105 :
106 1396 : NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGAngle::DOMBaseVal, mSVGElement)
107 :
108 1396 : NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGAngle::DOMAnimVal, mSVGElement)
109 :
110 1396 : NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGAngle::DOMAnimatedAngle, mSVGElement)
111 :
112 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsSVGAngle::DOMBaseVal)
113 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsSVGAngle::DOMBaseVal)
114 :
115 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsSVGAngle::DOMAnimVal)
116 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsSVGAngle::DOMAnimVal)
117 :
118 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsSVGAngle::DOMAnimatedAngle)
119 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsSVGAngle::DOMAnimatedAngle)
120 :
121 0 : NS_IMPL_ADDREF(DOMSVGAngle)
122 0 : NS_IMPL_RELEASE(DOMSVGAngle)
123 :
124 : DOMCI_DATA(SVGAngle, nsSVGAngle::DOMBaseVal)
125 : DOMCI_DATA(SVGAnimatedAngle, nsSVGAngle::DOMAnimatedAngle)
126 :
127 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGAngle::DOMBaseVal)
128 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAngle)
129 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
130 0 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAngle)
131 0 : NS_INTERFACE_MAP_END
132 :
133 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGAngle::DOMAnimVal)
134 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAngle)
135 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
136 0 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAngle)
137 0 : NS_INTERFACE_MAP_END
138 :
139 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGAngle::DOMAnimatedAngle)
140 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimatedAngle)
141 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
142 0 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAnimatedAngle)
143 0 : NS_INTERFACE_MAP_END
144 :
145 0 : NS_INTERFACE_MAP_BEGIN(DOMSVGAngle)
146 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAngle)
147 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
148 0 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAngle)
149 0 : NS_INTERFACE_MAP_END
150 :
151 : static nsIAtom** const unitMap[] =
152 : {
153 : nsnull, /* SVG_ANGLETYPE_UNKNOWN */
154 : nsnull, /* SVG_ANGLETYPE_UNSPECIFIED */
155 : &nsGkAtoms::deg,
156 : &nsGkAtoms::rad,
157 : &nsGkAtoms::grad
158 : };
159 :
160 : /* Helper functions */
161 :
162 : static bool
163 0 : IsValidUnitType(PRUint16 unit)
164 : {
165 0 : if (unit > nsIDOMSVGAngle::SVG_ANGLETYPE_UNKNOWN &&
166 : unit <= nsIDOMSVGAngle::SVG_ANGLETYPE_GRAD)
167 0 : return true;
168 :
169 0 : return false;
170 : }
171 :
172 : static void
173 0 : GetUnitString(nsAString& unit, PRUint16 unitType)
174 : {
175 0 : if (IsValidUnitType(unitType)) {
176 0 : if (unitMap[unitType]) {
177 0 : (*unitMap[unitType])->ToString(unit);
178 : }
179 0 : return;
180 : }
181 :
182 0 : NS_NOTREACHED("Unknown unit type");
183 0 : return;
184 : }
185 :
186 : static PRUint16
187 0 : GetUnitTypeForString(const char* unitStr)
188 : {
189 0 : if (!unitStr || *unitStr == '\0')
190 0 : return nsIDOMSVGAngle::SVG_ANGLETYPE_UNSPECIFIED;
191 :
192 0 : nsCOMPtr<nsIAtom> unitAtom = do_GetAtom(unitStr);
193 :
194 0 : for (PRUint32 i = 0 ; i < ArrayLength(unitMap) ; i++) {
195 0 : if (unitMap[i] && *unitMap[i] == unitAtom) {
196 0 : return i;
197 : }
198 : }
199 :
200 0 : return nsIDOMSVGAngle::SVG_ANGLETYPE_UNKNOWN;
201 : }
202 :
203 : static void
204 0 : GetValueString(nsAString &aValueAsString, float aValue, PRUint16 aUnitType)
205 : {
206 : PRUnichar buf[24];
207 : nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
208 0 : NS_LITERAL_STRING("%g").get(),
209 0 : (double)aValue);
210 0 : aValueAsString.Assign(buf);
211 :
212 0 : nsAutoString unitString;
213 0 : GetUnitString(unitString, aUnitType);
214 0 : aValueAsString.Append(unitString);
215 0 : }
216 :
217 : static nsresult
218 0 : GetValueFromString(const nsAString &aValueAsString,
219 : float *aValue,
220 : PRUint16 *aUnitType)
221 : {
222 0 : NS_ConvertUTF16toUTF8 value(aValueAsString);
223 0 : const char *str = value.get();
224 :
225 0 : if (NS_IsAsciiWhitespace(*str))
226 0 : return NS_ERROR_DOM_SYNTAX_ERR;
227 :
228 : char *rest;
229 0 : *aValue = float(PR_strtod(str, &rest));
230 0 : if (rest != str && NS_finite(*aValue)) {
231 0 : *aUnitType = GetUnitTypeForString(rest);
232 0 : if (IsValidUnitType(*aUnitType)) {
233 0 : return NS_OK;
234 : }
235 : }
236 :
237 0 : return NS_ERROR_DOM_SYNTAX_ERR;
238 : }
239 :
240 : /* static */ float
241 0 : nsSVGAngle::GetDegreesPerUnit(PRUint8 aUnit)
242 : {
243 0 : switch (aUnit) {
244 : case nsIDOMSVGAngle::SVG_ANGLETYPE_UNSPECIFIED:
245 : case nsIDOMSVGAngle::SVG_ANGLETYPE_DEG:
246 0 : return 1;
247 : case nsIDOMSVGAngle::SVG_ANGLETYPE_RAD:
248 0 : return static_cast<float>(180.0 / M_PI);
249 : case nsIDOMSVGAngle::SVG_ANGLETYPE_GRAD:
250 0 : return 90.0f / 100.0f;
251 : default:
252 0 : NS_NOTREACHED("Unknown unit type");
253 0 : return 0;
254 : }
255 : }
256 :
257 : void
258 0 : nsSVGAngle::SetBaseValueInSpecifiedUnits(float aValue,
259 : nsSVGElement *aSVGElement)
260 : {
261 0 : if (mBaseVal == aValue) {
262 0 : return;
263 : }
264 :
265 0 : nsAttrValue emptyOrOldValue = aSVGElement->WillChangeAngle(mAttrEnum);
266 0 : mBaseVal = aValue;
267 0 : if (!mIsAnimated) {
268 0 : mAnimVal = mBaseVal;
269 : }
270 : else {
271 0 : aSVGElement->AnimationNeedsResample();
272 : }
273 0 : aSVGElement->DidChangeAngle(mAttrEnum, emptyOrOldValue);
274 : }
275 :
276 : nsresult
277 0 : nsSVGAngle::ConvertToSpecifiedUnits(PRUint16 unitType,
278 : nsSVGElement *aSVGElement)
279 : {
280 0 : if (!IsValidUnitType(unitType))
281 0 : return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
282 :
283 0 : if (mBaseValUnit == PRUint8(unitType))
284 0 : return NS_OK;
285 :
286 0 : nsAttrValue emptyOrOldValue = aSVGElement->WillChangeAngle(mAttrEnum);
287 :
288 0 : float valueInUserUnits = mBaseVal * GetDegreesPerUnit(mBaseValUnit);
289 0 : mBaseValUnit = PRUint8(unitType);
290 : // Setting aDoSetAttr to false here will ensure we don't call
291 : // Will/DidChangeAngle a second time (and dispatch duplicate notifications).
292 0 : SetBaseValue(valueInUserUnits, aSVGElement, false);
293 :
294 0 : aSVGElement->DidChangeAngle(mAttrEnum, emptyOrOldValue);
295 :
296 0 : return NS_OK;
297 : }
298 :
299 : nsresult
300 0 : nsSVGAngle::NewValueSpecifiedUnits(PRUint16 unitType,
301 : float valueInSpecifiedUnits,
302 : nsSVGElement *aSVGElement)
303 : {
304 0 : NS_ENSURE_FINITE(valueInSpecifiedUnits, NS_ERROR_ILLEGAL_VALUE);
305 :
306 0 : if (!IsValidUnitType(unitType))
307 0 : return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
308 :
309 0 : if (mBaseVal == valueInSpecifiedUnits && mBaseValUnit == PRUint8(unitType))
310 0 : return NS_OK;
311 :
312 0 : nsAttrValue emptyOrOldValue;
313 0 : if (aSVGElement) {
314 0 : emptyOrOldValue = aSVGElement->WillChangeAngle(mAttrEnum);
315 : }
316 0 : mBaseVal = valueInSpecifiedUnits;
317 0 : mBaseValUnit = PRUint8(unitType);
318 0 : if (!mIsAnimated) {
319 0 : mAnimVal = mBaseVal;
320 0 : mAnimValUnit = mBaseValUnit;
321 : }
322 : else {
323 0 : aSVGElement->AnimationNeedsResample();
324 : }
325 0 : if (aSVGElement) {
326 0 : aSVGElement->DidChangeAngle(mAttrEnum, emptyOrOldValue);
327 : }
328 0 : return NS_OK;
329 : }
330 :
331 : nsresult
332 0 : nsSVGAngle::ToDOMBaseVal(nsIDOMSVGAngle **aResult, nsSVGElement *aSVGElement)
333 : {
334 0 : *aResult = new DOMBaseVal(this, aSVGElement);
335 0 : if (!*aResult)
336 0 : return NS_ERROR_OUT_OF_MEMORY;
337 :
338 0 : NS_ADDREF(*aResult);
339 0 : return NS_OK;
340 : }
341 :
342 : nsresult
343 0 : nsSVGAngle::ToDOMAnimVal(nsIDOMSVGAngle **aResult, nsSVGElement *aSVGElement)
344 : {
345 0 : *aResult = new DOMAnimVal(this, aSVGElement);
346 0 : if (!*aResult)
347 0 : return NS_ERROR_OUT_OF_MEMORY;
348 :
349 0 : NS_ADDREF(*aResult);
350 0 : return NS_OK;
351 : }
352 :
353 : /* Implementation */
354 :
355 : nsresult
356 0 : nsSVGAngle::SetBaseValueString(const nsAString &aValueAsString,
357 : nsSVGElement *aSVGElement,
358 : bool aDoSetAttr)
359 : {
360 0 : float value = 0;
361 0 : PRUint16 unitType = 0;
362 :
363 0 : nsresult rv = GetValueFromString(aValueAsString, &value, &unitType);
364 0 : if (NS_FAILED(rv)) {
365 0 : return rv;
366 : }
367 0 : if (mBaseVal == value && mBaseValUnit == PRUint8(unitType)) {
368 0 : return NS_OK;
369 : }
370 :
371 0 : nsAttrValue emptyOrOldValue;
372 0 : if (aDoSetAttr) {
373 0 : emptyOrOldValue = aSVGElement->WillChangeAngle(mAttrEnum);
374 : }
375 0 : mBaseVal = value;
376 0 : mBaseValUnit = PRUint8(unitType);
377 0 : if (!mIsAnimated) {
378 0 : mAnimVal = mBaseVal;
379 0 : mAnimValUnit = mBaseValUnit;
380 : }
381 : else {
382 0 : aSVGElement->AnimationNeedsResample();
383 : }
384 :
385 0 : if (aDoSetAttr) {
386 0 : aSVGElement->DidChangeAngle(mAttrEnum, emptyOrOldValue);
387 : }
388 0 : return NS_OK;
389 : }
390 :
391 : void
392 0 : nsSVGAngle::GetBaseValueString(nsAString & aValueAsString) const
393 : {
394 0 : GetValueString(aValueAsString, mBaseVal, mBaseValUnit);
395 0 : }
396 :
397 : void
398 0 : nsSVGAngle::GetAnimValueString(nsAString & aValueAsString) const
399 : {
400 0 : GetValueString(aValueAsString, mAnimVal, mAnimValUnit);
401 0 : }
402 :
403 : void
404 0 : nsSVGAngle::SetBaseValue(float aValue, nsSVGElement *aSVGElement,
405 : bool aDoSetAttr)
406 : {
407 0 : if (mBaseVal == aValue * GetDegreesPerUnit(mBaseValUnit)) {
408 0 : return;
409 : }
410 0 : nsAttrValue emptyOrOldValue;
411 0 : if (aSVGElement && aDoSetAttr) {
412 0 : emptyOrOldValue = aSVGElement->WillChangeAngle(mAttrEnum);
413 : }
414 :
415 0 : mBaseVal = aValue / GetDegreesPerUnit(mBaseValUnit);
416 0 : if (!mIsAnimated) {
417 0 : mAnimVal = mBaseVal;
418 : }
419 : else {
420 0 : aSVGElement->AnimationNeedsResample();
421 : }
422 0 : if (aSVGElement && aDoSetAttr) {
423 0 : aSVGElement->DidChangeAngle(mAttrEnum, emptyOrOldValue);
424 : }
425 : }
426 :
427 : void
428 0 : nsSVGAngle::SetAnimValue(float aValue, PRUint8 aUnit, nsSVGElement *aSVGElement)
429 : {
430 0 : mAnimVal = aValue;
431 0 : mAnimValUnit = aUnit;
432 0 : mIsAnimated = true;
433 0 : aSVGElement->DidAnimateAngle(mAttrEnum);
434 0 : }
435 :
436 : nsresult
437 0 : nsSVGAngle::ToDOMAnimatedAngle(nsIDOMSVGAnimatedAngle **aResult,
438 : nsSVGElement *aSVGElement)
439 : {
440 0 : *aResult = new DOMAnimatedAngle(this, aSVGElement);
441 0 : if (!*aResult)
442 0 : return NS_ERROR_OUT_OF_MEMORY;
443 :
444 0 : NS_ADDREF(*aResult);
445 0 : return NS_OK;
446 : }
447 :
448 : nsresult
449 0 : NS_NewDOMSVGAngle(nsIDOMSVGAngle** aResult)
450 : {
451 0 : *aResult = new DOMSVGAngle;
452 0 : if (!*aResult)
453 0 : return NS_ERROR_OUT_OF_MEMORY;
454 :
455 0 : NS_ADDREF(*aResult);
456 0 : return NS_OK;
457 : }
458 :
459 : nsISMILAttr*
460 0 : nsSVGAngle::ToSMILAttr(nsSVGElement *aSVGElement)
461 : {
462 0 : if (aSVGElement->NodeInfo()->Equals(nsGkAtoms::marker, kNameSpaceID_SVG)) {
463 0 : nsSVGMarkerElement *marker = static_cast<nsSVGMarkerElement*>(aSVGElement);
464 0 : return new SMILOrient(marker->GetOrientType(), this, aSVGElement);
465 : }
466 : // SMILOrient would not be useful for general angle attributes (also,
467 : // "orient" is the only animatable <angle>-valued attribute in SVG 1.1).
468 0 : NS_NOTREACHED("Trying to animate unknown angle attribute.");
469 0 : return nsnull;
470 : }
471 :
472 : nsresult
473 0 : nsSVGAngle::SMILOrient::ValueFromString(const nsAString& aStr,
474 : const nsISMILAnimationElement* /*aSrcElement*/,
475 : nsSMILValue& aValue,
476 : bool& aPreventCachingOfSandwich) const
477 : {
478 0 : nsSMILValue val(&SVGOrientSMILType::sSingleton);
479 0 : if (aStr.EqualsLiteral("auto")) {
480 0 : val.mU.mOrient.mOrientType = nsIDOMSVGMarkerElement::SVG_MARKER_ORIENT_AUTO;
481 : } else {
482 : float value;
483 : PRUint16 unitType;
484 0 : nsresult rv = GetValueFromString(aStr, &value, &unitType);
485 0 : if (NS_FAILED(rv)) {
486 0 : return rv;
487 : }
488 0 : val.mU.mOrient.mAngle = value;
489 0 : val.mU.mOrient.mUnit = unitType;
490 0 : val.mU.mOrient.mOrientType = nsIDOMSVGMarkerElement::SVG_MARKER_ORIENT_ANGLE;
491 : }
492 0 : aValue.Swap(val);
493 0 : aPreventCachingOfSandwich = false;
494 :
495 0 : return NS_OK;
496 : }
497 :
498 : nsSMILValue
499 0 : nsSVGAngle::SMILOrient::GetBaseValue() const
500 : {
501 0 : nsSMILValue val(&SVGOrientSMILType::sSingleton);
502 0 : val.mU.mOrient.mAngle = mAngle->GetBaseValInSpecifiedUnits();
503 0 : val.mU.mOrient.mUnit = mAngle->GetBaseValueUnit();
504 0 : val.mU.mOrient.mOrientType = mOrientType->GetBaseValue();
505 : return val;
506 : }
507 :
508 : void
509 0 : nsSVGAngle::SMILOrient::ClearAnimValue()
510 : {
511 0 : if (mAngle->mIsAnimated) {
512 0 : mOrientType->SetAnimValue(mOrientType->GetBaseValue());
513 0 : mAngle->mIsAnimated = false;
514 0 : mAngle->mAnimVal = mAngle->mBaseVal;
515 0 : mAngle->mAnimValUnit = mAngle->mBaseValUnit;
516 0 : mSVGElement->DidAnimateAngle(mAngle->mAttrEnum);
517 : }
518 0 : }
519 :
520 : nsresult
521 0 : nsSVGAngle::SMILOrient::SetAnimValue(const nsSMILValue& aValue)
522 : {
523 0 : NS_ASSERTION(aValue.mType == &SVGOrientSMILType::sSingleton,
524 : "Unexpected type to assign animated value");
525 :
526 0 : if (aValue.mType == &SVGOrientSMILType::sSingleton) {
527 0 : mOrientType->SetAnimValue(aValue.mU.mOrient.mOrientType);
528 0 : if (aValue.mU.mOrient.mOrientType == nsIDOMSVGMarkerElement::SVG_MARKER_ORIENT_AUTO) {
529 0 : mAngle->SetAnimValue(0.0f, nsIDOMSVGAngle::SVG_ANGLETYPE_UNSPECIFIED, mSVGElement);
530 : } else {
531 0 : mAngle->SetAnimValue(aValue.mU.mOrient.mAngle, aValue.mU.mOrient.mUnit, mSVGElement);
532 : }
533 : }
534 0 : return NS_OK;
535 4188 : }
|