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/. */ 6 7 #ifndef mozilla_ComputedTimingFunction_h 8 #define mozilla_ComputedTimingFunction_h 9 10 #include "nsDebug.h" 11 #include "nsStringFwd.h" 12 #include "nsTimingFunction.h" 13 14 #include "mozilla/Assertions.h" 15 #include "mozilla/Maybe.h" 16 #include "mozilla/SMILKeySpline.h" 17 18 namespace mozilla { 19 20 class ComputedTimingFunction { 21 public: 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() 30 }; 31 32 struct StepFunc { 33 uint32_t mSteps; 34 StyleStepPosition mPos; 35 bool operator==(const StepFunc& aOther) const { 36 return mSteps == aOther.mSteps && mPos == aOther.mPos; 37 } 38 }; 39 CubicBezier(double x1,double y1,double x2,double y2)40 static ComputedTimingFunction CubicBezier(double x1, double y1, double x2, 41 double y2) { 42 return ComputedTimingFunction(x1, y1, x2, y2); 43 } Steps(uint32_t aSteps,StyleStepPosition aPos)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); 47 } 48 49 ComputedTimingFunction() = default; ComputedTimingFunction(const nsTimingFunction & aFunction)50 explicit ComputedTimingFunction(const nsTimingFunction& aFunction) { 51 Init(aFunction); 52 } 53 void Init(const nsTimingFunction& aFunction); 54 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; GetFunction()59 const SMILKeySpline* GetFunction() const { 60 NS_ASSERTION(HasSpline(), "Type mismatch"); 61 return &mTimingFunction; 62 } GetType()63 Type GetType() const { return mType; } HasSpline()64 bool HasSpline() const { return mType != Type::Step; } GetSteps()65 const StepFunc& GetSteps() const { 66 MOZ_ASSERT(mType == Type::Step); 67 return mSteps; 68 } 69 bool operator==(const ComputedTimingFunction& aOther) const { 70 return mType == aOther.mType && 71 (HasSpline() ? mTimingFunction == aOther.mTimingFunction 72 : mSteps == aOther.mSteps); 73 } 74 bool operator!=(const ComputedTimingFunction& aOther) const { 75 return !(*this == aOther); 76 } 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; 89 default: 90 return false; 91 } 92 } 93 bool operator!=(const nsTimingFunction& aOther) const { 94 return !(*this == aOther); 95 } 96 int32_t Compare(const ComputedTimingFunction& aRhs) const; 97 void AppendToString(nsACString& aResult) const; 98 GetPortion(const Maybe<ComputedTimingFunction> & aFunction,double aPortion,BeforeFlag aBeforeFlag)99 static double GetPortion(const Maybe<ComputedTimingFunction>& aFunction, 100 double aPortion, BeforeFlag aBeforeFlag) { 101 return aFunction ? aFunction->GetValue(aPortion, aBeforeFlag) : aPortion; 102 } 103 static int32_t Compare(const Maybe<ComputedTimingFunction>& aLhs, 104 const Maybe<ComputedTimingFunction>& aRhs); 105 106 private: ComputedTimingFunction(double x1,double y1,double x2,double y2)107 ComputedTimingFunction(double x1, double y1, double x2, double y2) 108 : mType(Type::CubicBezier), mTimingFunction(x1, y1, x2, y2) {} ComputedTimingFunction(uint32_t aSteps,StyleStepPosition aPos)109 ComputedTimingFunction(uint32_t aSteps, StyleStepPosition aPos) 110 : mType(Type::Step), mSteps{aSteps, aPos} {} 111 112 Type mType; 113 SMILKeySpline mTimingFunction; 114 StepFunc mSteps; 115 }; 116 117 inline bool operator==(const Maybe<ComputedTimingFunction>& aLHS, 118 const nsTimingFunction& aRHS) { 119 if (aLHS.isNothing()) { 120 return aRHS.IsLinear(); 121 } 122 return aLHS.value() == aRHS; 123 } 124 125 inline bool operator!=(const Maybe<ComputedTimingFunction>& aLHS, 126 const nsTimingFunction& aRHS) { 127 return !(aLHS == aRHS); 128 } 129 130 } // namespace mozilla 131 132 #endif // mozilla_ComputedTimingFunction_h 133