/src/mozilla-central/dom/svg/SVGAnimatedPreserveAspectRatio.cpp
Line | Count | Source (jump to first uncovered line) |
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/ArrayUtils.h" |
8 | | |
9 | | #include "SVGAnimatedPreserveAspectRatio.h" |
10 | | #include "mozilla/dom/SVGAnimatedPreserveAspectRatioBinding.h" |
11 | | #include "nsSMILValue.h" |
12 | | #include "nsSVGAttrTearoffTable.h" |
13 | | #include "SMILEnumType.h" |
14 | | #include "SVGContentUtils.h" |
15 | | |
16 | | using namespace mozilla; |
17 | | using namespace mozilla::dom; |
18 | | |
19 | | //////////////////////////////////////////////////////////////////////// |
20 | | // SVGAnimatedPreserveAspectRatio class |
21 | | NS_SVG_VAL_IMPL_CYCLE_COLLECTION_WRAPPERCACHED(DOMSVGAnimatedPreserveAspectRatio, mSVGElement) |
22 | | |
23 | | NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMSVGAnimatedPreserveAspectRatio) |
24 | | NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMSVGAnimatedPreserveAspectRatio) |
25 | | |
26 | 0 | NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMSVGAnimatedPreserveAspectRatio) |
27 | 0 | NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY |
28 | 0 | NS_INTERFACE_MAP_ENTRY(nsISupports) |
29 | 0 | NS_INTERFACE_MAP_END |
30 | | |
31 | | JSObject* |
32 | | DOMSVGAnimatedPreserveAspectRatio::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) |
33 | 0 | { |
34 | 0 | return SVGAnimatedPreserveAspectRatio_Binding::Wrap(aCx, this, aGivenProto); |
35 | 0 | } |
36 | | |
37 | | /* Implementation */ |
38 | | |
39 | | static nsSVGAttrTearoffTable<SVGAnimatedPreserveAspectRatio, DOMSVGAnimatedPreserveAspectRatio> |
40 | | sSVGAnimatedPAspectRatioTearoffTable; |
41 | | static nsSVGAttrTearoffTable<SVGAnimatedPreserveAspectRatio, DOMSVGPreserveAspectRatio> |
42 | | sBaseSVGPAspectRatioTearoffTable; |
43 | | static nsSVGAttrTearoffTable<SVGAnimatedPreserveAspectRatio, DOMSVGPreserveAspectRatio> |
44 | | sAnimSVGPAspectRatioTearoffTable; |
45 | | |
46 | | already_AddRefed<DOMSVGPreserveAspectRatio> |
47 | | DOMSVGAnimatedPreserveAspectRatio::BaseVal() |
48 | 0 | { |
49 | 0 | RefPtr<DOMSVGPreserveAspectRatio> domBaseVal = |
50 | 0 | sBaseSVGPAspectRatioTearoffTable.GetTearoff(mVal); |
51 | 0 | if (!domBaseVal) { |
52 | 0 | domBaseVal = new DOMSVGPreserveAspectRatio(mVal, mSVGElement, true); |
53 | 0 | sBaseSVGPAspectRatioTearoffTable.AddTearoff(mVal, domBaseVal); |
54 | 0 | } |
55 | 0 |
|
56 | 0 | return domBaseVal.forget(); |
57 | 0 | } |
58 | | |
59 | | DOMSVGPreserveAspectRatio::~DOMSVGPreserveAspectRatio() |
60 | 0 | { |
61 | 0 | if (mIsBaseValue) { |
62 | 0 | sBaseSVGPAspectRatioTearoffTable.RemoveTearoff(mVal); |
63 | 0 | } else { |
64 | 0 | sAnimSVGPAspectRatioTearoffTable.RemoveTearoff(mVal); |
65 | 0 | } |
66 | 0 | } |
67 | | |
68 | | already_AddRefed<DOMSVGPreserveAspectRatio> |
69 | | DOMSVGAnimatedPreserveAspectRatio::AnimVal() |
70 | 0 | { |
71 | 0 | RefPtr<DOMSVGPreserveAspectRatio> domAnimVal = |
72 | 0 | sAnimSVGPAspectRatioTearoffTable.GetTearoff(mVal); |
73 | 0 | if (!domAnimVal) { |
74 | 0 | domAnimVal = new DOMSVGPreserveAspectRatio(mVal, mSVGElement, false); |
75 | 0 | sAnimSVGPAspectRatioTearoffTable.AddTearoff(mVal, domAnimVal); |
76 | 0 | } |
77 | 0 |
|
78 | 0 | return domAnimVal.forget(); |
79 | 0 | } |
80 | | |
81 | | nsresult |
82 | | SVGAnimatedPreserveAspectRatio::SetBaseValueString( |
83 | | const nsAString &aValueAsString, nsSVGElement *aSVGElement, bool aDoSetAttr) |
84 | 0 | { |
85 | 0 | SVGPreserveAspectRatio val; |
86 | 0 | nsresult res = SVGPreserveAspectRatio::FromString(aValueAsString, &val); |
87 | 0 | if (NS_FAILED(res)) { |
88 | 0 | return res; |
89 | 0 | } |
90 | 0 | |
91 | 0 | nsAttrValue emptyOrOldValue; |
92 | 0 | if (aDoSetAttr) { |
93 | 0 | emptyOrOldValue = aSVGElement->WillChangePreserveAspectRatio(); |
94 | 0 | } |
95 | 0 |
|
96 | 0 | mBaseVal = val; |
97 | 0 | mIsBaseSet = true; |
98 | 0 |
|
99 | 0 | if (!mIsAnimated) { |
100 | 0 | mAnimVal = mBaseVal; |
101 | 0 | } |
102 | 0 | if (aDoSetAttr) { |
103 | 0 | aSVGElement->DidChangePreserveAspectRatio(emptyOrOldValue); |
104 | 0 | } |
105 | 0 | if (mIsAnimated) { |
106 | 0 | aSVGElement->AnimationNeedsResample(); |
107 | 0 | } |
108 | 0 | return NS_OK; |
109 | 0 | } |
110 | | |
111 | | void |
112 | | SVGAnimatedPreserveAspectRatio::GetBaseValueString( |
113 | | nsAString& aValueAsString) const |
114 | 0 | { |
115 | 0 | mBaseVal.ToString(aValueAsString); |
116 | 0 | } |
117 | | |
118 | | void |
119 | | SVGAnimatedPreserveAspectRatio::SetBaseValue(const SVGPreserveAspectRatio &aValue, |
120 | | nsSVGElement *aSVGElement) |
121 | 0 | { |
122 | 0 | if (mIsBaseSet && mBaseVal == aValue) { |
123 | 0 | return; |
124 | 0 | } |
125 | 0 | |
126 | 0 | nsAttrValue emptyOrOldValue = aSVGElement->WillChangePreserveAspectRatio(); |
127 | 0 | mBaseVal = aValue; |
128 | 0 | mIsBaseSet = true; |
129 | 0 |
|
130 | 0 | if (!mIsAnimated) { |
131 | 0 | mAnimVal = mBaseVal; |
132 | 0 | } |
133 | 0 | aSVGElement->DidChangePreserveAspectRatio(emptyOrOldValue); |
134 | 0 | if (mIsAnimated) { |
135 | 0 | aSVGElement->AnimationNeedsResample(); |
136 | 0 | } |
137 | 0 | } |
138 | | |
139 | | static uint64_t |
140 | | PackPreserveAspectRatio(const SVGPreserveAspectRatio& par) |
141 | 0 | { |
142 | 0 | // All preserveAspectRatio values are enum values (do not interpolate), so we |
143 | 0 | // can safely collate them and treat them as a single enum as for SMIL. |
144 | 0 | uint64_t packed = 0; |
145 | 0 | packed |= uint64_t(par.GetAlign()) << 8; |
146 | 0 | packed |= uint64_t(par.GetMeetOrSlice()); |
147 | 0 | return packed; |
148 | 0 | } |
149 | | |
150 | | void |
151 | | SVGAnimatedPreserveAspectRatio::SetAnimValue(uint64_t aPackedValue, |
152 | | nsSVGElement *aSVGElement) |
153 | 0 | { |
154 | 0 | if (mIsAnimated && PackPreserveAspectRatio(mAnimVal) == aPackedValue) { |
155 | 0 | return; |
156 | 0 | } |
157 | 0 | mAnimVal.SetAlign(uint16_t((aPackedValue & 0xff00) >> 8)); |
158 | 0 | mAnimVal.SetMeetOrSlice(uint16_t(aPackedValue & 0xff)); |
159 | 0 | mIsAnimated = true; |
160 | 0 | aSVGElement->DidAnimatePreserveAspectRatio(); |
161 | 0 | } |
162 | | |
163 | | already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> |
164 | | SVGAnimatedPreserveAspectRatio::ToDOMAnimatedPreserveAspectRatio( |
165 | | nsSVGElement *aSVGElement) |
166 | 0 | { |
167 | 0 | RefPtr<DOMSVGAnimatedPreserveAspectRatio> domAnimatedPAspectRatio = |
168 | 0 | sSVGAnimatedPAspectRatioTearoffTable.GetTearoff(this); |
169 | 0 | if (!domAnimatedPAspectRatio) { |
170 | 0 | domAnimatedPAspectRatio = new DOMSVGAnimatedPreserveAspectRatio(this, aSVGElement); |
171 | 0 | sSVGAnimatedPAspectRatioTearoffTable.AddTearoff(this, domAnimatedPAspectRatio); |
172 | 0 | } |
173 | 0 | return domAnimatedPAspectRatio.forget(); |
174 | 0 | } |
175 | | |
176 | | DOMSVGAnimatedPreserveAspectRatio::~DOMSVGAnimatedPreserveAspectRatio() |
177 | 0 | { |
178 | 0 | sSVGAnimatedPAspectRatioTearoffTable.RemoveTearoff(mVal); |
179 | 0 | } |
180 | | |
181 | | UniquePtr<nsISMILAttr> |
182 | | SVGAnimatedPreserveAspectRatio::ToSMILAttr(nsSVGElement *aSVGElement) |
183 | 0 | { |
184 | 0 | return MakeUnique<SMILPreserveAspectRatio>(this, aSVGElement); |
185 | 0 | } |
186 | | |
187 | | // typedef for inner class, to make function signatures shorter below: |
188 | | typedef SVGAnimatedPreserveAspectRatio::SMILPreserveAspectRatio |
189 | | SMILPreserveAspectRatio; |
190 | | |
191 | | nsresult |
192 | | SMILPreserveAspectRatio::ValueFromString(const nsAString& aStr, |
193 | | const SVGAnimationElement* /*aSrcElement*/, |
194 | | nsSMILValue& aValue, |
195 | | bool& aPreventCachingOfSandwich) const |
196 | 0 | { |
197 | 0 | SVGPreserveAspectRatio par; |
198 | 0 | nsresult res = SVGPreserveAspectRatio::FromString(aStr, &par); |
199 | 0 | NS_ENSURE_SUCCESS(res, res); |
200 | 0 |
|
201 | 0 | nsSMILValue val(SMILEnumType::Singleton()); |
202 | 0 | val.mU.mUint = PackPreserveAspectRatio(par); |
203 | 0 | aValue = val; |
204 | 0 | aPreventCachingOfSandwich = false; |
205 | 0 | return NS_OK; |
206 | 0 | } |
207 | | |
208 | | nsSMILValue |
209 | | SMILPreserveAspectRatio::GetBaseValue() const |
210 | 0 | { |
211 | 0 | nsSMILValue val(SMILEnumType::Singleton()); |
212 | 0 | val.mU.mUint = PackPreserveAspectRatio(mVal->GetBaseValue()); |
213 | 0 | return val; |
214 | 0 | } |
215 | | |
216 | | void |
217 | | SMILPreserveAspectRatio::ClearAnimValue() |
218 | 0 | { |
219 | 0 | if (mVal->mIsAnimated) { |
220 | 0 | mVal->mIsAnimated = false; |
221 | 0 | mVal->mAnimVal = mVal->mBaseVal; |
222 | 0 | mSVGElement->DidAnimatePreserveAspectRatio(); |
223 | 0 | } |
224 | 0 | } |
225 | | |
226 | | nsresult |
227 | | SMILPreserveAspectRatio::SetAnimValue(const nsSMILValue& aValue) |
228 | 0 | { |
229 | 0 | NS_ASSERTION(aValue.mType == SMILEnumType::Singleton(), |
230 | 0 | "Unexpected type to assign animated value"); |
231 | 0 | if (aValue.mType == SMILEnumType::Singleton()) { |
232 | 0 | mVal->SetAnimValue(aValue.mU.mUint, mSVGElement); |
233 | 0 | } |
234 | 0 | return NS_OK; |
235 | 0 | } |