Bug 602759 part 5 - Refactor nsSVGTransform into SVGTransform and DOMSVGTransform; r=jwatt

--HG--
rename : content/svg/content/src/nsSVGTransform.cpp => content/svg/content/src/DOMSVGTransform.cpp
rename : content/svg/content/src/nsSVGTransform.h => content/svg/content/src/DOMSVGTransform.h
This commit is contained in:
Brian Birtles 2011-09-25 22:04:27 +01:00
parent 8ce9d44d6b
commit 1bc95dca8d
8 changed files with 895 additions and 514 deletions

View File

@ -0,0 +1,356 @@
/* -*- 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)
* 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 "DOMSVGTransform.h"
#include "DOMSVGMatrix.h"
#include "SVGAnimatedTransformList.h"
#include "nsDOMError.h"
#include <math.h>
#include "nsContentUtils.h"
namespace mozilla {
//----------------------------------------------------------------------
// nsISupports methods:
// We could use NS_IMPL_CYCLE_COLLECTION_1, except that in Unlink() we need to
// clear our list's weak ref to us to be safe. (The other option would be to
// not unlink and rely on the breaking of the other edges in the cycle, as
// NS_SVG_VAL_IMPL_CYCLE_COLLECTION does.)
NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGTransform)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGTransform)
// We may not belong to a list, so we must null check tmp->mList.
if (tmp->mList) {
tmp->mList->mItems[tmp->mListIndex] = nsnull;
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGTransform)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMSVGTransform)
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMSVGTransform)
} // namespace mozilla
DOMCI_DATA(SVGTransform, mozilla::DOMSVGTransform)
namespace mozilla {
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMSVGTransform)
NS_INTERFACE_MAP_ENTRY(mozilla::DOMSVGTransform)
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGTransform)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMSVGTransform)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGTransform)
NS_INTERFACE_MAP_END
//----------------------------------------------------------------------
// Ctors:
DOMSVGTransform::DOMSVGTransform(DOMSVGTransformList *aList,
PRUint32 aListIndex,
PRBool aIsAnimValItem)
: mList(aList)
, mListIndex(aListIndex)
, mIsAnimValItem(aIsAnimValItem)
, mTransform(nsnull)
, mMatrixTearoff(nsnull)
{
// These shifts are in sync with the members in the header.
NS_ABORT_IF_FALSE(aList &&
aListIndex <= MaxListIndex() &&
aIsAnimValItem < (1 << 1), "bad arg");
NS_ABORT_IF_FALSE(IndexIsValid(), "Bad index for DOMSVGNumber!");
}
DOMSVGTransform::DOMSVGTransform()
: mList(nsnull)
, mListIndex(0)
, mIsAnimValItem(PR_FALSE)
, mTransform(new SVGTransform()) // Default ctor for objects not in a list
// initialises to matrix type with identity
// matrix
, mMatrixTearoff(nsnull)
{
}
DOMSVGTransform::DOMSVGTransform(const gfxMatrix &aMatrix)
: mList(nsnull)
, mListIndex(0)
, mIsAnimValItem(PR_FALSE)
, mTransform(new SVGTransform(aMatrix))
, mMatrixTearoff(nsnull)
{
}
DOMSVGTransform::DOMSVGTransform(const SVGTransform &aTransform)
: mList(nsnull)
, mListIndex(0)
, mIsAnimValItem(PR_FALSE)
, mTransform(new SVGTransform(aTransform))
, mMatrixTearoff(nsnull)
{
}
//----------------------------------------------------------------------
// nsIDOMSVGTransform methods:
/* readonly attribute unsigned short type; */
NS_IMETHODIMP
DOMSVGTransform::GetType(PRUint16 *aType)
{
*aType = Transform().Type();
return NS_OK;
}
/* readonly attribute nsIDOMSVGMatrix matrix; */
NS_IMETHODIMP
DOMSVGTransform::GetMatrix(nsIDOMSVGMatrix * *aMatrix)
{
if (!mMatrixTearoff) {
mMatrixTearoff = new DOMSVGMatrix(*this);
}
NS_ADDREF(*aMatrix = mMatrixTearoff);
return NS_OK;
}
/* readonly attribute float angle; */
NS_IMETHODIMP
DOMSVGTransform::GetAngle(float *aAngle)
{
*aAngle = Transform().Angle();
return NS_OK;
}
/* void setMatrix (in nsIDOMSVGMatrix matrix); */
NS_IMETHODIMP
DOMSVGTransform::SetMatrix(nsIDOMSVGMatrix *matrix)
{
if (mIsAnimValItem)
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
nsCOMPtr<DOMSVGMatrix> domMatrix = do_QueryInterface(matrix);
if (!domMatrix)
return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
Transform().SetMatrix(domMatrix->Matrix());
NotifyElementOfChange();
return NS_OK;
}
/* void setTranslate (in float tx, in float ty); */
NS_IMETHODIMP
DOMSVGTransform::SetTranslate(float tx, float ty)
{
if (mIsAnimValItem) {
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
}
NS_ENSURE_FINITE2(tx, ty, NS_ERROR_ILLEGAL_VALUE);
Transform().SetTranslate(tx, ty);
NotifyElementOfChange();
return NS_OK;
}
/* void setScale (in float sx, in float sy); */
NS_IMETHODIMP
DOMSVGTransform::SetScale(float sx, float sy)
{
if (mIsAnimValItem) {
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
}
NS_ENSURE_FINITE2(sx, sy, NS_ERROR_ILLEGAL_VALUE);
Transform().SetScale(sx, sy);
NotifyElementOfChange();
return NS_OK;
}
/* void setRotate (in float angle, in float cx, in float cy); */
NS_IMETHODIMP
DOMSVGTransform::SetRotate(float angle, float cx, float cy)
{
if (mIsAnimValItem) {
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
}
NS_ENSURE_FINITE3(angle, cx, cy, NS_ERROR_ILLEGAL_VALUE);
Transform().SetRotate(angle, cx, cy);
NotifyElementOfChange();
return NS_OK;
}
/* void setSkewX (in float angle); */
NS_IMETHODIMP
DOMSVGTransform::SetSkewX(float angle)
{
if (mIsAnimValItem) {
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
}
NS_ENSURE_FINITE(angle, NS_ERROR_ILLEGAL_VALUE);
nsresult rv = Transform().SetSkewX(angle);
if (NS_FAILED(rv))
return rv;
NotifyElementOfChange();
return NS_OK;
}
/* void setSkewY (in float angle); */
NS_IMETHODIMP
DOMSVGTransform::SetSkewY(float angle)
{
if (mIsAnimValItem) {
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
}
NS_ENSURE_FINITE(angle, NS_ERROR_ILLEGAL_VALUE);
nsresult rv = Transform().SetSkewY(angle);
if (NS_FAILED(rv))
return rv;
NotifyElementOfChange();
return NS_OK;
}
//----------------------------------------------------------------------
// List management methods:
void
DOMSVGTransform::InsertingIntoList(DOMSVGTransformList *aList,
PRUint32 aListIndex,
PRBool aIsAnimValItem)
{
NS_ABORT_IF_FALSE(!HasOwner(), "Inserting item that is already in a list");
mList = aList;
mListIndex = aListIndex;
mIsAnimValItem = aIsAnimValItem;
mTransform = nsnull;
NS_ABORT_IF_FALSE(IndexIsValid(), "Bad index for DOMSVGLength!");
}
void
DOMSVGTransform::RemovingFromList()
{
NS_ABORT_IF_FALSE(!mTransform,
"Item in list also has another non-list value associated with it");
mTransform = new SVGTransform(InternalItem());
mList = nsnull;
mIsAnimValItem = PR_FALSE;
}
SVGTransform&
DOMSVGTransform::InternalItem()
{
SVGAnimatedTransformList *alist = Element()->GetAnimatedTransformList();
return mIsAnimValItem && alist->mAnimVal ?
(*alist->mAnimVal)[mListIndex] :
alist->mBaseVal[mListIndex];
}
const SVGTransform&
DOMSVGTransform::InternalItem() const
{
return const_cast<DOMSVGTransform *>(this)->InternalItem();
}
#ifdef DEBUG
PRBool
DOMSVGTransform::IndexIsValid()
{
SVGAnimatedTransformList *alist = Element()->GetAnimatedTransformList();
return (mIsAnimValItem &&
mListIndex < alist->GetAnimValue().Length()) ||
(!mIsAnimValItem &&
mListIndex < alist->GetBaseValue().Length());
}
#endif // DEBUG
//----------------------------------------------------------------------
// Interface for DOMSVGMatrix's use
void
DOMSVGTransform::SetMatrix(const gfxMatrix& aMatrix)
{
NS_ABORT_IF_FALSE(!mIsAnimValItem,
"Attempting to modify read-only transform");
Transform().SetMatrix(aMatrix);
NotifyElementOfChange();
}
void
DOMSVGTransform::ClearMatrixTearoff(DOMSVGMatrix* aMatrix)
{
NS_ABORT_IF_FALSE(mMatrixTearoff == aMatrix,
"Unexpected matrix pointer to be cleared");
mMatrixTearoff = nsnull;
}
//----------------------------------------------------------------------
// Implementation helpers
void
DOMSVGTransform::NotifyElementOfChange()
{
if (HasOwner()) {
Element()->DidChangeTransformList(PR_TRUE);
#ifdef MOZ_SMIL
if (mList->mAList->IsAnimating()) {
Element()->AnimationNeedsResample();
}
#endif // MOZ_SMIL
}
}
} // namespace mozilla

