Bug 602759 part 3 - Rewrite nsSVGMatrix and use gfxMatrix instead; r=jwatt

--HG--
rename : content/svg/content/src/nsSVGMatrix.cpp => content/svg/content/src/DOMSVGMatrix.cpp
rename : content/svg/content/src/nsSVGMatrix.h => content/svg/content/src/DOMSVGMatrix.h
This commit is contained in:
Brian Birtles 2011-09-25 22:03:26 +01:00
Родитель 036a332544
Коммит dc867fcc84
4 изменённых файлов: 404 добавлений и 395 удалений

Просмотреть файл

@ -0,0 +1,332 @@
/* -*- 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 ***** */
#include "DOMSVGMatrix.h"
#include "nsDOMError.h"
#include <math.h>
#include "nsContentUtils.h"
const double radPerDegree = 2.0*3.1415926535 / 360.0;
namespace mozilla {
//----------------------------------------------------------------------
// nsISupports methods:
// Make sure we clear the weak ref in the owning transform (if there is one)
// upon unlink.
NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGMatrix)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGMatrix)
if (tmp->mTransform) {
tmp->mTransform->ClearMatrixTearoff(tmp);
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTransform)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGMatrix)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTransform)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMSVGMatrix)
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMSVGMatrix)
} // namespace mozilla
DOMCI_DATA(SVGMatrix, mozilla::DOMSVGMatrix)
namespace mozilla {
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMSVGMatrix)
NS_INTERFACE_MAP_ENTRY(mozilla::DOMSVGMatrix) // pseudo-interface
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGMatrix)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGMatrix)
NS_INTERFACE_MAP_END
//----------------------------------------------------------------------
// nsIDOMSVGMatrix methods:
/* attribute float a; */
NS_IMETHODIMP DOMSVGMatrix::GetA(float *aA)
{
*aA = static_cast<float>(Matrix().xx);
return NS_OK;
}
NS_IMETHODIMP DOMSVGMatrix::SetA(float aA)
{
if (IsAnimVal()) {
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
}
NS_ENSURE_FINITE(aA, NS_ERROR_ILLEGAL_VALUE);
gfxMatrix mx = Matrix();
mx.xx = aA;
SetMatrix(mx);
return NS_OK;
}
/* attribute float b; */
NS_IMETHODIMP DOMSVGMatrix::GetB(float *aB)
{
*aB = static_cast<float>(Matrix().yx);
return NS_OK;
}
NS_IMETHODIMP DOMSVGMatrix::SetB(float aB)
{
if (IsAnimVal()) {
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
}
NS_ENSURE_FINITE(aB, NS_ERROR_ILLEGAL_VALUE);
gfxMatrix mx = Matrix();
mx.yx = aB;
SetMatrix(mx);
return NS_OK;
}
/* attribute float c; */
NS_IMETHODIMP DOMSVGMatrix::GetC(float *aC)
{
*aC = static_cast<float>(Matrix().xy);
return NS_OK;
}
NS_IMETHODIMP DOMSVGMatrix::SetC(float aC)
{
if (IsAnimVal()) {
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
}
NS_ENSURE_FINITE(aC, NS_ERROR_ILLEGAL_VALUE);
gfxMatrix mx = Matrix();
mx.xy = aC;
SetMatrix(mx);
return NS_OK;
}
/* attribute float d; */
NS_IMETHODIMP DOMSVGMatrix::GetD(float *aD)
{
*aD = static_cast<float>(Matrix().yy);
return NS_OK;
}
NS_IMETHODIMP DOMSVGMatrix::SetD(float aD)
{
if (IsAnimVal()) {
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
}
NS_ENSURE_FINITE(aD, NS_ERROR_ILLEGAL_VALUE);
gfxMatrix mx = Matrix();
mx.yy = aD;
SetMatrix(mx);
return NS_OK;
}
/* attribute float e; */
NS_IMETHODIMP DOMSVGMatrix::GetE(float *aE)
{
*aE = static_cast<float>(Matrix().x0);
return NS_OK;
}
NS_IMETHODIMP DOMSVGMatrix::SetE(float aE)
{
if (IsAnimVal()) {
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
}
NS_ENSURE_FINITE(aE, NS_ERROR_ILLEGAL_VALUE);
gfxMatrix mx = Matrix();
mx.x0 = aE;
SetMatrix(mx);
return NS_OK;
}
/* attribute float f; */
NS_IMETHODIMP DOMSVGMatrix::GetF(float *aF)
{
*aF = static_cast<float>(Matrix().y0);
return NS_OK;
}
NS_IMETHODIMP DOMSVGMatrix::SetF(float aF)
{
if (IsAnimVal()) {
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
}
NS_ENSURE_FINITE(aF, NS_ERROR_ILLEGAL_VALUE);
gfxMatrix mx = Matrix();
mx.y0 = aF;
SetMatrix(mx);
return NS_OK;
}
/* nsIDOMSVGMatrix multiply (in nsIDOMSVGMatrix secondMatrix); */
NS_IMETHODIMP DOMSVGMatrix::Multiply(nsIDOMSVGMatrix *secondMatrix,
nsIDOMSVGMatrix **_retval)
{
*_retval = nsnull;
nsCOMPtr<DOMSVGMatrix> domMatrix = do_QueryInterface(secondMatrix);
if (!domMatrix)
return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
NS_ADDREF(*_retval = new DOMSVGMatrix(domMatrix->Matrix() * Matrix()));
return NS_OK;
}
/* nsIDOMSVGMatrix inverse (); */
NS_IMETHODIMP DOMSVGMatrix::Inverse(nsIDOMSVGMatrix **_retval)
{
*_retval = nsnull;
if (Matrix().IsSingular())
return NS_ERROR_DOM_SVG_MATRIX_NOT_INVERTABLE;
NS_ADDREF(*_retval = new DOMSVGMatrix(gfxMatrix(Matrix()).Invert()));
return NS_OK;
}
/* nsIDOMSVGMatrix translate (in float x, in float y); */
NS_IMETHODIMP DOMSVGMatrix::Translate(float x, float y,
nsIDOMSVGMatrix **_retval)
{
*_retval = nsnull;
NS_ENSURE_FINITE2(x, y, NS_ERROR_ILLEGAL_VALUE);
NS_ADDREF(*_retval =
new DOMSVGMatrix(gfxMatrix(Matrix()).Translate(gfxPoint(x, y))));
return NS_OK;
}
/* nsIDOMSVGMatrix scale (in float scaleFactor); */
NS_IMETHODIMP DOMSVGMatrix::Scale(float scaleFactor, nsIDOMSVGMatrix **_retval)
{
return ScaleNonUniform(scaleFactor, scaleFactor, _retval);
}
/* nsIDOMSVGMatrix scaleNonUniform (in float scaleFactorX,
* in float scaleFactorY); */
NS_IMETHODIMP DOMSVGMatrix::ScaleNonUniform(float scaleFactorX,
float scaleFactorY,
nsIDOMSVGMatrix **_retval)
{
*_retval = nsnull;
NS_ENSURE_FINITE2(scaleFactorX, scaleFactorY, NS_ERROR_ILLEGAL_VALUE);
NS_ADDREF(*_retval =
new DOMSVGMatrix(gfxMatrix(Matrix()).Scale(scaleFactorX, scaleFactorY)));
return NS_OK;
}
/* nsIDOMSVGMatrix rotate (in float angle); */
NS_IMETHODIMP DOMSVGMatrix::Rotate(float angle, nsIDOMSVGMatrix **_retval)
{
*_retval = nsnull;
NS_ENSURE_FINITE(angle, NS_ERROR_ILLEGAL_VALUE);
NS_ADDREF(*_retval =
new DOMSVGMatrix(gfxMatrix(Matrix()).Rotate(angle*radPerDegree)));
return NS_OK;
}
/* nsIDOMSVGMatrix rotateFromVector (in float x, in float y); */
NS_IMETHODIMP DOMSVGMatrix::RotateFromVector(float x, float y,
nsIDOMSVGMatrix **_retval)
{
*_retval = nsnull;
NS_ENSURE_FINITE2(x, y, NS_ERROR_ILLEGAL_VALUE);
if (x == 0.0 || y == 0.0)
return NS_ERROR_DOM_SVG_INVALID_VALUE_ERR;
NS_ADDREF(*_retval =
new DOMSVGMatrix(gfxMatrix(Matrix()).Rotate(atan2(y, x))));
return NS_OK;
}
/* nsIDOMSVGMatrix flipX (); */
NS_IMETHODIMP DOMSVGMatrix::FlipX(nsIDOMSVGMatrix **_retval)
{
const gfxMatrix& mx = Matrix();
NS_ADDREF(*_retval = new DOMSVGMatrix(gfxMatrix(-mx.xx, -mx.yx,
mx.xy, mx.yy,
mx.x0, mx.y0)));
return NS_OK;
}
/* nsIDOMSVGMatrix flipY (); */
NS_IMETHODIMP DOMSVGMatrix::FlipY(nsIDOMSVGMatrix **_retval)
{
const gfxMatrix& mx = Matrix();
NS_ADDREF(*_retval = new DOMSVGMatrix(gfxMatrix(mx.xx, mx.yx,
-mx.xy, -mx.yy,
mx.x0, mx.y0)));
return NS_OK;
}
/* nsIDOMSVGMatrix skewX (in float angle); */
NS_IMETHODIMP DOMSVGMatrix::SkewX(float angle, nsIDOMSVGMatrix **_retval)
{
*_retval = nsnull;
NS_ENSURE_FINITE(angle, NS_ERROR_ILLEGAL_VALUE);
double ta = tan( angle*radPerDegree );
NS_ENSURE_FINITE(ta, NS_ERROR_DOM_SVG_INVALID_VALUE_ERR);
const gfxMatrix& mx = Matrix();
gfxMatrix skewMx(mx.xx, mx.yx,
(float) (mx.xy + mx.xx*ta), (float) (mx.yy + mx.yx*ta),
mx.x0, mx.y0);
NS_ADDREF(*_retval = new DOMSVGMatrix(skewMx));
return NS_OK;
}
/* nsIDOMSVGMatrix skewY (in float angle); */
NS_IMETHODIMP DOMSVGMatrix::SkewY(float angle, nsIDOMSVGMatrix **_retval)
{
*_retval = nsnull;
NS_ENSURE_FINITE(angle, NS_ERROR_ILLEGAL_VALUE);
double ta = tan( angle*radPerDegree );
NS_ENSURE_FINITE(ta, NS_ERROR_DOM_SVG_INVALID_VALUE_ERR);
const gfxMatrix& mx = Matrix();
gfxMatrix skewMx((float) (mx.xx + mx.xy*ta), (float) (mx.yx + mx.yy*ta),
mx.xy, mx.yy,
mx.x0, mx.y0);
NS_ADDREF(*_retval = new DOMSVGMatrix(skewMx));
return NS_OK;
}
} // namespace mozilla

