Line data Source code
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 : #ifndef MOZILLA_SVGANIMATEDTRANSFORMLIST_H__
8 : #define MOZILLA_SVGANIMATEDTRANSFORMLIST_H__
9 :
10 : #include "mozilla/Attributes.h"
11 : #include "mozilla/UniquePtr.h"
12 : #include "nsAutoPtr.h"
13 : #include "nsISMILAttr.h"
14 : #include "SVGTransformList.h"
15 :
16 : class nsIAtom;
17 : class nsSMILValue;
18 : class nsSVGElement;
19 :
20 : namespace mozilla {
21 :
22 : namespace dom {
23 : class SVGAnimationElement;
24 : class SVGTransform;
25 : } // namespace dom
26 :
27 : /**
28 : * Class nsSVGAnimatedTransformList
29 : *
30 : * This class is very different to the SVG DOM interface of the same name found
31 : * in the SVG specification. This is a lightweight internal class - see
32 : * SVGAnimatedTransformList for the heavier DOM class that wraps instances of
33 : * this class and implements the SVG specification's SVGAnimatedTransformList
34 : * DOM interface.
35 : *
36 : * Except where noted otherwise, this class' methods take care of keeping the
37 : * appropriate DOM wrappers in sync (see the comment in
38 : * SVGAnimatedTransformList::InternalBaseValListWillChangeTo) so that their
39 : * consumers don't need to concern themselves with that.
40 : */
41 0 : class nsSVGAnimatedTransformList
42 : {
43 : // friends so that they can get write access to mBaseVal
44 : friend class dom::SVGTransform;
45 : friend class DOMSVGTransformList;
46 :
47 : public:
48 7 : nsSVGAnimatedTransformList()
49 7 : : mIsAttrSet(false),
50 7 : mHadTransformBeforeLastBaseValChange(false) { }
51 :
52 : /**
53 : * Because it's so important that mBaseVal and its DOMSVGTransformList wrapper
54 : * (if any) be kept in sync (see the comment in
55 : * SVGAnimatedTransformList::InternalBaseValListWillChangeTo), this method
56 : * returns a const reference. Only our friend classes may get mutable
57 : * references to mBaseVal.
58 : */
59 7 : const SVGTransformList& GetBaseValue() const {
60 7 : return mBaseVal;
61 : }
62 :
63 : nsresult SetBaseValue(const SVGTransformList& aValue);
64 :
65 : nsresult SetBaseValueString(const nsAString& aValue);
66 :
67 : void ClearBaseValue();
68 :
69 42 : const SVGTransformList& GetAnimValue() const {
70 42 : return mAnimVal ? *mAnimVal : mBaseVal;
71 : }
72 :
73 : nsresult SetAnimValue(const SVGTransformList& aNewAnimValue,
74 : nsSVGElement *aElement);
75 :
76 : void ClearAnimValue(nsSVGElement *aElement);
77 :
78 : /**
79 : * Returns true if the corresponding transform attribute is set (or animated)
80 : * to a valid value. Unlike HasTransform it will return true for an empty
81 : * transform.
82 : */
83 : bool IsExplicitlySet() const;
84 :
85 : /**
86 : * Returns true if the corresponding transform attribute is set (or animated)
87 : * to a valid value, such that we have at least one transform in our list.
88 : * Returns false otherwise (e.g. if the transform attribute is missing or empty
89 : * or invalid).
90 : */
91 337 : bool HasTransform() const
92 337 : { return (mAnimVal && !mAnimVal->IsEmpty()) || !mBaseVal.IsEmpty(); }
93 :
94 0 : bool IsAnimating() const {
95 0 : return !!mAnimVal;
96 : }
97 :
98 : /**
99 : * Returns true iff "HasTransform" returned true just before our most recent
100 : * SetBaseValue/SetBaseValueString/ClearBaseValue change.
101 : *
102 : * (This is used as part of an optimization in
103 : * SVGTransformableElement::GetAttributeChangeHint. That function reports an
104 : * inexpensive nsChangeHint when a transform has just modified -- but this
105 : * accessor lets it detect cases where the "modification" is actually adding
106 : * a transform where we previously had none. These cases require a more
107 : * thorough nsChangeHint.)
108 : */
109 0 : bool HadTransformBeforeLastBaseValChange() const {
110 0 : return mHadTransformBeforeLastBaseValChange;
111 : }
112 :
113 : mozilla::UniquePtr<nsISMILAttr> ToSMILAttr(nsSVGElement* aSVGElement);
114 :
115 : private:
116 :
117 : // mAnimVal is a pointer to allow us to determine if we're being animated or
118 : // not. Making it a non-pointer member and using mAnimVal.IsEmpty() to check
119 : // if we're animating is not an option, since that would break animation *to*
120 : // the empty string (<set to="">).
121 :
122 : SVGTransformList mBaseVal;
123 : nsAutoPtr<SVGTransformList> mAnimVal;
124 : bool mIsAttrSet;
125 : // (See documentation for accessor, HadTransformBeforeLastBaseValChange.)
126 : bool mHadTransformBeforeLastBaseValChange;
127 :
128 0 : struct SMILAnimatedTransformList : public nsISMILAttr
129 : {
130 : public:
131 0 : SMILAnimatedTransformList(nsSVGAnimatedTransformList* aVal,
132 : nsSVGElement* aSVGElement)
133 0 : : mVal(aVal)
134 0 : , mElement(aSVGElement)
135 0 : {}
136 :
137 : // nsISMILAttr methods
138 : virtual nsresult ValueFromString(const nsAString& aStr,
139 : const dom::SVGAnimationElement* aSrcElement,
140 : nsSMILValue& aValue,
141 : bool& aPreventCachingOfSandwich) const override;
142 : virtual nsSMILValue GetBaseValue() const override;
143 : virtual void ClearAnimValue() override;
144 : virtual nsresult SetAnimValue(const nsSMILValue& aValue) override;
145 :
146 : protected:
147 : static void ParseValue(const nsAString& aSpec,
148 : const nsIAtom* aTransformType,
149 : nsSMILValue& aResult);
150 : static int32_t ParseParameterList(const nsAString& aSpec, float* aVars,
151 : int32_t aNVars);
152 :
153 : // These will stay alive because a nsISMILAttr only lives as long
154 : // as the Compositing step, and DOM elements don't get a chance to
155 : // die during that.
156 : nsSVGAnimatedTransformList* mVal;
157 : nsSVGElement* mElement;
158 : };
159 : };
160 :
161 : } // namespace mozilla
162 :
163 : #endif // MOZILLA_SVGANIMATEDTRANSFORMLIST_H__
|