View File

@ -0,0 +1,235 @@
/* -*- 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)
* 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 MOZILLA_DOMSVGTRANSFORM_H__
#define MOZILLA_DOMSVGTRANSFORM_H__
#include "nsIDOMSVGTransform.h"
#include "DOMSVGTransformList.h"
#include "SVGTransform.h"
#include "nsCycleCollectionParticipant.h"
#include "nsAutoPtr.h"
// We make DOMSVGTransform a pseudo-interface to allow us to QI to it in order
// to check that the objects that scripts pass in are our our *native* transform
// objects.
//
// {0A799862-9469-41FE-B4CD-2019E65D8DA6}
#define MOZILLA_DOMSVGTRANSFORM_IID \
{ 0x0A799862, 0x9469, 0x41FE, \
{ 0xB4, 0xCD, 0x20, 0x19, 0xE6, 0x5D, 0x8D, 0xA6 } }
#define MOZ_SVG_LIST_INDEX_BIT_COUNT 22 // supports > 4 million list items
namespace mozilla {
class DOMSVGMatrix;
/**
* DOM wrapper for an SVG transform. See DOMSVGLength.h.
*/
class DOMSVGTransform : public nsIDOMSVGTransform
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOMSVGTRANSFORM_IID)
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(DOMSVGTransform)
NS_DECL_NSIDOMSVGTRANSFORM
/**
* Generic ctor for DOMSVGTransform objects that are created for an attribute.
*/
DOMSVGTransform(DOMSVGTransformList *aList,
PRUint32 aListIndex,
PRBool aIsAnimValItem);
/**
* Ctors for creating the objects returned by:
* SVGSVGElement.createSVGTransform(),
* SVGSVGElement.createSVGTransformFromMatrix(in SVGMatrix matrix),
* SVGTransformList.createSVGTransformFromMatrix(in SVGMatrix matrix)
* which do not initially belong to an attribute.
*/
DOMSVGTransform();
DOMSVGTransform(const gfxMatrix &aMatrix);
/**
* Ctor for creating an unowned copy. Used with Clone().
*/
DOMSVGTransform(const SVGTransform &aMatrix);
~DOMSVGTransform() {
// Our matrix tear-off pointer should be cleared before we are destroyed
// (since matrix tear-offs keep an owning reference to their transform, and
// clear the tear-off pointer themselves if unlinked).
NS_ABORT_IF_FALSE(!mMatrixTearoff, "Matrix tear-off pointer not cleared."
" Transform being destroyed before matrix?");
// Our mList's weak ref to us must be nulled out when we die. If GC has
// unlinked us using the cycle collector code, then that has already
// happened, and mList is null.
if (mList) {
mList->mItems[mListIndex] = nsnull;
}
};
/**
* Create an unowned copy of an owned transform. The caller is responsible for
* the first AddRef().
*/
DOMSVGTransform* Clone() {
NS_ASSERTION(mList, "unexpected caller");
return new DOMSVGTransform(InternalItem());
}
PRBool IsInList() const {
return !!mList;
}
/**
* In future, if this class is used for non-list transforms, this will be
* different to IsInList().
*/
PRBool HasOwner() const {
return !!mList;
}
/**
* This method is called to notify this DOM object that it is being inserted
* into a list, and give it the information it needs as a result.
*
* This object MUST NOT already belong to a list when this method is called.
* That's not to say that script can't move these DOM objects between
* lists - it can - it's just that the logic to handle that (and send out
* the necessary notifications) is located elsewhere (in
* DOMSVGTransformList).)
*/
void InsertingIntoList(DOMSVGTransformList *aList,
PRUint32 aListIndex,
PRBool aIsAnimValItem);
static PRUint32 MaxListIndex() {
return (1U << MOZ_SVG_LIST_INDEX_BIT_COUNT) - 1;
}
/// This method is called to notify this object that its list index changed.
void UpdateListIndex(PRUint32 aListIndex) {
mListIndex = aListIndex;
}
/**
* This method is called to notify this DOM object that it is about to be
* removed from its current DOM list so that it can first make a copy of its
* internal counterpart's values. (If it didn't do this, then it would
* "lose" its value on being removed.)
*/
void RemovingFromList();
SVGTransform ToSVGTransform() const {
return Transform();
}
protected:
// Interface for DOMSVGMatrix's use
friend class DOMSVGMatrix;
const PRBool IsAnimVal() const {
return mIsAnimValItem;
}
const gfxMatrix& Matrix() const {
return Transform().Matrix();
}
void SetMatrix(const gfxMatrix& aMatrix);
void ClearMatrixTearoff(DOMSVGMatrix* aMatrix);
private:
nsSVGElement* Element() {
return mList->Element();
}
/**
* Get a reference to the internal SVGTransform list item that this DOM
* wrapper object currently wraps.
*/
SVGTransform& InternalItem();
const SVGTransform& InternalItem() const;
#ifdef DEBUG
PRBool IndexIsValid();
#endif
const SVGTransform& Transform() const {
return HasOwner() ? InternalItem() : *mTransform;
}
SVGTransform& Transform() {
return HasOwner() ? InternalItem() : *mTransform;
}
void NotifyElementOfChange();
nsRefPtr<DOMSVGTransformList> mList;
// Bounds for the following are checked in the ctor, so be sure to update
// that if you change the capacity of any of the following.
PRUint32 mListIndex:MOZ_SVG_LIST_INDEX_BIT_COUNT;
PRPackedBool mIsAnimValItem:1;
// Usually this class acts as a wrapper for an SVGTransform object which is
// part of a list and is accessed by going via the owning Element.
//
// However, in some circumstances, objects of this class may not be associated
// with any particular list and thus, no internal SVGTransform object. In
// that case we allocate an SVGTransform object on the heap to store the data.
nsAutoPtr<SVGTransform> mTransform;
// Weak ref to DOMSVGMatrix tearoff. The DOMSVGMatrix object will take of
// clearing this pointer when it is destroyed (by calling ClearMatrixTearoff).
//
// If this extra pointer member proves undesirable, it can be replaced with
// a hashmap (nsSVGAttrTearoffTable) to map from DOMSVGTransform to
// DOMSVGMatrix.
DOMSVGMatrix* mMatrixTearoff;
};
NS_DEFINE_STATIC_IID_ACCESSOR(DOMSVGTransform, MOZILLA_DOMSVGTRANSFORM_IID)
} // namespace mozilla
#undef MOZ_SVG_LIST_INDEX_BIT_COUNT
#endif // MOZILLA_DOMSVGTRANSFORM_H__