Просмотреть файл

@ -1,5 +1,6 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
/* -*- 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
@ -21,6 +22,7 @@
*
* 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"),
@ -66,29 +68,79 @@
* up.
*/
#ifndef __NS_SVGMATRIX_H__
#define __NS_SVGMATRIX_H__
#ifndef MOZILLA_DOMSVGMATRIX_H__
#define MOZILLA_DOMSVGMATRIX_H__
#include "nsIDOMSVGMatrix.h"
#include "DOMSVGTransform.h"
#include "gfxMatrix.h"
#include "nsAutoPtr.h"
#include "nsCycleCollectionParticipant.h"
nsresult
NS_NewSVGMatrix(nsIDOMSVGMatrix** result,
float a = 1.0f, float b = 0.0f,
float c = 0.0f, float d = 1.0f,
float e = 0.0f, float f = 0.0f);
// We make DOMSVGMatrix a pseudo-interface to allow us to QI to it in order
// to check that the objects that scripts pass in are our *native* matrix
// objects.
//
// {633419E5-7E88-4C3E-8A9A-856F635E90A3}
#define MOZILLA_DOMSVGMATRIX_IID \
{ 0x633419E5, 0x7E88, 0x4C3E, \
{ 0x8A, 0x9A, 0x85, 0x6F, 0x63, 0x5E, 0x90, 0xA3 } }
already_AddRefed<nsIDOMSVGMatrix>
NS_NewSVGMatrix(const gfxMatrix &aMatrix);
namespace mozilla {
#define NS_ENSURE_NATIVE_MATRIX(obj, retval) \
{ \
nsCOMPtr<nsISVGValue> val = do_QueryInterface(obj); \
if (!val) { \
*retval = nsnull; \
return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR; \
} \
/**
* DOM wrapper for an SVG matrix.
*/
class DOMSVGMatrix : public nsIDOMSVGMatrix
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOMSVGMATRIX_IID)
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(DOMSVGMatrix)
NS_DECL_NSIDOMSVGMATRIX
/**
* Ctor for DOMSVGMatrix objects that belong to a DOMSVGTransform.
*/
DOMSVGMatrix(DOMSVGTransform& aTransform) : mTransform(&aTransform) { }
/**
* Ctors for DOMSVGMatrix objects created independently of a DOMSVGTransform.
*/
DOMSVGMatrix() { } // Default ctor for gfxMatrix will produce identity mx
DOMSVGMatrix(const gfxMatrix &aMatrix) : mMatrix(aMatrix) { }
~DOMSVGMatrix() {
if (mTransform) {
mTransform->ClearMatrixTearoff(this);
}
}
#endif //__NS_SVGMATRIX_H__
const gfxMatrix& Matrix() const {
return mTransform ? mTransform->Matrix() : mMatrix;
}
private:
void SetMatrix(const gfxMatrix& aMatrix) {
if (mTransform) {
mTransform->SetMatrix(aMatrix);
} else {
mMatrix = aMatrix;
}
}
PRBool IsAnimVal() const {
return mTransform ? mTransform->IsAnimVal() : PR_FALSE;
}
nsRefPtr<DOMSVGTransform> mTransform;
// Typically we operate on the matrix data accessed via mTransform but for
// matrices that exist independently of an SVGTransform we use mMatrix below.
gfxMatrix mMatrix;
};
NS_DEFINE_STATIC_IID_ACCESSOR(DOMSVGMatrix, MOZILLA_DOMSVGMATRIX_IID)
} // namespace mozilla
#endif // MOZILLA_DOMSVGMATRIX_H__

