Index: /cvsroot/mozilla/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 +++ /cvsroot/mozilla/content/smil/Makefile.in 14 Sep 2005 10:44:00 -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 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 ***** + +DEPTH = ../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +DIRS = public src + +include $(topsrcdir)/config/rules.mk + Index: /cvsroot/mozilla/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 +++ /cvsroot/mozilla/content/smil/public/Makefile.in 14 Sep 2005 10:44:01 -0000 @@ -0,0 +1,61 @@ +# +# ***** 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 ***** + +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 \ + nsISMILAnimationRegistry.h \ + nsISMILComposable.h \ + nsISMILTimeClient.h \ + nsISMILTimeContainer.h \ + nsISMILTimedElement.h \ + $(NULL) + +include $(topsrcdir)/config/rules.mk + Index: /cvsroot/mozilla/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 +++ /cvsroot/mozilla/content/smil/public/nsISMILAnimAttr.h 14 Sep 2005 10:44:01 -0000 @@ -0,0 +1,70 @@ +/* -*- 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 SVG project. + * + * 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 + +// {c487920a-7d12-40ff-bf3b-c39dd4797cff} +#define NS_ISMILANIMATTR_IID \ +{ 0xc487920a, 0x7d12, 0x40ff, { 0xbf, 0x3b, 0xc3, 0x9d, 0xd4, 0x79, 0x7c, 0xff } } + +class nsISMILAnimAttr : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISMILANIMATTR_IID) + + virtual nsISMILAnimVal* GetBaseValue()=0; + virtual nsresult SetAnimValue(nsISMILAnimVal& aValue)=0; + + /* + * Factory methods + * + * NOTE: By moving these to nsISMILAnimVal, we'd be able to remove the + * dependency on this interface by nsSMILAnimationFunction and be one step + * closer to removing this interface altogether. + */ + virtual nsresult Create(nsISMILAnimVal** aResult) const = 0; + + virtual nsresult CreateFromSpec(const nsAString& aSpec, + nsISMILAnimVal** aResult) const = 0; +}; + +#endif // __NS_ISMILANIMATTR_H__ + Index: /cvsroot/mozilla/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 +++ /cvsroot/mozilla/content/smil/public/nsISMILAnimElement.h 14 Sep 2005 10:44:01 -0000 @@ -0,0 +1,58 @@ +/* -*- 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 SVG project. + * + * 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 } } + +class nsISMILAnimElement : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISMILANIMELEMENT_IID) + + virtual nsISMILAnimAttr* + GetAnimAttribute(PRInt32 aNamespaceID, nsIAtom* aName)=0; +}; + +#endif // __NS_ISMILANIMELEMENT__ + Index: /cvsroot/mozilla/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 +++ /cvsroot/mozilla/content/smil/public/nsISMILAnimVal.h 14 Sep 2005 10:44:01 -0000 @@ -0,0 +1,127 @@ +/* -*- 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 SVG project. + * + * 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 True on success, or false if there is no notion of distance for + * the underlying data type. + */ + virtual bool 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 (return false) 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 True on success, false on failure. + */ + virtual bool 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 True on success, false on failure such as when the underlying + * type of the specified object differs. + */ + virtual bool Set(const nsISMILAnimVal& aNewVal) = 0; + + /** + * Repeats this value or the specified value a number of times. This method + * will fail (return false) 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 True on success, false on failure. + */ + virtual bool Repeat(PRUint32 aCount, + const nsISMILAnimVal* aRepeatValue = nsnull) = 0; +}; + +#endif // __NS_ISMILANIMVAL_H__ + Index: /cvsroot/mozilla/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 +++ /cvsroot/mozilla/content/smil/public/nsISMILAnimationController.h 14 Sep 2005 10:44:02 -0000 @@ -0,0 +1,67 @@ +/* -*- 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 SVG project. + * + * 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; + +//////////////////////////////////////////////////////////////////////// +// 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; + + // 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(); + +#endif // __NS_ISMILANIMATIONCONTROLLER_H__ + Index: /cvsroot/mozilla/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 +++ /cvsroot/mozilla/content/smil/public/nsISMILAnimationFunction.h 14 Sep 2005 10:44:02 -0000 @@ -0,0 +1,104 @@ + +/* -*- 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 SVG project. + * + * 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 Init(nsISMILAnimAttr& aAttribute)=0; + virtual PRBool IsInitialised()=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; + + virtual void SetDocumentPosition(PRUint16 aDocPosition)=0; +}; + +nsISMILAnimationFunction* NS_NewSMILAnimationFunction(); + +#endif //__NS_ISMILANIMFUNCTION_H__ + Index: /cvsroot/mozilla/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 +++ /cvsroot/mozilla/content/smil/public/nsISMILAnimationRegistry.h 14 Sep 2005 10:44:02 -0000 @@ -0,0 +1,71 @@ +/* -*- 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 SVG project. + * + * 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 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) + + virtual nsresult SetController(nsISMILAnimationController* aController)=0; + virtual void Pause()=0; + virtual void Unpause()=0; + virtual PRBool IsPaused()=0; + virtual float GetCurrentTime()=0; + virtual nsresult SetCurrentTime(float aSeconds)=0; + virtual nsresult RegisterComposable(nsISMILAnimAttr* aTargetAttr, + nsISMILComposable* aComposable)=0; + virtual nsresult UnregisterComposable(nsISMILComposable* aComposable)=0; + virtual nsresult RegisterTimedElement(nsISMILTimedElement* aElement)=0; + virtual nsresult UnregisterTimedElement(nsISMILTimedElement* aElement)=0; +}; + +nsISMILAnimationRegistry* NS_NewSMILAnimationRegistry(); + +#endif // __NS_ISMILANIMATIONREGISTRY_H__ + Index: /cvsroot/mozilla/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 +++ /cvsroot/mozilla/content/smil/public/nsISMILComposable.h 14 Sep 2005 10:44:02 -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 SVG project. + * + * 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 + +// {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 in the future 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; +}; + +#endif // __NS_ISMILCOMPOSABLE_H__ + Index: /cvsroot/mozilla/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 +++ /cvsroot/mozilla/content/smil/public/nsISMILTimeClient.h 14 Sep 2005 10:44:02 -0000 @@ -0,0 +1,64 @@ +/* -*- 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 SVG project. + * + * 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) + + virtual void SampleAt(const PRInt64& aSimpleTime, + const nsSMILTimeValue& aSimpleDuration, + const PRUint32& aRepeatIteration)=0; + + virtual void SampleLastValue(const PRUint32& aRepeatIteration)=0; + + virtual void ToActive(const PRInt64& aBeginTime)=0; + + virtual void ToInactive()=0; +}; + +#endif // __NS_ISMILTIMECLIENT_H__ Index: /cvsroot/mozilla/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 +++ /cvsroot/mozilla/content/smil/public/nsISMILTimeContainer.h 14 Sep 2005 10:44:03 -0000 @@ -0,0 +1,67 @@ +/* -*- 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 SVG project. + * + * 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 } } + +// When implementing SMIL 2.0 time containers, this would inherit from +// nsISMILTimedElement, amongst other changes +class nsISMILTimeContainer : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISMILTIMECONTAINER_IID) + + virtual nsresult Pause()=0; + virtual nsresult Resume()=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; + + virtual nsresult AddTimedElement(nsISMILTimedElement* aElement)=0; + virtual nsresult RemoveTimedElement(nsISMILTimedElement* aElement)=0; +}; + +#endif // __NS_ISMILTIMECONTAINER_H__ + Index: /cvsroot/mozilla/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 +++ /cvsroot/mozilla/content/smil/public/nsISMILTimedElement.h 14 Sep 2005 10:44:03 -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 SVG project. + * + * 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 "nsWeakReference.h" + +class nsISMILTimeClient; +class nsSMILTimeValue; +class nsSMILInstanceTime; + +//////////////////////////////////////////////////////////////////////// +// nsISMILTimedElement + +// {c5f60446-5c1a-4f3b-8ce3-646199ac97f2} +#define NS_ISMILTIMEDELEMENT_IID \ +{ 0xc5f60446, 0x5c1a, 0x4f3b, { 0x8c, 0xe3, 0x64, 0x61, 0x99, 0xac, 0x97, 0xf2 } } + +class nsISMILTimedElement : public nsSupportsWeakReference +{ +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 a 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; + + /** + * 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 + * to be sampled with the appropriate simple time. + * + * @param aDocumentTime The document time at which to sample. + */ + virtual void SampleAt(const PRInt64& aDocumentTime)=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: /cvsroot/mozilla/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 +++ /cvsroot/mozilla/content/smil/src/Makefile.in 14 Sep 2005 10:44:03 -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 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 ***** + +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 \ + js \ + layout \ + content \ + necko \ + xpconnect \ + docshell \ + webshell \ + imglib2 \ + unicharutil \ + locale \ + $(NULL) + +CPPSRCS = \ + nsSMILAnimationController.cpp \ + nsSMILAnimationFunction.cpp \ + nsSMILAnimationRegistry.cpp \ + nsSMILCompositor.cpp \ + nsSMILInstanceTime.cpp \ + nsSMILInterval.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: /cvsroot/mozilla/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 +++ /cvsroot/mozilla/content/smil/src/nsSMILAnimationController.cpp 14 Sep 2005 10:44:04 -0000 @@ -0,0 +1,253 @@ +/* -*- 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 SVG project. + * + * 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" + +class nsSMILAnimationController : public nsISMILAnimationController, + public nsSupportsWeakReference, + public nsITimerCallback +{ +public: + virtual ~nsSMILAnimationController(); + + NS_DECL_ISUPPORTS + NS_DECL_NSITIMERCALLBACK + + // nsISMILAnimationController + virtual nsresult Pause(); + virtual nsresult Resume(); + virtual nsresult AddTimeContainer(nsISMILTimeContainer* aContainer); + virtual nsresult RemoveTimeContainer(nsISMILTimeContainer* aContainer); + +protected: + friend nsISMILAnimationController* NS_NewSMILAnimationController(); + + nsresult Init(); + nsresult StartTimer(); + nsresult StopTimer(); + void SampleChildren(); + + nsCOMPtr mTimer; + nsCOMArray mTimeContainers; +}; + +//////////////////////////////////////////////////////////////////////// +// nsSMILAnimationController implementation + +//---------------------------------------------------------------------- +// ctors, dtors, factory methods + +nsSMILAnimationController::~nsSMILAnimationController() +{ + if (mTimer) + mTimer->Cancel(); +} + +nsISMILAnimationController* NS_NewSMILAnimationController() +{ + nsSMILAnimationController* animationController = + new nsSMILAnimationController(); + + if (animationController) + { + nsresult rv = animationController->Init(); + if (NS_FAILED(rv)) + { + delete animationController; + animationController = nsnull; + } + } + + return animationController; +} + + +//---------------------------------------------------------------------- +// nsISupports methods: + +NS_IMPL_ISUPPORTS3(nsSMILAnimationController, + nsISMILAnimationController, + nsIAnimationController, + nsISupportsWeakReference); + +//---------------------------------------------------------------------- +// nsITimerCallback methods + +NS_IMETHODIMP +nsSMILAnimationController::Notify(nsITimer *timer) +{ + NS_ASSERTION(mTimer == timer, + "nsSMILAnimationController::Notify called with incorrect timer"); + + SampleChildren(); + + return NS_OK; +} + + +//---------------------------------------------------------------------- +// nsISMILAnimationController methods: + +nsresult +nsSMILAnimationController::Pause() +{ + // TODO[2]: (for now this just involves calling pause on all the children) + NS_NOTYETIMPLEMENTED("nsSMILAnimationController::Pause"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +nsresult +nsSMILAnimationController::Resume() +{ + // TODO[2]: (for now this just involves calling resume on all the children) + NS_NOTYETIMPLEMENTED("nsSMILAnimationController::Resume"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +nsresult +nsSMILAnimationController::AddTimeContainer(nsISMILTimeContainer* aContainer) +{ + if (!aContainer) + return NS_ERROR_NULL_POINTER; + + nsresult rv; + nsCOMPtr weakRef( + getter_AddRefs(do_GetWeakReference(aContainer, &rv)) ); + + if (NS_SUCCEEDED(rv)) + rv = (mTimeContainers.AppendObject(weakRef)) ? NS_OK : NS_ERROR_FAILURE; + + if (NS_SUCCEEDED(rv) && mTimeContainers.Count() == 1) + rv = StartTimer(); + + return rv; +} + +nsresult +nsSMILAnimationController::RemoveTimeContainer(nsISMILTimeContainer* aContainer) +{ + if (!aContainer) + return NS_ERROR_NULL_POINTER; + + nsresult rv; + nsCOMPtr weakRef( + getter_AddRefs(do_GetWeakReference(aContainer, &rv)) ); + + if (NS_SUCCEEDED(rv)) + rv = (mTimeContainers.RemoveObject(weakRef)) ? NS_OK : NS_ERROR_FAILURE; + + if (NS_SUCCEEDED(rv) && mTimeContainers.Count() == 0) + rv = StopTimer(); + + return rv; +} + +//---------------------------------------------------------------------- +// Implementation helpers: + +nsresult +nsSMILAnimationController::Init() +{ + mTimer = do_CreateInstance("@mozilla.org/timer;1"); + return (mTimer) ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +nsresult +nsSMILAnimationController::StartTimer() +{ + NS_ASSERTION(mTimer, "NULL timer!"); + + // TODO[2]: Remove magic number and make timer self-tuning + return mTimer->InitWithCallback(NS_STATIC_CAST(nsITimerCallback*, this), + 25, nsITimer::TYPE_REPEATING_SLACK); +} + +nsresult +nsSMILAnimationController::StopTimer() +{ + NS_ASSERTION(mTimer, "NULL timer!"); + + return mTimer->Cancel(); +} + +void +nsSMILAnimationController::SampleChildren() +{ + // Creating a new enumerator each sample provides thread-safety but I'm not + // sure what the cost is + + 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(); + } + + /* Non-thread safe version + PRUint32 i = mTimeContainers.Count(); + while (i > 0) + { + --i; + nsCOMPtr + container( do_QueryReferent(mTimeContainers[i]) ); + // The above could be replaced with mTimeContainers.SafeObjectAt(i) to + // provide a little more safety + + if (container) + container->Sample(); + else + mTimeContainers.RemoveObjectAt(i); + } + */ +} + Index: /cvsroot/mozilla/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 +++ /cvsroot/mozilla/content/smil/src/nsSMILAnimationFunction.cpp 14 Sep 2005 10:44:05 -0000 @@ -0,0 +1,731 @@ +/* -*- 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 SVG project. + * + * 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 "nsCOMPtr.h" +#include "nsCOMArray.h" +#include "nsReadableUtils.h" +#include "nsString.h" +#include "nsCRT.h" +#include + +//---------------------------------------------------------------------- +// nsSMILAnimationFunction + +class nsSMILAnimationFunction : public nsISMILAnimationFunction, + public nsISMILComposable, + public nsISMILTimeClient +{ +public: + nsSMILAnimationFunction(); + + NS_DECL_ISUPPORTS + + // nsISMILAnimationFunction + virtual nsresult Init(nsISMILAnimAttr& aAttribute); + virtual PRBool IsInitialised(); + + 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(); + + virtual void SetDocumentPosition(PRUint16 aDocPosition); + + // 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(); + + // 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; + +protected: + // Implementation helpers + nsISMILAnimationFunction* NS_NewSMILAnimationFunction(); + virtual void FillValuesArray(); + virtual PRBool IsAdditive() const; + + // Members + + /* + * The attribute being targeted. This is needed for parsing animation function + * values and creating temporary objects. + */ + nsCOMPtr mAttribute; + + /* + * There are a lot of member variables here. Most of these are keeping track + * of the state of various attributes so that as they are set and unset we + * know which ones to apply. This could be done more effectively in the + * element that owns this object (for example, by calling GetAttr) but we take + * care of it here as we expect many elements will reuse this logic. + */ + PRBool mIsActive; + + /* + * Animation function values. + */ + nsCOMPtr mFrom; + nsCOMPtr mTo; + nsCOMPtr mBy; + nsCOMArray mValues; + + /* + * When the values attribute isn't set explicitly, the mValues array is filled + * with an equivalent set of values based on the from, to and by attributes. + * This flag indicates if the values array is filled with values from an + * actual values attribute (in which case it is true) or if it has been filled + * with the values of from, to and by (in which case it is false). + */ + PRBool mValuesIsSet; + + enum nsSMILCalcMode + { + NS_SMIL_CALCMODE_LINEAR, + NS_SMIL_CALCMODE_DISCRETE, + NS_SMIL_CALCMODE_PACED, + NS_SMIL_CALCMODE_SPLINE + }; + nsSMILCalcMode mCalcMode; + + PRBool mAdditive; + + /* + * 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; + + PRInt64 mBeginTime; + PRUint16 mDocumentPosition; +}; + +//---------------------------------------------------------------------- +// Constructors etc. + +nsSMILAnimationFunction::nsSMILAnimationFunction() + : mValuesIsSet(PR_FALSE), + mCalcMode(NS_SMIL_CALCMODE_LINEAR), + mAdditive(PR_FALSE), + mIsActive(PR_FALSE), + mSimpleTime(-1), + mRepeatIteration(0), + mLastValue(PR_FALSE), + mBeginTime(LL_MinInt()), + mDocumentPosition(PR_UINT16_MAX) +{ +} + +nsISMILAnimationFunction* +NS_NewSMILAnimationFunction() +{ + return new nsSMILAnimationFunction(); +} + +//---------------------------------------------------------------------- +// nsISupports methods: + +NS_IMPL_ISUPPORTS4(nsSMILAnimationFunction, + nsISMILAnimationFunction, + nsISMILComposable, + nsISMILTimeClient, + nsISupportsWeakReference) + +//---------------------------------------------------------------------- +// nsISMILAnimationFunction methods: + +nsresult +nsSMILAnimationFunction::Init(nsISMILAnimAttr& aAttribute) +{ + mAttribute = &aAttribute; + return NS_OK; +} + +PRBool +nsSMILAnimationFunction::IsInitialised() +{ + return (mAttribute != nsnull); +} + +nsresult +nsSMILAnimationFunction::SetAdditive(const nsAString& aAdditive) +{ + /* + * We could use nsSVGEnum here but I'd prefer to keep this module independent + * of SVG if possible. Besides, the enums are very simple. + */ + nsresult rv = NS_ERROR_FAILURE; + mAdditive = PR_FALSE; + char* str = ToNewCString(aAdditive); + char* val = str; + + while (*val && NS_IS_SPACE(*val)) + ++val; + + if (*val != 0) { + if (PL_strncmp(val, "sum", 3) == 0) { + mAdditive = PR_TRUE; + val += 3; + rv = NS_OK; + } else if (PL_strncmp(val, "replace", 7) == 0) { + val += 7; + rv = NS_OK; + } + } + + if (NS_SUCCEEDED(rv)) { + while (*val && NS_IS_SPACE(*val)) + ++val; + if (*val != 0) { + mAdditive = PR_FALSE; + rv = NS_ERROR_FAILURE; + } + } + + nsMemory::Free(str); + + return rv; +} + +void +nsSMILAnimationFunction::UnsetAdditive() +{ + mAdditive = PR_FALSE; +} + +nsresult +nsSMILAnimationFunction::SetBy(const nsAString& aBy) +{ + NS_ASSERTION(mAttribute, "Animation element not initialised."); + + if (!mAttribute) + return NS_ERROR_FAILURE; + + nsresult rv; + rv = mAttribute->CreateFromSpec(aBy, getter_AddRefs(mBy)); + + FillValuesArray(); + + return rv; +} + +void +nsSMILAnimationFunction::UnsetBy() +{ + mBy = nsnull; + FillValuesArray(); +} + +nsresult +nsSMILAnimationFunction::SetCalcMode(const nsAString& aCalcMode) +{ + // TODO[2] + return NS_ERROR_NOT_IMPLEMENTED; +} + +void +nsSMILAnimationFunction::UnsetCalcMode() +{ + // TODO[2] +} + +nsresult +nsSMILAnimationFunction::SetAccumulate(const nsAString& aAccumulate) +{ + // TODO[2] + return NS_ERROR_NOT_IMPLEMENTED; +} + +void +nsSMILAnimationFunction::UnsetAccumulate() +{ + // TODO[2] +} + + +nsresult +nsSMILAnimationFunction::SetFrom(const nsAString& aFrom) +{ + NS_ASSERTION(mAttribute, "Animation element not initialised."); + + if (!mAttribute) + return NS_ERROR_FAILURE; + + nsresult rv; + rv = mAttribute->CreateFromSpec(aFrom, getter_AddRefs(mFrom)); + + FillValuesArray(); + + return rv; +} + +void +nsSMILAnimationFunction::UnsetFrom() +{ + mFrom = nsnull; + FillValuesArray(); +} + +nsresult +nsSMILAnimationFunction::SetKeySplines(const nsAString& aKeySplines) +{ + // TODO[2] + return NS_ERROR_NOT_IMPLEMENTED; +} + +void +nsSMILAnimationFunction::UnsetKeySplines() +{ + // TODO[2] +} + +nsresult +nsSMILAnimationFunction::SetKeyTimes(const nsAString& aKeyTimes) +{ + // TODO[2] + return NS_ERROR_NOT_IMPLEMENTED; +} + +void +nsSMILAnimationFunction::UnsetKeyTimes() +{ + // TODO[2] +} + +nsresult +nsSMILAnimationFunction::SetTo(const nsAString& aTo) +{ + NS_ASSERTION(mAttribute, "Animation element not initialised."); + + if (!mAttribute) + return NS_ERROR_FAILURE; + + nsresult rv; + rv = mAttribute->CreateFromSpec(aTo, getter_AddRefs(mTo)); + + FillValuesArray(); + + return rv; +} + +void +nsSMILAnimationFunction::UnsetTo() +{ + mTo = nsnull; + FillValuesArray(); +} + +nsresult +nsSMILAnimationFunction::SetValues(const nsAString& aValues) +{ + NS_ASSERTION(mAttribute, "Animation element not initialised."); + + if (!mAttribute) + return NS_ERROR_FAILURE; + + nsresult rv; + nsAString::const_iterator start; + nsAString::const_iterator end; + nsAString::const_iterator substr_end; + nsAString::const_iterator next; + + aValues.BeginReading(start); + aValues.EndReading(end); + + mValues.Clear(); + mValuesIsSet = PR_FALSE; + + while (start != end) { + rv = NS_ERROR_FAILURE; + + while (*start && NS_IS_SPACE(*start)) + ++start; + + if (*start == '\0' || *start == ';') + break; + + substr_end = start; + + while (substr_end != end && *substr_end != ';') + ++substr_end; + + next = substr_end; + if (*substr_end == ';') { + ++next; + if (next == end) + break; + } + + do --substr_end; while (start != substr_end && NS_IS_SPACE(*substr_end)); + ++substr_end; + + nsCOMPtr newValue; + rv = mAttribute->CreateFromSpec(Substring(start, substr_end), + getter_AddRefs(newValue)); + + if (NS_FAILED(rv)) + break; + + mValues.AppendObject(newValue); + + start = next; + } + + if (NS_SUCCEEDED(rv)) + mValuesIsSet = PR_TRUE; + else + mValues.Clear(); + + return rv; +} + +void +nsSMILAnimationFunction::UnsetValues() +{ + mValuesIsSet = PR_FALSE; + FillValuesArray(); +} + +void +nsSMILAnimationFunction::SetDocumentPosition(PRUint16 aDocPosition) +{ + mDocumentPosition = aDocPosition; +} + +//---------------------------------------------------------------------- +// nsISMILTimeClient methods + +void +nsSMILAnimationFunction::SampleAt(const PRInt64& aSimpleTime, + const nsSMILTimeValue& aSimpleDuration, + const PRUint32& aRepeatIteration) +{ + mSimpleTime = aSimpleTime; + mSimpleDuration = aSimpleDuration; + mRepeatIteration = aRepeatIteration; + mLastValue = PR_FALSE; +} + +void +nsSMILAnimationFunction::SampleLastValue(const PRUint32& aRepeatIteration) +{ + mRepeatIteration = aRepeatIteration; + mLastValue = PR_TRUE; +} + +void +nsSMILAnimationFunction::ToActive(const PRInt64& aBeginTime) +{ + mBeginTime = aBeginTime; + mIsActive = PR_TRUE; +} + +void +nsSMILAnimationFunction::ToInactive() +{ + mIsActive = PR_FALSE; +} + +//---------------------------------------------------------------------- +// nsISMILComposable methods + +void +nsSMILAnimationFunction::ComposeResult(nsISMILAnimVal &aResult) +{ + /* + * This checks if mValues is empty so we don't need to check it again + */ + if (!IsActive()) + return; + + NS_ENSURE_TRUE(mSimpleTime >= 0,); + NS_ENSURE_TRUE(mSimpleDuration.IsResolved() || + mSimpleDuration.IsIndefinite(), ); + NS_ENSURE_TRUE(mAttribute,); + + nsCOMPtr result; + NS_ENSURE_SUCCESS(mAttribute->Create(getter_AddRefs(result)),); + + if (mSimpleDuration.IsIndefinite() || + (mValuesIsSet && mValues.Count() == 1)) { + nsISMILAnimVal* firstValue = mValues.SafeObjectAt(0); + NS_ENSURE_TRUE(firstValue,); + result->Set(*firstValue); + } else if (mLastValue) { + nsISMILAnimVal* lastValue = mValues.SafeObjectAt(mValues.Count() - 1); + NS_ENSURE_TRUE(lastValue,); + result->Repeat(mRepeatIteration, lastValue); + } else { + const PRInt64& dur = mSimpleDuration.GetMillis(); + + if (LL_CMP(mSimpleTime, >=, dur) || !LL_GE_ZERO(mSimpleTime)) { + NS_ERROR("Animation sampled outside interval."); + return; + } + + double fTime; + double fDur; + double simpleDistance; + double intervalDistance; + PRInt32 index; + nsISMILAnimVal* from = nsnull; + nsISMILAnimVal* to = nsnull; + + LL_L2D(fTime, mSimpleTime); + LL_L2D(fDur, dur); + + NS_ASSERTION(mValues.Count() >= 2 || IsToAnimation(), + "Unexpected number of values."); + + simpleDistance = (fDur > 0.0) ? fTime / fDur : 0.0; + + if (IsToAnimation()) { + from = &aResult; + to = mValues.SafeObjectAt(0); + intervalDistance = simpleDistance; + } else { + index = (PRInt32) floor(simpleDistance * (mValues.Count() - 1)); + + from = mValues.SafeObjectAt(index); + NS_ENSURE_TRUE(from,); + + to = mValues.SafeObjectAt(index + 1); + NS_ENSURE_TRUE(to,); + + intervalDistance = simpleDistance * (mValues.Count() - 1) - index; + } + + nsresult rv = from->Interpolate(*to, + NS_STATIC_CAST(float, intervalDistance), + *result); + NS_ENSURE_SUCCESS(rv,); + } + + /* + * If additive animation isn't required or fails, just set the value. + */ + if (!IsAdditive() || !aResult.Add(*result)) + aResult.Set(*result); +} + +PRInt8 +nsSMILAnimationFunction::CompareTo(const nsISMILComposable& composable) const +{ + /* + * Inactive animations sort first + */ + if (!IsActive()) + return -1; + + if (!composable.IsActive()) + return 1; + + /* + * To animations sort last + */ + if (!IsToAnimation() && composable.IsToAnimation()) + return -1; + + if (IsToAnimation() && !composable.IsToAnimation()) + return 1; + + /* + * We sort using the same rules if both animations are 'to animations' or both + * animations are not 'to animations'. + */ + 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 + */ + /* + * Disabled for now until we implement the document traversal + NS_ASSERTION(mDocumentPosition != composable.GetDocumentPosition(), + "Two animations cannot have the same document position!"); + */ + + return (mDocumentPosition <= composable.GetDocumentPosition()) ? -1 : 1; +} + +PRBool +nsSMILAnimationFunction::IsToAnimation() const +{ + return (!mValuesIsSet && 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. + */ + return (mIsActive && mValues.Count() > 0); +} + + +PRBool +nsSMILAnimationFunction::WillReplace() const +{ + return !IsAdditive(); +} + +//---------------------------------------------------------------------- +// Implementation helpers + +/* + * 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 (!mValuesIsSet) { + 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; + if (NS_SUCCEEDED(mAttribute->Create(getter_AddRefs(to)))) { + to->Set(*mFrom); + to->Add(*mBy); + mValues.AppendObject(to); + } else { + mValues.Clear(); + } + } else { + /* + * Set values to '0; by' + */ + nsCOMPtr from; + if (NS_SUCCEEDED(mAttribute->Create(getter_AddRefs(from)))) { + mValues.AppendObject(from); + mValues.AppendObject(mBy); + } else { + mValues.Clear(); + } + } + } + /* else, do nothing, mValues has been cleared already. */ + } +} + +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 || (!mValuesIsSet && mBy && !mFrom))); +} + Index: /cvsroot/mozilla/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 +++ /cvsroot/mozilla/content/smil/src/nsSMILAnimationRegistry.cpp 14 Sep 2005 10:44:06 -0000 @@ -0,0 +1,273 @@ +/* -*- 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 SVG project. + * + * 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 "nsISMILAnimationController.h" +#include "nsISMILAnimAttr.h" +#include "nsSMILTimedDocumentRoot.h" +#include "nsISMILComposable.h" + +//////////////////////////////////////////////////////////////////////// +// nsSMILAnimationRegistry implementation + +struct CompositorEntry +{ + nsISMILAnimAttr* key; + nsSMILCompositor compositor; +}; + +//---------------------------------------------------------------------- +// ctors, dtors, factory methods + +nsSMILAnimationRegistry::nsSMILAnimationRegistry() +{ +} + +nsSMILAnimationRegistry::~nsSMILAnimationRegistry() +{ + if (mController && mTimedDocumentRoot) + mController->RemoveTimeContainer(mTimedDocumentRoot); + + CompositorEntry* entry; + PRInt32 count = mCompositors.Count(); + + for (PRInt32 i = 0; i < count; ++i) + { + entry = NS_STATIC_CAST(CompositorEntry*, mCompositors[i]); + mCompositors.ReplaceElementAt(nsnull, i); + delete entry; + } + + mCompositors.Clear(); +} + +nsISMILAnimationRegistry* +NS_NewSMILAnimationRegistry() +{ + nsSMILAnimationRegistry* animationRegistry = new nsSMILAnimationRegistry(); + + if (animationRegistry) + { + 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); + + return NS_OK; +} + +//---------------------------------------------------------------------- +// nsISupports methods: + +NS_IMPL_ISUPPORTS1(nsSMILAnimationRegistry, + nsISMILAnimationRegistry); + +//---------------------------------------------------------------------- +// nsISMILAnimationRegistry methods: + +nsresult +nsSMILAnimationRegistry::SetController(nsISMILAnimationController* aController) +{ + nsresult rv = NS_OK; + + if (mController) + { + rv = mController->RemoveTimeContainer(mTimedDocumentRoot); + NS_ENSURE_SUCCESS(rv,rv); + } + + mController = aController; + + if (mController && mTimedDocumentRoot) + rv = mController->AddTimeContainer(mTimedDocumentRoot); + + return rv; +} + +void +nsSMILAnimationRegistry::Pause() +{ + // TODO[3] +} + +void +nsSMILAnimationRegistry::Unpause() +{ + // TODO[3] +} + +PRBool +nsSMILAnimationRegistry::IsPaused() +{ + // TODO[3] + return false; +} + +float +nsSMILAnimationRegistry::GetCurrentTime() +{ + return 0.0f; +} + +nsresult +nsSMILAnimationRegistry::SetCurrentTime(float aSeconds) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +nsresult +nsSMILAnimationRegistry::RegisterComposable(nsISMILAnimAttr* aTargetAttr, + nsISMILComposable* aComposable) +{ + NS_ENSURE_ARG_POINTER(aTargetAttr); + NS_ENSURE_ARG_POINTER(aComposable); + + nsSMILCompositor* compositor = nsnull; + CompositorEntry* entry; + + /* + * 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; + nsSMILCompositor* compositor = nsnull; + CompositorEntry* entry; + PRInt32 count = mCompositors.Count(); + + 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. After all, 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() +{ + // TODO[2]: Suspend redraw +} + +void +nsSMILAnimationRegistry::EndSample() +{ + CompositorEntry* entry; + PRInt32 count = mCompositors.Count(); + + for (PRInt32 i = 0; i < count; ++i) + { + entry = NS_STATIC_CAST(CompositorEntry*, mCompositors[i]); + entry->compositor.ComposeSample(); + } + + // TODO[2]: Unsuspend redraw +} + Index: /cvsroot/mozilla/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 +++ /cvsroot/mozilla/content/smil/src/nsSMILAnimationRegistry.h 14 Sep 2005 10:44:06 -0000 @@ -0,0 +1,82 @@ +/* -*- 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 SVG project. + * + * 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 "nsSMILCompositor.h" +#include "nsVoidArray.h" +#include "nsAutoPtr.h" + +class nsSMILTimedDocumentRoot; +class nsISMILAnimAttr; +class nsISMILAnimationController; +class nsISMILComposable; + +class nsSMILAnimationRegistry : public nsISMILAnimationRegistry +{ +public: + nsSMILAnimationRegistry(); + ~nsSMILAnimationRegistry(); + + NS_DECL_ISUPPORTS + + virtual void StartSample(); + virtual void EndSample(); + + // nsISMILAnimationRegistry + virtual nsresult SetController(nsISMILAnimationController* aController); + 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; +}; + +#endif // __NS_SMILANIMATIONREGISTRY_H__ + Index: /cvsroot/mozilla/content/smil/src/nsSMILCompositor.cpp =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsSMILCompositor.cpp diff -N content/smil/src/nsSMILCompositor.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/content/smil/src/nsSMILCompositor.cpp 14 Sep 2005 10:44:08 -0000 @@ -0,0 +1,168 @@ +/* -*- 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 SVG project. + * + * 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 "nsSMILCompositor.h" +#include "nsISMILComposable.h" +#include "nsISimpleEnumerator.h" +#include "nsArrayEnumerator.h" +#include "nsISMILAnimAttr.h" +#include "nsISMILAnimVal.h" + +//////////////////////////////////////////////////////////////////////// +// nsSMILCompositor implementation + +nsresult +nsSMILCompositor::Init(nsISMILAnimAttr* aTargetAttribute) +{ + NS_ENSURE_ARG_POINTER(aTargetAttribute); + + nsresult rv; + mTargetAttribute = do_GetWeakReference(aTargetAttribute, &rv); + if (NS_FAILED(rv)) + { + mTargetAttribute = nsnull; + return rv; + } + + return NS_OK; +} + +nsresult +nsSMILCompositor::AddComposable(nsISMILComposable* aComposable) +{ + NS_ENSURE_ARG_POINTER(aComposable); + + nsresult rv; + nsCOMPtr weakRef( + getter_AddRefs(do_GetWeakReference(aComposable, &rv)) ); + + if (NS_SUCCEEDED(rv)) + rv = (mChildren.AppendObject(weakRef)) ? NS_OK : NS_ERROR_FAILURE; + + return rv; +} + +nsresult +nsSMILCompositor::RemoveComposable(nsISMILComposable* aComposable) +{ + NS_ENSURE_ARG_POINTER(aComposable); + + nsresult rv; + nsCOMPtr weakRef( + getter_AddRefs(do_GetWeakReference(aComposable, &rv)) ); + + if (NS_SUCCEEDED(rv)) + rv = (mChildren.RemoveObject(weakRef)) ? NS_OK : NS_ERROR_FAILURE; + + return rv; +} + +void +nsSMILCompositor::ComposeSample() +{ + NS_ASSERTION(mTargetAttribute, "Target attribute not set on compositor."); + + if (!mTargetAttribute) + return; + + nsCOMPtr targetAttribute( + do_QueryReferent(mTargetAttribute) ); + + if (!targetAttribute) + return; + + nsCOMPtr result( CopyBaseValue(targetAttribute) ); + if (!result) + return; + + mChildren.Sort(SortCompositors, nsnull); + + nsCOMPtr enumerator; + nsresult rv = + NS_NewArrayEnumerator(getter_AddRefs(enumerator), mChildren); + NS_ENSURE_SUCCESS(rv,); + + PRBool more = PR_FALSE; + nsCOMPtr composable; + nsCOMPtr weakRef; + + while (NS_SUCCEEDED(enumerator->HasMoreElements(&more)) && more) + { + if (NS_FAILED(enumerator->GetNext(getter_AddRefs(weakRef))) || !weakRef) + break; + + composable = do_QueryReferent(weakRef); + + if (composable) + { + composable->ComposeResult(*result); + } + } + + // We can't just call Set on the animated value itself, because the observers + // of the animated object as a whole need to be updated too. + targetAttribute->SetAnimValue(*result); +} + +//---------------------------------------------------------------------- +// Implementation helpers + +PR_CALLBACK int +nsSMILCompositor::SortCompositors(nsIWeakReference *aRef1, + nsIWeakReference *aRef2, + void* aData) +{ + nsCOMPtr a = do_QueryReferent(aRef1); + nsCOMPtr b = do_QueryReferent(aRef2); + + return (a && b) ? a->CompareTo(*b) : -1; +} + +nsISMILAnimVal* +nsSMILCompositor::CopyBaseValue(nsISMILAnimAttr* aTargetAttribute) +{ + nsISMILAnimVal* baseValueCopy; + + nsCOMPtr baseVal( aTargetAttribute->GetBaseValue() ); + if (!baseVal) + return nsnull; + + aTargetAttribute->Create(&baseValueCopy); + if (!baseValueCopy) + return nsnull; + + baseValueCopy->Set(*baseVal); + + return baseValueCopy; +} + Index: /cvsroot/mozilla/content/smil/src/nsSMILCompositor.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsSMILCompositor.h diff -N content/smil/src/nsSMILCompositor.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/content/smil/src/nsSMILCompositor.h 14 Sep 2005 10:44:08 -0000 @@ -0,0 +1,68 @@ +/* -*- 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 SVG project. + * + * 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_SMILCOMPOSITOR_H__ +#define __NS_SMILCOMPOSITOR_H__ + +#include "nsCOMArray.h" +#include "nsWeakReference.h" + +//////////////////////////////////////////////////////////////////////// +// nsSMILCompositor: Collection of animation compositors + +class nsISMILComposable; +class nsISMILAnimAttr; +class nsISMILAnimVal; + +class nsSMILCompositor +{ +public: + nsresult Init(nsISMILAnimAttr* aTargetAttribute); + + nsresult AddComposable(nsISMILComposable* aComposable); + nsresult RemoveComposable(nsISMILComposable* aComposable); + void ComposeSample(); + +protected: + PR_STATIC_CALLBACK(int) SortCompositors(nsIWeakReference* aRef1, + nsIWeakReference* aRef2, + void* aData); + + nsISMILAnimVal* CopyBaseValue(nsISMILAnimAttr* aTargetAttribute); + + nsCOMArray mChildren; + nsWeakPtr mTargetAttribute; +}; + +#endif // __NS_SMILCOMPOSITOR_H__ + Index: /cvsroot/mozilla/content/smil/src/nsSMILInstanceTime.cpp =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsSMILInstanceTime.cpp diff -N content/smil/src/nsSMILInstanceTime.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/content/smil/src/nsSMILInstanceTime.cpp 14 Sep 2005 10:44:08 -0000 @@ -0,0 +1,53 @@ +/* -*- 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 SVG project. + * + * 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 "nsSMILInstanceTime.h" +#include "nsSMILTimeValueSpec.h" +#include "nsSMILTimeValue.h" + +//---------------------------------------------------------------------- +// Implementation + +nsSMILInstanceTime::nsSMILInstanceTime (const nsSMILTimeValue &aTime, + nsSMILTimeValueSpec *aCreator, + PRBool aClearOnReset /*=false*/) + : mTime(aTime), // Copy the time + mClearOnReset(aClearOnReset) +{ + if (aCreator) + mCreator = do_GetWeakReference(aCreator); +} + +//---------------------------------------------------------------------- +// nsSMILInstanceTime + Index: /cvsroot/mozilla/content/smil/src/nsSMILInstanceTime.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsSMILInstanceTime.h diff -N content/smil/src/nsSMILInstanceTime.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/content/smil/src/nsSMILInstanceTime.h 14 Sep 2005 10:44:08 -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 SVG project. + * + * 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_SMILINSTANCETIME_H__ +#define __NS_SMILINSTANCETIME_H__ + +#include "nsSMILTimeValue.h" +#include "nsWeakReference.h" + +class nsSMILTimeValueSpec; + +//////////////////////////////////////////////////////////////////////// +// nsSMILInstanceTime + +class nsSMILInstanceTime +{ +public: + nsSMILInstanceTime (const nsSMILTimeValue &aTime, + nsSMILTimeValueSpec *aCreator, + PRBool aClearOnReset = false); + + const nsSMILTimeValue& Time() const { return mTime; } + + PRBool ClearOnReset() const { return mClearOnReset; } + + // dependent update + + nsrefcnt AddRef() { return ++mRefCnt; } + nsrefcnt Release(); + +protected: + nsSMILTimeValue mTime; + nsWeakPtr mCreator; + + /** + * Should this instance time be removed when the owning timed element is rest. + * True for events and DOM calls. + */ + PRBool mClearOnReset; + + /* + * This will only be used for for identifying the instance times associated + * with a deleting interval. We will never de-reference this pointer, but only + * use it for pointer comparisons. Therefore it's not necessary for instances + * of nsSMILInterval to be reference-counted. + * + * nsSMILInterval *mTimebase + */ + + nsAutoRefCnt mRefCnt; +}; + +inline nsrefcnt +nsSMILInstanceTime::Release() +{ + if (--mRefCnt == 0) + { + delete this; + return 0; + } + + return mRefCnt; +} + +#endif // __NS_SMILINSTANCETIME_H__ + Index: /cvsroot/mozilla/content/smil/src/nsSMILInterval.cpp =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsSMILInterval.cpp diff -N content/smil/src/nsSMILInterval.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/content/smil/src/nsSMILInterval.cpp 14 Sep 2005 10:44:09 -0000 @@ -0,0 +1,56 @@ +/* -*- 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 SVG project. + * + * 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 "nsSMILInterval.h" + +nsSMILInterval::nsSMILInterval(const nsSMILTimeValue& aBegin, + const nsSMILTimeValue& aEnd) +: mBegin(aBegin), + mEnd(aEnd) +{ +} + +//---------------------------------------------------------------------- +// Implementation + +PRBool +nsSMILInterval::Recalc(const nsVoidArray& aBeginTimes, + const nsVoidArray& aEndTimes, + PRBool aHasEnds, + const nsSMILTimeValue& min, + const nsSMILTimeValue& max) +{ + // TODO[2] + return PR_TRUE; +} + Index: /cvsroot/mozilla/content/smil/src/nsSMILInterval.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsSMILInterval.h diff -N content/smil/src/nsSMILInterval.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/content/smil/src/nsSMILInterval.h 14 Sep 2005 10:44:09 -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 the Mozilla SVG project. + * + * 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_SMILINTERVAL_H__ +#define __NS_SMILINTERVAL_H__ + +#include "nsSMILTimeValue.h" + +//////////////////////////////////////////////////////////////////////// +// nsSMILInterval class + +class nsVoidArray; + +class nsSMILInterval +{ +public: + nsSMILInterval() {} + + nsSMILInterval(const nsSMILTimeValue& aBegin, + const nsSMILTimeValue& aEnd); + + const nsSMILTimeValue& Begin() { return mBegin; } + const nsSMILTimeValue& End() { return mEnd; } + + PRBool Recalc(const nsVoidArray& aBeginTimes, + const nsVoidArray& aEndTimes, + PRBool aHasEnds, + const nsSMILTimeValue& min, + const nsSMILTimeValue& max); + +protected: + nsSMILTimeValue mBegin; + nsSMILTimeValue mEnd; +}; + +#endif // __NS_SMILINTERVAL_H__ Index: /cvsroot/mozilla/content/smil/src/nsSMILTimeValue.cpp =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsSMILTimeValue.cpp diff -N content/smil/src/nsSMILTimeValue.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/content/smil/src/nsSMILTimeValue.cpp 14 Sep 2005 10:44:09 -0000 @@ -0,0 +1,137 @@ +/* -*- 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 SVG project. + * + * 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 "nsSMILTimeValue.h" +#include "nsDebug.h" + +PRInt64 nsSMILTimeValue::mUnresolvedSeconds = LL_MaxInt(); + +//---------------------------------------------------------------------- +// Implementation + +// Default constructor creates an unresolved time +nsSMILTimeValue::nsSMILTimeValue() + : mMilliseconds(LL_MaxInt()), + mIndefinite(PR_FALSE), + mResolved(PR_FALSE) +{} + +//---------------------------------------------------------------------- +// nsSMILTimeValue methods: + +// TODO[3]: Profile and move the most accessed methods inline + +PRBool +nsSMILTimeValue::IsIndefinite() const +{ + return mIndefinite; +} + +void +nsSMILTimeValue::SetIndefinite() +{ + mResolved = PR_FALSE; + mIndefinite = PR_TRUE; + mMilliseconds = LL_MaxInt(); +} + +PRBool +nsSMILTimeValue::IsResolved() const +{ + return mResolved; +} + +void +nsSMILTimeValue::SetUnresolved() +{ + mResolved = PR_FALSE; + mIndefinite = PR_FALSE; + mMilliseconds = LL_MaxInt(); +} + +const PRInt64& +nsSMILTimeValue::GetMillis() const +{ + NS_ASSERTION(mResolved, "GetMillis() called for unresolved time."); + + if (!mResolved) + return mUnresolvedSeconds; + + return mMilliseconds; +} + +void +nsSMILTimeValue::SetMillis(const PRInt64& aMillis) +{ + mResolved = PR_TRUE; + mIndefinite = PR_FALSE; + mMilliseconds = aMillis; +} + +PRInt8 +nsSMILTimeValue::CompareTo(const nsSMILTimeValue& aCompare) const +{ + PRInt8 result; + + if (mResolved) + { + result = (aCompare.mResolved) + ? CmpLL(mMilliseconds, aCompare.mMilliseconds) + : -1; + } + else if (mIndefinite) + { + if (aCompare.mResolved) + result = 1; + else if (aCompare.mIndefinite) + result = 0; + else + result = -1; + } + else + { + result = (aCompare.mResolved || aCompare.mIndefinite) ? 1 : 0; + } + + return result; +} + +PR_CALLBACK int +nsSMILTimeValue::ComparisonCallback(const void *aElement1, + const void *aElement2, + void* aData) +{ + return NS_STATIC_CAST(const nsSMILTimeValue*, aElement1)->CompareTo + (*NS_STATIC_CAST(const nsSMILTimeValue*, aElement2)); +} + Index: /cvsroot/mozilla/content/smil/src/nsSMILTimeValue.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsSMILTimeValue.h diff -N content/smil/src/nsSMILTimeValue.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/content/smil/src/nsSMILTimeValue.h 14 Sep 2005 10:44:09 -0000 @@ -0,0 +1,115 @@ +/* -*- 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 SVG project. + * + * 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_SMILTIMEVALUE_H__ +#define __NS_SMILTIMEVALUE_H__ + +#include "prtypes.h" +#include "prlong.h" + +/* + * nsSMILTimeValue class + * + * This class considers three orthogonal cases: + * + * 1) The time is resolved and has a millisecond value + * 2) The time is indefinite + * 3) The time in unresolved + * + * There is considerable chance for confusion with regards to the indefinite + * state. Is it resolved? We adopt the convention that it is NOT resolved (but + * nor is it unresolved). This simplifies implementation as you can then write: + * + * if (time.IsResolved()) + * x = time.GetMillis() + * + * instead of: + * + * if (time.IsResolved() && !time.IsIndefinite()) + * x = time.GetMillis() + * + * Testing if a time is unresolved becomes more complicated but this is tested + * much less often. + * + * In summary: + * + * State | GetMillis | IsResolved | IsIndefinite + * --------------+--------------------+--------------------+------------------- + * Resolved | The millisecond | PR_TRUE | PR_FALSE + * | time | | + * --------------+--------------------+--------------------+------------------- + * Indefinite | LL_MaxInt | PR_FALSE | PR_TRUE + * --------------+--------------------+--------------------+------------------- + * Unresolved | LL_MaxInt | PR_FALSE | PR_FALSE + * + */ + +class nsSMILTimeValue +{ +public: + // Creates an unresolved time value + nsSMILTimeValue(); + + PRBool IsIndefinite() const; + void SetIndefinite(); + + PRBool IsResolved() const; + void SetUnresolved(); + + const PRInt64& GetMillis() const; + void SetMillis(const PRInt64& aMillis); + + PRInt8 CompareTo(const nsSMILTimeValue& aCompare) const; + + PR_STATIC_CALLBACK(int) ComparisonCallback(const void *aElement1, + const void *aElement2, + void* aData); + +private: + PRInt8 CmpLL(const PRInt64& a, const PRInt64& b) const; + + static PRInt64 mUnresolvedSeconds; + + PRInt64 mMilliseconds; + PRBool mIndefinite; + PRBool mResolved; +}; + +// A signed comparison of two signed 64-bit integers +inline PRInt8 +nsSMILTimeValue::CmpLL(const PRInt64& a, const PRInt64& b) const +{ + return (LL_EQ(a, b)) ? 0 : (LL_CMP(a, >, b)) ? 1 : -1; +} + +#endif // __NS_SMILTIMEVALUE_H__ Index: /cvsroot/mozilla/content/smil/src/nsSMILTimeValueSpec.cpp =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsSMILTimeValueSpec.cpp diff -N content/smil/src/nsSMILTimeValueSpec.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/content/smil/src/nsSMILTimeValueSpec.cpp 14 Sep 2005 10:44:10 -0000 @@ -0,0 +1,443 @@ +/* -*- 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 SVG project. + * + * 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 "nsSMILTimeValueSpec.h" +#include "nsSMILTimeValue.h" +#include "nsSMILInstanceTime.h" +#include "nsAutoPtr.h" +#include "nsCRT.h" +#include "prdtoa.h" + +const PRUint32 nsSMILTimeValueSpec::MSEC_PER_SEC = 1000; +const PRUint32 nsSMILTimeValueSpec::MSEC_PER_MIN = 1000 * 60; +const PRUint32 nsSMILTimeValueSpec::MSEC_PER_HOUR = 1000 * 60 * 60; + +//---------------------------------------------------------------------- +// Implementation + +// We can't return a raw pointer here because we call SetSpec, which calls +// getWeakReference on the newly created value spec which will cause it to be +// destroyed unless it is addref'ed first. + +nsresult NS_NewSMILTimeValueSpec(nsISMILTimedElement* aOwner, + PRBool aIsBegin, + const nsAString& aStringSpec, + nsSMILTimeValueSpec** aResult) +{ + if (nsnull == aResult) return NS_ERROR_NULL_POINTER; + + *aResult = nsnull; + + nsSMILTimeValueSpec* valueSpec = new nsSMILTimeValueSpec(aOwner, aIsBegin); + + if (!valueSpec) return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(valueSpec); + + nsresult rv = valueSpec->SetSpec(aStringSpec); + + if (NS_FAILED(rv)) + { + NS_RELEASE(valueSpec); + return rv; + } + + *aResult = valueSpec; + + return NS_OK; +} + +nsSMILTimeValueSpec::nsSMILTimeValueSpec(nsISMILTimedElement* aOwner, + PRBool aIsBegin) + : mIsBegin(aIsBegin), + mOffset() // initalises to zero +{ + if (aOwner) + mOwner = do_GetWeakReference(aOwner); +} + +//---------------------------------------------------------------------- +// nsISupports + +NS_IMPL_ISUPPORTS2(nsSMILTimeValueSpec, + nsSMILTimeValueSpec, + nsISupportsWeakReference) + +//---------------------------------------------------------------------- +// nsSMILTimeValueSpec + +nsresult +nsSMILTimeValueSpec::SetSpec(const nsAString& aStringSpec) +{ + // TODO[2]: Parse other specifiers + nsSMILTimeValue clockTime; + nsresult rv = ParseClockValue(aStringSpec, + &clockTime, + true, // allow + or - + true); // allow 'indefinite' + + if (NS_FAILED(rv) || (!clockTime.IsResolved() && !clockTime.IsIndefinite())) + return NS_ERROR_FAILURE; + + if (clockTime.IsResolved()) + mOffset = clockTime.GetMillis(); + + if (mOwner) + { + nsRefPtr instance = + new nsSMILInstanceTime(clockTime, this); + + nsCOMPtr owner = do_QueryReferent(mOwner); + if (owner) + owner->AddInstanceTime(instance, mIsBegin); + else + rv = NS_ERROR_FAILURE; + } + + return rv; +} + +// This method can actually parse more than a clock value as defined in the +// SMIL Animation specification. It can also parse: +// - the + or - before an offset +// - the special value "indefinite" +// - the special value "media" +// +// Because the value "media" cannot be represented as part of an nsSMILTimeValue +// and has different meanings depending on where it is used, it is passed out as +// a separate parameter (which can be set to null if the media attribute is not +// allowed). +// +// aResult may be NULL, e.g. to check if the string is a valid clock value +nsresult +nsSMILTimeValueSpec::ParseClockValue(const nsAString& aStringSpec, + nsSMILTimeValue* aResult, + PRBool aAllowSign, // = false + PRBool aAllowIndefinite, // = false + PRBool aAllowMedia, // = false + PRBool* aIsMedia) // = nsnull +{ + PRInt64 offset = LL_Zero(); + PRFloat64 component = 0.0l; + + PRInt8 sign = 0; + PRUint8 colonCount = 0; + + PRBool started = PR_FALSE; + PRBool isValid = PR_TRUE; + + PRInt32 metricMultiplicand = MSEC_PER_SEC; + + PRBool numIsReal = PR_FALSE; + PRBool prevNumCouldBeMin = PR_FALSE; + PRBool numCouldBeMin = PR_FALSE; + PRBool numCouldBeSec = PR_FALSE; + PRBool isIndefinite = PR_FALSE; + + char* spec; + char* str = spec = ToNewCString(aStringSpec); + + if (aIsMedia) + *aIsMedia = PR_FALSE; + + while (*str) + { + if (IsSpace(*str)) + { + if (started) + { + ++str; + break; + } + // else, we haven't started yet, ignore initial whitespace + } + else if (aAllowSign && (*str == '+' || *str == '-')) + { + if (sign != 0) + { + // sign has already been set + isValid = PR_FALSE; + break; + } + + if (started) + { + // sign appears in the middle of the string + isValid = PR_FALSE; + break; + } + + sign = (*str == '+') ? 1 : -1; + } + // The NS_IS_DIGIT etc. macros are not locale-specific + else if (NS_IS_DIGIT(*str)) + { + char *end; + + prevNumCouldBeMin = numCouldBeMin; + + if (!GetClockComponent(str, &end, component, numIsReal, numCouldBeMin, + numCouldBeSec)) + { + isValid = PR_FALSE; + break; + } + + started = PR_TRUE; + str = end - 1; + } + else if (*str == ':') + { + ++colonCount; + + // Neither minutes nor hours can be reals + if (numIsReal) + { + isValid = PR_FALSE; + break; + } + + // Clock value can't start with a ':' + if (!started) + { + isValid = PR_FALSE; + break; + } + + // Can't have more than two colons + if (colonCount > 2) + { + isValid = PR_FALSE; + break; + } + + // Multiply the offset by 60 and add the last accumulated component + PRInt64 component64; + LL_D2L(component64, component); + LL_MUL(offset, offset, LL_INIT(0,60)); + LL_ADD(offset, offset, component64); + + component = 0.0l; + } + else if (NS_IS_ALPHA(*str)) + { + if (colonCount > 0) + { + isValid = PR_FALSE; + break; + } + + char* end; + if (PL_strstr(str, "indefinite") == str && aAllowIndefinite) + { + // We set a separate flag because we don't know what the state of the + // passed in time value is and we shouldn't change it in the case of a + // bad input string (so we can't initialise it to 0ms for example). + isIndefinite = PR_TRUE; + if (aResult) + aResult->SetIndefinite(); + end = str + PL_strlen("indefinite"); + } + else if (PL_strstr(str, "media") == str && aAllowMedia) + { + if (aIsMedia) + *aIsMedia = PR_TRUE; + end = str + PL_strlen("media"); + } + else if (!GetMetricMultiplicand(str, &end, metricMultiplicand)) + { + isValid = PR_FALSE; + break; + } + + str = end; + + // Nothing must come after the string except whitespace + break; + } + else + { + isValid = PR_FALSE; + break; + } + + ++str; + } + + if (!started) isValid = PR_FALSE; + + // Process remainder of string (if any) to ensure it is only trailing + // whitespace (embedded whitespace is not allowed) + while (*str && isValid) + { + if (!IsSpace(*str)) isValid = PR_FALSE; + ++str; + } + + nsMemory::Free(spec); + + // No more processing required if the value was "indefinite" or "media". + if (isIndefinite || (aIsMedia && *aIsMedia)) + return NS_OK; + + // If there is more than one colon then the previous component must be a + // correctly formatted minute (i.e. two digits between 00 and 59) and the + // latest component must be a correctly formatted second (i.e. two digits + // before the .) + if (colonCount > 0 && (!prevNumCouldBeMin || !numCouldBeSec)) + isValid = PR_FALSE; + + if (isValid) + { + // Tack on the last component + if (colonCount > 0) + { + LL_MUL(offset, offset, LL_INIT(0,60)); + LL_MUL(offset, offset, LL_INIT(0,1000)); + component *= 1000; + // rounding + component = (component >= 0) ? component + 0.5l : component - 0.5l; + PRInt64 component64; + LL_D2L(component64, component); + LL_ADD(offset, offset, component64); + } + else + { + component *= metricMultiplicand; + // rounding + component = (component >= 0) ? component + 0.5l : component - 0.5l; + LL_D2L(offset, component); + } + + if (aResult) + { + PRInt64 millis = offset; + + if (sign == -1) + LL_NEG(millis, offset); + + aResult->SetMillis(millis); + } + } + + return (isValid) ? NS_OK : NS_ERROR_FAILURE; +} + +// NS_IS_SPACE relies on isspace which may return true for \xB and \xC but +// SMILANIM does not consider these characters to be whitespace. +inline PRBool +nsSMILTimeValueSpec::IsSpace(const char c) +{ + return (c == 0x9 || c == 0xA || c == 0xD || c == 0x20); +} + +inline PRBool +nsSMILTimeValueSpec::GetClockComponent(const char* aSrc, + char** aEnd, + PRFloat64& aResult, + PRBool& aIsReal, + PRBool& aCouldBeMin, + PRBool& aCouldBeSec) +{ + char *rest; + PRFloat64 value = PR_strtod(aSrc, &rest); + + // Check a number was found + if (rest == aSrc) + return PR_FALSE; + + // Check it's not expressed in exponential form + PRBool isExp = (PL_strnpbrk(aSrc, "eE", rest - aSrc) != nsnull); + if (isExp) + return PR_FALSE; + + // Don't allow real numbers of the form "23." + if (*(rest - 1) == '.') + return PR_FALSE; + + // Number looks good + aResult = value; + *aEnd = rest; + + // Set some flags so we can check this number is valid once we know + // whether it's an hour, minute string etc. + aIsReal = (PL_strnchr(aSrc, '.', rest - aSrc) != nsnull); + aCouldBeMin = (value < 60.0l && ((rest - aSrc) == 2)); + aCouldBeSec = (value < 60.0l || + (value == 60.0l && aSrc[0] == '5')); // Take care of rounding error + aCouldBeSec &= (PL_strlen(aSrc) >= 2 && + (aSrc[2] == '\0' || aSrc[2] == '.' || IsSpace(aSrc[2]))); + + return PR_TRUE; +} + +inline PRBool +nsSMILTimeValueSpec::GetMetricMultiplicand(char* aSrc, + char** aEnd, + PRInt32& multiplicand) +{ + nsresult result = PR_TRUE; + + switch (*aSrc) + { + case 'h': + *aEnd = aSrc + 1; + multiplicand = MSEC_PER_HOUR; + break; + case 'm': + if (aSrc[1] == 'i' && aSrc[2] == 'n') + { + *aEnd = aSrc + 3; + multiplicand = MSEC_PER_MIN; + } + else if (aSrc[1] == 's') + { + *aEnd = aSrc + 2; + multiplicand = 1; + } + else + { + result = PR_FALSE; + } + break; + case 's': + *aEnd = aSrc + 1; + multiplicand = MSEC_PER_SEC; + break; + default: + result = PR_FALSE; + break; + } + + return result; +} + Index: /cvsroot/mozilla/content/smil/src/nsSMILTimeValueSpec.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsSMILTimeValueSpec.h diff -N content/smil/src/nsSMILTimeValueSpec.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/content/smil/src/nsSMILTimeValueSpec.h 14 Sep 2005 10:44:10 -0000 @@ -0,0 +1,104 @@ +/* -*- 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 SVG project. + * + * 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_SMILTIMEVALUESPEC_H__ +#define __NS_SMILTIMEVALUESPEC_H__ + +#include "nsISupports.h" +#include "nsString.h" +#include "nsWeakReference.h" +#include "nsISMILTimedElement.h" + +class nsSMILTimeValue; + +//////////////////////////////////////////////////////////////////////// +// nsSMILTimeValueSpec class + +// {39d2f376-6bda-42c0-8510-a93b24828a80} +#define NS_SMILTIMEVALUESPEC_IID \ +{ 0x39d2f376, 0x6bda, 0x42c0, { 0x85, 0x10, 0xa9, 0x3b, 0x24, 0x82, 0x8a, 0x80 } } + +class nsSMILTimeValueSpec : public nsSupportsWeakReference +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_SMILTIMEVALUESPEC_IID) + NS_DECL_ISUPPORTS + + // Common parsing methods + static nsresult ParseClockValue(const nsAString& aStringSpec, + nsSMILTimeValue* aResult, + PRBool aAllowSign = false, + PRBool aAllowIndefinite = false, + PRBool aAllowMedia = false, + PRBool* aIsMedia = nsnull); + +protected: + nsSMILTimeValueSpec(nsISMILTimedElement* aOwner, PRBool aIsBegin); + + friend nsresult NS_NewSMILTimeValueSpec(nsISMILTimedElement* aOwner, + PRBool aIsBegin, + const nsAString& aStringSpec, + nsSMILTimeValueSpec** aResult); + + nsresult SetSpec(const nsAString& aStringSpec); + + static inline PRBool IsSpace(const char c); + static inline PRBool GetClockComponent(const char* aSrc, + char** aEnd, + PRFloat64& aResult, + PRBool& aIsReal, + PRBool& aCouldBeMin, + PRBool& aCouldBeSec); + static inline PRBool GetMetricMultiplicand(char* aSrc, + char** aEnd, + PRInt32& multiplicand); + + + static const PRUint32 MSEC_PER_SEC; + static const PRUint32 MSEC_PER_MIN; + static const PRUint32 MSEC_PER_HOUR; + + nsWeakPtr mOwner; + PRBool mIsBegin; + PRInt64 mOffset; +}; + +//////////////////////////////////////////////////////////////////////// +// Factory methods + +nsresult NS_NewSMILTimeValueSpec(nsISMILTimedElement* aOwner, + PRBool aIsBegin, + const nsAString& aStringSpec, + nsSMILTimeValueSpec** aResult); + +#endif // __NS_SMILTIMEVALUESPEC_H__ Index: /cvsroot/mozilla/content/smil/src/nsSMILTimedDocumentRoot.cpp =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsSMILTimedDocumentRoot.cpp diff -N content/smil/src/nsSMILTimedDocumentRoot.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/content/smil/src/nsSMILTimedDocumentRoot.cpp 14 Sep 2005 10:44:11 -0000 @@ -0,0 +1,167 @@ +/* -*- 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 SVG project. + * + * 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 "nsSMILTimedDocumentRoot.h" +#include "nsSMILTimeValue.h" + +//////////////////////////////////////////////////////////////////////// +// nsSMILTimedDocumentRoot implementation + +nsSMILTimedDocumentRoot::nsSMILTimedDocumentRoot( + nsSMILAnimationRegistry* registry) +: + mStartTime(), + mAccumulatedOffset(), + mAnimationRegistry(registry) +{ +} + +//---------------------------------------------------------------------- +// nsISupports methods: + +NS_IMPL_ISUPPORTS2(nsSMILTimedDocumentRoot, + nsISMILTimeContainer, + nsISupportsWeakReference); + +//---------------------------------------------------------------------- +// nsSMILTimedDocumentRoot methods + +nsSMILTimeValue +nsSMILTimedDocumentRoot::WallclockToDocumentTime(nsISMILTimeValueSpec* + aWallclockSpec) +{ + // TODO[2] + return nsSMILTimeValue(); +} + +nsresult +nsSMILTimedDocumentRoot::SeekToTime(PRInt64 aSeekTo) +{ + // TODO[3] + return NS_ERROR_NOT_IMPLEMENTED; +} + +//---------------------------------------------------------------------- +// nsISMILTimeContainer methods + +nsresult +nsSMILTimedDocumentRoot::Pause() +{ + // TODO[2] + return NS_ERROR_NOT_IMPLEMENTED; +} + +nsresult +nsSMILTimedDocumentRoot::Resume() +{ + // TODO[2] + return NS_ERROR_NOT_IMPLEMENTED; +} + +void +nsSMILTimedDocumentRoot::Sample() +{ + /* + * It's probably more correct to use PRIntervalNow but I'm not sure if it + * will have sufficient range and it's unsigned. + */ + PRInt64 now; + LL_DIV(now, PR_Now(), PR_USEC_PER_MSEC); + + /* + * If this is the first time, record the document begin time + */ + if (LL_IS_ZERO(mStartTime)) + mStartTime = now; + + PRInt64 instant; + LL_SUB(instant, now, mStartTime); + + if (mAnimationRegistry) + mAnimationRegistry->StartSample(); + + SampleChildren(instant); + + if (mAnimationRegistry) + mAnimationRegistry->EndSample(); +} + +nsresult +nsSMILTimedDocumentRoot::AddTimedElement(nsISMILTimedElement* aElement) +{ + if (!aElement) + return NS_ERROR_NULL_POINTER; + + nsresult rv; + nsCOMPtr weakRef( + getter_AddRefs(do_GetWeakReference(aElement, &rv)) ); + + if (NS_SUCCEEDED(rv)) + rv = (mTimedElements.AppendObject(weakRef)) ? NS_OK : NS_ERROR_FAILURE; + + // TODO[1]: If the object already exists, don't freak out, it may have been + // removed from the tree and re-added between samples (objects are removed + // during each sample) + + return rv; +} + +nsresult +nsSMILTimedDocumentRoot::RemoveTimedElement(nsISMILTimedElement* aElement) +{ + // TODO[2] + return NS_ERROR_NOT_IMPLEMENTED; +} + +//---------------------------------------------------------------------- +// Implementation helpers: + +void +nsSMILTimedDocumentRoot::SampleChildren(PRInt64 aDocumentTime) +{ + // TODO[f]: Replace with something thread-safe--probably a subclassed + // enumerator + PRUint32 i = mTimedElements.Count(); + while (i > 0) + { + --i; + nsCOMPtr + element( do_QueryReferent(mTimedElements[i]) ); + + if (element) + element->SampleAt(aDocumentTime); + else + mTimedElements.RemoveObjectAt(i); + } +} + Index: /cvsroot/mozilla/content/smil/src/nsSMILTimedDocumentRoot.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsSMILTimedDocumentRoot.h diff -N content/smil/src/nsSMILTimedDocumentRoot.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/content/smil/src/nsSMILTimedDocumentRoot.h 14 Sep 2005 10:44: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 the Mozilla SVG project. + * + * 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_SMILTIMEDDOCUMENTROOT_H__ +#define __NS_SMILTIMEDDOCUMENTROOT_H__ + +#include "nsISupports.h" +#include "nsISMILTimeContainer.h" +#include "nsSMILAnimationRegistry.h" +#include "nsWeakReference.h" +#include "nsCOMArray.h" + +class nsISMILTimeValueSpec; +class nsISMILTimedElement; +class nsSMILTimeValue; + +//////////////////////////////////////////////////////////////////////// +// nsSMILTimedDocumentRoot: Timed document root + +class nsSMILTimedDocumentRoot : public nsISMILTimeContainer, + public nsSupportsWeakReference +{ +public: + nsSMILTimedDocumentRoot(nsSMILAnimationRegistry* registry); + + NS_DECL_ISUPPORTS + + nsSMILTimeValue WallclockToDocumentTime(nsISMILTimeValueSpec* + aWallclockSpec); + nsresult SeekToTime(PRInt64 aSeekTo); + + // nsISMILTimeContainer + virtual nsresult Pause(); + virtual nsresult Resume(); + virtual void Sample(); + virtual nsresult AddTimedElement(nsISMILTimedElement* aElement); + virtual nsresult RemoveTimedElement(nsISMILTimedElement* aElement); + +protected: + void SampleChildren(PRInt64 aDocumentTime); + + PRInt64 mStartTime; + PRInt64 mAccumulatedOffset; + nsCOMArray mTimedElements; + nsSMILAnimationRegistry* mAnimationRegistry; +}; + +#endif // __NS_SMILTIMEDDOCUMENTROOT_H__ + Index: /cvsroot/mozilla/content/smil/src/nsSMILTimedElement.cpp =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsSMILTimedElement.cpp diff -N content/smil/src/nsSMILTimedElement.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/content/smil/src/nsSMILTimedElement.cpp 14 Sep 2005 10:44:13 -0000 @@ -0,0 +1,913 @@ +/* -*- 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 SVG project. + * + * 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 "nsISMILTimedElement.h" +#include "nsSMILTimeValue.h" +#include "nsSMILTimeValueSpec.h" +#include "nsSMILInstanceTime.h" +#include "nsSMILInterval.h" +#include "nsISMILTimeClient.h" +#include "nsCOMArray.h" +#include "nsReadableUtils.h" +#include "nsAutoPtr.h" +#include "prdtoa.h" +#include "plstr.h" + +//---------------------------------------------------------------------- +// Class declaration + +class nsSMILTimedElement : public nsISMILTimedElement +{ +public: + NS_DECL_ISUPPORTS + + /* + * nsISMILTimedElement + */ + virtual void AddInstanceTime(nsSMILInstanceTime* aInstanceTime, + PRBool aIsBegin); + virtual void SetTimeClient(nsISMILTimeClient* aClient); + virtual void SampleAt(const PRInt64& aDocumentTime); + + virtual nsresult SetBeginSpec(const nsAString& aBeginSpec); + virtual nsresult SetEndSpec(const nsAString& aEndSpec); + virtual nsresult SetSimpleDuration(const nsAString& aDurSpec); + virtual nsresult SetMin(const nsAString& aMinSpec); + virtual nsresult SetMax(const nsAString& aMaxSpec); + virtual nsresult SetRestart(const nsAString& aRestartSpec); + virtual nsresult SetRepeatCount(const nsAString& aRepeatCountSpec); + virtual nsresult SetRepeatDur(const nsAString& aRepeatDurSpec); + virtual nsresult SetFillMode(const nsAString& aFillModeSpec); + + virtual void UnsetBeginSpec(); + virtual void UnsetEndSpec(); + virtual void UnsetSimpleDuration(); + virtual void UnsetMin(); + virtual void UnsetMax(); + virtual void UnsetRestart(); + virtual void UnsetRepeatCount(); + virtual void UnsetRepeatDur(); + virtual void UnsetFillMode(); + +protected: + nsSMILTimedElement(); + virtual ~nsSMILTimedElement(); + + friend nsISMILTimedElement* NS_NewSMILTimedElement(); + + /* + * Implementation helpers + */ + + /* + * This may eventually be pushed to the public interface in order to support + * repeating time containers. For now we just use it when we need to + * re-initialise internally, such as when because a new begin specification is + * set. + */ + void Reset(); + + nsresult SetBeginOrEndSpec(const nsAString& aSpec, PRBool aIsBegin); + + /** + * Calculates the first acceptable interval for this element. + * + * @see SMILANIM 3.6.8 + */ + nsresult GetNextInterval(const nsSMILTimeValue& aBeginAfter, + PRBool aFirstInstance, + nsSMILInterval& aResult); + + PRBool GetNextGreater(const nsVoidArray& aList, + const nsSMILTimeValue& aBase, + PRInt32& aPosition, + nsSMILTimeValue& aResult); + + nsSMILTimeValue CalcActiveEnd(const nsSMILTimeValue& aBegin, + const nsSMILTimeValue& aEnd); + + PRInt64 ActiveTimeToSimpleTime(const PRInt64& aActiveTime, + PRUint32& aRepeatIteration); + + PRInt64 MinLL(const PRInt64& a, const PRInt64& b); + + /* + * Members + */ + nsCOMArray mBeginSpecs; + nsCOMArray mEndSpecs; + + /* + * We need to distinguish between attempting to set the begin spec and failing + * (in which case the mBeginSpecs array will be empty) and not attempting to + * set the begin spec at all. In the first case, we should act as if the begin + * was indefinite, and in the second, we should act as if begin was 0s. + */ + PRBool mBeginSpecSet; + + nsSMILTimeValue mSimpleDur; + + /** + * The number of iterations of the animation function. We use an + * nsSMILTimeValue type where: + * + * milliseconds = the number of iterations * 1000, + * indefinite = repeating indefinitely, until the document ends, and + * unresolved = the attribute is not set, therefore no repeating. + */ + nsSMILTimeValue mRepeatCount; + nsSMILTimeValue mRepeatDur; + + nsSMILTimeValue mMin; + nsSMILTimeValue mMax; + + enum nsSMILRestartMode + { + NS_SMIL_RESTART_ALWAYS, + NS_SMIL_RESTART_NEVER, + NS_SMIL_RESTART_WHENNOTACTIVE + }; + nsSMILRestartMode mRestartMode; + + enum nsSMILFillMode + { + NS_SMIL_FILL_REMOVE, + NS_SMIL_FILL_FREEZE + }; + nsSMILFillMode mFillMode; + + PRBool mEndHasEventConditions; + + // nsRefArray would be really nice here + nsVoidArray mBeginInstances; + nsVoidArray mEndInstances; + + nsCOMPtr mClient; + nsSMILInterval mCurrentInterval; + + /** + * The state of the element in its life-cycle. These states are based on the + * element life-cycle described in SMILANIM 3.6.8 + */ + enum nsSMILElementState + { + NS_SMIL_STATE_STARTUP, + NS_SMIL_STATE_WAITING, + NS_SMIL_STATE_ACTIVE, + NS_SMIL_STATE_POST_ACTIVE + }; + + nsSMILElementState mElementState; +}; + +//---------------------------------------------------------------------- +// Implementation + +nsISMILTimedElement* NS_NewSMILTimedElement() +{ + return new nsSMILTimedElement(); +} + +nsSMILTimedElement::nsSMILTimedElement() : mBeginSpecs(), + mEndSpecs(), + mBeginSpecSet(PR_FALSE), + mRestartMode(NS_SMIL_RESTART_ALWAYS), + mFillMode(NS_SMIL_FILL_REMOVE), + mEndHasEventConditions(PR_FALSE), + mElementState(NS_SMIL_STATE_STARTUP) +{ + mSimpleDur.SetIndefinite(); +} + +nsSMILTimedElement::~nsSMILTimedElement() +{ + PRInt32 i; + PRInt32 count = mBeginInstances.Count(); + + for (i = 0; i < count; ++i) + NS_STATIC_CAST(nsSMILInstanceTime*, mBeginInstances[i])->Release(); + + count = mEndInstances.Count(); + + for (i = 0; i < count; ++i) + NS_STATIC_CAST(nsSMILInstanceTime*, mEndInstances[i])->Release(); +} + +//---------------------------------------------------------------------- +// nsISupports + +NS_IMPL_ISUPPORTS2(nsSMILTimedElement, + nsISMILTimedElement, + nsISupportsWeakReference) + +//---------------------------------------------------------------------- +// nsISMILTimedElement + +void +nsSMILTimedElement::AddInstanceTime(nsSMILInstanceTime* aInstanceTime, + PRBool aIsBegin) +{ + NS_ASSERTION(aInstanceTime, "NULL instance time"); + + if (aIsBegin) + { + NS_ADDREF(aInstanceTime); + mBeginInstances.AppendElement(aInstanceTime); + } + else + { + NS_ADDREF(aInstanceTime); + mEndInstances.AppendElement(aInstanceTime); + } +} + +void +nsSMILTimedElement::SetTimeClient(nsISMILTimeClient* aClient) +{ + /* + * No need to check for NULL. A NULL parameter simply means to remove the + * previous client which we do by setting to NULL anyway. + */ + mClient = aClient; +} + +void +nsSMILTimedElement::SampleAt(const PRInt64& aDocumentTime) +{ + PRBool stateChanged; + nsSMILTimeValue docTime; + docTime.SetMillis(aDocumentTime); + + do + { + stateChanged = false; + + switch (mElementState) + { + case NS_SMIL_STATE_STARTUP: + { + nsSMILTimeValue beginAfter; + beginAfter.SetMillis(LL_MININT); + + mElementState = + (NS_SUCCEEDED(GetNextInterval(beginAfter, true, mCurrentInterval))) + ? NS_SMIL_STATE_WAITING + : NS_SMIL_STATE_POST_ACTIVE; + stateChanged = true; + } + break; + + case NS_SMIL_STATE_WAITING: + { + if (mCurrentInterval.Begin().CompareTo(docTime) < 1) + { + mElementState = NS_SMIL_STATE_ACTIVE; + if (mClient) + mClient->ToActive(mCurrentInterval.Begin().GetMillis()); + stateChanged = true; + } + } + break; + + case NS_SMIL_STATE_ACTIVE: + { + if (mCurrentInterval.End().CompareTo(docTime) < 1) + { + mElementState = + (NS_SUCCEEDED(GetNextInterval(mCurrentInterval.End(), + false, + mCurrentInterval))) + ? NS_SMIL_STATE_WAITING + : NS_SMIL_STATE_POST_ACTIVE; + if (mClient) + mClient->ToInactive(); + stateChanged = true; + } + else + { + PRInt64 beginTime = mCurrentInterval.Begin().GetMillis(); + + PRInt64 activeTime; + LL_SUB(activeTime, aDocumentTime, beginTime); + + if (mClient) + { + PRUint32 repeatIteration; + PRInt64 simpleTime = ActiveTimeToSimpleTime(activeTime, + repeatIteration); + mClient->SampleAt(simpleTime, mSimpleDur, repeatIteration); + } + } + } + break; + + case NS_SMIL_STATE_POST_ACTIVE: + // TODO: Sample the last value? + break; + } + } while (stateChanged); +} + +nsresult +nsSMILTimedElement::SetBeginSpec(const nsAString& aBeginSpec) +{ + mBeginSpecSet = PR_TRUE; + return SetBeginOrEndSpec(aBeginSpec, PR_TRUE); +} + +void +nsSMILTimedElement::UnsetBeginSpec() +{ + mBeginSpecs.Clear(); + mBeginInstances.Clear(); + mBeginSpecSet = PR_FALSE; + Reset(); +} + +nsresult +nsSMILTimedElement::SetEndSpec(const nsAString& aEndSpec) +{ + /* + * When implementing events etc., don't forget to ensure + * mEndEventHasEndConditions is set if the specification contains conditions + * that describe event-values, repeat-values or accessKey-values. + */ + return SetBeginOrEndSpec(aEndSpec, PR_FALSE); +} + +void +nsSMILTimedElement::UnsetEndSpec() +{ + mEndSpecs.Clear(); + mEndInstances.Clear(); + Reset(); +} + +nsresult +nsSMILTimedElement::SetSimpleDuration(const nsAString& aDurSpec) +{ + nsSMILTimeValue duration; + PRBool isMedia; + nsresult rv; + + rv = nsSMILTimeValueSpec::ParseClockValue(aDurSpec, + &duration, + false, // don't allow + or - + true, // allow indefinite + true, // allow media + &isMedia); + + if (NS_FAILED(rv) || (!duration.IsResolved() && !duration.IsIndefinite())) + return NS_ERROR_FAILURE; + + if (duration.IsResolved() && LL_EQ(duration.GetMillis(), LL_Zero())) + return NS_ERROR_FAILURE; + + /* + * SVG-specific: "For SVG's animation elements, if "media" is specified, the + * attribute will be ignored." (SVG 1.1, section 19.2.6) + */ + if (isMedia) + duration.SetIndefinite(); + + mSimpleDur = duration; + + return NS_OK; +} + +void +nsSMILTimedElement::UnsetSimpleDuration() +{ + mSimpleDur.SetIndefinite(); + Reset(); +} + +nsresult +nsSMILTimedElement::SetMin(const nsAString& aMinSpec) +{ + // TODO[2] + return NS_OK; +} + +void +nsSMILTimedElement::UnsetMin() +{ + // TODO[2] +} + +nsresult +nsSMILTimedElement::SetMax(const nsAString& aMaxSpec) +{ + // TODO[2] + return NS_OK; +} + +void +nsSMILTimedElement::UnsetMax() +{ + // TODO[2] +} + +nsresult +nsSMILTimedElement::SetRestart(const nsAString& aRestartSpec) +{ + // TODO[2] + return NS_OK; +} + +void +nsSMILTimedElement::UnsetRestart() +{ + // TODO[2] +} + +nsresult +nsSMILTimedElement::SetRepeatCount(const nsAString& aRepeatCountSpec) +{ + nsresult rv = NS_OK; + char* str = ToNewCString(aRepeatCountSpec); + char* number = str; + + nsSMILTimeValue newRepeatCount; + + Reset(); + + while (*number && isspace(*number)) + ++number; + + if (*number) + { + if (PL_strstr(number, "indefinite") == number) + { + newRepeatCount.SetIndefinite(); + number += PL_strlen("indefinite"); + } + else + { + char *rest; + PRFloat64 value = PR_strtod(number, &rest); + + if (rest != number) + { + PRInt64 count; + value *= 1000; + + LL_D2L(count, value); + + newRepeatCount.SetMillis(count); + + if (!LL_GE_ZERO(count) || LL_IS_ZERO(count)) + rv = NS_ERROR_FAILURE; + + number = rest; + } + else + { + rv = NS_ERROR_FAILURE; + } + } + + /* Check the remainder is whitespace */ + while (*number && isspace(*number)) + number++; + + if (*number != 0) + rv = NS_ERROR_FAILURE; + } + else + { + /* Empty spec */ + rv = NS_ERROR_FAILURE; + } + + if (NS_SUCCEEDED(rv)) + mRepeatCount = newRepeatCount; + else + mRepeatCount.SetUnresolved(); + + nsMemory::Free(str); + + return rv; +} + +void +nsSMILTimedElement::UnsetRepeatCount() +{ + mRepeatCount.SetUnresolved(); + Reset(); +} + +nsresult +nsSMILTimedElement::SetRepeatDur(const nsAString& aRepeatDurSpec) +{ + nsresult rv; + nsSMILTimeValue duration; + + Reset(); + + rv = nsSMILTimeValueSpec::ParseClockValue(aRepeatDurSpec, + &duration, + false, // don't allow + or - + true); // allow indefinite + + if (NS_FAILED(rv) || (!duration.IsResolved() && !duration.IsIndefinite())) + return NS_ERROR_FAILURE; + + mRepeatDur = duration; + + return NS_OK; +} + +void +nsSMILTimedElement::UnsetRepeatDur() +{ + mRepeatDur.SetUnresolved(); + Reset(); +} + +nsresult +nsSMILTimedElement::SetFillMode(const nsAString& aFillModeSpec) +{ + // TODO[2] + return NS_OK; +} + +void +nsSMILTimedElement::UnsetFillMode() +{ + // TODO[2] +} + +//---------------------------------------------------------------------- +// Implementation helpers + +void +nsSMILTimedElement::Reset() +{ + nsSMILInstanceTime* instance; + PRInt32 count = mBeginInstances.Count(); + + for (PRInt32 i = 0; i < count; ++i) + { + instance = NS_STATIC_CAST(nsSMILInstanceTime*, mBeginInstances[i]); + if (instance->ClearOnReset()) + mBeginInstances.RemoveElementAt(i); + } + + count = mEndInstances.Count(); + + for (PRInt32 i = 0; i < count; ++i) + { + instance = NS_STATIC_CAST(nsSMILInstanceTime*, mEndInstances[i]); + if (instance->ClearOnReset()) + mEndInstances.RemoveElementAt(i); + } + + nsSMILTimeValue unresolved; + mCurrentInterval = nsSMILInterval(unresolved, unresolved); + mElementState = NS_SMIL_STATE_STARTUP; + + // TODO[2] Clear old intervals +} + +nsresult +nsSMILTimedElement::SetBeginOrEndSpec(const nsAString& aSpec, + PRBool aIsBegin) +{ + nsresult rv = NS_ERROR_FAILURE; + + nsRefPtr spec; + nsCOMArray& timeSpecsList = (aIsBegin) + ? mBeginSpecs + : mEndSpecs; + nsVoidArray& instancesList = (aIsBegin) + ? mBeginInstances + : mEndInstances; + + timeSpecsList.Clear(); + instancesList.Clear(); + Reset(); + + PRInt32 start; + PRInt32 end = -1; + PRInt32 length; + + do + { + start = end + 1; + end = aSpec.FindChar(';', start); + length = (end == -1) ? -1 : end - start; + + rv = NS_NewSMILTimeValueSpec(this, aIsBegin, + Substring(aSpec, start, length), getter_AddRefs(spec)); + + if (NS_SUCCEEDED(rv)) + { + timeSpecsList.AppendObject(spec); + } + else + { + // TODO[3]: Appropriate error handling + } + } while (end != -1); + + return rv; +} + +/* + * This method is based on the pseudocode given in the SMILANIM spec. + * + * See: + * http://www.w3.org/TR/2001/REC-smil-animation-20010904/#Timing-BeginEnd-LC-Start + */ +nsresult +nsSMILTimedElement::GetNextInterval(const nsSMILTimeValue& aBeginAfter, + PRBool aFirstInterval, + nsSMILInterval& aResult) +{ + static nsSMILTimeValue zeroTime; + zeroTime.SetMillis(LL_Zero()); + + nsSMILTimeValue beginAfter = aBeginAfter; + nsSMILTimeValue tempBegin; + nsSMILTimeValue tempEnd; + PRInt32 beginPos = 0; + PRInt32 endPos = 0; + + /* + * This is to handle the special case when a we are calculating the first + * interval and we have a non-0-duration interval immediately after + * a 0-duration in which case but we have to be careful not to re-use an end + * that has already been used in another interval. See the pseudocode in + * SMILANIM 3.6.8 for getFirstInterval. + */ + PRInt32 endMaxPos = 0; + + mBeginInstances.Sort(nsSMILTimeValue::ComparisonCallback, nsnull); + mEndInstances.Sort(nsSMILTimeValue::ComparisonCallback, nsnull); + + while (true) + { + if (!mBeginSpecSet && beginAfter.CompareTo(zeroTime) < 1) + { + tempBegin.SetMillis(0); + } + else + { + PRBool beginFound = GetNextGreater(mBeginInstances, beginAfter, + beginPos, tempBegin); + if (!beginFound) + return NS_ERROR_FAILURE; + } + + if (mEndSpecs.Count() == 0) + { + nsSMILTimeValue indefiniteEnd; + indefiniteEnd.SetIndefinite(); + + tempEnd = CalcActiveEnd(tempBegin, indefiniteEnd); + } + else + { + /* + * Start searching from the beginning again. + */ + endPos = 0; + + PRBool endFound = GetNextGreater(mEndInstances, tempBegin, + endPos, tempEnd); + + if + ( + !aFirstInterval && tempEnd.CompareTo(aBeginAfter)==0 + || + (aFirstInterval && tempEnd.CompareTo(tempBegin)==0 && endPos<=endMaxPos) + ) + { + endFound = GetNextGreater(mEndInstances, tempBegin, endPos, tempEnd); + } + + endMaxPos = endPos; + + if (!endFound) + { + if (mEndHasEventConditions || mEndInstances.Count() == 0) + tempEnd.SetUnresolved(); + else + /* + * This is a little counter-intuitive but according to SMILANIM, if + * all the end's are after the begin, we _don't_ just assume an + * infinite end, it's actually a bad interval. ASV however will just + * use an infinite end. + */ + return NS_ERROR_FAILURE; + } + + tempEnd = CalcActiveEnd(tempBegin, tempEnd); + } + + if (tempEnd.CompareTo(zeroTime) == 1) + { + aResult = nsSMILInterval(tempBegin, tempEnd); + return NS_OK; + } + /* + TODO[2] + else if (restart == never) + { + return NS_ERROR_FAILURE; + } + */ + else + { + beginAfter = tempEnd; + } + } + NS_NOTREACHED("Hmm... we really shouldn't be here"); + + return NS_ERROR_FAILURE; +} + +PRBool +nsSMILTimedElement::GetNextGreater(const nsVoidArray& aList, + const nsSMILTimeValue& aBase, + PRInt32 &aPosition, + nsSMILTimeValue& aResult) +{ + PRBool found = PR_FALSE; + nsSMILInstanceTime* val; + PRInt32 count = aList.Count(); + + for (; aPosition < count && !found; ++aPosition) + { + val = NS_STATIC_CAST(nsSMILInstanceTime*, aList[aPosition]); + if (val->Time().CompareTo(aBase) > -1) + { + aResult = val->Time(); + found = PR_TRUE; + } + } + + return found; +} + +inline PRInt64 +nsSMILTimedElement::MinLL(const PRInt64& a, const PRInt64& b) +{ + return (LL_CMP(a, <, b)) ? a : b; +} + +/** + * @see SMILANIM 3.3.4 + */ +nsSMILTimeValue +nsSMILTimedElement::CalcActiveEnd(const nsSMILTimeValue& aBegin, + const nsSMILTimeValue& aEnd) +{ + nsSMILTimeValue result; + + if (!aEnd.IsIndefinite() && !aEnd.IsResolved()) + { + NS_ASSERTION(false, "Unresolved end time passed to CalcActiveEnd."); + result.SetIndefinite(); + return result; + } + + if (!mSimpleDur.IsIndefinite() && !mSimpleDur.IsResolved()) + { + NS_ASSERTION(false, "Unresolved simple duration in CalcActiveEnd."); + result.SetIndefinite(); + return result; + } + + if (!aBegin.IsResolved() && !aBegin.IsIndefinite()) + { + NS_ASSERTION(false, "Unresolved begin time passed to CalcActiveEnd."); + result.SetIndefinite(); + return result; + } + + if (mRepeatDur.IsIndefinite() || aBegin.IsIndefinite()) + { + result.SetIndefinite(); + } + else + { + if (mRepeatCount.IsResolved() && mRepeatDur.IsResolved()) + { + if (mSimpleDur.IsResolved()) + { + PRInt64 activeDur; + LL_MUL(activeDur, mRepeatCount.GetMillis(), mSimpleDur.GetMillis()); + LL_DIV(activeDur, activeDur, 1000); + result.SetMillis(MinLL(activeDur, mRepeatDur.GetMillis())); + } + else + { + result = mRepeatDur; + } + } + else if (mRepeatCount.IsResolved() && mSimpleDur.IsResolved()) + { + PRInt64 activeDur; + LL_MUL(activeDur, mRepeatCount.GetMillis(), mSimpleDur.GetMillis()); + LL_DIV(activeDur, activeDur, 1000); + result.SetMillis(activeDur); + } + else if (mRepeatDur.IsResolved()) + { + result = mRepeatDur; + } + else + { + if (mRepeatCount.IsIndefinite()) + { + result.SetIndefinite(); + } + else + { + result = mSimpleDur; + } + } + } + + if (aEnd.IsResolved() && aBegin.IsResolved()) + { + PRInt64 activeDur; + LL_SUB(activeDur, aEnd.GetMillis(), aBegin.GetMillis()); + + if (result.IsResolved()) + { + result.SetMillis(MinLL(result.GetMillis(), activeDur)); + } + else + { + result.SetMillis(activeDur); + } + } + + if (result.IsResolved()) + { + PRInt64 activeEnd; + LL_ADD(activeEnd, result.GetMillis(), aBegin.GetMillis()); + result.SetMillis(activeEnd); + } + + return result; +} + +PRInt64 +nsSMILTimedElement::ActiveTimeToSimpleTime(const PRInt64& aActiveTime, + PRUint32& aRepeatIteration) +{ + PRInt64 result; + + NS_ASSERTION(mSimpleDur.IsResolved() || mSimpleDur.IsIndefinite(), + "Trying to calculate active time with unresolved duration"); + + if (mSimpleDur.IsIndefinite() || LL_IS_ZERO(mSimpleDur.GetMillis())) + { + aRepeatIteration = 0; + result = aActiveTime; + } + else + { + PRInt64 repeatResult; + LL_MOD(result, aActiveTime, mSimpleDur.GetMillis()); + LL_DIV(repeatResult, aActiveTime, mSimpleDur.GetMillis()); + + LL_L2UI(aRepeatIteration, repeatResult); + } + + return result; +} Index: /cvsroot/mozilla/content/svg/content/src/Makefile.in =================================================================== RCS file: /cvsroot/mozilla/content/svg/content/src/Makefile.in,v retrieving revision 1.38 diff -u -r1.38 Makefile.in --- /cvsroot/mozilla/content/svg/content/src/Makefile.in 26 Aug 2005 02:49:49 -0000 1.38 +++ /cvsroot/mozilla/content/svg/content/src/Makefile.in 14 Sep 2005 10:44:17 -0000 @@ -136,6 +136,10 @@ CPPSRCS += nsSVGForeignObjectElement.cpp endif +ifdef MOZ_SMIL +CPPSRCS += nsSVGAnimateElement.cpp +endif + include $(topsrcdir)/config/config.mk # we don't want the shared lib, but we want to force the creation of a static lib. @@ -178,3 +182,6 @@ $(NULL) DEFINES += -D_IMPL_NS_LAYOUT + +#CXXFLAGS += -P + Index: /cvsroot/mozilla/content/svg/content/src/nsISVGLength.h =================================================================== RCS file: /cvsroot/mozilla/content/svg/content/src/nsISVGLength.h,v retrieving revision 1.4 diff -u -r1.4 nsISVGLength.h --- /cvsroot/mozilla/content/svg/content/src/nsISVGLength.h 5 Aug 2004 09:01:09 -0000 1.4 +++ /cvsroot/mozilla/content/svg/content/src/nsISVGLength.h 14 Sep 2005 10:44:17 -0000 @@ -42,6 +42,9 @@ #include "nsIDOMSVGLength.h" class nsSVGCoordCtx; +#ifdef MOZ_SMIL +class nsISMILAnimVal; +#endif // MOZ_SMIL //////////////////////////////////////////////////////////////////////// // nsISVGLength: private interface for svg lengths @@ -55,7 +58,11 @@ public: NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISVGLENGTH_IID) - NS_IMETHOD SetContext(nsSVGCoordCtx* ctx)=0; + NS_IMETHOD SetContext(nsSVGCoordCtx* ctx)=0; +#ifdef MOZ_SMIL + virtual nsresult GetAnimValue(nsIDOMSVGLength** aResult)=0; + virtual nsresult GetAnimVal(nsISMILAnimVal** aResult)=0; +#endif // MOZ_SMIL }; Index: /cvsroot/mozilla/content/svg/content/src/nsISVGSVGElement.h =================================================================== RCS file: /cvsroot/mozilla/content/svg/content/src/nsISVGSVGElement.h,v retrieving revision 1.6 diff -u -r1.6 nsISVGSVGElement.h --- /cvsroot/mozilla/content/svg/content/src/nsISVGSVGElement.h 25 Aug 2005 21:31:07 -0000 1.6 +++ /cvsroot/mozilla/content/svg/content/src/nsISVGSVGElement.h 14 Sep 2005 10:44:17 -0000 @@ -46,6 +46,9 @@ class nsSVGCoordCtxProvider; class nsIDOMSVGNumber; class nsISVGEnum; +#ifdef MOZ_SMIL +class nsISMILAnimationRegistry; +#endif //////////////////////////////////////////////////////////////////////// // nsISVGSVGElement: private interface implemented by -elements @@ -89,6 +92,13 @@ NS_IMETHOD_(float) GetPreviousScale()=0; NS_IMETHOD_(float) GetPreviousTranslate_x()=0; NS_IMETHOD_(float) GetPreviousTranslate_y()=0; + +#ifdef MOZ_SMIL + /** + * Get the animation registry object for the outermost svg element. + */ + NS_IMETHOD_(nsISMILAnimationRegistry*) GetAnimationRegistry()=0; +#endif }; #endif // __NS_ISVGSVGELEMENT__ Index: /cvsroot/mozilla/content/svg/content/src/nsSVGAnimateElement.cpp =================================================================== RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGAnimateElement.cpp diff -N content/svg/content/src/nsSVGAnimateElement.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/content/svg/content/src/nsSVGAnimateElement.cpp 14 Sep 2005 10:44:19 -0000 @@ -0,0 +1,623 @@ +/* -*- 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 SVG project. + * + * 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 "nsSVGElement.h" +#include "nsIDOMSVGAnimateElement.h" +#include "nsSVGAtoms.h" +#include "nsISVGSVGElement.h" +#include "nsIBindingManager.h" +#include "nsIDocument.h" +#include "nsISMILTimedElement.h" +#include "nsISMILAnimationFunction.h" +#include "nsISMILAnimElement.h" +#include "nsISMILAnimationRegistry.h" +#include "nsISMILTimeClient.h" +#include "nsISMILComposable.h" + +typedef nsSVGElement nsSVGAnimateElementBase; + +class nsSVGAnimateElement : public nsSVGAnimateElementBase, + public nsIDOMSVGAnimateElement + // : nsIDOMSVGAnimationElement +{ +protected: + friend nsresult NS_NewSVGAnimateElement(nsIContent **aResult, + nsINodeInfo *aNodeInfo); + nsSVGAnimateElement(nsINodeInfo* aNodeInfo); + nsresult Init(); + +public: + // interfaces: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIDOMSVGANIMATEELEMENT + NS_DECL_NSIDOMSVGANIMATIONELEMENT + + NS_FORWARD_NSIDOMNODE_NO_CLONENODE(nsSVGAnimateElementBase::) + NS_FORWARD_NSIDOMELEMENT(nsSVGAnimateElementBase::) + NS_FORWARD_NSIDOMSVGELEMENT(nsSVGAnimateElementBase::) + + // nsISVGContent specializations + virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, + nsIContent* aBindingParent, + PRBool aCompileEventHandlers); + virtual void UnbindFromTree(PRBool aDeep = PR_TRUE, + PRBool aNullParent = PR_TRUE); + + // nsIContent specializations + virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, + nsIAtom* aPrefix, const nsAString& aValue, + PRBool aNotify); + virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute, + PRBool aNotify); + +protected: + // Implementation helpers + nsISMILAnimationRegistry* GetAnimationRegistry(); + nsIContent* GetParentElement(); + void UpdateTargetElement(); + nsISMILAnimAttr* GetTargetAttribute(); + void UpdateTargetAttribute(); + void SetAnimationProperties(); + + nsWeakPtr mTargetElement; + nsRefPtr mAnimation; + nsCOMPtr mTimedElement; +}; + +NS_IMPL_NS_NEW_SVG_ELEMENT(Animate) + + +//---------------------------------------------------------------------- +// nsISupports methods + +NS_IMPL_ADDREF_INHERITED(nsSVGAnimateElement,nsSVGAnimateElementBase) +NS_IMPL_RELEASE_INHERITED(nsSVGAnimateElement,nsSVGAnimateElementBase) + +NS_INTERFACE_MAP_BEGIN(nsSVGAnimateElement) + NS_INTERFACE_MAP_ENTRY(nsIDOMNode) + NS_INTERFACE_MAP_ENTRY(nsIDOMElement) + NS_INTERFACE_MAP_ENTRY(nsIDOMSVGElement) + NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimationElement) + NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimateElement) + NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGAnimateElement) +NS_INTERFACE_MAP_END_INHERITING(nsSVGAnimateElementBase) + +//---------------------------------------------------------------------- +// Implementation + +nsSVGAnimateElement::nsSVGAnimateElement(nsINodeInfo *aNodeInfo) + : nsSVGAnimateElementBase(aNodeInfo) +{ +} + +nsresult +nsSVGAnimateElement::Init() +{ + mTimedElement = NS_NewSMILTimedElement(); + mAnimation = NS_NewSMILAnimationFunction(); + + return (mTimedElement) ? NS_OK : NS_ERROR_FAILURE; +} + +//---------------------------------------------------------------------- +// nsIDOMSVGAnimationElement methods + +/* readonly attribute SVGElement targetElement; */ +NS_IMETHODIMP nsSVGAnimateElement::GetTargetElement(nsIDOMSVGElement * *aTarget) +{ + if (mTargetElement) + { + nsCOMPtr weakref = do_QueryReferent(mTargetElement); + if (*aTarget) + NS_RELEASE(*aTarget); + NS_IF_ADDREF(*aTarget = weakref); + } + return NS_OK; +} + +NS_IMETHODIMP nsSVGAnimateElement::GetStartTime(float* retval) +{ + nsresult rv = NS_ERROR_FAILURE; + + if (mTimedElement) + { + // TODO[3]: Fill this in + rv = NS_ERROR_NOT_IMPLEMENTED; + } + + return rv; +} + +NS_IMETHODIMP nsSVGAnimateElement::GetCurrentTime(float* retval) +{ + // TODO[3]: Query the time container + return NS_OK; +} + +NS_IMETHODIMP nsSVGAnimateElement::GetSimpleDuration(float* retval) +{ + // TODO[3]: Query the timed element + return NS_OK; +} + + +//---------------------------------------------------------------------- +// nsIDOMNode methods + +NS_IMPL_DOM_CLONENODE_WITH_INIT(nsSVGAnimateElement) + + +//---------------------------------------------------------------------- +// nsISVGContent methods + +nsresult nsSVGAnimateElement::BindToTree(nsIDocument* aDocument, + nsIContent* aParent, + nsIContent* aBindingParent, + PRBool aCompileEventHandlers) +{ + nsresult rv = nsSVGAnimateElementBase::BindToTree(aDocument, aParent, + aBindingParent, + aCompileEventHandlers); + + if (NS_SUCCEEDED(rv)) + { + UpdateTargetElement(); + + if (mTimedElement) + { + + nsCOMPtr registry = GetAnimationRegistry(); + if (registry) + rv = registry->RegisterTimedElement(mTimedElement); + } + } + + return rv; +} + +void nsSVGAnimateElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent) +{ + if (mTimedElement) + { + nsCOMPtr registry = GetAnimationRegistry(); + if (registry) + registry->UnregisterTimedElement(mTimedElement); + } + + nsSVGAnimateElementBase::UnbindFromTree(aDeep, aNullParent); + + UpdateTargetElement(); +} + +//---------------------------------------------------------------------- +// nsIContent methods + +nsresult nsSVGAnimateElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, + nsIAtom* aPrefix, const nsAString& aValue, + PRBool aNotify) +{ + nsresult rv = nsSVGAnimateElementBase::SetAttr(aNameSpaceID, aName, aPrefix, + aValue, aNotify); + + NS_ASSERTION(mTimedElement, "Unexpected NULL timed element."); + + if (aName == nsSVGAtoms::attributeName && aNameSpaceID == kNameSpaceID_None) + { + UpdateTargetAttribute(); + return rv; + } + + if (mTimedElement && aNameSpaceID == kNameSpaceID_None) + { + if (aName == nsSVGAtoms::begin) + { + rv = mTimedElement->SetBeginSpec(aValue); + NS_ENSURE_SUCCESS(rv,rv); + } + else if (aName == nsSVGAtoms::dur) + { + rv = mTimedElement->SetSimpleDuration(aValue); + NS_ENSURE_SUCCESS(rv,rv); + } + else if (aName == nsSVGAtoms::end) + { + rv = mTimedElement->SetEndSpec(aValue); + NS_ENSURE_SUCCESS(rv,rv); + } + else if (aName == nsSVGAtoms::fill) + { + rv = mTimedElement->SetFillMode(aValue); + NS_ENSURE_SUCCESS(rv,rv); + } + else if (aName == nsSVGAtoms::max) + { + rv = mTimedElement->SetMax(aValue); + NS_ENSURE_SUCCESS(rv,rv); + } + else if (aName == nsSVGAtoms::min) + { + rv = mTimedElement->SetMin(aValue); + NS_ENSURE_SUCCESS(rv,rv); + } + else if (aName == nsSVGAtoms::repeatCount) + { + rv = mTimedElement->SetRepeatCount(aValue); + NS_ENSURE_SUCCESS(rv,rv); + } + else if (aName == nsSVGAtoms::repeatDur) + { + rv = mTimedElement->SetRepeatDur(aValue); + NS_ENSURE_SUCCESS(rv,rv); + } + else if (aName == nsSVGAtoms::restart) + { + rv = mTimedElement->SetRestart(aValue); + NS_ENSURE_SUCCESS(rv,rv); + } + + return rv; + } + + /* + * When we support xlink href's we need to revise the namespace restriction + * here. + */ + if (mAnimation && mAnimation->IsInitialised() && + aNameSpaceID == kNameSpaceID_None) + { + if (aName == nsSVGAtoms::accumulate) + { + rv = mAnimation->SetAccumulate(aValue); + NS_ENSURE_SUCCESS(rv,rv); + } + else if (aName == nsSVGAtoms::additive) + { + rv = mAnimation->SetAdditive(aValue); + NS_ENSURE_SUCCESS(rv,rv); + } + else if (aName == nsSVGAtoms::by) + { + rv = mAnimation->SetBy(aValue); + NS_ENSURE_SUCCESS(rv,rv); + } + else if (aName == nsSVGAtoms::calcMode) + { + rv = mAnimation->SetCalcMode(aValue); + NS_ENSURE_SUCCESS(rv,rv); + } + else if (aName == nsSVGAtoms::from) + { + rv = mAnimation->SetFrom(aValue); + NS_ENSURE_SUCCESS(rv,rv); + } + else if (aName == nsSVGAtoms::keyTimes) + { + rv = mAnimation->SetKeyTimes(aValue); + NS_ENSURE_SUCCESS(rv,rv); + } + else if (aName == nsSVGAtoms::keySplines) + { + rv = mAnimation->SetKeySplines(aValue); + NS_ENSURE_SUCCESS(rv,rv); + } + else if (aName == nsSVGAtoms::to) + { + rv = mAnimation->SetTo(aValue); + NS_ENSURE_SUCCESS(rv,rv); + } + else if (aName == nsSVGAtoms::values) + { + rv = mAnimation->SetValues(aValue); + NS_ENSURE_SUCCESS(rv,rv); + } + return rv; + } + + return rv; +} + +nsresult nsSVGAnimateElement::UnsetAttr(PRInt32 aNameSpaceID, + nsIAtom* aAttribute, PRBool aNotify) +{ + nsresult rv = nsSVGAnimateElementBase::UnsetAttr(aNameSpaceID, aAttribute, + aNotify); + + if (aAttribute == nsSVGAtoms::attributeName && + aNameSpaceID == kNameSpaceID_None) + { + UpdateTargetAttribute(); + } + else if (mTimedElement && aNameSpaceID == kNameSpaceID_None) + { + if (aAttribute == nsSVGAtoms::begin) + mTimedElement->UnsetBeginSpec(); + else if (aAttribute == nsSVGAtoms::dur) + mTimedElement->UnsetSimpleDuration(); + else if (aAttribute == nsSVGAtoms::end) + mTimedElement->UnsetEndSpec(); + else if (aAttribute == nsSVGAtoms::fill) + mTimedElement->UnsetFillMode(); + else if (aAttribute == nsSVGAtoms::max) + mTimedElement->UnsetMax(); + else if (aAttribute == nsSVGAtoms::min) + mTimedElement->UnsetMin(); + else if (aAttribute == nsSVGAtoms::repeatCount) + mTimedElement->UnsetRepeatCount(); + else if (aAttribute == nsSVGAtoms::repeatDur) + mTimedElement->UnsetRepeatDur(); + else if (aAttribute == nsSVGAtoms::restart) + mTimedElement->UnsetRestart(); + } + else if (mAnimation && mAnimation->IsInitialised() && + aNameSpaceID == kNameSpaceID_None) + { + if (aAttribute == nsSVGAtoms::accumulate) + mAnimation->UnsetAccumulate(); + else if (aAttribute == nsSVGAtoms::additive) + mAnimation->UnsetAdditive(); + else if (aAttribute == nsSVGAtoms::by) + mAnimation->UnsetBy(); + else if (aAttribute == nsSVGAtoms::calcMode) + mAnimation->UnsetCalcMode(); + else if (aAttribute == nsSVGAtoms::from) + mAnimation->UnsetFrom(); + else if (aAttribute == nsSVGAtoms::keyTimes) + mAnimation->UnsetKeyTimes(); + else if (aAttribute == nsSVGAtoms::keySplines) + mAnimation->UnsetKeySplines(); + else if (aAttribute == nsSVGAtoms::to) + mAnimation->UnsetTo(); + else if (aAttribute == nsSVGAtoms::values) + mAnimation->UnsetValues(); + } + + return rv; +} + +//---------------------------------------------------------------------- +// Implementation helpers + +nsISMILAnimationRegistry* +nsSVGAnimateElement::GetAnimationRegistry() +{ + nsISMILAnimationRegistry* result = nsnull; + nsCOMPtr ownerDOMSVG; + + nsresult rv = GetOwnerSVGElement(getter_AddRefs(ownerDOMSVG)); + + if (NS_SUCCEEDED(rv) && ownerDOMSVG) + { + nsCOMPtr ownerSVG( do_QueryInterface(ownerDOMSVG, &rv) ); + + if (ownerSVG) + result = ownerSVG->GetAnimationRegistry(); + } + + return result; +} + +nsIContent* +nsSVGAnimateElement::GetParentElement() +{ + nsIContent* result = nsnull; + nsIBindingManager* bindingManager = nsnull; + nsIDocument* ownerDoc = GetOwnerDoc(); + + if (ownerDoc) + bindingManager = ownerDoc->BindingManager(); + + if (bindingManager) + // we have a binding manager -- do we have an anonymous parent? + bindingManager->GetInsertionParent(this, &result); + + if (!result) + // if we didn't find an anonymous parent, use the explicit one, + // whether it's null or not... + result = GetParent(); + + return result; +} + +void +nsSVGAnimateElement::UpdateTargetElement() +{ + // XXX Follow xlink:href attributes when provided + + nsCOMPtr target = GetParentElement(); + + if (target) + { + nsWeakPtr targetElement = do_GetWeakReference(target); + if (targetElement && mTargetElement != targetElement) + { + mTargetElement = targetElement; + UpdateTargetAttribute(); + } + } + else + { + mTargetElement = nsnull; + mAnimation = nsnull; + } +} + +nsISMILAnimAttr* +nsSVGAnimateElement::GetTargetAttribute() +{ + nsISMILAnimAttr* result = nsnull; + + if (mTargetElement) + { + nsAutoString attributeName; + + GetAttr(kNameSpaceID_None, nsSVGAtoms::attributeName, attributeName); + + nsCOMPtr attributeAtom( do_GetAtom(attributeName) ); + nsCOMPtr + targetElement(do_QueryReferent(mTargetElement)); + + if (targetElement && attributeAtom) + { + result = + targetElement->GetAnimAttribute(kNameSpaceID_None, attributeAtom); + } + } + + return result; +} + +void +nsSVGAnimateElement::UpdateTargetAttribute() +{ + // XXX Implement XML vs CSS vs auto attribute types + nsresult rv; + + if (mTargetElement) + { + nsCOMPtr targetAttribute = GetTargetAttribute(); + + if (targetAttribute) + { + if (!mAnimation) + mAnimation = NS_NewSMILAnimationFunction(); + NS_ENSURE_TRUE(mAnimation,); + + rv = mAnimation->Init(*targetAttribute); + NS_ENSURE_SUCCESS(rv,); + + SetAnimationProperties(); + + nsCOMPtr timeClient( do_QueryInterface(mAnimation) ); + NS_ENSURE_TRUE(timeClient,); + if (mTimedElement) + mTimedElement->SetTimeClient(timeClient); + + nsCOMPtr registry = GetAnimationRegistry(); + NS_ENSURE_TRUE(registry,); + + nsCOMPtr composable( do_QueryInterface(mAnimation) ); + NS_ENSURE_TRUE(composable,); + + registry->RegisterComposable(targetAttribute, composable); + } + else + { + // XXX Attribute doesn't exist or it isn't animatable, mark document + // in error + // (if necessary, we might re-arrange the GetTargetAttribute method so we + // can produce separate errors for when the element is not animatable and + // when the attribute can't be found or isn't animatable) + } + } + /* else: We may still be loading, ignore for now. This will be called again + * when our parent changes. */ +} + +/* + * After re-initialising an animation element with a new target attribute, it is + * necessary to reset all the properties for that element. That is because the + * animation element needs to know the type of the target attribute so it knows + * how to interpret the value specifications it is given as "from", "to" etc. + * parameters. + */ +void +nsSVGAnimateElement::SetAnimationProperties() +{ + nsAutoString result; + + NS_ASSERTION(mAnimation, "Animation not created"); + NS_ASSERTION(mAnimation->IsInitialised(), "Animation not initialised"); + + if (mAnimation && mAnimation->IsInitialised()) + { + if (HasAttr(kNameSpaceID_None, nsSVGAtoms::accumulate)) + { + if (NS_SUCCEEDED(GetAttr(kNameSpaceID_None, nsSVGAtoms::accumulate, + result))) + mAnimation->SetAccumulate(result); + } + + if (HasAttr(kNameSpaceID_None, nsSVGAtoms::additive)) + { + if (NS_SUCCEEDED(GetAttr(kNameSpaceID_None, nsSVGAtoms::additive, + result))) + mAnimation->SetAdditive(result); + } + + if (HasAttr(kNameSpaceID_None, nsSVGAtoms::by)) + { + if (NS_SUCCEEDED(GetAttr(kNameSpaceID_None, nsSVGAtoms::by, result))) + mAnimation->SetBy(result); + } + + if (HasAttr(kNameSpaceID_None, nsSVGAtoms::calcMode)) + { + if (NS_SUCCEEDED(GetAttr(kNameSpaceID_None, nsSVGAtoms::calcMode, + result))) + mAnimation->SetCalcMode(result); + } + + if (HasAttr(kNameSpaceID_None, nsSVGAtoms::from)) + { + if (NS_SUCCEEDED(GetAttr(kNameSpaceID_None, nsSVGAtoms::from, result))) + mAnimation->SetFrom(result); + } + + if (HasAttr(kNameSpaceID_None, nsSVGAtoms::keyTimes)) + { + if (NS_SUCCEEDED(GetAttr(kNameSpaceID_None, nsSVGAtoms::keyTimes, + result))) + mAnimation->SetKeyTimes(result); + } + + if (HasAttr(kNameSpaceID_None, nsSVGAtoms::keySplines)) + { + if (NS_SUCCEEDED(GetAttr(kNameSpaceID_None, nsSVGAtoms::keySplines, + result))) + mAnimation->SetKeySplines(result); + } + + if (HasAttr(kNameSpaceID_None, nsSVGAtoms::to)) + { + if (NS_SUCCEEDED(GetAttr(kNameSpaceID_None, nsSVGAtoms::to, result))) + mAnimation->SetTo(result); + } + + if (HasAttr(kNameSpaceID_None, nsSVGAtoms::values)) + { + if (NS_SUCCEEDED(GetAttr(kNameSpaceID_None, nsSVGAtoms::values, result))) + mAnimation->SetValues(result); + } + } +} + Index: /cvsroot/mozilla/content/svg/content/src/nsSVGAnimatedLength.cpp =================================================================== RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGAnimatedLength.cpp,v retrieving revision 1.8 diff -u -r1.8 nsSVGAnimatedLength.cpp --- /cvsroot/mozilla/content/svg/content/src/nsSVGAnimatedLength.cpp 31 Jan 2005 19:45:10 -0000 1.8 +++ /cvsroot/mozilla/content/svg/content/src/nsSVGAnimatedLength.cpp 14 Sep 2005 10:44:19 -0000 @@ -41,6 +41,10 @@ #include "nsSVGAnimatedLength.h" #include "nsSVGLength.h" #include "nsContentUtils.h" +#ifdef MOZ_SMIL +#include "nsISMILAnimVal.h" +#include "nsISMILAnimAttr.h" +#endif // MOZ_SMIL //////////////////////////////////////////////////////////////////////// @@ -49,6 +53,9 @@ class nsSVGAnimatedLength : public nsIDOMSVGAnimatedLength, public nsSVGValue, public nsISVGValueObserver, +#ifdef MOZ_SMIL + public nsISMILAnimAttr, +#endif // MOZ_SMIL public nsSupportsWeakReference { protected: @@ -74,12 +81,24 @@ modificationType aModType); NS_IMETHOD DidModifySVGObservable (nsISVGValue* observable, modificationType aModType); + +#ifdef MOZ_SMIL + // nsISMILAnimAttr + virtual nsISMILAnimVal* GetBaseValue(); + virtual nsresult SetAnimValue(nsISMILAnimVal& aValue); + virtual nsresult Create(nsISMILAnimVal** aResult) const; + virtual nsresult CreateFromSpec(const nsAString& aSpec, + nsISMILAnimVal** aResult) const; +#endif // MOZ_SMIL // nsISupportsWeakReference // implementation inherited from nsSupportsWeakReference protected: nsCOMPtr mBaseVal; +#ifdef MOZ_SMIL + nsCOMPtr mAnimVal; +#endif // MOZ_SMIL }; @@ -102,8 +121,8 @@ void nsSVGAnimatedLength::Init(nsIDOMSVGLength* baseVal) { + if (!baseVal) return; mBaseVal = baseVal; - if (!mBaseVal) return; nsCOMPtr val = do_QueryInterface(mBaseVal); NS_ASSERTION(val, "baseval needs to implement nsISVGValue interface"); if (!val) return; @@ -122,6 +141,9 @@ NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimatedLength) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_ENTRY(nsISVGValueObserver) +#ifdef MOZ_SMIL + NS_INTERFACE_MAP_ENTRY(nsISMILAnimAttr) +#endif // MOZ_SMIL NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGAnimatedLength) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISVGValue) NS_INTERFACE_MAP_END @@ -159,8 +181,22 @@ NS_IMETHODIMP nsSVGAnimatedLength::GetAnimVal(nsIDOMSVGLength * *aAnimVal) { +#ifndef MOZ_SMIL *aAnimVal = mBaseVal; NS_ADDREF(*aAnimVal); +#else + nsresult rv = NS_OK; + + if (!mAnimVal && mBaseVal) + { + nsCOMPtr length( do_QueryInterface(mBaseVal) ); + if (length) + rv = length->GetAnimValue(getter_AddRefs(mAnimVal)); + } + + NS_IF_ADDREF(*aAnimVal = mAnimVal); +#endif // MOZ_SMIL + return NS_OK; } @@ -183,6 +219,83 @@ return NS_OK; } +#ifdef MOZ_SMIL +//---------------------------------------------------------------------- +// nsISMILAnimAttr methods + +nsISMILAnimVal* +nsSVGAnimatedLength::GetBaseValue() +{ + nsISMILAnimVal *result; + nsresult rv = mBaseVal->QueryInterface(NS_GET_IID(nsISMILAnimVal), + (void**)&result); + return result; +} + +nsresult +nsSVGAnimatedLength::SetAnimValue(nsISMILAnimVal& aValue) +{ + // TODO[1]: Check for equality before assigning + WillModify(mod_other); + nsCOMPtr animLength( do_QueryInterface(mAnimVal) ); + animLength->Set(aValue); + DidModify(mod_other); + + return NS_OK; +} + +nsresult +nsSVGAnimatedLength::Create(nsISMILAnimVal** aResult) const +{ + nsISVGLength* length = nsnull; + nsISMILAnimVal* result = nsnull; + + nsresult rv = NS_NewSVGLength(&length); + + if (NS_SUCCEEDED(rv) && length) + rv = length->GetAnimVal(&result); + else + result = nsnull; + + NS_IF_RELEASE(length); + + // GetAnimVal will add ref + *aResult = result; + + return rv; +} + +nsresult +nsSVGAnimatedLength::CreateFromSpec(const nsAString& aSpec, + nsISMILAnimVal** aResult) const +{ + NS_ASSERTION(aResult, "NULL pointer provided for storing new value."); + + if (!aResult) + return NS_ERROR_NULL_POINTER; + + *aResult = nsnull; + + // TODO[2] The syntax for numbers differs between XML attributes and CSS + // properties. Does the "attributeType" property affect this? + + nsCOMPtr length; + + nsresult rv = NS_NewSVGLength(getter_AddRefs(length), aSpec); + NS_ENSURE_SUCCESS(rv,rv); + + rv = length->ConvertToSpecifiedUnits(nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER); + NS_ENSURE_SUCCESS(rv,rv); + + rv = length->GetAnimVal(aResult); + NS_ENSURE_SUCCESS(rv,rv); + + // GetAnimVal will add ref + + return rv; +} +#endif // MOZ_SMIL + //////////////////////////////////////////////////////////////////////// // Exported creation functions Index: /cvsroot/mozilla/content/svg/content/src/nsSVGAtomList.h =================================================================== RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGAtomList.h,v retrieving revision 1.24 diff -u -r1.24 nsSVGAtomList.h --- /cvsroot/mozilla/content/svg/content/src/nsSVGAtomList.h 26 Aug 2005 02:49:49 -0000 1.24 +++ /cvsroot/mozilla/content/svg/content/src/nsSVGAtomList.h 14 Sep 2005 10:44:20 -0000 @@ -55,6 +55,9 @@ ******/ // tags +#ifdef MOZ_SMIL +SVG_ATOM(animate, "animate") +#endif SVG_ATOM(circle, "circle") SVG_ATOM(clipPath, "clipPath") SVG_ATOM(defs, "defs") @@ -207,6 +210,29 @@ SVG_ATOM(y1, "y1") SVG_ATOM(y2, "y2") SVG_ATOM(zoomAndPan, "zoomAndPan") + +// SMIL properties (to be integrated with the others later) +#ifdef MOZ_SMIL +SVG_ATOM(accumulate, "accumulate") +SVG_ATOM(additive, "additive") +SVG_ATOM(attributeName, "attributeName") +SVG_ATOM(attributeType, "attributeType") +SVG_ATOM(begin, "begin") +SVG_ATOM(by, "by") +SVG_ATOM(calcMode, "calcMode") +SVG_ATOM(dur, "dur") +SVG_ATOM(end, "end") +SVG_ATOM(from, "from") +SVG_ATOM(keySplines, "keySplines") +SVG_ATOM(keyTimes, "keyTimes") +SVG_ATOM(max, "max") +SVG_ATOM(min, "min") +SVG_ATOM(repeatCount, "repeatCount") +SVG_ATOM(repeatDur, "repeatDur") +SVG_ATOM(restart, "restart") +SVG_ATOM(to, "to") +SVG_ATOM(values, "values") +#endif // transformation keywords SVG_ATOM(matrix, "matrix") Index: /cvsroot/mozilla/content/svg/content/src/nsSVGElement.cpp =================================================================== RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGElement.cpp,v retrieving revision 1.80 diff -u -r1.80 nsSVGElement.cpp --- /cvsroot/mozilla/content/svg/content/src/nsSVGElement.cpp 25 Aug 2005 21:31:07 -0000 1.80 +++ /cvsroot/mozilla/content/svg/content/src/nsSVGElement.cpp 14 Sep 2005 10:44:22 -0000 @@ -92,6 +92,9 @@ NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_ENTRY(nsISVGValueObserver) NS_INTERFACE_MAP_ENTRY(nsISVGContent) +#ifdef MOZ_SMIL + NS_INTERFACE_MAP_ENTRY(nsISMILAnimElement) +#endif // MOZ_SMIL // provided by nsGenericElement: // NS_INTERFACE_MAP_ENTRY(nsIStyledContent) // NS_INTERFACE_MAP_ENTRY(nsIContent) @@ -213,7 +216,10 @@ attrValue.SetTo(proxy); } else { - attrValue.SetTo(svg_value); + // We don't want to continue on and call SetAttrAndNotify, as + // the SVGValue has already done that for us. Returning early + // is safe as no event attributes are also SVGValues. + return NS_OK; } } else if (aName == nsSVGAtoms::style && aNamespaceID == kNameSpaceID_None) { @@ -872,3 +878,23 @@ return aAttr; } + +#ifdef MOZ_SMIL +//---------------------------------------------------------------------- +// nsISMILAnimElement methods + +// This should be overridden as necessary, e.g. to ensure some attributes are +// not animatable + +nsISMILAnimAttr* +nsSVGElement::GetAnimAttribute(PRInt32 aNamespaceID, nsIAtom* aName) +{ + nsCOMPtr result; + nsCOMPtr attr = GetMappedAttribute(aNamespaceID, aName); + + if (attr != nsnull) + result = do_QueryInterface(attr); + + return result; +} +#endif // MOZ_SMIL Index: /cvsroot/mozilla/content/svg/content/src/nsSVGElement.h =================================================================== RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGElement.h,v retrieving revision 1.47 diff -u -r1.47 nsSVGElement.h --- /cvsroot/mozilla/content/svg/content/src/nsSVGElement.h 25 Aug 2005 21:57:31 -0000 1.47 +++ /cvsroot/mozilla/content/svg/content/src/nsSVGElement.h 14 Sep 2005 10:44:22 -0000 @@ -53,10 +53,16 @@ #include "nsWeakReference.h" #include "nsISVGContent.h" #include "nsICSSStyleRule.h" +#ifdef MOZ_SMIL +#include "nsISMILAnimElement.h" +#endif // MOZ_SMIL class nsSVGElement : public nsGenericElement, // :nsIXMLContent:nsIStyledContent:nsIContent public nsISVGValueObserver, public nsSupportsWeakReference, // :nsISupportsWeakReference +#ifdef MOZ_SMIL + public nsISMILAnimElement, +#endif // MOZ_SMIL public nsISVGContent { protected: @@ -122,6 +128,12 @@ // nsISVGContent virtual void ParentChainChanged(); + +#ifdef MOZ_SMIL + // nsISVGAnimationTarget + virtual nsISMILAnimAttr* + GetAnimAttribute(PRInt32 aNamespaceID, nsIAtom* aName); +#endif // MOZ_SMIL protected: // Hooks for subclasses Index: /cvsroot/mozilla/content/svg/content/src/nsSVGElementFactory.cpp =================================================================== RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGElementFactory.cpp,v retrieving revision 1.26 diff -u -r1.26 nsSVGElementFactory.cpp --- /cvsroot/mozilla/content/svg/content/src/nsSVGElementFactory.cpp 26 Aug 2005 02:49:49 -0000 1.26 +++ /cvsroot/mozilla/content/svg/content/src/nsSVGElementFactory.cpp 14 Sep 2005 10:44:23 -0000 @@ -100,6 +100,10 @@ NS_NewSVGClipPathElement(nsIContent **aResult, nsINodeInfo *aNodeInfo); nsresult NS_NewSVGTextPathElement(nsIContent **aResult, nsINodeInfo *aNodeInfo); +#ifdef MOZ_SMIL +nsresult +NS_NewSVGAnimateElement(nsIContent **aResult, nsINodeInfo *aNodeInfo); +#endif // MOZ_SMIL static PRBool gSVGEnabled; static const char SVG_PREF_STR[] = "svg.enabled"; @@ -205,6 +209,10 @@ return NS_NewSVGClipPathElement(aResult, aNodeInfo); if (name == nsSVGAtoms::textPath) return NS_NewSVGTextPathElement(aResult, aNodeInfo); +#ifdef MOZ_SMIL + if (name == nsSVGAtoms::animate) + return NS_NewSVGAnimateElement(aResult, aNodeInfo); +#endif // MOZ_SMIL // if we don't know what to create, just create a standard xml element: return NS_NewXMLElement(aResult, aNodeInfo); Index: /cvsroot/mozilla/content/svg/content/src/nsSVGLength.cpp =================================================================== RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGLength.cpp,v retrieving revision 1.21 diff -u -r1.21 nsSVGLength.cpp --- /cvsroot/mozilla/content/svg/content/src/nsSVGLength.cpp 9 Aug 2005 13:53:00 -0000 1.21 +++ /cvsroot/mozilla/content/svg/content/src/nsSVGLength.cpp 14 Sep 2005 10:44:25 -0000 @@ -49,10 +49,18 @@ #include "nsISVGValueUtils.h" #include "nsWeakReference.h" #include "nsContentUtils.h" +#ifdef MOZ_SMIL +#include "nsISMILAnimVal.h" +#include "nsDOMError.h" +#endif // MOZ_SMIL //////////////////////////////////////////////////////////////////////// // nsSVGLength class +#ifdef MOZ_SMIL +class nsSVGLength__Anim__; +#endif // MOZ_SMIL + class nsSVGLength : public nsISVGLength, public nsSVGValue, public nsISVGValueObserver, @@ -79,6 +87,10 @@ // nsISVGLength interface: NS_IMETHOD SetContext(nsSVGCoordCtx* context); +#ifdef MOZ_SMIL + virtual nsresult GetAnimValue(nsIDOMSVGLength** aResult); + virtual nsresult GetAnimVal(nsISMILAnimVal** aResult); +#endif // MOZ_SMIL // nsISVGValue interface: NS_IMETHOD SetValueString(const nsAString& aValue); @@ -104,8 +116,59 @@ float mValueInSpecifiedUnits; PRUint16 mSpecifiedUnitType; nsRefPtr mContext; +#ifdef MOZ_SMIL + nsWeakPtr mAnimValue; +#endif // MOZ_SMIL }; +#ifdef MOZ_SMIL +class nsSVGLength__Anim__ : public nsISVGLength, + public nsSVGValue, + public nsISVGValueObserver, + public nsISMILAnimVal, + public nsSupportsWeakReference +{ +public: + nsSVGLength__Anim__(nsSVGLength& aSource); + + // nsISupports interface: + NS_DECL_ISUPPORTS + + // nsIDOMSVGLength interface: + NS_DECL_NSIDOMSVGLENGTH + + // nsISMILAnimVal interface: + virtual bool ComputeDistance(const nsISMILAnimVal& aTo, + PRFloat64& aDistance) const; + virtual nsresult Interpolate(const nsISMILAnimVal& aEndValue, + float aUnitDistance, + nsISMILAnimVal& aResult); + virtual bool Add(const nsISMILAnimVal& aAddedValue); + virtual bool Set(const nsISMILAnimVal& aNewValue); + virtual bool Repeat(PRUint32 aCount, + const nsISMILAnimVal* aRepeatValue); + + // nsISVGLength interface: + NS_IMETHOD SetContext(nsSVGCoordCtx* context); + virtual nsresult GetAnimValue(nsIDOMSVGLength** aResult); + virtual nsresult GetAnimVal(nsISMILAnimVal** aResult); + + // nsISVGValue interface: + NS_IMETHOD SetValueString(const nsAString& aValue); + NS_IMETHOD GetValueString(nsAString& aValue); + + // nsISVGValueObserver interface: + NS_IMETHOD WillModifySVGObservable(nsISVGValue* observable, + modificationType aModType); + NS_IMETHOD DidModifySVGObservable (nsISVGValue* observable, + modificationType aModType); + +protected: + float mCanonicalValue; + nsRefPtr mBase; + PRPackedBool mIsAnimated:1; +}; +#endif // MOZ_SMIL //---------------------------------------------------------------------- // Implementation @@ -170,6 +233,9 @@ NS_INTERFACE_MAP_ENTRY(nsISVGLength) NS_INTERFACE_MAP_ENTRY(nsIDOMSVGLength) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) +#ifdef MOZ_SMIL + NS_INTERFACE_MAP_ENTRY_TEAROFF(nsISMILAnimVal, new nsSVGLength__Anim__(*this)) +#endif // MOZ_SMIL NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGLength) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISVGValue) NS_INTERFACE_MAP_END @@ -529,6 +595,64 @@ return NS_OK; } +#ifdef MOZ_SMIL +nsresult +nsSVGLength::GetAnimValue(nsIDOMSVGLength** aResult) +{ + nsIDOMSVGLength* result = nsnull; + nsresult rv; + + NS_ASSERTION(aResult, "Pointer for storing result is NULL."); + + if (!aResult) + return NS_ERROR_NULL_POINTER; + + if (!mAnimValue) + { + nsSVGLength__Anim__* animValue = new nsSVGLength__Anim__(*this); + if (!animValue) + { + rv = NS_ERROR_OUT_OF_MEMORY; + } + else + { + result = NS_STATIC_CAST(nsIDOMSVGLength*, animValue); + result->AddRef(); + mAnimValue = + do_GetWeakReference(NS_STATIC_CAST(nsIDOMSVGLength*, animValue)); + } + } + else + { + CallQueryReferent(mAnimValue.get(), &result); + } + + *aResult = result; + + return rv; +} + +nsresult +nsSVGLength::GetAnimVal(nsISMILAnimVal** aResult) +{ + NS_ASSERTION(aResult, "NULL parameter passed for storing result"); + + if (!aResult) + return NS_ERROR_NULL_POINTER; + + *aResult = nsnull; + + nsIDOMSVGLength* length; + nsresult rv = GetAnimValue(&length); + + if (NS_SUCCEEDED(rv) && length) + CallQueryInterface(length, aResult); + + // GetAnimValue() will addref + + return rv; +} +#endif // MOZ_SMIL //---------------------------------------------------------------------- // Implementation helpers: @@ -596,3 +720,352 @@ } } +#ifdef MOZ_SMIL +//---------------------------------------------------------------------- +// nsSVGLength__Anim__ + +nsSVGLength__Anim__::nsSVGLength__Anim__(nsSVGLength& aSource) + : mCanonicalValue(0.0f), + mBase(&aSource), + mIsAnimated(PR_FALSE) +{ +} + +//---------------------------------------------------------------------- +// nsSVGLength__Anim__::nsISupports + +NS_IMPL_ADDREF(nsSVGLength__Anim__) +NS_IMPL_RELEASE(nsSVGLength__Anim__) + +NS_INTERFACE_MAP_BEGIN(nsSVGLength__Anim__) + NS_INTERFACE_MAP_ENTRY(nsISVGValue) + NS_INTERFACE_MAP_ENTRY(nsISVGValueObserver) + NS_INTERFACE_MAP_ENTRY(nsISVGLength) + NS_INTERFACE_MAP_ENTRY(nsIDOMSVGLength) + NS_INTERFACE_MAP_ENTRY(nsISMILAnimVal) + NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) + NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGLength) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISVGValue) +NS_INTERFACE_MAP_END + +//---------------------------------------------------------------------- +// nsSVGLength__Anim__::nsIDOMSVGLength + +NS_IMETHODIMP +nsSVGLength__Anim__::GetUnitType(PRUint16 *aUnitType) +{ + return mBase->GetUnitType(aUnitType); +} + +NS_IMETHODIMP +nsSVGLength__Anim__::GetValue(float *aValue) +{ + if (mIsAnimated) + { + *aValue = mCanonicalValue; + return NS_OK; + } + else + { + return mBase->GetValue(aValue); + } +} + +NS_IMETHODIMP +nsSVGLength__Anim__::SetValue(float aValue) +{ + if (mIsAnimated) + { + return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; + } + else + { + WillModify(); + return mBase->SetValue(aValue); + DidModify(); + } +} + +NS_IMETHODIMP +nsSVGLength__Anim__::GetValueInSpecifiedUnits(float *aValueInSpecifiedUnits) +{ + if (mIsAnimated) + return NS_ERROR_NOT_IMPLEMENTED; // TODO + else + return mBase->GetValueInSpecifiedUnits(aValueInSpecifiedUnits); +} + +NS_IMETHODIMP +nsSVGLength__Anim__::SetValueInSpecifiedUnits(float aValueInSpecifiedUnits) +{ + if (mIsAnimated) + { + return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; + } + else + { + WillModify(); + return mBase->SetValueInSpecifiedUnits(aValueInSpecifiedUnits); + DidModify(); + } +} + +NS_IMETHODIMP +nsSVGLength__Anim__::GetValueAsString(nsAString & aValueAsString) +{ + if (mIsAnimated) + return NS_ERROR_NOT_IMPLEMENTED; // TODO + else + return mBase->GetValueAsString(aValueAsString); +} + +NS_IMETHODIMP +nsSVGLength__Anim__::SetValueAsString(const nsAString & aValueAsString) +{ + if (mIsAnimated) + { + return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; + } + else + { + WillModify(); + return mBase->SetValueAsString(aValueAsString); + DidModify(); + } +} + +NS_IMETHODIMP +nsSVGLength__Anim__::NewValueSpecifiedUnits(PRUint16 unitType, float valueInSpecifiedUnits) +{ + if (mIsAnimated) + { + return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; + } + else + { + WillModify(); + return mBase->NewValueSpecifiedUnits(unitType, valueInSpecifiedUnits); + DidModify(); + } +} + +NS_IMETHODIMP +nsSVGLength__Anim__::ConvertToSpecifiedUnits(PRUint16 unitType) +{ + if (mIsAnimated) + { + return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; + } + else + { + WillModify(); + return mBase->ConvertToSpecifiedUnits(unitType); + DidModify(); + } +} + +NS_IMETHODIMP +nsSVGLength__Anim__::GetTransformedValue(nsIDOMSVGMatrix *matrix, + float *_retval) +{ + if (mIsAnimated) + return NS_ERROR_NOT_IMPLEMENTED; // TODO + else + return mBase->GetTransformedValue(matrix, _retval); +} + +//---------------------------------------------------------------------- +// nsSVGLength__Anim__::nsISMILAnimVal + +bool +nsSVGLength__Anim__::ComputeDistance(const nsISMILAnimVal& aTo, + PRFloat64& aDistance) const +{ + // XXX + aDistance = 0.0; + return false; +} + +nsresult +nsSVGLength__Anim__::Interpolate(const nsISMILAnimVal& aEndValue, + float aUnitDistance, + nsISMILAnimVal& aResult) +{ + /* + * We wouldn't have to cast away const-ness if GetValue was a const member. + */ + nsSVGLength__Anim__* end = (nsSVGLength__Anim__*)&aEndValue; + if (!end) + return NS_ERROR_FAILURE; + + nsSVGLength__Anim__* length = NS_STATIC_CAST(nsSVGLength__Anim__*, &aResult); + if (!length) + return NS_ERROR_FAILURE; + + nsresult rv = NS_OK; + + float startVal; + rv = GetValue(&startVal); + NS_ENSURE_SUCCESS(rv,rv); + + float endVal; + rv = end->GetValue(&endVal); + NS_ENSURE_SUCCESS(rv,rv); + + length->mCanonicalValue = + (startVal + (endVal - startVal) * aUnitDistance); + length->mIsAnimated = PR_TRUE; + + return NS_OK; +} + +bool +nsSVGLength__Anim__::Add(const nsISMILAnimVal& aAddedValue) +{ + /* + * We wouldn't have to cast away const-ness if GetValue was a const member. + */ + nsSVGLength__Anim__* add = (nsSVGLength__Anim__*)&aAddedValue; + + if (!add) + return false; + + float value; + add->GetValue(&value); + + WillModify(); + mCanonicalValue += value; + mIsAnimated = PR_TRUE; + DidModify(); + + return true; +} + +bool +nsSVGLength__Anim__::Repeat(PRUint32 aCount, + const nsISMILAnimVal* aRepeatValue) +{ + float value = mCanonicalValue; + + if (aRepeatValue) + { + /* + * We wouldn't have to cast away const-ness if GetValue was a const member. + */ + nsSVGLength__Anim__* repeat = (nsSVGLength__Anim__*)&aRepeatValue; + if (!repeat) + return false; + repeat->GetValue(&value); + } + + WillModify(); + mCanonicalValue = value * aCount; + mIsAnimated = PR_TRUE; + DidModify(); + + return true; +} + +bool +nsSVGLength__Anim__::Set(const nsISMILAnimVal& aNewValue) +{ + nsSVGLength__Anim__* length = (nsSVGLength__Anim__*)&aNewValue; + + if (!length) + return false; + + WillModify(); + length->GetValue(&mCanonicalValue); + mIsAnimated = PR_TRUE; + DidModify(); + return true; +} + +//---------------------------------------------------------------------- +// nsSVGLength__Anim__::nsISVGLength + +NS_IMETHODIMP +nsSVGLength__Anim__::SetContext(nsSVGCoordCtx* context) +{ + WillModify(); + nsresult rv = mBase->SetContext(context); + DidModify(); + return rv; + // TODO[2]: Update stuff +} + +nsresult +nsSVGLength__Anim__::GetAnimValue(nsIDOMSVGLength** aResult) +{ + if (aResult) + { + NS_ADDREF(*aResult = this); + return NS_OK; + } + else + { + return NS_ERROR_NULL_POINTER; + } +} + +nsresult +nsSVGLength__Anim__::GetAnimVal(nsISMILAnimVal** aResult) +{ + if (aResult) + { + NS_ADDREF(*aResult = this); + return NS_OK; + } + else + { + return NS_ERROR_NULL_POINTER; + } +} + +//---------------------------------------------------------------------- +// nsSVGLength__Anim__::nsISVGValue + +NS_IMETHODIMP +nsSVGLength__Anim__::SetValueString(const nsAString& aValue) +{ + if (mIsAnimated) + { + return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; + } + else + { + WillModify(); + return mBase->SetValueString(aValue); + DidModify(); + } +} + +NS_IMETHODIMP +nsSVGLength__Anim__::GetValueString(nsAString& aValue) +{ + if (mIsAnimated) + return NS_ERROR_NOT_IMPLEMENTED; // TODO + else + return mBase->GetValueString(aValue); +} + +//---------------------------------------------------------------------- +// nsSVGLength__Anim__::nsISVGValueObserver + +NS_IMETHODIMP +nsSVGLength__Anim__::WillModifySVGObservable(nsISVGValue* observable, + modificationType aModType) +{ + WillModify(aModType); + return NS_OK; +} + +NS_IMETHODIMP +nsSVGLength__Anim__::DidModifySVGObservable(nsISVGValue* observable, + modificationType aModType) +{ + DidModify(aModType); + return NS_OK; +} +#endif // MOZ_SMIL + Index: /cvsroot/mozilla/content/svg/content/src/nsSVGSVGElement.cpp =================================================================== RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGSVGElement.cpp,v retrieving revision 1.53 diff -u -r1.53 nsSVGSVGElement.cpp --- /cvsroot/mozilla/content/svg/content/src/nsSVGSVGElement.cpp 25 Aug 2005 21:31:07 -0000 1.53 +++ /cvsroot/mozilla/content/svg/content/src/nsSVGSVGElement.cpp 14 Sep 2005 10:44:28 -0000 @@ -69,6 +69,10 @@ #include "nsSVGEnum.h" #include "nsISVGChildFrame.h" #include "nsGUIEvent.h" +#ifdef MOZ_SMIL +#include "nsISMILAnimationController.h" +#include "nsISMILAnimationRegistry.h" +#endif // MOZ_SMIL typedef nsSVGStylableElement nsSVGSVGElementBase; @@ -110,6 +114,9 @@ NS_IMETHOD_(float) GetPreviousTranslate_x(); NS_IMETHOD_(float) GetPreviousTranslate_y(); NS_IMETHOD_(float) GetPreviousScale(); +#ifdef MOZ_SMIL + NS_IMETHOD_(nsISMILAnimationRegistry*) GetAnimationRegistry(); +#endif // MOZ_SMIL // nsIStyledContent interface NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const; @@ -123,9 +130,20 @@ protected: // nsSVGElement overrides PRBool IsEventName(nsIAtom* aName); +#ifdef MOZ_SMIL + virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, + nsIContent* aBindingParent, + PRBool aCompileEventHandlers); + virtual void UnbindFromTree(PRBool aDeep = PR_TRUE, + PRBool aNullParent = PR_TRUE); +#endif // MOZ_SMIL // implementation helpers: void GetScreenPosition(PRInt32 &x, PRInt32 &y); +#ifdef MOZ_SMIL + nsISMILAnimationController* GetAnimationController(nsIDocument* aDocument, + PRBool aCreate = PR_FALSE); +#endif // MOZ_SMIL nsCOMPtr mWidth; nsCOMPtr mHeight; @@ -146,6 +164,11 @@ float mPreviousScale; PRBool mZooming; +#ifdef MOZ_SMIL + // animation + nsCOMPtr mAnimationRegistry; +#endif // MOZ_SMIL + PRInt32 mRedrawSuspendCount; }; @@ -1344,6 +1367,34 @@ return mPreviousScale; } +#ifdef MOZ_SMIL +nsISMILAnimationRegistry* +nsSVGSVGElement::GetAnimationRegistry() +{ + nsISMILAnimationRegistry* result = nsnull; + + if (mAnimationRegistry) + { + result = mAnimationRegistry; + } + else + { + // We must not be the outermost SVG element, try to find it + nsCOMPtr outerSVGDOM; + + nsresult rv = GetOwnerSVGElement(getter_AddRefs(outerSVGDOM)); + + if (NS_SUCCEEDED(rv) && outerSVGDOM) + { + nsCOMPtr outerSVG( do_QueryInterface(outerSVGDOM) ); + result = outerSVG->GetAnimationRegistry(); + } + } + + return result; +} +#endif // MOZ_SMIL + //---------------------------------------------------------------------- // nsIStyledContent methods @@ -1480,6 +1531,60 @@ aName == nsSVGAtoms::onzoom; } +#ifdef MOZ_SMIL +nsresult +nsSVGSVGElement::BindToTree(nsIDocument* aDocument, + nsIContent* aParent, + nsIContent* aBindingParent, + PRBool aCompileEventHandlers) +{ + nsCOMPtr outerSVG; + + GetOwnerSVGElement(getter_AddRefs(outerSVG)); + + PRBool outermost = (outerSVG == nsnull); + + nsCOMPtr smilController = + GetAnimationController(aDocument, PR_TRUE); + NS_ASSERTION(smilController, "Couldn't get animation controller"); + + if (!mAnimationRegistry && outermost) + { + // We are now the outermost SVG element + mAnimationRegistry = NS_NewSMILAnimationRegistry(); + NS_ENSURE_TRUE(mAnimationRegistry, NS_ERROR_FAILURE); + } + else if (mAnimationRegistry && !outermost) + { + mAnimationRegistry = nsnull; + } + + nsresult rv = nsSVGSVGElementBase::BindToTree(aDocument, aParent, + aBindingParent, + aCompileEventHandlers); + NS_ENSURE_SUCCESS(rv,rv); + + // Eventually this will be done at the same time as the SVGLoad event but + // given that we don't currently support externalResourcesRequired, + // starting up the animation at this time is roughly the same + if (mAnimationRegistry && smilController) + rv = mAnimationRegistry->SetController(smilController); + + return rv; +} + +void +nsSVGSVGElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent) +{ + if (mAnimationRegistry) + { + mAnimationRegistry->SetController(nsnull); + } + + nsSVGSVGElementBase::UnbindFromTree(aDeep, aNullParent); +} +#endif // MOZ_SMIL + //---------------------------------------------------------------------- // implementation helpers void nsSVGSVGElement::GetScreenPosition(PRInt32 &x, PRInt32 &y) @@ -1508,3 +1613,39 @@ y = rect.y; } } + +#ifdef MOZ_SMIL +nsISMILAnimationController* +nsSVGSVGElement::GetAnimationController(nsIDocument* aDocument, + PRBool aCreate /* = PR_FALSE */) +{ + nsISMILAnimationController* result = nsnull; + + nsIPresShell* presShell; + nsPresContext* context; + + if ((aDocument) + && + (presShell = aDocument->GetShellAt(0)) + && + (context = presShell->GetPresContext())) + { + nsIAnimationController* controller = context->GetAnimationController(); + if (controller) + { + nsresult rv = CallQueryInterface(controller, &result); + + if (NS_FAILED(rv)) + result = nsnull; + } + else if (aCreate) + { + result = NS_NewSMILAnimationController(); + context->SetAnimationController(result); + } + } + + return result; +} +#endif // MOZ_SMIL + Index: /cvsroot/mozilla/content/Makefile.in =================================================================== RCS file: /cvsroot/mozilla/content/Makefile.in,v retrieving revision 1.10 diff -u -r1.10 Makefile.in --- /cvsroot/mozilla/content/Makefile.in 18 Apr 2005 06:33:19 -0000 1.10 +++ /cvsroot/mozilla/content/Makefile.in 14 Sep 2005 10:44:31 -0000 @@ -53,6 +53,10 @@ DIRS += xtf endif +ifdef MOZ_SMIL +DIRS += smil +endif + DIRS += events include $(topsrcdir)/config/rules.mk Index: /cvsroot/mozilla/dom/public/nsIDOMClassInfo.h =================================================================== RCS file: /cvsroot/mozilla/dom/public/nsIDOMClassInfo.h,v retrieving revision 1.69 diff -u -r1.69 nsIDOMClassInfo.h --- /cvsroot/mozilla/dom/public/nsIDOMClassInfo.h 26 Aug 2005 02:49:49 -0000 1.69 +++ /cvsroot/mozilla/dom/public/nsIDOMClassInfo.h 14 Sep 2005 10:44:34 -0000 @@ -248,6 +248,10 @@ eDOMClassInfo_SVGDocument_id, // SVG element classes +#ifdef MOZ_SMIL + eDOMClassInfo_SVGAnimateElement_id, + eDOMClassInfo_SVGAnimationElement_id, +#endif // MOZ_SMIL eDOMClassInfo_SVGCircleElement_id, eDOMClassInfo_SVGClipPathElement_id, eDOMClassInfo_SVGDefsElement_id, Index: /cvsroot/mozilla/dom/public/idl/svg/Makefile.in =================================================================== RCS file: /cvsroot/mozilla/dom/public/idl/svg/Makefile.in,v retrieving revision 1.20 diff -u -r1.20 Makefile.in --- /cvsroot/mozilla/dom/public/idl/svg/Makefile.in 26 Aug 2005 02:49:50 -0000 1.20 +++ /cvsroot/mozilla/dom/public/idl/svg/Makefile.in 14 Sep 2005 10:44:35 -0000 @@ -117,4 +117,10 @@ nsIDOMSVGZoomEvent.idl \ $(NULL) +ifdef MOZ_SMIL +XPIDLSRCS += nsIDOMSVGAnimateElement.idl \ + nsIDOMSVGAnimationElement.idl \ + $(NULL) +endif + include $(topsrcdir)/config/rules.mk Index: /cvsroot/mozilla/dom/public/idl/svg/nsIDOMSVGAnimateElement.idl =================================================================== RCS file: /cvsroot/mozilla/dom/public/idl/svg/nsIDOMSVGAnimateElement.idl diff -N dom/public/idl/svg/nsIDOMSVGAnimateElement.idl --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/dom/public/idl/svg/nsIDOMSVGAnimateElement.idl 14 Sep 2005 10:44:35 -0000 @@ -0,0 +1,43 @@ +/* -*- Mode: IDL; 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 SVG project. + * + * The Initial Developer of the Original Code is + * Crocodile Clips Ltd.. + * Portions created by the Initial Developer are Copyright (C) 2001 + * 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 "nsIDOMSVGAnimationElement.idl" + +[scriptable, uuid(0c4297e8-68d0-471d-a933-64132ccc5b97)] +interface nsIDOMSVGAnimateElement : nsIDOMSVGAnimationElement {}; + Index: /cvsroot/mozilla/dom/public/idl/svg/nsIDOMSVGAnimationElement.idl =================================================================== RCS file: /cvsroot/mozilla/dom/public/idl/svg/nsIDOMSVGAnimationElement.idl diff -N dom/public/idl/svg/nsIDOMSVGAnimationElement.idl --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/dom/public/idl/svg/nsIDOMSVGAnimationElement.idl 14 Sep 2005 10:44:36 -0000 @@ -0,0 +1,63 @@ +/* -*- Mode: IDL; 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 SVG project. + * + * The Initial Developer of the Original Code is + * Crocodile Clips Ltd.. + * Portions created by the Initial Developer are Copyright (C) 2001 + * 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 "nsIDOMSVGElement.idl" + +[scriptable, uuid(8f2ccf31-5544-4a9d-8927-ef35d242039e)] +interface nsIDOMSVGAnimationElement + : nsIDOMSVGElement +/* + The SVG DOM makes use of multiple interface inheritance. + Since XPCOM only supports single interface inheritance, + the best thing that we can do is to promise that whenever + an object implements _this_ interface it will also + implement the following interfaces. (We then have to QI to + hop between them.) + + nsIDOMSVGTests, + nsIDOMSVGExternalResourcesRequired, + smil::ElementTimeControl, + events::nsIDOMEventTarget +*/ +{ + readonly attribute nsIDOMSVGElement targetElement; + float getStartTime ( ); + float getCurrentTime ( ); + float getSimpleDuration ( ); + // raises (nsIDOMDOMException) +}; Index: /cvsroot/mozilla/dom/src/base/nsDOMClassInfo.cpp =================================================================== RCS file: /cvsroot/mozilla/dom/src/base/nsDOMClassInfo.cpp,v retrieving revision 1.307 diff -u -r1.307 nsDOMClassInfo.cpp --- /cvsroot/mozilla/dom/src/base/nsDOMClassInfo.cpp 1 Sep 2005 23:02:54 -0000 1.307 +++ /cvsroot/mozilla/dom/src/base/nsDOMClassInfo.cpp 14 Sep 2005 10:44:57 -0000 @@ -328,6 +328,10 @@ #include "nsIDOMSVGAnimPresAspRatio.h" #include "nsIDOMSVGAnimatedRect.h" #include "nsIDOMSVGAnimatedString.h" +#ifdef MOZ_SMIL +#include "nsIDOMSVGAnimateElement.h" +#include "nsIDOMSVGAnimationElement.h" +#endif // MOZ_SMIL #include "nsIDOMSVGAnimTransformList.h" #include "nsIDOMSVGCircleElement.h" #include "nsIDOMSVGClipPathElement.h" @@ -854,6 +858,12 @@ DOCUMENT_SCRIPTABLE_FLAGS) // SVG element classes +#ifdef MOZ_SMIL + NS_DEFINE_CLASSINFO_DATA(SVGAnimateElement, nsElementSH, + ELEMENT_SCRIPTABLE_FLAGS) + NS_DEFINE_CLASSINFO_DATA(SVGAnimationElement, nsElementSH, + ELEMENT_SCRIPTABLE_FLAGS) +#endif // MOZ_SMIL NS_DEFINE_CLASSINFO_DATA(SVGCircleElement, nsElementSH, ELEMENT_SCRIPTABLE_FLAGS) NS_DEFINE_CLASSINFO_DATA(SVGClipPathElement, nsElementSH, @@ -2393,6 +2403,19 @@ // SVG element classes +#ifdef MOZ_SMIL + DOM_CLASSINFO_MAP_BEGIN(SVGAnimateElement, nsIDOMSVGAnimateElement) + DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimationElement) + DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimateElement) + DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES + DOM_CLASSINFO_MAP_END + + DOM_CLASSINFO_MAP_BEGIN(SVGAnimationElement, nsIDOMSVGAnimationElement) + DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimationElement) + DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES + DOM_CLASSINFO_MAP_END +#endif // MOZ_SMIL + DOM_CLASSINFO_MAP_BEGIN(SVGCircleElement, nsIDOMSVGCircleElement) DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGCircleElement) DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES Index: /cvsroot/mozilla/layout/base/Makefile.in =================================================================== RCS file: /cvsroot/mozilla/layout/base/Makefile.in,v retrieving revision 1.21 diff -u -r1.21 Makefile.in --- /cvsroot/mozilla/layout/base/Makefile.in 4 May 2005 20:22:28 -0000 1.21 +++ /cvsroot/mozilla/layout/base/Makefile.in 14 Sep 2005 10:44:59 -0000 @@ -112,6 +112,10 @@ nsStyleConsts.h \ $(NULL) +ifdef MOZ_SMIL +EXPORTS += nsIAnimationController.h +endif + CPPSRCS = \ nsBidiUtils.cpp \ nsCSSColorUtils.cpp \ Index: /cvsroot/mozilla/layout/base/nsIAnimationController.h =================================================================== RCS file: /cvsroot/mozilla/layout/base/nsIAnimationController.h diff -N layout/base/nsIAnimationController.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/layout/base/nsIAnimationController.h 14 Sep 2005 10:44:59 -0000 @@ -0,0 +1,56 @@ +/* -*- 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 SVG project. + * + * 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_IANIMATIONCONTROLLER_H__ +#define __NS_IANIMATIONCONTROLLER_H__ + +#include "nsISupports.h" + +//////////////////////////////////////////////////////////////////////// +// nsIAnimationController: Animation controller + +// {7aa203ea-e6e1-4cca-84af-a29f0eaedef5} +#define NS_IANIMATIONCONTROLLER_IID \ +{ 0x7aa203ea, 0xe6e1, 0x4cca, { 0x84, 0xaf, 0xa2, 0x9f, 0x0e, 0xae, 0xde, 0xf5 } } + +class nsIAnimationController : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_IANIMATIONCONTROLLER_IID) + + virtual nsresult Pause()=0; + virtual nsresult Resume()=0; +}; + +#endif // __NS_IANIMATIONCONTROLLER_H__ + Index: /cvsroot/mozilla/layout/base/nsPresContext.cpp =================================================================== RCS file: /cvsroot/mozilla/layout/base/nsPresContext.cpp,v retrieving revision 3.290 diff -u -r3.290 nsPresContext.cpp --- /cvsroot/mozilla/layout/base/nsPresContext.cpp 23 Aug 2005 23:52:16 -0000 3.290 +++ /cvsroot/mozilla/layout/base/nsPresContext.cpp 14 Sep 2005 10:45:02 -0000 @@ -267,6 +267,10 @@ NS_IF_RELEASE(mDeviceContext); NS_IF_RELEASE(mLookAndFeel); NS_IF_RELEASE(mLangGroup); + +#ifdef MOZ_SMIL + NS_IF_RELEASE(mAnimationController); +#endif } NS_IMPL_ISUPPORTS2(nsPresContext, nsPresContext, nsIObserver) Index: /cvsroot/mozilla/layout/base/nsPresContext.h =================================================================== RCS file: /cvsroot/mozilla/layout/base/nsPresContext.h,v retrieving revision 3.152 diff -u -r3.152 nsPresContext.h --- /cvsroot/mozilla/layout/base/nsPresContext.h 23 Aug 2005 23:52:16 -0000 3.152 +++ /cvsroot/mozilla/layout/base/nsPresContext.h 14 Sep 2005 10:45:04 -0000 @@ -56,6 +56,10 @@ #include "nsCRT.h" #include "nsIPrintSettings.h" #include "nsPropertyTable.h" +#ifdef MOZ_SMIL +#include "nsIAnimationController.h" +#endif + #ifdef IBMBIDI class nsBidiPresUtils; #endif // IBMBIDI @@ -626,6 +630,18 @@ */ const nscoord* GetBorderWidthTable() { return mBorderWidthTable; } +#ifdef MOZ_SMIL + nsIAnimationController* GetAnimationController() + { return mAnimationController; } + void SetAnimationController(nsIAnimationController* aController) + { + NS_IF_ADDREF(aController); + nsIAnimationController* temp = mAnimationController; + mAnimationController = aController; + NS_IF_RELEASE(temp); + } +#endif + protected: NS_HIDDEN_(void) SetImgAnimations(nsIContent *aParent, PRUint16 aMode); NS_HIDDEN_(void) GetDocumentColorPreferences(); @@ -669,6 +685,10 @@ nsBidiPresUtils* mBidiUtils; #endif +#ifdef MOZ_SMIL + nsIAnimationController* mAnimationController; // [STRONG] +#endif + nsCOMPtr mTheme; nsCOMPtr mLangService; nsCOMPtr mPrintSettings; Index: /cvsroot/mozilla/layout/build/Makefile.in =================================================================== RCS file: /cvsroot/mozilla/layout/build/Makefile.in,v retrieving revision 1.128 diff -u -r1.128 Makefile.in --- /cvsroot/mozilla/layout/build/Makefile.in 18 Aug 2005 12:31:30 -0000 1.128 +++ /cvsroot/mozilla/layout/build/Makefile.in 14 Sep 2005 10:45:06 -0000 @@ -188,6 +188,12 @@ endif endif +ifdef MOZ_SMIL +SHARED_LIBRARY_LIBS += \ + $(DIST)/lib/$(LIB_PREFIX)gkconsmil_s.$(LIB_SUFFIX) \ + $(NULL) +endif + EXTRA_DSO_LDOPTS = \ $(LIBS_DIR) \ $(EXTRA_DSO_LIBS) \ Index: /cvsroot/mozilla/config/autoconf.mk.in =================================================================== RCS file: /cvsroot/mozilla/config/autoconf.mk.in,v retrieving revision 3.366 diff -u -r3.366 autoconf.mk.in --- /cvsroot/mozilla/config/autoconf.mk.in 31 Aug 2005 22:15:30 -0000 3.366 +++ /cvsroot/mozilla/config/autoconf.mk.in 14 Sep 2005 10:45:08 -0000 @@ -197,6 +197,7 @@ MOZ_LIBART_CFLAGS = @MOZ_LIBART_CFLAGS@ MOZ_ENABLE_CANVAS = @MOZ_ENABLE_CANVAS@ MOZ_CAIRO_CFLAGS = @MOZ_CAIRO_CFLAGS@ +MOZ_SMIL = @MOZ_SMIL@ TX_EXE = @TX_EXE@ # Mac's don't like / in a #include, so we include the libart Index: /cvsroot/mozilla/allmakefiles.sh =================================================================== RCS file: /cvsroot/mozilla/allmakefiles.sh,v retrieving revision 1.585 diff -u -r1.585 allmakefiles.sh --- /cvsroot/mozilla/allmakefiles.sh 31 Aug 2005 22:15:27 -0000 1.585 +++ /cvsroot/mozilla/allmakefiles.sh 14 Sep 2005 10:45:43 -0000 @@ -1340,6 +1340,15 @@ " fi +# smil +if [ "$MOZ_SMIL" ]; then + MAKEFILES_content="$MAKEFILES_content + content/smil/Makefile + content/smil/public/Makefile + content/smil/src/Makefile +" +fi + # xtf if [ "$MOZ_XTF" ]; then MAKEFILES_content="$MAKEFILES_content Index: /cvsroot/mozilla/configure.in =================================================================== RCS file: /cvsroot/mozilla/configure.in,v retrieving revision 1.1524 diff -u -r1.1524 configure.in --- /cvsroot/mozilla/configure.in 2 Sep 2005 02:59:01 -0000 1.1524 +++ /cvsroot/mozilla/configure.in 14 Sep 2005 10:46:03 -0000 @@ -5020,6 +5020,17 @@ dnl fi dnl ======================================================== +dnl SMIL +dnl ======================================================== +MOZ_ARG_ENABLE_BOOL(smil, +[ --enable-smil Enable SMIL animation support], + MOZ_SMIL=1, + MOZ_SMIL= ) +if test -n "$MOZ_SMIL"; then + AC_DEFINE(MOZ_SMIL) +fi + +dnl ======================================================== dnl Transformiix dnl ======================================================== @@ -6633,6 +6644,7 @@ AC_SUBST(MOZ_SVG_RENDERER_GDIPLUS) AC_SUBST(MOZ_SVG_RENDERER_LIBART) AC_SUBST(MOZ_SVG_RENDERER_CAIRO) +AC_SUBST(MOZ_SMIL) AC_SUBST(TX_EXE) AC_SUBST(MOZ_JS_LIBS) AC_SUBST(MOZ_PSM)