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/. */
6 /* Utilities for animation of computed style values */
8 #ifndef mozilla_StyleAnimationValue_h_
9 #define mozilla_StyleAnimationValue_h_
11 #include "nsStringFwd.h"
12 #include "nsStringBuffer.h"
13 #include "nsCSSProperty.h"
16 #include "nsCSSValue.h"
28 * Utility class to handle animated style values
30 class StyleAnimationValue
{
32 // Mathematical methods
33 // --------------------
35 * Adds |aCount| copies of |aValueToAdd| to |aDest|. The result of this
36 * addition is stored in aDest.
38 * Note that if |aCount| is 0, then |aDest| will be unchanged. Also, if
39 * this method fails, then |aDest| will be unchanged.
41 * @param aDest The value to add to.
42 * @param aValueToAdd The value to add.
43 * @param aCount The number of times to add aValueToAdd.
44 * @return true on success, false on failure.
46 static bool Add(nsCSSProperty aProperty
, StyleAnimationValue
& aDest
,
47 const StyleAnimationValue
& aValueToAdd
, uint32_t aCount
) {
48 return AddWeighted(aProperty
, 1.0, aDest
, aCount
, aValueToAdd
, aDest
);
52 * Calculates a measure of 'distance' between two values.
54 * This measure of Distance is guaranteed to be proportional to
55 * portions passed to Interpolate, Add, or AddWeighted. However, for
56 * some types of StyleAnimationValue it may not produce sensible results
57 * for paced animation.
59 * If this method succeeds, the returned distance value is guaranteed to be
62 * @param aStartValue The start of the interval for which the distance
63 * should be calculated.
64 * @param aEndValue The end of the interval for which the distance
65 * should be calculated.
66 * @param aDistance The result of the calculation.
67 * @return true on success, false on failure.
69 static bool ComputeDistance(nsCSSProperty aProperty
,
70 const StyleAnimationValue
& aStartValue
,
71 const StyleAnimationValue
& aEndValue
,
75 * Calculates an interpolated value that is the specified |aPortion| between
76 * the two given values.
78 * This really just does the following calculation:
79 * aResultValue = (1.0 - aPortion) * aStartValue + aPortion * aEndValue
81 * @param aStartValue The value defining the start of the interval of
83 * @param aEndValue The value defining the end of the interval of
85 * @param aPortion A number in the range [0.0, 1.0] defining the
86 * distance of the interpolated value in the interval.
87 * @param [out] aResultValue The resulting interpolated value.
88 * @return true on success, false on failure.
90 static bool Interpolate(nsCSSProperty aProperty
,
91 const StyleAnimationValue
& aStartValue
,
92 const StyleAnimationValue
& aEndValue
,
94 StyleAnimationValue
& aResultValue
) {
95 return AddWeighted(aProperty
, 1.0 - aPortion
, aStartValue
,
96 aPortion
, aEndValue
, aResultValue
);
100 * Does the calculation:
101 * aResultValue = aCoeff1 * aValue1 + aCoeff2 * aValue2
103 * @param [out] aResultValue The resulting interpolated value. May be
104 * the same as aValue1 or aValue2.
105 * @return true on success, false on failure.
107 * NOTE: Current callers always pass aCoeff1 and aCoeff2 >= 0. They
108 * are currently permitted to be negative; however, if, as we add
109 * support more value types types, we find that this causes
110 * difficulty, we might change this to restrict them to being
113 static bool AddWeighted(nsCSSProperty aProperty
,
114 double aCoeff1
, const StyleAnimationValue
& aValue1
,
115 double aCoeff2
, const StyleAnimationValue
& aValue2
,
116 StyleAnimationValue
& aResultValue
);
118 // Type-conversion methods
119 // -----------------------
121 * Creates a computed value for the given specified value
122 * (property ID + string). A style context is needed in case the
123 * specified value depends on inherited style or on the values of other
126 * @param aProperty The property whose value we're computing.
127 * @param aTargetElement The content node to which our computed value is
129 * @param aSpecifiedValue The specified value, from which we'll build our
131 * @param aUseSVGMode A flag to indicate whether we should parse
132 * |aSpecifiedValue| in SVG mode.
133 * @param [out] aComputedValue The resulting computed value.
134 * @param [out] aIsContextSensitive
135 * Set to true if |aSpecifiedValue| may produce
136 * a different |aComputedValue| depending on other CSS
137 * properties on |aTargetElement| or its ancestors.
139 * Note that the operation of this method is
140 * significantly faster when |aIsContextSensitive| is
142 * @return true on success, false on failure.
144 static bool ComputeValue(nsCSSProperty aProperty
,
145 mozilla::dom::Element
* aTargetElement
,
146 const nsAString
& aSpecifiedValue
,
148 StyleAnimationValue
& aComputedValue
,
149 bool* aIsContextSensitive
= nullptr);
152 * Creates a specified value for the given computed value.
154 * The first overload fills in an nsCSSValue object; the second
155 * produces a string. The nsCSSValue result may depend on objects
156 * owned by the |aComputedValue| object, so users of that variant
157 * must keep |aComputedValue| alive longer than |aSpecifiedValue|.
159 * @param aProperty The property whose value we're uncomputing.
160 * @param aComputedValue The computed value to be converted.
161 * @param [out] aSpecifiedValue The resulting specified value.
162 * @return true on success, false on failure.
164 static bool UncomputeValue(nsCSSProperty aProperty
,
165 const StyleAnimationValue
& aComputedValue
,
166 nsCSSValue
& aSpecifiedValue
);
167 static bool UncomputeValue(nsCSSProperty aProperty
,
168 const StyleAnimationValue
& aComputedValue
,
169 nsAString
& aSpecifiedValue
);
172 * Gets the computed value for the given property from the given style
175 * @param aProperty The property whose value we're looking up.
176 * @param aStyleContext The style context to check for the computed value.
177 * @param [out] aComputedValue The resulting computed value.
178 * @return true on success, false on failure.
180 static bool ExtractComputedValue(nsCSSProperty aProperty
,
181 nsStyleContext
* aStyleContext
,
182 StyleAnimationValue
& aComputedValue
);
185 * Interpolates between 2 matrices by decomposing them.
187 * @param aMatrix1 First matrix, using CSS pixel units.
188 * @param aMatrix2 Second matrix, using CSS pixel units.
189 * @param aProgress Interpolation value in the range [0.0, 1.0]
191 static gfx3DMatrix
InterpolateTransformMatrix(const gfx3DMatrix
&aMatrix1
,
192 const gfx3DMatrix
&aMatrix2
,
195 static already_AddRefed
<nsCSSValue::Array
>
196 AppendTransformFunction(nsCSSKeyword aTransformFunction
,
197 nsCSSValueList
**& aListTail
);
200 * The types and values for the values that we extract and animate.
203 eUnit_Null
, // not initialized
208 eUnit_Visibility
, // special case for transitions (which converts
209 // Enumerated to Visibility as needed)
215 eUnit_Calc
, // nsCSSValue* (never null), always with a single
216 // calc() expression that's either length or length+percent
217 eUnit_CSSValuePair
, // nsCSSValuePair* (never null)
218 eUnit_CSSValueTriplet
, // nsCSSValueTriplet* (never null)
219 eUnit_CSSRect
, // nsCSSRect* (never null)
220 eUnit_Dasharray
, // nsCSSValueList* (never null)
221 eUnit_Filter
, // nsCSSValueList* (may be null)
222 eUnit_Shadow
, // nsCSSValueList* (may be null)
223 eUnit_Transform
, // nsCSSValueList* (never null)
224 eUnit_BackgroundPosition
, // nsCSSValueList* (never null)
225 eUnit_CSSValuePairList
, // nsCSSValuePairList* (never null)
226 eUnit_UnparsedString
// nsStringBuffer* (never null)
236 nsCSSValue
* mCSSValue
;
237 nsCSSValuePair
* mCSSValuePair
;
238 nsCSSValueTriplet
* mCSSValueTriplet
;
240 nsCSSValueList
* mCSSValueList
;
241 nsCSSValueSharedList
* mCSSValueSharedList
;
242 nsCSSValuePairList
* mCSSValuePairList
;
243 nsStringBuffer
* mString
;
247 Unit
GetUnit() const {
248 NS_ASSERTION(mUnit
!= eUnit_Null
, "uninitialized");
252 // Accessor to let us verify assumptions about presence of null unit,
253 // without tripping the assertion in GetUnit().
254 bool IsNull() const {
255 return mUnit
== eUnit_Null
;
258 int32_t GetIntValue() const {
259 NS_ASSERTION(IsIntUnit(mUnit
), "unit mismatch");
262 nscoord
GetCoordValue() const {
263 NS_ASSERTION(mUnit
== eUnit_Coord
, "unit mismatch");
264 return mValue
.mCoord
;
266 float GetPercentValue() const {
267 NS_ASSERTION(mUnit
== eUnit_Percent
, "unit mismatch");
268 return mValue
.mFloat
;
270 float GetFloatValue() const {
271 NS_ASSERTION(mUnit
== eUnit_Float
, "unit mismatch");
272 return mValue
.mFloat
;
274 nscolor
GetColorValue() const {
275 NS_ASSERTION(mUnit
== eUnit_Color
, "unit mismatch");
276 return mValue
.mColor
;
278 nsCSSValue
* GetCSSValueValue() const {
279 NS_ASSERTION(IsCSSValueUnit(mUnit
), "unit mismatch");
280 return mValue
.mCSSValue
;
282 nsCSSValuePair
* GetCSSValuePairValue() const {
283 NS_ASSERTION(IsCSSValuePairUnit(mUnit
), "unit mismatch");
284 return mValue
.mCSSValuePair
;
286 nsCSSValueTriplet
* GetCSSValueTripletValue() const {
287 NS_ASSERTION(IsCSSValueTripletUnit(mUnit
), "unit mismatch");
288 return mValue
.mCSSValueTriplet
;
290 nsCSSRect
* GetCSSRectValue() const {
291 NS_ASSERTION(IsCSSRectUnit(mUnit
), "unit mismatch");
292 return mValue
.mCSSRect
;
294 nsCSSValueList
* GetCSSValueListValue() const {
295 NS_ASSERTION(IsCSSValueListUnit(mUnit
), "unit mismatch");
296 return mValue
.mCSSValueList
;
298 nsCSSValueSharedList
* GetCSSValueSharedListValue() const {
299 NS_ASSERTION(IsCSSValueSharedListValue(mUnit
), "unit mismatch");
300 return mValue
.mCSSValueSharedList
;
302 nsCSSValuePairList
* GetCSSValuePairListValue() const {
303 NS_ASSERTION(IsCSSValuePairListUnit(mUnit
), "unit mismatch");
304 return mValue
.mCSSValuePairList
;
306 const char16_t
* GetStringBufferValue() const {
307 NS_ASSERTION(IsStringUnit(mUnit
), "unit mismatch");
308 return GetBufferValue(mValue
.mString
);
311 void GetStringValue(nsAString
& aBuffer
) const {
312 NS_ASSERTION(IsStringUnit(mUnit
), "unit mismatch");
314 uint32_t len
= NS_strlen(GetBufferValue(mValue
.mString
));
315 mValue
.mString
->ToString(len
, aBuffer
);
318 explicit StyleAnimationValue(Unit aUnit
= eUnit_Null
) : mUnit(aUnit
) {
319 NS_ASSERTION(aUnit
== eUnit_Null
|| aUnit
== eUnit_Normal
||
320 aUnit
== eUnit_Auto
|| aUnit
== eUnit_None
,
321 "must be valueless unit");
323 StyleAnimationValue(const StyleAnimationValue
& aOther
)
324 : mUnit(eUnit_Null
) { *this = aOther
; }
325 enum IntegerConstructorType
{ IntegerConstructor
};
326 StyleAnimationValue(int32_t aInt
, Unit aUnit
, IntegerConstructorType
);
327 enum CoordConstructorType
{ CoordConstructor
};
328 StyleAnimationValue(nscoord aLength
, CoordConstructorType
);
329 enum PercentConstructorType
{ PercentConstructor
};
330 StyleAnimationValue(float aPercent
, PercentConstructorType
);
331 enum FloatConstructorType
{ FloatConstructor
};
332 StyleAnimationValue(float aFloat
, FloatConstructorType
);
333 enum ColorConstructorType
{ ColorConstructor
};
334 StyleAnimationValue(nscolor aColor
, ColorConstructorType
);
336 ~StyleAnimationValue() { FreeValue(); }
338 void SetNormalValue();
341 void SetIntValue(int32_t aInt
, Unit aUnit
);
342 void SetCoordValue(nscoord aCoord
);
343 void SetPercentValue(float aPercent
);
344 void SetFloatValue(float aFloat
);
345 void SetColorValue(nscolor aColor
);
346 void SetUnparsedStringValue(const nsString
& aString
);
348 // These setters take ownership of |aValue|, and are therefore named
350 void SetAndAdoptCSSValueValue(nsCSSValue
*aValue
, Unit aUnit
);
351 void SetAndAdoptCSSValuePairValue(nsCSSValuePair
*aValue
, Unit aUnit
);
352 void SetAndAdoptCSSValueTripletValue(nsCSSValueTriplet
*aValue
, Unit aUnit
);
353 void SetAndAdoptCSSRectValue(nsCSSRect
*aValue
, Unit aUnit
);
354 void SetAndAdoptCSSValueListValue(nsCSSValueList
*aValue
, Unit aUnit
);
355 void SetAndAdoptCSSValuePairListValue(nsCSSValuePairList
*aValue
);
357 void SetTransformValue(nsCSSValueSharedList
* aList
);
359 StyleAnimationValue
& operator=(const StyleAnimationValue
& aOther
);
361 bool operator==(const StyleAnimationValue
& aOther
) const;
362 bool operator!=(const StyleAnimationValue
& aOther
) const
363 { return !(*this == aOther
); }
368 static const char16_t
* GetBufferValue(nsStringBuffer
* aBuffer
) {
369 return static_cast<char16_t
*>(aBuffer
->Data());
372 static bool IsIntUnit(Unit aUnit
) {
373 return aUnit
== eUnit_Enumerated
|| aUnit
== eUnit_Visibility
||
374 aUnit
== eUnit_Integer
;
376 static bool IsCSSValueUnit(Unit aUnit
) {
377 return aUnit
== eUnit_Calc
;
379 static bool IsCSSValuePairUnit(Unit aUnit
) {
380 return aUnit
== eUnit_CSSValuePair
;
382 static bool IsCSSValueTripletUnit(Unit aUnit
) {
383 return aUnit
== eUnit_CSSValueTriplet
;
385 static bool IsCSSRectUnit(Unit aUnit
) {
386 return aUnit
== eUnit_CSSRect
;
388 static bool IsCSSValueListUnit(Unit aUnit
) {
389 return aUnit
== eUnit_Dasharray
|| aUnit
== eUnit_Filter
||
390 aUnit
== eUnit_Shadow
||
391 aUnit
== eUnit_BackgroundPosition
;
393 static bool IsCSSValueSharedListValue(Unit aUnit
) {
394 return aUnit
== eUnit_Transform
;
396 static bool IsCSSValuePairListUnit(Unit aUnit
) {
397 return aUnit
== eUnit_CSSValuePairList
;
399 static bool IsStringUnit(Unit aUnit
) {
400 return aUnit
== eUnit_UnparsedString
;
404 } // namespace mozilla