Bug 468996. Implement SMIL animateTransform element. r+sr=roc
|
@ -67,6 +67,7 @@ class nsSMILValue;
|
||||||
// | | | | |
|
// | | | | |
|
||||||
// | -- Assign? | X | X | X |
|
// | -- Assign? | X | X | X |
|
||||||
// | -- Add? | - | X? | X |
|
// | -- Add? | - | X? | X |
|
||||||
|
// | -- SandwichAdd? | - | -? | X |
|
||||||
// | -- ComputeDistance? | - | - | X? |
|
// | -- ComputeDistance? | - | - | X? |
|
||||||
// | -- Interpolate? | - | X | X |
|
// | -- Interpolate? | - | X | X |
|
||||||
// +---------------------+---------------+-------------+------------------+
|
// +---------------------+---------------+-------------+------------------+
|
||||||
|
@ -144,6 +145,30 @@ public:
|
||||||
const nsSMILValue& aValueToAdd,
|
const nsSMILValue& aValueToAdd,
|
||||||
PRUint32 aCount) const = 0;
|
PRUint32 aCount) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds aValueToAdd to the underlying value in the animation sandwich, aDest.
|
||||||
|
*
|
||||||
|
* For most types this operation is identical to a regular Add() but for some
|
||||||
|
* types (notably <animateTransform>) the operation differs. For
|
||||||
|
* <animateTransform> Add() corresponds to simply adding together the
|
||||||
|
* transform parameters and is used when calculating cumulative values or
|
||||||
|
* by-animation values. On the other hand SandwichAdd() is used when adding to
|
||||||
|
* the underlying value and requires matrix post-multiplication. (This
|
||||||
|
* distinction is most clearly indicated by the SVGT1.2 test suite. It is not
|
||||||
|
* obvious within the SMIL specifications.)
|
||||||
|
*
|
||||||
|
* @param aDest The value to add to.
|
||||||
|
* @param aValueToAdd The value to add.
|
||||||
|
* @return NS_OK on success, an error code on failure.
|
||||||
|
*
|
||||||
|
* @pre aValueToAdd.mType == aDest.mType == this
|
||||||
|
*/
|
||||||
|
virtual nsresult SandwichAdd(nsSMILValue& aDest,
|
||||||
|
const nsSMILValue& aValueToAdd) const
|
||||||
|
{
|
||||||
|
return Add(aDest, aValueToAdd, 1);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the 'distance' between two values. This is the distance used in
|
* Calculates the 'distance' between two values. This is the distance used in
|
||||||
* paced interpolation.
|
* paced interpolation.
|
||||||
|
|
|
@ -292,8 +292,9 @@ nsSMILAnimationFunction::ComposeResult(const nsISMILAttr& aSMILAttr,
|
||||||
}
|
}
|
||||||
|
|
||||||
// If additive animation isn't required or isn't supported, set the value.
|
// If additive animation isn't required or isn't supported, set the value.
|
||||||
if (!IsAdditive() || NS_FAILED(aResult.Add(result)))
|
if (!IsAdditive() || NS_FAILED(aResult.SandwichAdd(result))) {
|
||||||
aResult = result;
|
aResult = result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PRInt8
|
PRInt8
|
||||||
|
|
|
@ -88,18 +88,32 @@ nsSMILValue::Add(const nsSMILValue& aValueToAdd, PRUint32 aCount)
|
||||||
if (aValueToAdd.IsNull()) return NS_OK;
|
if (aValueToAdd.IsNull()) return NS_OK;
|
||||||
|
|
||||||
if (aValueToAdd.mType != mType) {
|
if (aValueToAdd.mType != mType) {
|
||||||
NS_WARNING("Trying to add incompatible types.");
|
NS_ERROR("Trying to add incompatible types.");
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mType->Add(*this, aValueToAdd, aCount);
|
return mType->Add(*this, aValueToAdd, aCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsSMILValue::SandwichAdd(const nsSMILValue& aValueToAdd)
|
||||||
|
{
|
||||||
|
if (aValueToAdd.IsNull())
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
if (aValueToAdd.mType != mType) {
|
||||||
|
NS_ERROR("Trying to add incompatible types.");
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mType->SandwichAdd(*this, aValueToAdd);
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsSMILValue::ComputeDistance(const nsSMILValue& aTo, double& aDistance) const
|
nsSMILValue::ComputeDistance(const nsSMILValue& aTo, double& aDistance) const
|
||||||
{
|
{
|
||||||
if (aTo.mType != mType) {
|
if (aTo.mType != mType) {
|
||||||
NS_WARNING("Trying to calculate distance between incompatible types.");
|
NS_ERROR("Trying to calculate distance between incompatible types.");
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +126,7 @@ nsSMILValue::Interpolate(const nsSMILValue& aEndVal,
|
||||||
nsSMILValue& aResult) const
|
nsSMILValue& aResult) const
|
||||||
{
|
{
|
||||||
if (aEndVal.mType != mType) {
|
if (aEndVal.mType != mType) {
|
||||||
NS_WARNING("Trying to interpolate between incompatible types.");
|
NS_ERROR("Trying to interpolate between incompatible types.");
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult Add(const nsSMILValue& aValueToAdd, PRUint32 aCount = 1);
|
nsresult Add(const nsSMILValue& aValueToAdd, PRUint32 aCount = 1);
|
||||||
|
nsresult SandwichAdd(const nsSMILValue& aValueToAdd);
|
||||||
nsresult ComputeDistance(const nsSMILValue& aTo, double& aDistance) const;
|
nsresult ComputeDistance(const nsSMILValue& aTo, double& aDistance) const;
|
||||||
nsresult Interpolate(const nsSMILValue& aEndVal,
|
nsresult Interpolate(const nsSMILValue& aEndVal,
|
||||||
double aUnitDistance,
|
double aUnitDistance,
|
||||||
|
|
|
@ -140,8 +140,11 @@ CPPSRCS = \
|
||||||
|
|
||||||
ifdef MOZ_SMIL
|
ifdef MOZ_SMIL
|
||||||
CPPSRCS += nsSVGAnimateElement.cpp \
|
CPPSRCS += nsSVGAnimateElement.cpp \
|
||||||
|
nsSVGAnimateTransformElement.cpp \
|
||||||
nsSVGAnimationElement.cpp \
|
nsSVGAnimationElement.cpp \
|
||||||
nsSVGSetElement.cpp \
|
nsSVGSetElement.cpp \
|
||||||
|
nsSVGTransformSMILType.cpp \
|
||||||
|
nsSVGTransformSMILAttr.cpp \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
/* -*- 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.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Brian Birtles.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Brian Birtles <birtles@gmail.com>
|
||||||
|
* Chris Double <chris.double@double.co.nz>
|
||||||
|
* Daniel Holbert <dholbert@mozilla.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include "nsSVGAnimationElement.h"
|
||||||
|
#include "nsIDOMSVGAnimateTransformElement.h"
|
||||||
|
#include "nsSVGEnum.h"
|
||||||
|
#include "nsIDOMSVGTransform.h"
|
||||||
|
#include "nsIDOMSVGTransformable.h"
|
||||||
|
#include "nsSVGAnimatedTransformList.h"
|
||||||
|
#include "nsSVGTransformSMILAttr.h"
|
||||||
|
#include "nsSMILAnimationFunction.h"
|
||||||
|
|
||||||
|
typedef nsSVGAnimationElement nsSVGAnimateTransformElementBase;
|
||||||
|
|
||||||
|
class nsSVGAnimateTransformElement : public nsSVGAnimateTransformElementBase,
|
||||||
|
public nsIDOMSVGAnimateTransformElement
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
friend nsresult NS_NewSVGAnimateTransformElement(nsIContent **aResult,
|
||||||
|
nsINodeInfo *aNodeInfo);
|
||||||
|
nsSVGAnimateTransformElement(nsINodeInfo* aNodeInfo);
|
||||||
|
|
||||||
|
nsSMILAnimationFunction mAnimationFunction;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// interfaces:
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
NS_DECL_NSIDOMSVGANIMATETRANSFORMELEMENT
|
||||||
|
|
||||||
|
NS_FORWARD_NSIDOMNODE(nsSVGAnimateTransformElementBase::)
|
||||||
|
NS_FORWARD_NSIDOMELEMENT(nsSVGAnimateTransformElementBase::)
|
||||||
|
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGAnimateTransformElementBase::)
|
||||||
|
NS_FORWARD_NSIDOMSVGANIMATIONELEMENT(nsSVGAnimateTransformElementBase::)
|
||||||
|
|
||||||
|
// nsIDOMNode specializations
|
||||||
|
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||||
|
|
||||||
|
// nsGenericElement specializations
|
||||||
|
PRBool ParseAttribute(PRInt32 aNamespaceID,
|
||||||
|
nsIAtom* aAttribute,
|
||||||
|
const nsAString& aValue,
|
||||||
|
nsAttrValue& aResult);
|
||||||
|
|
||||||
|
// nsISMILAnimationElement
|
||||||
|
virtual nsSMILAnimationFunction& AnimationFunction();
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_IMPL_NS_NEW_SVG_ELEMENT(AnimateTransform)
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// nsISupports methods
|
||||||
|
|
||||||
|
NS_IMPL_ADDREF_INHERITED(nsSVGAnimateTransformElement,nsSVGAnimateTransformElementBase)
|
||||||
|
NS_IMPL_RELEASE_INHERITED(nsSVGAnimateTransformElement,nsSVGAnimateTransformElementBase)
|
||||||
|
|
||||||
|
NS_INTERFACE_TABLE_HEAD(nsSVGAnimateTransformElement)
|
||||||
|
NS_NODE_INTERFACE_TABLE5(nsSVGAnimateTransformElement, nsIDOMNode,
|
||||||
|
nsIDOMElement, nsIDOMSVGElement,
|
||||||
|
nsIDOMSVGAnimationElement,
|
||||||
|
nsIDOMSVGAnimateTransformElement)
|
||||||
|
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGAnimateElement)
|
||||||
|
NS_INTERFACE_MAP_END_INHERITING(nsSVGAnimateTransformElementBase)
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Implementation
|
||||||
|
|
||||||
|
nsSVGAnimateTransformElement::nsSVGAnimateTransformElement(nsINodeInfo *aNodeInfo)
|
||||||
|
: nsSVGAnimateTransformElementBase(aNodeInfo)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsSVGAnimateTransformElement::ParseAttribute(PRInt32 aNamespaceID,
|
||||||
|
nsIAtom* aAttribute,
|
||||||
|
const nsAString& aValue,
|
||||||
|
nsAttrValue& aResult)
|
||||||
|
{
|
||||||
|
// 'type' is an <animateTransform>-specific attribute, and we'll handle it
|
||||||
|
// specially.
|
||||||
|
if (aNamespaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::type) {
|
||||||
|
aResult.ParseAtom(aValue);
|
||||||
|
nsIAtom* atom = aResult.GetAtomValue();
|
||||||
|
if (atom != nsGkAtoms::translate &&
|
||||||
|
atom != nsGkAtoms::scale &&
|
||||||
|
atom != nsGkAtoms::rotate &&
|
||||||
|
atom != nsGkAtoms::skewX &&
|
||||||
|
atom != nsGkAtoms::skewY) {
|
||||||
|
ReportAttributeParseFailure(GetOwnerDoc(), aAttribute, aValue);
|
||||||
|
}
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nsSVGAnimateTransformElementBase::ParseAttribute(aNamespaceID,
|
||||||
|
aAttribute, aValue,
|
||||||
|
aResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// nsIDOMNode methods
|
||||||
|
|
||||||
|
NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGAnimateTransformElement)
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// nsISMILAnimationElement methods
|
||||||
|
|
||||||
|
nsSMILAnimationFunction&
|
||||||
|
nsSVGAnimateTransformElement::AnimationFunction()
|
||||||
|
{
|
||||||
|
return mAnimationFunction;
|
||||||
|
}
|
|
@ -38,62 +38,15 @@
|
||||||
|
|
||||||
#include "nsSVGAnimatedTransformList.h"
|
#include "nsSVGAnimatedTransformList.h"
|
||||||
#include "nsSVGTransformList.h"
|
#include "nsSVGTransformList.h"
|
||||||
#include "nsSVGValue.h"
|
|
||||||
#include "nsWeakReference.h"
|
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// nsSVGAnimatedTransformList
|
|
||||||
|
|
||||||
class nsSVGAnimatedTransformList : public nsIDOMSVGAnimatedTransformList,
|
|
||||||
public nsSVGValue,
|
|
||||||
public nsISVGValueObserver
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
friend nsresult
|
|
||||||
NS_NewSVGAnimatedTransformList(nsIDOMSVGAnimatedTransformList** result,
|
|
||||||
nsIDOMSVGTransformList* baseVal);
|
|
||||||
|
|
||||||
nsSVGAnimatedTransformList();
|
|
||||||
~nsSVGAnimatedTransformList();
|
|
||||||
void Init(nsIDOMSVGTransformList* baseVal);
|
|
||||||
|
|
||||||
public:
|
|
||||||
// nsISupports interface:
|
|
||||||
NS_DECL_ISUPPORTS
|
|
||||||
|
|
||||||
// nsIDOMSVGAnimatedTransformList interface:
|
|
||||||
NS_DECL_NSIDOMSVGANIMATEDTRANSFORMLIST
|
|
||||||
|
|
||||||
// remainder of nsISVGValue interface:
|
|
||||||
NS_IMETHOD SetValueString(const nsAString& aValue);
|
|
||||||
NS_IMETHOD GetValueString(nsAString& aValue);
|
|
||||||
|
|
||||||
// nsISVGValueObserver
|
|
||||||
NS_IMETHOD WillModifySVGObservable(nsISVGValue* observable,
|
|
||||||
modificationType aModType);
|
|
||||||
NS_IMETHOD DidModifySVGObservable (nsISVGValue* observable,
|
|
||||||
modificationType aModType);
|
|
||||||
|
|
||||||
// nsISupportsWeakReference
|
|
||||||
// implementation inherited from nsSupportsWeakReference
|
|
||||||
|
|
||||||
protected:
|
|
||||||
nsCOMPtr<nsIDOMSVGTransformList> mBaseVal;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// Implementation
|
// Implementation
|
||||||
|
|
||||||
nsSVGAnimatedTransformList::nsSVGAnimatedTransformList()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
nsSVGAnimatedTransformList::~nsSVGAnimatedTransformList()
|
nsSVGAnimatedTransformList::~nsSVGAnimatedTransformList()
|
||||||
{
|
{
|
||||||
if (!mBaseVal) return;
|
if (!mBaseVal) return;
|
||||||
nsCOMPtr<nsISVGValue> val = do_QueryInterface(mBaseVal);
|
nsCOMPtr<nsISVGValue> val = do_QueryInterface(mBaseVal);
|
||||||
if (!val) return;
|
if (!val) return;
|
||||||
val->RemoveObserver(this);
|
val->RemoveObserver(this);
|
||||||
}
|
}
|
||||||
|
@ -146,7 +99,7 @@ nsSVGAnimatedTransformList::GetValueString(nsAString& aValue)
|
||||||
|
|
||||||
/* readonly attribute nsIDOMSVGTransformList baseVal; */
|
/* readonly attribute nsIDOMSVGTransformList baseVal; */
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsSVGAnimatedTransformList::GetBaseVal(nsIDOMSVGTransformList * *aBaseVal)
|
nsSVGAnimatedTransformList::GetBaseVal(nsIDOMSVGTransformList** aBaseVal)
|
||||||
{
|
{
|
||||||
*aBaseVal = mBaseVal;
|
*aBaseVal = mBaseVal;
|
||||||
NS_ADDREF(*aBaseVal);
|
NS_ADDREF(*aBaseVal);
|
||||||
|
@ -155,9 +108,9 @@ nsSVGAnimatedTransformList::GetBaseVal(nsIDOMSVGTransformList * *aBaseVal)
|
||||||
|
|
||||||
/* readonly attribute nsIDOMSVGTransformList animVal; */
|
/* readonly attribute nsIDOMSVGTransformList animVal; */
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsSVGAnimatedTransformList::GetAnimVal(nsIDOMSVGTransformList * *aAnimVal)
|
nsSVGAnimatedTransformList::GetAnimVal(nsIDOMSVGTransformList** aAnimVal)
|
||||||
{
|
{
|
||||||
*aAnimVal = mBaseVal;
|
*aAnimVal = mAnimVal ? mAnimVal : mBaseVal;
|
||||||
NS_ADDREF(*aAnimVal);
|
NS_ADDREF(*aAnimVal);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,52 @@
|
||||||
|
|
||||||
#include "nsIDOMSVGAnimTransformList.h"
|
#include "nsIDOMSVGAnimTransformList.h"
|
||||||
#include "nsIDOMSVGTransformList.h"
|
#include "nsIDOMSVGTransformList.h"
|
||||||
|
#include "nsSVGValue.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
// nsSVGAnimatedTransformList
|
||||||
|
|
||||||
|
class nsSVGTransformSMILAttr;
|
||||||
|
|
||||||
|
class nsSVGAnimatedTransformList : public nsIDOMSVGAnimatedTransformList,
|
||||||
|
public nsSVGValue,
|
||||||
|
public nsISVGValueObserver
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
friend nsresult
|
||||||
|
NS_NewSVGAnimatedTransformList(nsIDOMSVGAnimatedTransformList** result,
|
||||||
|
nsIDOMSVGTransformList* baseVal);
|
||||||
|
|
||||||
|
~nsSVGAnimatedTransformList();
|
||||||
|
void Init(nsIDOMSVGTransformList* baseVal);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// nsISupports interface:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
|
// nsIDOMSVGAnimatedTransformList interface:
|
||||||
|
NS_DECL_NSIDOMSVGANIMATEDTRANSFORMLIST
|
||||||
|
|
||||||
|
// remainder of nsISVGValue interface:
|
||||||
|
NS_IMETHOD SetValueString(const nsAString& aValue);
|
||||||
|
NS_IMETHOD GetValueString(nsAString& aValue);
|
||||||
|
|
||||||
|
// nsISVGValueObserver
|
||||||
|
NS_IMETHOD WillModifySVGObservable(nsISVGValue* observable,
|
||||||
|
modificationType aModType);
|
||||||
|
NS_IMETHOD DidModifySVGObservable (nsISVGValue* observable,
|
||||||
|
modificationType aModType);
|
||||||
|
|
||||||
|
// nsISupportsWeakReference
|
||||||
|
// implementation inherited from nsSupportsWeakReference
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend class nsSVGTransformSMILAttr;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMSVGTransformList> mBaseVal;
|
||||||
|
// XXX This should be read-only, i.e. its setters should throw
|
||||||
|
nsCOMPtr<nsIDOMSVGTransformList> mAnimVal;
|
||||||
|
};
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
NS_NewSVGAnimatedTransformList(nsIDOMSVGAnimatedTransformList** result,
|
NS_NewSVGAnimatedTransformList(nsIDOMSVGAnimatedTransformList** result,
|
||||||
|
|
|
@ -91,6 +91,8 @@
|
||||||
#include "prdtoa.h"
|
#include "prdtoa.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#ifdef MOZ_SMIL
|
#ifdef MOZ_SMIL
|
||||||
|
#include "nsSVGTransformSMILAttr.h"
|
||||||
|
#include "nsSVGAnimatedTransformList.h"
|
||||||
#include "nsIDOMSVGTransformable.h"
|
#include "nsIDOMSVGTransformable.h"
|
||||||
#endif // MOZ_SMIL
|
#endif // MOZ_SMIL
|
||||||
|
|
||||||
|
@ -1650,6 +1652,22 @@ nsSVGElement::RecompileScriptEventListeners()
|
||||||
nsISMILAttr*
|
nsISMILAttr*
|
||||||
nsSVGElement::GetAnimatedAttr(const nsIAtom* aName)
|
nsSVGElement::GetAnimatedAttr(const nsIAtom* aName)
|
||||||
{
|
{
|
||||||
|
// Transforms:
|
||||||
|
if (aName == nsGkAtoms::transform) {
|
||||||
|
nsCOMPtr<nsIDOMSVGTransformable> transformable(
|
||||||
|
do_QueryInterface(static_cast<nsIContent*>(this)));
|
||||||
|
if (!transformable)
|
||||||
|
return nsnull;
|
||||||
|
nsCOMPtr<nsIDOMSVGAnimatedTransformList> transformList;
|
||||||
|
nsresult rv = transformable->GetTransform(getter_AddRefs(transformList));
|
||||||
|
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||||
|
nsSVGAnimatedTransformList* list
|
||||||
|
= static_cast<nsSVGAnimatedTransformList*>(transformList.get());
|
||||||
|
NS_ENSURE_TRUE(list, nsnull);
|
||||||
|
|
||||||
|
return new nsSVGTransformSMILAttr(list, this);
|
||||||
|
}
|
||||||
|
|
||||||
// Lengths:
|
// Lengths:
|
||||||
LengthAttributesInfo info = GetLengthInfo();
|
LengthAttributesInfo info = GetLengthInfo();
|
||||||
for (PRUint32 i = 0; i < info.mLengthCount; i++) {
|
for (PRUint32 i = 0; i < info.mLengthCount; i++) {
|
||||||
|
|
|
@ -165,6 +165,8 @@ NS_NewSVGFEDisplacementMapElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
|
||||||
nsresult
|
nsresult
|
||||||
NS_NewSVGAnimateElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
|
NS_NewSVGAnimateElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
|
||||||
nsresult
|
nsresult
|
||||||
|
NS_NewSVGAnimateTransformElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
|
||||||
|
nsresult
|
||||||
NS_NewSVGSetElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
|
NS_NewSVGSetElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
|
||||||
#endif // MOZ_SMIL
|
#endif // MOZ_SMIL
|
||||||
|
|
||||||
|
@ -299,6 +301,8 @@ NS_NewSVGElement(nsIContent** aResult, nsINodeInfo *aNodeInfo,
|
||||||
#ifdef MOZ_SMIL
|
#ifdef MOZ_SMIL
|
||||||
if (name == nsGkAtoms::animate)
|
if (name == nsGkAtoms::animate)
|
||||||
return NS_NewSVGAnimateElement(aResult, aNodeInfo);
|
return NS_NewSVGAnimateElement(aResult, aNodeInfo);
|
||||||
|
if (name == nsGkAtoms::animateTransform)
|
||||||
|
return NS_NewSVGAnimateTransformElement(aResult, aNodeInfo);
|
||||||
if (name == nsGkAtoms::set)
|
if (name == nsGkAtoms::set)
|
||||||
return NS_NewSVGSetElement(aResult, aNodeInfo);
|
return NS_NewSVGSetElement(aResult, aNodeInfo);
|
||||||
#endif // MOZ_SMIL
|
#endif // MOZ_SMIL
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
/* -*- 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.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Brian Birtles.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Brian Birtles <birtles@gmail.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#ifndef NS_SVGSMILTRANSFORM_H_
|
||||||
|
#define NS_SVGSMILTRANSFORM_H_
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
// nsSVGSMILTransform
|
||||||
|
//
|
||||||
|
// A pared-down representation of an SVG transform used in SMIL animation. We
|
||||||
|
// just store the most basic facts about the transform such that we can add the
|
||||||
|
// transform parameters together and later reconstruct a full SVG transform from
|
||||||
|
// this information.
|
||||||
|
//
|
||||||
|
// The meaning of the mParams array depends on the transform type as follows:
|
||||||
|
//
|
||||||
|
// Type | mParams[0], mParams[1], mParams[2], ...
|
||||||
|
// --------------------+-----------------------------------------
|
||||||
|
// TRANSFORM_TRANSLATE | tx, ty
|
||||||
|
// TRANSFORM_SCALE | sx, sy
|
||||||
|
// TRANSFORM_ROTATE | rotation-angle (in degrees), cx, cy
|
||||||
|
// TRANSFORM_SKEWX | skew-angle (in degrees)
|
||||||
|
// TRANSFORM_SKEWY | skew-angle (in degrees)
|
||||||
|
// TRANSFORM_MATRIX | a, b, c, d, e, f
|
||||||
|
//
|
||||||
|
// TRANSFORM_MATRIX is never generated by animation code (it is only produced
|
||||||
|
// when the user inserts one via the DOM) and often requires special handling
|
||||||
|
// when we do encounter it. Therefore many users of this class are only
|
||||||
|
// interested in the first three parameters and so we provide a special
|
||||||
|
// constructor for setting those parameters only.
|
||||||
|
class nsSVGSMILTransform
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum TransformType
|
||||||
|
{
|
||||||
|
TRANSFORM_TRANSLATE,
|
||||||
|
TRANSFORM_SCALE,
|
||||||
|
TRANSFORM_ROTATE,
|
||||||
|
TRANSFORM_SKEWX,
|
||||||
|
TRANSFORM_SKEWY,
|
||||||
|
TRANSFORM_MATRIX
|
||||||
|
};
|
||||||
|
|
||||||
|
nsSVGSMILTransform(TransformType aType)
|
||||||
|
: mTransformType(aType)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 6; ++i) {
|
||||||
|
mParams[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsSVGSMILTransform(TransformType aType, float (&aParams)[3])
|
||||||
|
: mTransformType(aType)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
mParams[i] = aParams[i];
|
||||||
|
}
|
||||||
|
for (int i = 3; i < 6; ++i) {
|
||||||
|
mParams[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsSVGSMILTransform(float (&aParams)[6])
|
||||||
|
: mTransformType(TRANSFORM_MATRIX)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 6; ++i) {
|
||||||
|
mParams[i] = aParams[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TransformType mTransformType;
|
||||||
|
|
||||||
|
float mParams[6];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NS_SVGSMILTRANSFORM_H_
|
|
@ -39,54 +39,13 @@
|
||||||
#include "nsSVGTransform.h"
|
#include "nsSVGTransform.h"
|
||||||
#include "prdtoa.h"
|
#include "prdtoa.h"
|
||||||
#include "nsSVGMatrix.h"
|
#include "nsSVGMatrix.h"
|
||||||
#include "nsSVGValue.h"
|
|
||||||
#include "nsISVGValueUtils.h"
|
#include "nsISVGValueUtils.h"
|
||||||
#include "nsISVGValueObserver.h"
|
|
||||||
#include "nsWeakReference.h"
|
#include "nsWeakReference.h"
|
||||||
#include "nsSVGMatrix.h"
|
#include "nsSVGMatrix.h"
|
||||||
#include "nsTextFormatter.h"
|
#include "nsTextFormatter.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// nsSVGTransform
|
|
||||||
|
|
||||||
class nsSVGTransform : public nsIDOMSVGTransform,
|
|
||||||
public nsSVGValue,
|
|
||||||
public nsISVGValueObserver
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static nsresult Create(nsIDOMSVGTransform** aResult);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
nsSVGTransform();
|
|
||||||
~nsSVGTransform();
|
|
||||||
nsresult Init();
|
|
||||||
public:
|
|
||||||
// nsISupports interface:
|
|
||||||
NS_DECL_ISUPPORTS
|
|
||||||
|
|
||||||
// nsIDOMSVGTransform interface:
|
|
||||||
NS_DECL_NSIDOMSVGTRANSFORM
|
|
||||||
|
|
||||||
// nsISVGValue interface:
|
|
||||||
NS_IMETHOD SetValueString(const nsAString& aValue);
|
|
||||||
NS_IMETHOD GetValueString(nsAString& aValue);
|
|
||||||
|
|
||||||
// nsISVGValueObserver
|
|
||||||
NS_IMETHOD WillModifySVGObservable(nsISVGValue* observable,
|
|
||||||
modificationType aModType);
|
|
||||||
NS_IMETHOD DidModifySVGObservable (nsISVGValue* observable,
|
|
||||||
modificationType aModType);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
nsCOMPtr<nsIDOMSVGMatrix> mMatrix;
|
|
||||||
float mAngle, mOriginX, mOriginY;
|
|
||||||
PRUint16 mType;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// Implementation
|
// Implementation
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,54 @@
|
||||||
#define __NS_SVGTRANSFORM_H__
|
#define __NS_SVGTRANSFORM_H__
|
||||||
|
|
||||||
#include "nsIDOMSVGTransform.h"
|
#include "nsIDOMSVGTransform.h"
|
||||||
|
#include "nsSVGValue.h"
|
||||||
|
#include "nsISVGValueObserver.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
// nsSVGTransform
|
||||||
|
|
||||||
|
class nsSVGTransform : public nsIDOMSVGTransform,
|
||||||
|
public nsSVGValue,
|
||||||
|
public nsISVGValueObserver
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static nsresult Create(nsIDOMSVGTransform** aResult);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
nsSVGTransform();
|
||||||
|
~nsSVGTransform();
|
||||||
|
nsresult Init();
|
||||||
|
public:
|
||||||
|
// nsISupports interface:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
|
// nsIDOMSVGTransform interface:
|
||||||
|
NS_DECL_NSIDOMSVGTRANSFORM
|
||||||
|
|
||||||
|
// nsISVGValue interface:
|
||||||
|
NS_IMETHOD SetValueString(const nsAString& aValue);
|
||||||
|
NS_IMETHOD GetValueString(nsAString& aValue);
|
||||||
|
|
||||||
|
// nsISVGValueObserver
|
||||||
|
NS_IMETHOD WillModifySVGObservable(nsISVGValue* observable,
|
||||||
|
modificationType aModType);
|
||||||
|
NS_IMETHOD DidModifySVGObservable (nsISVGValue* observable,
|
||||||
|
modificationType aModType);
|
||||||
|
|
||||||
|
#ifdef MOZ_SMIL
|
||||||
|
// Additional methods needed for animation
|
||||||
|
void GetRotationOrigin(float& aOriginX, float& aOriginY) const
|
||||||
|
{
|
||||||
|
aOriginX = mOriginX;
|
||||||
|
aOriginY = mOriginY;
|
||||||
|
}
|
||||||
|
#endif // MOZ_SMIL
|
||||||
|
|
||||||
|
protected:
|
||||||
|
nsCOMPtr<nsIDOMSVGMatrix> mMatrix;
|
||||||
|
float mAngle, mOriginX, mOriginY;
|
||||||
|
PRUint16 mType;
|
||||||
|
};
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
NS_NewSVGTransform(nsIDOMSVGTransform** result);
|
NS_NewSVGTransform(nsIDOMSVGTransform** result);
|
||||||
|
|
|
@ -0,0 +1,439 @@
|
||||||
|
/* -*- 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.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Brian Birtles.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Brian Birtles <birtles@gmail.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include "nsSVGTransformSMILAttr.h"
|
||||||
|
#include "nsSVGTransformSMILType.h"
|
||||||
|
#include "nsSVGAnimatedTransformList.h"
|
||||||
|
#include "nsSVGTransformList.h"
|
||||||
|
#include "nsSVGTransform.h"
|
||||||
|
#include "nsIDOMSVGTransform.h"
|
||||||
|
#include "nsIDOMSVGMatrix.h"
|
||||||
|
#include "nsSVGMatrix.h"
|
||||||
|
#include "nsSMILValue.h"
|
||||||
|
#include "nsSMILNullType.h"
|
||||||
|
#include "nsISMILAnimationElement.h"
|
||||||
|
#include "nsSVGElement.h"
|
||||||
|
#include "nsISVGValue.h"
|
||||||
|
#include "prdtoa.h"
|
||||||
|
|
||||||
|
nsISMILType*
|
||||||
|
nsSVGTransformSMILAttr::GetSMILType() const
|
||||||
|
{
|
||||||
|
return &nsSVGTransformSMILType::sSingleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsSVGTransformSMILAttr::ValueFromString(const nsAString& aStr,
|
||||||
|
const nsISMILAnimationElement* aSrcElement,
|
||||||
|
nsSMILValue& aValue) const
|
||||||
|
{
|
||||||
|
NS_ENSURE_TRUE(aSrcElement, NS_ERROR_FAILURE);
|
||||||
|
NS_ASSERTION(aValue.IsNull(),
|
||||||
|
"aValue should have been cleared before calling ValueFromString.");
|
||||||
|
|
||||||
|
nsSMILValue val(&nsSVGTransformSMILType::sSingleton);
|
||||||
|
if (val.IsNull())
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
const nsAttrValue* typeAttr = aSrcElement->GetAnimAttr(nsGkAtoms::type);
|
||||||
|
|
||||||
|
const nsIAtom* transformType = typeAttr
|
||||||
|
? typeAttr->GetAtomValue()
|
||||||
|
: nsGkAtoms::translate;
|
||||||
|
|
||||||
|
nsresult rv = ParseValue(aStr, transformType, val);
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
aValue = val;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsSMILValue
|
||||||
|
nsSVGTransformSMILAttr::GetBaseValue() const
|
||||||
|
{
|
||||||
|
nsSVGTransformSMILType *type = &nsSVGTransformSMILType::sSingleton;
|
||||||
|
nsSMILValue val(type);
|
||||||
|
if (val.IsNull())
|
||||||
|
return val;
|
||||||
|
|
||||||
|
nsIDOMSVGTransformList *list = mVal->mBaseVal.get();
|
||||||
|
|
||||||
|
PRUint32 numItems = 0;
|
||||||
|
list->GetNumberOfItems(&numItems);
|
||||||
|
for (PRUint32 i = 0; i < numItems; i++) {
|
||||||
|
nsCOMPtr<nsIDOMSVGTransform> transform;
|
||||||
|
nsresult rv = list->GetItem(i, getter_AddRefs(transform));
|
||||||
|
if (NS_SUCCEEDED(rv) && transform) {
|
||||||
|
rv = AppendSVGTransformToSMILValue(transform.get(), val);
|
||||||
|
NS_ENSURE_SUCCESS(rv,nsSMILValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsSVGTransformSMILAttr::SetAnimValue(const nsSMILValue& aValue)
|
||||||
|
{
|
||||||
|
if (aValue.mType != &nsSVGTransformSMILType::sSingleton) {
|
||||||
|
NS_WARNING("Unexpected SMIL Type");
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
|
||||||
|
// Create the anim value if necessary
|
||||||
|
mVal->WillModify(nsISVGValue::mod_other);
|
||||||
|
if (!mVal->mAnimVal) {
|
||||||
|
rv = nsSVGTransformList::Create(getter_AddRefs(mVal->mAnimVal));
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do a minimal update on the anim value and if anything fails, set the anim
|
||||||
|
// value to null so that calls to nsSVGAnimatedTransformList::GetAnimVal will
|
||||||
|
// return the base value instead.
|
||||||
|
rv = UpdateFromSMILValue(mVal->mAnimVal, aValue);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
mVal->mAnimVal = nsnull;
|
||||||
|
}
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
mVal->DidModify(nsISVGValue::mod_other);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Implementation helpers
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsSVGTransformSMILAttr::ParseValue(const nsAString& aSpec,
|
||||||
|
const nsIAtom* aTransformType,
|
||||||
|
nsSMILValue& aResult) const
|
||||||
|
{
|
||||||
|
nsSVGTransformSMILType* type = &nsSVGTransformSMILType::sSingleton;
|
||||||
|
NS_ASSERTION(
|
||||||
|
type == static_cast<nsSVGTransformSMILType const *>(aResult.mType),
|
||||||
|
"Unexpected type for SMIL value result.");
|
||||||
|
|
||||||
|
// Reset the result so we can just append to it
|
||||||
|
nsresult rv = type->Init(aResult);
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
float params[3] = { 0.f };
|
||||||
|
PRInt32 numParsed = ParseParameterList(aSpec, params, 3);
|
||||||
|
nsSVGSMILTransform::TransformType transformType;
|
||||||
|
|
||||||
|
if (aTransformType == nsGkAtoms::translate) {
|
||||||
|
// tx [ty=0]
|
||||||
|
if (numParsed != 1 && numParsed != 2)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
transformType = nsSVGSMILTransform::TRANSFORM_TRANSLATE;
|
||||||
|
} else if (aTransformType == nsGkAtoms::scale) {
|
||||||
|
// sx [sy=sx]
|
||||||
|
if (numParsed != 1 && numParsed != 2)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
if (numParsed == 1) {
|
||||||
|
params[1] = params[0];
|
||||||
|
}
|
||||||
|
transformType = nsSVGSMILTransform::TRANSFORM_SCALE;
|
||||||
|
} else if (aTransformType == nsGkAtoms::rotate) {
|
||||||
|
// r [cx=0 cy=0]
|
||||||
|
if (numParsed != 1 && numParsed != 3)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
transformType = nsSVGSMILTransform::TRANSFORM_ROTATE;
|
||||||
|
} else if (aTransformType == nsGkAtoms::skewX) {
|
||||||
|
// x-angle
|
||||||
|
if (numParsed != 1)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
transformType = nsSVGSMILTransform::TRANSFORM_SKEWX;
|
||||||
|
} else if (aTransformType == nsGkAtoms::skewY) {
|
||||||
|
// y-angle
|
||||||
|
if (numParsed != 1)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
transformType = nsSVGSMILTransform::TRANSFORM_SKEWY;
|
||||||
|
} else {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return type->AppendTransform(nsSVGSMILTransform(transformType, params),
|
||||||
|
aResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline PRBool
|
||||||
|
nsSVGTransformSMILAttr::IsSpace(const char c) const
|
||||||
|
{
|
||||||
|
return (c == 0x9 || c == 0xA || c == 0xD || c == 0x20);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
nsSVGTransformSMILAttr::SkipWsp(nsACString::const_iterator& aIter,
|
||||||
|
const nsACString::const_iterator& aIterEnd) const
|
||||||
|
{
|
||||||
|
while (aIter != aIterEnd && IsSpace(*aIter))
|
||||||
|
++aIter;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRInt32
|
||||||
|
nsSVGTransformSMILAttr::ParseParameterList(const nsAString& aSpec,
|
||||||
|
float* aVars,
|
||||||
|
PRInt32 aNVars) const
|
||||||
|
{
|
||||||
|
NS_ConvertUTF16toUTF8 spec(aSpec);
|
||||||
|
|
||||||
|
nsACString::const_iterator start, end;
|
||||||
|
spec.BeginReading(start);
|
||||||
|
spec.EndReading(end);
|
||||||
|
|
||||||
|
SkipWsp(start, end);
|
||||||
|
|
||||||
|
int numArgsFound = 0;
|
||||||
|
|
||||||
|
while (start != end) {
|
||||||
|
char const *arg = start.get();
|
||||||
|
char *argend;
|
||||||
|
float f = float(PR_strtod(arg, &argend));
|
||||||
|
if (arg == argend || argend > end.get())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (numArgsFound < aNVars) {
|
||||||
|
aVars[numArgsFound] = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
start.advance(argend - arg);
|
||||||
|
numArgsFound++;
|
||||||
|
|
||||||
|
SkipWsp(start, end);
|
||||||
|
if (*start == ',') {
|
||||||
|
++start;
|
||||||
|
SkipWsp(start, end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return numArgsFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsSVGTransformSMILAttr::AppendSVGTransformToSMILValue(
|
||||||
|
nsIDOMSVGTransform* aTransform, nsSMILValue& aValue) const
|
||||||
|
{
|
||||||
|
nsSVGTransformSMILType* type = &nsSVGTransformSMILType::sSingleton;
|
||||||
|
|
||||||
|
PRUint16 svgTransformType = nsIDOMSVGTransform::SVG_TRANSFORM_MATRIX;
|
||||||
|
aTransform->GetType(&svgTransformType);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMSVGMatrix> matrix;
|
||||||
|
nsresult rv = aTransform->GetMatrix(getter_AddRefs(matrix));
|
||||||
|
if (NS_FAILED(rv) || !matrix)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
float params[3] = { 0.f };
|
||||||
|
nsSVGSMILTransform::TransformType transformType;
|
||||||
|
|
||||||
|
switch (svgTransformType)
|
||||||
|
{
|
||||||
|
case nsIDOMSVGTransform::SVG_TRANSFORM_TRANSLATE:
|
||||||
|
{
|
||||||
|
matrix->GetE(¶ms[0]);
|
||||||
|
matrix->GetF(¶ms[1]);
|
||||||
|
transformType = nsSVGSMILTransform::TRANSFORM_TRANSLATE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nsIDOMSVGTransform::SVG_TRANSFORM_SCALE:
|
||||||
|
{
|
||||||
|
matrix->GetA(¶ms[0]);
|
||||||
|
matrix->GetD(¶ms[1]);
|
||||||
|
transformType = nsSVGSMILTransform::TRANSFORM_SCALE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nsIDOMSVGTransform::SVG_TRANSFORM_ROTATE:
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Unfortunately the SVG 1.1 DOM API for transforms doesn't allow us to
|
||||||
|
* query the center of rotation so we do some dirty casting to make up
|
||||||
|
* for it.
|
||||||
|
*/
|
||||||
|
nsSVGTransform* svgTransform = static_cast<nsSVGTransform*>(aTransform);
|
||||||
|
svgTransform->GetAngle(¶ms[0]);
|
||||||
|
svgTransform->GetRotationOrigin(params[1], params[2]);
|
||||||
|
transformType = nsSVGSMILTransform::TRANSFORM_ROTATE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nsIDOMSVGTransform::SVG_TRANSFORM_SKEWX:
|
||||||
|
{
|
||||||
|
aTransform->GetAngle(¶ms[0]);
|
||||||
|
transformType = nsSVGSMILTransform::TRANSFORM_SKEWX;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nsIDOMSVGTransform::SVG_TRANSFORM_SKEWY:
|
||||||
|
{
|
||||||
|
aTransform->GetAngle(¶ms[0]);
|
||||||
|
transformType = nsSVGSMILTransform::TRANSFORM_SKEWY;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nsIDOMSVGTransform::SVG_TRANSFORM_MATRIX:
|
||||||
|
{
|
||||||
|
float mx[6];
|
||||||
|
matrix->GetA(&mx[0]);
|
||||||
|
matrix->GetB(&mx[1]);
|
||||||
|
matrix->GetC(&mx[2]);
|
||||||
|
matrix->GetD(&mx[3]);
|
||||||
|
matrix->GetE(&mx[4]);
|
||||||
|
matrix->GetF(&mx[5]);
|
||||||
|
rv = type->AppendTransform(nsSVGSMILTransform(mx), aValue);
|
||||||
|
transformType = nsSVGSMILTransform::TRANSFORM_MATRIX;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nsIDOMSVGTransform::SVG_TRANSFORM_UNKNOWN:
|
||||||
|
// If it's 'unknown', it's probably not initialised, so just skip it.
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
default:
|
||||||
|
NS_WARNING("Trying to convert unrecognised SVG transform type.");
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transformType != nsSVGSMILTransform::TRANSFORM_MATRIX) {
|
||||||
|
rv =
|
||||||
|
type->AppendTransform(nsSVGSMILTransform(transformType, params), aValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsSVGTransformSMILAttr::UpdateFromSMILValue(
|
||||||
|
nsIDOMSVGTransformList* aTransformList, const nsSMILValue& aValue)
|
||||||
|
{
|
||||||
|
PRUint32 svgLength = -1;
|
||||||
|
aTransformList->GetNumberOfItems(&svgLength);
|
||||||
|
|
||||||
|
nsSVGTransformSMILType* type = &nsSVGTransformSMILType::sSingleton;
|
||||||
|
PRUint32 smilLength = type->GetNumTransforms(aValue);
|
||||||
|
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
|
||||||
|
for (PRUint32 i = 0; i < smilLength; i++) {
|
||||||
|
nsCOMPtr<nsIDOMSVGTransform> transform;
|
||||||
|
if (i < svgLength) {
|
||||||
|
// Get the transform to update
|
||||||
|
rv = aTransformList->GetItem(i, getter_AddRefs(transform));
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
} else {
|
||||||
|
// Append another transform to the list
|
||||||
|
nsresult rv = NS_NewSVGTransform(getter_AddRefs(transform));
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMSVGTransform> result;
|
||||||
|
rv = aTransformList->AppendItem(transform, getter_AddRefs(result));
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
}
|
||||||
|
// Set the value
|
||||||
|
const nsSVGSMILTransform* smilTransform = type->GetTransformAt(i, aValue);
|
||||||
|
rv = GetSVGTransformFromSMILValue(*smilTransform, transform);
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trim excess elements
|
||||||
|
while (svgLength > smilLength) {
|
||||||
|
nsCOMPtr<nsIDOMSVGTransform> removed;
|
||||||
|
rv = aTransformList->RemoveItem(--svgLength, getter_AddRefs(removed));
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsSVGTransformSMILAttr::GetSVGTransformFromSMILValue(
|
||||||
|
const nsSVGSMILTransform& aSMILTransform,
|
||||||
|
nsIDOMSVGTransform* aSVGTransform) const
|
||||||
|
{
|
||||||
|
nsresult rv = NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
switch (aSMILTransform.mTransformType)
|
||||||
|
{
|
||||||
|
case nsSVGSMILTransform::TRANSFORM_TRANSLATE:
|
||||||
|
rv = aSVGTransform->SetTranslate(aSMILTransform.mParams[0],
|
||||||
|
aSMILTransform.mParams[1]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nsSVGSMILTransform::TRANSFORM_SCALE:
|
||||||
|
rv = aSVGTransform->SetScale(aSMILTransform.mParams[0],
|
||||||
|
aSMILTransform.mParams[1]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nsSVGSMILTransform::TRANSFORM_ROTATE:
|
||||||
|
rv = aSVGTransform->SetRotate(aSMILTransform.mParams[0],
|
||||||
|
aSMILTransform.mParams[1],
|
||||||
|
aSMILTransform.mParams[2]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nsSVGSMILTransform::TRANSFORM_SKEWX:
|
||||||
|
rv = aSVGTransform->SetSkewX(aSMILTransform.mParams[0]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nsSVGSMILTransform::TRANSFORM_SKEWY:
|
||||||
|
rv = aSVGTransform->SetSkewY(aSMILTransform.mParams[0]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nsSVGSMILTransform::TRANSFORM_MATRIX:
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIDOMSVGMatrix> svgMatrix;
|
||||||
|
rv = NS_NewSVGMatrix(getter_AddRefs(svgMatrix),
|
||||||
|
aSMILTransform.mParams[0],
|
||||||
|
aSMILTransform.mParams[1],
|
||||||
|
aSMILTransform.mParams[2],
|
||||||
|
aSMILTransform.mParams[3],
|
||||||
|
aSMILTransform.mParams[4],
|
||||||
|
aSMILTransform.mParams[5]);
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
NS_ENSURE_TRUE(svgMatrix,NS_ERROR_FAILURE);
|
||||||
|
rv = aSVGTransform->SetMatrix(svgMatrix);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
/* -*- 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.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Brian Birtles.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Brian Birtles <birtles@gmail.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#ifndef NS_SVGTRANSFORMSMILATTR_H_
|
||||||
|
#define NS_SVGTRANSFORMSMILATTR_H_
|
||||||
|
|
||||||
|
#include "nsISMILAttr.h"
|
||||||
|
#include "nsIAtom.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
|
||||||
|
class nsSVGElement;
|
||||||
|
class nsSVGAnimatedTransformList;
|
||||||
|
class nsISMILType;
|
||||||
|
class nsIDOMSVGTransform;
|
||||||
|
class nsIDOMSVGTransformList;
|
||||||
|
class nsSVGSMILTransform;
|
||||||
|
|
||||||
|
class nsSVGTransformSMILAttr : public nsISMILAttr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsSVGTransformSMILAttr(nsSVGAnimatedTransformList* aTransform,
|
||||||
|
nsSVGElement* aSVGElement)
|
||||||
|
: mVal(aTransform),
|
||||||
|
mSVGElement(aSVGElement) {}
|
||||||
|
|
||||||
|
// nsISMILAttr methods
|
||||||
|
virtual nsISMILType* GetSMILType() const;
|
||||||
|
virtual nsresult ValueFromString(const nsAString& aStr,
|
||||||
|
const nsISMILAnimationElement* aSrcElement,
|
||||||
|
nsSMILValue& aValue) const;
|
||||||
|
virtual nsSMILValue GetBaseValue() const;
|
||||||
|
virtual nsresult SetAnimValue(const nsSMILValue& aValue);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
nsresult ParseValue(const nsAString& aSpec,
|
||||||
|
const nsIAtom* aTransformType,
|
||||||
|
nsSMILValue& aResult) const;
|
||||||
|
PRInt32 ParseParameterList(const nsAString& aSpec, float* aVars,
|
||||||
|
PRInt32 aNVars) const;
|
||||||
|
PRBool IsSpace(const char c) const;
|
||||||
|
void SkipWsp(nsACString::const_iterator& aIter,
|
||||||
|
const nsACString::const_iterator& aIterEnd) const;
|
||||||
|
nsresult AppendSVGTransformToSMILValue(nsIDOMSVGTransform* transform,
|
||||||
|
nsSMILValue& aValue) const;
|
||||||
|
nsresult UpdateFromSMILValue(nsIDOMSVGTransformList* aTransformList,
|
||||||
|
const nsSMILValue& aValue);
|
||||||
|
nsresult GetSVGTransformFromSMILValue(
|
||||||
|
const nsSVGSMILTransform& aSMILTransform,
|
||||||
|
nsIDOMSVGTransform* aSVGTransform) const;
|
||||||
|
already_AddRefed<nsIDOMSVGTransform> GetSVGTransformFromSMILValue(
|
||||||
|
const nsSMILValue& aValue) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Raw pointers are OK here because this nsSVGTransformSMILAttr is both
|
||||||
|
// created & destroyed during a SMIL sample-step, during which time the DOM
|
||||||
|
// isn't modified.
|
||||||
|
nsSVGAnimatedTransformList* mVal;
|
||||||
|
nsSVGElement* mSVGElement;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NS_SVGTRANSFORMSMILATTR_H_
|
|
@ -0,0 +1,356 @@
|
||||||
|
/* -*- 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.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Brian Birtles.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Brian Birtles <birtles@gmail.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include "nsSVGTransformSMILType.h"
|
||||||
|
#include "nsSMILValue.h"
|
||||||
|
#include "nsCRT.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
/*static*/ nsSVGTransformSMILType nsSVGTransformSMILType::sSingleton;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// nsISMILType implementation
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsSVGTransformSMILType::Init(nsSMILValue &aValue) const
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aValue.mType == this || aValue.IsNull(),
|
||||||
|
"Unexpected value type");
|
||||||
|
NS_ASSERTION(aValue.mType != this || aValue.mU.mPtr,
|
||||||
|
"Invalid nsSMILValue of SVG transform type: NULL data member.");
|
||||||
|
|
||||||
|
if (aValue.mType != this || !aValue.mU.mPtr) {
|
||||||
|
// Different type, or no data member: allocate memory and set type
|
||||||
|
TransformArray* transforms = new TransformArray(1);
|
||||||
|
NS_ENSURE_TRUE(transforms, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
aValue.mU.mPtr = transforms;
|
||||||
|
aValue.mType = this;
|
||||||
|
} else {
|
||||||
|
// Same type, just set clear
|
||||||
|
TransformArray* transforms = static_cast<TransformArray*>(aValue.mU.mPtr);
|
||||||
|
transforms->Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsSVGTransformSMILType::Destroy(nsSMILValue& aValue) const
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value type.");
|
||||||
|
TransformArray* params = static_cast<TransformArray*>(aValue.mU.mPtr);
|
||||||
|
delete params;
|
||||||
|
aValue.mU.mPtr = nsnull;
|
||||||
|
aValue.mType = &nsSMILNullType::sSingleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsSVGTransformSMILType::Assign(nsSMILValue& aDest,
|
||||||
|
const nsSMILValue& aSrc) const
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types.");
|
||||||
|
NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value.");
|
||||||
|
|
||||||
|
const TransformArray* srcTransforms =
|
||||||
|
static_cast<const TransformArray*>(aSrc.mU.mPtr);
|
||||||
|
TransformArray* dstTransforms = static_cast<TransformArray*>(aDest.mU.mPtr);
|
||||||
|
|
||||||
|
// Before we assign, ensure we have sufficient memory
|
||||||
|
PRBool result = dstTransforms->SetCapacity(srcTransforms->Length());
|
||||||
|
NS_ENSURE_TRUE(result,NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
|
*dstTransforms = *srcTransforms;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsSVGTransformSMILType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
|
||||||
|
PRUint32 aCount) const
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL type.");
|
||||||
|
NS_PRECONDITION(aDest.mType == aValueToAdd.mType, "Incompatible SMIL types.");
|
||||||
|
|
||||||
|
TransformArray& dstTransforms(*static_cast<TransformArray*>(aDest.mU.mPtr));
|
||||||
|
const TransformArray& srcTransforms
|
||||||
|
(*static_cast<const TransformArray*>(aValueToAdd.mU.mPtr));
|
||||||
|
|
||||||
|
// We're doing a simple add here (as opposed to a sandwich add below).
|
||||||
|
// We only do this when we're accumulating a repeat result or calculating
|
||||||
|
// a by-animation value.
|
||||||
|
//
|
||||||
|
// In either case we should have 1 transform in the source array.
|
||||||
|
NS_ASSERTION(srcTransforms.Length() == 1,
|
||||||
|
"Invalid source transform list to add.");
|
||||||
|
|
||||||
|
// And we should have 0 or 1 transforms in the dest array.
|
||||||
|
// (We can have 0 transforms in the case of by-animation when we are
|
||||||
|
// calculating the by-value as "0 + by". Zero being represented by an
|
||||||
|
// nsSMILValue with an empty transform array.)
|
||||||
|
NS_ASSERTION(dstTransforms.Length() < 2,
|
||||||
|
"Invalid dest transform list to add to.");
|
||||||
|
|
||||||
|
// Get the individual transforms to add
|
||||||
|
const nsSVGSMILTransform& srcTransform = srcTransforms[0];
|
||||||
|
if (dstTransforms.IsEmpty()) {
|
||||||
|
nsSVGSMILTransform* result = dstTransforms.AppendElement(
|
||||||
|
nsSVGSMILTransform(srcTransform.mTransformType));
|
||||||
|
NS_ENSURE_TRUE(result,NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
}
|
||||||
|
nsSVGSMILTransform& dstTransform = dstTransforms[0];
|
||||||
|
|
||||||
|
// The types must be the same
|
||||||
|
NS_ASSERTION(srcTransform.mTransformType == dstTransform.mTransformType,
|
||||||
|
"Trying to perform simple add of different transform types.");
|
||||||
|
|
||||||
|
// And it should be impossible that one of them is of matrix type
|
||||||
|
NS_ASSERTION(
|
||||||
|
srcTransform.mTransformType != nsSVGSMILTransform::TRANSFORM_MATRIX,
|
||||||
|
"Trying to perform simple add with matrix transform.");
|
||||||
|
|
||||||
|
// Add the parameters
|
||||||
|
for (int i = 0; i <= 2; ++i) {
|
||||||
|
dstTransform.mParams[i] += srcTransform.mParams[i] * aCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsSVGTransformSMILType::SandwichAdd(nsSMILValue& aDest,
|
||||||
|
const nsSMILValue& aValueToAdd) const
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL type.");
|
||||||
|
NS_PRECONDITION(aDest.mType == aValueToAdd.mType, "Incompatible SMIL types.");
|
||||||
|
|
||||||
|
// For <animateTransform> a sandwich add means a matrix post-multiplication
|
||||||
|
// which just means to put the additional transform on the end of the array
|
||||||
|
|
||||||
|
TransformArray& dstTransforms(*static_cast<TransformArray*>(aDest.mU.mPtr));
|
||||||
|
const TransformArray& srcTransforms
|
||||||
|
(*static_cast<const TransformArray*>(aValueToAdd.mU.mPtr));
|
||||||
|
|
||||||
|
// We're only expecting to be adding 1 src transform on to the list
|
||||||
|
NS_ASSERTION(srcTransforms.Length() == 1,
|
||||||
|
"Trying to do sandwich add of more than one value.");
|
||||||
|
|
||||||
|
// Stick the src on the end of the array
|
||||||
|
const nsSVGSMILTransform& srcTransform = srcTransforms[0];
|
||||||
|
nsSVGSMILTransform* result = dstTransforms.AppendElement(srcTransform);
|
||||||
|
NS_ENSURE_TRUE(result,NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsSVGTransformSMILType::ComputeDistance(const nsSMILValue& aFrom,
|
||||||
|
const nsSMILValue& aTo,
|
||||||
|
double& aDistance) const
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aFrom.mType == aTo.mType,
|
||||||
|
"Can't compute difference between different SMIL types.");
|
||||||
|
NS_PRECONDITION(aFrom.mType == this, "Unexpected SMIL type.");
|
||||||
|
|
||||||
|
const TransformArray* fromTransforms =
|
||||||
|
static_cast<const TransformArray*>(aFrom.mU.mPtr);
|
||||||
|
const TransformArray* toTransforms =
|
||||||
|
static_cast<const TransformArray*>(aTo.mU.mPtr);
|
||||||
|
|
||||||
|
// ComputeDistance is only used for calculating distances between single
|
||||||
|
// values in a values array which necessarily have the same type
|
||||||
|
//
|
||||||
|
// So we should only have one transform in each array and they should be of
|
||||||
|
// the same type
|
||||||
|
NS_ASSERTION(fromTransforms->Length() == 1,
|
||||||
|
"Wrong number of elements in from value.");
|
||||||
|
NS_ASSERTION(toTransforms->Length() == 1,
|
||||||
|
"Wrong number of elements in to value.");
|
||||||
|
|
||||||
|
const nsSVGSMILTransform& fromTransform = (*fromTransforms)[0];
|
||||||
|
const nsSVGSMILTransform& toTransform = (*toTransforms)[0];
|
||||||
|
NS_ASSERTION(fromTransform.mTransformType == toTransform.mTransformType,
|
||||||
|
"Incompatible transform types to calculate distance between.");
|
||||||
|
|
||||||
|
switch (fromTransform.mTransformType)
|
||||||
|
{
|
||||||
|
// We adopt the SVGT1.2 notions of distance here
|
||||||
|
// See: http://www.w3.org/TR/SVGTiny12/animate.html#complexDistances
|
||||||
|
// (As discussed in bug #469040)
|
||||||
|
case nsSVGSMILTransform::TRANSFORM_TRANSLATE:
|
||||||
|
case nsSVGSMILTransform::TRANSFORM_SCALE:
|
||||||
|
{
|
||||||
|
const float& a_tx = fromTransform.mParams[0];
|
||||||
|
const float& a_ty = fromTransform.mParams[1];
|
||||||
|
const float& b_tx = toTransform.mParams[0];
|
||||||
|
const float& b_ty = toTransform.mParams[1];
|
||||||
|
aDistance = sqrt(pow(a_tx - b_tx, 2) + (pow(a_ty - b_ty, 2)));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nsSVGSMILTransform::TRANSFORM_ROTATE:
|
||||||
|
case nsSVGSMILTransform::TRANSFORM_SKEWX:
|
||||||
|
case nsSVGSMILTransform::TRANSFORM_SKEWY:
|
||||||
|
{
|
||||||
|
const float& a = fromTransform.mParams[0];
|
||||||
|
const float& b = toTransform.mParams[0];
|
||||||
|
aDistance = fabs(a-b);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
NS_ERROR("Got bad transform types for calculating distances.");
|
||||||
|
aDistance = 1.0;
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsSVGTransformSMILType::Interpolate(const nsSMILValue& aStartVal,
|
||||||
|
const nsSMILValue& aEndVal,
|
||||||
|
double aUnitDistance,
|
||||||
|
nsSMILValue& aResult) const
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
|
||||||
|
"Can't interpolate between different SMIL types.");
|
||||||
|
NS_PRECONDITION(aStartVal.mType == this,
|
||||||
|
"Unexpected type for interpolation.");
|
||||||
|
NS_PRECONDITION(aResult.mType == this, "Unexpected result type.");
|
||||||
|
|
||||||
|
const TransformArray& startTransforms =
|
||||||
|
(*static_cast<const TransformArray*>(aStartVal.mU.mPtr));
|
||||||
|
const TransformArray& endTransforms
|
||||||
|
(*static_cast<const TransformArray*>(aEndVal.mU.mPtr));
|
||||||
|
|
||||||
|
// We may have 0..n transforms in the start transform array (the base
|
||||||
|
// value) but we should only have 1 transform in the end transform array
|
||||||
|
NS_ASSERTION(endTransforms.Length() == 1,
|
||||||
|
"Invalid end-point for interpolating between transform values.");
|
||||||
|
|
||||||
|
// The end point should never be a matrix transform
|
||||||
|
const nsSVGSMILTransform& endTransform = endTransforms[0];
|
||||||
|
NS_ASSERTION(
|
||||||
|
endTransform.mTransformType != nsSVGSMILTransform::TRANSFORM_MATRIX,
|
||||||
|
"End point for interpolation should not be a matrix transform.");
|
||||||
|
|
||||||
|
// If we have 0 or more than 1 transform in the start transform array then we
|
||||||
|
// just interpolate from 0, 0, 0
|
||||||
|
// Likewise, even if there's only 1 transform in the start transform array
|
||||||
|
// then if the type of the start transform doesn't match the end then we
|
||||||
|
// can't interpolate and should just use 0, 0, 0
|
||||||
|
static float identityParams[3] = { 0.f };
|
||||||
|
const float* startParams = nsnull;
|
||||||
|
if (startTransforms.Length() == 1) {
|
||||||
|
const nsSVGSMILTransform& startTransform = startTransforms[0];
|
||||||
|
if (startTransform.mTransformType == endTransform.mTransformType) {
|
||||||
|
startParams = startTransform.mParams;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!startParams) {
|
||||||
|
startParams = identityParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float* endParams = endTransform.mParams;
|
||||||
|
|
||||||
|
// Interpolate between the params
|
||||||
|
float newParams[3];
|
||||||
|
for (int i = 0; i <= 2; ++i) {
|
||||||
|
const float& a = startParams[i];
|
||||||
|
const float& b = endParams[i];
|
||||||
|
newParams[i] = a + (b - a) * aUnitDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the result
|
||||||
|
nsSVGSMILTransform resultTransform(endTransform.mTransformType, newParams);
|
||||||
|
|
||||||
|
// Clear the way for it in the result array
|
||||||
|
TransformArray& dstTransforms =
|
||||||
|
(*static_cast<TransformArray*>(aResult.mU.mPtr));
|
||||||
|
dstTransforms.Clear();
|
||||||
|
|
||||||
|
// Assign the result
|
||||||
|
nsSVGSMILTransform* transform = dstTransforms.AppendElement(resultTransform);
|
||||||
|
NS_ENSURE_TRUE(transform,NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Transform array accessors
|
||||||
|
|
||||||
|
PRUint32
|
||||||
|
nsSVGTransformSMILType::GetNumTransforms(const nsSMILValue& aValue) const
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value.");
|
||||||
|
|
||||||
|
const TransformArray& transforms =
|
||||||
|
*static_cast<const TransformArray*>(aValue.mU.mPtr);
|
||||||
|
|
||||||
|
return transforms.Length();
|
||||||
|
}
|
||||||
|
|
||||||
|
const nsSVGSMILTransform*
|
||||||
|
nsSVGTransformSMILType::GetTransformAt(PRUint32 aIndex,
|
||||||
|
const nsSMILValue& aValue) const
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value.");
|
||||||
|
|
||||||
|
const TransformArray& transforms =
|
||||||
|
*static_cast<const TransformArray*>(aValue.mU.mPtr);
|
||||||
|
|
||||||
|
if (aIndex >= transforms.Length()) {
|
||||||
|
NS_ERROR("Attempting to access invalid transform.");
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &transforms[aIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsSVGTransformSMILType::AppendTransform(const nsSVGSMILTransform& aTransform,
|
||||||
|
nsSMILValue& aValue) const
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value.");
|
||||||
|
|
||||||
|
TransformArray& transforms = *static_cast<TransformArray*>(aValue.mU.mPtr);
|
||||||
|
|
||||||
|
nsSVGSMILTransform* transform = transforms.AppendElement(aTransform);
|
||||||
|
NS_ENSURE_TRUE(transform,NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
|
@ -0,0 +1,141 @@
|
||||||
|
/* -*- 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.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Brian Birtles.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Brian Birtles <birtles@gmail.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#ifndef NS_SVGTRANSFORMSMILTYPE_H_
|
||||||
|
#define NS_SVGTRANSFORMSMILTYPE_H_
|
||||||
|
|
||||||
|
#include "nsISMILType.h"
|
||||||
|
#include "nsSVGSMILTransform.h"
|
||||||
|
#include "nsTArray.h"
|
||||||
|
|
||||||
|
struct nsSMILValue;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
// nsSVGTransformSMILType
|
||||||
|
//
|
||||||
|
// Operations for animating an nsSVGTransformList.
|
||||||
|
//
|
||||||
|
// This class is confused somewhat by the fact that:
|
||||||
|
// (i) An <animateTransform> element animates an SVGTransformList
|
||||||
|
// (ii) BUT <animateTransform> only allows the user to specify animation values
|
||||||
|
// for an SVGTransform
|
||||||
|
//
|
||||||
|
// This may be rectified in a future edition of SVG but for now it means that
|
||||||
|
// the underlying value of an animation may be something of the form:
|
||||||
|
//
|
||||||
|
// rotate(90) scale(2) skewX(50)
|
||||||
|
//
|
||||||
|
// BUT the animation values can only ever be SINGLE transform operations such as
|
||||||
|
//
|
||||||
|
// rotate(90)
|
||||||
|
//
|
||||||
|
// (actually the syntax here is:
|
||||||
|
// <animateTransform type="rotate" from="0" to="90"...
|
||||||
|
// OR maybe
|
||||||
|
// <animateTransform type="rotate" values="0; 90; 30; 50"...
|
||||||
|
// OR even (with a rotation centre)
|
||||||
|
// <animateTransform type="rotate" values="0 50 20; 30 50 20; 70 0 0"...)
|
||||||
|
//
|
||||||
|
// This has many implications for the number of elements we expect in the
|
||||||
|
// transform array supplied for each operation.
|
||||||
|
//
|
||||||
|
// For example, Add() only ever operates on the values specified on an
|
||||||
|
// <animateTransform> element and so these values can only ever contain 0 or
|
||||||
|
// 1 TRANSFORM elements as the syntax doesn't allow more. (A "value" here is
|
||||||
|
// a single element in the values array such as "0 50 20" above.)
|
||||||
|
//
|
||||||
|
// Likewise ComputeDistance() only ever operates within the values specified on
|
||||||
|
// an <animateTransform> element so similar conditions hold.
|
||||||
|
//
|
||||||
|
// However, SandwichAdd() combines with a base value which may contain 0..n
|
||||||
|
// transforms either because the base value of the attribute specifies a series
|
||||||
|
// of transforms, e.g.
|
||||||
|
//
|
||||||
|
// <circle transform="translate(30) rotate(50)"... >
|
||||||
|
// <animateTransform.../>
|
||||||
|
// </circle>
|
||||||
|
//
|
||||||
|
// or because several animations target the same attribute and are additive and
|
||||||
|
// so are simply appended on to the transformation array, e.g.
|
||||||
|
//
|
||||||
|
// <circle transform="translate(30)"... >
|
||||||
|
// <animateTransform type="rotate" additive="sum".../>
|
||||||
|
// <animateTransform type="scale" additive="sum".../>
|
||||||
|
// <animateTransform type="skewX" additive="sum".../>
|
||||||
|
// </circle>
|
||||||
|
//
|
||||||
|
// Similar conditions hold for Interpolate() which in cases such as to-animation
|
||||||
|
// may have use a start-value the base value of the target attribute (which as
|
||||||
|
// we have seen above can contain 0..n elements) whilst the end-value comes from
|
||||||
|
// the <animateTransform> and so can only hold 1 transform.
|
||||||
|
//
|
||||||
|
class nsSVGTransformSMILType : public nsISMILType
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// nsISMILType
|
||||||
|
virtual nsresult Init(nsSMILValue& aValue) const;
|
||||||
|
virtual void Destroy(nsSMILValue& aValue) const;
|
||||||
|
virtual nsresult Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const;
|
||||||
|
virtual nsresult Add(nsSMILValue& aDest,
|
||||||
|
const nsSMILValue& aValueToAdd,
|
||||||
|
PRUint32 aCount) const;
|
||||||
|
virtual nsresult SandwichAdd(nsSMILValue& aDest,
|
||||||
|
const nsSMILValue& aValueToAdd) const;
|
||||||
|
virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
|
||||||
|
const nsSMILValue& aTo,
|
||||||
|
double& aDistance) const;
|
||||||
|
virtual nsresult Interpolate(const nsSMILValue& aStartVal,
|
||||||
|
const nsSMILValue& aEndVal,
|
||||||
|
double aUnitDistance,
|
||||||
|
nsSMILValue& aResult) const;
|
||||||
|
// Transform array accessors
|
||||||
|
PRUint32 GetNumTransforms(const nsSMILValue& aValue) const;
|
||||||
|
const nsSVGSMILTransform* GetTransformAt(PRUint32 aIndex,
|
||||||
|
const nsSMILValue& aValue) const;
|
||||||
|
nsresult AppendTransform(const nsSVGSMILTransform& aTransform,
|
||||||
|
nsSMILValue& aValue) const;
|
||||||
|
|
||||||
|
static nsSVGTransformSMILType sSingleton;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
typedef nsTArray<nsSVGSMILTransform> TransformArray;
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsSVGTransformSMILType() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NS_SVGTRANSFORMSMILTYPE_H_
|
|
@ -131,6 +131,7 @@ XPIDLSRCS = \
|
||||||
ifdef MOZ_SMIL
|
ifdef MOZ_SMIL
|
||||||
XPIDLSRCS += \
|
XPIDLSRCS += \
|
||||||
nsIDOMSVGAnimateElement.idl \
|
nsIDOMSVGAnimateElement.idl \
|
||||||
|
nsIDOMSVGAnimateTransformElement.idl \
|
||||||
nsIDOMSVGAnimationElement.idl \
|
nsIDOMSVGAnimationElement.idl \
|
||||||
nsIDOMSVGSetElement.idl \
|
nsIDOMSVGSetElement.idl \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is the Mozilla SVG project.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Brian Birtles.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Brian Birtles <birtles@gmail.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include "nsIDOMSVGAnimationElement.idl"
|
||||||
|
|
||||||
|
[scriptable, uuid(735e0f75-c6aa-4aee-bcd2-46426d6ac90c)]
|
||||||
|
interface nsIDOMSVGAnimateTransformElement : nsIDOMSVGAnimationElement {};
|
|
@ -245,6 +245,7 @@ enum nsDOMClassInfoID {
|
||||||
eDOMClassInfo_SVGAElement_id,
|
eDOMClassInfo_SVGAElement_id,
|
||||||
#ifdef MOZ_SMIL
|
#ifdef MOZ_SMIL
|
||||||
eDOMClassInfo_SVGAnimateElement_id,
|
eDOMClassInfo_SVGAnimateElement_id,
|
||||||
|
eDOMClassInfo_SVGAnimateTransformElement_id,
|
||||||
eDOMClassInfo_SVGSetElement_id,
|
eDOMClassInfo_SVGSetElement_id,
|
||||||
#endif // MOZ_SMIL
|
#endif // MOZ_SMIL
|
||||||
eDOMClassInfo_SVGCircleElement_id,
|
eDOMClassInfo_SVGCircleElement_id,
|
||||||
|
|
|
@ -378,6 +378,7 @@
|
||||||
#include "nsIDOMSVGAnimatedString.h"
|
#include "nsIDOMSVGAnimatedString.h"
|
||||||
#ifdef MOZ_SMIL
|
#ifdef MOZ_SMIL
|
||||||
#include "nsIDOMSVGAnimateElement.h"
|
#include "nsIDOMSVGAnimateElement.h"
|
||||||
|
#include "nsIDOMSVGAnimateTransformElement.h"
|
||||||
#include "nsIDOMSVGSetElement.h"
|
#include "nsIDOMSVGSetElement.h"
|
||||||
#include "nsIDOMSVGAnimationElement.h"
|
#include "nsIDOMSVGAnimationElement.h"
|
||||||
#include "nsIDOMElementTimeControl.h"
|
#include "nsIDOMElementTimeControl.h"
|
||||||
|
@ -948,6 +949,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||||
#ifdef MOZ_SMIL
|
#ifdef MOZ_SMIL
|
||||||
NS_DEFINE_CLASSINFO_DATA(SVGAnimateElement, nsElementSH,
|
NS_DEFINE_CLASSINFO_DATA(SVGAnimateElement, nsElementSH,
|
||||||
ELEMENT_SCRIPTABLE_FLAGS)
|
ELEMENT_SCRIPTABLE_FLAGS)
|
||||||
|
NS_DEFINE_CLASSINFO_DATA(SVGAnimateTransformElement, nsElementSH,
|
||||||
|
ELEMENT_SCRIPTABLE_FLAGS)
|
||||||
NS_DEFINE_CLASSINFO_DATA(SVGSetElement, nsElementSH,
|
NS_DEFINE_CLASSINFO_DATA(SVGSetElement, nsElementSH,
|
||||||
ELEMENT_SCRIPTABLE_FLAGS)
|
ELEMENT_SCRIPTABLE_FLAGS)
|
||||||
#endif // MOZ_SMIL
|
#endif // MOZ_SMIL
|
||||||
|
@ -2771,6 +2774,14 @@ nsDOMClassInfo::Init()
|
||||||
DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
|
DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
|
||||||
DOM_CLASSINFO_MAP_END
|
DOM_CLASSINFO_MAP_END
|
||||||
|
|
||||||
|
DOM_CLASSINFO_MAP_BEGIN(SVGAnimateTransformElement,
|
||||||
|
nsIDOMSVGAnimateTransformElement)
|
||||||
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimationElement)
|
||||||
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimateTransformElement)
|
||||||
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMElementTimeControl)
|
||||||
|
DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
|
||||||
|
DOM_CLASSINFO_MAP_END
|
||||||
|
|
||||||
DOM_CLASSINFO_MAP_BEGIN(SVGSetElement,
|
DOM_CLASSINFO_MAP_BEGIN(SVGSetElement,
|
||||||
nsIDOMSVGSetElement)
|
nsIDOMSVGSetElement)
|
||||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimationElement)
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimationElement)
|
||||||
|
|
|
@ -19,6 +19,9 @@ include sort/reftest.list
|
||||||
# style tests
|
# style tests
|
||||||
include style/reftest.list
|
include style/reftest.list
|
||||||
|
|
||||||
|
# animateTransform tests
|
||||||
|
include transform/reftest.list
|
||||||
|
|
||||||
# time-dependent tests
|
# time-dependent tests
|
||||||
# XXXdholbert Disabling this class of tests for now, because most of them
|
# XXXdholbert Disabling this class of tests for now, because most of them
|
||||||
# can & should be converted so they don't depend on specific timeout values.
|
# can & should be converted so they don't depend on specific timeout values.
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g transform="translate(50 50)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(150 50)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(250 50)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(50 150)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(150 150)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(250 150)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(50 250)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(150 250)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(250 250)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(50 350)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
После Ширина: | Высота: | Размер: 1.3 KiB |
|
@ -0,0 +1,209 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="reftest-wait"
|
||||||
|
onload="setupSnapshot(1.5)">
|
||||||
|
<script type="text/ecmascript"><![CDATA[
|
||||||
|
function setupSnapshot(timeInSeconds) {
|
||||||
|
var svg = document.documentElement;
|
||||||
|
svg.pauseAnimations();
|
||||||
|
svg.setCurrentTime(timeInSeconds);
|
||||||
|
// Use setTimeout to allow SMIL to update the animation before we check
|
||||||
|
// the values and take a snapshot
|
||||||
|
setTimeout('checkAnimVals()');
|
||||||
|
}
|
||||||
|
function checkAnimVals() {
|
||||||
|
var svg = document.documentElement;
|
||||||
|
var paths = svg.getElementsByTagName("path");
|
||||||
|
for (var i = 0; i < paths.length; i++) {
|
||||||
|
var path = paths[i];
|
||||||
|
checkAnimVal(path, path.transform.animVal, i);
|
||||||
|
}
|
||||||
|
svg.removeAttribute("class");
|
||||||
|
}
|
||||||
|
function Transform(type, angle) {
|
||||||
|
this.type = type;
|
||||||
|
this.angle = angle;
|
||||||
|
}
|
||||||
|
function checkAnimVal(path, val, index) {
|
||||||
|
var expected = [];
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_ROTATE, 90));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_ROTATE, 90));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_ROTATE, -90));
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_ROTATE, 180));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_ROTATE, 45));
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_ROTATE, 45));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_TRANSLATE, 0));
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_ROTATE, 90));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_ROTATE, -90));
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_ROTATE, 90));
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_ROTATE, 90));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_TRANSLATE, 0));
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_ROTATE, 45));
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_ROTATE, 45));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7:
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_SKEWX, 20));
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_TRANSLATE, 0));
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_ROTATE, 45));
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_ROTATE, 45));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_SKEWX, 20));
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_TRANSLATE, 0));
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_ROTATE, 45));
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_TRANSLATE, 0));
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_TRANSLATE, 0));
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_ROTATE, 45));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 9:
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_ROTATE, 90));
|
||||||
|
expected.push(new Transform(SVGTransform.SVG_TRANSFORM_TRANSLATE, 0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok = true;
|
||||||
|
if (val.numberOfItems == expected.length) {
|
||||||
|
for (var i = 0; i < val.numberOfItems; i++) {
|
||||||
|
var transform = val.getItem(i);
|
||||||
|
if (transform.type != expected[i].type ||
|
||||||
|
transform.angle != expected[i].angle) {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
path.style.visibility = 'hidden';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]]></script>
|
||||||
|
<!-- not additive -->
|
||||||
|
<g transform="translate(50 50)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(-90)">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="90" dur="1s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<!-- to-animation: special additive -->
|
||||||
|
<g transform="translate(150 50)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(-90)">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" to="90" dur="1s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<!-- by-animation: special additive -->
|
||||||
|
<g transform="translate(250 50)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(-90)">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" by="180" dur="1s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<!-- normal additive: same type -->
|
||||||
|
<g transform="translate(50 150)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(45)">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="45" dur="1s" fill="freeze"
|
||||||
|
additive="sum"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<!-- normal additive: different type -->
|
||||||
|
<g transform="translate(100 150)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="translate(50)">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="90" dur="1s" fill="freeze"
|
||||||
|
additive="sum"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<!-- stacked additive: same type -->
|
||||||
|
<g transform="translate(250 150)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(-90)">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="90" dur="1s" fill="freeze"
|
||||||
|
additive="sum"/>
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="90" dur="1s" fill="freeze"
|
||||||
|
additive="sum"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<!-- stacked additive: different types #1 -->
|
||||||
|
<g transform="translate(0 250)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="translate(50)">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="45" dur="1s" fill="freeze"
|
||||||
|
additive="sum"/>
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="45" dur="1s" fill="freeze"
|
||||||
|
additive="sum"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<!-- stacked additive: different types #2 -->
|
||||||
|
<g transform="translate(100 250) skewX(-20)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="skewX(20) translate(50)">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="45" dur="1s" fill="freeze"
|
||||||
|
additive="sum"/>
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="45" dur="1s" fill="freeze"
|
||||||
|
additive="sum"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<!-- stacked additive: different types #3 -->
|
||||||
|
<g transform="translate(200 250) skewX(-20)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="skewX(20) translate(50)">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="45" dur="1s" fill="freeze"
|
||||||
|
additive="sum"/>
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="translate" from="0" to="30" dur="1s" fill="freeze"
|
||||||
|
additive="sum"/>
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="translate" from="0" to="-30" dur="1s" fill="freeze"
|
||||||
|
additive="sum"/>
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="45" dur="1s" fill="freeze"
|
||||||
|
additive="sum"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<!-- base value with rotation around a centre -->
|
||||||
|
<g transform="translate(-50 300)">
|
||||||
|
<path d="M48 100h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90 50 50)">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="translate" from="0 0" to="0 -50" dur="1s" fill="freeze"
|
||||||
|
additive="sum"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
После Ширина: | Высота: | Размер: 7.6 KiB |
|
@ -0,0 +1,31 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<defs>
|
||||||
|
<g id="smiley">
|
||||||
|
<circle fill="yellow" stroke="black" stroke-width="2" cx="0" cy="0"
|
||||||
|
r="40"/>
|
||||||
|
<circle fill="white" stroke="black" stroke-width="1" cx="-14" cy="-14"
|
||||||
|
r="14"/>
|
||||||
|
<circle fill="white" stroke="black" stroke-width="1" cx="14" cy="-14"
|
||||||
|
r="14"/>
|
||||||
|
<circle cx="-10" cy="-14" r="4"/>
|
||||||
|
<circle cx="10" cy="-14" r="4"/>
|
||||||
|
<path d="m-11 14a13,13 0 0,0 22,0" fill="none" stroke="black"/>
|
||||||
|
</g>
|
||||||
|
</defs>
|
||||||
|
<g transform="translate(50 50)">
|
||||||
|
<use xlink:href="#smiley"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(150 50)">
|
||||||
|
<use xlink:href="#smiley"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(250 50)">
|
||||||
|
<use xlink:href="#smiley"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(50 150)">
|
||||||
|
<use xlink:href="#smiley"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(150 150)">
|
||||||
|
<use xlink:href="#smiley"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
После Ширина: | Высота: | Размер: 946 B |
|
@ -0,0 +1,64 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
class="reftest-wait"
|
||||||
|
onload="setTimeAndSnapshot(1, true)">
|
||||||
|
<script xlink:href="../smil-util.js" type="text/javascript"/>
|
||||||
|
<defs>
|
||||||
|
<g id="smiley">
|
||||||
|
<circle fill="yellow" stroke="black" stroke-width="2" cx="0" cy="0"
|
||||||
|
r="40"/>
|
||||||
|
<circle fill="white" stroke="black" stroke-width="1" cx="-14" cy="-14"
|
||||||
|
r="14"/>
|
||||||
|
<circle fill="white" stroke="black" stroke-width="1" cx="14" cy="-14"
|
||||||
|
r="14"/>
|
||||||
|
<circle cx="-10" cy="-14" r="4"/>
|
||||||
|
<circle cx="10" cy="-14" r="4"/>
|
||||||
|
<path d="m-11 14a13,13 0 0,0 22,0" fill="none" stroke="black"/>
|
||||||
|
</g>
|
||||||
|
</defs>
|
||||||
|
<!-- translation -->
|
||||||
|
<g transform="translate(0 50)">
|
||||||
|
<use xlink:href="#smiley">
|
||||||
|
<animateTransform attributeName="transform" attributeType="XML"
|
||||||
|
type="translate" fill="freeze" dur="2s" calcMode="paced"
|
||||||
|
values="-5 -10; 35 20; 95 -60"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
<!-- rotation -->
|
||||||
|
<g transform="translate(150 50) rotate(-90)">
|
||||||
|
<use xlink:href="#smiley">
|
||||||
|
<animateTransform attributeName="transform" attributeType="XML"
|
||||||
|
type="rotate" fill="freeze" dur="2s" calcMode="paced"
|
||||||
|
values="20 10 10; 40 -15 25; 160 21 -35"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
<!-- skewY -->
|
||||||
|
<g transform="translate(250 50) skewY(-30)">
|
||||||
|
<use xlink:href="#smiley">
|
||||||
|
<animateTransform attributeName="transform" attributeType="XML"
|
||||||
|
type="skewY" fill="freeze" dur="2s" calcMode="paced"
|
||||||
|
values="10; 40; 50"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
<!-- scale -->
|
||||||
|
<g transform="translate(50 150) scale(0.5)">
|
||||||
|
<use xlink:href="#smiley">
|
||||||
|
<animateTransform attributeName="transform" attributeType="XML"
|
||||||
|
type="scale" fill="freeze" dur="2s" calcMode="paced"
|
||||||
|
values="-4 -2.5; 4 3.5; 8 0.5"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
<!-- to-animation
|
||||||
|
|
||||||
|
You can't have to-animation with a paced calcMode. This test should just
|
||||||
|
produce regular to-animation without any assertions. This is a white-box
|
||||||
|
test.
|
||||||
|
-->
|
||||||
|
<g transform="translate(100 150)">
|
||||||
|
<use xlink:href="#smiley">
|
||||||
|
<animateTransform attributeName="transform" attributeType="XML"
|
||||||
|
type="translate" fill="freeze" dur="2s" calcMode="paced"
|
||||||
|
to="100"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
</svg>
|
После Ширина: | Высота: | Размер: 2.2 KiB |
|
@ -0,0 +1,12 @@
|
||||||
|
# Tests related to SVG Animation (using SMIL), focusing on the animateTransform
|
||||||
|
# element.
|
||||||
|
|
||||||
|
== rotate-angle-1.svg rotate-angle-ref.svg
|
||||||
|
== rotate-angle-2.svg rotate-angle-ref.svg
|
||||||
|
== rotate-angle-3.svg rotate-angle-ref.svg
|
||||||
|
== rotate-angle-4.svg rotate-angle-ref.svg
|
||||||
|
== rotate-angle-5.svg rotate-angle-ref.svg
|
||||||
|
== scale-1.svg scale-1-ref.svg
|
||||||
|
== skew-1.svg skew-1-ref.svg
|
||||||
|
== paced-1.svg paced-1-ref.svg
|
||||||
|
== additive-1.svg additive-1-ref.svg
|
|
@ -0,0 +1,60 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
class="reftest-wait"
|
||||||
|
onload="setTimeAndSnapshot(1, true)">
|
||||||
|
<script xlink:href="../smil-util.js" type="text/javascript"/>
|
||||||
|
<g transform="translate(50 50) rotate(90)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="0" dur="4s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(150 50)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="90" dur="1s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(250 50)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="180" dur="2s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(50 150)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="270" dur="3s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(150 150)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="360" dur="4s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(250 150)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="540" dur="6s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(50 250)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="3600" dur="40s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(150 250)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="-270" dur="1s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(250 250)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="-540" dur="2s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
После Ширина: | Высота: | Размер: 2.3 KiB |
|
@ -0,0 +1,60 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
class="reftest-wait"
|
||||||
|
onload="setTimeAndSnapshot(1, true)">
|
||||||
|
<script xlink:href="../smil-util.js" type="text/javascript"/>
|
||||||
|
<g transform="translate(44 0) rotate(90 6 50)">
|
||||||
|
<path d="M4 100h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0 6 50" to="0 6 50" dur="4s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(144 0)">
|
||||||
|
<path d="M4 100h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0,6,50" to="90 6 50" dur="1s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(244,0)">
|
||||||
|
<path d="M4 100h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0 6 50" to="180,6,50" dur="2s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(44,100)">
|
||||||
|
<path d="M4 100h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0,6,50" to="270,6,50" dur="3s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(144,100)">
|
||||||
|
<path d="M4 100h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0 6 50" to="360 6 50" dur="4s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(244,100)">
|
||||||
|
<path d="M4 100h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0 6 50" to="540 6 50" dur="6s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(44,200)">
|
||||||
|
<path d="M4 100h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0 6 50" to="3600 6 50" dur="40s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(144,200)">
|
||||||
|
<path d="M4 100h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0 6 50" to="-270 6 50" dur="1s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(244,200)">
|
||||||
|
<path d="M4 100h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0 6 50" to="-540 6 50" dur="2s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
После Ширина: | Высота: | Размер: 2.3 KiB |
|
@ -0,0 +1,60 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
class="reftest-wait"
|
||||||
|
onload="setTimeAndSnapshot(1, true)">
|
||||||
|
<script xlink:href="../smil-util.js" type="text/javascript"/>
|
||||||
|
<g transform="translate(0 0) rotate(90 50 50)">
|
||||||
|
<path d="M48 100h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0 0 50" to="0 200 50" dur="4s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(100 0)">
|
||||||
|
<path d="M48 100h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0 0 50" to="90 50 50" dur="1s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(200 0)">
|
||||||
|
<path d="M48 100h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0 0 50" to="180 100 50" dur="2s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(0 100)">
|
||||||
|
<path d="M48 100h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0 0 50" to="270 150 50" dur="3s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(100 100)">
|
||||||
|
<path d="M48 100h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0 0 50" to="360 200 50" dur="4s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(200 100)">
|
||||||
|
<path d="M48 100h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0 0 50" to="540 300 50" dur="6s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(0 200)">
|
||||||
|
<path d="M48 100h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0 0 50" to="3600 2000 50" dur="40s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(100 200)">
|
||||||
|
<path d="M48 100h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0 0 50" to="-270 50 50" dur="1s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(200 200)">
|
||||||
|
<path d="M48 100h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0 0 50" to="-540 100 50" dur="2s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
После Ширина: | Высота: | Размер: 2.4 KiB |
|
@ -0,0 +1,79 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
class="reftest-wait"
|
||||||
|
onload="setTimeAndSnapshot(1, true)">
|
||||||
|
<script xlink:href="../smil-util.js" type="text/javascript"/>
|
||||||
|
<!-- no animation -->
|
||||||
|
<g transform="translate(50 50) rotate(90)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"/>
|
||||||
|
</g>
|
||||||
|
<!-- accumulate: sum -->
|
||||||
|
<g transform="translate(150 50)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="45" dur="0.5s" fill="freeze"
|
||||||
|
repeatCount="4" accumulate="sum"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<!-- accumulate: none -->
|
||||||
|
<g transform="translate(250 50)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="270" dur="0.75s" fill="freeze"
|
||||||
|
repeatCount="2"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<!-- additive: replace -->
|
||||||
|
<g transform="translate(50 150)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(-90)">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="180" dur="2s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<!-- additive: sum (adding to base value) -->
|
||||||
|
<g transform="translate(150 150)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(-90)">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="270" dur="1.5s" fill="freeze"
|
||||||
|
additive="sum"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<!-- additive: sum (adding to other animations) -->
|
||||||
|
<g transform="translate(250 150)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="60" dur="2s" fill="freeze"/>
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="60" dur="2s" fill="freeze"
|
||||||
|
additive="sum"/>
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="60" dur="2s" fill="freeze"
|
||||||
|
additive="sum"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<!-- to animation -->
|
||||||
|
<g transform="translate(50 250)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(45)">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" to="135" dur="2s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<!-- by animation -->
|
||||||
|
<g transform="translate(150 250)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(45)">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" by="90" dur="2s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<!-- values animation -->
|
||||||
|
<g transform="translate(250 250)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" values="0; 135; 0" dur="1.5s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
После Ширина: | Высота: | Размер: 2.9 KiB |
|
@ -0,0 +1,86 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
class="reftest-wait"
|
||||||
|
onload="setTimeAndSnapshot(1, true)">
|
||||||
|
<script xlink:href="../smil-util.js" type="text/javascript"/>
|
||||||
|
<!-- Tests to-animation behaviour for a lot of undefined situations.
|
||||||
|
SVG 1.1 doesn't define what should happen here but the behaviour we
|
||||||
|
expect is based on other browsers. -->
|
||||||
|
<!-- to animation: rotation from base value -90 to final value 180 -->
|
||||||
|
<g transform="translate(50 50)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(-90)">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" to="180" dur="1.5s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<!-- to animation: rotation from base value -810 to final value 990 -->
|
||||||
|
<g transform="translate(150 50)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(-810)">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" to="990" dur="2s" fill="freeze"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<!-- to animation: rotation from base value -180 to final value 90 but with
|
||||||
|
other animations combined.
|
||||||
|
|
||||||
|
What happens here is that the rotation animation can't interpolate from
|
||||||
|
the base value as it's not a rotation transformation, so instead it
|
||||||
|
assumes an underlying zero matrix as the base value. (see next comment)
|
||||||
|
-->
|
||||||
|
<g transform="translate(250 50)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(-90) translate(0 50) scale(2)">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" to="180" dur="2s" fill="freeze" additive="sum"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<!-- to animation: rotate and scale
|
||||||
|
|
||||||
|
Here again the scale animation can't interpolate from its base value
|
||||||
|
which is of a different type so it assumes a zero matrix NOT an identity
|
||||||
|
matrix (this is what the SVG WG have decided in the SVGT1.2 Tiny test
|
||||||
|
suite).
|
||||||
|
-->
|
||||||
|
<g transform="translate(50 150) rotate(90)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="scale(2)">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" to="180" dur="1s" fill="freeze" additive="sum"/>
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="scale" to="2" dur="2s" fill="freeze" additive="sum"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<!-- to animation: translate and rotate
|
||||||
|
|
||||||
|
Likewise here we end up rotating from 0 to 180 because we can't
|
||||||
|
interpolate from the underlying translation transformation.
|
||||||
|
-->
|
||||||
|
<g transform="translate(150 150)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(-90) translate(0 50) scale(2)">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="translate" to="0" dur="1s" fill="freeze" additive="sum"/>
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" to="180" dur="2s" fill="freeze" additive="sum"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
<!-- The following are from the reference image -->
|
||||||
|
<g transform="translate(250 150)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(50 250)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(150 250)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(250 250)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
После Ширина: | Высота: | Размер: 3.5 KiB |
|
@ -0,0 +1,38 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g transform="translate(50 50)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(150 50)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(250 50)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(50 150)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(150 150)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(250 150)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(50 250)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(150 250)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(250 250)">
|
||||||
|
<path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue"
|
||||||
|
transform="rotate(90)"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
После Ширина: | Высота: | Размер: 1.2 KiB |
|
@ -0,0 +1,38 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="grad">
|
||||||
|
<stop offset="5%" stop-color="#F66"/>
|
||||||
|
<stop offset="95%" stop-color="#FF6"/>
|
||||||
|
</linearGradient>
|
||||||
|
<circle fill="url(#grad)" stroke="black" stroke-width="1" cx="0" cy="0"
|
||||||
|
r="20" id="circle"/>
|
||||||
|
</defs>
|
||||||
|
<g transform="translate(50 50)">
|
||||||
|
<use xlink:href="#circle" transform="scale(2)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(150 50)">
|
||||||
|
<use xlink:href="#circle" transform="scale(2)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(250 50)">
|
||||||
|
<use xlink:href="#circle" transform="scale(2)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(50 150)">
|
||||||
|
<use xlink:href="#circle" transform="scale(2)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(150 150)">
|
||||||
|
<use xlink:href="#circle" transform="scale(2)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(250 150)">
|
||||||
|
<use xlink:href="#circle" transform="scale(2)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(50 250)">
|
||||||
|
<use xlink:href="#circle" transform="scale(2)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(150 250)">
|
||||||
|
<use xlink:href="#circle" transform="scale(2)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(250 250)">
|
||||||
|
<use xlink:href="#circle" transform="scale(2)"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
После Ширина: | Высота: | Размер: 1.2 KiB |
|
@ -0,0 +1,108 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
class="reftest-wait"
|
||||||
|
onload="setTimeAndSnapshot(1, true)">
|
||||||
|
<script xlink:href="../smil-util.js" type="text/javascript"/>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="grad">
|
||||||
|
<stop offset="5%" stop-color="#F66"/>
|
||||||
|
<stop offset="95%" stop-color="#FF6"/>
|
||||||
|
</linearGradient>
|
||||||
|
<circle fill="url(#grad)" stroke="black" stroke-width="1" cx="0" cy="0"
|
||||||
|
r="20" id="circle"/>
|
||||||
|
</defs>
|
||||||
|
<!-- to animation
|
||||||
|
|
||||||
|
This should interpolate from 0 (not 1) to 4 to match the behaviour
|
||||||
|
required by the SVGT1.2 test suite and Opera's behaviour.
|
||||||
|
-->
|
||||||
|
<g transform="translate(50 50)">
|
||||||
|
<use xlink:href="#circle">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="scale" to="4" dur="2s" fill="freeze"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
<!-- from-to animation -->
|
||||||
|
<g transform="translate(150 50)">
|
||||||
|
<use xlink:href="#circle">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="scale" from="-5" to="9" dur="2s" fill="freeze"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
<!-- negative to-animation
|
||||||
|
|
||||||
|
Should go from 0 to -4 over 2s, therefore at t=1s, the scale factor
|
||||||
|
should be -2, so we add a rotation animation to correct the gradient
|
||||||
|
-->
|
||||||
|
<g transform="translate(250 50)">
|
||||||
|
<use xlink:href="#circle">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="scale" to="-4" dur="2s" fill="freeze"/>
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="rotate" from="0" to="360" dur="2s" fill="freeze" additive="sum"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
<!-- by animation
|
||||||
|
|
||||||
|
The behaviour at this point is not clear. The definition of by-animation
|
||||||
|
is:
|
||||||
|
|
||||||
|
"simple animation in which the animation function is defined to offset
|
||||||
|
the underlying value for the attribute, using a delta that varies over
|
||||||
|
the course of the simple duration, starting from a delta of 0 and ending
|
||||||
|
with the delta specified with the by attribute." (SMILANIM 3.2.2)
|
||||||
|
|
||||||
|
Therefore it might seem like by-animation of by="1" means to ADD to the
|
||||||
|
underlying scale factor. Furthermore, the underlying scale factor when
|
||||||
|
not otherwise specified might seemt to be 1, but the SVG WG have decided
|
||||||
|
it's 0. This is inconsistent with the definition of addition for
|
||||||
|
animateTransform (post-multiplication of matrices) but it is the
|
||||||
|
behaviour required by SVGT1.2 test suite and used by Opera.
|
||||||
|
|
||||||
|
The following animation should go from 0 to 4, over 2s so at t=1s, the
|
||||||
|
scale factor should be 2.
|
||||||
|
-->
|
||||||
|
<g transform="translate(50 150)">
|
||||||
|
<use xlink:href="#circle">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="scale" by="4" dur="2s" fill="freeze"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
<!-- by animation #2 -->
|
||||||
|
<g transform="translate(150 150)">
|
||||||
|
<use xlink:href="#circle" transform="scale(4)">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="scale" by="1" dur="2s" fill="freeze" additive="sum"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
<!-- from-by animation -->
|
||||||
|
<g transform="translate(250 150)">
|
||||||
|
<use xlink:href="#circle">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="scale" from="2" by="0" dur="2s" fill="freeze"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
<!-- values animation -->
|
||||||
|
<g transform="translate(50 250)">
|
||||||
|
<use xlink:href="#circle">
|
||||||
|
<animateTransform attributeName="transform"
|
||||||
|
type="scale" values="0; 10; 2; 5; -1" dur="2s" fill="freeze"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
<!-- repetition -->
|
||||||
|
<g transform="translate(150 250)">
|
||||||
|
<use xlink:href="#circle">
|
||||||
|
<animateTransform attributeName="transform" type="scale" from="0"
|
||||||
|
to="0.6" dur="0.3s" repeatCount="4" accumulate="sum"
|
||||||
|
fill="freeze"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
<!-- repeated to-animation (should NOT accumulate) -->
|
||||||
|
<g transform="translate(250 250)">
|
||||||
|
<use xlink:href="#circle">
|
||||||
|
<animateTransform attributeName="transform" type="scale"
|
||||||
|
to="6" dur="0.75" repeatCount="2" accumulate="sum"
|
||||||
|
fill="freeze"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
</svg>
|
После Ширина: | Высота: | Размер: 3.9 KiB |
|
@ -0,0 +1,43 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<defs>
|
||||||
|
<g id="smiley">
|
||||||
|
<circle fill="yellow" stroke="black" stroke-width="2" cx="0" cy="0"
|
||||||
|
r="40"/>
|
||||||
|
<circle fill="white" stroke="black" stroke-width="1" cx="-14" cy="-14"
|
||||||
|
r="14"/>
|
||||||
|
<circle fill="white" stroke="black" stroke-width="1" cx="14" cy="-14"
|
||||||
|
r="14"/>
|
||||||
|
<circle cx="-10" cy="-14" r="4"/>
|
||||||
|
<circle cx="10" cy="-14" r="4"/>
|
||||||
|
<path d="m-11 14a13,13 0 0,0 22,0" fill="none" stroke="black"/>
|
||||||
|
</g>
|
||||||
|
</defs>
|
||||||
|
<g transform="translate(50 50)">
|
||||||
|
<use xlink:href="#smiley" transform="skewX(30)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(150 50)">
|
||||||
|
<use xlink:href="#smiley" transform="skewX(30)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(250 50)">
|
||||||
|
<use xlink:href="#smiley" transform="skewX(30)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(50 150)">
|
||||||
|
<use xlink:href="#smiley" transform="skewX(30)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(150 150)">
|
||||||
|
<use xlink:href="#smiley" transform="skewX(30)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(250 150)">
|
||||||
|
<use xlink:href="#smiley" transform="skewX(30)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(50 250)">
|
||||||
|
<use xlink:href="#smiley" transform="skewX(30)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(150 250)">
|
||||||
|
<use xlink:href="#smiley" transform="skewX(30)"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(250 250)">
|
||||||
|
<use xlink:href="#smiley" transform="skewX(30)"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
После Ширина: | Высота: | Размер: 1.4 KiB |
|
@ -0,0 +1,86 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
class="reftest-wait"
|
||||||
|
onload="setTimeAndSnapshot(1, true)">
|
||||||
|
<script xlink:href="../smil-util.js" type="text/javascript"/>
|
||||||
|
<defs>
|
||||||
|
<g id="smiley">
|
||||||
|
<circle fill="yellow" stroke="black" stroke-width="2" cx="0" cy="0"
|
||||||
|
r="40"/>
|
||||||
|
<circle fill="white" stroke="black" stroke-width="1" cx="-14" cy="-14"
|
||||||
|
r="14"/>
|
||||||
|
<circle fill="white" stroke="black" stroke-width="1" cx="14" cy="-14"
|
||||||
|
r="14"/>
|
||||||
|
<circle cx="-10" cy="-14" r="4"/>
|
||||||
|
<circle cx="10" cy="-14" r="4"/>
|
||||||
|
<path d="m-11 14a13,13 0 0,0 22,0" fill="none" stroke="black"/>
|
||||||
|
</g>
|
||||||
|
</defs>
|
||||||
|
<!-- from-to animation -->
|
||||||
|
<g transform="translate(50 50)">
|
||||||
|
<use xlink:href="#smiley">
|
||||||
|
<animateTransform attributeName="transform" attributeType="XML"
|
||||||
|
type="skewX" fill="freeze" from="-30" to="90" dur="2s"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
<!-- from-by animation -->
|
||||||
|
<g transform="translate(150 50)">
|
||||||
|
<use xlink:href="#smiley">
|
||||||
|
<animateTransform attributeName="transform" attributeType="XML"
|
||||||
|
type="skewX" fill="freeze" from="60" by="-60" dur="2s"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
<!-- by animation -->
|
||||||
|
<g transform="translate(250 50) skewX(-15)">
|
||||||
|
<use xlink:href="#smiley" transform="skewX(15)">
|
||||||
|
<animateTransform attributeName="transform" attributeType="XML"
|
||||||
|
type="skewX" fill="freeze" by="60" dur="2s"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
<!-- to animation -->
|
||||||
|
<g transform="translate(50 150)">
|
||||||
|
<use xlink:href="#smiley" transform="skewX(15)">
|
||||||
|
<animateTransform attributeName="transform" attributeType="XML"
|
||||||
|
type="skewX" fill="freeze" to="45" dur="2s"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
<!-- values animation -->
|
||||||
|
<g transform="translate(150 150)">
|
||||||
|
<use xlink:href="#smiley">
|
||||||
|
<animateTransform attributeName="transform" attributeType="XML"
|
||||||
|
type="skewX" fill="freeze" values="10; 40; 20; 60" dur="2s"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
<!-- additive -->
|
||||||
|
<g transform="translate(250 150)">
|
||||||
|
<use xlink:href="#smiley" transform="skewY(-30)">
|
||||||
|
<animateTransform attributeName="transform" attributeType="XML"
|
||||||
|
type="skewY" fill="freeze" to="30" dur="2s"/>
|
||||||
|
<animateTransform attributeName="transform" attributeType="XML"
|
||||||
|
type="skewX" fill="freeze" from="-30" to="90" dur="2s" additive="sum"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
<!-- accumulate: none -->
|
||||||
|
<g transform="translate(50 250)">
|
||||||
|
<use xlink:href="#smiley">
|
||||||
|
<animateTransform attributeName="transform" attributeType="XML"
|
||||||
|
type="skewX" fill="freeze" from="20" to="50" dur="0.75s"
|
||||||
|
repeatCount="3"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
<!-- accumulate: sum -->
|
||||||
|
<g transform="translate(150 250)">
|
||||||
|
<use xlink:href="#smiley">
|
||||||
|
<animateTransform attributeName="transform" attributeType="XML"
|
||||||
|
type="skewX" fill="freeze" from="0" to="22.5" dur="0.75"
|
||||||
|
accumulate="sum" repeatCount="3"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
<!-- angles > 360 -->
|
||||||
|
<g transform="translate(250 250)">
|
||||||
|
<use xlink:href="#smiley">
|
||||||
|
<animateTransform attributeName="transform" attributeType="XML"
|
||||||
|
type="skewX" fill="freeze" from="-690" to="750" dur="2s"/>
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
</svg>
|
После Ширина: | Высота: | Размер: 3.1 KiB |