1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_ComputedTimingFunction_h
8 #define mozilla_ComputedTimingFunction_h
11 #include "nsStringFwd.h"
12 #include "nsTimingFunction.h"
14 #include "mozilla/Assertions.h"
15 #include "mozilla/Maybe.h"
16 #include "mozilla/SMILKeySpline.h"
20 class ComputedTimingFunction
{
22 enum class Type
: uint8_t {
23 Ease
= uint8_t(StyleTimingKeyword::Ease
), // ease
24 Linear
= uint8_t(StyleTimingKeyword::Linear
), // linear
25 EaseIn
= uint8_t(StyleTimingKeyword::EaseIn
), // ease-in
26 EaseOut
= uint8_t(StyleTimingKeyword::EaseOut
), // ease-out
27 EaseInOut
= uint8_t(StyleTimingKeyword::EaseInOut
), // ease-in-out
28 CubicBezier
, // cubic-bezier()
29 Step
, // step-start | step-end | steps()
34 StyleStepPosition mPos
;
35 bool operator==(const StepFunc
& aOther
) const {
36 return mSteps
== aOther
.mSteps
&& mPos
== aOther
.mPos
;
40 static ComputedTimingFunction
CubicBezier(double x1
, double y1
, double x2
,
42 return ComputedTimingFunction(x1
, y1
, x2
, y2
);
44 static ComputedTimingFunction
Steps(uint32_t aSteps
, StyleStepPosition aPos
) {
45 MOZ_ASSERT(aSteps
> 0, "The number of steps should be 1 or more");
46 return ComputedTimingFunction(aSteps
, aPos
);
49 ComputedTimingFunction() = default;
50 explicit ComputedTimingFunction(const nsTimingFunction
& aFunction
) {
53 void Init(const nsTimingFunction
& aFunction
);
55 // BeforeFlag is used in step timing function.
56 // https://drafts.csswg.org/css-easing/#before-flag
57 enum class BeforeFlag
{ Unset
, Set
};
58 double GetValue(double aPortion
, BeforeFlag aBeforeFlag
) const;
59 const SMILKeySpline
* GetFunction() const {
60 NS_ASSERTION(HasSpline(), "Type mismatch");
61 return &mTimingFunction
;
63 Type
GetType() const { return mType
; }
64 bool HasSpline() const { return mType
!= Type::Step
; }
65 const StepFunc
& GetSteps() const {
66 MOZ_ASSERT(mType
== Type::Step
);
69 bool operator==(const ComputedTimingFunction
& aOther
) const {
70 return mType
== aOther
.mType
&&
71 (HasSpline() ? mTimingFunction
== aOther
.mTimingFunction
72 : mSteps
== aOther
.mSteps
);
74 bool operator!=(const ComputedTimingFunction
& aOther
) const {
75 return !(*this == aOther
);
77 bool operator==(const nsTimingFunction
& aOther
) const {
78 switch (aOther
.mTiming
.tag
) {
79 case StyleComputedTimingFunction::Tag::Keyword
:
80 return uint8_t(mType
) == uint8_t(aOther
.mTiming
.keyword
._0
);
81 case StyleComputedTimingFunction::Tag::CubicBezier
:
82 return mTimingFunction
.X1() == aOther
.mTiming
.cubic_bezier
.x1
&&
83 mTimingFunction
.Y1() == aOther
.mTiming
.cubic_bezier
.y1
&&
84 mTimingFunction
.X2() == aOther
.mTiming
.cubic_bezier
.x2
&&
85 mTimingFunction
.Y2() == aOther
.mTiming
.cubic_bezier
.y2
;
86 case StyleComputedTimingFunction::Tag::Steps
:
87 return mSteps
.mSteps
== uint32_t(aOther
.mTiming
.steps
._0
) &&
88 mSteps
.mPos
== aOther
.mTiming
.steps
._1
;
93 bool operator!=(const nsTimingFunction
& aOther
) const {
94 return !(*this == aOther
);
96 int32_t Compare(const ComputedTimingFunction
& aRhs
) const;
97 void AppendToString(nsACString
& aResult
) const;
99 static double GetPortion(const Maybe
<ComputedTimingFunction
>& aFunction
,
100 double aPortion
, BeforeFlag aBeforeFlag
) {
101 return aFunction
? aFunction
->GetValue(aPortion
, aBeforeFlag
) : aPortion
;
103 static int32_t Compare(const Maybe
<ComputedTimingFunction
>& aLhs
,
104 const Maybe
<ComputedTimingFunction
>& aRhs
);
107 ComputedTimingFunction(double x1
, double y1
, double x2
, double y2
)
108 : mType(Type::CubicBezier
), mTimingFunction(x1
, y1
, x2
, y2
) {}
109 ComputedTimingFunction(uint32_t aSteps
, StyleStepPosition aPos
)
110 : mType(Type::Step
), mSteps
{aSteps
, aPos
} {}
113 SMILKeySpline mTimingFunction
;
117 inline bool operator==(const Maybe
<ComputedTimingFunction
>& aLHS
,
118 const nsTimingFunction
& aRHS
) {
119 if (aLHS
.isNothing()) {
120 return aRHS
.IsLinear();
122 return aLHS
.value() == aRHS
;
125 inline bool operator!=(const Maybe
<ComputedTimingFunction
>& aLHS
,
126 const nsTimingFunction
& aRHS
) {
127 return !(aLHS
== aRHS
);
130 } // namespace mozilla
132 #endif // mozilla_ComputedTimingFunction_h