Bug 1941128 - Turn off network.dns.native_https_query on Mac again
[gecko.git] / dom / svg / SVGAnimatedPreserveAspectRatio.cpp
blob420bb614838ec8165e5d48e1db41847cae7c5e66
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/. */
7 #include "SVGAnimatedPreserveAspectRatio.h"
9 #include "mozAutoDocUpdate.h"
10 #include "mozilla/ArrayUtils.h"
11 #include "mozilla/Maybe.h"
12 #include "mozilla/SMILValue.h"
13 #include "mozilla/SVGContentUtils.h"
14 #include "mozilla/dom/SVGAnimatedPreserveAspectRatioBinding.h"
15 #include "SMILEnumType.h"
16 #include "SVGAttrTearoffTable.h"
18 using namespace mozilla::dom;
20 namespace mozilla {
22 ////////////////////////////////////////////////////////////////////////
23 // SVGAnimatedPreserveAspectRatio class
24 NS_SVG_VAL_IMPL_CYCLE_COLLECTION_WRAPPERCACHED(
25 DOMSVGAnimatedPreserveAspectRatio, mSVGElement)
27 JSObject* DOMSVGAnimatedPreserveAspectRatio::WrapObject(
28 JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
29 return SVGAnimatedPreserveAspectRatio_Binding::Wrap(aCx, this, aGivenProto);
32 /* Implementation */
34 //----------------------------------------------------------------------
35 // Helper class: AutoChangePreserveAspectRatioNotifier
36 // Stack-based helper class to pair calls to WillChangePreserveAspectRatio and
37 // DidChangePreserveAspectRatio.
38 class MOZ_RAII AutoChangePreserveAspectRatioNotifier {
39 public:
40 AutoChangePreserveAspectRatioNotifier(
41 SVGAnimatedPreserveAspectRatio* aPreserveAspectRatio,
42 SVGElement* aSVGElement, bool aDoSetAttr = true)
43 : mPreserveAspectRatio(aPreserveAspectRatio),
44 mSVGElement(aSVGElement),
45 mDoSetAttr(aDoSetAttr) {
46 MOZ_ASSERT(mPreserveAspectRatio, "Expecting non-null preserveAspectRatio");
47 MOZ_ASSERT(mSVGElement, "Expecting non-null element");
48 if (mDoSetAttr) {
49 mUpdateBatch.emplace(aSVGElement->GetComposedDoc(), true);
50 mEmptyOrOldValue =
51 mSVGElement->WillChangePreserveAspectRatio(mUpdateBatch.ref());
55 ~AutoChangePreserveAspectRatioNotifier() {
56 if (mDoSetAttr) {
57 mSVGElement->DidChangePreserveAspectRatio(mEmptyOrOldValue,
58 mUpdateBatch.ref());
60 if (mPreserveAspectRatio->mIsAnimated) {
61 mSVGElement->AnimationNeedsResample();
65 private:
66 SVGAnimatedPreserveAspectRatio* const mPreserveAspectRatio;
67 SVGElement* const mSVGElement;
68 Maybe<mozAutoDocUpdate> mUpdateBatch;
69 nsAttrValue mEmptyOrOldValue;
70 bool mDoSetAttr;
73 MOZ_CONSTINIT static SVGAttrTearoffTable<SVGAnimatedPreserveAspectRatio,
74 DOMSVGAnimatedPreserveAspectRatio>
75 sSVGAnimatedPAspectRatioTearoffTable;
76 MOZ_CONSTINIT static SVGAttrTearoffTable<SVGAnimatedPreserveAspectRatio,
77 DOMSVGPreserveAspectRatio>
78 sBaseSVGPAspectRatioTearoffTable;
79 MOZ_CONSTINIT static SVGAttrTearoffTable<SVGAnimatedPreserveAspectRatio,
80 DOMSVGPreserveAspectRatio>
81 sAnimSVGPAspectRatioTearoffTable;
83 already_AddRefed<DOMSVGPreserveAspectRatio>
84 DOMSVGAnimatedPreserveAspectRatio::BaseVal() {
85 RefPtr<DOMSVGPreserveAspectRatio> domBaseVal =
86 sBaseSVGPAspectRatioTearoffTable.GetTearoff(mVal);
87 if (!domBaseVal) {
88 domBaseVal = new DOMSVGPreserveAspectRatio(mVal, mSVGElement, true);
89 sBaseSVGPAspectRatioTearoffTable.AddTearoff(mVal, domBaseVal);
92 return domBaseVal.forget();
95 DOMSVGPreserveAspectRatio::~DOMSVGPreserveAspectRatio() {
96 if (mIsBaseValue) {
97 sBaseSVGPAspectRatioTearoffTable.RemoveTearoff(mVal);
98 } else {
99 sAnimSVGPAspectRatioTearoffTable.RemoveTearoff(mVal);
103 already_AddRefed<DOMSVGPreserveAspectRatio>
104 DOMSVGAnimatedPreserveAspectRatio::AnimVal() {
105 RefPtr<DOMSVGPreserveAspectRatio> domAnimVal =
106 sAnimSVGPAspectRatioTearoffTable.GetTearoff(mVal);
107 if (!domAnimVal) {
108 domAnimVal = new DOMSVGPreserveAspectRatio(mVal, mSVGElement, false);
109 sAnimSVGPAspectRatioTearoffTable.AddTearoff(mVal, domAnimVal);
112 return domAnimVal.forget();
115 nsresult SVGAnimatedPreserveAspectRatio::SetBaseValueString(
116 const nsAString& aValueAsString, SVGElement* aSVGElement, bool aDoSetAttr) {
117 SVGPreserveAspectRatio val;
118 nsresult res = SVGPreserveAspectRatio::FromString(aValueAsString, &val);
119 if (NS_FAILED(res)) {
120 return res;
123 AutoChangePreserveAspectRatioNotifier notifier(this, aSVGElement, aDoSetAttr);
125 mBaseVal = val;
126 mIsBaseSet = true;
127 if (!mIsAnimated) {
128 mAnimVal = mBaseVal;
131 return NS_OK;
134 void SVGAnimatedPreserveAspectRatio::GetBaseValueString(
135 nsAString& aValueAsString) const {
136 mBaseVal.ToString(aValueAsString);
139 void SVGAnimatedPreserveAspectRatio::SetBaseValue(
140 const SVGPreserveAspectRatio& aValue, SVGElement* aSVGElement) {
141 if (mIsBaseSet && mBaseVal == aValue) {
142 return;
145 AutoChangePreserveAspectRatioNotifier notifier(this, aSVGElement);
147 mBaseVal = aValue;
148 mIsBaseSet = true;
149 if (!mIsAnimated) {
150 mAnimVal = mBaseVal;
154 static uint64_t PackPreserveAspectRatio(const SVGPreserveAspectRatio& par) {
155 // All preserveAspectRatio values are enum values (do not interpolate), so we
156 // can safely collate them and treat them as a single enum as for SMIL.
157 uint64_t packed = 0;
158 packed |= uint64_t(par.GetAlign()) << 8;
159 packed |= uint64_t(par.GetMeetOrSlice());
160 return packed;
163 void SVGAnimatedPreserveAspectRatio::SetAnimValue(uint64_t aPackedValue,
164 SVGElement* aSVGElement) {
165 if (mIsAnimated && PackPreserveAspectRatio(mAnimVal) == aPackedValue) {
166 return;
168 mAnimVal.SetAlign(uint16_t((aPackedValue & 0xff00) >> 8));
169 mAnimVal.SetMeetOrSlice(uint16_t(aPackedValue & 0xff));
170 mIsAnimated = true;
171 aSVGElement->DidAnimatePreserveAspectRatio();
174 already_AddRefed<DOMSVGAnimatedPreserveAspectRatio>
175 SVGAnimatedPreserveAspectRatio::ToDOMAnimatedPreserveAspectRatio(
176 SVGElement* aSVGElement) {
177 RefPtr<DOMSVGAnimatedPreserveAspectRatio> domAnimatedPAspectRatio =
178 sSVGAnimatedPAspectRatioTearoffTable.GetTearoff(this);
179 if (!domAnimatedPAspectRatio) {
180 domAnimatedPAspectRatio =
181 new DOMSVGAnimatedPreserveAspectRatio(this, aSVGElement);
182 sSVGAnimatedPAspectRatioTearoffTable.AddTearoff(this,
183 domAnimatedPAspectRatio);
185 return domAnimatedPAspectRatio.forget();
188 DOMSVGAnimatedPreserveAspectRatio::~DOMSVGAnimatedPreserveAspectRatio() {
189 sSVGAnimatedPAspectRatioTearoffTable.RemoveTearoff(mVal);
192 UniquePtr<SMILAttr> SVGAnimatedPreserveAspectRatio::ToSMILAttr(
193 SVGElement* aSVGElement) {
194 return MakeUnique<SMILPreserveAspectRatio>(this, aSVGElement);
197 // typedef for inner class, to make function signatures shorter below:
198 using SMILPreserveAspectRatio =
199 SVGAnimatedPreserveAspectRatio::SMILPreserveAspectRatio;
201 nsresult SMILPreserveAspectRatio::ValueFromString(
202 const nsAString& aStr, const SVGAnimationElement* /*aSrcElement*/,
203 SMILValue& aValue, bool& aPreventCachingOfSandwich) const {
204 SVGPreserveAspectRatio par;
205 nsresult res = SVGPreserveAspectRatio::FromString(aStr, &par);
206 NS_ENSURE_SUCCESS(res, res);
208 SMILValue val(SMILEnumType::Singleton());
209 val.mU.mUint = PackPreserveAspectRatio(par);
210 aValue = val;
211 return NS_OK;
214 SMILValue SMILPreserveAspectRatio::GetBaseValue() const {
215 SMILValue val(SMILEnumType::Singleton());
216 val.mU.mUint = PackPreserveAspectRatio(mVal->GetBaseValue());
217 return val;
220 void SMILPreserveAspectRatio::ClearAnimValue() {
221 if (mVal->mIsAnimated) {
222 mVal->mIsAnimated = false;
223 mVal->mAnimVal = mVal->mBaseVal;
224 mSVGElement->DidAnimatePreserveAspectRatio();
228 nsresult SMILPreserveAspectRatio::SetAnimValue(const SMILValue& aValue) {
229 NS_ASSERTION(aValue.mType == SMILEnumType::Singleton(),
230 "Unexpected type to assign animated value");
231 if (aValue.mType == SMILEnumType::Singleton()) {
232 mVal->SetAnimValue(aValue.mU.mUint, mSVGElement);
234 return NS_OK;
237 } // namespace mozilla