LCOV - code coverage report
Current view: top level - dom/smil - nsSMILAnimationFunction.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 54 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 19 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef NS_SMILANIMATIONFUNCTION_H_
       8             : #define NS_SMILANIMATIONFUNCTION_H_
       9             : 
      10             : #include "nsISMILAttr.h"
      11             : #include "nsGkAtoms.h"
      12             : #include "nsString.h"
      13             : #include "nsSMILTargetIdentifier.h"
      14             : #include "nsSMILTimeValue.h"
      15             : #include "nsSMILKeySpline.h"
      16             : #include "nsSMILValue.h"
      17             : #include "nsTArray.h"
      18             : #include "nsAttrValue.h"
      19             : #include "nsSMILTypes.h"
      20             : 
      21             : namespace mozilla {
      22             : namespace dom {
      23             : class SVGAnimationElement;
      24             : } // namespace dom
      25             : } // namespace mozilla
      26             : 
      27             : //----------------------------------------------------------------------
      28             : // nsSMILAnimationFunction
      29             : //
      30             : // The animation function calculates animation values. It it is provided with
      31             : // time parameters (sample time, repeat iteration etc.) and it uses this to
      32             : // build an appropriate animation value by performing interpolation and
      33             : // addition operations.
      34             : //
      35             : // It is responsible for implementing the animation parameters of an animation
      36             : // element (e.g. from, by, to, values, calcMode, additive, accumulate, keyTimes,
      37             : // keySplines)
      38             : //
      39           0 : class nsSMILAnimationFunction
      40             : {
      41             : public:
      42             :   nsSMILAnimationFunction();
      43             : 
      44             :   /*
      45             :    * Sets the owning animation element which this class uses to query attribute
      46             :    * values and compare document positions.
      47             :    */
      48             :   void SetAnimationElement(mozilla::dom::SVGAnimationElement* aAnimationElement);
      49             : 
      50             :   /*
      51             :    * Sets animation-specific attributes (or marks them dirty, in the case
      52             :    * of from/to/by/values).
      53             :    *
      54             :    * @param aAttribute The attribute being set
      55             :    * @param aValue     The updated value of the attribute.
      56             :    * @param aResult    The nsAttrValue object that may be used for storing the
      57             :    *                   parsed result.
      58             :    * @param aParseResult  Outparam used for reporting parse errors. Will be set
      59             :    *                      to NS_OK if everything succeeds.
      60             :    * @return  true if aAttribute is a recognized animation-related
      61             :    *          attribute; false otherwise.
      62             :    */
      63             :   virtual bool SetAttr(nsIAtom* aAttribute, const nsAString& aValue,
      64             :                          nsAttrValue& aResult, nsresult* aParseResult = nullptr);
      65             : 
      66             :   /*
      67             :    * Unsets the given attribute.
      68             :    *
      69             :    * @returns true if aAttribute is a recognized animation-related
      70             :    *          attribute; false otherwise.
      71             :    */
      72             :   virtual bool UnsetAttr(nsIAtom* aAttribute);
      73             : 
      74             :   /**
      75             :    * Indicate a new sample has occurred.
      76             :    *
      77             :    * @param aSampleTime The sample time for this timed element expressed in
      78             :    *                    simple time.
      79             :    * @param aSimpleDuration The simple duration for this timed element.
      80             :    * @param aRepeatIteration  The repeat iteration for this sample. The first
      81             :    *                          iteration has a value of 0.
      82             :    */
      83             :   void SampleAt(nsSMILTime aSampleTime,
      84             :                 const nsSMILTimeValue& aSimpleDuration,
      85             :                 uint32_t aRepeatIteration);
      86             : 
      87             :   /**
      88             :    * Indicate to sample using the last value defined for the animation function.
      89             :    * This value is not normally sampled due to the end-point exclusive timing
      90             :    * model but only occurs when the fill mode is "freeze" and the active
      91             :    * duration is an even multiple of the simple duration.
      92             :    *
      93             :    * @param aRepeatIteration  The repeat iteration for this sample. The first
      94             :    *                          iteration has a value of 0.
      95             :    */
      96             :   void SampleLastValue(uint32_t aRepeatIteration);
      97             : 
      98             :   /**
      99             :    * Indicate that this animation is now active. This is used to instruct the
     100             :    * animation function that it should now add its result to the animation
     101             :    * sandwich. The begin time is also provided for proper prioritization of
     102             :    * animation functions, and for this reason, this method must be called
     103             :    * before either of the Sample methods.
     104             :    *
     105             :    * @param aBeginTime The begin time for the newly active interval.
     106             :    */
     107             :   void Activate(nsSMILTime aBeginTime);
     108             : 
     109             :   /**
     110             :    * Indicate that this animation is no longer active. This is used to instruct
     111             :    * the animation function that it should no longer add its result to the
     112             :    * animation sandwich.
     113             :    *
     114             :    * @param aIsFrozen true if this animation should continue to contribute
     115             :    *                  to the animation sandwich using the most recent sample
     116             :    *                  parameters.
     117             :    */
     118             :   void Inactivate(bool aIsFrozen);
     119             : 
     120             :   /**
     121             :    * Combines the result of this animation function for the last sample with the
     122             :    * specified value.
     123             :    *
     124             :    * @param aSMILAttr This animation's target attribute. Used here for
     125             :    *                  doing attribute-specific parsing of from/to/by/values.
     126             :    *
     127             :    * @param aResult   The value to compose with.
     128             :    */
     129             :   void ComposeResult(const nsISMILAttr& aSMILAttr, nsSMILValue& aResult);
     130             : 
     131             :   /**
     132             :    * Returns the relative priority of this animation to another. The priority is
     133             :    * used for determining the position of the animation in the animation
     134             :    * sandwich -- higher priority animations are applied on top of lower
     135             :    * priority animations.
     136             :    *
     137             :    * @return  -1 if this animation has lower priority or 1 if this animation has
     138             :    *          higher priority
     139             :    *
     140             :    * This method should never return any other value, including 0.
     141             :    */
     142             :   int8_t CompareTo(const nsSMILAnimationFunction* aOther) const;
     143             : 
     144             :   /*
     145             :    * The following methods are provided so that the compositor can optimize its
     146             :    * operations by only composing those animation that will affect the final
     147             :    * result.
     148             :    */
     149             : 
     150             :   /**
     151             :    * Indicates if the animation is currently active or frozen. Inactive
     152             :    * animations will not contribute to the composed result.
     153             :    *
     154             :    * @return  true if the animation is active or frozen, false otherwise.
     155             :    */
     156           0 :   bool IsActiveOrFrozen() const
     157             :   {
     158             :     /*
     159             :      * - Frozen animations should be considered active for the purposes of
     160             :      * compositing.
     161             :      * - This function does not assume that our nsSMILValues (by/from/to/values)
     162             :      * have already been parsed.
     163             :      */
     164           0 :     return (mIsActive || mIsFrozen);
     165             :   }
     166             : 
     167             :   /**
     168             :    * Indicates if the animation is active.
     169             :    *
     170             :    * @return  true if the animation is active, false otherwise.
     171             :    */
     172           0 :   bool IsActive() const {
     173           0 :     return mIsActive;
     174             :   }
     175             : 
     176             :   /**
     177             :    * Indicates if this animation will replace the passed in result rather than
     178             :    * adding to it. Animations that replace the underlying value may be called
     179             :    * without first calling lower priority animations.
     180             :    *
     181             :    * @return  True if the animation will replace, false if it will add or
     182             :    *          otherwise build on the passed in value.
     183             :    */
     184             :   virtual bool WillReplace() const;
     185             : 
     186             :   /**
     187             :    * Indicates if the parameters for this animation have changed since the last
     188             :    * time it was composited. This allows rendering to be performed only when
     189             :    * necessary, particularly when no animations are active.
     190             :    *
     191             :    * Note that the caller is responsible for determining if the animation
     192             :    * target has changed (with help from my UpdateCachedTarget() method).
     193             :    *
     194             :    * @return  true if the animation parameters have changed, false
     195             :    *          otherwise.
     196             :    */
     197             :   bool HasChanged() const;
     198             : 
     199             :   /**
     200             :    * This method lets us clear the 'HasChanged' flag for inactive animations
     201             :    * after we've reacted to their change to the 'inactive' state, so that we
     202             :    * won't needlessly recompose their targets in every sample.
     203             :    *
     204             :    * This should only be called on an animation function that is inactive and
     205             :    * that returns true from HasChanged().
     206             :    */
     207           0 :   void ClearHasChanged()
     208             :   {
     209           0 :     MOZ_ASSERT(HasChanged(),
     210             :                "clearing mHasChanged flag, when it's already false");
     211           0 :     MOZ_ASSERT(!IsActiveOrFrozen(),
     212             :                "clearing mHasChanged flag for active animation");
     213           0 :     mHasChanged = false;
     214           0 :   }
     215             : 
     216             :   /**
     217             :    * Updates the cached record of our animation target, and returns a boolean
     218             :    * that indicates whether the target has changed since the last call to this
     219             :    * function. (This lets nsSMILCompositor check whether its animation
     220             :    * functions have changed value or target since the last sample.  If none of
     221             :    * them have, then the compositor doesn't need to do anything.)
     222             :    *
     223             :    * @param aNewTarget A nsSMILTargetIdentifier representing the animation
     224             :    *                   target of this function for this sample.
     225             :    * @return  true if |aNewTarget| is different from the old cached value;
     226             :    *          otherwise, false.
     227             :    */
     228             :   bool UpdateCachedTarget(const nsSMILTargetIdentifier& aNewTarget);
     229             : 
     230             :   /**
     231             :    * Returns true if this function was skipped in the previous sample (because
     232             :    * there was a higher-priority non-additive animation). If a skipped animation
     233             :    * function is later used, then the animation sandwich must be recomposited.
     234             :    */
     235           0 :   bool WasSkippedInPrevSample() const {
     236           0 :     return mWasSkippedInPrevSample;
     237             :   }
     238             : 
     239             :   /**
     240             :    * Mark this animation function as having been skipped. By marking the
     241             :    * function as skipped, if it is used in a subsequent sample we'll know to
     242             :    * recomposite the sandwich.
     243             :    */
     244           0 :   void SetWasSkipped() {
     245           0 :     mWasSkippedInPrevSample = true;
     246           0 :   }
     247             : 
     248             :   /**
     249             :    * Returns true if we need to recalculate the animation value on every sample.
     250             :    * (e.g. because it depends on context like the font-size)
     251             :    */
     252           0 :   bool ValueNeedsReparsingEverySample() const {
     253           0 :     return mValueNeedsReparsingEverySample;
     254             :   }
     255             : 
     256             :   // Comparator utility class, used for sorting nsSMILAnimationFunctions
     257             :   class Comparator {
     258             :     public:
     259           0 :       bool Equals(const nsSMILAnimationFunction* aElem1,
     260             :                     const nsSMILAnimationFunction* aElem2) const {
     261           0 :         return (aElem1->CompareTo(aElem2) == 0);
     262             :       }
     263           0 :       bool LessThan(const nsSMILAnimationFunction* aElem1,
     264             :                       const nsSMILAnimationFunction* aElem2) const {
     265           0 :         return (aElem1->CompareTo(aElem2) < 0);
     266             :       }
     267             :   };
     268             : 
     269             : protected:
     270             :   // Typedefs
     271             :   typedef FallibleTArray<nsSMILValue> nsSMILValueArray;
     272             : 
     273             :   // Types
     274             :   enum nsSMILCalcMode : uint8_t
     275             :   {
     276             :     CALC_LINEAR,
     277             :     CALC_DISCRETE,
     278             :     CALC_PACED,
     279             :     CALC_SPLINE
     280             :   };
     281             : 
     282             :   // Used for sorting nsSMILAnimationFunctions
     283           0 :   nsSMILTime GetBeginTime() const { return mBeginTime; }
     284             : 
     285             :   // Property getters
     286             :   bool                   GetAccumulate() const;
     287             :   bool                   GetAdditive() const;
     288             :   virtual nsSMILCalcMode GetCalcMode() const;
     289             : 
     290             :   // Property setters
     291             :   nsresult SetAccumulate(const nsAString& aAccumulate, nsAttrValue& aResult);
     292             :   nsresult SetAdditive(const nsAString& aAdditive, nsAttrValue& aResult);
     293             :   nsresult SetCalcMode(const nsAString& aCalcMode, nsAttrValue& aResult);
     294             :   nsresult SetKeyTimes(const nsAString& aKeyTimes, nsAttrValue& aResult);
     295             :   nsresult SetKeySplines(const nsAString& aKeySplines, nsAttrValue& aResult);
     296             : 
     297             :   // Property un-setters
     298             :   void     UnsetAccumulate();
     299             :   void     UnsetAdditive();
     300             :   void     UnsetCalcMode();
     301             :   void     UnsetKeyTimes();
     302             :   void     UnsetKeySplines();
     303             : 
     304             :   // Helpers
     305             :   virtual nsresult InterpolateResult(const nsSMILValueArray& aValues,
     306             :                                      nsSMILValue& aResult,
     307             :                                      nsSMILValue& aBaseValue);
     308             :   nsresult AccumulateResult(const nsSMILValueArray& aValues,
     309             :                             nsSMILValue& aResult);
     310             : 
     311             :   nsresult ComputePacedPosition(const nsSMILValueArray& aValues,
     312             :                                 double aSimpleProgress,
     313             :                                 double& aIntervalProgress,
     314             :                                 const nsSMILValue*& aFrom,
     315             :                                 const nsSMILValue*& aTo);
     316             :   double   ComputePacedTotalDistance(const nsSMILValueArray& aValues) const;
     317             : 
     318             :   /**
     319             :    * Adjust the simple progress, that is, the point within the simple duration,
     320             :    * by applying any keyTimes.
     321             :    */
     322             :   double   ScaleSimpleProgress(double aProgress, nsSMILCalcMode aCalcMode);
     323             :   /**
     324             :    * Adjust the progress within an interval, that is, between two animation
     325             :    * values, by applying any keySplines.
     326             :    */
     327             :   double   ScaleIntervalProgress(double aProgress, uint32_t aIntervalIndex);
     328             : 
     329             :   // Convenience attribute getters -- use these instead of querying
     330             :   // mAnimationElement as these may need to be overridden by subclasses
     331             :   virtual bool               HasAttr(nsIAtom* aAttName) const;
     332             :   virtual const nsAttrValue* GetAttr(nsIAtom* aAttName) const;
     333             :   virtual bool               GetAttr(nsIAtom* aAttName,
     334             :                                      nsAString& aResult) const;
     335             : 
     336             :   bool     ParseAttr(nsIAtom* aAttName, const nsISMILAttr& aSMILAttr,
     337             :                      nsSMILValue& aResult,
     338             :                      bool& aPreventCachingOfSandwich) const;
     339             : 
     340             :   virtual nsresult GetValues(const nsISMILAttr& aSMILAttr,
     341             :                              nsSMILValueArray& aResult);
     342             : 
     343             :   virtual void CheckValueListDependentAttrs(uint32_t aNumValues);
     344             :   void         CheckKeyTimes(uint32_t aNumValues);
     345             :   void         CheckKeySplines(uint32_t aNumValues);
     346             : 
     347           0 :   virtual bool IsToAnimation() const {
     348           0 :     return !HasAttr(nsGkAtoms::values) &&
     349           0 :             HasAttr(nsGkAtoms::to) &&
     350           0 :            !HasAttr(nsGkAtoms::from);
     351             :   }
     352             : 
     353             :   // Returns true if we know our composited value won't change over the
     354             :   // simple duration of this animation (for a fixed base value).
     355             :   virtual bool IsValueFixedForSimpleDuration() const;
     356             : 
     357           0 :   inline bool IsAdditive() const {
     358             :     /*
     359             :      * Animation is additive if:
     360             :      *
     361             :      * (1) additive = "sum" (GetAdditive() == true), or
     362             :      * (2) it is 'by animation' (by is set, from and values are not)
     363             :      *
     364             :      * Although animation is not additive if it is 'to animation'
     365             :      */
     366           0 :     bool isByAnimation = (!HasAttr(nsGkAtoms::values) &&
     367           0 :                              HasAttr(nsGkAtoms::by) &&
     368           0 :                             !HasAttr(nsGkAtoms::from));
     369           0 :     return !IsToAnimation() && (GetAdditive() || isByAnimation);
     370             :   }
     371             : 
     372             :   // Setters for error flags
     373             :   // These correspond to bit-indices in mErrorFlags, for tracking parse errors
     374             :   // in these attributes, when those parse errors should block us from doing
     375             :   // animation.
     376             :   enum AnimationAttributeIdx {
     377             :     BF_ACCUMULATE  = 0,
     378             :     BF_ADDITIVE    = 1,
     379             :     BF_CALC_MODE   = 2,
     380             :     BF_KEY_TIMES   = 3,
     381             :     BF_KEY_SPLINES = 4,
     382             :     BF_KEY_POINTS  = 5 // <animateMotion> only
     383             :   };
     384             : 
     385           0 :   inline void SetAccumulateErrorFlag(bool aNewValue) {
     386           0 :     SetErrorFlag(BF_ACCUMULATE, aNewValue);
     387           0 :   }
     388           0 :   inline void SetAdditiveErrorFlag(bool aNewValue) {
     389           0 :     SetErrorFlag(BF_ADDITIVE, aNewValue);
     390           0 :   }
     391           0 :   inline void SetCalcModeErrorFlag(bool aNewValue) {
     392           0 :     SetErrorFlag(BF_CALC_MODE, aNewValue);
     393           0 :   }
     394           0 :   inline void SetKeyTimesErrorFlag(bool aNewValue) {
     395           0 :     SetErrorFlag(BF_KEY_TIMES, aNewValue);
     396           0 :   }
     397           0 :   inline void SetKeySplinesErrorFlag(bool aNewValue) {
     398           0 :     SetErrorFlag(BF_KEY_SPLINES, aNewValue);
     399           0 :   }
     400           0 :   inline void SetKeyPointsErrorFlag(bool aNewValue) {
     401           0 :     SetErrorFlag(BF_KEY_POINTS, aNewValue);
     402           0 :   }
     403           0 :   inline void SetErrorFlag(AnimationAttributeIdx aField, bool aValue) {
     404           0 :     if (aValue) {
     405           0 :       mErrorFlags |=  (0x01 << aField);
     406             :     } else {
     407           0 :       mErrorFlags &= ~(0x01 << aField);
     408             :     }
     409           0 :   }
     410             : 
     411             :   // Members
     412             :   // -------
     413             : 
     414             :   static nsAttrValue::EnumTable sAdditiveTable[];
     415             :   static nsAttrValue::EnumTable sCalcModeTable[];
     416             :   static nsAttrValue::EnumTable sAccumulateTable[];
     417             : 
     418             :   FallibleTArray<double>          mKeyTimes;
     419             :   FallibleTArray<nsSMILKeySpline> mKeySplines;
     420             : 
     421             :   // These are the parameters provided by the previous sample. Currently we
     422             :   // perform lazy calculation. That is, we only calculate the result if and when
     423             :   // instructed by the compositor. This allows us to apply the result directly
     424             :   // to the animation value and allows the compositor to filter out functions
     425             :   // that it determines will not contribute to the final result.
     426             :   nsSMILTime                    mSampleTime; // sample time within simple dur
     427             :   nsSMILTimeValue               mSimpleDuration;
     428             :   uint32_t                      mRepeatIteration;
     429             : 
     430             :   nsSMILTime                    mBeginTime; // document time
     431             : 
     432             :   // The owning animation element. This is used for sorting based on document
     433             :   // position and for fetching attribute values stored in the element.
     434             :   // Raw pointer is OK here, because this nsSMILAnimationFunction can't outlive
     435             :   // its owning animation element.
     436             :   mozilla::dom::SVGAnimationElement* mAnimationElement;
     437             : 
     438             :   // Which attributes have been set but have had errors. This is not used for
     439             :   // all attributes but only those which have specified error behaviour
     440             :   // associated with them.
     441             :   uint16_t                      mErrorFlags;
     442             : 
     443             :   // Allows us to check whether an animation function has changed target from
     444             :   // sample to sample (because if neither target nor animated value have
     445             :   // changed, we don't have to do anything).
     446             :   nsSMILWeakTargetIdentifier    mLastTarget;
     447             : 
     448             :   // Boolean flags
     449             :   bool mIsActive:1;
     450             :   bool mIsFrozen:1;
     451             :   bool mLastValue:1;
     452             :   bool mHasChanged:1;
     453             :   bool mValueNeedsReparsingEverySample:1;
     454             :   bool mPrevSampleWasSingleValueAnimation:1;
     455             :   bool mWasSkippedInPrevSample:1;
     456             : };
     457             : 
     458             : #endif // NS_SMILANIMATIONFUNCTION_H_

Generated by: LCOV version 1.13