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 4 Sep 2005 07:25:55 -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 4 Sep 2005 07:25:55 -0000 @@ -0,0 +1,60 @@ +# +# ***** 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 = \ + nsISMILAnimatableAttribute.h \ + nsISMILAnimatableElement.h \ + nsISMILAnimatableValue.h \ + nsISMILAnimatableValueFactory.h \ + nsISMILAnimationController.h \ + nsISMILAnimationElement.h \ + nsISMILTimeClient.h \ + nsISMILTimeContainer.h \ + nsISMILTimedElement.h \ + $(NULL) + +include $(topsrcdir)/config/rules.mk + Index: /cvsroot/mozilla/content/smil/public/nsISMILAnimatableAttribute.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/public/nsISMILAnimatableAttribute.h diff -N content/smil/public/nsISMILAnimatableAttribute.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/content/smil/public/nsISMILAnimatableAttribute.h 4 Sep 2005 07:25:55 -0000 @@ -0,0 +1,60 @@ +/* -*- 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_ISMILANIMATABLEATTRIBUTE_H__ +#define __NS_ISMILANIMATABLEATTRIBUTE_H__ + +#include "nsISupports.h" + +class nsISMILAnimatableValue; + +//////////////////////////////////////////////////////////////////////// +// nsISMILAnimatableAttribute + +// {c487920a-7d12-40ff-bf3b-c39dd4797cff} +#define NS_ISMILANIMATABLEATTRIBUTE_IID \ +{ 0xc487920a, 0x7d12, 0x40ff, { 0xbf, 0x3b, 0xc3, 0x9d, 0xd4, 0x79, 0x7c, 0xff } } + +class nsISMILAnimatableAttribute : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISMILANIMATABLEATTRIBUTE_IID) + + // TODO[2]: Try to remove this interface altogether + virtual nsISMILAnimatableValue* GetBaseValue()=0; + virtual nsISMILAnimatableValue* GetAnimValue()=0; + virtual nsresult SetAnimValue(nsISMILAnimatableValue& aValue)=0; +}; + +#endif // __NS_ISMILANIMATABLEATTRIBUTE_H__ + Index: /cvsroot/mozilla/content/smil/public/nsISMILAnimatableElement.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/public/nsISMILAnimatableElement.h diff -N content/smil/public/nsISMILAnimatableElement.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/content/smil/public/nsISMILAnimatableElement.h 4 Sep 2005 07:25:55 -0000 @@ -0,0 +1,59 @@ +/* -*- 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_ISMILANIMATABLEELEMENT__ +#define __NS_ISMILANIMATABLEELEMENT__ + +#include "nsISupports.h" +#include "nsISMILAnimatableAttribute.h" + +//////////////////////////////////////////////////////////////////////// +// nsISMILAnimatableElement: interface of elements that have attributes +// that can be animated. + +// {5DD94E10-FD8D-42FB-B054-8D29F771033A} +#define NS_ISMILANIMATABLEELEMENT_IID \ +{ 0x5dd94e10, 0xfd8d, 0x42fb, { 0xb0, 0x54, 0x8d, 0x29, 0xf7, 0x71, 0x03, 0x3a } } + +class nsISMILAnimatableElement : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISMILANIMATABLEELEMENT_IID) + + virtual nsISMILAnimatableAttribute* + GetAnimatableAttribute(PRInt32 aNamespaceID, + nsIAtom* aName)=0; +}; + +#endif // __NS_ISMILANIMATABLEELEMENT__ + Index: /cvsroot/mozilla/content/smil/public/nsISMILAnimatableValue.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/public/nsISMILAnimatableValue.h diff -N content/smil/public/nsISMILAnimatableValue.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/content/smil/public/nsISMILAnimatableValue.h 4 Sep 2005 07:25:55 -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_ISMILANIMATABLEVALUE_H__ +#define __NS_ISMILANIMATABLEVALUE_H__ + +#include "nsISupports.h" + +//////////////////////////////////////////////////////////////////////// +// nsISMILAnimatableValue + +// {01d2aae5-9de4-4e8f-a1e9-ae660ad27925} +#define NS_ISMILANIMATABLEVALUE_IID \ +{ 0x01d2aae5, 0x9de4, 0x4e8f, { 0xa1, 0xe9, 0xae, 0x66, 0x0a, 0xd2, 0x79, 0x25 } } + +class nsISMILAnimatableValue : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISMILANIMATABLEVALUE_IID) + + virtual void ComputeDistance(const nsISMILAnimatableValue& aFrom, + const nsISMILAnimatableValue& aTo, + PRFloat64& aDistance) const = 0; + + virtual nsresult Interpolate(nsISMILAnimatableValue& aEndValue, + float aUnitDistance, + nsISMILAnimatableValue* aResult) = 0; + + virtual void Accumulate(const nsISMILAnimatableValue& aAddedValue) = 0; + virtual void Set(const nsISMILAnimatableValue& aNewValue) = 0; +}; + +#endif // __NS_ISMILANIMATABLEVALUE_H__ + Index: /cvsroot/mozilla/content/smil/public/nsISMILAnimatableValueFactory.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/public/nsISMILAnimatableValueFactory.h diff -N content/smil/public/nsISMILAnimatableValueFactory.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/content/smil/public/nsISMILAnimatableValueFactory.h 4 Sep 2005 07:25:56 -0000 @@ -0,0 +1,59 @@ +/* -*- 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_ISMILANIMATABLEVALUEFACTORY_H__ +#define __NS_ISMILANIMATABLEVALUEFACTORY_H__ + +#include "nsISupports.h" + +//////////////////////////////////////////////////////////////////////// +// nsISMILAnimatableValueFactory + +// {819c6fae-1574-49fb-b593-b5b3f941d095} +#define NS_ISMILANIMATABLEVALUEFACTORY_IID \ +{ 0x819c6fae, 0x1574, 0x49fb, { 0xb5, 0x93, 0xb5, 0xb3, 0xf9, 0x41, 0xd0, 0x95 } } + +class nsISMILAnimatableValueFactory : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISMILANIMATABLEVALUEFACTORY_IID) + + virtual nsresult Create(nsISMILAnimatableValue** aResult) const = 0; + + virtual nsresult CreateFromSpec(const nsAString& aSpec, + nsISMILAnimatableValue** aResult, + PRBool& aIsAddable) const = 0; +}; + +#endif // __NS_ISMILANIMATABLEVALUEFACTORY_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 4 Sep 2005 07:25:56 -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" + +//////////////////////////////////////////////////////////////////////// +// nsISMILAnimationController: Animation controller + +#define NS_ISMILANIMATIONCONTROLLER_IID \ +{ 0xd2c81398, 0x1f30, 0x4303, { 0xbe, 0xbe, 0xc5, 0x0c, 0x01, 0xfd, 0xd8, 0x85 } } + +class nsISMILTimeContainer; + +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/nsISMILAnimationElement.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/public/nsISMILAnimationElement.h diff -N content/smil/public/nsISMILAnimationElement.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/content/smil/public/nsISMILAnimationElement.h 4 Sep 2005 07:25:56 -0000 @@ -0,0 +1,83 @@ + +/* -*- 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_ISMILANIMATIONELEMENT_H__ +#define __NS_ISMILANIMATIONELEMENT_H__ + +#include "nsISupports.h" + +class nsISMILAnimatableAttribute; + +enum nsSMILCalcMode +{ + NS_SMIL_CALCMODE_LINEAR, + NS_SMIL_CALCMODE_DISCRETE, + NS_SMIL_CALCMODE_PACED, + NS_SMIL_CALCMODE_SPLINE +}; + +// {14eb1aab-e4ba-4c77-be89-195ef975c90d} +#define NS_ISMILANIMATIONELEMENT_IID \ +{ 0x14eb1aab, 0xe4ba, 0x4c77, { 0xbe, 0x89, 0x19, 0x5e, 0xf9, 0x75, 0xc9, 0x0d } } + +class nsISMILAnimationElement : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISMILANIMATIONELEMENT_IID) + + virtual nsresult Init(nsISMILAnimatableAttribute& aAttribute)=0; + virtual PRBool IsInitialised()=0; + + // TODO[2]: Unsetters or some method for handling un-setting attributes + virtual nsresult SetFrom(const nsAString& aFrom)=0; + virtual nsresult SetTo(const nsAString& aTo)=0; + virtual nsresult SetBy(const nsAString& aBy)=0; + virtual nsresult SetValues(const nsAString& aValues)=0; + virtual nsresult SetKeyTimes(const nsAString& aKeyTimes)=0; + virtual nsresult SetKeySplines(const nsAString& aKeySplines)=0; + + virtual PRBool IsAdditive() const=0; + virtual void SetAdditive(PRBool aAdditive)=0; + + virtual PRBool IsCumulative() const=0; + virtual void SetCumulative(PRBool aCumulative)=0; + + virtual nsSMILCalcMode GetCalcMode() const=0; + virtual void SetCalcMode(nsSMILCalcMode aCalcMode)=0; +}; + +nsISMILAnimationElement* NS_NewSMILAnimationElement(); + +#endif //__NS_ISMILANIMATIONELEMENT_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 4 Sep 2005 07:25:56 -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_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; +}; + +#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 4 Sep 2005 07:25:56 -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 4 Sep 2005 07:25:57 -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 4 Sep 2005 07:25:57 -0000 @@ -0,0 +1,85 @@ +# +# ***** 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) + +EXPORTS = \ + nsSMILTimedDocumentRoot.h \ + $(NULL) + +CPPSRCS = \ + nsSMILAnimationController.cpp \ + nsSMILAnimationElement.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/nsISMILComposable.h =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsISMILComposable.h diff -N content/smil/src/nsISMILComposable.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/content/smil/src/nsISMILComposable.h 4 Sep 2005 07:25:57 -0000 @@ -0,0 +1,55 @@ +/* -*- 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" + +//////////////////////////////////////////////////////////////////////// +// nsISMILComposable + +// {4b05aa22-712e-4a9e-8452-f7c4b2e507e7} +#define NS_ISMILCOMPOSABLE_IID \ +{ 0x4b05aa22, 0x712e, 0x4a9e, { 0x84, 0x52, 0xf7, 0xc4, 0xb2, 0xe5, 0x07, 0xe7 } } + +class nsISMILComposable : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISMILCOMPOSABLE_IID) + + virtual void CalcResult()=0; +}; + +#endif // __NS_ISMILCOMPOSABLE_H__ + 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 4 Sep 2005 07:25:57 -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/nsSMILAnimationElement.cpp =================================================================== RCS file: /cvsroot/mozilla/content/smil/src/nsSMILAnimationElement.cpp diff -N content/smil/src/nsSMILAnimationElement.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /cvsroot/mozilla/content/smil/src/nsSMILAnimationElement.cpp 4 Sep 2005 07:25:58 -0000 @@ -0,0 +1,355 @@ +/* -*- 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 "nsISMILAnimationElement.h" +#include "nsISMILComposable.h" +#include "nsISMILTimeClient.h" +#include "nsSMILTimeValue.h" +#include "nsISMILAnimatableValue.h" +#include "nsISMILAnimatableAttribute.h" +#include "nsISMILAnimatableValueFactory.h" +#include "nsCOMPtr.h" + +//---------------------------------------------------------------------- +// nsSMILAnimationElement + +class nsSMILAnimationElement : public nsISMILAnimationElement, + public nsISMILComposable, + public nsISMILTimeClient +{ +public: + nsSMILAnimationElement(); + + NS_DECL_ISUPPORTS + + // nsISMILAnimationElement + virtual nsresult Init(nsISMILAnimatableAttribute& aAttribute); + virtual PRBool IsInitialised(); + + virtual nsresult SetFrom(const nsAString& aFrom); + virtual nsresult SetTo(const nsAString& aTo); + virtual nsresult SetBy(const nsAString& aBy); + virtual nsresult SetValues(const nsAString& aValues); + virtual nsresult SetKeyTimes(const nsAString& aKeyTimes); + virtual nsresult SetKeySplines(const nsAString& aKeySplines); + + virtual PRBool IsAdditive() const; + virtual void SetAdditive(PRBool aAdditive); + + virtual PRBool IsCumulative() const; + virtual void SetCumulative(PRBool aCumulative); + + virtual nsSMILCalcMode GetCalcMode() const; + virtual void SetCalcMode(nsSMILCalcMode aCalcMode); + + // nsISMILTimeClient methods + virtual void SampleAt(const PRInt64& aSimpleTime, + const nsSMILTimeValue& aSimpleDuration, + const PRUint32& aRepeatIteration); + + // nsISMILComposable methods + virtual void CalcResult(); + +protected: + nsISMILAnimationElement* NS_NewSMILAnimationElement(); + + PRBool mIsAdditive; + PRBool mIsCumulative; + nsSMILCalcMode mCalcMode; + PRBool mIsInitialised; + + // TODO[1]: Remove this--it belongs in the compositor I think + nsCOMPtr mAttribute; + + // TODO[1]: Replace with an array + nsCOMPtr mFrom; + nsCOMPtr mTo; + + nsCOMPtr mAnimValue; + + // TODO[2]: Key times, key splines +}; + +//---------------------------------------------------------------------- +// Constructors etc. + +nsSMILAnimationElement::nsSMILAnimationElement() + : mIsAdditive(PR_TRUE), + mIsCumulative(PR_FALSE), + mCalcMode(NS_SMIL_CALCMODE_LINEAR), + mIsInitialised(PR_FALSE) +{ +} + +nsISMILAnimationElement* +NS_NewSMILAnimationElement() +{ + return new nsSMILAnimationElement(); +} + +//---------------------------------------------------------------------- +// nsISupports methods: + +NS_IMPL_ISUPPORTS3(nsSMILAnimationElement, + nsISMILAnimationElement, + nsISMILComposable, + nsISMILTimeClient); + +//---------------------------------------------------------------------- +// nsISMILAnimationElement methods: + +nsresult +nsSMILAnimationElement::Init(nsISMILAnimatableAttribute& aAttribute) +{ + mAttribute = &aAttribute; + mIsInitialised = PR_TRUE; + return NS_OK; +} + +PRBool +nsSMILAnimationElement::IsInitialised() +{ + return mIsInitialised; +} + +PRBool +nsSMILAnimationElement::IsAdditive() const +{ + return mIsAdditive; +} + +void +nsSMILAnimationElement::SetAdditive(PRBool aAdditive) +{ + // TODO[2] + mIsAdditive = aAdditive; +} + +PRBool +nsSMILAnimationElement::IsCumulative() const +{ + return mIsCumulative; +} + +void +nsSMILAnimationElement::SetCumulative(PRBool aCumulative) +{ + // TODO[2] + mIsCumulative = aCumulative; +} + +nsSMILCalcMode +nsSMILAnimationElement::GetCalcMode() const +{ + return mCalcMode; +} + +void +nsSMILAnimationElement::SetCalcMode(nsSMILCalcMode aCalcMode) +{ + // TODO[2] + mCalcMode = aCalcMode; +} + +nsresult +nsSMILAnimationElement::SetFrom(const nsAString& aFrom) +{ + NS_ASSERTION(mAttribute, "Animation element not initialised."); + + if (!mAttribute || !mIsInitialised) + return NS_ERROR_FAILURE; + + PRBool isAdditive; + nsresult rv; + nsCOMPtr factory( + do_QueryInterface(mAttribute) ); + + if (!factory) + return NS_ERROR_FAILURE; + + rv = factory->CreateFromSpec(aFrom, getter_AddRefs(mFrom), isAdditive); + + if (NS_SUCCEEDED(rv)) + mIsAdditive &= isAdditive; + + return rv; +} + +nsresult +nsSMILAnimationElement::SetTo(const nsAString& aTo) +{ + NS_ASSERTION(mAttribute, "Animation element not initialised."); + + if (!mAttribute || !mIsInitialised) + return NS_ERROR_FAILURE; + + PRBool isAdditive; + nsresult rv; + nsCOMPtr factory( + do_QueryInterface(mAttribute) ); + + if (!factory) + return NS_ERROR_FAILURE; + + rv = factory->CreateFromSpec(aTo, getter_AddRefs(mTo), isAdditive); + + if (NS_SUCCEEDED(rv)) + mIsAdditive &= isAdditive; + + return NS_OK; +} + +nsresult +nsSMILAnimationElement::SetBy(const nsAString& aBy) +{ + // TODO[1] + return NS_ERROR_NOT_IMPLEMENTED; +} + +nsresult +nsSMILAnimationElement::SetValues(const nsAString& aValues) +{ + // TODO[1] + return NS_ERROR_NOT_IMPLEMENTED; +} + +nsresult +nsSMILAnimationElement::SetKeyTimes(const nsAString& aKeyTimes) +{ + // TODO[2] + return NS_ERROR_NOT_IMPLEMENTED; +} + +nsresult +nsSMILAnimationElement::SetKeySplines(const nsAString& aKeySplines) +{ + // TODO[2] + return NS_ERROR_NOT_IMPLEMENTED; +} + + +//---------------------------------------------------------------------- +// nsISMILTimeClient methods + +void +nsSMILAnimationElement::SampleAt(const PRInt64& aSimpleTime, + const nsSMILTimeValue& aSimpleDuration, + const PRUint32& aRepeatIteration) +{ + // TODO[1]: Remove once we implement more advanced from/to/by syntax but make + // sure we check these things before using them. + NS_ASSERTION(mFrom, "From not set"); + NS_ASSERTION(mTo, "To not set"); + + // TODO[1]: Remove this check once we no longer set the attribute here + NS_ASSERTION(mAttribute, "Attribute not set"); + NS_ASSERTION(mIsInitialised, "Trying to sample un-initialised animation"); + + // TODO[3]: All this checking might need to be removed (except in the debug + // build) to improve performance as this method will be called very frequently + if (!mAttribute || !mIsInitialised) + return; + + nsresult rv; + + // Create anim value if it doesn't already exist + if (!mAnimValue) + { + nsCOMPtr factory( + do_QueryInterface(mAttribute) ); + if (factory) + factory->Create(getter_AddRefs(mAnimValue)); + if (!factory || !mAnimValue) + return; + } + + if (!aSimpleDuration.IsResolved() && !aSimpleDuration.IsIndefinite()) + { + // TODO[3]: Generate an error! + return; + } + + // TODO[1]: This is not right (except from from-to animation) but we need test + // cases to cover this behaviour + if (aSimpleDuration.IsIndefinite()) + { + mFrom->Interpolate(*mFrom, 0.0f, mAnimValue); + } + else + { + const PRInt64 &dur = aSimpleDuration.GetMillis(); + double unitDistance; + + if (LL_CMP(aSimpleTime, >, dur)) + { + // TODO[1]: Remove this one! (Replace with proper filling + repeating) + unitDistance = 1.0; + } + else if (!LL_GE_ZERO(aSimpleTime)) + { + NS_ASSERTION(PR_TRUE, "Animation sampled with negative simple time"); + unitDistance = 0.0; + } + else + { + double fTime; + double fDur; + + LL_L2D(fTime, aSimpleTime); + LL_L2D(fDur, dur); + + unitDistance = fTime / fDur; + } + + rv = mFrom->Interpolate(*mTo, + NS_STATIC_CAST(float, unitDistance), + mAnimValue); + NS_ENSURE_SUCCESS(rv,); + } + + // 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. + rv = mAttribute->SetAnimValue(*mAnimValue); + + NS_ENSURE_SUCCESS(rv,); +} + +//---------------------------------------------------------------------- +// nsISMILComposable methods + +void +nsSMILAnimationElement::CalcResult() +{ + // TODO[1] +} + 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 4 Sep 2005 07:25:58 -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 4 Sep 2005 07:25:58 -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 4 Sep 2005 07:25: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 ***** */ + +#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 4 Sep 2005 07:25:59 -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 4 Sep 2005 07:25:59 -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 4 Sep 2005 07:25:59 -0000 @@ -0,0 +1,116 @@ +/* -*- 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 4 Sep 2005 07:26:00 -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 4 Sep 2005 07:26:00 -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 4 Sep 2005 07:26:01 -0000 @@ -0,0 +1,155 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla 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() +: + mStartTime(), + mAccumulatedOffset() +{ +} + +//---------------------------------------------------------------------- +// 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 is 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); + + SampleChildren(instant); +} + +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 4 Sep 2005 07:26:01 -0000 @@ -0,0 +1,77 @@ +/* -*- 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 (original author) + * + * 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_ISMILTIMEDDOCUMENTROOT_H__ +#define __NS_ISMILTIMEDDOCUMENTROOT_H__ + +#include "nsISupports.h" +#include "nsISMILTimeContainer.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(); + + 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; +}; + +#endif // __NS_ISMILTIMEDDOCUMENTROOT_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 4 Sep 2005 07:26:03 -0000 @@ -0,0 +1,912 @@ +/* -*- 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) + { + // TODO[3]: Fire begin event, update dependents + mElementState = NS_SMIL_STATE_ACTIVE; + stateChanged = true; + } + } + break; + + case NS_SMIL_STATE_ACTIVE: + { + if (mCurrentInterval.End().CompareTo(docTime) < 1) + { + // TODO[3]: Fire end event, update dependents + mElementState = + (NS_SUCCEEDED(GetNextInterval(mCurrentInterval.End(), + false, + mCurrentInterval))) + ? NS_SMIL_STATE_WAITING + : NS_SMIL_STATE_POST_ACTIVE; + 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 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_ASSERTION(0, "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 = aAct