View File

@ -60,6 +60,7 @@ CPPSRCS = \
DOMSVGPathSegList.cpp \
DOMSVGPoint.cpp \
DOMSVGPointList.cpp \
DOMSVGTransform.cpp \
nsDOMSVGZoomEvent.cpp \
nsDOMSVGEvent.cpp \
nsSVGAElement.cpp \
@ -118,7 +119,6 @@ CPPSRCS = \
nsSVGTextPathElement.cpp \
nsSVGTextPositioningElement.cpp \
nsSVGTitleElement.cpp \
nsSVGTransform.cpp \
nsSVGTransformList.cpp \
nsSVGTransformListParser.cpp \
nsSVGUseElement.cpp \
@ -135,6 +135,7 @@ CPPSRCS = \
SVGPathData.cpp \
SVGPathSegUtils.cpp \
SVGPointList.cpp \
SVGTransform.cpp \
$(NULL)
ifdef MOZ_SMIL

View File

@ -40,7 +40,6 @@
#include "SVGMotionSMILType.h"
#include "nsSMILValue.h"
#include "nsDebug.h"
#include "nsSVGTransform.h"
#include "nsSVGAngle.h"
#include "nsIDOMSVGAngle.h"
#include "nsSVGPathElement.h"

View File

@ -0,0 +1,185 @@
/* -*- 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 ***** */
#include "SVGTransform.h"
#include "nsContentUtils.h"
#include "nsTextFormatter.h"
namespace {
const double radPerDegree = 2.0*3.1415926535 / 360.0;
}
namespace mozilla {
void
SVGTransform::GetValueAsString(nsAString& aValue) const
{
PRUnichar buf[256];
switch (mType) {
case nsIDOMSVGTransform::SVG_TRANSFORM_TRANSLATE:
if (mMatrix.x0 != 0.0f)
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
NS_LITERAL_STRING("translate(%g, %g)").get(),
mMatrix.x0, mMatrix.y0);
else
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
NS_LITERAL_STRING("translate(%g)").get(),
mMatrix.x0);
break;
case nsIDOMSVGTransform::SVG_TRANSFORM_ROTATE:
if (mOriginX != 0.0f || mOriginY != 0.0f)
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
NS_LITERAL_STRING("rotate(%g, %g, %g)").get(),
mAngle, mOriginX, mOriginY);
else
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
NS_LITERAL_STRING("rotate(%g)").get(), mAngle);
break;
case nsIDOMSVGTransform::SVG_TRANSFORM_SCALE:
if (mMatrix.xx != mMatrix.yy)
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
NS_LITERAL_STRING("scale(%g, %g)").get(), mMatrix.xx, mMatrix.yy);
else
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
NS_LITERAL_STRING("scale(%g)").get(), mMatrix.xx);
break;
case nsIDOMSVGTransform::SVG_TRANSFORM_SKEWX:
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
NS_LITERAL_STRING("skewX(%g)").get(), mAngle);
break;
case nsIDOMSVGTransform::SVG_TRANSFORM_SKEWY:
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
NS_LITERAL_STRING("skewY(%g)").get(), mAngle);
break;
case nsIDOMSVGTransform::SVG_TRANSFORM_MATRIX:
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
NS_LITERAL_STRING("matrix(%g, %g, %g, %g, %g, %g)").get(),
mMatrix.xx, mMatrix.yx,
mMatrix.xy, mMatrix.yy,
mMatrix.x0, mMatrix.y0);
break;
default:
buf[0] = '\0';
NS_ERROR("unknown transformation type");
break;
}
aValue.Assign(buf);
}
void
SVGTransform::SetMatrix(const gfxMatrix& aMatrix)
{
mType = nsIDOMSVGTransform::SVG_TRANSFORM_MATRIX;
mMatrix = aMatrix;
// We set the other members here too, since operator== requires it and
// the DOM requires it for mAngle.
mAngle = 0.f;
mOriginX = 0.f;
mOriginY = 0.f;
}
void
SVGTransform::SetTranslate(float aTx, float aTy)
{
mType = nsIDOMSVGTransform::SVG_TRANSFORM_TRANSLATE;
mMatrix.Reset();
mMatrix.x0 = aTx;
mMatrix.y0 = aTy;
mAngle = 0.f;
mOriginX = 0.f;
mOriginY = 0.f;
}
void
SVGTransform::SetScale(float aSx, float aSy)
{
mType = nsIDOMSVGTransform::SVG_TRANSFORM_SCALE;
mMatrix.Reset();
mMatrix.xx = aSx;
mMatrix.yy = aSy;
mAngle = 0.f;
mOriginX = 0.f;
mOriginY = 0.f;
}
void
SVGTransform::SetRotate(float aAngle, float aCx, float aCy)
{
mType = nsIDOMSVGTransform::SVG_TRANSFORM_ROTATE;
mMatrix.Reset();
mMatrix.Translate(gfxPoint(aCx, aCy));
mMatrix.Rotate(aAngle*radPerDegree);
mMatrix.Translate(gfxPoint(-aCx, -aCy));
mAngle = aAngle;
mOriginX = aCx;
mOriginY = aCy;
}
nsresult
SVGTransform::SetSkewX(float aAngle)
{
double ta = tan(aAngle*radPerDegree);
NS_ENSURE_FINITE(ta, NS_ERROR_DOM_SVG_INVALID_VALUE_ERR);
mType = nsIDOMSVGTransform::SVG_TRANSFORM_SKEWX;
mMatrix.Reset();
mMatrix.xy = ta;
mAngle = aAngle;
mOriginX = 0.f;
mOriginY = 0.f;
return NS_OK;
}
nsresult
SVGTransform::SetSkewY(float aAngle)
{
double ta = tan(aAngle*radPerDegree);
NS_ENSURE_FINITE(ta, NS_ERROR_DOM_SVG_INVALID_VALUE_ERR);
mType = nsIDOMSVGTransform::SVG_TRANSFORM_SKEWY;
mMatrix.Reset();
mMatrix.yx = ta;
mAngle = aAngle;
mOriginX = 0.f;
mOriginY = 0.f;
return NS_OK;
}
} // namespace mozilla

