mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Bug 602759 part 7 - Refactor nsSVGAnimatedTransformList into SVGAnimatedTransformList and DOMSVGAnimatedTransformList and incorporate nsSVGTransformSMILAttr; r=jwatt
--HG-- rename : content/svg/content/src/nsSVGAnimatedTransformList.cpp => content/svg/content/src/DOMSVGAnimatedTransformList.cpp rename : content/svg/content/src/nsSVGAnimatedTransformList.h => content/svg/content/src/DOMSVGAnimatedTransformList.h
This commit is contained in:
parent
722c1262b1
commit
bdc7e4ee3e
176
content/svg/content/src/DOMSVGAnimatedTransformList.cpp
Normal file
176
content/svg/content/src/DOMSVGAnimatedTransformList.cpp
Normal file
@ -0,0 +1,176 @@
|
||||
/* -*- 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
|
||||
* Crocodile Clips Ltd..
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Alex Fritze <alex.fritze@crocodile-clips.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "DOMSVGAnimatedTransformList.h"
|
||||
#include "DOMSVGTransformList.h"
|
||||
#include "SVGAnimatedTransformList.h"
|
||||
#include "nsSVGAttrTearoffTable.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
static
|
||||
nsSVGAttrTearoffTable<SVGAnimatedTransformList,DOMSVGAnimatedTransformList>
|
||||
sSVGAnimatedTransformListTearoffTable;
|
||||
|
||||
NS_SVG_VAL_IMPL_CYCLE_COLLECTION(DOMSVGAnimatedTransformList, mElement)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMSVGAnimatedTransformList)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMSVGAnimatedTransformList)
|
||||
|
||||
} // namespace mozilla
|
||||
DOMCI_DATA(SVGAnimatedTransformList, mozilla::DOMSVGAnimatedTransformList)
|
||||
namespace mozilla {
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMSVGAnimatedTransformList)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimatedTransformList)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAnimatedTransformList)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIDOMSVGAnimatedTransformList methods:
|
||||
|
||||
/* readonly attribute nsIDOMSVGTransformList baseVal; */
|
||||
NS_IMETHODIMP
|
||||
DOMSVGAnimatedTransformList::GetBaseVal(nsIDOMSVGTransformList** aBaseVal)
|
||||
{
|
||||
if (!mBaseVal) {
|
||||
mBaseVal = new DOMSVGTransformList(this, InternalAList().GetBaseValue());
|
||||
}
|
||||
NS_ADDREF(*aBaseVal = mBaseVal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIDOMSVGTransformList animVal; */
|
||||
NS_IMETHODIMP
|
||||
DOMSVGAnimatedTransformList::GetAnimVal(nsIDOMSVGTransformList** aAnimVal)
|
||||
{
|
||||
if (!mAnimVal) {
|
||||
mAnimVal = new DOMSVGTransformList(this, InternalAList().GetAnimValue());
|
||||
}
|
||||
NS_ADDREF(*aAnimVal = mAnimVal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<DOMSVGAnimatedTransformList>
|
||||
DOMSVGAnimatedTransformList::GetDOMWrapper(SVGAnimatedTransformList *aList,
|
||||
nsSVGElement *aElement)
|
||||
{
|
||||
DOMSVGAnimatedTransformList *wrapper =
|
||||
sSVGAnimatedTransformListTearoffTable.GetTearoff(aList);
|
||||
if (!wrapper) {
|
||||
wrapper = new DOMSVGAnimatedTransformList(aElement);
|
||||
sSVGAnimatedTransformListTearoffTable.AddTearoff(aList, wrapper);
|
||||
}
|
||||
NS_ADDREF(wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/* static */ DOMSVGAnimatedTransformList*
|
||||
DOMSVGAnimatedTransformList::GetDOMWrapperIfExists(
|
||||
SVGAnimatedTransformList *aList)
|
||||
{
|
||||
return sSVGAnimatedTransformListTearoffTable.GetTearoff(aList);
|
||||
}
|
||||
|
||||
DOMSVGAnimatedTransformList::~DOMSVGAnimatedTransformList()
|
||||
{
|
||||
// Script no longer has any references to us, to our base/animVal objects, or
|
||||
// to any of their list items.
|
||||
sSVGAnimatedTransformListTearoffTable.RemoveTearoff(&InternalAList());
|
||||
}
|
||||
|
||||
void
|
||||
DOMSVGAnimatedTransformList::InternalBaseValListWillChangeLengthTo(
|
||||
PRUint32 aNewLength)
|
||||
{
|
||||
// When the number of items in our internal counterpart's baseVal changes,
|
||||
// we MUST keep our baseVal in sync. If we don't, script will either see a
|
||||
// list that is too short and be unable to access indexes that should be
|
||||
// valid, or else, MUCH WORSE, script will see a list that is too long and be
|
||||
// able to access "items" at indexes that are out of bounds (read/write to
|
||||
// bad memory)!!
|
||||
|
||||
nsRefPtr<DOMSVGAnimatedTransformList> kungFuDeathGrip;
|
||||
if (mBaseVal) {
|
||||
if (aNewLength < mBaseVal->Length()) {
|
||||
// InternalListLengthWillChange might clear last reference to |this|.
|
||||
// Retain a temporary reference to keep from dying before returning.
|
||||
kungFuDeathGrip = this;
|
||||
}
|
||||
mBaseVal->InternalListLengthWillChange(aNewLength);
|
||||
}
|
||||
|
||||
// If our attribute is not animating, then our animVal mirrors our baseVal
|
||||
// and we must sync its length too. (If our attribute is animating, then the
|
||||
// SMIL engine takes care of calling InternalAnimValListWillChangeLengthTo()
|
||||
// if necessary.)
|
||||
|
||||
if (!IsAnimating()) {
|
||||
InternalAnimValListWillChangeLengthTo(aNewLength);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DOMSVGAnimatedTransformList::InternalAnimValListWillChangeLengthTo(
|
||||
PRUint32 aNewLength)
|
||||
{
|
||||
if (mAnimVal) {
|
||||
mAnimVal->InternalListLengthWillChange(aNewLength);
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
DOMSVGAnimatedTransformList::IsAnimating() const
|
||||
{
|
||||
return InternalAList().IsAnimating();
|
||||
}
|
||||
|
||||
SVGAnimatedTransformList&
|
||||
DOMSVGAnimatedTransformList::InternalAList()
|
||||
{
|
||||
return *mElement->GetAnimatedTransformList();
|
||||
}
|
||||
|
||||
const SVGAnimatedTransformList&
|
||||
DOMSVGAnimatedTransformList::InternalAList() const
|
||||
{
|
||||
return *mElement->GetAnimatedTransformList();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
155
content/svg/content/src/DOMSVGAnimatedTransformList.h
Normal file
155
content/svg/content/src/DOMSVGAnimatedTransformList.h
Normal file
@ -0,0 +1,155 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Mozilla SVG project.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Crocodile Clips Ltd..
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Alex Fritze <alex.fritze@crocodile-clips.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef MOZILLA_DOMSVGANIMATEDTRANSFORMLIST_H__
|
||||
#define MOZILLA_DOMSVGANIMATEDTRANSFORMLIST_H__
|
||||
|
||||
#include "nsIDOMSVGAnimTransformList.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
class nsSVGElement;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class SVGAnimatedTransformList;
|
||||
class SVGTransformList;
|
||||
class DOMSVGTransformList;
|
||||
|
||||
/**
|
||||
* Class DOMSVGAnimatedTransformList
|
||||
*
|
||||
* This class is used to create the DOM tearoff objects that wrap internal
|
||||
* SVGAnimatedTransformList objects.
|
||||
*
|
||||
* See the architecture comment in DOMSVGAnimatedLengthList.h (that's
|
||||
* LENGTH list). The comment for that class largly applies to this one too
|
||||
* and will go a long way to helping you understand the architecture here.
|
||||
*
|
||||
* This class is strongly intertwined with DOMSVGTransformList and
|
||||
* DOMSVGTransform.
|
||||
* Our DOMSVGTransformList base and anim vals are friends and take care of
|
||||
* nulling out our pointers to them when they die (making our pointers to them
|
||||
* true weak refs).
|
||||
*/
|
||||
class DOMSVGAnimatedTransformList : public nsIDOMSVGAnimatedTransformList
|
||||
{
|
||||
friend class DOMSVGTransformList;
|
||||
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(DOMSVGAnimatedTransformList)
|
||||
NS_DECL_NSIDOMSVGANIMATEDTRANSFORMLIST
|
||||
|
||||
/**
|
||||
* Factory method to create and return a DOMSVGAnimatedTransformList wrapper
|
||||
* for a given internal SVGAnimatedTransformList object. The factory takes
|
||||
* care of caching the object that it returns so that the same object can be
|
||||
* returned for the given SVGAnimatedTransformList each time it is requested.
|
||||
* The cached object is only removed from the cache when it is destroyed due
|
||||
* to there being no more references to it or to any of its descendant
|
||||
* objects. If that happens, any subsequent call requesting the DOM wrapper
|
||||
* for the SVGAnimatedTransformList will naturally result in a new
|
||||
* DOMSVGAnimatedTransformList being returned.
|
||||
*/
|
||||
static already_AddRefed<DOMSVGAnimatedTransformList>
|
||||
GetDOMWrapper(SVGAnimatedTransformList *aList, nsSVGElement *aElement);
|
||||
|
||||
/**
|
||||
* This method returns the DOMSVGAnimatedTransformList wrapper for an internal
|
||||
* SVGAnimatedTransformList object if it currently has a wrapper. If it does
|
||||
* not, then nsnull is returned.
|
||||
*/
|
||||
static DOMSVGAnimatedTransformList*
|
||||
GetDOMWrapperIfExists(SVGAnimatedTransformList *aList);
|
||||
|
||||
/**
|
||||
* Called by internal code to notify us when we need to sync the length of
|
||||
* our baseVal DOM list with its internal list. This is called just prior to
|
||||
* the length of the internal baseVal list being changed so that any DOM list
|
||||
* items that need to be removed from the DOM list can first get their values
|
||||
* from their internal counterpart.
|
||||
*
|
||||
* The only time this method could fail is on OOM when trying to increase the
|
||||
* length of the DOM list. If that happens then this method simply clears the
|
||||
* list and returns. Callers just proceed as normal, and we simply accept
|
||||
* that the DOM list will be empty (until successfully set to a new value).
|
||||
*/
|
||||
void InternalBaseValListWillChangeLengthTo(PRUint32 aNewLength);
|
||||
void InternalAnimValListWillChangeLengthTo(PRUint32 aNewLength);
|
||||
|
||||
/**
|
||||
* Returns true if our attribute is animating (in which case our animVal is
|
||||
* not simply a mirror of our baseVal).
|
||||
*/
|
||||
PRBool IsAnimating() const;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Only our static GetDOMWrapper() factory method may create objects of our
|
||||
* type.
|
||||
*/
|
||||
DOMSVGAnimatedTransformList(nsSVGElement *aElement)
|
||||
: mBaseVal(nsnull)
|
||||
, mAnimVal(nsnull)
|
||||
, mElement(aElement)
|
||||
{}
|
||||
|
||||
~DOMSVGAnimatedTransformList();
|
||||
|
||||
/// Get a reference to this DOM wrapper object's internal counterpart.
|
||||
SVGAnimatedTransformList& InternalAList();
|
||||
const SVGAnimatedTransformList& InternalAList() const;
|
||||
|
||||
// Weak refs to our DOMSVGTransformList baseVal/animVal objects. These objects
|
||||
// are friends and take care of clearing these pointers when they die, making
|
||||
// these true weak references.
|
||||
DOMSVGTransformList *mBaseVal;
|
||||
DOMSVGTransformList *mAnimVal;
|
||||
|
||||
// Strong ref to our element to keep it alive. We hold this not only for
|
||||
// ourself, but also for our base/animVal and all of their items.
|
||||
nsRefPtr<nsSVGElement> mElement;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // MOZILLA_DOMSVGANIMATEDTRANSFORMLIST_H__
|
@ -51,6 +51,7 @@ LIBXUL_LIBRARY = 1
|
||||
CPPSRCS = \
|
||||
DOMSVGAnimatedLengthList.cpp \
|
||||
DOMSVGAnimatedNumberList.cpp \
|
||||
DOMSVGAnimatedTransformList.cpp \
|
||||
DOMSVGLength.cpp \
|
||||
DOMSVGLengthList.cpp \
|
||||
DOMSVGMatrix.cpp \
|
||||
@ -67,7 +68,6 @@ CPPSRCS = \
|
||||
nsSVGAElement.cpp \
|
||||
nsSVGAltGlyphElement.cpp \
|
||||
nsSVGAngle.cpp \
|
||||
nsSVGAnimatedTransformList.cpp \
|
||||
nsSVGBoolean.cpp \
|
||||
nsSVGCircleElement.cpp \
|
||||
nsSVGClass.cpp \
|
||||
@ -129,6 +129,7 @@ CPPSRCS = \
|
||||
SVGAnimatedPathSegList.cpp \
|
||||
SVGAnimatedPointList.cpp \
|
||||
SVGAnimatedPreserveAspectRatio.cpp \
|
||||
SVGAnimatedTransformList.cpp \
|
||||
SVGLength.cpp \
|
||||
SVGLengthList.cpp \
|
||||
SVGNumberList.cpp \
|
||||
@ -147,7 +148,6 @@ CPPSRCS += nsSVGAnimateElement.cpp \
|
||||
nsSVGMpathElement.cpp \
|
||||
nsSVGSetElement.cpp \
|
||||
nsSVGTransformSMILType.cpp \
|
||||
nsSVGTransformSMILAttr.cpp \
|
||||
SVGIntegerPairSMILType.cpp \
|
||||
SVGLengthListSMILType.cpp \
|
||||
SVGMotionSMILType.cpp \
|
||||
|
355
content/svg/content/src/SVGAnimatedTransformList.cpp
Normal file
355
content/svg/content/src/SVGAnimatedTransformList.cpp
Normal file
@ -0,0 +1,355 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla SVG Project code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either 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 "SVGAnimatedTransformList.h"
|
||||
#include "DOMSVGAnimatedTransformList.h"
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
#include "nsSMILValue.h"
|
||||
#include "SVGTransform.h"
|
||||
#include "SVGTransformListSMILType.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "prdtoa.h"
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
nsresult
|
||||
SVGAnimatedTransformList::SetBaseValueString(const nsAString& aValue)
|
||||
{
|
||||
SVGTransformList newBaseValue;
|
||||
nsresult rv = newBaseValue.SetValueFromString(aValue);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
DOMSVGAnimatedTransformList *domWrapper =
|
||||
DOMSVGAnimatedTransformList::GetDOMWrapperIfExists(this);
|
||||
if (domWrapper) {
|
||||
// We must send this notification *before* changing mBaseVal! If the length
|
||||
// of our baseVal is being reduced, our baseVal's DOM wrapper list may have
|
||||
// to remove DOM items from itself, and any removed DOM items need to copy
|
||||
// their internal counterpart values *before* we change them.
|
||||
//
|
||||
domWrapper->InternalBaseValListWillChangeLengthTo(newBaseValue.Length());
|
||||
}
|
||||
|
||||
// We don't need to call DidChange* here - we're only called by
|
||||
// nsSVGElement::ParseAttribute under nsGenericElement::SetAttr,
|
||||
// which takes care of notifying.
|
||||
|
||||
rv = mBaseVal.CopyFrom(newBaseValue);
|
||||
if (NS_FAILED(rv) && domWrapper) {
|
||||
// Attempting to increase mBaseVal's length failed - reduce domWrapper
|
||||
// back to the same length:
|
||||
domWrapper->InternalBaseValListWillChangeLengthTo(mBaseVal.Length());
|
||||
} else {
|
||||
mIsAttrSet = PR_TRUE;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
SVGAnimatedTransformList::ClearBaseValue()
|
||||
{
|
||||
DOMSVGAnimatedTransformList *domWrapper =
|
||||
DOMSVGAnimatedTransformList::GetDOMWrapperIfExists(this);
|
||||
if (domWrapper) {
|
||||
// We must send this notification *before* changing mBaseVal! (See above.)
|
||||
domWrapper->InternalBaseValListWillChangeLengthTo(0);
|
||||
}
|
||||
mBaseVal.Clear();
|
||||
mIsAttrSet = PR_FALSE;
|
||||
// Caller notifies
|
||||
}
|
||||
|
||||
nsresult
|
||||
SVGAnimatedTransformList::SetAnimValue(const SVGTransformList& aValue,
|
||||
nsSVGElement *aElement)
|
||||
{
|
||||
DOMSVGAnimatedTransformList *domWrapper =
|
||||
DOMSVGAnimatedTransformList::GetDOMWrapperIfExists(this);
|
||||
if (domWrapper) {
|
||||
// A new animation may totally change the number of items in the animVal
|
||||
// list, replacing what was essentially a mirror of the baseVal list, or
|
||||
// else replacing and overriding an existing animation. When this happens
|
||||
// we must try and keep our animVal's DOM wrapper in sync (see the comment
|
||||
// in DOMSVGAnimatedTransformList::InternalBaseValListWillChangeLengthTo).
|
||||
//
|
||||
// It's not possible for us to reliably distinguish between calls to this
|
||||
// method that are setting a new sample for an existing animation, and
|
||||
// calls that are setting the first sample of an animation that will
|
||||
// override an existing animation. Happily it's cheap to just blindly
|
||||
// notify our animVal's DOM wrapper of its internal counterpart's new value
|
||||
// each time this method is called, so that's what we do.
|
||||
//
|
||||
// Note that we must send this notification *before* setting or changing
|
||||
// mAnimVal! (See the comment in SetBaseValueString above.)
|
||||
//
|
||||
domWrapper->InternalAnimValListWillChangeLengthTo(aValue.Length());
|
||||
}
|
||||
if (!mAnimVal) {
|
||||
mAnimVal = new SVGTransformList();
|
||||
}
|
||||
nsresult rv = mAnimVal->CopyFrom(aValue);
|
||||
if (NS_FAILED(rv)) {
|
||||
// OOM. We clear the animation, and, importantly, ClearAnimValue() ensures
|
||||
// that mAnimVal and its DOM wrapper (if any) will have the same length!
|
||||
ClearAnimValue(aElement);
|
||||
return rv;
|
||||
}
|
||||
aElement->DidAnimateTransformList();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
SVGAnimatedTransformList::ClearAnimValue(nsSVGElement *aElement)
|
||||
{
|
||||
DOMSVGAnimatedTransformList *domWrapper =
|
||||
DOMSVGAnimatedTransformList::GetDOMWrapperIfExists(this);
|
||||
if (domWrapper) {
|
||||
// When all animation ends, animVal simply mirrors baseVal, which may have
|
||||
// a different number of items to the last active animated value. We must
|
||||
// keep the length of our animVal's DOM wrapper list in sync, and again we
|
||||
// must do that before touching mAnimVal. See comments above.
|
||||
//
|
||||
domWrapper->InternalAnimValListWillChangeLengthTo(mBaseVal.Length());
|
||||
}
|
||||
mAnimVal = nsnull;
|
||||
aElement->DidAnimateTransformList();
|
||||
}
|
||||
|
||||
PRBool
|
||||
SVGAnimatedTransformList::IsExplicitlySet() const
|
||||
{
|
||||
// Like other methods of this name, we need to know when a transform value has
|
||||
// been explicitly set.
|
||||
//
|
||||
// There are three ways an animated list can become set:
|
||||
// 1) Markup -- we set mIsAttrSet to PR_TRUE on any successful call to
|
||||
// SetBaseValueString and clear it on ClearBaseValue (as called by
|
||||
// nsSVGElement::UnsetAttr or a failed nsSVGElement::ParseAttribute)
|
||||
// 2) DOM call -- simply fetching the baseVal doesn't mean the transform value
|
||||
// has been set. It is set if that baseVal has one or more transforms in
|
||||
// the list.
|
||||
// 3) Animation -- which will cause the mAnimVal member to be allocated
|
||||
return mIsAttrSet || !mBaseVal.IsEmpty() || mAnimVal;
|
||||
}
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
nsISMILAttr*
|
||||
SVGAnimatedTransformList::ToSMILAttr(nsSVGElement* aSVGElement)
|
||||
{
|
||||
return new SMILAnimatedTransformList(this, aSVGElement);
|
||||
}
|
||||
|
||||
nsresult
|
||||
SVGAnimatedTransformList::SMILAnimatedTransformList::ValueFromString(
|
||||
const nsAString& aStr,
|
||||
const nsISMILAnimationElement* aSrcElement,
|
||||
nsSMILValue& aValue,
|
||||
PRBool& aPreventCachingOfSandwich) const
|
||||
{
|
||||
NS_ENSURE_TRUE(aSrcElement, NS_ERROR_FAILURE);
|
||||
NS_ABORT_IF_FALSE(aValue.IsNull(),
|
||||
"aValue should have been cleared before calling ValueFromString");
|
||||
|
||||
const nsAttrValue* typeAttr = aSrcElement->GetAnimAttr(nsGkAtoms::type);
|
||||
const nsIAtom* transformType = nsGkAtoms::translate; // default val
|
||||
if (typeAttr) {
|
||||
if (typeAttr->Type() != nsAttrValue::eAtom) {
|
||||
// Recognized values of |type| are parsed as an atom -- so if we have
|
||||
// something other than an atom, then we know already our |type| is
|
||||
// invalid.
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
transformType = typeAttr->GetAtomValue();
|
||||
}
|
||||
|
||||
ParseValue(aStr, transformType, aValue);
|
||||
aPreventCachingOfSandwich = PR_FALSE;
|
||||
return aValue.IsNull() ? NS_ERROR_FAILURE : NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
SVGAnimatedTransformList::SMILAnimatedTransformList::ParseValue(
|
||||
const nsAString& aSpec,
|
||||
const nsIAtom* aTransformType,
|
||||
nsSMILValue& aResult)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aResult.IsNull(), "Unexpected type for SMIL value");
|
||||
|
||||
// nsSVGSMILTransform constructor should be expecting array with 3 params
|
||||
PR_STATIC_ASSERT(SVGTransformSMILData::NUM_SIMPLE_PARAMS == 3);
|
||||
|
||||
float params[3] = { 0.f };
|
||||
PRInt32 numParsed = ParseParameterList(aSpec, params, 3);
|
||||
PRUint16 transformType;
|
||||
|
||||
if (aTransformType == nsGkAtoms::translate) {
|
||||
// tx [ty=0]
|
||||
if (numParsed != 1 && numParsed != 2)
|
||||
return;
|
||||
transformType = nsIDOMSVGTransform::SVG_TRANSFORM_TRANSLATE;
|
||||
} else if (aTransformType == nsGkAtoms::scale) {
|
||||
// sx [sy=sx]
|
||||
if (numParsed != 1 && numParsed != 2)
|
||||
return;
|
||||
if (numParsed == 1) {
|
||||
params[1] = params[0];
|
||||
}
|
||||
transformType = nsIDOMSVGTransform::SVG_TRANSFORM_SCALE;
|
||||
} else if (aTransformType == nsGkAtoms::rotate) {
|
||||
// r [cx=0 cy=0]
|
||||
if (numParsed != 1 && numParsed != 3)
|
||||
return;
|
||||
transformType = nsIDOMSVGTransform::SVG_TRANSFORM_ROTATE;
|
||||
} else if (aTransformType == nsGkAtoms::skewX) {
|
||||
// x-angle
|
||||
if (numParsed != 1)
|
||||
return;
|
||||
transformType = nsIDOMSVGTransform::SVG_TRANSFORM_SKEWX;
|
||||
} else if (aTransformType == nsGkAtoms::skewY) {
|
||||
// y-angle
|
||||
if (numParsed != 1)
|
||||
return;
|
||||
transformType = nsIDOMSVGTransform::SVG_TRANSFORM_SKEWY;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
nsSMILValue val(&SVGTransformListSMILType::sSingleton);
|
||||
SVGTransformSMILData transform(transformType, params);
|
||||
if (NS_FAILED(SVGTransformListSMILType::AppendTransform(transform, val))) {
|
||||
return; // OOM
|
||||
}
|
||||
|
||||
// Success! Populate our outparam with parsed value.
|
||||
aResult.Swap(val);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
inline void
|
||||
SkipWsp(nsACString::const_iterator& aIter,
|
||||
const nsACString::const_iterator& aIterEnd)
|
||||
{
|
||||
while (aIter != aIterEnd && IsSVGWhitespace(*aIter))
|
||||
++aIter;
|
||||
}
|
||||
} // end anonymous namespace block
|
||||
|
||||
PRInt32
|
||||
SVGAnimatedTransformList::SMILAnimatedTransformList::ParseParameterList(
|
||||
const nsAString& aSpec,
|
||||
float* aVars,
|
||||
PRInt32 aNVars)
|
||||
{
|
||||
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() || !NS_finite(f))
|
||||
return -1;
|
||||
|
||||
if (numArgsFound < aNVars) {
|
||||
aVars[numArgsFound] = f;
|
||||
}
|
||||
|
||||
start.advance(argend - arg);
|
||||
numArgsFound++;
|
||||
|
||||
SkipWsp(start, end);
|
||||
if (*start == ',') {
|
||||
++start;
|
||||
SkipWsp(start, end);
|
||||
}
|
||||
}
|
||||
|
||||
return numArgsFound;
|
||||
}
|
||||
|
||||
nsSMILValue
|
||||
SVGAnimatedTransformList::SMILAnimatedTransformList::GetBaseValue() const
|
||||
{
|
||||
// To benefit from Return Value Optimization and avoid copy constructor calls
|
||||
// due to our use of return-by-value, we must return the exact same object
|
||||
// from ALL return points. This function must only return THIS variable:
|
||||
nsSMILValue val(&SVGTransformListSMILType::sSingleton);
|
||||
if (!SVGTransformListSMILType::AppendTransforms(mVal->mBaseVal, val)) {
|
||||
val = nsSMILValue();
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
nsresult
|
||||
SVGAnimatedTransformList::SMILAnimatedTransformList::SetAnimValue(
|
||||
const nsSMILValue& aNewAnimValue)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(
|
||||
aNewAnimValue.mType == &SVGTransformListSMILType::sSingleton,
|
||||
"Unexpected type to assign animated value");
|
||||
SVGTransformList animVal;
|
||||
if (!SVGTransformListSMILType::GetTransforms(aNewAnimValue,
|
||||
animVal.mItems)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return mVal->SetAnimValue(animVal, mElement);
|
||||
}
|
||||
|
||||
void
|
||||
SVGAnimatedTransformList::SMILAnimatedTransformList::ClearAnimValue()
|
||||
{
|
||||
if (mVal->mAnimVal) {
|
||||
mVal->ClearAnimValue(mElement);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
} // namespace mozilla
|
158
content/svg/content/src/SVGAnimatedTransformList.h
Normal file
158
content/svg/content/src/SVGAnimatedTransformList.h
Normal file
@ -0,0 +1,158 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla SVG Project code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* 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 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 MOZILLA_SVGANIMATEDTRANSFORMLIST_H__
|
||||
#define MOZILLA_SVGANIMATEDTRANSFORMLIST_H__
|
||||
|
||||
#include "SVGTransformList.h"
|
||||
|
||||
class nsSVGElement;
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
#include "nsISMILAttr.h"
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/**
|
||||
* Class SVGAnimatedTransformList
|
||||
*
|
||||
* This class is very different to the SVG DOM interface of the same name found
|
||||
* in the SVG specification. This is a lightweight internal class - see
|
||||
* DOMSVGAnimatedTransformList for the heavier DOM class that wraps instances of
|
||||
* this class and implements the SVG specification's SVGAnimatedTransformList
|
||||
* DOM interface.
|
||||
*
|
||||
* Except where noted otherwise, this class' methods take care of keeping the
|
||||
* appropriate DOM wrappers in sync (see the comment in
|
||||
* DOMSVGAnimatedTransformList::InternalBaseValListWillChangeTo) so that their
|
||||
* consumers don't need to concern themselves with that.
|
||||
*/
|
||||
class SVGAnimatedTransformList
|
||||
{
|
||||
// friends so that they can get write access to mBaseVal
|
||||
friend class DOMSVGTransform;
|
||||
friend class DOMSVGTransformList;
|
||||
|
||||
public:
|
||||
SVGAnimatedTransformList() : mIsAttrSet(PR_FALSE) { }
|
||||
|
||||
/**
|
||||
* Because it's so important that mBaseVal and its DOMSVGTransformList wrapper
|
||||
* (if any) be kept in sync (see the comment in
|
||||
* DOMSVGAnimatedTransformList::InternalBaseValListWillChangeTo), this method
|
||||
* returns a const reference. Only our friend classes may get mutable
|
||||
* references to mBaseVal.
|
||||
*/
|
||||
const SVGTransformList& GetBaseValue() const {
|
||||
return mBaseVal;
|
||||
}
|
||||
|
||||
nsresult SetBaseValueString(const nsAString& aValue);
|
||||
|
||||
void ClearBaseValue();
|
||||
|
||||
const SVGTransformList& GetAnimValue() const {
|
||||
return mAnimVal ? *mAnimVal : mBaseVal;
|
||||
}
|
||||
|
||||
nsresult SetAnimValue(const SVGTransformList& aNewAnimValue,
|
||||
nsSVGElement *aElement);
|
||||
|
||||
void ClearAnimValue(nsSVGElement *aElement);
|
||||
|
||||
PRBool IsExplicitlySet() const;
|
||||
|
||||
PRBool IsAnimating() const {
|
||||
return !!mAnimVal;
|
||||
}
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
/// Callers own the returned nsISMILAttr
|
||||
nsISMILAttr* ToSMILAttr(nsSVGElement* aSVGElement);
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
private:
|
||||
|
||||
// mAnimVal is a pointer to allow us to determine if we're being animated or
|
||||
// not. Making it a non-pointer member and using mAnimVal.IsEmpty() to check
|
||||
// if we're animating is not an option, since that would break animation *to*
|
||||
// the empty string (<set to="">).
|
||||
|
||||
SVGTransformList mBaseVal;
|
||||
nsAutoPtr<SVGTransformList> mAnimVal;
|
||||
PRPackedBool mIsAttrSet;
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
struct SMILAnimatedTransformList : public nsISMILAttr
|
||||
{
|
||||
public:
|
||||
SMILAnimatedTransformList(SVGAnimatedTransformList* aVal,
|
||||
nsSVGElement* aSVGElement)
|
||||
: mVal(aVal)
|
||||
, mElement(aSVGElement)
|
||||
{}
|
||||
|
||||
// nsISMILAttr methods
|
||||
virtual nsresult ValueFromString(const nsAString& aStr,
|
||||
const nsISMILAnimationElement* aSrcElement,
|
||||
nsSMILValue& aValue,
|
||||
PRBool& aPreventCachingOfSandwich) const;
|
||||
virtual nsSMILValue GetBaseValue() const;
|
||||
virtual void ClearAnimValue();
|
||||
virtual nsresult SetAnimValue(const nsSMILValue& aValue);
|
||||
|
||||
protected:
|
||||
static void ParseValue(const nsAString& aSpec,
|
||||
const nsIAtom* aTransformType,
|
||||
nsSMILValue& aResult);
|
||||
static PRInt32 ParseParameterList(const nsAString& aSpec, float* aVars,
|
||||
PRInt32 aNVars);
|
||||
|
||||
// These will stay alive because a nsISMILAttr only lives as long
|
||||
// as the Compositing step, and DOM elements don't get a chance to
|
||||
// die during that.
|
||||
SVGAnimatedTransformList* mVal;
|
||||
nsSVGElement* mElement;
|
||||
};
|
||||
#endif // MOZ_SMIL
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // MOZILLA_SVGANIMATEDTRANSFORMLIST_H__
|
@ -42,7 +42,6 @@
|
||||
#include "nsSVGEnum.h"
|
||||
#include "nsIDOMSVGTransform.h"
|
||||
#include "nsIDOMSVGTransformable.h"
|
||||
#include "nsSVGAnimatedTransformList.h"
|
||||
#include "nsSVGTransformSMILAttr.h"
|
||||
#include "nsSMILAnimationFunction.h"
|
||||
|
||||
|
@ -1,184 +0,0 @@
|
||||
/* -*- 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
|
||||
* Crocodile Clips Ltd..
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Alex Fritze <alex.fritze@crocodile-clips.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGAnimatedTransformList.h"
|
||||
#include "nsSVGTransformList.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Implementation
|
||||
|
||||
nsSVGAnimatedTransformList::~nsSVGAnimatedTransformList()
|
||||
{
|
||||
if (!mBaseVal) return;
|
||||
nsCOMPtr<nsISVGValue> val = do_QueryInterface(mBaseVal);
|
||||
if (!val) return;
|
||||
val->RemoveObserver(this);
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGAnimatedTransformList::Init(nsIDOMSVGTransformList* baseVal)
|
||||
{
|
||||
mBaseVal = baseVal;
|
||||
if (!mBaseVal) return;
|
||||
nsCOMPtr<nsISVGValue> val = do_QueryInterface(mBaseVal);
|
||||
if (!val) return;
|
||||
val->AddObserver(this);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISupports methods:
|
||||
|
||||
NS_IMPL_ADDREF(nsSVGAnimatedTransformList)
|
||||
NS_IMPL_RELEASE(nsSVGAnimatedTransformList)
|
||||
|
||||
DOMCI_DATA(SVGAnimatedTransformList, nsSVGAnimatedTransformList)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsSVGAnimatedTransformList)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISVGValue)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimatedTransformList)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISVGValueObserver)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAnimatedTransformList)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISVGValue)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISVGValue methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGAnimatedTransformList::SetValueString(const nsAString& aValue)
|
||||
{
|
||||
nsCOMPtr<nsISVGValue> value = do_QueryInterface(mBaseVal);
|
||||
return value->SetValueString(aValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGAnimatedTransformList::GetValueString(nsAString& aValue)
|
||||
{
|
||||
nsCOMPtr<nsISVGValue> value = do_QueryInterface(mBaseVal);
|
||||
return value->GetValueString(aValue);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIDOMSVGAnimatedTransformList methods:
|
||||
|
||||
/* readonly attribute nsIDOMSVGTransformList baseVal; */
|
||||
NS_IMETHODIMP
|
||||
nsSVGAnimatedTransformList::GetBaseVal(nsIDOMSVGTransformList** aBaseVal)
|
||||
{
|
||||
*aBaseVal = mBaseVal;
|
||||
NS_ADDREF(*aBaseVal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIDOMSVGTransformList animVal; */
|
||||
NS_IMETHODIMP
|
||||
nsSVGAnimatedTransformList::GetAnimVal(nsIDOMSVGTransformList** aAnimVal)
|
||||
{
|
||||
*aAnimVal = mAnimVal ? mAnimVal : mBaseVal;
|
||||
NS_ADDREF(*aAnimVal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISVGValueObserver methods
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGAnimatedTransformList::WillModifySVGObservable(nsISVGValue* observable,
|
||||
modificationType aModType)
|
||||
{
|
||||
WillModify(aModType);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGAnimatedTransformList::DidModifySVGObservable (nsISVGValue* observable,
|
||||
modificationType aModType)
|
||||
{
|
||||
DidModify(aModType);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Misc nsSVGAnimatedTransformList methods
|
||||
|
||||
PRBool
|
||||
nsSVGAnimatedTransformList::IsExplicitlySet() const
|
||||
{
|
||||
// XXX Dummy implementation until bug 602759 is fixed.
|
||||
// Like other methods of this name, we need to know when a transform value has
|
||||
// been explicitly set (either by markup, a DOM call, or animation).
|
||||
// Given our current implementation, we can say that's the case so long as
|
||||
// mBaseVal has something in it or mAnimVal exists.
|
||||
// It's not quite right because, for example, if we have transform="" we
|
||||
// should probably behave as if the value is set, but for now it will do until
|
||||
// bug 602759 is fixed.
|
||||
if (mAnimVal)
|
||||
return PR_TRUE;
|
||||
|
||||
if (!mBaseVal)
|
||||
return PR_FALSE;
|
||||
|
||||
PRUint32 numItems = 0;
|
||||
nsIDOMSVGTransformList *list = mBaseVal.get();
|
||||
list->GetNumberOfItems(&numItems);
|
||||
return numItems > 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Exported creation functions:
|
||||
|
||||
nsresult
|
||||
NS_NewSVGAnimatedTransformList(nsIDOMSVGAnimatedTransformList** result,
|
||||
nsIDOMSVGTransformList* baseVal)
|
||||
{
|
||||
*result = nsnull;
|
||||
|
||||
nsSVGAnimatedTransformList* animatedTransformList = new nsSVGAnimatedTransformList();
|
||||
if(!animatedTransformList) return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(animatedTransformList);
|
||||
|
||||
animatedTransformList->Init(baseVal);
|
||||
|
||||
*result = (nsIDOMSVGAnimatedTransformList*) animatedTransformList;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1,97 +0,0 @@
|
||||
/* -*- 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
|
||||
* Crocodile Clips Ltd..
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Alex Fritze <alex.fritze@crocodile-clips.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef __NS_SVGANIMATEDTRANSFORMLIST_H__
|
||||
#define __NS_SVGANIMATEDTRANSFORMLIST_H__
|
||||
|
||||
#include "nsIDOMSVGAnimTransformList.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
|
||||
|
||||
PRBool IsExplicitlySet() const;
|
||||
|
||||
protected:
|
||||
friend class nsSVGTransformSMILAttr;
|
||||
|
||||
nsCOMPtr<nsIDOMSVGTransformList> mBaseVal;
|
||||
// XXX This should be read-only, i.e. its setters should throw
|
||||
nsCOMPtr<nsIDOMSVGTransformList> mAnimVal;
|
||||
};
|
||||
|
||||
nsresult
|
||||
NS_NewSVGAnimatedTransformList(nsIDOMSVGAnimatedTransformList** result,
|
||||
nsIDOMSVGTransformList* baseVal);
|
||||
|
||||
#endif //__NS_SVGANIMATEDTRANSFORMLIST_H__
|
@ -1,447 +0,0 @@
|
||||
/* -*- 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"
|
||||
#include "prlog.h"
|
||||
#include "nsMathUtils.h"
|
||||
|
||||
nsresult
|
||||
nsSVGTransformSMILAttr::ValueFromString(const nsAString& aStr,
|
||||
const nsISMILAnimationElement* aSrcElement,
|
||||
nsSMILValue& aValue,
|
||||
PRBool& aPreventCachingOfSandwich) const
|
||||
{
|
||||
NS_ENSURE_TRUE(aSrcElement, NS_ERROR_FAILURE);
|
||||
NS_ASSERTION(aValue.IsNull(),
|
||||
"aValue should have been cleared before calling ValueFromString");
|
||||
|
||||
const nsAttrValue* typeAttr = aSrcElement->GetAnimAttr(nsGkAtoms::type);
|
||||
const nsIAtom* transformType = nsGkAtoms::translate;
|
||||
if (typeAttr) {
|
||||
if (typeAttr->Type() != nsAttrValue::eAtom) {
|
||||
// Recognized values of |type| are parsed as an atom -- so if we have
|
||||
// something other than an atom, then it means our |type| was invalid.
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
transformType = typeAttr->GetAtomValue();
|
||||
}
|
||||
|
||||
ParseValue(aStr, transformType, aValue);
|
||||
aPreventCachingOfSandwich = PR_FALSE;
|
||||
return aValue.IsNull() ? NS_ERROR_FAILURE : NS_OK;
|
||||
}
|
||||
|
||||
nsSMILValue
|
||||
nsSVGTransformSMILAttr::GetBaseValue() const
|
||||
{
|
||||
// To benefit from Return Value Optimization and avoid copy constructor calls
|
||||
// due to our use of return-by-value, we must return the exact same object
|
||||
// from ALL return points. This function must only return THIS variable:
|
||||
nsSMILValue val(&nsSVGTransformSMILType::sSingleton);
|
||||
|
||||
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);
|
||||
if (NS_FAILED(rv)) { // Appending to |val| failed (OOM?)
|
||||
val = nsSMILValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGTransformSMILAttr::ClearAnimValue()
|
||||
{
|
||||
PRBool animValSet = !!mVal->mAnimVal;
|
||||
mVal->mAnimVal = nsnull;
|
||||
if (animValSet) {
|
||||
mSVGElement->DidAnimateTransform();
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
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);
|
||||
|
||||
mSVGElement->DidAnimateTransform();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Implementation helpers
|
||||
|
||||
void
|
||||
nsSVGTransformSMILAttr::ParseValue(const nsAString& aSpec,
|
||||
const nsIAtom* aTransformType,
|
||||
nsSMILValue& aResult)
|
||||
{
|
||||
NS_ASSERTION(aResult.IsNull(), "Unexpected type for SMIL value");
|
||||
|
||||
// nsSVGSMILTransform constructor should be expecting array with 3 params
|
||||
PR_STATIC_ASSERT(nsSVGSMILTransform::NUM_SIMPLE_PARAMS == 3);
|
||||
|
||||
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;
|
||||
transformType = nsSVGSMILTransform::TRANSFORM_TRANSLATE;
|
||||
} else if (aTransformType == nsGkAtoms::scale) {
|
||||
// sx [sy=sx]
|
||||
if (numParsed != 1 && numParsed != 2)
|
||||
return;
|
||||
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;
|
||||
transformType = nsSVGSMILTransform::TRANSFORM_ROTATE;
|
||||
} else if (aTransformType == nsGkAtoms::skewX) {
|
||||
// x-angle
|
||||
if (numParsed != 1)
|
||||
return;
|
||||
transformType = nsSVGSMILTransform::TRANSFORM_SKEWX;
|
||||
} else if (aTransformType == nsGkAtoms::skewY) {
|
||||
// y-angle
|
||||
if (numParsed != 1)
|
||||
return;
|
||||
transformType = nsSVGSMILTransform::TRANSFORM_SKEWY;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
nsSMILValue val(&nsSVGTransformSMILType::sSingleton);
|
||||
nsSVGSMILTransform transform(transformType, params);
|
||||
if (NS_FAILED(nsSVGTransformSMILType::AppendTransform(transform, val))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Success! Populate our outparam with parsed value.
|
||||
aResult.Swap(val);
|
||||
}
|
||||
|
||||
inline PRBool
|
||||
IsSpace(const char c)
|
||||
{
|
||||
return (c == 0x9 || c == 0xA || c == 0xD || c == 0x20);
|
||||
}
|
||||
|
||||
inline void
|
||||
SkipWsp(nsACString::const_iterator& aIter,
|
||||
const nsACString::const_iterator& aIterEnd)
|
||||
{
|
||||
while (aIter != aIterEnd && IsSpace(*aIter))
|
||||
++aIter;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsSVGTransformSMILAttr::ParseParameterList(const nsAString& aSpec,
|
||||
float* aVars,
|
||||
PRInt32 aNVars)
|
||||
{
|
||||
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() || !NS_finite(f))
|
||||
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)
|
||||
{
|
||||
NS_ASSERTION(aValue.mType == &nsSVGTransformSMILType::sSingleton,
|
||||
"Unexpected type for SMIL value");
|
||||
|
||||
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;
|
||||
|
||||
// nsSVGSMILTransform constructor should be expecting array with 3 params
|
||||
PR_STATIC_ASSERT(nsSVGSMILTransform::NUM_SIMPLE_PARAMS == 3);
|
||||
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:
|
||||
{
|
||||
// nsSVGSMILTransform constructor for TRANSFORM_MATRIX type should be
|
||||
// expecting array with 6 params
|
||||
PR_STATIC_ASSERT(nsSVGSMILTransform::NUM_STORED_PARAMS == 6);
|
||||
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]);
|
||||
return nsSVGTransformSMILType::AppendTransform(nsSVGSMILTransform(mx),
|
||||
aValue);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
NS_ABORT_IF_FALSE(transformType != nsSVGSMILTransform::TRANSFORM_MATRIX,
|
||||
"generalized matrix case should have returned above");
|
||||
|
||||
return nsSVGTransformSMILType::
|
||||
AppendTransform(nsSVGSMILTransform(transformType, params), aValue);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
switch (aSMILTransform.mTransformType)
|
||||
{
|
||||
case nsSVGSMILTransform::TRANSFORM_TRANSLATE:
|
||||
return aSVGTransform->SetTranslate(aSMILTransform.mParams[0],
|
||||
aSMILTransform.mParams[1]);
|
||||
|
||||
case nsSVGSMILTransform::TRANSFORM_SCALE:
|
||||
return aSVGTransform->SetScale(aSMILTransform.mParams[0],
|
||||
aSMILTransform.mParams[1]);
|
||||
|
||||
case nsSVGSMILTransform::TRANSFORM_ROTATE:
|
||||
return aSVGTransform->SetRotate(aSMILTransform.mParams[0],
|
||||
aSMILTransform.mParams[1],
|
||||
aSMILTransform.mParams[2]);
|
||||
|
||||
case nsSVGSMILTransform::TRANSFORM_SKEWX:
|
||||
return aSVGTransform->SetSkewX(aSMILTransform.mParams[0]);
|
||||
|
||||
case nsSVGSMILTransform::TRANSFORM_SKEWY:
|
||||
return aSVGTransform->SetSkewY(aSMILTransform.mParams[0]);
|
||||
|
||||
case nsSVGSMILTransform::TRANSFORM_MATRIX:
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGMatrix> svgMatrix;
|
||||
nsresult 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_ABORT_IF_FALSE(svgMatrix,
|
||||
"NS_NewSVGMatrix succeeded, so it should have "
|
||||
"given us a non-null result");
|
||||
return aSVGTransform->SetMatrix(svgMatrix);
|
||||
}
|
||||
default:
|
||||
NS_WARNING("Unexpected transform type");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
/* -*- 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 nsresult ValueFromString(const nsAString& aStr,
|
||||
const nsISMILAnimationElement* aSrcElement,
|
||||
nsSMILValue& aValue,
|
||||
PRBool& aPreventCachingOfSandwich) const;
|
||||
virtual nsSMILValue GetBaseValue() const;
|
||||
virtual void ClearAnimValue();
|
||||
virtual nsresult SetAnimValue(const nsSMILValue& aValue);
|
||||
|
||||
protected:
|
||||
static void ParseValue(const nsAString& aSpec,
|
||||
const nsIAtom* aTransformType,
|
||||
nsSMILValue& aResult);
|
||||
static PRInt32 ParseParameterList(const nsAString& aSpec, float* aVars,
|
||||
PRInt32 aNVars);
|
||||
static nsresult AppendSVGTransformToSMILValue(nsIDOMSVGTransform* transform,
|
||||
nsSMILValue& aValue);
|
||||
static nsresult UpdateFromSMILValue(nsIDOMSVGTransformList* aTransformList,
|
||||
const nsSMILValue& aValue);
|
||||
static nsresult GetSVGTransformFromSMILValue(
|
||||
const nsSVGSMILTransform& aSMILTransform,
|
||||
nsIDOMSVGTransform* aSVGTransform);
|
||||
|
||||
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_
|
Loading…
Reference in New Issue
Block a user