mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-24 16:54:08 +00:00
365 lines
14 KiB
C++
365 lines
14 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
* http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
* for the specific language governing rights and limitations under the
|
|
* License.
|
|
*
|
|
* The Original Code is the Mozilla SMIL module.
|
|
*
|
|
* The Initial Developer of the Original Code is Brian Birtles.
|
|
* Portions created by the Initial Developer are Copyright (C) 2005
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Brian Birtles <birtles@gmail.com>
|
|
* Daniel Holbert <dholbert@mozilla.com>
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
* the provisions above, a recipient may use your version of this file under
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
#ifndef NS_SMILANIMATIONFUNCTION_H_
|
|
#define NS_SMILANIMATIONFUNCTION_H_
|
|
|
|
#include "nsISMILAttr.h"
|
|
#include "nsGkAtoms.h"
|
|
#include "nsString.h"
|
|
#include "nsSMILTimeValue.h"
|
|
#include "nsSMILKeySpline.h"
|
|
#include "nsSMILValue.h"
|
|
#include "nsAutoPtr.h"
|
|
#include "nsTArray.h"
|
|
#include "nsAttrValue.h"
|
|
#include "nsSMILTypes.h"
|
|
|
|
class nsISMILAnimationElement;
|
|
|
|
//----------------------------------------------------------------------
|
|
// nsSMILAnimationFunction
|
|
//
|
|
// The animation function calculates animation values. It it is provided with
|
|
// time parameters (sample time, repeat iteration etc.) and it uses this to
|
|
// build an appropriate animation value by performing interpolation and
|
|
// addition operations.
|
|
//
|
|
// It is responsible for implementing the animation parameters of an animation
|
|
// element (e.g. from, by, to, values, calcMode, additive, accumulate, keyTimes,
|
|
// keySplines)
|
|
//
|
|
class nsSMILAnimationFunction
|
|
{
|
|
public:
|
|
nsSMILAnimationFunction();
|
|
|
|
/*
|
|
* Sets the owning animation element which this class uses to query attribute
|
|
* values and compare document positions.
|
|
*/
|
|
void SetAnimationElement(nsISMILAnimationElement* aAnimationElement);
|
|
|
|
/*
|
|
* Sets animation-specific attributes (or marks them dirty, in the case
|
|
* of from/to/by/values).
|
|
*
|
|
* @param aAttribute The attribute being set
|
|
* @param aValue The updated value of the attribute.
|
|
* @param aResult The nsAttrValue object that may be used for storing the
|
|
* parsed result.
|
|
* @param aParseResult Outparam used for reporting parse errors. Will be set
|
|
* to NS_OK if everything succeeds.
|
|
* @returns PR_TRUE if aAttribute is a recognized animation-related
|
|
* attribute; PR_FALSE otherwise.
|
|
*/
|
|
virtual PRBool SetAttr(nsIAtom* aAttribute, const nsAString& aValue,
|
|
nsAttrValue& aResult, nsresult* aParseResult = nsnull);
|
|
|
|
/*
|
|
* Unsets the given attribute.
|
|
*
|
|
* @returns PR_TRUE if aAttribute is a recognized animation-related
|
|
* attribute; PR_FALSE otherwise.
|
|
*/
|
|
virtual PRBool UnsetAttr(nsIAtom* aAttribute);
|
|
|
|
/**
|
|
* Indicate a new sample has occurred.
|
|
*
|
|
* @param aSampleTime The sample time for this timed element expressed in
|
|
* simple time.
|
|
* @param aSimpleDuration The simple duration for this timed element.
|
|
* @param aRepeatIteration The repeat iteration for this sample. The first
|
|
* iteration has a value of 0.
|
|
*/
|
|
void SampleAt(nsSMILTime aSampleTime,
|
|
const nsSMILTimeValue& aSimpleDuration,
|
|
PRUint32 aRepeatIteration);
|
|
|
|
/**
|
|
* Indicate to sample using the last value defined for the animation function.
|
|
* This value is not normally sampled due to the end-point exclusive timing
|
|
* model but only occurs when the fill mode is "freeze" and the active
|
|
* duration is an even multiple of the simple duration.
|
|
*
|
|
* @param aRepeatIteration The repeat iteration for this sample. The first
|
|
* iteration has a value of 0.
|
|
*/
|
|
void SampleLastValue(PRUint32 aRepeatIteration);
|
|
|
|
/**
|
|
* Indicate that this animation is now active. This is used to instruct the
|
|
* animation function that it should now add its result to the animation
|
|
* sandwich. The begin time is also provided for proper prioritization of
|
|
* animation functions, and for this reason, this method must be called
|
|
* before either of the Sample methods.
|
|
*
|
|
* @param aBeginTime The begin time for the newly active interval.
|
|
*/
|
|
void Activate(nsSMILTime aBeginTime);
|
|
|
|
/**
|
|
* Indicate that this animation is no longer active. This is used to instruct
|
|
* the animation function that it should no longer add its result to the
|
|
* animation sandwich.
|
|
*
|
|
* @param aIsFrozen True if this animation should continue to contribute to
|
|
* the animation sandwich using the most recent sample
|
|
* parameters.
|
|
*/
|
|
void Inactivate(PRBool aIsFrozen);
|
|
|
|
/**
|
|
* Combines the result of this animation function for the last sample with the
|
|
* specified value.
|
|
*
|
|
* @param aSMILAttr This animation's target attribute. Used here for
|
|
* doing attribute-specific parsing of from/to/by/values.
|
|
*
|
|
* @param aResult The value to compose with.
|
|
*/
|
|
void ComposeResult(const nsISMILAttr& aSMILAttr, nsSMILValue& aResult);
|
|
|
|
/**
|
|
* Returns the relative priority of this animation to another. The priority is
|
|
* used for determining the position of the animation in the animation
|
|
* sandwich -- higher priority animations are applied on top of lower
|
|
* priority animations.
|
|
*
|
|
* @return -1 if this animation has lower priority or 1 if this animation has
|
|
* higher priority
|
|
*
|
|
* This method should never return any other value, including 0.
|
|
*/
|
|
PRInt8 CompareTo(const nsSMILAnimationFunction* aOther) const;
|
|
|
|
/*
|
|
* The following methods are provided so that the compositor can optimize its
|
|
* operations by only composing those animation that will affect the final
|
|
* result.
|
|
*/
|
|
|
|
/**
|
|
* Indicates if the animation is currently active. Inactive animations will
|
|
* not contribute to the composed result.
|
|
*
|
|
* @return True if the animation active, false otherwise.
|
|
*/
|
|
PRBool IsActive() const
|
|
{
|
|
/*
|
|
* - Frozen animations should be considered active for the purposes of
|
|
* compositing.
|
|
* - This function does not assume that our nsSMILValues (by/from/to/values)
|
|
* have already been parsed.
|
|
*/
|
|
return (mIsActive || mIsFrozen);
|
|
}
|
|
|
|
/**
|
|
* Indicates if this animation will replace the passed in result rather than
|
|
* adding to it. Animations that replace the underlying value may be called
|
|
* without first calling lower priority animations.
|
|
*
|
|
* @return True if the animation will replace, false if it will add or
|
|
* otherwise build on the passed in value.
|
|
*/
|
|
PRBool WillReplace() const;
|
|
|
|
/**
|
|
* Indicates if the parameters for this animation have changed since the last
|
|
* time it was composited. This allows rendering to be performed only when
|
|
* necessary, particularly when no animations are active.
|
|
*
|
|
* Note that the caller is responsible for determining if the animation target
|
|
* has changed.
|
|
*
|
|
* @return True if the animation parameters have changed, false otherwise.
|
|
*/
|
|
PRBool HasChanged() const;
|
|
|
|
// Comparator utility class, used for sorting nsSMILAnimationFunctions
|
|
class Comparator {
|
|
public:
|
|
PRBool Equals(const nsSMILAnimationFunction* aElem1,
|
|
const nsSMILAnimationFunction* aElem2) const {
|
|
return (aElem1->CompareTo(aElem2) == 0);
|
|
}
|
|
PRBool LessThan(const nsSMILAnimationFunction* aElem1,
|
|
const nsSMILAnimationFunction* aElem2) const {
|
|
return (aElem1->CompareTo(aElem2) < 0);
|
|
}
|
|
};
|
|
|
|
protected:
|
|
// Typedefs
|
|
typedef nsTArray<nsSMILValue> nsSMILValueArray;
|
|
|
|
// Types
|
|
enum nsSMILCalcMode
|
|
{
|
|
CALC_LINEAR,
|
|
CALC_DISCRETE,
|
|
CALC_PACED,
|
|
CALC_SPLINE
|
|
};
|
|
|
|
// Used for sorting nsSMILAnimationFunctions
|
|
nsSMILTime GetBeginTime() const { return mBeginTime; }
|
|
|
|
// Property getters
|
|
PRBool GetAccumulate() const;
|
|
PRBool GetAdditive() const;
|
|
virtual nsSMILCalcMode GetCalcMode() const;
|
|
|
|
// Property setters
|
|
nsresult SetAccumulate(const nsAString& aAccumulate, nsAttrValue& aResult);
|
|
nsresult SetAdditive(const nsAString& aAdditive, nsAttrValue& aResult);
|
|
nsresult SetCalcMode(const nsAString& aCalcMode, nsAttrValue& aResult);
|
|
nsresult SetKeyTimes(const nsAString& aKeyTimes, nsAttrValue& aResult);
|
|
nsresult SetKeySplines(const nsAString& aKeySplines, nsAttrValue& aResult);
|
|
|
|
// Property un-setters
|
|
void UnsetAccumulate();
|
|
void UnsetAdditive();
|
|
void UnsetCalcMode();
|
|
void UnsetKeyTimes();
|
|
void UnsetKeySplines();
|
|
|
|
// Helpers
|
|
nsresult InterpolateResult(const nsSMILValueArray& aValues,
|
|
nsSMILValue& aResult,
|
|
nsSMILValue& aBaseValue);
|
|
nsresult AccumulateResult(const nsSMILValueArray& aValues,
|
|
nsSMILValue& aResult);
|
|
|
|
nsresult ComputePacedPosition(const nsSMILValueArray& aValues,
|
|
double aSimpleProgress,
|
|
double& aIntervalProgress,
|
|
const nsSMILValue*& aFrom,
|
|
const nsSMILValue*& aTo);
|
|
double ComputePacedTotalDistance(const nsSMILValueArray& aValues) const;
|
|
|
|
void ScaleSimpleProgress(double& aProgress);
|
|
void ScaleIntervalProgress(double& aProgress, PRUint32 aIntervalIndex,
|
|
PRUint32 aNumIntervals);
|
|
|
|
// Convenience attribute getters -- use these instead of querying
|
|
// mAnimationElement as these may need to be overridden by subclasses
|
|
virtual PRBool HasAttr(nsIAtom* aAttName) const;
|
|
virtual const nsAttrValue* GetAttr(nsIAtom* aAttName) const;
|
|
virtual PRBool GetAttr(nsIAtom* aAttName,
|
|
nsAString& aResult) const;
|
|
|
|
PRBool ParseAttr(nsIAtom* aAttName, const nsISMILAttr& aSMILAttr,
|
|
nsSMILValue& aResult) const;
|
|
nsresult GetValues(const nsISMILAttr& aSMILAttr,
|
|
nsSMILValueArray& aResult);
|
|
void UpdateValuesArray();
|
|
PRBool IsToAnimation() const;
|
|
PRBool IsAdditive() const;
|
|
void CheckKeyTimes(PRUint32 aNumValues);
|
|
void CheckKeySplines(PRUint32 aNumValues);
|
|
|
|
|
|
// Members
|
|
// -------
|
|
|
|
static nsAttrValue::EnumTable sAdditiveTable[];
|
|
static nsAttrValue::EnumTable sCalcModeTable[];
|
|
static nsAttrValue::EnumTable sAccumulateTable[];
|
|
|
|
nsTArray<double> mKeyTimes;
|
|
nsTArray<nsSMILKeySpline> mKeySplines;
|
|
|
|
PRPackedBool mIsActive;
|
|
PRPackedBool mIsFrozen;
|
|
|
|
// These are the parameters provided by the previous sample. Currently we
|
|
// perform lazy calculation. That is, we only calculate the result if and when
|
|
// instructed by the compositor. This allows us to apply the result directly
|
|
// to the animation value and allows the compositor to filter out functions
|
|
// that it determines will not contribute to the final result.
|
|
nsSMILTime mSampleTime; // sample time within simple dur
|
|
nsSMILTimeValue mSimpleDuration;
|
|
PRUint32 mRepeatIteration;
|
|
PRPackedBool mLastValue;
|
|
PRPackedBool mHasChanged;
|
|
|
|
nsSMILTime mBeginTime; // document time
|
|
|
|
// The owning animation element. This is used for sorting based on document
|
|
// position and for fetching attribute values stored in the element.
|
|
// Raw pointer is OK here, because this nsSMILAnimationFunction can't outlive
|
|
// its owning animation element.
|
|
nsISMILAnimationElement* mAnimationElement;
|
|
|
|
// Which attributes have been set but have had errors. This is not used for
|
|
// all attributes but only those which have specified error behaviour
|
|
// associated with them.
|
|
PRUint16 mErrorFlags;
|
|
|
|
// This is for the very specific case where we have a 'to' animation that is
|
|
// frozen part way through the simple duration and there are other active
|
|
// lower-priority animations targetting the same attribute. In this case
|
|
// SMILANIM 3.3.6 says:
|
|
//
|
|
// The value for F(t) when a to-animation is frozen (at the end of the
|
|
// simple duration) is just the to value. If a to-animation is frozen
|
|
// anywhere within the simple duration (e.g., using a repeatCount of "2.5"),
|
|
// the value for F(t) when the animation is frozen is the value computed for
|
|
// the end of the active duration. Even if other, lower priority animations
|
|
// are active while a to-animation is frozen, the value for F(t) does not
|
|
// change.
|
|
//
|
|
// To implement this properly we'd need to force a resample of all the lower
|
|
// priority animations at the active end of this animation--something which
|
|
// would introduce unwanted coupling between the timing and animation model.
|
|
// Instead we just save the value calculated when this animation is frozen (in
|
|
// which case this animation will be sampled at the active end and the lower
|
|
// priority animations should be sampled at a time pretty close to this,
|
|
// provided we have a reasonable frame rate and we aren't seeking).
|
|
//
|
|
// @see
|
|
// http://www.w3.org/TR/2001/REC-smil-animation-20010904/#FromToByAndAdditive
|
|
nsSMILValue mFrozenValue;
|
|
};
|
|
|
|
#endif // NS_SMILANIMATIONFUNCTION_H_
|