Line data Source code
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/. */
5 :
6 : /* Utilities for animation of computed style values */
7 :
8 : #ifndef mozilla_StyleAnimationValue_h_
9 : #define mozilla_StyleAnimationValue_h_
10 :
11 : #include "gfxPoint.h"
12 : #include "mozilla/gfx/MatrixFwd.h"
13 : #include "mozilla/ServoBindingTypes.h"
14 : #include "mozilla/UniquePtr.h"
15 : #include "nsStringFwd.h"
16 : #include "nsStringBuffer.h"
17 : #include "nsCoord.h"
18 : #include "nsColor.h"
19 : #include "nsCSSProps.h"
20 : #include "nsCSSValue.h"
21 : #include "nsStyleCoord.h"
22 : #include "nsStyleTransformMatrix.h"
23 :
24 : class nsIFrame;
25 : class nsStyleContext;
26 : class gfx3DMatrix;
27 :
28 : namespace mozilla {
29 :
30 : namespace css {
31 : class StyleRule;
32 : } // namespace css
33 :
34 : namespace dom {
35 : class Element;
36 : } // namespace dom
37 :
38 : enum class CSSPseudoElementType : uint8_t;
39 : struct PropertyStyleAnimationValuePair;
40 :
41 : /**
42 : * Utility class to handle animated style values
43 : */
44 : class StyleAnimationValue {
45 : public:
46 : // Mathematical methods
47 : // --------------------
48 : /**
49 : * Adds |aCount| copies of |aValueToAdd| to |aDest|. The result of this
50 : * addition is stored in aDest.
51 : *
52 : * Note that if |aCount| is 0, then |aDest| will be unchanged. Also, if
53 : * this method fails, then |aDest| will be unchanged.
54 : *
55 : * @param aDest The value to add to.
56 : * @param aValueToAdd The value to add.
57 : * @param aCount The number of times to add aValueToAdd.
58 : * @return true on success, false on failure.
59 : */
60 : static MOZ_MUST_USE bool
61 0 : Add(nsCSSPropertyID aProperty, StyleAnimationValue& aDest,
62 : const StyleAnimationValue& aValueToAdd, uint32_t aCount) {
63 0 : return AddWeighted(aProperty, 1.0, aDest, aCount, aValueToAdd, aDest);
64 : }
65 :
66 : /**
67 : * Alternative version of Add that reflects the naming used in Web Animations
68 : * and which returns the result using the return value.
69 : */
70 : static StyleAnimationValue
71 : Add(nsCSSPropertyID aProperty,
72 : const StyleAnimationValue& aA,
73 : StyleAnimationValue&& aB);
74 :
75 : /**
76 : * Calculates a measure of 'distance' between two colors.
77 : *
78 : * @param aStartColor The start of the interval for which the distance
79 : * should be calculated.
80 : * @param aEndColor The end of the interval for which the distance
81 : * should be calculated.
82 : * @return the result of the calculation.
83 : */
84 : static double ComputeColorDistance(const css::RGBAColorData& aStartColor,
85 : const css::RGBAColorData& aEndColor);
86 :
87 : /**
88 : * Calculates a measure of 'distance' between two values.
89 : *
90 : * This measure of Distance is guaranteed to be proportional to
91 : * portions passed to Interpolate, Add, or AddWeighted. However, for
92 : * some types of StyleAnimationValue it may not produce sensible results
93 : * for paced animation.
94 : *
95 : * If this method succeeds, the returned distance value is guaranteed to be
96 : * non-negative.
97 : *
98 : * @param aStartValue The start of the interval for which the distance
99 : * should be calculated.
100 : * @param aEndValue The end of the interval for which the distance
101 : * should be calculated.
102 : * @param aStyleContext The style context to use for processing the
103 : * translate part of transforms.
104 : * @param aDistance The result of the calculation.
105 : * @return true on success, false on failure.
106 : */
107 : static MOZ_MUST_USE bool
108 : ComputeDistance(nsCSSPropertyID aProperty,
109 : const StyleAnimationValue& aStartValue,
110 : const StyleAnimationValue& aEndValue,
111 : nsStyleContext* aStyleContext,
112 : double& aDistance);
113 :
114 : /**
115 : * Calculates an interpolated value that is the specified |aPortion| between
116 : * the two given values.
117 : *
118 : * This really just does the following calculation:
119 : * aResultValue = (1.0 - aPortion) * aStartValue + aPortion * aEndValue
120 : *
121 : * @param aStartValue The value defining the start of the interval of
122 : * interpolation.
123 : * @param aEndValue The value defining the end of the interval of
124 : * interpolation.
125 : * @param aPortion A number in the range [0.0, 1.0] defining the
126 : * distance of the interpolated value in the interval.
127 : * @param [out] aResultValue The resulting interpolated value.
128 : * @return true on success, false on failure.
129 : */
130 : static MOZ_MUST_USE bool
131 10 : Interpolate(nsCSSPropertyID aProperty,
132 : const StyleAnimationValue& aStartValue,
133 : const StyleAnimationValue& aEndValue,
134 : double aPortion,
135 : StyleAnimationValue& aResultValue) {
136 10 : return AddWeighted(aProperty, 1.0 - aPortion, aStartValue,
137 10 : aPortion, aEndValue, aResultValue);
138 : }
139 :
140 : /**
141 : * Does the calculation:
142 : * aResultValue = aCoeff1 * aValue1 + aCoeff2 * aValue2
143 : *
144 : * @param [out] aResultValue The resulting interpolated value. May be
145 : * the same as aValue1 or aValue2.
146 : * @return true on success, false on failure.
147 : *
148 : * NOTE: Current callers always pass aCoeff1 and aCoeff2 >= 0. They
149 : * are currently permitted to be negative; however, if, as we add
150 : * support more value types types, we find that this causes
151 : * difficulty, we might change this to restrict them to being
152 : * positive.
153 : */
154 : static MOZ_MUST_USE bool
155 : AddWeighted(nsCSSPropertyID aProperty,
156 : double aCoeff1, const StyleAnimationValue& aValue1,
157 : double aCoeff2, const StyleAnimationValue& aValue2,
158 : StyleAnimationValue& aResultValue);
159 :
160 : /**
161 : * Accumulates |aA| onto |aA| (|aCount| - 1) times then accumulates |aB| onto
162 : * the result.
163 : * If |aCount| is zero or no accumulation or addition procedure is defined
164 : * for |aProperty|, the result will be |aB|.
165 : */
166 : static StyleAnimationValue
167 : Accumulate(nsCSSPropertyID aProperty,
168 : const StyleAnimationValue& aA,
169 : StyleAnimationValue&& aB,
170 : uint64_t aCount = 1);
171 :
172 : // Type-conversion methods
173 : // -----------------------
174 : /**
175 : * Creates a computed value for the given specified value
176 : * (property ID + string). A style context is needed in case the
177 : * specified value depends on inherited style or on the values of other
178 : * properties.
179 : *
180 : * @param aProperty The property whose value we're computing.
181 : * @param aTargetElement The content node to which our computed value is
182 : * applicable. For pseudo-elements, this is the parent
183 : * element to which the pseudo is attached, not the
184 : * generated content node.
185 : * @param aStyleContext The style context used to compute values from the
186 : * specified value. For pseudo-elements, this should
187 : * be the style context corresponding to the pseudo
188 : * element.
189 : * @param aSpecifiedValue The specified value, from which we'll build our
190 : * computed value.
191 : * @param aUseSVGMode A flag to indicate whether we should parse
192 : * |aSpecifiedValue| in SVG mode.
193 : * @param [out] aComputedValue The resulting computed value.
194 : * @param [out] aIsContextSensitive
195 : * Set to true if |aSpecifiedValue| may produce
196 : * a different |aComputedValue| depending on other CSS
197 : * properties on |aTargetElement| or its ancestors.
198 : * false otherwise.
199 : * Note that the operation of this method is
200 : * significantly faster when |aIsContextSensitive| is
201 : * nullptr.
202 : * @return true on success, false on failure.
203 : */
204 : static MOZ_MUST_USE bool
205 : ComputeValue(nsCSSPropertyID aProperty,
206 : mozilla::dom::Element* aTargetElement,
207 : nsStyleContext* aStyleContext,
208 : const nsAString& aSpecifiedValue,
209 : bool aUseSVGMode,
210 : StyleAnimationValue& aComputedValue,
211 : bool* aIsContextSensitive = nullptr);
212 :
213 : /**
214 : * Like ComputeValue, but returns an array of StyleAnimationValues.
215 : *
216 : * On success, when aProperty is a longhand, aResult will have a single
217 : * value in it. When aProperty is a shorthand, aResult will be filled with
218 : * values for all of aProperty's longhand components. aEnabledState
219 : * is used to filter the longhand components that will be appended
220 : * to aResult. On failure, aResult might still have partial results
221 : * in it.
222 : */
223 : static MOZ_MUST_USE bool
224 : ComputeValues(nsCSSPropertyID aProperty,
225 : mozilla::CSSEnabledState aEnabledState,
226 : mozilla::dom::Element* aTargetElement,
227 : nsStyleContext* aStyleContext,
228 : const nsAString& aSpecifiedValue,
229 : bool aUseSVGMode,
230 : nsTArray<PropertyStyleAnimationValuePair>& aResult);
231 :
232 : /**
233 : * A variant on ComputeValues that takes an nsCSSValue as the specified
234 : * value. Only longhand properties are supported.
235 : */
236 : static MOZ_MUST_USE bool
237 : ComputeValues(nsCSSPropertyID aProperty,
238 : mozilla::CSSEnabledState aEnabledState,
239 : mozilla::dom::Element* aTargetElement,
240 : nsStyleContext* aStyleContext,
241 : const nsCSSValue& aSpecifiedValue,
242 : bool aUseSVGMode,
243 : nsTArray<PropertyStyleAnimationValuePair>& aResult);
244 :
245 : /**
246 : * Creates a specified value for the given computed value.
247 : *
248 : * The first two overloads fill in an nsCSSValue object; the third
249 : * produces a string. For the overload that takes a const
250 : * StyleAnimationValue& reference, the nsCSSValue result may depend on
251 : * objects owned by the |aComputedValue| object, so users of that variant
252 : * must keep |aComputedValue| alive longer than |aSpecifiedValue|.
253 : * The overload that takes an rvalue StyleAnimationValue reference
254 : * transfers ownership for some resources such that the |aComputedValue|
255 : * does not depend on the lifetime of |aSpecifiedValue|.
256 : *
257 : * @param aProperty The property whose value we're uncomputing.
258 : * @param aComputedValue The computed value to be converted.
259 : * @param [out] aSpecifiedValue The resulting specified value.
260 : * @return true on success, false on failure.
261 : */
262 : static MOZ_MUST_USE bool
263 : UncomputeValue(nsCSSPropertyID aProperty,
264 : const StyleAnimationValue& aComputedValue,
265 : nsCSSValue& aSpecifiedValue);
266 : static MOZ_MUST_USE bool
267 : UncomputeValue(nsCSSPropertyID aProperty,
268 : StyleAnimationValue&& aComputedValue,
269 : nsCSSValue& aSpecifiedValue);
270 : static MOZ_MUST_USE bool
271 : UncomputeValue(nsCSSPropertyID aProperty,
272 : const StyleAnimationValue& aComputedValue,
273 : nsAString& aSpecifiedValue);
274 :
275 : /**
276 : * Gets the computed value for the given property from the given style
277 : * context.
278 : *
279 : * Obtaining the computed value allows us to animate properties when the
280 : * content author has specified a value like "inherit" or "initial" or some
281 : * other keyword that isn't directly interpolatable, but which *computes* to
282 : * something interpolatable.
283 : *
284 : * @param aProperty The property whose value we're looking up.
285 : * @param aStyleContext The style context to check for the computed value.
286 : * @param [out] aComputedValue The resulting computed value.
287 : * @return true on success, false on failure.
288 : */
289 : static MOZ_MUST_USE bool ExtractComputedValue(
290 : nsCSSPropertyID aProperty,
291 : nsStyleContext* aStyleContext,
292 : StyleAnimationValue& aComputedValue);
293 :
294 : static already_AddRefed<nsCSSValue::Array>
295 : AppendTransformFunction(nsCSSKeyword aTransformFunction,
296 : nsCSSValueList**& aListTail);
297 :
298 : /**
299 : * The types and values for the values that we extract and animate.
300 : */
301 : enum Unit {
302 : eUnit_Null, // not initialized
303 : eUnit_Normal,
304 : eUnit_Auto,
305 : eUnit_None,
306 : eUnit_Enumerated,
307 : eUnit_Visibility, // special case for transitions (which converts
308 : // Enumerated to Visibility as needed)
309 : eUnit_Integer,
310 : eUnit_Coord,
311 : eUnit_Percent,
312 : eUnit_Float,
313 : eUnit_Color, // nsCSSValue* (never null), always with an nscolor or
314 : // an nsCSSValueFloatColor
315 : eUnit_CurrentColor,
316 : eUnit_ComplexColor, // ComplexColorValue* (never null)
317 : eUnit_Calc, // nsCSSValue* (never null), always with a single
318 : // calc() expression that's either length or length+percent
319 : eUnit_ObjectPosition, // nsCSSValue* (never null), always with a
320 : // 4-entry nsCSSValue::Array
321 : eUnit_URL, // nsCSSValue* (never null), always with a css::URLValue
322 : eUnit_DiscreteCSSValue, // nsCSSValue* (never null)
323 : eUnit_CSSValuePair, // nsCSSValuePair* (never null)
324 : eUnit_CSSValueTriplet, // nsCSSValueTriplet* (never null)
325 : eUnit_CSSRect, // nsCSSRect* (never null)
326 : eUnit_Dasharray, // nsCSSValueList* (never null)
327 : eUnit_Shadow, // nsCSSValueList* (may be null)
328 : eUnit_Shape, // nsCSSValue::Array* (never null)
329 : eUnit_Filter, // nsCSSValueList* (may be null)
330 : eUnit_Transform, // nsCSSValueList* (never null)
331 : eUnit_BackgroundPositionCoord, // nsCSSValueList* (never null)
332 : eUnit_CSSValuePairList, // nsCSSValuePairList* (never null)
333 : eUnit_UnparsedString // nsStringBuffer* (never null)
334 : };
335 :
336 : private:
337 : Unit mUnit;
338 : union {
339 : int32_t mInt;
340 : nscoord mCoord;
341 : float mFloat;
342 : nsCSSValue* mCSSValue;
343 : nsCSSValuePair* mCSSValuePair;
344 : nsCSSValueTriplet* mCSSValueTriplet;
345 : nsCSSRect* mCSSRect;
346 : nsCSSValue::Array* mCSSValueArray;
347 : nsCSSValueList* mCSSValueList;
348 : nsCSSValueSharedList* mCSSValueSharedList;
349 : nsCSSValuePairList* mCSSValuePairList;
350 : nsStringBuffer* mString;
351 : css::ComplexColorValue* mComplexColor;
352 : } mValue;
353 :
354 : public:
355 38 : Unit GetUnit() const {
356 38 : NS_ASSERTION(mUnit != eUnit_Null, "uninitialized");
357 38 : return mUnit;
358 : }
359 :
360 : // Accessor to let us verify assumptions about presence of null unit,
361 : // without tripping the assertion in GetUnit().
362 92 : bool IsNull() const {
363 92 : return mUnit == eUnit_Null;
364 : }
365 :
366 0 : int32_t GetIntValue() const {
367 0 : NS_ASSERTION(IsIntUnit(mUnit), "unit mismatch");
368 0 : return mValue.mInt;
369 : }
370 0 : nscoord GetCoordValue() const {
371 0 : NS_ASSERTION(mUnit == eUnit_Coord, "unit mismatch");
372 0 : return mValue.mCoord;
373 : }
374 0 : float GetPercentValue() const {
375 0 : NS_ASSERTION(mUnit == eUnit_Percent, "unit mismatch");
376 0 : return mValue.mFloat;
377 : }
378 34 : float GetFloatValue() const {
379 34 : NS_ASSERTION(mUnit == eUnit_Float, "unit mismatch");
380 34 : return mValue.mFloat;
381 : }
382 0 : nsCSSValue* GetCSSValueValue() const {
383 0 : NS_ASSERTION(IsCSSValueUnit(mUnit), "unit mismatch");
384 0 : return mValue.mCSSValue;
385 : }
386 0 : nsCSSValuePair* GetCSSValuePairValue() const {
387 0 : NS_ASSERTION(IsCSSValuePairUnit(mUnit), "unit mismatch");
388 0 : return mValue.mCSSValuePair;
389 : }
390 0 : nsCSSValueTriplet* GetCSSValueTripletValue() const {
391 0 : NS_ASSERTION(IsCSSValueTripletUnit(mUnit), "unit mismatch");
392 0 : return mValue.mCSSValueTriplet;
393 : }
394 0 : nsCSSRect* GetCSSRectValue() const {
395 0 : NS_ASSERTION(IsCSSRectUnit(mUnit), "unit mismatch");
396 0 : return mValue.mCSSRect;
397 : }
398 0 : nsCSSValue::Array* GetCSSValueArrayValue() const {
399 0 : NS_ASSERTION(IsCSSValueArrayUnit(mUnit), "unit mismatch");
400 0 : return mValue.mCSSValueArray;
401 : }
402 0 : nsCSSValueList* GetCSSValueListValue() const {
403 0 : NS_ASSERTION(IsCSSValueListUnit(mUnit), "unit mismatch");
404 0 : return mValue.mCSSValueList;
405 : }
406 0 : nsCSSValueSharedList* GetCSSValueSharedListValue() const {
407 0 : NS_ASSERTION(IsCSSValueSharedListValue(mUnit), "unit mismatch");
408 0 : return mValue.mCSSValueSharedList;
409 : }
410 0 : nsCSSValuePairList* GetCSSValuePairListValue() const {
411 0 : NS_ASSERTION(IsCSSValuePairListUnit(mUnit), "unit mismatch");
412 0 : return mValue.mCSSValuePairList;
413 : }
414 0 : const char16_t* GetStringBufferValue() const {
415 0 : NS_ASSERTION(IsStringUnit(mUnit), "unit mismatch");
416 0 : return GetBufferValue(mValue.mString);
417 : }
418 :
419 0 : void GetStringValue(nsAString& aBuffer) const {
420 0 : NS_ASSERTION(IsStringUnit(mUnit), "unit mismatch");
421 0 : aBuffer.Truncate();
422 0 : uint32_t len = NS_strlen(GetBufferValue(mValue.mString));
423 0 : mValue.mString->ToString(len, aBuffer);
424 0 : }
425 :
426 : /// @return the scale for this value, calculated with reference to @aForFrame.
427 : gfxSize GetScaleValue(const nsIFrame* aForFrame) const;
428 :
429 0 : const css::ComplexColorData& GetComplexColorData() const {
430 0 : MOZ_ASSERT(mUnit == eUnit_ComplexColor, "unit mismatch");
431 0 : return *mValue.mComplexColor;
432 : }
433 : StyleComplexColor GetStyleComplexColorValue() const {
434 : return GetComplexColorData().ToComplexColor();
435 : }
436 :
437 0 : UniquePtr<nsCSSValueList> TakeCSSValueListValue() {
438 0 : nsCSSValueList* list = GetCSSValueListValue();
439 0 : mValue.mCSSValueList = nullptr;
440 0 : mUnit = eUnit_Null;
441 0 : return UniquePtr<nsCSSValueList>(list);
442 : }
443 0 : UniquePtr<nsCSSValuePairList> TakeCSSValuePairListValue() {
444 0 : nsCSSValuePairList* list = GetCSSValuePairListValue();
445 0 : mValue.mCSSValuePairList = nullptr;
446 0 : mUnit = eUnit_Null;
447 0 : return UniquePtr<nsCSSValuePairList>(list);
448 : }
449 :
450 833 : explicit StyleAnimationValue(Unit aUnit = eUnit_Null) : mUnit(aUnit) {
451 833 : NS_ASSERTION(aUnit == eUnit_Null || aUnit == eUnit_Normal ||
452 : aUnit == eUnit_Auto || aUnit == eUnit_None,
453 : "must be valueless unit");
454 833 : }
455 249 : StyleAnimationValue(const StyleAnimationValue& aOther)
456 249 : : mUnit(eUnit_Null) { *this = aOther; }
457 32 : StyleAnimationValue(StyleAnimationValue&& aOther)
458 32 : : mUnit(aOther.mUnit)
459 32 : , mValue(aOther.mValue)
460 : {
461 32 : aOther.mUnit = eUnit_Null;
462 32 : }
463 : enum IntegerConstructorType { IntegerConstructor };
464 : StyleAnimationValue(int32_t aInt, Unit aUnit, IntegerConstructorType);
465 : enum CoordConstructorType { CoordConstructor };
466 : StyleAnimationValue(nscoord aLength, CoordConstructorType);
467 : enum PercentConstructorType { PercentConstructor };
468 : StyleAnimationValue(float aPercent, PercentConstructorType);
469 : enum FloatConstructorType { FloatConstructor };
470 : StyleAnimationValue(float aFloat, FloatConstructorType);
471 : enum ColorConstructorType { ColorConstructor };
472 : StyleAnimationValue(nscolor aColor, ColorConstructorType);
473 :
474 1074 : ~StyleAnimationValue() { FreeValue(); }
475 :
476 : void SetNormalValue();
477 : void SetAutoValue();
478 : void SetNoneValue();
479 : void SetIntValue(int32_t aInt, Unit aUnit);
480 : template<typename T,
481 : typename = typename std::enable_if<std::is_enum<T>::value>::type>
482 0 : void SetEnumValue(T aInt)
483 : {
484 : static_assert(mozilla::EnumTypeFitsWithin<T, int32_t>::value,
485 : "aValue must be an enum that fits within mValue.mInt");
486 0 : SetIntValue(static_cast<int32_t>(aInt), eUnit_Enumerated);
487 0 : }
488 : void SetCoordValue(nscoord aCoord);
489 : void SetPercentValue(float aPercent);
490 : void SetFloatValue(float aFloat);
491 : void SetColorValue(nscolor aColor);
492 : void SetCurrentColorValue();
493 : void SetComplexColorValue(const StyleComplexColor& aColor);
494 : void SetComplexColorValue(already_AddRefed<css::ComplexColorValue> aValue);
495 : void SetUnparsedStringValue(const nsString& aString);
496 : void SetCSSValueArrayValue(nsCSSValue::Array* aValue, Unit aUnit);
497 :
498 : // These setters take ownership of |aValue|, and are therefore named
499 : // "SetAndAdopt*".
500 : void SetAndAdoptCSSValueValue(nsCSSValue *aValue, Unit aUnit);
501 : void SetAndAdoptCSSValuePairValue(nsCSSValuePair *aValue, Unit aUnit);
502 : void SetAndAdoptCSSValueTripletValue(nsCSSValueTriplet *aValue, Unit aUnit);
503 : void SetAndAdoptCSSRectValue(nsCSSRect *aValue, Unit aUnit);
504 : void SetAndAdoptCSSValueListValue(nsCSSValueList *aValue, Unit aUnit);
505 : void SetAndAdoptCSSValuePairListValue(nsCSSValuePairList *aValue);
506 :
507 : void SetTransformValue(nsCSSValueSharedList* aList);
508 :
509 : StyleAnimationValue& operator=(const StyleAnimationValue& aOther);
510 34 : StyleAnimationValue& operator=(StyleAnimationValue&& aOther)
511 : {
512 34 : MOZ_ASSERT(this != &aOther, "Do not move itself");
513 34 : if (this != &aOther) {
514 34 : FreeValue();
515 34 : mUnit = aOther.mUnit;
516 34 : mValue = aOther.mValue;
517 34 : aOther.mUnit = eUnit_Null;
518 : }
519 34 : return *this;
520 : }
521 :
522 : bool operator==(const StyleAnimationValue& aOther) const;
523 0 : bool operator!=(const StyleAnimationValue& aOther) const
524 0 : { return !(*this == aOther); }
525 :
526 : private:
527 : void FreeValue();
528 :
529 0 : static const char16_t* GetBufferValue(nsStringBuffer* aBuffer) {
530 0 : return static_cast<char16_t*>(aBuffer->Data());
531 : }
532 :
533 18 : static bool IsIntUnit(Unit aUnit) {
534 18 : return aUnit == eUnit_Enumerated || aUnit == eUnit_Visibility ||
535 18 : aUnit == eUnit_Integer;
536 : }
537 1980 : static bool IsCSSValueUnit(Unit aUnit) {
538 1839 : return aUnit == eUnit_Color ||
539 1839 : aUnit == eUnit_Calc ||
540 1839 : aUnit == eUnit_ObjectPosition ||
541 3819 : aUnit == eUnit_URL ||
542 1980 : aUnit == eUnit_DiscreteCSSValue;
543 : }
544 1771 : static bool IsCSSValuePairUnit(Unit aUnit) {
545 1771 : return aUnit == eUnit_CSSValuePair;
546 : }
547 1771 : static bool IsCSSValueTripletUnit(Unit aUnit) {
548 1771 : return aUnit == eUnit_CSSValueTriplet;
549 : }
550 1771 : static bool IsCSSRectUnit(Unit aUnit) {
551 1771 : return aUnit == eUnit_CSSRect;
552 : }
553 1771 : static bool IsCSSValueArrayUnit(Unit aUnit) {
554 1771 : return aUnit == eUnit_Shape;
555 : }
556 1907 : static bool IsCSSValueListUnit(Unit aUnit) {
557 1907 : return aUnit == eUnit_Dasharray || aUnit == eUnit_Filter ||
558 3678 : aUnit == eUnit_Shadow ||
559 1907 : aUnit == eUnit_BackgroundPositionCoord;
560 : }
561 1771 : static bool IsCSSValueSharedListValue(Unit aUnit) {
562 1771 : return aUnit == eUnit_Transform;
563 : }
564 1771 : static bool IsCSSValuePairListUnit(Unit aUnit) {
565 1771 : return aUnit == eUnit_CSSValuePairList;
566 : }
567 1771 : static bool IsStringUnit(Unit aUnit) {
568 1771 : return aUnit == eUnit_UnparsedString;
569 : }
570 : };
571 :
572 618 : struct AnimationValue
573 : {
574 : explicit AnimationValue(const StyleAnimationValue& aValue)
575 : : mGecko(aValue) { }
576 : explicit AnimationValue(const RefPtr<RawServoAnimationValue>& aValue)
577 : : mServo(aValue) { }
578 568 : AnimationValue() = default;
579 :
580 26 : AnimationValue(const AnimationValue& aOther)
581 26 : : mGecko(aOther.mGecko), mServo(aOther.mServo) { }
582 32 : AnimationValue(AnimationValue&& aOther)
583 32 : : mGecko(Move(aOther.mGecko)), mServo(Move(aOther.mServo)) { }
584 :
585 32 : AnimationValue& operator=(const AnimationValue& aOther)
586 : {
587 32 : if (this != &aOther) {
588 32 : mGecko = aOther.mGecko;
589 32 : mServo = aOther.mServo;
590 : }
591 32 : return *this;
592 : }
593 26 : AnimationValue& operator=(AnimationValue&& aOther)
594 : {
595 26 : MOZ_ASSERT(this != &aOther, "Do not move itself");
596 26 : if (this != &aOther) {
597 26 : mGecko = Move(aOther.mGecko);
598 26 : mServo = Move(aOther.mServo);
599 : }
600 26 : return *this;
601 : }
602 :
603 : bool operator==(const AnimationValue& aOther) const;
604 : bool operator!=(const AnimationValue& aOther) const;
605 :
606 58 : bool IsNull() const { return mGecko.IsNull() && !mServo; }
607 :
608 : float GetOpacity() const;
609 :
610 : // Returns the scale for mGecko or mServo, which are calculated with
611 : // reference to aFrame.
612 : gfxSize GetScaleValue(const nsIFrame* aFrame) const;
613 :
614 : // Uncompute this AnimationValue and then serialize it.
615 : void SerializeSpecifiedValue(nsCSSPropertyID aProperty,
616 : nsAString& aString) const;
617 :
618 : // Check if |*this| and |aToValue| can be interpolated.
619 : bool IsInterpolableWith(nsCSSPropertyID aProperty,
620 : const AnimationValue& aToValue) const;
621 :
622 : // Compute the distance between *this and aOther.
623 : // If |aStyleContext| is nullptr, we will return 0.0 if we have mismatched
624 : // transform lists.
625 : double ComputeDistance(nsCSSPropertyID aProperty,
626 : const AnimationValue& aOther,
627 : nsStyleContext* aStyleContext) const;
628 :
629 : // Create an AnimaitonValue from a string. This method flushes style, so we
630 : // should use this carefully. Now, it is only used by
631 : // nsDOMWindowUtils::ComputeAnimationDistance.
632 : static AnimationValue FromString(nsCSSPropertyID aProperty,
633 : const nsAString& aValue,
634 : dom::Element* aElement);
635 :
636 : // mGecko and mServo are mutually exclusive: only one or the other should
637 : // ever be set.
638 : // FIXME: After obsoleting StyleAnimationValue, we should remove mGecko, and
639 : // make AnimationValue a wrapper of RawServoAnimationValue to hide these
640 : // FFIs.
641 : StyleAnimationValue mGecko;
642 : RefPtr<RawServoAnimationValue> mServo;
643 : };
644 :
645 64 : struct PropertyStyleAnimationValuePair
646 : {
647 : nsCSSPropertyID mProperty;
648 : AnimationValue mValue;
649 : };
650 : } // namespace mozilla
651 :
652 : #endif
|