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 : #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 0 : NS_SVG_VAL_IMPL_CYCLE_COLLECTION_WRAPPERCACHED(DOMSVGAnimatedPreserveAspectRatio, mSVGElement)
22 :
23 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMSVGAnimatedPreserveAspectRatio)
24 0 : 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 0 : DOMSVGAnimatedPreserveAspectRatio::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
33 : {
34 0 : return SVGAnimatedPreserveAspectRatioBinding::Wrap(aCx, this, aGivenProto);
35 : }
36 :
37 : /* Implementation */
38 :
39 : static nsSVGAttrTearoffTable<SVGAnimatedPreserveAspectRatio, DOMSVGAnimatedPreserveAspectRatio>
40 3 : sSVGAnimatedPAspectRatioTearoffTable;
41 : static nsSVGAttrTearoffTable<SVGAnimatedPreserveAspectRatio, DOMSVGPreserveAspectRatio>
42 3 : sBaseSVGPAspectRatioTearoffTable;
43 : static nsSVGAttrTearoffTable<SVGAnimatedPreserveAspectRatio, DOMSVGPreserveAspectRatio>
44 3 : sAnimSVGPAspectRatioTearoffTable;
45 :
46 : already_AddRefed<DOMSVGPreserveAspectRatio>
47 0 : DOMSVGAnimatedPreserveAspectRatio::BaseVal()
48 : {
49 : 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 : }
55 :
56 0 : return domBaseVal.forget();
57 : }
58 :
59 0 : DOMSVGPreserveAspectRatio::~DOMSVGPreserveAspectRatio()
60 : {
61 0 : if (mIsBaseValue) {
62 0 : sBaseSVGPAspectRatioTearoffTable.RemoveTearoff(mVal);
63 : } else {
64 0 : sAnimSVGPAspectRatioTearoffTable.RemoveTearoff(mVal);
65 : }
66 0 : }
67 :
68 : already_AddRefed<DOMSVGPreserveAspectRatio>
69 0 : DOMSVGAnimatedPreserveAspectRatio::AnimVal()
70 : {
71 : 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 : }
77 :
78 0 : return domAnimVal.forget();
79 : }
80 :
81 : nsresult
82 3 : SVGAnimatedPreserveAspectRatio::SetBaseValueString(
83 : const nsAString &aValueAsString, nsSVGElement *aSVGElement, bool aDoSetAttr)
84 : {
85 3 : SVGPreserveAspectRatio val;
86 3 : nsresult res = SVGPreserveAspectRatio::FromString(aValueAsString, &val);
87 3 : if (NS_FAILED(res)) {
88 0 : return res;
89 : }
90 :
91 6 : nsAttrValue emptyOrOldValue;
92 3 : if (aDoSetAttr) {
93 0 : emptyOrOldValue = aSVGElement->WillChangePreserveAspectRatio();
94 : }
95 :
96 3 : mBaseVal = val;
97 3 : mIsBaseSet = true;
98 :
99 3 : if (!mIsAnimated) {
100 3 : mAnimVal = mBaseVal;
101 : }
102 3 : if (aDoSetAttr) {
103 0 : aSVGElement->DidChangePreserveAspectRatio(emptyOrOldValue);
104 : }
105 3 : if (mIsAnimated) {
106 0 : aSVGElement->AnimationNeedsResample();
107 : }
108 3 : return NS_OK;
109 : }
110 :
111 : void
112 0 : SVGAnimatedPreserveAspectRatio::GetBaseValueString(
113 : nsAString& aValueAsString) const
114 : {
115 0 : mBaseVal.ToString(aValueAsString);
116 0 : }
117 :
118 : void
119 0 : SVGAnimatedPreserveAspectRatio::SetBaseValue(const SVGPreserveAspectRatio &aValue,
120 : nsSVGElement *aSVGElement)
121 : {
122 0 : if (mIsBaseSet && mBaseVal == aValue) {
123 0 : return;
124 : }
125 :
126 0 : nsAttrValue emptyOrOldValue = aSVGElement->WillChangePreserveAspectRatio();
127 0 : mBaseVal = aValue;
128 0 : mIsBaseSet = true;
129 :
130 0 : if (!mIsAnimated) {
131 0 : mAnimVal = mBaseVal;
132 : }
133 0 : aSVGElement->DidChangePreserveAspectRatio(emptyOrOldValue);
134 0 : if (mIsAnimated) {
135 0 : aSVGElement->AnimationNeedsResample();
136 : }
137 : }
138 :
139 : static uint64_t
140 0 : PackPreserveAspectRatio(const SVGPreserveAspectRatio& par)
141 : {
142 : // All preserveAspectRatio values are enum values (do not interpolate), so we
143 : // 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 : }
149 :
150 : void
151 0 : SVGAnimatedPreserveAspectRatio::SetAnimValue(uint64_t aPackedValue,
152 : nsSVGElement *aSVGElement)
153 : {
154 0 : if (mIsAnimated && PackPreserveAspectRatio(mAnimVal) == aPackedValue) {
155 0 : return;
156 : }
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 : }
162 :
163 : already_AddRefed<DOMSVGAnimatedPreserveAspectRatio>
164 0 : SVGAnimatedPreserveAspectRatio::ToDOMAnimatedPreserveAspectRatio(
165 : nsSVGElement *aSVGElement)
166 : {
167 : 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 : }
173 0 : return domAnimatedPAspectRatio.forget();
174 : }
175 :
176 0 : DOMSVGAnimatedPreserveAspectRatio::~DOMSVGAnimatedPreserveAspectRatio()
177 : {
178 0 : sSVGAnimatedPAspectRatioTearoffTable.RemoveTearoff(mVal);
179 0 : }
180 :
181 : UniquePtr<nsISMILAttr>
182 0 : SVGAnimatedPreserveAspectRatio::ToSMILAttr(nsSVGElement *aSVGElement)
183 : {
184 0 : return MakeUnique<SMILPreserveAspectRatio>(this, aSVGElement);
185 : }
186 :
187 : // typedef for inner class, to make function signatures shorter below:
188 : typedef SVGAnimatedPreserveAspectRatio::SMILPreserveAspectRatio
189 : SMILPreserveAspectRatio;
190 :
191 : nsresult
192 0 : SMILPreserveAspectRatio::ValueFromString(const nsAString& aStr,
193 : const SVGAnimationElement* /*aSrcElement*/,
194 : nsSMILValue& aValue,
195 : bool& aPreventCachingOfSandwich) const
196 : {
197 0 : SVGPreserveAspectRatio par;
198 0 : nsresult res = SVGPreserveAspectRatio::FromString(aStr, &par);
199 0 : NS_ENSURE_SUCCESS(res, res);
200 :
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 : }
207 :
208 : nsSMILValue
209 0 : SMILPreserveAspectRatio::GetBaseValue() const
210 : {
211 0 : nsSMILValue val(SMILEnumType::Singleton());
212 0 : val.mU.mUint = PackPreserveAspectRatio(mVal->GetBaseValue());
213 0 : return val;
214 : }
215 :
216 : void
217 0 : SMILPreserveAspectRatio::ClearAnimValue()
218 : {
219 0 : if (mVal->mIsAnimated) {
220 0 : mVal->mIsAnimated = false;
221 0 : mVal->mAnimVal = mVal->mBaseVal;
222 0 : mSVGElement->DidAnimatePreserveAspectRatio();
223 : }
224 0 : }
225 :
226 : nsresult
227 0 : SMILPreserveAspectRatio::SetAnimValue(const nsSMILValue& aValue)
228 : {
229 0 : NS_ASSERTION(aValue.mType == SMILEnumType::Singleton(),
230 : "Unexpected type to assign animated value");
231 0 : if (aValue.mType == SMILEnumType::Singleton()) {
232 0 : mVal->SetAnimValue(aValue.mU.mUint, mSVGElement);
233 : }
234 0 : return NS_OK;
235 : }
|