Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/svg/nsSVGNumber2.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 "nsSVGNumber2.h"
8
#include "mozilla/Attributes.h"
9
#include "nsContentUtils.h" // NS_ENSURE_FINITE
10
#include "nsSMILFloatType.h"
11
#include "nsSMILValue.h"
12
#include "nsSVGAttrTearoffTable.h"
13
#include "SVGContentUtils.h"
14
15
using namespace mozilla;
16
using namespace mozilla::dom;
17
18
/* Implementation */
19
20
static nsSVGAttrTearoffTable<nsSVGNumber2, nsSVGNumber2::DOMAnimatedNumber>
21
  sSVGAnimatedNumberTearoffTable;
22
23
static bool
24
GetValueFromString(const nsAString& aString,
25
                   bool aPercentagesAllowed,
26
                   float& aValue)
27
0
{
28
0
  RangedPtr<const char16_t> iter =
29
0
    SVGContentUtils::GetStartRangedPtr(aString);
30
0
  const RangedPtr<const char16_t> end =
31
0
    SVGContentUtils::GetEndRangedPtr(aString);
32
0
33
0
  if (!SVGContentUtils::ParseNumber(iter, end, aValue)) {
34
0
    return false;
35
0
  }
36
0
37
0
  if (aPercentagesAllowed) {
38
0
    const nsAString& units = Substring(iter.get(), end.get());
39
0
    if (units.EqualsLiteral("%")) {
40
0
      aValue /= 100;
41
0
      return true;
42
0
    }
43
0
  }
44
0
45
0
  return iter == end;
46
0
}
47
48
nsresult
49
nsSVGNumber2::SetBaseValueString(const nsAString &aValueAsString,
50
                                 nsSVGElement *aSVGElement)
51
0
{
52
0
  float val;
53
0
54
0
  if (!GetValueFromString(aValueAsString,
55
0
                          aSVGElement->NumberAttrAllowsPercentage(mAttrEnum),
56
0
                          val)) {
57
0
    return NS_ERROR_DOM_SYNTAX_ERR;
58
0
  }
59
0
60
0
  mBaseVal = val;
61
0
  mIsBaseSet = true;
62
0
  if (!mIsAnimated) {
63
0
    mAnimVal = mBaseVal;
64
0
  }
65
0
  else {
66
0
    aSVGElement->AnimationNeedsResample();
67
0
  }
68
0
69
0
  // We don't need to call DidChange* here - we're only called by
70
0
  // nsSVGElement::ParseAttribute under Element::SetAttr,
71
0
  // which takes care of notifying.
72
0
  return NS_OK;
73
0
}
74
75
void
76
nsSVGNumber2::GetBaseValueString(nsAString & aValueAsString)
77
0
{
78
0
  aValueAsString.Truncate();
79
0
  aValueAsString.AppendFloat(mBaseVal);
80
0
}
81
82
void
83
nsSVGNumber2::SetBaseValue(float aValue, nsSVGElement *aSVGElement)
84
0
{
85
0
  if (mIsBaseSet && aValue == mBaseVal) {
86
0
    return;
87
0
  }
88
0
89
0
  mBaseVal = aValue;
90
0
  mIsBaseSet = true;
91
0
  if (!mIsAnimated) {
92
0
    mAnimVal = mBaseVal;
93
0
  }
94
0
  else {
95
0
    aSVGElement->AnimationNeedsResample();
96
0
  }
97
0
  aSVGElement->DidChangeNumber(mAttrEnum);
98
0
}
99
100
void
101
nsSVGNumber2::SetAnimValue(float aValue, nsSVGElement *aSVGElement)
102
0
{
103
0
  if (mIsAnimated && aValue == mAnimVal) {
104
0
    return;
105
0
  }
106
0
  mAnimVal = aValue;
107
0
  mIsAnimated = true;
108
0
  aSVGElement->DidAnimateNumber(mAttrEnum);
109
0
}
110
111
already_AddRefed<SVGAnimatedNumber>
112
nsSVGNumber2::ToDOMAnimatedNumber(nsSVGElement* aSVGElement)
113
0
{
114
0
  RefPtr<DOMAnimatedNumber> domAnimatedNumber =
115
0
    sSVGAnimatedNumberTearoffTable.GetTearoff(this);
116
0
  if (!domAnimatedNumber) {
117
0
    domAnimatedNumber = new DOMAnimatedNumber(this, aSVGElement);
118
0
    sSVGAnimatedNumberTearoffTable.AddTearoff(this, domAnimatedNumber);
119
0
  }
120
0
121
0
  return domAnimatedNumber.forget();
122
0
}
123
124
nsSVGNumber2::DOMAnimatedNumber::~DOMAnimatedNumber()
125
0
{
126
0
  sSVGAnimatedNumberTearoffTable.RemoveTearoff(mVal);
127
0
}
128
129
UniquePtr<nsISMILAttr>
130
nsSVGNumber2::ToSMILAttr(nsSVGElement *aSVGElement)
131
0
{
132
0
  return MakeUnique<SMILNumber>(this, aSVGElement);
133
0
}
134
135
nsresult
136
nsSVGNumber2::SMILNumber::ValueFromString(const nsAString& aStr,
137
                                          const mozilla::dom::SVGAnimationElement* /*aSrcElement*/,
138
                                          nsSMILValue& aValue,
139
                                          bool& aPreventCachingOfSandwich) const
140
0
{
141
0
  float value;
142
0
143
0
  if (!GetValueFromString(aStr,
144
0
                          mSVGElement->NumberAttrAllowsPercentage(mVal->mAttrEnum),
145
0
                          value)) {
146
0
    return NS_ERROR_DOM_SYNTAX_ERR;
147
0
  }
148
0
149
0
  nsSMILValue val(nsSMILFloatType::Singleton());
150
0
  val.mU.mDouble = value;
151
0
  aValue = val;
152
0
  aPreventCachingOfSandwich = false;
153
0
154
0
  return NS_OK;
155
0
}
156
157
nsSMILValue
158
nsSVGNumber2::SMILNumber::GetBaseValue() const
159
0
{
160
0
  nsSMILValue val(nsSMILFloatType::Singleton());
161
0
  val.mU.mDouble = mVal->mBaseVal;
162
0
  return val;
163
0
}
164
165
void
166
nsSVGNumber2::SMILNumber::ClearAnimValue()
167
0
{
168
0
  if (mVal->mIsAnimated) {
169
0
    mVal->mIsAnimated = false;
170
0
    mVal->mAnimVal = mVal->mBaseVal;
171
0
    mSVGElement->DidAnimateNumber(mVal->mAttrEnum);
172
0
  }
173
0
}
174
175
nsresult
176
nsSVGNumber2::SMILNumber::SetAnimValue(const nsSMILValue& aValue)
177
0
{
178
0
  NS_ASSERTION(aValue.mType == nsSMILFloatType::Singleton(),
179
0
               "Unexpected type to assign animated value");
180
0
  if (aValue.mType == nsSMILFloatType::Singleton()) {
181
0
    mVal->SetAnimValue(float(aValue.mU.mDouble), mSVGElement);
182
0
  }
183
0
  return NS_OK;
184
0
}