View File

@ -0,0 +1,117 @@
/* -*- 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_SVGTRANSFORM_H__
#define MOZILLA_SVGTRANSFORM_H__
#include "gfxMatrix.h"
#include "nsIDOMSVGTransform.h"
namespace mozilla {
/*
* The DOM wrapper class for this class is DOMSVGTransformMatrix.
*/
class SVGTransform
{
public:
// Default ctor initialises to matrix type with identity matrix
SVGTransform()
: mMatrix() // Initialises to identity
, mAngle(0.f)
, mOriginX(0.f)
, mOriginY(0.f)
, mType(nsIDOMSVGTransform::SVG_TRANSFORM_MATRIX)
{ }
SVGTransform(const gfxMatrix& aMatrix)
: mMatrix(aMatrix)
, mAngle(0.f)
, mOriginX(0.f)
, mOriginY(0.f)
, mType(nsIDOMSVGTransform::SVG_TRANSFORM_MATRIX)
{ }
PRBool operator==(const SVGTransform& rhs) const {
return mType == rhs.mType &&
MatricesEqual(mMatrix, rhs.mMatrix) &&
mAngle == rhs.mAngle &&
mOriginX == rhs.mOriginX &&
mOriginY == rhs.mOriginY;
}
void GetValueAsString(nsAString& aValue) const;
float Angle() const {
return mAngle;
}
void GetRotationOrigin(float& aOriginX, float& aOriginY) const {
aOriginX = mOriginX;
aOriginY = mOriginY;
}
PRUint16 Type() const {
return mType;
}
const gfxMatrix& Matrix() const { return mMatrix; }
void SetMatrix(const gfxMatrix& aMatrix);
void SetTranslate(float aTx, float aTy);
void SetScale(float aSx, float aSy);
void SetRotate(float aAngle, float aCx, float aCy);
nsresult SetSkewX(float aAngle);
nsresult SetSkewY(float aAngle);
protected:
static PRBool MatricesEqual(const gfxMatrix& a, const gfxMatrix& b)
{
return a.xx == b.xx &&
a.yx == b.yx &&
a.xy == b.xy &&
a.yy == b.yy &&
a.x0 == b.x0 &&
a.y0 == b.y0;
}
gfxMatrix mMatrix;
float mAngle, mOriginX, mOriginY;
PRUint16 mType;
};
} // namespace mozilla
#endif // MOZILLA_SVGTRANSFORM_H__