Просмотреть файл

@ -53,6 +53,7 @@ CPPSRCS = \
DOMSVGAnimatedNumberList.cpp \
DOMSVGLength.cpp \
DOMSVGLengthList.cpp \
DOMSVGMatrix.cpp \
DOMSVGNumber.cpp \
DOMSVGNumberList.cpp \
DOMSVGPathSeg.cpp \
@ -90,7 +91,6 @@ CPPSRCS = \
nsSVGLineElement.cpp \
nsSVGMarkerElement.cpp \
nsSVGMaskElement.cpp \
nsSVGMatrix.cpp \
nsSVGMetadataElement.cpp \
nsSVGNumber2.cpp \
nsSVGNumberPair.cpp \
@ -172,7 +172,6 @@ EXPORTS = \
nsISVGValueUtils.h \
nsSVGFeatures.h \
nsSVGRect.h \
nsSVGMatrix.h \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -1,374 +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 "nsSVGMatrix.h"
#include "nsDOMError.h"
#include "nsSVGValue.h"
#include <math.h>
#include "nsContentUtils.h"
#include "nsISupportsImpl.h"
const double radPerDegree = 2.0*3.1415926535 / 360.0;
class nsSVGMatrix : public nsIDOMSVGMatrix,
public nsSVGValue
{
public:
nsSVGMatrix(float a, float b, float c, float d, float e, float f);
// nsISupports interface:
NS_DECL_ISUPPORTS
// nsIDOMSVGMatrix interface:
NS_DECL_NSIDOMSVGMATRIX
// nsISVGValue interface:
NS_IMETHOD SetValueString(const nsAString& aValue);
NS_IMETHOD GetValueString(nsAString& aValue);
protected:
float mA, mB, mC, mD, mE, mF;
// implementation helpers:
nsresult RotateRadians(float rad, nsIDOMSVGMatrix **_retval);
};
//----------------------------------------------------------------------
// Implementation
nsresult
NS_NewSVGMatrix(nsIDOMSVGMatrix** result,
float a, float b, float c,
float d, float e, float f)
{
*result = new nsSVGMatrix(a, b, c, d, e, f);
if (!*result)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*result);
return NS_OK;
}
already_AddRefed<nsIDOMSVGMatrix>
NS_NewSVGMatrix(const gfxMatrix &aMatrix)
{
nsSVGMatrix *matrix = new nsSVGMatrix(aMatrix.xx, aMatrix.yx, aMatrix.xy,
aMatrix.yy, aMatrix.x0, aMatrix.y0);
NS_IF_ADDREF(matrix);
return matrix;
}
nsSVGMatrix::nsSVGMatrix(float a, float b, float c,
float d, float e, float f)
: mA(a), mB(b), mC(c), mD(d), mE(e), mF(f)
{
}
//----------------------------------------------------------------------
// nsISupports methods:
NS_IMPL_ADDREF(nsSVGMatrix)
NS_IMPL_RELEASE(nsSVGMatrix)
DOMCI_DATA(SVGMatrix, nsSVGMatrix)
NS_INTERFACE_MAP_BEGIN(nsSVGMatrix)
NS_INTERFACE_MAP_ENTRY(nsISVGValue)
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGMatrix)
// NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
// NS_INTERFACE_MAP_ENTRY(nsISVGValueObserver)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGMatrix)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISVGValue)
NS_INTERFACE_MAP_END
//----------------------------------------------------------------------
// nsIDOMSVGMatrix methods:
/* attribute float a; */
NS_IMETHODIMP nsSVGMatrix::GetA(float *aA)
{
*aA = mA;
return NS_OK;
}
NS_IMETHODIMP nsSVGMatrix::SetA(float aA)
{
NS_ENSURE_FINITE(aA, NS_ERROR_ILLEGAL_VALUE);
WillModify();
mA = aA;
DidModify();
return NS_OK;
}
/* attribute float b; */
NS_IMETHODIMP nsSVGMatrix::GetB(float *aB)
{
*aB = mB;
return NS_OK;
}
NS_IMETHODIMP nsSVGMatrix::SetB(float aB)
{
NS_ENSURE_FINITE(aB, NS_ERROR_ILLEGAL_VALUE);
WillModify();
mB = aB;
DidModify();
return NS_OK;
}
/* attribute float c; */
NS_IMETHODIMP nsSVGMatrix::GetC(float *aC)
{
*aC = mC;
return NS_OK;
}
NS_IMETHODIMP nsSVGMatrix::SetC(float aC)
{
NS_ENSURE_FINITE(aC, NS_ERROR_ILLEGAL_VALUE);
WillModify();
mC = aC;
DidModify();
return NS_OK;
}
/* attribute float d; */
NS_IMETHODIMP nsSVGMatrix::GetD(float *aD)
{
*aD = mD;
return NS_OK;
}
NS_IMETHODIMP nsSVGMatrix::SetD(float aD)
{
NS_ENSURE_FINITE(aD, NS_ERROR_ILLEGAL_VALUE);
WillModify();
mD = aD;
DidModify();
return NS_OK;
}
/* attribute float e; */
NS_IMETHODIMP nsSVGMatrix::GetE(float *aE)
{
*aE = mE;
return NS_OK;
}
NS_IMETHODIMP nsSVGMatrix::SetE(float aE)
{
NS_ENSURE_FINITE(aE, NS_ERROR_ILLEGAL_VALUE);
WillModify();
mE = aE;
DidModify();
return NS_OK;
}
/* attribute float f; */
NS_IMETHODIMP nsSVGMatrix::GetF(float *aF)
{
*aF = mF;
return NS_OK;
}
NS_IMETHODIMP nsSVGMatrix::SetF(float aF)
{
NS_ENSURE_FINITE(aF, NS_ERROR_ILLEGAL_VALUE);
WillModify();
mF = aF;
DidModify();
return NS_OK;
}
/* nsIDOMSVGMatrix multiply (in nsIDOMSVGMatrix secondMatrix); */
NS_IMETHODIMP nsSVGMatrix::Multiply(nsIDOMSVGMatrix *secondMatrix,
nsIDOMSVGMatrix **_retval)
{
if (!secondMatrix)
return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
float sa,sb,sc,sd,se,sf;
secondMatrix->GetA(&sa);
secondMatrix->GetB(&sb);
secondMatrix->GetC(&sc);
secondMatrix->GetD(&sd);
secondMatrix->GetE(&se);
secondMatrix->GetF(&sf);
return NS_NewSVGMatrix(_retval,
mA*sa + mC*sb, mB*sa + mD*sb,
mA*sc + mC*sd, mB*sc + mD*sd,
mA*se + mC*sf + mE, mB*se + mD*sf + mF);
}
/* nsIDOMSVGMatrix inverse (); */
NS_IMETHODIMP nsSVGMatrix::Inverse(nsIDOMSVGMatrix **_retval)
{
double det = mA*mD - mC*mB;
if (det == 0.0)
return NS_ERROR_DOM_SVG_MATRIX_NOT_INVERTABLE;
return NS_NewSVGMatrix(_retval,
(float)( mD/det), (float)(-mB/det),
(float)(-mC/det), (float)( mA/det),
(float)((mC*mF - mE*mD)/det), (float)((mE*mB - mA*mF)/det));
}
/* nsIDOMSVGMatrix translate (in float x, in float y); */
NS_IMETHODIMP nsSVGMatrix::Translate(float x, float y, nsIDOMSVGMatrix **_retval)
{
NS_ENSURE_FINITE2(x, y, NS_ERROR_ILLEGAL_VALUE);
return NS_NewSVGMatrix(_retval,
mA, mB,
mC, mD,
mA*x + mC*y + mE, mB*x + mD*y + mF);
}
/* nsIDOMSVGMatrix scale (in float scaleFactor); */
NS_IMETHODIMP nsSVGMatrix::Scale(float scaleFactor, nsIDOMSVGMatrix **_retval)
{
NS_ENSURE_FINITE(scaleFactor, NS_ERROR_ILLEGAL_VALUE);
return NS_NewSVGMatrix(_retval,
mA*scaleFactor, mB*scaleFactor,
mC*scaleFactor, mD*scaleFactor,
mE, mF);
}
/* nsIDOMSVGMatrix scaleNonUniform (in float scaleFactorX, in float scaleFactorY); */
NS_IMETHODIMP nsSVGMatrix::ScaleNonUniform(float scaleFactorX, float scaleFactorY, nsIDOMSVGMatrix **_retval)
{
NS_ENSURE_FINITE2(scaleFactorX, scaleFactorY, NS_ERROR_ILLEGAL_VALUE);
return NS_NewSVGMatrix(_retval,
mA*scaleFactorX, mB*scaleFactorX,
mC*scaleFactorY, mD*scaleFactorY,
mE, mF);
}
/* nsIDOMSVGMatrix rotate (in float angle); */
NS_IMETHODIMP nsSVGMatrix::Rotate(float angle, nsIDOMSVGMatrix **_retval)
{
NS_ENSURE_FINITE(angle, NS_ERROR_ILLEGAL_VALUE);
return RotateRadians(angle*radPerDegree, _retval);
}
/* nsIDOMSVGMatrix rotateFromVector (in float x, in float y); */
NS_IMETHODIMP nsSVGMatrix::RotateFromVector(float x, float y, nsIDOMSVGMatrix **_retval)
{
NS_ENSURE_FINITE2(x, y, NS_ERROR_ILLEGAL_VALUE);
if (x == 0.0 || y == 0.0)
return NS_ERROR_DOM_SVG_INVALID_VALUE_ERR;
double rad = atan2(y, x);
return RotateRadians(rad, _retval);
}
/* nsIDOMSVGMatrix flipX (); */
NS_IMETHODIMP nsSVGMatrix::FlipX(nsIDOMSVGMatrix **_retval)
{
return NS_NewSVGMatrix(_retval,
-mA, -mB,
mC, mD,
mE, mF);
}
/* nsIDOMSVGMatrix flipY (); */
NS_IMETHODIMP nsSVGMatrix::FlipY(nsIDOMSVGMatrix **_retval)
{
return NS_NewSVGMatrix(_retval,
mA, mB,
-mC, -mD,
mE, mF);
}
/* nsIDOMSVGMatrix skewX (in float angle); */
NS_IMETHODIMP nsSVGMatrix::SkewX(float angle, nsIDOMSVGMatrix **_retval)
{
NS_ENSURE_FINITE(angle, NS_ERROR_ILLEGAL_VALUE);
double ta = tan( angle*radPerDegree );
NS_ENSURE_FINITE(ta, NS_ERROR_DOM_SVG_INVALID_VALUE_ERR);
return NS_NewSVGMatrix(_retval,
mA, mB,
(float) ( mC + mA*ta), (float) ( mD + mB*ta),
mE, mF);
}
/* nsIDOMSVGMatrix skewY (in float angle); */
NS_IMETHODIMP nsSVGMatrix::SkewY(float angle, nsIDOMSVGMatrix **_retval)
{
NS_ENSURE_FINITE(angle, NS_ERROR_ILLEGAL_VALUE);
double ta = tan( angle*radPerDegree );
NS_ENSURE_FINITE(ta, NS_ERROR_DOM_SVG_INVALID_VALUE_ERR);
return NS_NewSVGMatrix(_retval,
(float) (mA + mC*ta), (float) (mB + mD*ta),
mC, mD,
mE, mF);
}
//----------------------------------------------------------------------
// nsISVGValue methods:
NS_IMETHODIMP
nsSVGMatrix::SetValueString(const nsAString& aValue)
{
NS_NOTYETIMPLEMENTED("nsSVGMatrix::SetValueString");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsSVGMatrix::GetValueString(nsAString& aValue)
{
NS_NOTYETIMPLEMENTED("nsSVGMatrix::GetValueString");
return NS_ERROR_NOT_IMPLEMENTED;
}
//----------------------------------------------------------------------
// Implementation helpers:
nsresult
nsSVGMatrix::RotateRadians(float rad, nsIDOMSVGMatrix **_retval)
{
double ca = cos(rad);
double sa = sin(rad);
return NS_NewSVGMatrix(_retval,
(float) (mA*ca + mC*sa), (float) (mB*ca + mD*sa),
(float) (mC*ca - mA*sa), (float) (mD*ca - mB*sa),
mE, mF);
}