author | David Zbarsky <dzbarsky@gmail.com> |
Sat, 22 Dec 2012 23:54:20 -0500 (2012-12-23) | |
changeset 116915 | 9b19cd969afcaab7b9e4fde83480e37db7c20f83 |
parent 116914 | 347128caddd541d65a16c830dc0310212668df93 |
child 116916 | 0ca634658b96fd7da279869443029e9144f22f16 |
push id | 24076 |
push user | ryanvm@gmail.com |
push date | Sun, 23 Dec 2012 20:50:19 +0000 (2012-12-23) |
treeherder | mozilla-central@4f74d77d6d8b [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bz |
bugs | 816778 |
milestone | 20.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/content/svg/content/src/DOMSVGMatrix.cpp +++ b/content/svg/content/src/DOMSVGMatrix.cpp @@ -3,297 +3,472 @@ * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "DOMSVGMatrix.h" #include "nsError.h" #include <math.h> #include "nsContentUtils.h" +#include "mozilla/dom/SVGMatrixBinding.h" const double radPerDegree = 2.0 * M_PI / 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(mTransform) +NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_UNLINK_END + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGMatrix) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTransform) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGMatrix) +NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER +NS_IMPL_CYCLE_COLLECTION_TRACE_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_WRAPPERCACHE_INTERFACE_MAP_ENTRY 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 +DOMSVGTransform* +DOMSVGMatrix::GetParentObject() const +{ + return mTransform; +} + +JSObject* +DOMSVGMatrix::WrapObject(JSContext* aCx, JSObject* aScope, bool* aTriedToWrap) +{ + return mozilla::dom::SVGMatrixBinding::Wrap(aCx, aScope, this, aTriedToWrap); +} + //---------------------------------------------------------------------- // nsIDOMSVGMatrix methods: /* attribute float a; */ NS_IMETHODIMP DOMSVGMatrix::GetA(float *aA) { - *aA = static_cast<float>(Matrix().xx); + *aA = A(); return NS_OK; } -NS_IMETHODIMP DOMSVGMatrix::SetA(float aA) + +void +DOMSVGMatrix::SetA(float aA, ErrorResult& rv) { if (IsAnimVal()) { - return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; + rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); + return; } - NS_ENSURE_FINITE(aA, NS_ERROR_ILLEGAL_VALUE); gfxMatrix mx = Matrix(); mx.xx = aA; SetMatrix(mx); - return NS_OK; +} + +NS_IMETHODIMP DOMSVGMatrix::SetA(float aA) +{ + NS_ENSURE_FINITE(aA, NS_ERROR_ILLEGAL_VALUE); + ErrorResult rv; + SetA(aA, rv); + return rv.ErrorCode(); } /* attribute float b; */ NS_IMETHODIMP DOMSVGMatrix::GetB(float *aB) { - *aB = static_cast<float>(Matrix().yx); + *aB = B(); return NS_OK; } -NS_IMETHODIMP DOMSVGMatrix::SetB(float aB) + +void +DOMSVGMatrix::SetB(float aB, ErrorResult& rv) { if (IsAnimVal()) { - return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; + rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); + return; } - NS_ENSURE_FINITE(aB, NS_ERROR_ILLEGAL_VALUE); gfxMatrix mx = Matrix(); mx.yx = aB; SetMatrix(mx); - return NS_OK; +} + +NS_IMETHODIMP DOMSVGMatrix::SetB(float aB) +{ + NS_ENSURE_FINITE(aB, NS_ERROR_ILLEGAL_VALUE); + ErrorResult rv; + SetB(aB, rv); + return rv.ErrorCode(); } /* attribute float c; */ NS_IMETHODIMP DOMSVGMatrix::GetC(float *aC) { - *aC = static_cast<float>(Matrix().xy); + *aC = C(); return NS_OK; } -NS_IMETHODIMP DOMSVGMatrix::SetC(float aC) + +void +DOMSVGMatrix::SetC(float aC, ErrorResult& rv) { if (IsAnimVal()) { - return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; + rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); + return; } - NS_ENSURE_FINITE(aC, NS_ERROR_ILLEGAL_VALUE); gfxMatrix mx = Matrix(); mx.xy = aC; SetMatrix(mx); - return NS_OK; +} + +NS_IMETHODIMP DOMSVGMatrix::SetC(float aC) +{ + NS_ENSURE_FINITE(aC, NS_ERROR_ILLEGAL_VALUE); + ErrorResult rv; + SetC(aC, rv); + return rv.ErrorCode(); } /* attribute float d; */ NS_IMETHODIMP DOMSVGMatrix::GetD(float *aD) { - *aD = static_cast<float>(Matrix().yy); + *aD = D(); return NS_OK; } -NS_IMETHODIMP DOMSVGMatrix::SetD(float aD) + +void +DOMSVGMatrix::SetD(float aD, ErrorResult& rv) { if (IsAnimVal()) { - return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; + rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); + return; } - NS_ENSURE_FINITE(aD, NS_ERROR_ILLEGAL_VALUE); gfxMatrix mx = Matrix(); mx.yy = aD; SetMatrix(mx); - return NS_OK; +} + +NS_IMETHODIMP DOMSVGMatrix::SetD(float aD) +{ + NS_ENSURE_FINITE(aD, NS_ERROR_ILLEGAL_VALUE); + ErrorResult rv; + SetD(aD, rv); + return rv.ErrorCode(); } /* attribute float e; */ NS_IMETHODIMP DOMSVGMatrix::GetE(float *aE) { - *aE = static_cast<float>(Matrix().x0); + *aE = E(); return NS_OK; } -NS_IMETHODIMP DOMSVGMatrix::SetE(float aE) + +void +DOMSVGMatrix::SetE(float aE, ErrorResult& rv) { if (IsAnimVal()) { - return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; + rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); + return; } - NS_ENSURE_FINITE(aE, NS_ERROR_ILLEGAL_VALUE); gfxMatrix mx = Matrix(); mx.x0 = aE; SetMatrix(mx); - return NS_OK; +} + +NS_IMETHODIMP DOMSVGMatrix::SetE(float aE) +{ + NS_ENSURE_FINITE(aE, NS_ERROR_ILLEGAL_VALUE); + ErrorResult rv; + SetE(aE, rv); + return rv.ErrorCode(); } /* attribute float f; */ NS_IMETHODIMP DOMSVGMatrix::GetF(float *aF) { - *aF = static_cast<float>(Matrix().y0); + *aF = F(); return NS_OK; } -NS_IMETHODIMP DOMSVGMatrix::SetF(float aF) + +void +DOMSVGMatrix::SetF(float aF, ErrorResult& rv) { if (IsAnimVal()) { - return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; + rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); + return; } - NS_ENSURE_FINITE(aF, NS_ERROR_ILLEGAL_VALUE); gfxMatrix mx = Matrix(); mx.y0 = aF; SetMatrix(mx); - return NS_OK; +} + +NS_IMETHODIMP DOMSVGMatrix::SetF(float aF) +{ + NS_ENSURE_FINITE(aF, NS_ERROR_ILLEGAL_VALUE); + ErrorResult rv; + SetF(aF, rv); + return rv.ErrorCode(); +} + +already_AddRefed<DOMSVGMatrix> +DOMSVGMatrix::Multiply(DOMSVGMatrix& aMatrix) +{ + nsCOMPtr<DOMSVGMatrix> matrix = new DOMSVGMatrix(aMatrix.Matrix() * Matrix()); + return matrix.forget(); } /* nsIDOMSVGMatrix multiply (in nsIDOMSVGMatrix secondMatrix); */ NS_IMETHODIMP DOMSVGMatrix::Multiply(nsIDOMSVGMatrix *secondMatrix, nsIDOMSVGMatrix **_retval) { *_retval = nullptr; nsCOMPtr<DOMSVGMatrix> domMatrix = do_QueryInterface(secondMatrix); if (!domMatrix) return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR; - NS_ADDREF(*_retval = new DOMSVGMatrix(domMatrix->Matrix() * Matrix())); + *_retval = Multiply(*domMatrix).get(); return NS_OK; } +already_AddRefed<DOMSVGMatrix> +DOMSVGMatrix::Inverse(ErrorResult& rv) +{ + if (Matrix().IsSingular()) { + rv.Throw(NS_ERROR_DOM_SVG_MATRIX_NOT_INVERTABLE); + return nullptr; + } + nsRefPtr<DOMSVGMatrix> matrix = new DOMSVGMatrix(gfxMatrix(Matrix()).Invert()); + return matrix.forget(); +} + /* nsIDOMSVGMatrix inverse (); */ NS_IMETHODIMP DOMSVGMatrix::Inverse(nsIDOMSVGMatrix **_retval) { - *_retval = nullptr; - if (Matrix().IsSingular()) - return NS_ERROR_DOM_SVG_MATRIX_NOT_INVERTABLE; + ErrorResult rv; + *_retval = Inverse(rv).get(); + return rv.ErrorCode(); +} - NS_ADDREF(*_retval = new DOMSVGMatrix(gfxMatrix(Matrix()).Invert())); - return NS_OK; +already_AddRefed<DOMSVGMatrix> +DOMSVGMatrix::Translate(float x, float y) +{ + nsRefPtr<DOMSVGMatrix> matrix = + new DOMSVGMatrix(gfxMatrix(Matrix()).Translate(gfxPoint(x, y))); + return matrix.forget(); } + /* nsIDOMSVGMatrix translate (in float x, in float y); */ NS_IMETHODIMP DOMSVGMatrix::Translate(float x, float y, nsIDOMSVGMatrix **_retval) { - *_retval = nullptr; - NS_ENSURE_FINITE2(x, y, NS_ERROR_ILLEGAL_VALUE); - - NS_ADDREF(*_retval = - new DOMSVGMatrix(gfxMatrix(Matrix()).Translate(gfxPoint(x, y)))); + if (!NS_finite(x) || !NS_finite(y)) { + *_retval = nullptr; + return NS_ERROR_ILLEGAL_VALUE; + } + *_retval = Translate(x, y).get(); return NS_OK; } -/* nsIDOMSVGMatrix scale (in float scaleFactor); */ +already_AddRefed<DOMSVGMatrix> +DOMSVGMatrix::Scale(float scaleFactor) +{ + return ScaleNonUniform(scaleFactor, scaleFactor); +} + + /* nsIDOMSVGMatrix scale (in float scaleFactor); */ NS_IMETHODIMP DOMSVGMatrix::Scale(float scaleFactor, nsIDOMSVGMatrix **_retval) { return ScaleNonUniform(scaleFactor, scaleFactor, _retval); } -/* nsIDOMSVGMatrix scaleNonUniform (in float scaleFactorX, +already_AddRefed<DOMSVGMatrix> +DOMSVGMatrix::ScaleNonUniform(float scaleFactorX, + float scaleFactorY) +{ + nsRefPtr<DOMSVGMatrix> matrix = + new DOMSVGMatrix(gfxMatrix(Matrix()).Scale(scaleFactorX, scaleFactorY)); + return matrix.forget(); +} + + + /* nsIDOMSVGMatrix scaleNonUniform (in float scaleFactorX, * in float scaleFactorY); */ NS_IMETHODIMP DOMSVGMatrix::ScaleNonUniform(float scaleFactorX, float scaleFactorY, nsIDOMSVGMatrix **_retval) { - *_retval = nullptr; - NS_ENSURE_FINITE2(scaleFactorX, scaleFactorY, NS_ERROR_ILLEGAL_VALUE); + if (!NS_finite(scaleFactorX) || !NS_finite(scaleFactorY)) { + *_retval = nullptr; + return NS_ERROR_ILLEGAL_VALUE; + } + *_retval = ScaleNonUniform(scaleFactorX, scaleFactorY).get(); + return NS_OK; +} - NS_ADDREF(*_retval = - new DOMSVGMatrix(gfxMatrix(Matrix()).Scale(scaleFactorX, scaleFactorY))); - return NS_OK; +already_AddRefed<DOMSVGMatrix> +DOMSVGMatrix::Rotate(float angle) +{ + nsRefPtr<DOMSVGMatrix> matrix = + new DOMSVGMatrix(gfxMatrix(Matrix()).Rotate(angle*radPerDegree)); + return matrix.forget(); } /* nsIDOMSVGMatrix rotate (in float angle); */ NS_IMETHODIMP DOMSVGMatrix::Rotate(float angle, nsIDOMSVGMatrix **_retval) { - *_retval = nullptr; - NS_ENSURE_FINITE(angle, NS_ERROR_ILLEGAL_VALUE); + if (!NS_finite(angle)) { + *_retval = nullptr; + return NS_ERROR_ILLEGAL_VALUE; + } + *_retval = Rotate(angle).get(); + return NS_OK; +} - NS_ADDREF(*_retval = - new DOMSVGMatrix(gfxMatrix(Matrix()).Rotate(angle*radPerDegree))); - return NS_OK; +already_AddRefed<DOMSVGMatrix> +DOMSVGMatrix::RotateFromVector(float x, float y, ErrorResult& rv) +{ + if (x == 0.0 || y == 0.0) { + rv.Throw(NS_ERROR_RANGE_ERR); + return nullptr; + } + + nsRefPtr<DOMSVGMatrix> matrix = + new DOMSVGMatrix(gfxMatrix(Matrix()).Rotate(atan2(y, x))); + return matrix.forget(); } /* nsIDOMSVGMatrix rotateFromVector (in float x, in float y); */ NS_IMETHODIMP DOMSVGMatrix::RotateFromVector(float x, float y, nsIDOMSVGMatrix **_retval) { - *_retval = nullptr; - NS_ENSURE_FINITE2(x, y, NS_ERROR_ILLEGAL_VALUE); + if (!NS_finite(x) || !NS_finite(y)) { + *_retval = nullptr; + return NS_ERROR_ILLEGAL_VALUE; + } - if (x == 0.0 || y == 0.0) - return NS_ERROR_RANGE_ERR; + ErrorResult rv; + *_retval = RotateFromVector(x, y, rv).get(); + return rv.ErrorCode(); +} - NS_ADDREF(*_retval = - new DOMSVGMatrix(gfxMatrix(Matrix()).Rotate(atan2(y, x)))); - return NS_OK; +already_AddRefed<DOMSVGMatrix> +DOMSVGMatrix::FlipX() +{ + const gfxMatrix& mx = Matrix(); + nsRefPtr<DOMSVGMatrix> matrix = + new DOMSVGMatrix(gfxMatrix(-mx.xx, -mx.yx, mx.xy, mx.yy, mx.x0, mx.y0)); + return matrix.forget(); } /* nsIDOMSVGMatrix flipX (); */ NS_IMETHODIMP DOMSVGMatrix::FlipX(nsIDOMSVGMatrix **_retval) { + *_retval = FlipX().get(); + return NS_OK; +} + +already_AddRefed<DOMSVGMatrix> +DOMSVGMatrix::FlipY() +{ 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; + nsRefPtr<DOMSVGMatrix> matrix = + new DOMSVGMatrix(gfxMatrix(mx.xx, mx.yx, -mx.xy, -mx.yy, mx.x0, mx.y0)); + return matrix.forget(); } /* 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))); + *_retval = FlipY().get(); return NS_OK; } -/* nsIDOMSVGMatrix skewX (in float angle); */ -NS_IMETHODIMP DOMSVGMatrix::SkewX(float angle, nsIDOMSVGMatrix **_retval) +already_AddRefed<DOMSVGMatrix> +DOMSVGMatrix::SkewX(float angle, ErrorResult& rv) { - *_retval = nullptr; - NS_ENSURE_FINITE(angle, NS_ERROR_ILLEGAL_VALUE); - double ta = tan( angle*radPerDegree ); - NS_ENSURE_FINITE(ta, NS_ERROR_RANGE_ERR); + if (!NS_finite(ta)) { + rv.Throw(NS_ERROR_RANGE_ERR); + return nullptr; + } 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; + nsRefPtr<DOMSVGMatrix> matrix = new DOMSVGMatrix(skewMx); + return matrix.forget(); +} + +/* nsIDOMSVGMatrix skewX (in float angle); */ +NS_IMETHODIMP DOMSVGMatrix::SkewX(float angle, nsIDOMSVGMatrix **_retval) +{ + if (!NS_finite(angle)) { + *_retval = nullptr; + return NS_ERROR_ILLEGAL_VALUE; + } + + ErrorResult rv; + *_retval = SkewX(angle, rv).get(); + return rv.ErrorCode(); +} + +already_AddRefed<DOMSVGMatrix> +DOMSVGMatrix::SkewY(float angle, ErrorResult& rv) +{ + double ta = tan( angle*radPerDegree ); + if (!NS_finite(ta)) { + rv.Throw(NS_ERROR_RANGE_ERR); + return nullptr; + } + + 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); + + nsRefPtr<DOMSVGMatrix> matrix = new DOMSVGMatrix(skewMx); + return matrix.forget(); } /* nsIDOMSVGMatrix skewY (in float angle); */ NS_IMETHODIMP DOMSVGMatrix::SkewY(float angle, nsIDOMSVGMatrix **_retval) { - *_retval = nullptr; - NS_ENSURE_FINITE(angle, NS_ERROR_ILLEGAL_VALUE); - - double ta = tan( angle*radPerDegree ); - NS_ENSURE_FINITE(ta, NS_ERROR_RANGE_ERR); + if (!NS_finite(angle)) { + *_retval = nullptr; + return NS_ERROR_ILLEGAL_VALUE; + } - 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; + ErrorResult rv; + *_retval = SkewY(angle, rv).get(); + return rv.ErrorCode(); } + } // namespace mozilla
--- a/content/svg/content/src/DOMSVGMatrix.h +++ b/content/svg/content/src/DOMSVGMatrix.h @@ -37,60 +37,102 @@ #ifndef MOZILLA_DOMSVGMATRIX_H__ #define MOZILLA_DOMSVGMATRIX_H__ #include "DOMSVGTransform.h" #include "gfxMatrix.h" #include "nsAutoPtr.h" #include "nsCycleCollectionParticipant.h" #include "nsIDOMSVGMatrix.h" +#include "nsWrapperCache.h" #include "mozilla/Attributes.h" // 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 } } namespace mozilla { /** * DOM wrapper for an SVG matrix. */ -class DOMSVGMatrix MOZ_FINAL : public nsIDOMSVGMatrix +class DOMSVGMatrix MOZ_FINAL : public nsIDOMSVGMatrix, + public nsWrapperCache { public: NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOMSVGMATRIX_IID) NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_CLASS(DOMSVGMatrix) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGMatrix) NS_DECL_NSIDOMSVGMATRIX /** * Ctor for DOMSVGMatrix objects that belong to a DOMSVGTransform. */ - DOMSVGMatrix(DOMSVGTransform& aTransform) : mTransform(&aTransform) { } + DOMSVGMatrix(DOMSVGTransform& aTransform) : mTransform(&aTransform) { + SetIsDOMBinding(); + } /** * Ctors for DOMSVGMatrix objects created independently of a DOMSVGTransform. */ - DOMSVGMatrix() { } // Default ctor for gfxMatrix will produce identity mx - DOMSVGMatrix(const gfxMatrix &aMatrix) : mMatrix(aMatrix) { } + // Default ctor for gfxMatrix will produce identity mx + DOMSVGMatrix() { + SetIsDOMBinding(); + } + + DOMSVGMatrix(const gfxMatrix &aMatrix) : mMatrix(aMatrix) { + SetIsDOMBinding(); + } + ~DOMSVGMatrix() { if (mTransform) { mTransform->ClearMatrixTearoff(this); } } const gfxMatrix& Matrix() const { return mTransform ? mTransform->Matrix() : mMatrix; } + // WebIDL + DOMSVGTransform* GetParentObject() const; + virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope, bool* aTriedToWrap); + + float A() const { return static_cast<float>(Matrix().xx); } + void SetA(float aA, ErrorResult& rv); + float B() const { return static_cast<float>(Matrix().yx); } + void SetB(float aB, ErrorResult& rv); + float C() const { return static_cast<float>(Matrix().xy); } + void SetC(float aC, ErrorResult& rv); + float D() const { return static_cast<float>(Matrix().yy); } + void SetD(float aD, ErrorResult& rv); + float E() const { return static_cast<float>(Matrix().x0); } + void SetE(float aE, ErrorResult& rv); + float F() const { return static_cast<float>(Matrix().y0); } + void SetF(float aF, ErrorResult& rv); + already_AddRefed<DOMSVGMatrix> Multiply(DOMSVGMatrix& aMatrix); + already_AddRefed<DOMSVGMatrix> Inverse(ErrorResult& aRv); + already_AddRefed<DOMSVGMatrix> Translate(float x, float y); + already_AddRefed<DOMSVGMatrix> Scale(float scaleFactor); + already_AddRefed<DOMSVGMatrix> ScaleNonUniform(float scaleFactorX, + float scaleFactorY); + already_AddRefed<DOMSVGMatrix> Rotate(float angle); + already_AddRefed<DOMSVGMatrix> RotateFromVector(float x, + float y, + ErrorResult& aRv); + already_AddRefed<DOMSVGMatrix> FlipX(); + already_AddRefed<DOMSVGMatrix> FlipY(); + already_AddRefed<DOMSVGMatrix> SkewX(float angle, ErrorResult& rv); + already_AddRefed<DOMSVGMatrix> SkewY(float angle, ErrorResult& rv); + private: void SetMatrix(const gfxMatrix& aMatrix) { if (mTransform) { mTransform->SetMatrix(aMatrix); } else { mMatrix = aMatrix; } }
--- a/content/svg/content/src/DOMSVGPoint.cpp +++ b/content/svg/content/src/DOMSVGPoint.cpp @@ -157,29 +157,32 @@ DOMSVGPoint::SetY(float aY, ErrorResult& } mPt.mY = aY; } NS_IMETHODIMP DOMSVGPoint::MatrixTransform(nsIDOMSVGMatrix *matrix, nsIDOMSVGPoint **_retval) { - *_retval = MatrixTransform(matrix).get(); + nsCOMPtr<DOMSVGMatrix> domMatrix = do_QueryInterface(matrix); + if (!domMatrix) { + *_retval = nullptr; + return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR; + } + *_retval = MatrixTransform(*domMatrix).get(); return NS_OK; } already_AddRefed<nsISVGPoint> -DOMSVGPoint::MatrixTransform(nsIDOMSVGMatrix* matrix) +DOMSVGPoint::MatrixTransform(DOMSVGMatrix& matrix) { - nsCOMPtr<DOMSVGMatrix> domMatrix = do_QueryInterface(matrix); - float x = HasOwner() ? InternalItem().mX : mPt.mX; float y = HasOwner() ? InternalItem().mY : mPt.mY; - gfxPoint pt = domMatrix->Matrix().Transform(gfxPoint(x, y)); + gfxPoint pt = matrix.Matrix().Transform(gfxPoint(x, y)); nsCOMPtr<nsISVGPoint> newPoint = new DOMSVGPoint(pt); return newPoint.forget(); } void DOMSVGPoint::InsertingIntoList(DOMSVGPointList *aList, uint32_t aListIndex, bool aIsAnimValItem)
--- a/content/svg/content/src/DOMSVGPoint.h +++ b/content/svg/content/src/DOMSVGPoint.h @@ -27,16 +27,18 @@ class nsSVGElement; #define MOZILLA_DOMSVGPOINT_IID \ { 0xd6b6c440, 0xaf8d, 0x40ee, \ { 0x85, 0x6b, 0x02, 0xa3, 0x17, 0xca, 0xb2, 0x75 } } #define MOZ_SVG_LIST_INDEX_BIT_COUNT 30 namespace mozilla { +class DOMSVGMatrix; + /** * Class DOMSVGPoint * * This class creates the DOM objects that wrap internal SVGPoint objects that * are in an SVGPointList. It is also used to create the objects returned by * SVGSVGElement.createSVGPoint() and other functions that return DOM SVGPoint * objects. * @@ -119,17 +121,17 @@ public: } } // WebIDL virtual float X(); virtual void SetX(float aX, ErrorResult& rv); virtual float Y(); virtual void SetY(float aY, ErrorResult& rv); - virtual already_AddRefed<nsISVGPoint> MatrixTransform(nsIDOMSVGMatrix* matrix); + virtual already_AddRefed<nsISVGPoint> MatrixTransform(DOMSVGMatrix& matrix); nsISupports* GetParentObject() MOZ_OVERRIDE { return mList; } /** * Create an unowned copy of this object. The caller is responsible for the * first AddRef()! */
--- a/content/svg/content/src/DOMSVGTransformList.cpp +++ b/content/svg/content/src/DOMSVGTransformList.cpp @@ -417,38 +417,35 @@ DOMSVGTransformList::AppendItem(nsIDOMSV nsIDOMSVGTransform **_retval) { ErrorResult rv; *_retval = AppendItem(newItem, rv).get(); return rv.ErrorCode(); } already_AddRefed<nsIDOMSVGTransform> -DOMSVGTransformList::CreateSVGTransformFromMatrix(nsIDOMSVGMatrix *matrix, - ErrorResult& error) +DOMSVGTransformList::CreateSVGTransformFromMatrix(DOMSVGMatrix& matrix) { - nsCOMPtr<DOMSVGMatrix> domItem = do_QueryInterface(matrix); - if (!domItem) { - error.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR); - return nullptr; - } - - nsCOMPtr<nsIDOMSVGTransform> result = new DOMSVGTransform(domItem->Matrix()); + nsCOMPtr<nsIDOMSVGTransform> result = new DOMSVGTransform(matrix.Matrix()); return result.forget(); } /* nsIDOMSVGTransform createSVGTransformFromMatrix (in nsIDOMSVGMatrix matrix); */ NS_IMETHODIMP DOMSVGTransformList::CreateSVGTransformFromMatrix(nsIDOMSVGMatrix *matrix, nsIDOMSVGTransform **_retval) { - ErrorResult rv; - *_retval = CreateSVGTransformFromMatrix(matrix, rv).get(); - return rv.ErrorCode(); + nsCOMPtr<DOMSVGMatrix> domItem = do_QueryInterface(matrix); + if (!domItem) { + *_retval = nullptr; + return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR; + } + *_retval = CreateSVGTransformFromMatrix(*domItem).get(); + return NS_OK; } already_AddRefed<nsIDOMSVGTransform> DOMSVGTransformList::Consolidate(ErrorResult& error) { if (IsAnimValList()) { error.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); return nullptr;
--- a/content/svg/content/src/DOMSVGTransformList.h +++ b/content/svg/content/src/DOMSVGTransformList.h @@ -17,16 +17,17 @@ #include "mozilla/Attributes.h" #include "mozilla/ErrorResult.h" class nsIDOMSVGTransform; class nsSVGElement; namespace mozilla { +class DOMSVGMatrix; class DOMSVGTransform; /** * Class DOMSVGTransformList * * This class is used to create the DOM tearoff objects that wrap internal * SVGTransformList objects. * @@ -116,18 +117,17 @@ public: ErrorResult& error); already_AddRefed<nsIDOMSVGTransform> RemoveItem(uint32_t index, ErrorResult& error); already_AddRefed<nsIDOMSVGTransform> AppendItem(nsIDOMSVGTransform *newItem, ErrorResult& error) { return InsertItemBefore(newItem, LengthNoFlush(), error); } - already_AddRefed<nsIDOMSVGTransform> - CreateSVGTransformFromMatrix(nsIDOMSVGMatrix *matrix, ErrorResult& error); + already_AddRefed<nsIDOMSVGTransform> CreateSVGTransformFromMatrix(DOMSVGMatrix& matrix); already_AddRefed<nsIDOMSVGTransform> Consolidate(ErrorResult& error); uint32_t Length() const { return NumberOfItems(); } private:
--- a/content/svg/content/src/nsISVGPoint.h +++ b/content/svg/content/src/nsISVGPoint.h @@ -15,16 +15,18 @@ class nsSVGElement; // {d6b6c440-af8d-40ee-856b-02a317cab275} #define MOZILLA_NSISVGPOINT_IID \ { 0xd6b6c440, 0xaf8d, 0x40ee, \ { 0x85, 0x6b, 0x02, 0xa3, 0x17, 0xca, 0xb2, 0x75 } } namespace mozilla { +class DOMSVGMatrix; + /** * Class nsISVGPoint * * This class creates the DOM objects that wrap internal SVGPoint objects. * An nsISVGPoint can be either a DOMSVGPoint or a nsSVGTranslatePoint::DOMVal. */ class nsISVGPoint : public nsIDOMSVGPoint, public nsWrapperCache @@ -44,17 +46,17 @@ public: using nsIDOMSVGPoint::SetY; using nsIDOMSVGPoint::MatrixTransform; // WebIDL virtual float X() = 0; virtual void SetX(float aX, ErrorResult& rv) = 0; virtual float Y() = 0; virtual void SetY(float aY, ErrorResult& rv) = 0; - virtual already_AddRefed<nsISVGPoint> MatrixTransform(nsIDOMSVGMatrix* matrix) = 0; + virtual already_AddRefed<nsISVGPoint> MatrixTransform(DOMSVGMatrix& matrix) = 0; virtual JSObject* WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap) { return dom::SVGPointBinding::Wrap(cx, scope, this, triedToWrap); } virtual nsISupports* GetParentObject() = 0; }; NS_DEFINE_STATIC_IID_ACCESSOR(nsISVGPoint, MOZILLA_NSISVGPOINT_IID)
--- a/content/svg/content/src/nsSVGSVGElement.cpp +++ b/content/svg/content/src/nsSVGSVGElement.cpp @@ -129,32 +129,31 @@ nsSVGTranslatePoint::DOMVal::SetY(float SetY(aY, rv); return rv.ErrorCode(); } NS_IMETHODIMP nsSVGTranslatePoint::DOMVal::MatrixTransform(nsIDOMSVGMatrix *matrix, nsIDOMSVGPoint **_retval) { - *_retval = MatrixTransform(matrix).get(); + nsCOMPtr<DOMSVGMatrix> domMatrix = do_QueryInterface(matrix); + if (!domMatrix) { + *_retval = nullptr; + return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR; + } + *_retval = MatrixTransform(*domMatrix).get(); return NS_OK; } /* nsIDOMSVGPoint matrixTransform (in nsIDOMSVGMatrix matrix); */ already_AddRefed<nsISVGPoint> -nsSVGTranslatePoint::DOMVal::MatrixTransform(nsIDOMSVGMatrix *matrix) +nsSVGTranslatePoint::DOMVal::MatrixTransform(DOMSVGMatrix& matrix) { - float a, b, c, d, e, f; - matrix->GetA(&a); - matrix->GetB(&b); - matrix->GetC(&c); - matrix->GetD(&d); - matrix->GetE(&e); - matrix->GetF(&f); - + float a = matrix.A(), b = matrix.B(), c = matrix.C(); + float d = matrix.D(), e = matrix.E(), f = matrix.F(); float x = mVal->GetX(); float y = mVal->GetY(); nsCOMPtr<nsISVGPoint> point = new DOMSVGPoint(a*x + c*y + e, b*x + d*y + f); return point.forget(); } nsSVGElement::LengthInfo nsSVGSVGElement::sLengthInfo[4] =
--- a/content/svg/content/src/nsSVGSVGElement.h +++ b/content/svg/content/src/nsSVGSVGElement.h @@ -15,20 +15,20 @@ #include "nsIDOMSVGZoomAndPan.h" #include "nsSVGEnum.h" #include "nsSVGLength2.h" #include "nsSVGStylableElement.h" #include "nsSVGViewBox.h" #include "SVGAnimatedPreserveAspectRatio.h" #include "mozilla/Attributes.h" -class nsIDOMSVGMatrix; class nsSMILTimeContainer; class nsSVGViewElement; namespace mozilla { + class DOMSVGMatrix; class SVGFragmentIdentifier; } typedef nsSVGStylableElement nsSVGSVGElementBase; class nsSVGSVGElement; class nsSVGTranslatePoint { @@ -68,17 +68,17 @@ private: NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMVal) NS_DECL_NSIDOMSVGPOINT // WebIDL virtual float X() { return mVal->GetX(); } virtual float Y() { return mVal->GetY(); } virtual void SetX(float aValue, mozilla::ErrorResult& rv); virtual void SetY(float aValue, mozilla::ErrorResult& rv); - virtual already_AddRefed<mozilla::nsISVGPoint> MatrixTransform(nsIDOMSVGMatrix* matrix); + virtual already_AddRefed<mozilla::nsISVGPoint> MatrixTransform(mozilla::DOMSVGMatrix& matrix); virtual nsISupports* GetParentObject() MOZ_OVERRIDE; nsSVGTranslatePoint *mVal; // kept alive because it belongs to mElement nsRefPtr<nsSVGSVGElement> mElement; }; float mX;
--- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -442,16 +442,21 @@ DOMInterfaces = { }, 'SVGLengthList': { 'nativeType': 'mozilla::DOMSVGLengthList', 'headerFile': 'DOMSVGLengthList.h', 'resultNotAddRefed': [ 'getItem' ] }, +'SVGMatrix': { + 'nativeType': 'mozilla::DOMSVGMatrix', + 'headerFile': 'DOMSVGMatrix.h' +}, + 'SVGNumberList': { 'nativeType': 'mozilla::DOMSVGNumberList', 'headerFile': 'DOMSVGNumberList.h', 'resultNotAddRefed': [ 'getItem' ] }, 'SVGPathSegList': { 'nativeType': 'mozilla::DOMSVGPathSegList', @@ -857,17 +862,16 @@ addExternalIface('OutputStream', nativeT notflattened=True) addExternalIface('Principal', nativeType='nsIPrincipal', headerFile='nsIPrincipal.h', notflattened=True) addExternalIface('ProcessingInstruction', nativeType='nsXMLProcessingInstruction') addExternalIface('Range', nativeType='nsRange') addExternalIface("Rect") addExternalIface('StyleSheetList') addExternalIface('SVGLength') -addExternalIface('SVGMatrix') addExternalIface('SVGNumber') addExternalIface('SVGPathSeg') addExternalIface('SVGTransform') addExternalIface('Text', nativeType='nsTextNode') addExternalIface('TextMetrics', headerFile='nsIDOMCanvasRenderingContext2D.h') addExternalIface('TreeWalker') addExternalIface('Touch', headerFile='nsIDOMTouchEvent.h') addExternalIface('TouchList', headerFile='nsIDOMTouchEvent.h')
new file mode 100644 --- /dev/null +++ b/dom/webidl/SVGMatrix.webidl @@ -0,0 +1,51 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * The origin of this IDL file is + * http://www.w3.org/TR/SVG2/ + * + * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C + * liability, trademark and document use rules apply. + */ + +interface SVGMatrix { + + [SetterThrows] + attribute float a; + [SetterThrows] + attribute float b; + [SetterThrows] + attribute float c; + [SetterThrows] + attribute float d; + [SetterThrows] + attribute float e; + [SetterThrows] + attribute float f; + + [Creator] + SVGMatrix multiply(SVGMatrix secondMatrix); + [Creator, Throws] + SVGMatrix inverse(); + [Creator] + SVGMatrix translate(float x, float y); + [Creator] + SVGMatrix scale(float scaleFactor); + [Creator] + SVGMatrix scaleNonUniform(float scaleFactorX, float scaleFactorY); + [Creator] + SVGMatrix rotate(float angle); + [Creator, Throws] + SVGMatrix rotateFromVector(float x, float y); + [Creator] + SVGMatrix flipX(); + [Creator] + SVGMatrix flipY(); + [Creator, Throws] + SVGMatrix skewX(float angle); + [Creator, Throws] + SVGMatrix skewY(float angle); +}; +
--- a/dom/webidl/SVGPoint.webidl +++ b/dom/webidl/SVGPoint.webidl @@ -5,18 +5,16 @@ * * The origin of this IDL file is * http://www.w3.org/TR/SVG2/ * * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C * liability, trademark and document use rules apply. */ -interface SVGMatrix; - interface SVGPoint { [SetterThrows] attribute float x; [SetterThrows] attribute float y; [Creator]
--- a/dom/webidl/SVGTransformList.webidl +++ b/dom/webidl/SVGTransformList.webidl @@ -5,17 +5,16 @@ * * The origin of this IDL file is * http://www.w3.org/TR/SVG11/ * * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C * liability, trademark and document use rules apply. */ -interface SVGMatrix; interface SVGTransform; interface SVGTransformList { readonly attribute unsigned long numberOfItems; [Throws] void clear(); [Throws] SVGTransform initialize(SVGTransform newItem); @@ -24,16 +23,15 @@ interface SVGTransformList { [Throws] SVGTransform insertItemBefore(SVGTransform newItem, unsigned long index); [Throws] SVGTransform replaceItem(SVGTransform newItem, unsigned long index); [Throws] SVGTransform removeItem(unsigned long index); [Throws] SVGTransform appendItem(SVGTransform newItem); - [Throws] SVGTransform createSVGTransformFromMatrix(SVGMatrix matrix); [Throws] SVGTransform consolidate(); // Mozilla-specific stuff readonly attribute unsigned long length; // synonym for numberOfItems };
--- a/dom/webidl/WebIDL.mk +++ b/dom/webidl/WebIDL.mk @@ -64,16 +64,17 @@ webidl_files = \ PaintRequestList.webidl \ PannerNode.webidl \ Performance.webidl \ PerformanceNavigation.webidl \ PerformanceTiming.webidl \ RGBColor.webidl \ Screen.webidl \ SVGLengthList.webidl \ + SVGMatrix.webidl \ SVGNumberList.webidl \ SVGPathSegList.webidl \ SVGPoint.webidl \ SVGPointList.webidl \ SVGTransformList.webidl \ TextDecoder.webidl \ TextEncoder.webidl \ URL.webidl \