Index: content/smil/Makefile.in =================================================================== RCS file: /cvsroot/mozilla/content/smil/Makefile.in diff -N content/smil/Makefile.in --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ content/smil/Makefile.in 5 Nov 2005 04:39:04 -0000 @@ -0,0 +1,48 @@ +# +# ***** 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 +# +# 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 ***** + +DEPTH = ../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +DIRS = public src + +include $(topsrcdir)/config/rules.mk + Index: content/smil/public/Makefile.in =================================================================== RCS file: /cvsroot/mozilla/content/smil/public/Makefile.in diff -N content/smil/public/Makefile.in --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ content/smil/public/Makefile.in 5 Nov 2005 04:39:04 -0000 @@ -0,0 +1,62 @@ +# +# ***** 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 +# +# 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 ***** + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = content + +EXPORTS = \ + nsISMILAnimAttr.h \ + nsISMILAnimElement.h \ + nsISMILAnimVal.h \ + nsISMILAnimationController.h \ + nsISMILAnimationFunction.h \ + nsISMILAnimationObserver.h \ + nsISMILAnimationRegistry.h \ + nsISMILComposable.h \ + nsISMILTimeClient.h \ + nsISMILTimeContainer.h \ + nsISMILTimedElement.h \ + $(NULL) + +include $(topsrcdir)/config/rules.mk + Index: content/smil/public/nsISMILAnimAttr.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/public/nsISMILAnimAttr.h diff -N content/smil/public/nsISMILAnimAttr.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ content/smil/public/nsISMILAnimAttr.h 5 Nov 2005 04:39:04 -0000 @@ -0,0 +1,108 @@ +/* -*- 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 + * + * 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_ISMILANIMATTR_H__ +#define __NS_ISMILANIMATTR_H__ + +#include "nsISupports.h" + +class nsISMILAnimVal; + +//////////////////////////////////////////////////////////////////////// +// nsISMILAnimAttr: Interfaces for data types that can have a base and animated +// value. + +// {c487920a-7d12-40ff-bf3b-c39dd4797cff} +#define NS_ISMILANIMATTR_IID \ +{ 0xc487920a, 0x7d12, 0x40ff, { 0xbf, 0x3b, 0xc3, 0x9d, 0xd4, 0x79, 0x7c, 0xff } } + +/** + * Interfaces for data types that can have a base and animated value. + * + * This interface is like a stepping stone between nsISMILAnimElement and + * nsISMILAnimVal. It should be possible to do without this interface altogether + * and I think this would produce a simpler design. However, keeping it should + * mean that nsISMILAnimVal can be implemented by a separate lightweight object, + * perhaps even implemented as a tear off from the class implementing + * nsISMILAnimAttr. + */ +class nsISMILAnimAttr : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISMILANIMATTR_IID) + + /** + * Gets the underlying value of this attribute. It is the same as Create() but + * avoids allocating memory. + * + * @param aValue The value to fill. + * @return NS_OK on success or an error code if getting failed. + */ + virtual nsresult GetBaseValue(nsISMILAnimVal& aValue) = 0; + + /** + * Sets the presentation value of this attribute. + * + * @param aValue The value to set. + * @return NS_OK on success or an error code if setting failed. + */ + virtual nsresult SetAnimValue(const nsISMILAnimVal& aValue) = 0; + + /* + * Factory methods + */ + + /** + * Creates a new nsISMILAnimVal initialized to the base value of this + * attribute. + * + * @return The newly created object or null if creation failed. + */ + virtual nsISMILAnimVal* Create() const = 0; + + /** + * Creates a new nsISMILAnimVal from the given specification. + * + * @param aSpec A string representation that should be parsed to determine + * the value of the newly created object. + * @return The newly created object or null if creation failed. + */ + virtual nsISMILAnimVal* CreateFromSpec(const nsAString& aSpec) const = 0; +}; + +#endif // __NS_ISMILANIMATTR_H__ + Index: content/smil/public/nsISMILAnimElement.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/public/nsISMILAnimElement.h diff -N content/smil/public/nsISMILAnimElement.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ content/smil/public/nsISMILAnimElement.h 5 Nov 2005 04:39:04 -0000 @@ -0,0 +1,78 @@ +/* -*- 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 + * + * 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_ISMILANIMELEMENT__ +#define __NS_ISMILANIMELEMENT__ + +#include "nsISupports.h" +#include "nsISMILAnimAttr.h" + +//////////////////////////////////////////////////////////////////////// +// nsISMILAnimElement: interface of elements that have attributes +// that can be animated. + +// {5DD94E10-FD8D-42FB-B054-8D29F771033A} +#define NS_ISMILANIMELEMENT_IID \ +{ 0x5dd94e10, 0xfd8d, 0x42fb, { 0xb0, 0x54, 0x8d, 0x29, 0xf7, 0x71, 0x03, 0x3a } } + +/** + * Interface for elements that have attributes that can be animated. + * + * This interface is not actually used by the SMIL module. Instead it is used by + * the host language to identify targets for animation. However, in a mixed + * namespace environment this interface might be used by several modules so it + * should probably stay here in SMIL. + */ +class nsISMILAnimElement : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISMILANIMELEMENT_IID) + + /** + * Gets an animatable attribute identified by namespace and attribute name. + * + * @param aNamespaceID The namespace of the attribute + * @param aName The attribute name + * @return The attribute or NULL if this attribute does not exist or is not + * animatable. + */ + virtual nsISMILAnimAttr* + GetAnimAttribute(PRInt32 aNamespaceID, nsIAtom* aName)=0; +}; + +#endif // __NS_ISMILANIMELEMENT__ + Index: content/smil/public/nsISMILAnimVal.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/public/nsISMILAnimVal.h diff -N content/smil/public/nsISMILAnimVal.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ content/smil/public/nsISMILAnimVal.h 5 Nov 2005 04:39:05 -0000 @@ -0,0 +1,131 @@ +/* -*- 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 + * + * 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_ISMILANIMVAL_H__ +#define __NS_ISMILANIMVAL_H__ + +#include "nsISupports.h" + +//////////////////////////////////////////////////////////////////////// +// nsISMILAnimVal + +// {01d2aae5-9de4-4e8f-a1e9-ae660ad27925} +#define NS_ISMILANIMVAL_IID \ +{ 0x01d2aae5, 0x9de4, 0x4e8f, { 0xa1, 0xe9, 0xae, 0x66, 0x0a, 0xd2, 0x79, 0x25 } } + +class nsISMILAnimVal : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISMILANIMVAL_IID) + + /** + * Calculates the 'distance' between this value and another. This is the + * distance used in paced interpolation. + * + * @param aTo The end of the interval for which the distance should be + * calculated. + * @param aDistance The result of the calculation. + * @return NS_OK on success, or an appropriate code if there is no notion of + * distance for the underlying data type or the distance could not be + * calculated. + */ + virtual nsresult ComputeDistance(const nsISMILAnimVal& aTo, + PRFloat64& aDistance) const = 0; + + /** + * Calculates an interpolates value between this value and the specified end + * value using the specified proportion. + * + * @param aEndVal The value defining the end of the interval of + * interpolation. + * @param aUnitDistance A number between 0.0 and 1.0 (inclusive) defining + * the distance of the interpolated value in the + * interval. + * @param aResult The interpolated value. + * @result NS_OK on success, NS_ERROR_FAILURE if this data type cannot be + * interpolated or NS_ERROR_OUT_OF_MEMORY if insufficient memory was + * available for storing the result. + */ + virtual nsresult Interpolate(const nsISMILAnimVal& aEndVal, + float aUnitDistance, + nsISMILAnimVal& aResult) = 0; + + /** + * Add the given value to this value. This method facilitates additive and + * cumulative animation. + * + * This method will fail if the underlying datatype is not additive or was not + * specified using an additive syntax. + * + * See SVG 1.1, section 19.2.5. In particular, + * + * "If a given attribute or property can take values of keywords (which are + * not additive) or numeric values (which are additive), then additive + * animations are possible if the subsequent animation uses a numeric value + * even if the base animation uses a keyword value; however, if the subsequent + * animation uses a keyword value, additive animation is not possible." + * + * @param aAddedVal The value to add to this value. + * @return NS_OK on success, an error code on failure. + */ + virtual nsresult Add(const nsISMILAnimVal& aAddedVal) = 0; + + /** + * Assign this object the value of another. Think of this as the assignment + * operator. + * + * @param aNewVal The value to set. + * @return NS_OK on success, an error code on failure such as when the + * underlying type of the specified object differs. + */ + virtual nsresult Set(const nsISMILAnimVal& aNewVal) = 0; + + /** + * Repeats this value or the specified value a number of times. This method + * will fail if the underlying data type is not additive. + * + * @param aCount The number of times to repeat the value. + * @param aRepeatValue The value to repeat. If this parameter is null the + * current value will be repeated. + * @return NS_OK on success, an error code on failure. + */ + virtual nsresult Repeat(PRUint32 aCount, + const nsISMILAnimVal* aRepeatValue = nsnull) = 0; +}; + +#endif // __NS_ISMILANIMVAL_H__ + Index: content/smil/public/nsISMILAnimationController.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/public/nsISMILAnimationController.h diff -N content/smil/public/nsISMILAnimationController.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ content/smil/public/nsISMILAnimationController.h 5 Nov 2005 04:39:05 -0000 @@ -0,0 +1,75 @@ +/* -*- 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 + * + * 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_ISMILANIMATIONCONTROLLER_H__ +#define __NS_ISMILANIMATIONCONTROLLER_H__ + +#include "nsIAnimationController.h" + +#define NS_ISMILANIMATIONCONTROLLER_IID \ +{ 0xd2c81398, 0x1f30, 0x4303, { 0xbe, 0xbe, 0xc5, 0x0c, 0x01, 0xfd, 0xd8, 0x85 } } + +class nsISMILTimeContainer; +class nsIDocument; + +//////////////////////////////////////////////////////////////////////// +// nsISMILAnimationController: Animation controller + +class nsISMILAnimationController : public nsIAnimationController +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISMILANIMATIONCONTROLLER_IID) + + // nsIAnimationController methods + virtual nsresult Pause()=0; + virtual nsresult Resume()=0; + virtual nsresult Reset()=0; + + // + // Eventually, this will probably be all nsISMILTimedElements so that it is + // possible to have hierarchies of containers (which will implement + // nsISMILTimedElement), and then these methods will be replaced with + // SetRootElement. + // + virtual nsresult AddTimeContainer(nsISMILTimeContainer* aContainer)=0; + virtual nsresult RemoveTimeContainer(nsISMILTimeContainer* aContainer)=0; +}; + +nsISMILAnimationController* NS_NewSMILAnimationController(nsIDocument *doc); + +#endif // __NS_ISMILANIMATIONCONTROLLER_H__ + Index: content/smil/public/nsISMILAnimationFunction.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/public/nsISMILAnimationFunction.h diff -N content/smil/public/nsISMILAnimationFunction.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ content/smil/public/nsISMILAnimationFunction.h 5 Nov 2005 04:39:05 -0000 @@ -0,0 +1,106 @@ +/* -*- 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 + * + * 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_ISMILANIMFUNCTION_H__ +#define __NS_ISMILANIMFUNCTION_H__ + +#include "nsISupports.h" + +class nsISMILAnimAttr; + +// {14eb1aab-e4ba-4c77-be89-195ef975c90d} +#define NS_ISMILANIMFUNCTION_IID \ +{ 0x14eb1aab, 0xe4ba, 0x4c77, { 0xbe, 0x89, 0x19, 0x5e, 0xf9, 0x75, 0xc9, 0x0d } } + +/** + * Provides the animation function for an interpolating animation element. This + * includes the animation-related attributes. It is intended to be used by + * elements such as , and so on. + * + * It will likely be split into nsISMILInterpolatingAnimFunc and + * nsISMILSimpleAnimFunc when is introduced. Extra parameters or perhaps + * a subclass will probably be needed to support , + * and the like. + */ +class nsISMILAnimationFunction : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISMILANIMFUNCTION_IID) + + virtual nsresult SetTargetAttribute(nsISMILAnimAttr* aAttribute)=0; + virtual nsISMILAnimAttr* GetTargetAttribute()=0; + virtual void SetDocumentPosition(PRUint16 aDocPosition)=0; + + /* + * Property setters + */ + virtual nsresult SetAccumulate(const nsAString& aAccumulate)=0; + virtual nsresult SetAdditive(const nsAString& aAdditive)=0; + virtual nsresult SetBy(const nsAString& aBy)=0; + virtual nsresult SetCalcMode(const nsAString& aCalcMode)=0; + virtual nsresult SetFrom(const nsAString& aFrom)=0; + virtual nsresult SetKeyTimes(const nsAString& aKeyTimes)=0; + virtual nsresult SetKeySplines(const nsAString& aKeySplines)=0; + virtual nsresult SetTo(const nsAString& aTo)=0; + virtual nsresult SetValues(const nsAString& aValues)=0; + + /* + * Property unsetters + * + * Unsetters are used instead of simply passing an empty string to the setters + * as in some cases an empty string is an error whereas not specifying an + * attribute is not. + * + * Unsetters are used in preference to setting a default value so that this + * object is responsible for supplying default values and not all the + * different animation elements that use it. + */ + virtual void UnsetAdditive()=0; + virtual void UnsetBy()=0; + virtual void UnsetCalcMode()=0; + virtual void UnsetAccumulate()=0; + virtual void UnsetFrom()=0; + virtual void UnsetKeyTimes()=0; + virtual void UnsetKeySplines()=0; + virtual void UnsetTo()=0; + virtual void UnsetValues()=0; +}; + +nsISMILAnimationFunction* NS_NewSMILAnimationFunction(); + +#endif //__NS_ISMILANIMFUNCTION_H__ + Index: content/smil/public/nsISMILAnimationObserver.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/public/nsISMILAnimationObserver.h diff -N content/smil/public/nsISMILAnimationObserver.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ content/smil/public/nsISMILAnimationObserver.h 5 Nov 2005 04:39:05 -0000 @@ -0,0 +1,63 @@ +/* -*- 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 + * + * 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_ISMILANIMATIONOBSERVER_H__ +#define __NS_ISMILANIMATIONOBSERVER_H__ + +#include "nsISupports.h" +#include "nsWeakReference.h" + +#define NS_ISMILANIMATIONOBSERVER_IID \ +{ 0x8f96dd0c, 0x9c70, 0x4b3a, { 0xa0, 0x72, 0xce, 0x71, 0x0f, 0x47, 0xa0, 0x06 } } + +//////////////////////////////////////////////////////////////////////// +// nsISMILAnimationObserver: Interfaces for clients that want to be informed of +// stages in the animation's life cycle + +class nsISMILAnimationObserver : public nsSupportsWeakReference +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISMILANIMATIONOBSERVER_IID) + + virtual void StartSample()=0; + virtual void StartCompositing()=0; + virtual void EndCompositing()=0; + virtual void EndSample()=0; +}; + +#endif // __NS_ISMILANIMATIONOBSERVER_H__ + Index: content/smil/public/nsISMILAnimationRegistry.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/public/nsISMILAnimationRegistry.h diff -N content/smil/public/nsISMILAnimationRegistry.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ content/smil/public/nsISMILAnimationRegistry.h 5 Nov 2005 04:39:06 -0000 @@ -0,0 +1,155 @@ +/* -*- 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 + * + * 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_ISMILANIMATIONREGISTRY_H__ +#define __NS_ISMILANIMATIONREGISTRY_H__ + +#include "nsISupports.h" + +class nsISMILAnimationController; +class nsISMILAnimationObserver; +class nsISMILComposable; +class nsISMILAnimAttr; +class nsISMILTimedElement; + +#define NS_ISMILANIMATIONREGISTRY_IID \ +{ 0xdd3c7124, 0xcc1f, 0x447b, { 0xa1, 0x35, 0x4a, 0xd8, 0xfc, 0xd4, 0x9f, 0x31 } } + +//////////////////////////////////////////////////////////////////////// +// nsISMILAnimationRegistry: Entry point for SMIL animated documents + +class nsISMILAnimationRegistry : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISMILANIMATIONREGISTRY_IID) + + /** + * Sets the animation controller which is needed for registering the time + * container managed by this registry. + * + * @param aController The animation controller. May be NULL to disassociate + * this registry from any controller. + */ + virtual nsresult SetController(nsISMILAnimationController* aController)=0; + + /** + * Sets the object which will receive notifications when samples begin and end + * and when compositing takes place. Currently only one observer can be set at + * a time. + * + * @param aObserver The observer to receive notifications. May be null to + * remove the currently set observer if any. + */ + virtual void SetObserver(nsISMILAnimationObserver* aObserver)=0; + + /* + * The next five methods correspond to methods in the nsIDOMSVGSVGElement + * interface. + */ + + /** + * Starts animation. After creating the registry this method needs to be + * called before animation starts. This allows more precise control over when + * the animation starts allowing the registry to be created and set up but + * only started when the conditions are right. + */ + virtual nsresult Start()=0; + + /** + * Pauses animation. + */ + virtual void Pause()=0; + + /** + * Unpauses animation. + */ + virtual void Unpause()=0; + + /** + * @return true if the animation is in a paused state. + */ + virtual PRBool IsPaused()=0; + + /** + * Returns the current time in seconds relative to the start time of the + * animation. + */ + virtual float GetCurrentTime()=0; + + /** + * Adjusts the clock for the animation to the specified time. + * + * @param aSeconds The new current time in seconds relative to the start time + * for this animation. + */ + virtual nsresult SetCurrentTime(float aSeconds)=0; + + /** + * Registers a composable object with the compositor for the specified target + * attribute. The composable object may be registered with several target + * attributes and each target attribute may have several composable objects + * associated with it. + */ + virtual nsresult RegisterComposable(nsISMILAnimAttr* aTargetAttr, + nsISMILComposable* aComposable)=0; + + /** + * Removes the specified composable object from all compositors with which is + * it registered. + */ + virtual nsresult UnregisterComposable(nsISMILComposable* aComposable)=0; + + /** + * Registers the timed element with the time container managed by this + * registry. + */ + virtual nsresult RegisterTimedElement(nsISMILTimedElement* aElement)=0; + + /** + * Unregisters the timed element from the time container managed by this + * registry. + */ + virtual nsresult UnregisterTimedElement(nsISMILTimedElement* aElement)=0; +}; + +/** + * Creates a new animation registry object. + */ +nsISMILAnimationRegistry* NS_NewSMILAnimationRegistry(); + +#endif // __NS_ISMILANIMATIONREGISTRY_H__ + Index: content/smil/public/nsISMILComposable.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/public/nsISMILComposable.h diff -N content/smil/public/nsISMILComposable.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ content/smil/public/nsISMILComposable.h 5 Nov 2005 04:39:06 -0000 @@ -0,0 +1,145 @@ +/* -*- 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 + * + * 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_ISMILCOMPOSABLE_H__ +#define __NS_ISMILCOMPOSABLE_H__ + +#include "nsISupports.h" +#include "nsWeakReference.h" + +class nsISMILAnimVal; + +//////////////////////////////////////////////////////////////////////// +// nsISMILComposable : Interface for animations that can be composited +// by the compositor + +// {4b05aa22-712e-4a9e-8452-f7c4b2e507e7} +#define NS_ISMILCOMPOSABLE_IID \ +{ 0x4b05aa22, 0x712e, 0x4a9e, { 0x84, 0x52, 0xf7, 0xc4, 0xb2, 0xe5, 0x07, 0xe7 } } + +class nsISMILComposable : public nsSupportsWeakReference +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISMILCOMPOSABLE_IID) + + /** + * Combines the result of this animation function for the last sample with the + * specified value. + * + * @param aResult The value to compose with. + */ + virtual void ComposeResult(nsISMILAnimVal &aResult)=0; + + /** + * Returns the relative priority of this animation to another. The priority is + * used for determining the position of the animation in the animation + * sandwich. + * + * @return -1 if this animation has lower priority or 1 if this animation has + * higher priority + * + * This method should never return 0. + */ + virtual PRInt8 CompareTo(const nsISMILComposable& composable) const=0; + + /* + * The following three methods are used in sorting. + */ + + /** + * Indicates if this animation is a 'to animation'. Such animations appear + * 'higher' in the animation sandwich than all other animations. + * + * @return True if this animation is a to animation, false otherwise. + */ + virtual PRBool IsToAnimation() const=0; + + /** + * Returns the begin time of this animation for the interval it is currently + * animating. For inactive animations this will be LL_MinInt but such + * animations should be filtered from compositing anyway. + * + * @return A 64-bit integer representing the begin time of this animation. + */ + virtual const PRInt64& GetBeginTime() const=0; + + /** + * Returns a unique (0-based) index indicating the position of this animation + * in the document. The first animation will have index 0 as so on. Positions + * are recalculated when the document structure is changed. + * + * @return An unsigned integer representing this animation's position in the + * document. + */ + virtual PRUint16 GetDocumentPosition() const=0; + + /* + * The following methods are provided so that the compositor can optimise 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. + */ + virtual PRBool IsActive() const=0; + + /** + * 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. + */ + virtual PRBool WillReplace() const=0; + + /** + * 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. + * + * @return True if the animation parameters have changed, false otherwise. + */ + virtual PRBool HasChanged() const=0; +}; + +#endif // __NS_ISMILCOMPOSABLE_H__ + Index: content/smil/public/nsISMILTimeClient.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/public/nsISMILTimeClient.h diff -N content/smil/public/nsISMILTimeClient.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ content/smil/public/nsISMILTimeClient.h 5 Nov 2005 04:39:06 -0000 @@ -0,0 +1,106 @@ +/* -*- 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 + * + * 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_ISMILTIMECLIENT_H__ +#define __NS_ISMILTIMECLIENT_H__ + +#include "nsISupports.h" + +class nsSMILTimeValue; + +//////////////////////////////////////////////////////////////////////// +// nsISMILTimeClient + +// {196f66f4-e6f6-420b-a337-da42a2efccde} +#define NS_ISMILTIMECLIENT_IID \ +{ 0x196f66f4, 0xe6f6, 0x420b, { 0xa3, 0x37, 0xda, 0x42, 0xa2, 0xef, 0xcc, 0xde } } + +class nsISMILTimeClient : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISMILTIMECLIENT_IID) + + /** + * Indicate a new sample has occurred. + * + * @param aSimpleTime 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. + */ + virtual void SampleAt(const PRInt64& aSimpleTime, + const nsSMILTimeValue& aSimpleDuration, + const PRUint32& aRepeatIteration)=0; + + /** + * 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. + */ + virtual void SampleLastValue(const PRUint32& aRepeatIteration)=0; + + /** + * Indicate that the timed element is now active. This is used, for example, + * to instruct the animation function that it should now add its result to the + * animation sandwich. The begin time is also provided for proper + * prioritisation 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. + */ + virtual void ToActive(const PRInt64& aBeginTime)=0; + + /** + * Indicate that the timed element is no longer active. This is used, for + * example, 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 even though these parameters are unlikely to + * change between samples. + */ + virtual void ToInactive(PRBool aIsFrozen)=0; +}; + +#endif // __NS_ISMILTIMECLIENT_H__ + Index: content/smil/public/nsISMILTimeContainer.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/public/nsISMILTimeContainer.h diff -N content/smil/public/nsISMILTimeContainer.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ content/smil/public/nsISMILTimeContainer.h 5 Nov 2005 04:39:07 -0000 @@ -0,0 +1,128 @@ +/* -*- 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 + * + * 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_ISMILTIMECONTAINER_H__ +#define __NS_ISMILTIMECONTAINER_H__ + +#include "nsISupports.h" +#include "nsISMILTimedElement.h" + +//////////////////////////////////////////////////////////////////////// +// nsISMILTimeContainer: Time container + +// {46b51a7b-d857-45f1-9c7d-4d0d12719238} +#define NS_ISMILTIMECONTAINER_IID \ +{ 0x46b51a7b, 0xd857, 0x45f1, { 0x9c, 0x7d, 0x4d, 0x0d, 0x12, 0x71, 0x92, 0x38 } } + +/** + * A SMIL time container. + * + * When implementing SMIL 2.0 time containers, this interface will most likely + * inherit from nsISMILTimedElement, amongst other changes + */ +class nsISMILTimeContainer : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISMILTIMECONTAINER_IID) + + /** + * Pause the time container. The time container is initially unpaused. + */ + virtual nsresult Pause()=0; + + /** + * Resume the time container. + */ + virtual nsresult Resume()=0; + + /** + * Returns the paused state of the time container independently of the paused + * state of the container's parent. + */ + virtual PRBool IsPaused()=0; + + /** + * Inform the time container that its parent has been paused. + * + * Currently this is necessary so that the time container will accumulate + * pause offsets correctly as these are not maintained by the parent. + * + * Re-using Pause() and maintaining pause counts can lead to unwanted + * behaviour when calls to pause and resume are unbalanced. + */ + virtual nsresult ParentPaused()=0; + + /** + * Inform the time container that its parent has been resumed. + */ + virtual nsresult ParentResumed()=0; + + /** + * Reset the time container's internal state. This is particularly useful when + * a cached time container is to be re-used. + */ + virtual nsresult Reset()=0; + + /** + * We may later change this to SampleAt and maintain separate host document + * and document fragment times. This would allow more advanced time + * manipulations for documents with several animated SVG document fragments. + */ + virtual void Sample()=0; + + /** + * Add a timed element to this container. No attempt is made to check if the + * timed element is already a child of this container--in that case the timed + * element will be added twice and will be sampled twice. + * + * @param aElement The element to add. + * @return NS_OK if the element was successfully added or an error otherwise. + */ + virtual nsresult AddTimedElement(nsISMILTimedElement* aElement)=0; + + /** + * Remove the specified timed element from this container. + * + * @param aElement The element to remove. + * @return NS_OK if the element is found and successfully removed or an error + * otherwise. + */ + virtual nsresult RemoveTimedElement(nsISMILTimedElement* aElement)=0; +}; + +#endif // __NS_ISMILTIMECONTAINER_H__ + Index: content/smil/public/nsISMILTimedElement.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/public/nsISMILTimedElement.h diff -N content/smil/public/nsISMILTimedElement.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ content/smil/public/nsISMILTimedElement.h 5 Nov 2005 04:39:07 -0000 @@ -0,0 +1,156 @@ +/* -*- 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 + * + * 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_ISMILTIMEDELEMENT_H__ +#define __NS_ISMILTIMEDELEMENT_H__ + +#include "nsISupports.h" + +class nsISMILTimeClient; +class nsSMILTimeValue; +class nsSMILInstanceTime; +class nsSMILTimedDocumentRoot; + +//////////////////////////////////////////////////////////////////////// +// nsISMILTimedElement + +// {c5f60446-5c1a-4f3b-8ce3-646199ac97f2} +#define NS_ISMILTIMEDELEMENT_IID \ +{ 0xc5f60446, 0x5c1a, 0x4f3b, { 0x8c, 0xe3, 0x64, 0x61, 0x99, 0xac, 0x97, 0xf2 } } + +class nsISMILTimedElement : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISMILTIMEDELEMENT_IID) + + /** + * Adds an instance time object this this element's list of instance times. + * These instance times are used when creating intervals. + * + * This method is typically called by an nsSMILTimeValueSpec to register an + * instance time corresponding its specification. + * + * @param aInstanceTime The time to add. + * + * @param aIsBegin True if the time to be added represents a begin time + * or false if it represents an end time. + */ + virtual void AddInstanceTime(nsSMILInstanceTime* aInstanceTime, + PRBool aIsBegin)=0; + + /** + * Associates a timed document root. This is required for resolving wallclock + * values and getting the document time in order to create new instance times. + * + * @param aRoot The timed document root to associate. + */ + virtual void SetDocumentRoot(nsSMILTimedDocumentRoot* aRoot)=0; + + /** + * Sets the object that will be called by this timed element each time it is + * sampled. + * + * In Schmitz's model it is possible to associate several time clients with + * a timed element but for now we only allow one. + * + * @param aClient The time client to associate. Any previous time client + * will be disassociated and no longer sampled. Setting this + * to NULL will simply disassociate the previous client, if + * any. + */ + virtual void SetTimeClient(nsISMILTimeClient* aClient)=0; + + /** + * Samples the object at the given document time. Timing intervals are updated + * and if this element is active at the given time the associated time client + * will be sampled with the appropriate simple time. + * + * @param aDocumentTime The document time at which to sample. + */ + virtual void SampleAt(const PRInt64& aDocumentTime)=0; + + /** + * Reset the element's internal state. This is useful for repeating time + * containers and so that the timing model can be cached. + * + * @param aHardReset Perform a hard reset such that all instance times are + * cleared. For a soft reset only instance times created by + * DOM calls and events are cleared. A hard reset is needed + * in the case of a cached timing model whilst for + * repeating only a soft reset is required. + */ + virtual void Reset(PRBool aHardReset = PR_FALSE)=0; + + /* + * Property setters + */ + virtual nsresult SetBeginSpec(const nsAString& aBeginSpec)=0; + virtual nsresult SetEndSpec(const nsAString& aEndSpec)=0; + virtual nsresult SetSimpleDuration(const nsAString& aDurSpec)=0; + virtual nsresult SetMin(const nsAString& aMinSpec)=0; + virtual nsresult SetMax(const nsAString& aMaxSpec)=0; + virtual nsresult SetRestart(const nsAString& aRestartSpec)=0; + virtual nsresult SetRepeatCount(const nsAString& aRepeatCountSpec)=0; + virtual nsresult SetRepeatDur(const nsAString& aRepeatDurSpec)=0; + virtual nsresult SetFillMode(const nsAString& aFillModeSpec)=0; + + /* + * Property unsetters + * + * Unsetters are used instead of simply passing an empty string to the setters + * as in some cases an empty string is an error whereas not specifying an + * attribute is not. + * + * Unsetters are used in preference to setting a default value so that this + * object is responsible for supplying default values and not all the + * different animation elements that use it. + */ + virtual void UnsetBeginSpec()=0; + virtual void UnsetEndSpec()=0; + virtual void UnsetSimpleDuration()=0; + virtual void UnsetMin()=0; + virtual void UnsetMax()=0; + virtual void UnsetRestart()=0; + virtual void UnsetRepeatCount()=0; + virtual void UnsetRepeatDur()=0; + virtual void UnsetFillMode()=0; +}; + +nsISMILTimedElement* NS_NewSMILTimedElement(); + +#endif // __NS_ISMILTIMEDELEMENT_H__ + Index: content/smil/src/Makefile.in =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/Makefile.in diff -N content/smil/src/Makefile.in --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ content/smil/src/Makefile.in 5 Nov 2005 04:39:07 -0000 @@ -0,0 +1,83 @@ +# +# ***** 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 +# +# 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 ***** + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = content +LIBRARY_NAME = gkconsmil_s +LIBXUL_LIBRARY = 1 + +REQUIRES = xpcom \ + string \ + layout \ + content \ + unicharutil \ + widget \ + dom \ + $(NULL) + +CPPSRCS = \ + nsSMILAnimationController.cpp \ + nsSMILAnimationFunction.cpp \ + nsSMILAnimationRegistry.cpp \ + nsSMILAtoms.cpp \ + nsSMILCompositor.cpp \ + nsSMILEnum.cpp \ + nsSMILInstanceTime.cpp \ + nsSMILInterval.cpp \ + nsSMILKeySpline.cpp \ + nsSMILParserUtils.cpp \ + nsSMILTimedDocumentRoot.cpp \ + nsSMILTimedElement.cpp \ + nsSMILTimeValue.cpp \ + nsSMILTimeValueSpec.cpp \ + $(NULL) + +include $(topsrcdir)/config/config.mk + +# we don't want the shared lib, but we want to force the creation of a static lib. +FORCE_STATIC_LIB = 1 + +include $(topsrcdir)/config/rules.mk + +DEFINES += -D_IMPL_NS_LAYOUT + Index: content/smil/src/nsSMILAnimationController.cpp =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsSMILAnimationController.cpp diff -N content/smil/src/nsSMILAnimationController.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ content/smil/src/nsSMILAnimationController.cpp 5 Nov 2005 04:39:08 -0000 @@ -0,0 +1,430 @@ +/* -*- 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 + * + * 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 ***** */ + +#include "nsISMILAnimationController.h" +#include "nsComponentManagerUtils.h" +#include "nsWeakReference.h" +#include "nsITimer.h" +#include "nsISMILTimeContainer.h" +#include "nsCOMArray.h" +#include "nsISimpleEnumerator.h" +#include "nsArrayEnumerator.h" +#include "nsAutoLock.h" +#include "nsIDocument.h" +#include "nsIDOMEventReceiver.h" +#include "nsIScriptGlobalObject.h" +#include "nsIDOMPageTransitionListener.h" + +class nsSMILAnimationController : public nsISMILAnimationController, + public nsIDOMPageTransitionListener, + public nsSupportsWeakReference +{ +public: + nsSMILAnimationController(); + ~nsSMILAnimationController(); + + NS_DECL_ISUPPORTS + + // nsISMILAnimationController + virtual nsresult Pause(); + virtual nsresult Resume(); + virtual nsresult Reset(); + virtual nsresult AddTimeContainer(nsISMILTimeContainer* aContainer); + virtual nsresult RemoveTimeContainer(nsISMILTimeContainer* aContainer); + + // nsIDOMPageTransitionListener, + NS_IMETHOD HandleEvent(nsIDOMEvent *event); + NS_IMETHOD PageShow(nsIDOMEvent *event); + NS_IMETHOD PageHide(nsIDOMEvent *event); + +protected: + friend nsISMILAnimationController* + NS_NewSMILAnimationController(nsIDocument* doc); + + // nsISMILAnimationController + nsresult Init(nsIDocument* doc); + nsresult StartTimer(); + nsresult StopTimer(); + void SampleChildren(); + static void Notify(nsITimer* aTimer, void* aClosure); + + static const PRUint32 kTimerInterval; + nsCOMPtr mTimer; + nsCOMArray mTimeContainers; + PRLock* mAnimationLock; + PRUint16 mPauseCount; + PRBool mHidden; +}; + +//////////////////////////////////////////////////////////////////////// +// nsSMILAnimationController implementation + +// 28ms per frame =~ 36fps which seems like a lot (Flash traditionally uses +// 14fps) but in my fiddling this was the minimum necessary for smooth motion +// using our current setup. +const PRUint32 nsSMILAnimationController::kTimerInterval = 28; + +//---------------------------------------------------------------------- +// ctors, dtors, factory methods + +nsSMILAnimationController::nsSMILAnimationController() + : mPauseCount(0), + mHidden(PR_FALSE) +{ +} + +nsSMILAnimationController::~nsSMILAnimationController() +{ + if (mAnimationLock) + PR_Lock(mAnimationLock); + + if (mTimer) { + mTimer->Cancel(); + mTimer = nsnull; + } + + if (mAnimationLock) { + PR_Unlock(mAnimationLock); + PR_DestroyLock(mAnimationLock); + } +} + +nsISMILAnimationController* NS_NewSMILAnimationController(nsIDocument* doc) +{ + nsSMILAnimationController* animationController = + new nsSMILAnimationController(); + NS_ENSURE_TRUE(animationController, nsnull); + + nsresult rv = animationController->Init(doc); + if (NS_FAILED(rv)) { + delete animationController; + animationController = nsnull; + } + + return animationController; +} + +//---------------------------------------------------------------------- +// nsISupports methods: + +NS_IMPL_ISUPPORTS5(nsSMILAnimationController, + nsISMILAnimationController, + nsIAnimationController, + nsIDOMEventListener, + nsIDOMPageTransitionListener, + nsISupportsWeakReference); + +//---------------------------------------------------------------------- +// Timer callback + +// +// We use the function callback rather than implementing nsITimerCallback to +// avoid circular ownership between the timer and this object. +// + +/*static*/ void +nsSMILAnimationController::Notify(nsITimer* timer, void* aClosure) +{ + nsSMILAnimationController* controller = (nsSMILAnimationController*)aClosure; + + NS_ASSERTION(controller->mTimer == timer, + "nsSMILAnimationController::Notify called with incorrect timer"); + + controller->SampleChildren(); +} + +//---------------------------------------------------------------------- +// nsISMILAnimationController methods: + +nsresult +nsSMILAnimationController::Pause() +{ + nsAutoLock lock(mAnimationLock); + + if (++mPauseCount > 1) + return NS_OK; + + nsresult rv = NS_OK; + + rv = StopTimer(); + + // We must tell the children too so they can keep their accumulated offsets + // accurate + PRUint32 i = mTimeContainers.Count(); + while (i > 0) { + --i; + nsCOMPtr + container( do_QueryReferent(mTimeContainers[i]) ); + + // This mess means that we continue processing all the children even if an + // error occurs but that we report the first error encountered + if (container) { + if (NS_SUCCEEDED(rv)) + rv = container->ParentPaused(); + else + container->ParentPaused(); + } else { + mTimeContainers.RemoveObjectAt(i); + } + } + + return rv; +} + +nsresult +nsSMILAnimationController::Resume() +{ + nsAutoLock lock(mAnimationLock); + + nsresult rv = NS_OK; + + NS_ASSERTION(mPauseCount > 0, "Unbalanced calls to Pause() and Resume()"); + if (mPauseCount == 0) + return NS_ERROR_FAILURE; + + if (--mPauseCount > 0) + return NS_OK; + + // We must tell the children so they can keep their accumulated offsets + // accurate + PRUint32 i = mTimeContainers.Count(); + while (i > 0) { + --i; + nsCOMPtr + container( do_QueryReferent(mTimeContainers[i]) ); + + if (container) { + if (NS_SUCCEEDED(rv)) + rv = container->ParentResumed(); + else + container->ParentResumed(); + } else { + mTimeContainers.RemoveObjectAt(i); + } + } + + if (mTimeContainers.Count() > 0) + StartTimer(); + + return rv; +} + +nsresult +nsSMILAnimationController::Reset() +{ + nsresult rv = NS_OK; + + nsAutoLock lock(mAnimationLock); + + PRUint32 i = mTimeContainers.Count(); + while (i > 0) { + --i; + nsCOMPtr + container( do_QueryReferent(mTimeContainers[i]) ); + + if (container) { + if (NS_SUCCEEDED(rv)) + rv = container->Reset(); + else + container->Reset(); + } else { + mTimeContainers.RemoveObjectAt(i); + } + } + + return rv; +} + +nsresult +nsSMILAnimationController::AddTimeContainer(nsISMILTimeContainer* aContainer) +{ + NS_ENSURE_ARG_POINTER(aContainer); + + nsresult rv; + nsCOMPtr weakRef( + getter_AddRefs(do_GetWeakReference(aContainer, &rv)) ); + NS_ENSURE_SUCCESS(rv,rv); + + { + nsAutoLock lock(mAnimationLock); + rv = (mTimeContainers.AppendObject(weakRef)) ? NS_OK : NS_ERROR_FAILURE; + NS_ENSURE_SUCCESS(rv,rv); + + if (mPauseCount > 0) { + aContainer->ParentPaused(); + } else if (mTimeContainers.Count() == 1) { + rv = StartTimer(); + } + } + + return rv; +} + +nsresult +nsSMILAnimationController::RemoveTimeContainer(nsISMILTimeContainer* aContainer) +{ + NS_ENSURE_ARG_POINTER(aContainer); + + nsresult rv; + nsCOMPtr weakRef( + getter_AddRefs(do_GetWeakReference(aContainer, &rv)) ); + + { + nsAutoLock lock(mAnimationLock); + if (NS_SUCCEEDED(rv)) + rv = (mTimeContainers.RemoveObject(weakRef)) ? NS_OK : NS_ERROR_FAILURE; + + if (NS_SUCCEEDED(rv) && mPauseCount == 0 && mTimeContainers.Count() == 0) + rv = StopTimer(); + } + + return rv; +} + +//---------------------------------------------------------------------- +// nsIDOMPageTransitionListener methods + +nsresult +nsSMILAnimationController::HandleEvent(nsIDOMEvent * /*event*/) +{ + return NS_OK; +} + +nsresult +nsSMILAnimationController::PageShow(nsIDOMEvent * /*event*/) +{ + if (!mHidden) + return NS_OK; + + mHidden = PR_FALSE; + + nsresult rv = Reset(); + NS_ENSURE_SUCCESS(rv,rv); + + return Resume(); +} + +nsresult +nsSMILAnimationController::PageHide(nsIDOMEvent * /*event*/) +{ + mHidden = PR_TRUE; + return Pause(); +} + +//---------------------------------------------------------------------- +// Implementation helpers: + +nsresult +nsSMILAnimationController::Init(nsIDocument *doc) +{ + mTimer = do_CreateInstance("@mozilla.org/timer;1"); + mAnimationLock = PR_NewLock(); + + // SMIL should be able to be used from a wide variety of contexts so in the + // following we fail silently. It is only necessary to support the bfcache. + if (doc) { + nsCOMPtr global(doc->GetScriptGlobalObject()); + if (global) { + nsCOMPtr receiver( do_QueryInterface(global) ); + if (receiver) { + receiver->AddEventListener(NS_LITERAL_STRING("pageshow"), this, + PR_FALSE); + receiver->AddEventListener(NS_LITERAL_STRING("pagehide"), this, + PR_FALSE); + } + } + } + + return (mTimer && mAnimationLock) ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +nsresult +nsSMILAnimationController::StartTimer() +{ + NS_ENSURE_TRUE(mTimer, NS_ERROR_FAILURE); + NS_ASSERTION(mPauseCount == 0, "Starting timer but controller is paused."); + + // Run the first sample manually + SampleChildren(); + + // + // XXX Make this self-tuning. Sounds like control theory to me and not + // something I'm familiar with. + // + return mTimer->InitWithFuncCallback(nsSMILAnimationController::Notify, + this, + kTimerInterval, + nsITimer::TYPE_REPEATING_PRECISE); +} + +nsresult +nsSMILAnimationController::StopTimer() +{ + NS_ENSURE_TRUE(mTimer, NS_ERROR_FAILURE); + + return mTimer->Cancel(); +} + +void +nsSMILAnimationController::SampleChildren() +{ + // Creating a new enumerator each sample provides thread-safety but I'm not + // sure what the cost is + + if (mPauseCount > 0) + return; + + nsCOMPtr enumerator; + nsresult rv = + NS_NewArrayEnumerator(getter_AddRefs(enumerator), mTimeContainers); + NS_ENSURE_SUCCESS(rv,); + + PRBool more = PR_FALSE; + nsCOMPtr container; + nsCOMPtr weakRef; + + while (NS_SUCCEEDED(enumerator->HasMoreElements(&more)) && more) { + if (NS_FAILED(enumerator->GetNext(getter_AddRefs(weakRef))) || !weakRef) + break; + + container = do_QueryReferent(weakRef); + + if (container) + container->Sample(); + } +} + Index: content/smil/src/nsSMILAnimationFunction.cpp =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsSMILAnimationFunction.cpp diff -N content/smil/src/nsSMILAnimationFunction.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ content/smil/src/nsSMILAnimationFunction.cpp 5 Nov 2005 04:39:10 -0000 @@ -0,0 +1,1180 @@ +/* -*- 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 + * + * 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 ***** */ + +#include "nsISMILAnimationFunction.h" +#include "nsISMILComposable.h" +#include "nsISMILTimeClient.h" +#include "nsSMILTimeValue.h" +#include "nsISMILAnimVal.h" +#include "nsISMILAnimAttr.h" +#include "nsSMILEnum.h" +#include "nsSMILAtoms.h" +#include "nsSMILKeySpline.h" +#include "nsSMILParserUtils.h" +#include "nsCOMPtr.h" +#include "nsCOMArray.h" +#include "nsReadableUtils.h" +#include "nsString.h" +#include "nsAutoLock.h" +#include + +#define ALLOW_BAD_KEYTIMES + +//---------------------------------------------------------------------- +// nsSMILAnimationFunction + +class nsSMILAnimationFunction : public nsISMILAnimationFunction, + public nsISMILComposable, + public nsISMILTimeClient +{ +public: + nsSMILAnimationFunction(); + ~nsSMILAnimationFunction(); + + NS_DECL_ISUPPORTS + + nsresult Init(); + + // nsISMILAnimationFunction + virtual nsresult SetTargetAttribute(nsISMILAnimAttr* aAttribute); + virtual nsISMILAnimAttr* GetTargetAttribute(); + virtual void SetDocumentPosition(PRUint16 aDocPosition); + + virtual nsresult SetAccumulate(const nsAString& aAccumulate); + virtual nsresult SetAdditive(const nsAString& aAdditive); + virtual nsresult SetBy(const nsAString& aBy); + virtual nsresult SetCalcMode(const nsAString& aCalcMode); + virtual nsresult SetFrom(const nsAString& aFrom); + virtual nsresult SetKeyTimes(const nsAString& aKeyTimes); + virtual nsresult SetKeySplines(const nsAString& aKeySplines); + virtual nsresult SetTo(const nsAString& aTo); + virtual nsresult SetValues(const nsAString& aValues); + + virtual void UnsetAdditive(); + virtual void UnsetBy(); + virtual void UnsetCalcMode(); + virtual void UnsetAccumulate(); + virtual void UnsetFrom(); + virtual void UnsetKeyTimes(); + virtual void UnsetKeySplines(); + virtual void UnsetTo(); + virtual void UnsetValues(); + + // nsISMILTimeClient methods + virtual void SampleAt(const PRInt64& aSimpleTime, + const nsSMILTimeValue& aSimpleDuration, + const PRUint32& aRepeatIteration); + virtual void SampleLastValue(const PRUint32& aRepeatIteration); + virtual void ToActive(const PRInt64& aBeginTime); + virtual void ToInactive(PRBool aIsFrozen); + + // nsISMILComposable methods + virtual void ComposeResult(nsISMILAnimVal &aResult); + virtual PRInt8 CompareTo(const nsISMILComposable& composable) const; + virtual PRBool IsToAnimation() const; + virtual const PRInt64& GetBeginTime() const; + virtual PRUint16 GetDocumentPosition() const; + virtual PRBool IsActive() const; + virtual PRBool WillReplace() const; + virtual PRBool HasChanged() const; + +protected: + // Implementation helpers + nsISMILAnimationFunction* NS_NewSMILAnimationFunction(); + + nsresult InterpolateResult(nsISMILAnimVal& aResult, + nsISMILAnimVal& aBaseValue); + nsresult AccumulateResult(nsISMILAnimVal& aResult); + void ScaleSimpleDistance(PRFloat64& aDist); + void ScaleIntervalDistance(PRFloat64& aDist, PRUint32 aIntervalIndex, + PRUint32 aNumIntervals); + void FillValuesArray(); + PRBool IsAdditive() const; + void ClearKeyTimes(); + void ClearKeySplines(); + void CheckKeyTimes(); + void CheckKeySplines(); + + // Members + + /** + * The attribute being targeted. This is needed for parsing animation function + * values and creating temporary objects. + */ + nsCOMPtr mAttribute; + + // + // Animation function values. + // + nsCOMPtr mFrom; + nsCOMPtr mTo; + nsCOMPtr mBy; + nsCOMArray mValues; + + enum nsSMILCalcMode + { + calc_linear, + calc_discrete, + calc_paced, + calc_spline + }; + static nsSMILEnumMapping sCalcModeMap[]; + nsSMILEnum mCalcMode; + + static nsSMILEnumMapping sAdditiveMap[]; + nsSMILEnum mAdditive; + + static nsSMILEnumMapping sAccumulateMap[]; + nsSMILEnum mAccumulate; + + // Array of PRFloat64* allocated and free'd by this class + nsVoidArray mKeyTimes; + // Array of nsKeySpline* allocated and free'd by this class + nsVoidArray mKeySplines; + + PRBool mIsActive; + PRBool 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. + // + PRInt64 mSimpleTime; + nsSMILTimeValue mSimpleDuration; + PRUint32 mRepeatIteration; + PRBool mLastValue; + PRBool mHasChanged; + + PRInt64 mBeginTime; + PRUint16 mDocumentPosition; + + // Keep track of which attributes have been set. This is mostly necessary for + // correct error handling but it also used to distinguish between when the + // mValues array is filled from a 'values' spec or from the values of + // 'from', 'to' and 'by'. + // + // Currently it is not used for all attributes. + PRUint16 mSetFlags; + + // 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 + // + nsCOMPtr mFrozenValue; + + PRLock* mCompositingLock; +}; + +//---------------------------------------------------------------------- +// Static members + +nsSMILEnumMapping nsSMILAnimationFunction::sCalcModeMap[] = { + {&nsSMILAtoms::linear, calc_linear}, + {&nsSMILAtoms::discrete, calc_discrete}, + {&nsSMILAtoms::paced, calc_paced}, + {&nsSMILAtoms::spline, calc_spline}, + {nsnull, 0} +}; + +nsSMILEnumMapping nsSMILAnimationFunction::sAdditiveMap[] = { + {&nsSMILAtoms::replace, PR_FALSE}, + {&nsSMILAtoms::sum, PR_TRUE}, + {nsnull, 0} +}; + +nsSMILEnumMapping nsSMILAnimationFunction::sAccumulateMap[] = { + {&nsSMILAtoms::none, PR_FALSE}, + {&nsSMILAtoms::sum, PR_TRUE}, + {nsnull, 0} +}; + +#define BF_ACCUMULATE 0 +#define BF_ADDITIVE 1 +#define BF_BY 2 +#define BF_CALC_MODE 3 +#define BF_FROM 4 +#define BF_KEY_TIMES 5 +#define BF_KEY_SPLINES 6 +#define BF_TO 7 +#define BF_VALUES 8 + +// Based on GET/SET_BOOLBIT in nsHTMLInputElement.cpp +#define GET_FLAG(bitfield, field) (((bitfield) & (0x01 << (field))) \ + ? PR_TRUE : PR_FALSE) +#define SET_FLAG(bitfield, field, b) ((b) \ + ? ((bitfield) |= (0x01 << (field))) \ + : ((bitfield) &= ~(0x01 << (field)))) + +//---------------------------------------------------------------------- +// Constructors etc. + +nsSMILAnimationFunction::nsSMILAnimationFunction() + : mCalcMode(calc_linear, sCalcModeMap), + mAdditive(PR_FALSE, sAdditiveMap), + mAccumulate(PR_FALSE, sAccumulateMap), + mIsActive(PR_FALSE), + mIsFrozen(PR_FALSE), + mSimpleTime(-1), + mRepeatIteration(0), + mLastValue(PR_FALSE), + mHasChanged(PR_TRUE), + mBeginTime(LL_MinInt()), + mDocumentPosition(PR_UINT16_MAX), + mSetFlags(0), + mErrorFlags(0) +{ +} + +nsSMILAnimationFunction::~nsSMILAnimationFunction() +{ + // Wait for the lock in case we're in the middle of compositing + if (mCompositingLock) { + PR_Lock(mCompositingLock); + PR_Unlock(mCompositingLock); + PR_DestroyLock(mCompositingLock); + } + + ClearKeyTimes(); + ClearKeySplines(); +} + +nsresult +nsSMILAnimationFunction::Init() +{ + mCompositingLock = PR_NewLock(); + return (mCompositingLock) ? NS_OK : NS_ERROR_FAILURE; +} + +nsISMILAnimationFunction* +NS_NewSMILAnimationFunction() +{ + nsSMILAnimationFunction *func = new nsSMILAnimationFunction(); + NS_ENSURE_TRUE(func, nsnull); + + if (NS_FAILED(func->Init())) { + delete func; + return nsnull; + } + + return func; +} + +//---------------------------------------------------------------------- +// nsISupports methods: + +NS_IMPL_ISUPPORTS4(nsSMILAnimationFunction, + nsISMILAnimationFunction, + nsISMILComposable, + nsISMILTimeClient, + nsISupportsWeakReference) + +//---------------------------------------------------------------------- +// nsISMILAnimationFunction methods: + +nsresult +nsSMILAnimationFunction::SetTargetAttribute(nsISMILAnimAttr* aAttribute) +{ + nsAutoLock lock(mCompositingLock); + mAttribute = aAttribute; + mValues.Clear(); + SET_FLAG(mSetFlags, BF_VALUES, PR_FALSE); + mFrom = nsnull; + mTo = nsnull; + mBy = nsnull; + mHasChanged = PR_TRUE; + + return NS_OK; +} + +nsISMILAnimAttr* +nsSMILAnimationFunction::GetTargetAttribute() +{ + return mAttribute; +} + +void +nsSMILAnimationFunction::SetDocumentPosition(PRUint16 aDocPosition) +{ + mDocumentPosition = aDocPosition; + mHasChanged = PR_TRUE; +} + +nsresult +nsSMILAnimationFunction::SetAdditive(const nsAString& aAdditive) +{ + mHasChanged = PR_TRUE; + return mAdditive.SetStringValue(aAdditive); +} + +void +nsSMILAnimationFunction::UnsetAdditive() +{ + mAdditive.SetIntegerValue((PRUint16)PR_FALSE); + mHasChanged = PR_TRUE; +} + +nsresult +nsSMILAnimationFunction::SetBy(const nsAString& aBy) +{ + NS_ENSURE_TRUE(mAttribute, NS_ERROR_FAILURE); + + nsAutoLock lock(mCompositingLock); + mBy = mAttribute->CreateFromSpec(aBy); + SET_FLAG(mErrorFlags, BF_BY, !mBy); + if (!mBy) + return NS_ERROR_FAILURE; + + FillValuesArray(); + mHasChanged = PR_TRUE; + + return NS_OK; +} + +void +nsSMILAnimationFunction::UnsetBy() +{ + nsAutoLock lock(mCompositingLock); + mBy = nsnull; + FillValuesArray(); + SET_FLAG(mErrorFlags, BF_BY, PR_FALSE); + mHasChanged = PR_TRUE; +} + +nsresult +nsSMILAnimationFunction::SetCalcMode(const nsAString& aCalcMode) +{ + mHasChanged = PR_TRUE; + nsresult rv = mCalcMode.SetStringValue(aCalcMode); + SET_FLAG(mErrorFlags, BF_CALC_MODE, NS_FAILED(rv)); + CheckKeyTimes(); + CheckKeySplines(); + + return rv; +} + +void +nsSMILAnimationFunction::UnsetCalcMode() +{ + mCalcMode.SetIntegerValue(calc_linear); + SET_FLAG(mErrorFlags, BF_CALC_MODE, PR_FALSE); + mHasChanged = PR_TRUE; + CheckKeyTimes(); + CheckKeySplines(); +} + +nsresult +nsSMILAnimationFunction::SetAccumulate(const nsAString& aAccumulate) +{ + mHasChanged = PR_TRUE; + return mAccumulate.SetStringValue(aAccumulate); +} + +void +nsSMILAnimationFunction::UnsetAccumulate() +{ + mAccumulate.SetIntegerValue((PRUint16)PR_FALSE); + mHasChanged = PR_TRUE; +} + + +nsresult +nsSMILAnimationFunction::SetFrom(const nsAString& aFrom) +{ + NS_ENSURE_TRUE(mAttribute, NS_ERROR_FAILURE); + + nsAutoLock lock(mCompositingLock); + mFrom = mAttribute->CreateFromSpec(aFrom); + SET_FLAG(mErrorFlags, BF_FROM, !mFrom); + if (!mFrom) + return NS_ERROR_FAILURE; + + FillValuesArray(); + mHasChanged = PR_TRUE; + + return NS_OK; +} + +void +nsSMILAnimationFunction::UnsetFrom() +{ + nsAutoLock lock(mCompositingLock); + mFrom = nsnull; + FillValuesArray(); + SET_FLAG(mErrorFlags, BF_FROM, PR_FALSE); + mHasChanged = PR_TRUE; +} + +nsresult +nsSMILAnimationFunction::SetKeySplines(const nsAString& aKeySplines) +{ + nsAutoLock lock(mCompositingLock); + + ClearKeySplines(); + + // This will be filled with PRFloat64*'s + nsVoidArray keySplines; + nsresult rv = nsSMILParserUtils::GetKeySplines(aKeySplines, keySplines); + + if (keySplines.Count() < 1 || keySplines.Count() % 4) + rv = NS_ERROR_FAILURE; + + if (NS_SUCCEEDED(rv)) + { + PRFloat64* x1; + PRFloat64* y1; + PRFloat64* x2; + PRFloat64* y2; + + for (int i = 0; i < keySplines.Count(); i += 4) + { + x1 = NS_STATIC_CAST(PRFloat64*, keySplines[i]); + y1 = NS_STATIC_CAST(PRFloat64*, keySplines[i+1]); + x2 = NS_STATIC_CAST(PRFloat64*, keySplines[i+2]); + y2 = NS_STATIC_CAST(PRFloat64*, keySplines[i+3]); + + mKeySplines.AppendElement(new nsSMILKeySpline(*x1, *y1, *x2, *y2)); + + delete x1; + delete y1; + delete x2; + delete y2; + } + } + + keySplines.Clear(); + + mHasChanged = PR_TRUE; + SET_FLAG(mSetFlags, BF_KEY_SPLINES, PR_TRUE); + + CheckKeySplines(); + + return NS_OK; +} + +void +nsSMILAnimationFunction::UnsetKeySplines() +{ + nsAutoLock lock(mCompositingLock); + ClearKeySplines(); + SET_FLAG(mErrorFlags, BF_KEY_SPLINES, PR_FALSE); + SET_FLAG(mSetFlags, BF_KEY_SPLINES, PR_FALSE); + mHasChanged = PR_TRUE; +} + +nsresult +nsSMILAnimationFunction::SetKeyTimes(const nsAString& aKeyTimes) +{ + nsAutoLock lock(mCompositingLock); + + ClearKeyTimes(); + nsresult rv = nsSMILParserUtils::GetKeyTimes(aKeyTimes, mKeyTimes); + + if (NS_SUCCEEDED(rv) && mKeyTimes.Count() < 1) + rv = NS_ERROR_FAILURE; + + if (NS_FAILED(rv)) + ClearKeyTimes(); + + mHasChanged = PR_TRUE; + SET_FLAG(mSetFlags, BF_KEY_TIMES, PR_TRUE); + + CheckKeyTimes(); + + return NS_OK; +} + +void +nsSMILAnimationFunction::UnsetKeyTimes() +{ + nsAutoLock lock(mCompositingLock); + ClearKeyTimes(); + SET_FLAG(mErrorFlags, BF_KEY_TIMES, PR_FALSE); + SET_FLAG(mSetFlags, BF_KEY_TIMES, PR_FALSE); + mHasChanged = PR_TRUE; +} + +nsresult +nsSMILAnimationFunction::SetTo(const nsAString& aTo) +{ + NS_ENSURE_TRUE(mAttribute, NS_ERROR_FAILURE); + + nsAutoLock lock(mCompositingLock); + mTo = mAttribute->CreateFromSpec(aTo); + SET_FLAG(mErrorFlags, BF_TO, !mTo); + if (!mTo) + return NS_ERROR_FAILURE; + + FillValuesArray(); + mHasChanged = PR_TRUE; + + return NS_OK; +} + +void +nsSMILAnimationFunction::UnsetTo() +{ + nsAutoLock lock(mCompositingLock); + mTo = nsnull; + FillValuesArray(); + SET_FLAG(mErrorFlags, BF_TO, PR_FALSE); + mHasChanged = PR_TRUE; +} + +nsresult +nsSMILAnimationFunction::SetValues(const nsAString& aValues) +{ + NS_ENSURE_TRUE(mAttribute, NS_ERROR_FAILURE); + + nsAutoLock lock(mCompositingLock); + mValues.Clear(); + SET_FLAG(mSetFlags, BF_VALUES, PR_FALSE); + + nsresult rv = nsSMILParserUtils::GetValues(aValues, mValues, mAttribute); + + if (NS_SUCCEEDED(rv)) + SET_FLAG(mSetFlags, BF_VALUES, PR_TRUE); + else + mValues.Clear(); + + mHasChanged = PR_TRUE; + SET_FLAG(mErrorFlags, BF_VALUES, NS_FAILED(rv)); + CheckKeyTimes(); + CheckKeySplines(); + + return rv; +} + +void +nsSMILAnimationFunction::UnsetValues() +{ + nsAutoLock lock(mCompositingLock); + SET_FLAG(mSetFlags, BF_VALUES, PR_FALSE); + FillValuesArray(); + SET_FLAG(mErrorFlags, BF_VALUES, PR_FALSE); + mHasChanged = PR_TRUE; +} + +//---------------------------------------------------------------------- +// nsISMILTimeClient methods + +void +nsSMILAnimationFunction::SampleAt(const PRInt64& aSimpleTime, + const nsSMILTimeValue& aSimpleDuration, + const PRUint32& aRepeatIteration) +{ + if (mHasChanged || mLastValue || LL_NE(mSimpleTime, aSimpleTime) || + mSimpleDuration.CompareTo(aSimpleDuration) || + mRepeatIteration != aRepeatIteration) + mHasChanged = PR_TRUE; + + mSimpleTime = aSimpleTime; + mSimpleDuration = aSimpleDuration; + mRepeatIteration = aRepeatIteration; + mLastValue = PR_FALSE; +} + +void +nsSMILAnimationFunction::SampleLastValue(const PRUint32& aRepeatIteration) +{ + if (mHasChanged || !mLastValue || mRepeatIteration != aRepeatIteration) + mHasChanged = PR_TRUE; + + mRepeatIteration = aRepeatIteration; + mLastValue = PR_TRUE; +} + +void +nsSMILAnimationFunction::ToActive(const PRInt64& aBeginTime) +{ + mBeginTime = aBeginTime; + mIsActive = PR_TRUE; + mIsFrozen = PR_FALSE; + mFrozenValue = nsnull; +} + +void +nsSMILAnimationFunction::ToInactive(PRBool aIsFrozen) +{ + mIsActive = PR_FALSE; + mIsFrozen = aIsFrozen; + mFrozenValue = nsnull; + mHasChanged = PR_TRUE; +} + +//---------------------------------------------------------------------- +// nsISMILComposable methods + +void +nsSMILAnimationFunction::ComposeResult(nsISMILAnimVal &aResult) +{ + mHasChanged = PR_FALSE; + + // This checks if mValues is empty so we don't need to check it again later + if (!IsActive()) + return; + + nsAutoLock lock(mCompositingLock); + + if (!mAttribute) + return; + + NS_ENSURE_TRUE(mSimpleTime >= 0,); + NS_ENSURE_TRUE(mSimpleDuration.IsResolved() || + mSimpleDuration.IsIndefinite(), ); + + nsCOMPtr result(mAttribute->Create()); + NS_ENSURE_TRUE(result,); + + if (mSimpleDuration.IsIndefinite() || + (GET_FLAG(mSetFlags, BF_VALUES) && mValues.Count() == 1)) { + + // Indefinite duration or only one value set: Always set the first value + nsISMILAnimVal* firstValue = mValues.SafeObjectAt(0); + NS_ENSURE_TRUE(firstValue,); + NS_ENSURE_SUCCESS(result->Set(*firstValue),); + + } else if (mLastValue) { + + // Sampling last value + nsISMILAnimVal* lastValue = mValues.SafeObjectAt(mValues.Count() - 1); + NS_ENSURE_TRUE(lastValue,); + if (mAccumulate.GetIntegerValue() && mRepeatIteration > 0) { + if (NS_FAILED(result->Repeat(mRepeatIteration, lastValue))) + NS_ENSURE_SUCCESS(result->Set(*lastValue),); + } else { + NS_ENSURE_SUCCESS(result->Set(*lastValue),); + } + + } else if (mFrozenValue && !mHasChanged) { + + // Frozen to animation + NS_ENSURE_SUCCESS(result->Set(*mFrozenValue),); + + } else { + + // Interpolation + NS_ENSURE_SUCCESS(InterpolateResult(*result, aResult),); + NS_ENSURE_SUCCESS(AccumulateResult(*result),); + + if (IsToAnimation() && mIsFrozen) { + mFrozenValue = mAttribute->Create(); + NS_ENSURE_TRUE(mFrozenValue,); + NS_ENSURE_SUCCESS(mFrozenValue->Set(*result),); + } + } + + // + // If additive animation isn't required or isn't supported, set the value. + // + if (!IsAdditive() || NS_FAILED(aResult.Add(*result))) + aResult.Set(*result); +} + +PRInt8 +nsSMILAnimationFunction::CompareTo(const nsISMILComposable& composable) const +{ + // + // Inactive animations sort first + // + if (!IsActive() && composable.IsActive()) + return -1; + + if (IsActive() && !composable.IsActive()) + return 1; + + // + // Sort based on begin time + // + if (LL_NE(mBeginTime, composable.GetBeginTime())) + return LL_CMP(mBeginTime, >, composable.GetBeginTime()) ? 1 : -1; + + // XXX When syncbase timing is implemented, we next need to sort based on + // dependencies + + // + // Animations that appear later in the document sort after those earlier in + // the document + // + NS_ASSERTION(mDocumentPosition != composable.GetDocumentPosition(), + "Two animations cannot have the same document position!"); + + return (mDocumentPosition > composable.GetDocumentPosition()) + ? 1 + : (mDocumentPosition == composable.GetDocumentPosition()) ? 0 : -1; +} + +PRBool +nsSMILAnimationFunction::IsToAnimation() const +{ + return (!GET_FLAG(mSetFlags, BF_VALUES) && mTo && !mFrom); +} + +const PRInt64& +nsSMILAnimationFunction::GetBeginTime() const +{ + return mBeginTime; +} + +PRUint16 +nsSMILAnimationFunction::GetDocumentPosition() const +{ + return mDocumentPosition; +} + +PRBool +nsSMILAnimationFunction::IsActive() const +{ + // + // Even if an animation should be active, if its attributes are set + // incorrectly, it will have no effect and should be considered by the + // compositor to be inactive. + // + // Frozen animations should be considered active for the purposes of + // compositing. + // + return ((mIsActive || mIsFrozen) && mValues.Count() > 0 && mErrorFlags == 0); +} + + +PRBool +nsSMILAnimationFunction::WillReplace() const +{ + /* + * In IsAdditive() we don't consider to animation to be additive as it is + * a special case that is dealt with differently in the compositing method but + * here we return false for to animation as it builds on the underlying value + * unless its a frozen to animation. + */ + return !(IsAdditive() || IsToAnimation()) || + (IsToAnimation() && mIsFrozen && !mHasChanged); +} + +PRBool +nsSMILAnimationFunction::HasChanged() const +{ + return mHasChanged; +} + +//---------------------------------------------------------------------- +// Implementation helpers + +nsresult +nsSMILAnimationFunction::InterpolateResult +( + nsISMILAnimVal& aResult, + nsISMILAnimVal& aBaseValue +) +{ + double fTime; + double fDur; + double simpleDistance; + double intervalDistance; + PRInt32 index; + nsISMILAnimVal* from = nsnull; + nsISMILAnimVal* to = nsnull; + const PRInt64& dur = mSimpleDuration.GetMillis(); + + LL_L2D(fTime, mSimpleTime); + LL_L2D(fDur, dur); + + if (LL_CMP(mSimpleTime, >=, dur) || !LL_GE_ZERO(mSimpleTime)) { + NS_ERROR("Animation sampled outside interval."); + return NS_ERROR_FAILURE; + } + + if (mValues.Count() < 2 && !IsToAnimation()) { + NS_ERROR("Unexpected number of values."); + return NS_ERROR_FAILURE; + } + + simpleDistance = (fDur > 0.0) ? fTime / fDur : 0.0; + +#ifdef ALLOW_BAD_KEYTIMES + if (GET_FLAG(mSetFlags, BF_KEY_TIMES)) { + PRFloat64 first = *NS_STATIC_CAST(PRFloat64*, mKeyTimes[0]); + if (first > 0.0 && simpleDistance < first) { + if (!IsToAnimation()) + aResult.Set(*mValues[0]); + return NS_OK; + } + PRFloat64 last = + *NS_STATIC_CAST(PRFloat64*, mKeyTimes[mKeyTimes.Count() - 1]); + if (last < 1.0 && simpleDistance >= last) { + if (IsToAnimation()) + aResult.Set(*mValues[0]); + else + aResult.Set(*mValues[mValues.Count() - 1]); + return NS_OK; + } + } +#endif + + ScaleSimpleDistance(simpleDistance); + + if (IsToAnimation()) { + from = &aBaseValue; + to = mValues.SafeObjectAt(0); + NS_ENSURE_TRUE(to, NS_ERROR_FAILURE); + intervalDistance = simpleDistance; + ScaleIntervalDistance(intervalDistance, 0, 1); + } else { + index = (PRInt32) floor(simpleDistance * (mValues.Count() - 1)); + + from = mValues.SafeObjectAt(index); + NS_ENSURE_TRUE(from, NS_ERROR_FAILURE); + + to = mValues.SafeObjectAt(index + 1); + NS_ENSURE_TRUE(to, NS_ERROR_FAILURE); + + intervalDistance = simpleDistance * (mValues.Count() - 1) - index; + ScaleIntervalDistance(intervalDistance, index, mValues.Count() - 1); + } + + return from->Interpolate(*to, + NS_STATIC_CAST(float, intervalDistance), + aResult); +} + +nsresult +nsSMILAnimationFunction::AccumulateResult(nsISMILAnimVal& aResult) +{ + if (!IsToAnimation() && mAccumulate.GetIntegerValue() && mRepeatIteration) + { + nsCOMPtr repeatValue(mAttribute->Create()); + NS_ENSURE_TRUE(repeatValue, NS_ERROR_FAILURE); + + nsISMILAnimVal* lastValue = mValues.SafeObjectAt(mValues.Count() - 1); + NS_ENSURE_TRUE(lastValue, NS_ERROR_FAILURE); + + // If the target attribute doesn't support addition, Repeat will fail and we + // leave aResult untouched. + if (NS_SUCCEEDED(repeatValue->Repeat(mRepeatIteration - 1, lastValue))) + aResult.Add(*repeatValue); + } + + return NS_OK; +} + +/* + * Scale the simple distance taking into account any keyTimes. + */ +void +nsSMILAnimationFunction::ScaleSimpleDistance(PRFloat64& dist) +{ + if (!GET_FLAG(mSetFlags, BF_KEY_TIMES)) + return; + + PRUint32 numTimes = mKeyTimes.Count(); + + if (numTimes < 2) + return; + + PRUint32 i = 0; + for (; + i < numTimes - 2 && dist >= *NS_STATIC_CAST(PRFloat64*, mKeyTimes[i+1]); + ++i); + + PRFloat64& intervalStart = *NS_STATIC_CAST(PRFloat64*, mKeyTimes[i]); + PRFloat64& intervalEnd = *NS_STATIC_CAST(PRFloat64*, mKeyTimes[i+1]); + + PRFloat64 intervalLength = intervalEnd - intervalStart; + if (intervalLength <= 0.0) { + dist = intervalStart; + return; + } + + dist = (i + (dist - intervalStart) / intervalLength) * + 1.0 / (PRFloat64)(numTimes - 1); +} + +/* + * Scale the interval distance taking into account any keySplines. + */ +void +nsSMILAnimationFunction::ScaleIntervalDistance(PRFloat64& aDist, + PRUint32 aIntervalIndex, + PRUint32 aNumIntervals) +{ + if (mCalcMode.GetIntegerValue() != calc_spline) + return; + + if (!GET_FLAG(mSetFlags, BF_KEY_SPLINES)) + return; + + NS_ASSERTION(aIntervalIndex >= 0 && + aIntervalIndex < (PRUint32)mKeySplines.Count(), + "Invalid interval index."); + NS_ASSERTION(aNumIntervals >= 1, "Invalid number of intervals."); + + if (aIntervalIndex < 0 || + aIntervalIndex >= (PRUint32)mKeySplines.Count() || + aNumIntervals < 1) + return; + + nsSMILKeySpline *spline = + NS_STATIC_CAST(nsSMILKeySpline*, mKeySplines[aIntervalIndex]); + aDist = spline->GetSplineValue(aDist); +} + +/* + * SMILANIM specifies the following rules for animation function values: + * + * (1) if values is set, it overrides everything + * (2) for from/to/by animation at least to or by must be specified, from on its + * own (or nothing) is an error--which we will ignore + * (3) if both by and to are specified only to will be used, by will be ignored + * (4) if by is specified without from (by animation), forces additive behaviour + * (5) if to is specified without from (to animation), special care needs to be + * taken when compositing animation as such animations are composited last. + * + * This helper method applies these rules to fill in the values list and to set + * some internal state. + */ +void +nsSMILAnimationFunction::FillValuesArray() +{ + if (!GET_FLAG(mSetFlags, BF_VALUES)) { + mValues.Clear(); + + if (mTo) { + if (mFrom) { + mValues.AppendObject(mFrom); + mValues.AppendObject(mTo); + } else { + mValues.AppendObject(mTo); + } + } else if (mBy) { + if (mFrom) { + // + // Set values to 'from; from + to' + // + mValues.AppendObject(mFrom); + nsCOMPtr to (mAttribute->Create()); + if (to && + NS_SUCCEEDED(to->Set(*mFrom)) && + NS_SUCCEEDED(to->Add(*mBy))) { + mValues.AppendObject(to); + } else { + mValues.Clear(); + } + } else { + // + // Set values to '0; by' + // + nsCOMPtr from (mAttribute->Create()); + if (from) { + mValues.AppendObject(from); + mValues.AppendObject(mBy); + } else { + mValues.Clear(); + } + } + } + // else, do nothing, mValues has been cleared already. + } + + // mValues has changed, do we still have the right number of keySplines and + // keyTimes? + CheckKeyTimes(); + CheckKeySplines(); +} + +inline PRBool +nsSMILAnimationFunction::IsAdditive() const +{ + /* + * Animation is additive if: + * + * (1) additive = "sum" (mAdditive == true), or + * (2) it is 'by animation' (by is set, from and values are not) + * + * Although animation is not additive if it is 'to animation' + */ + return (!IsToAnimation() && + (mAdditive.GetIntegerValue() || + (!GET_FLAG(mSetFlags, BF_VALUES) && mBy && !mFrom))); +} + +inline void +nsSMILAnimationFunction::ClearKeyTimes() +{ + PRUint32 i, count = mKeyTimes.Count(); + for (i=0; i < count; ++i) + delete NS_STATIC_CAST(PRFloat64*, mKeyTimes[i]); + mKeyTimes.Clear(); +} + +inline void +nsSMILAnimationFunction::ClearKeySplines() +{ + PRUint32 i, count = mKeySplines.Count(); + for (i=0; i < count; ++i) + delete NS_STATIC_CAST(nsSMILKeySpline*, mKeySplines[i]); + mKeySplines.Clear(); +} + +/** + * Performs checks for the keyTimes attribute required by the SMIL spec but + * which depend on other attributes and therefore needs to be updated as + * dependent attributes are set. + */ +void +nsSMILAnimationFunction::CheckKeyTimes() +{ + if (!GET_FLAG(mSetFlags, BF_KEY_TIMES)) + return; + + // attribute is ignored for calcMode = paced + if (mCalcMode.GetIntegerValue() == calc_paced) { + SET_FLAG(mErrorFlags, BF_KEY_TIMES, PR_FALSE); + return; + } + + if (mKeyTimes.Count() < 1) { + // keyTimes isn't set or failed preliminary checks + SET_FLAG(mErrorFlags, BF_KEY_TIMES, PR_TRUE); + return; + } + + // no. keyTimes == no. values + if ((mKeyTimes.Count() != mValues.Count() && !IsToAnimation()) || + (IsToAnimation() && mKeyTimes.Count() != 2)) { + SET_FLAG(mErrorFlags, BF_KEY_TIMES, PR_TRUE); + return; + } + + // special handling if there is only one keyTime. The spec doesn't say what to + // do in this case so we allow the keyTime to be either 0 or 1. + if (mKeyTimes.Count() == 1) { + PRFloat64& time = *NS_STATIC_CAST(PRFloat64*, mKeyTimes[0]); + SET_FLAG(mErrorFlags, BF_KEY_TIMES, !(time == 0.0 || time == 1.0)); + return; + } + + // there is a contradiction in the spec here. We're told the last value must + // be 1 for linear or spline calcMode's but then an example is given later of + // a from-to animation with a spline calcMode and keyTimes "0.0; 0.7". + +#ifndef ALLOW_BAD_KEYTIMES + // first value must be 0 + if (*NS_STATIC_CAST(PRFloat64*,mKeyTimes[0]) != 0.0) { + SET_FLAG(mErrorFlags, BF_KEY_TIMES, PR_TRUE); + return; + } + + // last value must be 1 for linear or spline calcMode's + if (mCalcMode.GetIntegerValue() == calc_linear || + mCalcMode.GetIntegerValue() == calc_spline) { + PRInt32 count = mKeyTimes.Count(); + PRFloat64* lastValue = NS_STATIC_CAST(PRFloat64*, mKeyTimes[count - 1]); + if (!lastValue || *lastValue != 1.0) { + SET_FLAG(mErrorFlags, BF_KEY_TIMES, PR_TRUE); + return; + } + } +#endif + + SET_FLAG(mErrorFlags, BF_KEY_TIMES, PR_FALSE); +} + +void +nsSMILAnimationFunction::CheckKeySplines() +{ + // attribute is ignored if calc mode is not spline + if (mCalcMode.GetIntegerValue() != calc_spline) { + SET_FLAG(mErrorFlags, BF_KEY_SPLINES, PR_FALSE); + return; + } + + // calc mode is spline but the attribute is not set + if (!GET_FLAG(mSetFlags, BF_KEY_SPLINES)) { + SET_FLAG(mErrorFlags, BF_KEY_SPLINES, PR_FALSE); + return; + } + + if (mKeySplines.Count() < 1) { + // keyTimes isn't set or failed preliminary checks + SET_FLAG(mErrorFlags, BF_KEY_SPLINES, PR_TRUE); + return; + } + + // ignore splines if there's only one value + if (mValues.Count() == 1 && !IsToAnimation()) { + SET_FLAG(mErrorFlags, BF_KEY_SPLINES, PR_FALSE); + return; + } + + // no. keySpline specs == no. values - 1 + PRInt32 splineSpecs = mKeySplines.Count(); + if ((splineSpecs != mValues.Count() - 1 && !IsToAnimation()) || + (IsToAnimation() && splineSpecs != 1)) { + SET_FLAG(mErrorFlags, BF_KEY_SPLINES, PR_TRUE); + return; + } + + SET_FLAG(mErrorFlags, BF_KEY_SPLINES, PR_FALSE); +} + Index: content/smil/src/nsSMILAnimationRegistry.cpp =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsSMILAnimationRegistry.cpp diff -N content/smil/src/nsSMILAnimationRegistry.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ content/smil/src/nsSMILAnimationRegistry.cpp 5 Nov 2005 04:39:11 -0000 @@ -0,0 +1,337 @@ +/* -*- 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 + * + * 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 ***** */ + +#include "nsSMILAnimationRegistry.h" +#include "nsISMILAnimationObserver.h" +#include "nsISMILAnimAttr.h" +#include "nsISMILComposable.h" +#include "nsSMILTimedDocumentRoot.h" +#include "nsSMILCompositor.h" +#include "nsAutoLock.h" + +//////////////////////////////////////////////////////////////////////// +// nsSMILAnimationRegistry implementation + +struct CompositorEntry +{ + nsISMILAnimAttr* key; + nsSMILCompositor compositor; +}; + +//---------------------------------------------------------------------- +// ctors, dtors, factory methods + +nsSMILAnimationRegistry::~nsSMILAnimationRegistry() +{ + if (mController && mTimedDocumentRoot) + mController->RemoveTimeContainer(mTimedDocumentRoot); + + CompositorEntry* entry; + PRInt32 count = mCompositors.Count(); + + PR_Lock(mAnimationLock); + + for (PRInt32 i = 0; i < count; ++i) { + entry = NS_STATIC_CAST(CompositorEntry*, mCompositors[i]); + mCompositors.ReplaceElementAt(nsnull, i); + delete entry; + } + + mCompositors.Clear(); + + PR_Unlock(mAnimationLock); + PR_DestroyLock(mAnimationLock); +} + +nsISMILAnimationRegistry* +NS_NewSMILAnimationRegistry() +{ + nsSMILAnimationRegistry* animationRegistry = new nsSMILAnimationRegistry(); + + if (!animationRegistry) + return nsnull; + + nsresult rv = animationRegistry->Init(); + if (NS_FAILED(rv)) { + delete animationRegistry; + animationRegistry = nsnull; + } + + return animationRegistry; +} + +nsresult +nsSMILAnimationRegistry::Init() +{ + mTimedDocumentRoot = new nsSMILTimedDocumentRoot(this); + NS_ENSURE_TRUE(mTimedDocumentRoot, NS_ERROR_OUT_OF_MEMORY); + + mTimedDocumentRoot->Pause(); + + mAnimationLock = PR_NewLock(); + NS_ENSURE_TRUE(mAnimationLock, NS_ERROR_OUT_OF_MEMORY); + + return NS_OK; +} + +//---------------------------------------------------------------------- +// nsISupports methods: + +NS_IMPL_ISUPPORTS1(nsSMILAnimationRegistry, + nsISMILAnimationRegistry); + +//---------------------------------------------------------------------- +// nsISMILAnimationRegistry methods: + +nsresult +nsSMILAnimationRegistry::SetController(nsISMILAnimationController* aController) +{ + nsresult rv = NS_OK; + + NS_ENSURE_TRUE(mTimedDocumentRoot, NS_ERROR_FAILURE); + + if (mController) { + rv = mController->RemoveTimeContainer(mTimedDocumentRoot); + NS_ENSURE_SUCCESS(rv,rv); + } + + mController = aController; + + if (mController) + rv = mController->AddTimeContainer(mTimedDocumentRoot); + + return rv; +} + +void +nsSMILAnimationRegistry::SetObserver(nsISMILAnimationObserver* aObserver) +{ + if (aObserver) { + mObserver = do_GetWeakReference(aObserver); + } else { + mObserver = nsnull; + } +} + +nsresult +nsSMILAnimationRegistry::Start() +{ + NS_ENSURE_TRUE(mTimedDocumentRoot,NS_ERROR_FAILURE); + if (!mStarted) { + mTimedDocumentRoot->Resume(); + mStarted = PR_TRUE; + } + return NS_OK; +} + +void +nsSMILAnimationRegistry::Pause() +{ + NS_ENSURE_TRUE(mTimedDocumentRoot,); + NS_ENSURE_TRUE(mStarted,); + mTimedDocumentRoot->Pause(); +} + +void +nsSMILAnimationRegistry::Unpause() +{ + NS_ENSURE_TRUE(mTimedDocumentRoot,); + NS_ENSURE_TRUE(mStarted,); + mTimedDocumentRoot->Resume(); +} + +PRBool +nsSMILAnimationRegistry::IsPaused() +{ + if (!mStarted) + return PR_TRUE; + + NS_ENSURE_TRUE(mTimedDocumentRoot,PR_FALSE); + + return mTimedDocumentRoot->IsPaused(); +} + +float +nsSMILAnimationRegistry::GetCurrentTime() +{ + PRFloat64 fCurrentTime; + PRInt64 currentTime = mTimedDocumentRoot->GetDocumentTime(); + LL_L2D(fCurrentTime, currentTime); + return (float)(fCurrentTime / PR_MSEC_PER_SEC); +} + +nsresult +nsSMILAnimationRegistry::SetCurrentTime(float aSeconds) +{ + PRInt64 lSeconds; + LL_D2L(lSeconds, aSeconds); + LL_MUL(lSeconds, PR_MSEC_PER_SEC, lSeconds); + return mTimedDocumentRoot->SeekToTime(lSeconds); +} + +nsresult +nsSMILAnimationRegistry::RegisterComposable(nsISMILAnimAttr* aTargetAttr, + nsISMILComposable* aComposable) +{ + NS_ENSURE_ARG_POINTER(aTargetAttr); + NS_ENSURE_ARG_POINTER(aComposable); + + nsSMILCompositor* compositor = nsnull; + CompositorEntry* entry; + + nsAutoLock lock(mAnimationLock); + + // + // Iterate in reverse as if a compositor already exists for this attribute it + // is most likely to be the most recently added entry. + // + for (PRInt32 i = mCompositors.Count() - 1; i >= 0 && !compositor; --i) { + entry = (CompositorEntry*)mCompositors[i]; + if (entry && entry->key == aTargetAttr) + compositor = &entry->compositor; + } + + if (!compositor) { + entry = new CompositorEntry(); + NS_ENSURE_TRUE(entry,NS_ERROR_OUT_OF_MEMORY); + + nsresult rv = entry->compositor.Init(aTargetAttr); + NS_ENSURE_SUCCESS(rv,rv); + + entry->key = aTargetAttr; + if (!mCompositors.AppendElement(entry)) { + delete entry; + return NS_ERROR_FAILURE; + } + + compositor = &entry->compositor; + } + + return compositor->AddComposable(aComposable); +} + +nsresult +nsSMILAnimationRegistry::UnregisterComposable(nsISMILComposable* aComposable) +{ + NS_ENSURE_ARG_POINTER(aComposable); + + PRBool found = PR_FALSE; + nsresult result = NS_OK; + nsresult rv = NS_ERROR_FAILURE; + CompositorEntry* entry; + PRInt32 count = mCompositors.Count(); + + nsAutoLock lock(mAnimationLock); + + for (PRInt32 i = 0; i < count; ++i) { + entry = (CompositorEntry*)mCompositors[i]; + if (entry) { + rv = entry->compositor.RemoveComposable(aComposable); + + // This rather complicated error handling just ensures that we report the + // first error that occurs, or a generic error if the item wasn't found. + if (NS_SUCCEEDED(result)) + result = rv; + found = PR_TRUE; + } + + // Even if the entry now no longer has any compositors we don't bother + // deleting it as it may be re-used again later. + } + + return (found) ? rv : NS_ERROR_FAILURE; +} + +nsresult +nsSMILAnimationRegistry::RegisterTimedElement(nsISMILTimedElement *aElement) +{ + return (mTimedDocumentRoot) ? mTimedDocumentRoot->AddTimedElement(aElement) + : NS_ERROR_FAILURE; +} + +nsresult +nsSMILAnimationRegistry::UnregisterTimedElement(nsISMILTimedElement *aElement) +{ + return (mTimedDocumentRoot) ? mTimedDocumentRoot->RemoveTimedElement(aElement) + : NS_ERROR_FAILURE; +} + +void +nsSMILAnimationRegistry::StartSample() +{ + if (mObserver) { + nsCOMPtr observer = do_QueryReferent(mObserver); + if (observer) + observer->StartSample(); + } + + // Do any pre-animation actions here, e.g. acquiring locks, blocking scripts + // etc. +} + +void +nsSMILAnimationRegistry::EndSample() +{ + CompositorEntry* entry; + PRInt32 count = mCompositors.Count(); + nsCOMPtr observer; + + if (mObserver) + observer = do_QueryReferent(mObserver); + + if (observer) + observer->StartCompositing(); + + PR_Lock(mAnimationLock); + + for (PRInt32 i = 0; i < count; ++i) { + entry = NS_STATIC_CAST(CompositorEntry*, mCompositors[i]); + if (entry) + entry->compositor.ComposeSample(); + } + + PR_Unlock(mAnimationLock); + + if (observer) + observer->EndCompositing(); + + // Release any locks etc. + + if (observer) + observer->EndSample(); +} + Index: content/smil/src/nsSMILAnimationRegistry.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsSMILAnimationRegistry.h diff -N content/smil/src/nsSMILAnimationRegistry.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ content/smil/src/nsSMILAnimationRegistry.h 5 Nov 2005 04:39:11 -0000 @@ -0,0 +1,96 @@ +/* -*- 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 + * + * 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_SMILANIMATIONREGISTRY_H__ +#define __NS_SMILANIMATIONREGISTRY_H__ + +#include "nsISMILAnimationRegistry.h" +#include "nsISMILAnimationController.h" +#include "nsVoidArray.h" +#include "nsAutoPtr.h" +#include "nsWeakPtr.h" + +class nsSMILTimedDocumentRoot; + +class nsSMILAnimationRegistry : public nsISMILAnimationRegistry +{ +public: + ~nsSMILAnimationRegistry(); + + NS_DECL_ISUPPORTS + + virtual void StartSample(); + virtual void EndSample(); + + // nsISMILAnimationRegistry + virtual nsresult SetController(nsISMILAnimationController* aController); + virtual void SetObserver(nsISMILAnimationObserver* aObserver); + virtual nsresult Start(); + virtual void Pause(); + virtual void Unpause(); + virtual PRBool IsPaused(); + virtual float GetCurrentTime(); + virtual nsresult SetCurrentTime(float aSeconds); + virtual nsresult RegisterComposable(nsISMILAnimAttr *aTargetAttr, + nsISMILComposable *aComposable); + virtual nsresult UnregisterComposable(nsISMILComposable *aComposable); + virtual nsresult RegisterTimedElement(nsISMILTimedElement *aElement); + virtual nsresult UnregisterTimedElement(nsISMILTimedElement *aElement); + +protected: + friend nsISMILAnimationRegistry* NS_NewSMILAnimationRegistry(); + + nsresult Init(); + + nsVoidArray mCompositors; + nsRefPtr mTimedDocumentRoot; + nsCOMPtr mController; + nsWeakPtr mObserver; + PRBool mStarted; + PRLock* mAnimationLock; + +private: + // This class should only be created by the factory method + nsSMILAnimationRegistry() : mStarted(PR_FALSE) {} + + // Pass by value and assignment should not be used + nsSMILAnimationRegistry(const nsSMILAnimationRegistry& other); + nsSMILAnimationRegistry& operator=(const nsSMILAnimationRegistry& right); +}; + +#endif // __NS_SMILANIMATIONREGISTRY_H__ + Index: content/smil/src/nsSMILAtomList.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsSMILAtomList.h diff -N content/smil/src/nsSMILAtomList.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ content/smil/src/nsSMILAtomList.h 5 Nov 2005 04:39:11 -0000 @@ -0,0 +1,79 @@ +/* -*- 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 mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * 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 ***** */ + +/****** + + This file contains the list of all SMIL nsIAtoms and their values + + It is designed to be used as inline input to nsSMILAtoms.cpp *only* + through the magic of C preprocessing. + + All entires must be enclosed in the macro SMIL_ATOM which will have cruel + and unusual things done to it + + It is recommended (but not strictly necessary) to keep all entries + in alphabetical order + + The first argument to SMIL_ATOM is the C++ identifier of the atom + The second argument is the string value of the atom + + ******/ + +// calc modes +SMIL_ATOM(discrete, "discrete") +SMIL_ATOM(linear, "linear") +SMIL_ATOM(paced, "paced") +SMIL_ATOM(spline, "spline") + +// fill modes +SMIL_ATOM(freeze, "freeze") +SMIL_ATOM(remove, "remove") + +// additive +SMIL_ATOM(replace, "replace") +SMIL_ATOM(sum, "sum") + +// accumulate +SMIL_ATOM(none, "none") +// sum is already listed + +// restart modes +SMIL_ATOM(always, "always") +SMIL_ATOM(whennotactive, "whenNotActive") +SMIL_ATOM(never, "never") + Index: content/smil/src/nsSMILAtoms.cpp =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsSMILAtoms.cpp diff -N content/smil/src/nsSMILAtoms.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ content/smil/src/nsSMILAtoms.cpp 5 Nov 2005 04:39:12 -0000 @@ -0,0 +1,63 @@ +/* -*- 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 mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * 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 ***** */ + +#include "nsSMILAtoms.h" +#include "nsStaticAtom.h" +#include "nsMemory.h" + +// define storage for all atoms +#define SMIL_ATOM(_name, _value) nsIAtom* nsSMILAtoms::_name; +#include "nsSMILAtomList.h" +#undef SMIL_ATOM + +static const nsStaticAtom SMILAtoms_info[] = { +#define SMIL_ATOM(name_, value_) { value_, &nsSMILAtoms::name_ }, +#include "nsSMILAtomList.h" +#undef SMIL_ATOM +}; + +void nsSMILAtoms::AddRefAtoms() +{ + static bool atomsRegistered = PR_FALSE; + + if (!atomsRegistered) { + NS_RegisterStaticAtoms(SMILAtoms_info, NS_ARRAY_LENGTH(SMILAtoms_info)); + atomsRegistered = PR_TRUE; + } +} + Index: content/smil/src/nsSMILAtoms.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsSMILAtoms.h diff -N content/smil/src/nsSMILAtoms.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ content/smil/src/nsSMILAtoms.h 5 Nov 2005 04:39:12 -0000 @@ -0,0 +1,66 @@ +/* -*- 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 mozilla.org code. + * + * The Initial Developer of the Original Code is + *