|
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 #ifndef NS_ISMILTYPE_H_ |
|
7 #define NS_ISMILTYPE_H_ |
|
8 |
|
9 #include "mozilla/Attributes.h" |
|
10 #include "nscore.h" |
|
11 |
|
12 class nsSMILValue; |
|
13 |
|
14 ////////////////////////////////////////////////////////////////////////////// |
|
15 // nsISMILType: Interface for defining the basic operations needed for animating |
|
16 // a particular kind of data (e.g. lengths, colors, transformation matrices). |
|
17 // |
|
18 // This interface is never used directly but always through an nsSMILValue that |
|
19 // bundles together a pointer to a concrete implementation of this interface and |
|
20 // the data upon which it should operate. |
|
21 // |
|
22 // We keep the data and type separate rather than just providing different |
|
23 // subclasses of nsSMILValue. This is so that sizeof(nsSMILValue) is the same |
|
24 // for all value types, allowing us to have a type-agnostic nsTArray of |
|
25 // nsSMILValue objects (actual objects, not pointers). It also allows most |
|
26 // nsSMILValues (except those that need to allocate extra memory for their |
|
27 // data) to be allocated on the stack and directly assigned to one another |
|
28 // provided performance benefits for the animation code. |
|
29 // |
|
30 // Note that different types have different capabilities. Roughly speaking there |
|
31 // are probably three main types: |
|
32 // |
|
33 // +---------------------+---------------+-------------+------------------+ |
|
34 // | CATEGORY: | DISCRETE | LINEAR | ADDITIVE | |
|
35 // +---------------------+---------------+-------------+------------------+ |
|
36 // | Example: | strings, | path data? | lengths, | |
|
37 // | | color k/words?| | RGB color values | |
|
38 // | | | | | |
|
39 // | -- Assign? | X | X | X | |
|
40 // | -- Add? | - | X? | X | |
|
41 // | -- SandwichAdd? | - | -? | X | |
|
42 // | -- ComputeDistance? | - | - | X? | |
|
43 // | -- Interpolate? | - | X | X | |
|
44 // +---------------------+---------------+-------------+------------------+ |
|
45 // |
|
46 |
|
47 class nsISMILType |
|
48 { |
|
49 /** |
|
50 * Only give the nsSMILValue class access to this interface. |
|
51 */ |
|
52 friend class nsSMILValue; |
|
53 |
|
54 protected: |
|
55 /** |
|
56 * Initialises aValue and sets it to some identity value such that adding |
|
57 * aValue to another value of the same type has no effect. |
|
58 * |
|
59 * @pre aValue.IsNull() |
|
60 * @post aValue.mType == this |
|
61 */ |
|
62 virtual void Init(nsSMILValue& aValue) const = 0; |
|
63 |
|
64 /** |
|
65 * Destroys any data associated with a value of this type. |
|
66 * |
|
67 * @pre aValue.mType == this |
|
68 * @post aValue.IsNull() |
|
69 */ |
|
70 virtual void Destroy(nsSMILValue& aValue) const = 0; |
|
71 |
|
72 /** |
|
73 * Assign this object the value of another. Think of this as the assignment |
|
74 * operator. |
|
75 * |
|
76 * @param aDest The left-hand side of the assignment. |
|
77 * @param aSrc The right-hand side of the assignment. |
|
78 * @return NS_OK on success, an error code on failure such as when the |
|
79 * underlying type of the specified object differs. |
|
80 * |
|
81 * @pre aDest.mType == aSrc.mType == this |
|
82 */ |
|
83 virtual nsresult Assign(nsSMILValue& aDest, |
|
84 const nsSMILValue& aSrc) const = 0; |
|
85 |
|
86 /** |
|
87 * Test two nsSMILValue objects (of this nsISMILType) for equality. |
|
88 * |
|
89 * A return value of true represents a guarantee that aLeft and aRight are |
|
90 * equal. (That is, they would behave identically if passed to the methods |
|
91 * Add, SandwichAdd, ComputeDistance, and Interpolate). |
|
92 * |
|
93 * A return value of false simply indicates that we make no guarantee |
|
94 * about equality. |
|
95 * |
|
96 * NOTE: It's perfectly legal for implementations of this method to return |
|
97 * false in all cases. However, smarter implementations will make this |
|
98 * method more useful for optimization. |
|
99 * |
|
100 * @param aLeft The left-hand side of the equality check. |
|
101 * @param aRight The right-hand side of the equality check. |
|
102 * @return true if we're sure the values are equal, false otherwise. |
|
103 * |
|
104 * @pre aDest.mType == aSrc.mType == this |
|
105 */ |
|
106 virtual bool IsEqual(const nsSMILValue& aLeft, |
|
107 const nsSMILValue& aRight) const = 0; |
|
108 |
|
109 /** |
|
110 * Adds two values. |
|
111 * |
|
112 * The count parameter facilitates repetition. |
|
113 * |
|
114 * By equation, |
|
115 * |
|
116 * aDest += aValueToAdd * aCount |
|
117 * |
|
118 * Therefore, if aCount == 0, aDest will be unaltered. |
|
119 * |
|
120 * This method will fail if this data type is not additive or the value was |
|
121 * not specified using an additive syntax. |
|
122 * |
|
123 * See SVG 1.1, section 19.2.5. In particular, |
|
124 * |
|
125 * "If a given attribute or property can take values of keywords (which are |
|
126 * not additive) or numeric values (which are additive), then additive |
|
127 * animations are possible if the subsequent animation uses a numeric value |
|
128 * even if the base animation uses a keyword value; however, if the |
|
129 * subsequent animation uses a keyword value, additive animation is not |
|
130 * possible." |
|
131 * |
|
132 * If this method fails (e.g. because the data type is not additive), aDest |
|
133 * will be unaltered. |
|
134 * |
|
135 * @param aDest The value to add to. |
|
136 * @param aValueToAdd The value to add. |
|
137 * @param aCount The number of times to add aValueToAdd. |
|
138 * @return NS_OK on success, an error code on failure. |
|
139 * |
|
140 * @pre aValueToAdd.mType == aDest.mType == this |
|
141 */ |
|
142 virtual nsresult Add(nsSMILValue& aDest, |
|
143 const nsSMILValue& aValueToAdd, |
|
144 uint32_t aCount) const = 0; |
|
145 |
|
146 /** |
|
147 * Adds aValueToAdd to the underlying value in the animation sandwich, aDest. |
|
148 * |
|
149 * For most types this operation is identical to a regular Add() but for some |
|
150 * types (notably <animateTransform>) the operation differs. For |
|
151 * <animateTransform> Add() corresponds to simply adding together the |
|
152 * transform parameters and is used when calculating cumulative values or |
|
153 * by-animation values. On the other hand SandwichAdd() is used when adding to |
|
154 * the underlying value and requires matrix post-multiplication. (This |
|
155 * distinction is most clearly indicated by the SVGT1.2 test suite. It is not |
|
156 * obvious within the SMIL specifications.) |
|
157 * |
|
158 * @param aDest The value to add to. |
|
159 * @param aValueToAdd The value to add. |
|
160 * @return NS_OK on success, an error code on failure. |
|
161 * |
|
162 * @pre aValueToAdd.mType == aDest.mType == this |
|
163 */ |
|
164 virtual nsresult SandwichAdd(nsSMILValue& aDest, |
|
165 const nsSMILValue& aValueToAdd) const |
|
166 { |
|
167 return Add(aDest, aValueToAdd, 1); |
|
168 } |
|
169 |
|
170 /** |
|
171 * Calculates the 'distance' between two values. This is the distance used in |
|
172 * paced interpolation. |
|
173 * |
|
174 * @param aFrom The start of the interval for which the distance should |
|
175 * be calculated. |
|
176 * @param aTo The end of the interval for which the distance should be |
|
177 * calculated. |
|
178 * @param aDistance The result of the calculation. |
|
179 * @return NS_OK on success, or an appropriate error code if there is no |
|
180 * notion of distance for the underlying data type or the distance |
|
181 * could not be calculated. |
|
182 * |
|
183 * @pre aFrom.mType == aTo.mType == this |
|
184 */ |
|
185 virtual nsresult ComputeDistance(const nsSMILValue& aFrom, |
|
186 const nsSMILValue& aTo, |
|
187 double& aDistance) const = 0; |
|
188 |
|
189 /** |
|
190 * Calculates an interpolated value between two values using the specified |
|
191 * proportion. |
|
192 * |
|
193 * @param aStartVal The value defining the start of the interval of |
|
194 * interpolation. |
|
195 * @param aEndVal The value defining the end of the interval of |
|
196 * interpolation. |
|
197 * @param aUnitDistance A number between 0.0 and 1.0 (inclusive) defining |
|
198 * the distance of the interpolated value in the |
|
199 * interval. |
|
200 * @param aResult The interpolated value. |
|
201 * @return NS_OK on success, NS_ERROR_FAILURE if this data type cannot be |
|
202 * interpolated or NS_ERROR_OUT_OF_MEMORY if insufficient memory was |
|
203 * available for storing the result. |
|
204 * |
|
205 * @pre aStartVal.mType == aEndVal.mType == aResult.mType == this |
|
206 */ |
|
207 virtual nsresult Interpolate(const nsSMILValue& aStartVal, |
|
208 const nsSMILValue& aEndVal, |
|
209 double aUnitDistance, |
|
210 nsSMILValue& aResult) const = 0; |
|
211 }; |
|
212 |
|
213 #endif // NS_ISMILTYPE_H_ |