Coverage Report

Created: 2018-09-25 14:53

/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
}