Merge mozilla-central and tracemonkey. (a=blockers)
[mozilla-central.git] / layout / style / nsStyleAnimation.h
blob22e7f25a7bf63c7f07c2a454415c2ddceff7d3f7
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is nsStyleAnimation.
17 * The Initial Developer of the Original Code is
18 * The Mozilla Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 2009
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
23 * Daniel Holbert <dholbert@mozilla.com>, Mozilla Corporation
24 * L. David Baron <dbaron@dbaron.org>, Mozilla Corporation
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 /* Utilities for animation of computed style values */
42 #ifndef nsStyleAnimation_h_
43 #define nsStyleAnimation_h_
45 #include "prtypes.h"
46 #include "nsAString.h"
47 #include "nsCRTGlue.h"
48 #include "nsStringBuffer.h"
49 #include "nsCSSProperty.h"
50 #include "nsCoord.h"
51 #include "nsColor.h"
53 class nsIContent;
54 class nsPresContext;
55 class nsStyleContext;
56 class nsCSSValue;
57 struct nsCSSValueList;
58 struct nsCSSValuePair;
59 struct nsCSSValuePairList;
60 struct nsCSSRect;
62 /**
63 * Utility class to handle animated style values
65 class nsStyleAnimation {
66 public:
67 class Value;
69 // Mathematical methods
70 // --------------------
71 /**
72 * Adds |aCount| copies of |aValueToAdd| to |aDest|. The result of this
73 * addition is stored in aDest.
75 * Note that if |aCount| is 0, then |aDest| will be unchanged. Also, if
76 * this method fails, then |aDest| will be unchanged.
78 * @param aDest The value to add to.
79 * @param aValueToAdd The value to add.
80 * @param aCount The number of times to add aValueToAdd.
81 * @return PR_TRUE on success, PR_FALSE on failure.
83 static PRBool Add(nsCSSProperty aProperty, Value& aDest,
84 const Value& aValueToAdd, PRUint32 aCount) {
85 return AddWeighted(aProperty, 1.0, aDest, aCount, aValueToAdd, aDest);
88 /**
89 * Calculates a measure of 'distance' between two values.
91 * This measure of Distance is guaranteed to be proportional to
92 * portions passed to Interpolate, Add, or AddWeighted. However, for
93 * some types of Value it may not produce sensible results for paced
94 * animation.
96 * If this method succeeds, the returned distance value is guaranteed to be
97 * non-negative.
99 * @param aStartValue The start of the interval for which the distance
100 * should be calculated.
101 * @param aEndValue The end of the interval for which the distance
102 * should be calculated.
103 * @param aDistance The result of the calculation.
104 * @return PR_TRUE on success, PR_FALSE on failure.
106 static PRBool ComputeDistance(nsCSSProperty aProperty,
107 const Value& aStartValue,
108 const Value& aEndValue,
109 double& aDistance);
112 * Calculates an interpolated value that is the specified |aPortion| between
113 * the two given values.
115 * This really just does the following calculation:
116 * aResultValue = (1.0 - aPortion) * aStartValue + aPortion * aEndValue
118 * @param aStartValue The value defining the start of the interval of
119 * interpolation.
120 * @param aEndValue The value defining the end of the interval of
121 * interpolation.
122 * @param aPortion A number in the range [0.0, 1.0] defining the
123 * distance of the interpolated value in the interval.
124 * @param [out] aResultValue The resulting interpolated value.
125 * @return PR_TRUE on success, PR_FALSE on failure.
127 static PRBool Interpolate(nsCSSProperty aProperty,
128 const Value& aStartValue,
129 const Value& aEndValue,
130 double aPortion,
131 Value& aResultValue) {
132 return AddWeighted(aProperty, 1.0 - aPortion, aStartValue,
133 aPortion, aEndValue, aResultValue);
137 * Does the calculation:
138 * aResultValue = aCoeff1 * aValue1 + aCoeff2 * aValue2
140 * @param [out] aResultValue The resulting interpolated value. May be
141 * the same as aValue1 or aValue2.
142 * @return PR_TRUE on success, PR_FALSE on failure.
144 * NOTE: Current callers always pass aCoeff1 and aCoeff2 >= 0. They
145 * are currently permitted to be negative; however, if, as we add
146 * support more value types types, we find that this causes
147 * difficulty, we might change this to restrict them to being
148 * positive.
150 static PRBool AddWeighted(nsCSSProperty aProperty,
151 double aCoeff1, const Value& aValue1,
152 double aCoeff2, const Value& aValue2,
153 Value& aResultValue);
155 // Type-conversion methods
156 // -----------------------
158 * Creates a computed value for the given specified value
159 * (property ID + string). A style context is needed in case the
160 * specified value depends on inherited style or on the values of other
161 * properties.
163 * @param aProperty The property whose value we're computing.
164 * @param aTargetElement The content node to which our computed value is
165 * applicable.
166 * @param aSpecifiedValue The specified value, from which we'll build our
167 * computed value.
168 * @param aUseSVGMode A flag to indicate whether we should parse
169 * |aSpecifiedValue| in SVG mode.
170 * @param [out] aComputedValue The resulting computed value.
171 * @return PR_TRUE on success, PR_FALSE on failure.
173 static PRBool ComputeValue(nsCSSProperty aProperty,
174 nsIContent* aElement,
175 const nsAString& aSpecifiedValue,
176 PRBool aUseSVGMode,
177 Value& aComputedValue);
180 * Creates a specified value for the given computed value.
182 * The first overload fills in an nsCSSValue object; the second
183 * produces a string. The nsCSSValue result may depend on objects
184 * owned by the |aComputedValue| object, so users of that variant
185 * must keep |aComputedValue| alive longer than |aSpecifiedValue|.
187 * @param aProperty The property whose value we're uncomputing.
188 * @param aPresContext The presentation context for the document in
189 * which we're working.
190 * @param aComputedValue The computed value to be converted.
191 * @param [out] aSpecifiedValue The resulting specified value.
192 * @return PR_TRUE on success, PR_FALSE on failure.
194 static PRBool UncomputeValue(nsCSSProperty aProperty,
195 nsPresContext* aPresContext,
196 const Value& aComputedValue,
197 nsCSSValue& aSpecifiedValue);
198 static PRBool UncomputeValue(nsCSSProperty aProperty,
199 nsPresContext* aPresContext,
200 const Value& aComputedValue,
201 nsAString& aSpecifiedValue);
204 * Gets the computed value for the given property from the given style
205 * context.
207 * @param aProperty The property whose value we're looking up.
208 * @param aStyleContext The style context to check for the computed value.
209 * @param [out] aComputedValue The resulting computed value.
210 * @return PR_TRUE on success, PR_FALSE on failure.
212 static PRBool ExtractComputedValue(nsCSSProperty aProperty,
213 nsStyleContext* aStyleContext,
214 Value& aComputedValue);
217 * The types and values for the values that we extract and animate.
219 enum Unit {
220 eUnit_Null, // not initialized
221 eUnit_Normal,
222 eUnit_Auto,
223 eUnit_None,
224 eUnit_Enumerated,
225 eUnit_Visibility, // special case for transitions (which converts
226 // Enumerated to Visibility as needed)
227 eUnit_Integer,
228 eUnit_Coord,
229 eUnit_Percent,
230 eUnit_Float,
231 eUnit_Color,
232 eUnit_Calc, // nsCSSValue* (never null), always with a single
233 // calc() expression that's either length or length+percent
234 eUnit_CSSValuePair, // nsCSSValuePair* (never null)
235 eUnit_CSSRect, // nsCSSRect* (never null)
236 eUnit_Dasharray, // nsCSSValueList* (never null)
237 eUnit_Shadow, // nsCSSValueList* (may be null)
238 eUnit_Transform, // nsCSSValueList* (never null)
239 eUnit_CSSValuePairList, // nsCSSValuePairList* (never null)
240 eUnit_UnparsedString // nsStringBuffer* (never null)
243 class Value {
244 private:
245 Unit mUnit;
246 union {
247 PRInt32 mInt;
248 nscoord mCoord;
249 float mFloat;
250 nscolor mColor;
251 nsCSSValue* mCSSValue;
252 nsCSSValuePair* mCSSValuePair;
253 nsCSSRect* mCSSRect;
254 nsCSSValueList* mCSSValueList;
255 nsCSSValuePairList* mCSSValuePairList;
256 nsStringBuffer* mString;
257 } mValue;
258 public:
259 Unit GetUnit() const {
260 NS_ASSERTION(mUnit != eUnit_Null, "uninitialized");
261 return mUnit;
264 // Accessor to let us verify assumptions about presence of null unit,
265 // without tripping the assertion in GetUnit().
266 PRBool IsNull() const {
267 return mUnit == eUnit_Null;
270 PRInt32 GetIntValue() const {
271 NS_ASSERTION(IsIntUnit(mUnit), "unit mismatch");
272 return mValue.mInt;
274 nscoord GetCoordValue() const {
275 NS_ASSERTION(mUnit == eUnit_Coord, "unit mismatch");
276 return mValue.mCoord;
278 float GetPercentValue() const {
279 NS_ASSERTION(mUnit == eUnit_Percent, "unit mismatch");
280 return mValue.mFloat;
282 float GetFloatValue() const {
283 NS_ASSERTION(mUnit == eUnit_Float, "unit mismatch");
284 return mValue.mFloat;
286 nscolor GetColorValue() const {
287 NS_ASSERTION(mUnit == eUnit_Color, "unit mismatch");
288 return mValue.mColor;
290 nsCSSValue* GetCSSValueValue() const {
291 NS_ASSERTION(IsCSSValueUnit(mUnit), "unit mismatch");
292 return mValue.mCSSValue;
294 nsCSSValuePair* GetCSSValuePairValue() const {
295 NS_ASSERTION(IsCSSValuePairUnit(mUnit), "unit mismatch");
296 return mValue.mCSSValuePair;
298 nsCSSRect* GetCSSRectValue() const {
299 NS_ASSERTION(IsCSSRectUnit(mUnit), "unit mismatch");
300 return mValue.mCSSRect;
302 nsCSSValueList* GetCSSValueListValue() const {
303 NS_ASSERTION(IsCSSValueListUnit(mUnit), "unit mismatch");
304 return mValue.mCSSValueList;
306 nsCSSValuePairList* GetCSSValuePairListValue() const {
307 NS_ASSERTION(IsCSSValuePairListUnit(mUnit), "unit mismatch");
308 return mValue.mCSSValuePairList;
310 const PRUnichar* GetStringBufferValue() const {
311 NS_ASSERTION(IsStringUnit(mUnit), "unit mismatch");
312 return GetBufferValue(mValue.mString);
315 void GetStringValue(nsAString& aBuffer) const {
316 NS_ASSERTION(IsStringUnit(mUnit), "unit mismatch");
317 aBuffer.Truncate();
318 PRUint32 len = NS_strlen(GetBufferValue(mValue.mString));
319 mValue.mString->ToString(len, aBuffer);
322 explicit Value(Unit aUnit = eUnit_Null) : mUnit(aUnit) {
323 NS_ASSERTION(aUnit == eUnit_Null || aUnit == eUnit_Normal ||
324 aUnit == eUnit_Auto || aUnit == eUnit_None,
325 "must be valueless unit");
327 Value(const Value& aOther) : mUnit(eUnit_Null) { *this = aOther; }
328 enum IntegerConstructorType { IntegerConstructor };
329 Value(PRInt32 aInt, Unit aUnit, IntegerConstructorType);
330 enum CoordConstructorType { CoordConstructor };
331 Value(nscoord aLength, CoordConstructorType);
332 enum PercentConstructorType { PercentConstructor };
333 Value(float aPercent, PercentConstructorType);
334 enum FloatConstructorType { FloatConstructor };
335 Value(float aFloat, FloatConstructorType);
336 enum ColorConstructorType { ColorConstructor };
337 Value(nscolor aColor, ColorConstructorType);
339 ~Value() { FreeValue(); }
341 void SetNormalValue();
342 void SetAutoValue();
343 void SetNoneValue();
344 void SetIntValue(PRInt32 aInt, Unit aUnit);
345 void SetCoordValue(nscoord aCoord);
346 void SetPercentValue(float aPercent);
347 void SetFloatValue(float aFloat);
348 void SetColorValue(nscolor aColor);
349 void SetUnparsedStringValue(const nsString& aString);
351 // These setters take ownership of |aValue|, and are therefore named
352 // "SetAndAdopt*".
353 void SetAndAdoptCSSValueValue(nsCSSValue *aValue, Unit aUnit);
354 void SetAndAdoptCSSValuePairValue(nsCSSValuePair *aValue, Unit aUnit);
355 void SetAndAdoptCSSRectValue(nsCSSRect *aValue, Unit aUnit);
356 void SetAndAdoptCSSValueListValue(nsCSSValueList *aValue, Unit aUnit);
357 void SetAndAdoptCSSValuePairListValue(nsCSSValuePairList *aValue);
359 Value& operator=(const Value& aOther);
361 PRBool operator==(const Value& aOther) const;
362 PRBool operator!=(const Value& aOther) const
363 { return !(*this == aOther); }
365 private:
366 void FreeValue();
368 static const PRUnichar* GetBufferValue(nsStringBuffer* aBuffer) {
369 return static_cast<PRUnichar*>(aBuffer->Data());
372 static PRBool IsIntUnit(Unit aUnit) {
373 return aUnit == eUnit_Enumerated || aUnit == eUnit_Visibility ||
374 aUnit == eUnit_Integer;
376 static PRBool IsCSSValueUnit(Unit aUnit) {
377 return aUnit == eUnit_Calc;
379 static PRBool IsCSSValuePairUnit(Unit aUnit) {
380 return aUnit == eUnit_CSSValuePair;
382 static PRBool IsCSSRectUnit(Unit aUnit) {
383 return aUnit == eUnit_CSSRect;
385 static PRBool IsCSSValueListUnit(Unit aUnit) {
386 return aUnit == eUnit_Dasharray || aUnit == eUnit_Shadow ||
387 aUnit == eUnit_Transform;
389 static PRBool IsCSSValuePairListUnit(Unit aUnit) {
390 return aUnit == eUnit_CSSValuePairList;
392 static PRBool IsStringUnit(Unit aUnit) {
393 return aUnit == eUnit_UnparsedString;
398 #endif