Thu, 15 Jan 2015 21:03:48 +0100
Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)
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 nsStyleAnimation_h_
9 #define nsStyleAnimation_h_
11 #include "nsStringFwd.h"
12 #include "nsCRTGlue.h"
13 #include "nsStringBuffer.h"
14 #include "nsCSSProperty.h"
15 #include "nsCoord.h"
16 #include "nsColor.h"
17 #include "nsCSSValue.h"
19 class nsStyleContext;
20 class gfx3DMatrix;
22 namespace mozilla {
23 namespace dom {
24 class Element;
25 } // namespace dom
26 } // namespace mozilla
28 /**
29 * Utility class to handle animated style values
30 */
31 class nsStyleAnimation {
32 public:
33 class Value;
35 // Mathematical methods
36 // --------------------
37 /**
38 * Adds |aCount| copies of |aValueToAdd| to |aDest|. The result of this
39 * addition is stored in aDest.
40 *
41 * Note that if |aCount| is 0, then |aDest| will be unchanged. Also, if
42 * this method fails, then |aDest| will be unchanged.
43 *
44 * @param aDest The value to add to.
45 * @param aValueToAdd The value to add.
46 * @param aCount The number of times to add aValueToAdd.
47 * @return true on success, false on failure.
48 */
49 static bool Add(nsCSSProperty aProperty, Value& aDest,
50 const Value& aValueToAdd, uint32_t aCount) {
51 return AddWeighted(aProperty, 1.0, aDest, aCount, aValueToAdd, aDest);
52 }
54 /**
55 * Calculates a measure of 'distance' between two values.
56 *
57 * This measure of Distance is guaranteed to be proportional to
58 * portions passed to Interpolate, Add, or AddWeighted. However, for
59 * some types of Value it may not produce sensible results for paced
60 * animation.
61 *
62 * If this method succeeds, the returned distance value is guaranteed to be
63 * non-negative.
64 *
65 * @param aStartValue The start of the interval for which the distance
66 * should be calculated.
67 * @param aEndValue The end of the interval for which the distance
68 * should be calculated.
69 * @param aDistance The result of the calculation.
70 * @return true on success, false on failure.
71 */
72 static bool ComputeDistance(nsCSSProperty aProperty,
73 const Value& aStartValue,
74 const Value& aEndValue,
75 double& aDistance);
77 /**
78 * Calculates an interpolated value that is the specified |aPortion| between
79 * the two given values.
80 *
81 * This really just does the following calculation:
82 * aResultValue = (1.0 - aPortion) * aStartValue + aPortion * aEndValue
83 *
84 * @param aStartValue The value defining the start of the interval of
85 * interpolation.
86 * @param aEndValue The value defining the end of the interval of
87 * interpolation.
88 * @param aPortion A number in the range [0.0, 1.0] defining the
89 * distance of the interpolated value in the interval.
90 * @param [out] aResultValue The resulting interpolated value.
91 * @return true on success, false on failure.
92 */
93 static bool Interpolate(nsCSSProperty aProperty,
94 const Value& aStartValue,
95 const Value& aEndValue,
96 double aPortion,
97 Value& aResultValue) {
98 return AddWeighted(aProperty, 1.0 - aPortion, aStartValue,
99 aPortion, aEndValue, aResultValue);
100 }
102 /**
103 * Does the calculation:
104 * aResultValue = aCoeff1 * aValue1 + aCoeff2 * aValue2
105 *
106 * @param [out] aResultValue The resulting interpolated value. May be
107 * the same as aValue1 or aValue2.
108 * @return true on success, false on failure.
109 *
110 * NOTE: Current callers always pass aCoeff1 and aCoeff2 >= 0. They
111 * are currently permitted to be negative; however, if, as we add
112 * support more value types types, we find that this causes
113 * difficulty, we might change this to restrict them to being
114 * positive.
115 */
116 static bool AddWeighted(nsCSSProperty aProperty,
117 double aCoeff1, const Value& aValue1,
118 double aCoeff2, const Value& aValue2,
119 Value& aResultValue);
121 // Type-conversion methods
122 // -----------------------
123 /**
124 * Creates a computed value for the given specified value
125 * (property ID + string). A style context is needed in case the
126 * specified value depends on inherited style or on the values of other
127 * properties.
128 *
129 * @param aProperty The property whose value we're computing.
130 * @param aTargetElement The content node to which our computed value is
131 * applicable.
132 * @param aSpecifiedValue The specified value, from which we'll build our
133 * computed value.
134 * @param aUseSVGMode A flag to indicate whether we should parse
135 * |aSpecifiedValue| in SVG mode.
136 * @param [out] aComputedValue The resulting computed value.
137 * @param [out] aIsContextSensitive
138 * Set to true if |aSpecifiedValue| may produce
139 * a different |aComputedValue| depending on other CSS
140 * properties on |aTargetElement| or its ancestors.
141 * false otherwise.
142 * Note that the operation of this method is
143 * significantly faster when |aIsContextSensitive| is
144 * nullptr.
145 * @return true on success, false on failure.
146 */
147 static bool ComputeValue(nsCSSProperty aProperty,
148 mozilla::dom::Element* aTargetElement,
149 const nsAString& aSpecifiedValue,
150 bool aUseSVGMode,
151 Value& aComputedValue,
152 bool* aIsContextSensitive = nullptr);
154 /**
155 * Creates a specified value for the given computed value.
156 *
157 * The first overload fills in an nsCSSValue object; the second
158 * produces a string. The nsCSSValue result may depend on objects
159 * owned by the |aComputedValue| object, so users of that variant
160 * must keep |aComputedValue| alive longer than |aSpecifiedValue|.
161 *
162 * @param aProperty The property whose value we're uncomputing.
163 * @param aComputedValue The computed value to be converted.
164 * @param [out] aSpecifiedValue The resulting specified value.
165 * @return true on success, false on failure.
166 */
167 static bool UncomputeValue(nsCSSProperty aProperty,
168 const Value& aComputedValue,
169 nsCSSValue& aSpecifiedValue);
170 static bool UncomputeValue(nsCSSProperty aProperty,
171 const Value& aComputedValue,
172 nsAString& aSpecifiedValue);
174 /**
175 * Gets the computed value for the given property from the given style
176 * context.
177 *
178 * @param aProperty The property whose value we're looking up.
179 * @param aStyleContext The style context to check for the computed value.
180 * @param [out] aComputedValue The resulting computed value.
181 * @return true on success, false on failure.
182 */
183 static bool ExtractComputedValue(nsCSSProperty aProperty,
184 nsStyleContext* aStyleContext,
185 Value& aComputedValue);
187 /**
188 * Interpolates between 2 matrices by decomposing them.
189 *
190 * @param aMatrix1 First matrix, using CSS pixel units.
191 * @param aMatrix2 Second matrix, using CSS pixel units.
192 * @param aProgress Interpolation value in the range [0.0, 1.0]
193 */
194 static gfx3DMatrix InterpolateTransformMatrix(const gfx3DMatrix &aMatrix1,
195 const gfx3DMatrix &aMatrix2,
196 double aProgress);
198 static already_AddRefed<nsCSSValue::Array>
199 AppendTransformFunction(nsCSSKeyword aTransformFunction,
200 nsCSSValueList**& aListTail);
202 /**
203 * The types and values for the values that we extract and animate.
204 */
205 enum Unit {
206 eUnit_Null, // not initialized
207 eUnit_Normal,
208 eUnit_Auto,
209 eUnit_None,
210 eUnit_Enumerated,
211 eUnit_Visibility, // special case for transitions (which converts
212 // Enumerated to Visibility as needed)
213 eUnit_Integer,
214 eUnit_Coord,
215 eUnit_Percent,
216 eUnit_Float,
217 eUnit_Color,
218 eUnit_Calc, // nsCSSValue* (never null), always with a single
219 // calc() expression that's either length or length+percent
220 eUnit_CSSValuePair, // nsCSSValuePair* (never null)
221 eUnit_CSSValueTriplet, // nsCSSValueTriplet* (never null)
222 eUnit_CSSRect, // nsCSSRect* (never null)
223 eUnit_Dasharray, // nsCSSValueList* (never null)
224 eUnit_Filter, // nsCSSValueList* (may be null)
225 eUnit_Shadow, // nsCSSValueList* (may be null)
226 eUnit_Transform, // nsCSSValueList* (never null)
227 eUnit_BackgroundPosition, // nsCSSValueList* (never null)
228 eUnit_CSSValuePairList, // nsCSSValuePairList* (never null)
229 eUnit_UnparsedString // nsStringBuffer* (never null)
230 };
232 class Value {
233 private:
234 Unit mUnit;
235 union {
236 int32_t mInt;
237 nscoord mCoord;
238 float mFloat;
239 nscolor mColor;
240 nsCSSValue* mCSSValue;
241 nsCSSValuePair* mCSSValuePair;
242 nsCSSValueTriplet* mCSSValueTriplet;
243 nsCSSRect* mCSSRect;
244 nsCSSValueList* mCSSValueList;
245 nsCSSValueSharedList* mCSSValueSharedList;
246 nsCSSValuePairList* mCSSValuePairList;
247 nsStringBuffer* mString;
248 } mValue;
249 public:
250 Unit GetUnit() const {
251 NS_ASSERTION(mUnit != eUnit_Null, "uninitialized");
252 return mUnit;
253 }
255 // Accessor to let us verify assumptions about presence of null unit,
256 // without tripping the assertion in GetUnit().
257 bool IsNull() const {
258 return mUnit == eUnit_Null;
259 }
261 int32_t GetIntValue() const {
262 NS_ASSERTION(IsIntUnit(mUnit), "unit mismatch");
263 return mValue.mInt;
264 }
265 nscoord GetCoordValue() const {
266 NS_ASSERTION(mUnit == eUnit_Coord, "unit mismatch");
267 return mValue.mCoord;
268 }
269 float GetPercentValue() const {
270 NS_ASSERTION(mUnit == eUnit_Percent, "unit mismatch");
271 return mValue.mFloat;
272 }
273 float GetFloatValue() const {
274 NS_ASSERTION(mUnit == eUnit_Float, "unit mismatch");
275 return mValue.mFloat;
276 }
277 nscolor GetColorValue() const {
278 NS_ASSERTION(mUnit == eUnit_Color, "unit mismatch");
279 return mValue.mColor;
280 }
281 nsCSSValue* GetCSSValueValue() const {
282 NS_ASSERTION(IsCSSValueUnit(mUnit), "unit mismatch");
283 return mValue.mCSSValue;
284 }
285 nsCSSValuePair* GetCSSValuePairValue() const {
286 NS_ASSERTION(IsCSSValuePairUnit(mUnit), "unit mismatch");
287 return mValue.mCSSValuePair;
288 }
289 nsCSSValueTriplet* GetCSSValueTripletValue() const {
290 NS_ASSERTION(IsCSSValueTripletUnit(mUnit), "unit mismatch");
291 return mValue.mCSSValueTriplet;
292 }
293 nsCSSRect* GetCSSRectValue() const {
294 NS_ASSERTION(IsCSSRectUnit(mUnit), "unit mismatch");
295 return mValue.mCSSRect;
296 }
297 nsCSSValueList* GetCSSValueListValue() const {
298 NS_ASSERTION(IsCSSValueListUnit(mUnit), "unit mismatch");
299 return mValue.mCSSValueList;
300 }
301 nsCSSValueSharedList* GetCSSValueSharedListValue() const {
302 NS_ASSERTION(IsCSSValueSharedListValue(mUnit), "unit mismatch");
303 return mValue.mCSSValueSharedList;
304 }
305 nsCSSValuePairList* GetCSSValuePairListValue() const {
306 NS_ASSERTION(IsCSSValuePairListUnit(mUnit), "unit mismatch");
307 return mValue.mCSSValuePairList;
308 }
309 const char16_t* GetStringBufferValue() const {
310 NS_ASSERTION(IsStringUnit(mUnit), "unit mismatch");
311 return GetBufferValue(mValue.mString);
312 }
314 void GetStringValue(nsAString& aBuffer) const {
315 NS_ASSERTION(IsStringUnit(mUnit), "unit mismatch");
316 aBuffer.Truncate();
317 uint32_t len = NS_strlen(GetBufferValue(mValue.mString));
318 mValue.mString->ToString(len, aBuffer);
319 }
321 explicit Value(Unit aUnit = eUnit_Null) : mUnit(aUnit) {
322 NS_ASSERTION(aUnit == eUnit_Null || aUnit == eUnit_Normal ||
323 aUnit == eUnit_Auto || aUnit == eUnit_None,
324 "must be valueless unit");
325 }
326 Value(const Value& aOther) : mUnit(eUnit_Null) { *this = aOther; }
327 enum IntegerConstructorType { IntegerConstructor };
328 Value(int32_t aInt, Unit aUnit, IntegerConstructorType);
329 enum CoordConstructorType { CoordConstructor };
330 Value(nscoord aLength, CoordConstructorType);
331 enum PercentConstructorType { PercentConstructor };
332 Value(float aPercent, PercentConstructorType);
333 enum FloatConstructorType { FloatConstructor };
334 Value(float aFloat, FloatConstructorType);
335 enum ColorConstructorType { ColorConstructor };
336 Value(nscolor aColor, ColorConstructorType);
338 ~Value() { FreeValue(); }
340 void SetNormalValue();
341 void SetAutoValue();
342 void SetNoneValue();
343 void SetIntValue(int32_t aInt, Unit aUnit);
344 void SetCoordValue(nscoord aCoord);
345 void SetPercentValue(float aPercent);
346 void SetFloatValue(float aFloat);
347 void SetColorValue(nscolor aColor);
348 void SetUnparsedStringValue(const nsString& aString);
350 // These setters take ownership of |aValue|, and are therefore named
351 // "SetAndAdopt*".
352 void SetAndAdoptCSSValueValue(nsCSSValue *aValue, Unit aUnit);
353 void SetAndAdoptCSSValuePairValue(nsCSSValuePair *aValue, Unit aUnit);
354 void SetAndAdoptCSSValueTripletValue(nsCSSValueTriplet *aValue, Unit aUnit);
355 void SetAndAdoptCSSRectValue(nsCSSRect *aValue, Unit aUnit);
356 void SetAndAdoptCSSValueListValue(nsCSSValueList *aValue, Unit aUnit);
357 void SetAndAdoptCSSValuePairListValue(nsCSSValuePairList *aValue);
359 void SetTransformValue(nsCSSValueSharedList* aList);
361 Value& operator=(const Value& aOther);
363 bool operator==(const Value& aOther) const;
364 bool operator!=(const Value& aOther) const
365 { return !(*this == aOther); }
367 private:
368 void FreeValue();
370 static const char16_t* GetBufferValue(nsStringBuffer* aBuffer) {
371 return static_cast<char16_t*>(aBuffer->Data());
372 }
374 static bool IsIntUnit(Unit aUnit) {
375 return aUnit == eUnit_Enumerated || aUnit == eUnit_Visibility ||
376 aUnit == eUnit_Integer;
377 }
378 static bool IsCSSValueUnit(Unit aUnit) {
379 return aUnit == eUnit_Calc;
380 }
381 static bool IsCSSValuePairUnit(Unit aUnit) {
382 return aUnit == eUnit_CSSValuePair;
383 }
384 static bool IsCSSValueTripletUnit(Unit aUnit) {
385 return aUnit == eUnit_CSSValueTriplet;
386 }
387 static bool IsCSSRectUnit(Unit aUnit) {
388 return aUnit == eUnit_CSSRect;
389 }
390 static bool IsCSSValueListUnit(Unit aUnit) {
391 return aUnit == eUnit_Dasharray || aUnit == eUnit_Filter ||
392 aUnit == eUnit_Shadow ||
393 aUnit == eUnit_BackgroundPosition;
394 }
395 static bool IsCSSValueSharedListValue(Unit aUnit) {
396 return aUnit == eUnit_Transform;
397 }
398 static bool IsCSSValuePairListUnit(Unit aUnit) {
399 return aUnit == eUnit_CSSValuePairList;
400 }
401 static bool IsStringUnit(Unit aUnit) {
402 return aUnit == eUnit_UnparsedString;
403 }
404 };
405 };
407 #endif