|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "SMILIntegerType.h" |
|
7 #include "nsSMILValue.h" |
|
8 #include "nsDebug.h" |
|
9 #include <math.h> |
|
10 |
|
11 namespace mozilla { |
|
12 |
|
13 void |
|
14 SMILIntegerType::Init(nsSMILValue& aValue) const |
|
15 { |
|
16 NS_ABORT_IF_FALSE(aValue.IsNull(), "Unexpected value type"); |
|
17 aValue.mU.mInt = 0; |
|
18 aValue.mType = this; |
|
19 } |
|
20 |
|
21 void |
|
22 SMILIntegerType::Destroy(nsSMILValue& aValue) const |
|
23 { |
|
24 NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value"); |
|
25 aValue.mU.mInt = 0; |
|
26 aValue.mType = nsSMILNullType::Singleton(); |
|
27 } |
|
28 |
|
29 nsresult |
|
30 SMILIntegerType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const |
|
31 { |
|
32 NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types"); |
|
33 NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value"); |
|
34 aDest.mU.mInt = aSrc.mU.mInt; |
|
35 return NS_OK; |
|
36 } |
|
37 |
|
38 bool |
|
39 SMILIntegerType::IsEqual(const nsSMILValue& aLeft, |
|
40 const nsSMILValue& aRight) const |
|
41 { |
|
42 NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types"); |
|
43 NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value"); |
|
44 |
|
45 return aLeft.mU.mInt == aRight.mU.mInt; |
|
46 } |
|
47 |
|
48 nsresult |
|
49 SMILIntegerType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd, |
|
50 uint32_t aCount) const |
|
51 { |
|
52 NS_PRECONDITION(aValueToAdd.mType == aDest.mType, |
|
53 "Trying to add invalid types"); |
|
54 NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type"); |
|
55 aDest.mU.mInt += aValueToAdd.mU.mInt * aCount; |
|
56 return NS_OK; |
|
57 } |
|
58 |
|
59 nsresult |
|
60 SMILIntegerType::ComputeDistance(const nsSMILValue& aFrom, |
|
61 const nsSMILValue& aTo, |
|
62 double& aDistance) const |
|
63 { |
|
64 NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types"); |
|
65 NS_PRECONDITION(aFrom.mType == this, "Unexpected source type"); |
|
66 aDistance = fabs(double(aTo.mU.mInt - aFrom.mU.mInt)); |
|
67 return NS_OK; |
|
68 } |
|
69 |
|
70 nsresult |
|
71 SMILIntegerType::Interpolate(const nsSMILValue& aStartVal, |
|
72 const nsSMILValue& aEndVal, |
|
73 double aUnitDistance, |
|
74 nsSMILValue& aResult) const |
|
75 { |
|
76 NS_PRECONDITION(aStartVal.mType == aEndVal.mType, |
|
77 "Trying to interpolate different types"); |
|
78 NS_PRECONDITION(aStartVal.mType == this, |
|
79 "Unexpected types for interpolation"); |
|
80 NS_PRECONDITION(aResult.mType == this, "Unexpected result type"); |
|
81 |
|
82 const double startVal = double(aStartVal.mU.mInt); |
|
83 const double endVal = double(aEndVal.mU.mInt); |
|
84 const double currentVal = startVal + (endVal - startVal) * aUnitDistance; |
|
85 |
|
86 // When currentVal is exactly midway between its two nearest integers, we |
|
87 // jump to the "next" integer to provide simple, easy to remember and |
|
88 // consistent behaviour (from the SMIL author's point of view). |
|
89 |
|
90 if (startVal < endVal) { |
|
91 aResult.mU.mInt = int64_t(floor(currentVal + 0.5)); // round mid up |
|
92 } else { |
|
93 aResult.mU.mInt = int64_t(ceil(currentVal - 0.5)); // round mid down |
|
94 } |
|
95 |
|
96 return NS_OK; |
|
97 } |
|
98 |
|
99 } // namespace mozilla |