From 71bd54891acbe2d92bab6910391abd3d4c3460c5 Mon Sep 17 00:00:00 2001 From: Moonchild Date: Fri, 16 Aug 2024 11:02:07 +0200 Subject: [PATCH 1/3] Issue #1810 - Implement {get|set}Transform with DOMMatrix arguments. We already had part of the plumbing for other canvas manipulations, so this is somewhat simplified. This excludes the interface as that is breaking the build at this stage. Some more research is required. --- dom/base/DOMMatrix.cpp | 9 ++------ dom/base/DOMMatrix.h | 11 +++++++++- dom/canvas/CanvasRenderingContext2D.cpp | 28 +++++++++++++++++++++++++ dom/canvas/CanvasRenderingContext2D.h | 6 ++++++ 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/dom/base/DOMMatrix.cpp b/dom/base/DOMMatrix.cpp index 56cf6f1b17..f2dbe2a2a7 100644 --- a/dom/base/DOMMatrix.cpp +++ b/dom/base/DOMMatrix.cpp @@ -129,17 +129,12 @@ DOMMatrixReadOnly::SetDataFromMatrix2DInit(const DOMMatrix2DInit& aMatrixInit) { } void -DOMMatrixReadOnly::SetDataFromMatrixInit(DOMMatrixInit& aMatrixInit) +DOMMatrixReadOnly::SetDataFromMatrixInit(const DOMMatrixInit& aMatrixInit) { const bool is2D = aMatrixInit.mIs2D.Value(); MOZ_ASSERT(is2D == Is2D()); if (is2D) { - mMatrix2D->_11 = aMatrixInit.mM11.Value(); - mMatrix2D->_12 = aMatrixInit.mM12.Value(); - mMatrix2D->_21 = aMatrixInit.mM21.Value(); - mMatrix2D->_22 = aMatrixInit.mM22.Value(); - mMatrix2D->_31 = aMatrixInit.mM41.Value(); - mMatrix2D->_32 = aMatrixInit.mM42.Value(); + SetDataFromMatrix2DInit(aMatrixInit); } else { mMatrix3D->_11 = aMatrixInit.mM11.Value(); mMatrix3D->_12 = aMatrixInit.mM12.Value(); diff --git a/dom/base/DOMMatrix.h b/dom/base/DOMMatrix.h index 423580e2c4..9e961de7b4 100644 --- a/dom/base/DOMMatrix.h +++ b/dom/base/DOMMatrix.h @@ -52,6 +52,11 @@ public: mMatrix3D = new gfx::Matrix4x4(aMatrix); } + DOMMatrixReadOnly(nsISupports* aParent, const gfx::Matrix& aMatrix) + : mParent(aParent) { + mMatrix2D = new gfx::Matrix(aMatrix); + } + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMMatrixReadOnly) NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMMatrixReadOnly) @@ -234,7 +239,7 @@ protected: * The init dictionary's dimension must match the matrix one. */ void SetDataFromMatrix2DInit(const DOMMatrix2DInit& aMatrixInit); - void SetDataFromMatrixInit(DOMMatrixInit& aMatrixInit); + void SetDataFromMatrixInit(const DOMMatrixInit& aMatrixInit); DOMMatrixReadOnly* SetMatrixValue(const nsAString& aTransformList, ErrorResult& aRv); void Ensure3DMatrix(); @@ -268,6 +273,10 @@ public: : DOMMatrixReadOnly(aParent, aMatrix) {} + DOMMatrix(nsISupports* aParent, const gfx::Matrix& aMatrix) + : DOMMatrixReadOnly(aParent, aMatrix) + {} + static already_AddRefed FromMatrix(nsISupports* aParent, const DOMMatrixInit& aMatrixInit, ErrorResult& aRv); static already_AddRefed diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index 60078a8fcb..d134cfade1 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -2229,6 +2229,18 @@ CanvasRenderingContext2D::Transform(double aM11, double aM12, double aM21, SetTransformInternal(newMatrix); } +already_AddRefed +CanvasRenderingContext2D::GetTransform(ErrorResult& aError) { + EnsureTarget(); + if (!IsTargetValid()) { + aError.Throw(NS_ERROR_FAILURE); + return nullptr; + } + RefPtr matrix = + new DOMMatrix(GetParentObject(), mTarget->GetTransform()); + return matrix.forget(); +} + void CanvasRenderingContext2D::SetTransform(double aM11, double aM12, double aM21, double aM22, @@ -2244,6 +2256,22 @@ CanvasRenderingContext2D::SetTransform(double aM11, double aM12, SetTransformInternal(Matrix(aM11, aM12, aM21, aM22, aDx, aDy)); } +void +CanvasRenderingContext2D::SetTransform(const DOMMatrix2DInit& aInit, + ErrorResult& aError) { + TransformWillUpdate(); + if (!IsTargetValid()) { + aError.Throw(NS_ERROR_FAILURE); + return; + } + + RefPtr matrix = + DOMMatrixReadOnly::FromMatrix(GetParentObject(), aInit, aError); + if (!aError.Failed()) { + SetTransformInternal(Matrix(*(matrix->GetInternal2D()))); + } +} + void CanvasRenderingContext2D::SetTransformInternal(const Matrix& aTransform) { diff --git a/dom/canvas/CanvasRenderingContext2D.h b/dom/canvas/CanvasRenderingContext2D.h index d4f295a03f..81637e8eb6 100644 --- a/dom/canvas/CanvasRenderingContext2D.h +++ b/dom/canvas/CanvasRenderingContext2D.h @@ -57,6 +57,10 @@ class CanvasRenderingContext2DUserData; class CanvasDrawObserver; class CanvasShutdownObserver; +class DOMMatrix; +class DOMMatrixReadOnly; +struct DOMMatrix2DInit; + /** ** CanvasRenderingContext2D **/ @@ -88,8 +92,10 @@ public: void Translate(double aX, double aY, mozilla::ErrorResult& aError); void Transform(double aM11, double aM12, double aM21, double aM22, double aDx, double aDy, mozilla::ErrorResult& aError); + already_AddRefed GetTransform(mozilla::ErrorResult& aError); void SetTransform(double aM11, double aM12, double aM21, double aM22, double aDx, double aDy, mozilla::ErrorResult& aError); + void SetTransform(const DOMMatrix2DInit& aInit, mozilla::ErrorResult& aError); void ResetTransform(mozilla::ErrorResult& aError); double GlobalAlpha() From 18f039543aaac5cf52666433ece5697dcc6b100d Mon Sep 17 00:00:00 2001 From: Moonchild Date: Fri, 16 Aug 2024 14:31:51 +0200 Subject: [PATCH 2/3] Issue #1810 - Allow superfluous [LenientFloat] extended attributes. This changes the way the extended attribute [LenientFloat] behaves, so that overloading functions can match extended attributes while not having restricted float type arguments themselves. --- dom/bindings/parser/WebIDL.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/dom/bindings/parser/WebIDL.py b/dom/bindings/parser/WebIDL.py index 0aa3afa4e8..5c6b6eed32 100644 --- a/dom/bindings/parser/WebIDL.py +++ b/dom/bindings/parser/WebIDL.py @@ -4888,6 +4888,16 @@ class IDLMethod(IDLInterfaceMember, IDLScope): raise WebIDLError("StaticClassOverride can be applied to static" " methods on JS-implemented classes only.", [self.location]) + if self.getExtendedAttribute("LenientFloat"): + assert len(self.signatures()) >= 1 + found = False + for sig in self.signatures(): + if any(arg.type.includesRestrictedFloat() for arg in sig[1]): + found = True + if not found: + raise WebIDLError("[LenientFloat] used on an operation with no " + "restricted float type arguments", + [self.location]) def overloadsForArgCount(self, argc): return [overload for overload in self._overloads if @@ -4966,10 +4976,6 @@ class IDLMethod(IDLInterfaceMember, IDLScope): if not sig[0].isVoid(): raise WebIDLError("[LenientFloat] used on a non-void method", [attr.location, self.location]) - if not any(arg.type.includesRestrictedFloat() for arg in sig[1]): - raise WebIDLError("[LenientFloat] used on an operation with no " - "restricted float type arguments", - [attr.location, self.location]) elif identifier == "Exposed": convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames) elif (identifier == "CrossOriginCallable" or From 9d6ffb5814d400d77bc7c25fadba64934a11f452 Mon Sep 17 00:00:00 2001 From: Moonchild Date: Fri, 16 Aug 2024 14:33:06 +0200 Subject: [PATCH 3/3] Issue #1810 - Add DOMMatrix {get|set}Transform WebIDL interfaces --- dom/webidl/CanvasRenderingContext2D.webidl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dom/webidl/CanvasRenderingContext2D.webidl b/dom/webidl/CanvasRenderingContext2D.webidl index fe48385d7a..449e41d558 100644 --- a/dom/webidl/CanvasRenderingContext2D.webidl +++ b/dom/webidl/CanvasRenderingContext2D.webidl @@ -54,8 +54,13 @@ interface CanvasRenderingContext2D { void translate(double x, double y); [Throws, LenientFloat] void transform(double a, double b, double c, double d, double e, double f); + + [NewObject, Throws] + DOMMatrix getTransform(); [Throws, LenientFloat] void setTransform(double a, double b, double c, double d, double e, double f); + [Throws, LenientFloat] + void setTransform(optional DOMMatrix2DInit transform); [Throws] void resetTransform();