Bumping manifests a=b2g-bump
[gecko.git] / layout / style / StyleAnimationValue.h
blobb87121acbed46b15c0744754994d8d20b441a470
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"
14 #include "nsCoord.h"
15 #include "nsColor.h"
16 #include "nsCSSValue.h"
18 class nsStyleContext;
19 class gfx3DMatrix;
21 namespace mozilla {
23 namespace dom {
24 class Element;
25 } // namespace dom
27 /**
28 * Utility class to handle animated style values
30 class StyleAnimationValue {
31 public:
32 // Mathematical methods
33 // --------------------
34 /**
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);
51 /**
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
60 * non-negative.
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,
72 double& aDistance);
74 /**
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
82 * interpolation.
83 * @param aEndValue The value defining the end of the interval of
84 * interpolation.
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,
93 double aPortion,
94 StyleAnimationValue& aResultValue) {
95 return AddWeighted(aProperty, 1.0 - aPortion, aStartValue,
96 aPortion, aEndValue, aResultValue);
99 /**
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
111 * positive.
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
124 * properties.
126 * @param aProperty The property whose value we're computing.
127 * @param aTargetElement The content node to which our computed value is
128 * applicable.
129 * @param aSpecifiedValue The specified value, from which we'll build our
130 * computed value.
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.
138 * false otherwise.
139 * Note that the operation of this method is
140 * significantly faster when |aIsContextSensitive| is
141 * nullptr.
142 * @return true on success, false on failure.
144 static bool ComputeValue(nsCSSProperty aProperty,
145 mozilla::dom::Element* aTargetElement,
146 const nsAString& aSpecifiedValue,
147 bool aUseSVGMode,
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
173 * context.
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,
193 double aProgress);
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.
202 enum Unit {
203 eUnit_Null, // not initialized
204 eUnit_Normal,
205 eUnit_Auto,
206 eUnit_None,
207 eUnit_Enumerated,
208 eUnit_Visibility, // special case for transitions (which converts
209 // Enumerated to Visibility as needed)
210 eUnit_Integer,
211 eUnit_Coord,
212 eUnit_Percent,
213 eUnit_Float,
214 eUnit_Color,
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)
229 private:
230 Unit mUnit;
231 union {
232 int32_t mInt;
233 nscoord mCoord;
234 float mFloat;
235 nscolor mColor;
236 nsCSSValue* mCSSValue;
237 nsCSSValuePair* mCSSValuePair;
238 nsCSSValueTriplet* mCSSValueTriplet;
239 nsCSSRect* mCSSRect;
240 nsCSSValueList* mCSSValueList;
241 nsCSSValueSharedList* mCSSValueSharedList;
242 nsCSSValuePairList* mCSSValuePairList;
243 nsStringBuffer* mString;
244 } mValue;
246 public:
247 Unit GetUnit() const {
248 NS_ASSERTION(mUnit != eUnit_Null, "uninitialized");
249 return mUnit;
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");
260 return mValue.mInt;
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");
313 aBuffer.Truncate();
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();
339 void SetAutoValue();
340 void SetNoneValue();
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
349 // "SetAndAdopt*".
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); }
365 private:
366 void FreeValue();
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
406 #endif