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
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.
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_
46 #include "nsAString.h"
47 #include "nsCRTGlue.h"
48 #include "nsStringBuffer.h"
49 #include "nsCSSProperty.h"
57 struct nsCSSValueList
;
58 struct nsCSSValuePair
;
59 struct nsCSSValuePairList
;
63 * Utility class to handle animated style values
65 class nsStyleAnimation
{
69 // Mathematical methods
70 // --------------------
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
);
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
96 * If this method succeeds, the returned distance value is guaranteed to be
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
,
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
120 * @param aEndValue The value defining the end of the interval of
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
,
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
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
163 * @param aProperty The property whose value we're computing.
164 * @param aTargetElement The content node to which our computed value is
166 * @param aSpecifiedValue The specified value, from which we'll build our
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
,
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
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.
220 eUnit_Null
, // not initialized
225 eUnit_Visibility
, // special case for transitions (which converts
226 // Enumerated to Visibility as needed)
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)
251 nsCSSValue
* mCSSValue
;
252 nsCSSValuePair
* mCSSValuePair
;
254 nsCSSValueList
* mCSSValueList
;
255 nsCSSValuePairList
* mCSSValuePairList
;
256 nsStringBuffer
* mString
;
259 Unit
GetUnit() const {
260 NS_ASSERTION(mUnit
!= eUnit_Null
, "uninitialized");
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");
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");
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();
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
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
); }
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
;