View File

@ -1,412 +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 "nsSVGTransform.h"
#include "prdtoa.h"
#include "nsSVGMatrix.h"
#include "nsISVGValueUtils.h"
#include "nsWeakReference.h"
#include "nsSVGMatrix.h"
#include "nsTextFormatter.h"
#include "nsContentUtils.h"
#include "nsDOMError.h"
const double radPerDegree = 2.0*3.1415926535 / 360.0;
//----------------------------------------------------------------------
// Implementation
nsresult
nsSVGTransform::Create(nsIDOMSVGTransform** aResult)
{
nsSVGTransform *pl = new nsSVGTransform();
NS_ENSURE_TRUE(pl, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(pl);
if (NS_FAILED(pl->Init())) {
NS_RELEASE(pl);
*aResult = nsnull;
return NS_ERROR_FAILURE;
}
*aResult = pl;
return NS_OK;
}
nsSVGTransform::nsSVGTransform()
: mAngle(0.0f),
mOriginX(0.0f),
mOriginY(0.0f),
mType( SVG_TRANSFORM_MATRIX )
{
}
nsSVGTransform::~nsSVGTransform()
{
NS_REMOVE_SVGVALUE_OBSERVER(mMatrix);
}
nsresult nsSVGTransform::Init()
{
nsresult rv = NS_NewSVGMatrix(getter_AddRefs(mMatrix));
NS_ADD_SVGVALUE_OBSERVER(mMatrix);
return rv;
}
//----------------------------------------------------------------------
// nsISupports methods:
NS_IMPL_ADDREF(nsSVGTransform)
NS_IMPL_RELEASE(nsSVGTransform)
DOMCI_DATA(SVGTransform, nsSVGTransform)
NS_INTERFACE_MAP_BEGIN(nsSVGTransform)
NS_INTERFACE_MAP_ENTRY(nsISVGValue)
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGTransform)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY(nsISVGValueObserver)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGTransform)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISVGValue)
NS_INTERFACE_MAP_END
//----------------------------------------------------------------------
// nsISVGValue methods:
NS_IMETHODIMP
nsSVGTransform::SetValueString(const nsAString& aValue)
{
NS_NOTYETIMPLEMENTED("nsSVGTransform::SetValueString");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsSVGTransform::GetValueString(nsAString& aValue)
{
PRUnichar buf[256];
switch (mType) {
case nsIDOMSVGTransform::SVG_TRANSFORM_TRANSLATE:
{
float dx, dy;
mMatrix->GetE(&dx);
mMatrix->GetF(&dy);
if (dy != 0.0f)
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar), NS_LITERAL_STRING("translate(%g, %g)").get(), dx, dy);
else
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar), NS_LITERAL_STRING("translate(%g)").get(), dx);
}
break;
case nsIDOMSVGTransform::SVG_TRANSFORM_ROTATE:
{
if (mOriginX != 0.0f || mOriginY != 0.0f)
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
NS_LITERAL_STRING("rotate(%g, %g, %g)").get(),
mAngle, mOriginX, mOriginY);
else
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
NS_LITERAL_STRING("rotate(%g)").get(), mAngle);
}
break;
case nsIDOMSVGTransform::SVG_TRANSFORM_SCALE:
{
float sx, sy;
mMatrix->GetA(&sx);
mMatrix->GetD(&sy);
if (sy != sx)
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
NS_LITERAL_STRING("scale(%g, %g)").get(), sx, sy);
else
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
NS_LITERAL_STRING("scale(%g)").get(), sx);
}
break;
case nsIDOMSVGTransform::SVG_TRANSFORM_SKEWX:
{
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
NS_LITERAL_STRING("skewX(%g)").get(), mAngle);
}
break;
case nsIDOMSVGTransform::SVG_TRANSFORM_SKEWY:
{
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
NS_LITERAL_STRING("skewY(%g)").get(), mAngle);
}
break;
case nsIDOMSVGTransform::SVG_TRANSFORM_MATRIX:
{
float a,b,c,d,e,f;
mMatrix->GetA(&a);
mMatrix->GetB(&b);
mMatrix->GetC(&c);
mMatrix->GetD(&d);
mMatrix->GetE(&e);
mMatrix->GetF(&f);
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
NS_LITERAL_STRING("matrix(%g, %g, %g, %g, %g, %g)").get(),
a, b, c, d, e, f);
}
break;
default:
buf[0] = '\0';
NS_ERROR("unknown transformation type");
break;
}
aValue.Assign(buf);
return NS_OK;
}
//----------------------------------------------------------------------
// nsISVGValueObserver methods:
NS_IMETHODIMP nsSVGTransform::WillModifySVGObservable(nsISVGValue* observable,
modificationType aModType)
{
WillModify();
return NS_OK;
}
NS_IMETHODIMP nsSVGTransform::DidModifySVGObservable (nsISVGValue* observable,
modificationType aModType)
{
// we become a general matrix transform if mMatrix changes
mType = SVG_TRANSFORM_MATRIX;
mAngle = 0.0f;
DidModify();
return NS_OK;
}
//----------------------------------------------------------------------
// nsIDOMSVGTransform methods:
/* readonly attribute unsigned short type; */
NS_IMETHODIMP nsSVGTransform::GetType(PRUint16 *aType)
{
*aType = mType;
return NS_OK;
}
/* readonly attribute nsIDOMSVGMatrix matrix; */
NS_IMETHODIMP nsSVGTransform::GetMatrix(nsIDOMSVGMatrix * *aMatrix)
{
*aMatrix = mMatrix;
NS_IF_ADDREF(*aMatrix);
return NS_OK;
}
/* readonly attribute float angle; */
NS_IMETHODIMP nsSVGTransform::GetAngle(float *aAngle)
{
*aAngle = mAngle;
return NS_OK;
}
/* void setMatrix (in nsIDOMSVGMatrix matrix); */
NS_IMETHODIMP nsSVGTransform::SetMatrix(nsIDOMSVGMatrix *matrix)
{
float a, b, c, d, e, f;
if (!matrix)
return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
WillModify();
mType = SVG_TRANSFORM_MATRIX;
mAngle = 0.0f;
matrix->GetA(&a);
matrix->GetB(&b);
matrix->GetC(&c);
matrix->GetD(&d);
matrix->GetE(&e);
matrix->GetF(&f);
NS_REMOVE_SVGVALUE_OBSERVER(mMatrix);
mMatrix->SetA(a);
mMatrix->SetB(b);
mMatrix->SetC(c);
mMatrix->SetD(d);
mMatrix->SetE(e);
mMatrix->SetF(f);
NS_ADD_SVGVALUE_OBSERVER(mMatrix);
DidModify();
return NS_OK;
}
/* void setTranslate (in float tx, in float ty); */
NS_IMETHODIMP nsSVGTransform::SetTranslate(float tx, float ty)
{
NS_ENSURE_FINITE2(tx, ty, NS_ERROR_ILLEGAL_VALUE);
WillModify();
mType = SVG_TRANSFORM_TRANSLATE;
mAngle = 0.0f;
NS_REMOVE_SVGVALUE_OBSERVER(mMatrix);
mMatrix->SetA(1.0f);
mMatrix->SetB(0.0f);
mMatrix->SetC(0.0f);
mMatrix->SetD(1.0f);
mMatrix->SetE(tx);
mMatrix->SetF(ty);
NS_ADD_SVGVALUE_OBSERVER(mMatrix);
DidModify();
return NS_OK;
}
/* void setScale (in float sx, in float sy); */
NS_IMETHODIMP nsSVGTransform::SetScale(float sx, float sy)
{
NS_ENSURE_FINITE2(sx, sy, NS_ERROR_ILLEGAL_VALUE);
WillModify();
mType = SVG_TRANSFORM_SCALE;
mAngle = 0.0f;
NS_REMOVE_SVGVALUE_OBSERVER(mMatrix);
mMatrix->SetA(sx);
mMatrix->SetB(0.0f);
mMatrix->SetC(0.0f);
mMatrix->SetD(sy);
mMatrix->SetE(0.0f);
mMatrix->SetF(0.0f);
NS_ADD_SVGVALUE_OBSERVER(mMatrix);
DidModify();
return NS_OK;
}
/* void setRotate (in float angle, in float cx, in float cy); */
NS_IMETHODIMP nsSVGTransform::SetRotate(float angle, float cx, float cy)
{
NS_ENSURE_FINITE3(angle, cx, cy, NS_ERROR_ILLEGAL_VALUE);
WillModify();
mType = SVG_TRANSFORM_ROTATE;
mAngle = angle;
mOriginX = cx;
mOriginY = cy;
gfxMatrix matrix(1, 0, 0, 1, cx, cy);
matrix.Rotate(angle * radPerDegree);
matrix.Translate(gfxPoint(-cx, -cy));
NS_REMOVE_SVGVALUE_OBSERVER(mMatrix);
mMatrix->SetA(static_cast<float>(matrix.xx));
mMatrix->SetB(static_cast<float>(matrix.yx));
mMatrix->SetC(static_cast<float>(matrix.xy));
mMatrix->SetD(static_cast<float>(matrix.yy));
mMatrix->SetE(static_cast<float>(matrix.x0));
mMatrix->SetF(static_cast<float>(matrix.y0));
NS_ADD_SVGVALUE_OBSERVER(mMatrix);
DidModify();
return NS_OK;
}
/* void setSkewX (in float angle); */
NS_IMETHODIMP nsSVGTransform::SetSkewX(float angle)
{
NS_ENSURE_FINITE(angle, NS_ERROR_ILLEGAL_VALUE);
float ta = static_cast<float>(tan(angle * radPerDegree));
NS_ENSURE_FINITE(ta, NS_ERROR_DOM_SVG_INVALID_VALUE_ERR);
WillModify();
mType = SVG_TRANSFORM_SKEWX;
mAngle = angle;
NS_REMOVE_SVGVALUE_OBSERVER(mMatrix);
mMatrix->SetA(1.0f);
mMatrix->SetB(0.0f);
mMatrix->SetC(ta);
mMatrix->SetD(1.0f);
mMatrix->SetE(0.0f);
mMatrix->SetF(0.0f);
NS_ADD_SVGVALUE_OBSERVER(mMatrix);
DidModify();
return NS_OK;
}
/* void setSkewY (in float angle); */
NS_IMETHODIMP nsSVGTransform::SetSkewY(float angle)
{
NS_ENSURE_FINITE(angle, NS_ERROR_ILLEGAL_VALUE);
float ta = static_cast<float>(tan(angle * radPerDegree));
NS_ENSURE_FINITE(ta, NS_ERROR_DOM_SVG_INVALID_VALUE_ERR);
WillModify();
mType = SVG_TRANSFORM_SKEWY;
mAngle = angle;
NS_REMOVE_SVGVALUE_OBSERVER(mMatrix);
mMatrix->SetA(1.0f);
mMatrix->SetB(ta);
mMatrix->SetC(0.0f);
mMatrix->SetD(1.0f);
mMatrix->SetE(0.0f);
mMatrix->SetF(0.0f);
NS_ADD_SVGVALUE_OBSERVER(mMatrix);
DidModify();
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
// Exported creation functions:
nsresult
NS_NewSVGTransform(nsIDOMSVGTransform** result)
{
return nsSVGTransform::Create(result);
}

View File

@ -1,100 +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_SVGTRANSFORM_H__
#define __NS_SVGTRANSFORM_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
NS_NewSVGTransform(nsIDOMSVGTransform** result);
// XXX we'll need this prototype-based stuff to support unsetting:
//nsresult NS_NewSVGTransform(nsIDOMSVGTransform** result,
// nsIDOMSVGTransform* prototype);
#endif //__NS_SVGTRANSFORM_H__