summaryrefslogtreecommitdiff
path: root/dom/base
diff options
context:
space:
mode:
authorJob Bautista <jobbautista9@aol.com>2023-05-12 15:42:46 +0800
committerJob Bautista <jobbautista9@aol.com>2023-05-12 16:26:06 +0800
commitb2889d844f8c2f826100588b23b741f73e96cbbc (patch)
treee14cb0225f044641194ce5f09839af9aba2a434e /dom/base
parentfdfe7a8245eb33db252f2a9a3474ac931f15a7d8 (diff)
downloaduxp-b2889d844f8c2f826100588b23b741f73e96cbbc.tar.gz
Issue #2241 - Part 6: Implement DOMMatrix.fromMatrix.
Also fixes .multiply() to use DOMMatrixInit. Backported from Mozilla bug 1560462.
Diffstat (limited to 'dom/base')
-rw-r--r--dom/base/DOMMatrix.cpp177
-rw-r--r--dom/base/DOMMatrix.h23
-rw-r--r--dom/base/WebKitCSSMatrix.cpp4
-rw-r--r--dom/base/WebKitCSSMatrix.h3
4 files changed, 187 insertions, 20 deletions
diff --git a/dom/base/DOMMatrix.cpp b/dom/base/DOMMatrix.cpp
index 0045e17d84..09c186e77e 100644
--- a/dom/base/DOMMatrix.cpp
+++ b/dom/base/DOMMatrix.cpp
@@ -17,6 +17,8 @@
#include <math.h>
+#include "js/Equality.h" // JS::SameValueZero
+
namespace mozilla {
namespace dom {
@@ -37,6 +39,130 @@ DOMMatrixReadOnly::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
return DOMMatrixReadOnlyBinding::Wrap(aCx, this, aGivenProto);
}
+// https://drafts.fxtf.org/geometry/#matrix-validate-and-fixup-2d
+static bool
+ValidateAndFixupMatrix2DInit(DOMMatrix2DInit& aMatrixInit, ErrorResult& aRv)
+{
+#define ValidateAliases(field, alias, fieldName, aliasName) \
+ if ((field).WasPassed() && (alias).WasPassed() && \
+ !JS::SameValueZero((field).Value(), (alias).Value())) { \
+ aRv.ThrowTypeError<MSG_MATRIX_INIT_CONFLICTING_VALUE>((fieldName), \
+ (aliasName)); \
+ return false; \
+ }
+#define SetFromAliasOrDefault(field, alias, defaultValue) \
+ if (!(field).WasPassed()) { \
+ if ((alias).WasPassed()) { \
+ (field).Construct((alias).Value()); \
+ } else { \
+ (field).Construct(defaultValue); \
+ } \
+ }
+#define ValidateAndSet(field, alias, fieldName, aliasName, defaultValue) \
+ ValidateAliases((field), (alias), NS_LITERAL_STRING(fieldName), \
+ NS_LITERAL_STRING(aliasName)); \
+ SetFromAliasOrDefault((field), (alias), (defaultValue));
+
+ ValidateAndSet(aMatrixInit.mM11, aMatrixInit.mA, "m11", "a", 1);
+ ValidateAndSet(aMatrixInit.mM12, aMatrixInit.mB, "m12", "b", 0);
+ ValidateAndSet(aMatrixInit.mM21, aMatrixInit.mC, "m21", "c", 0);
+ ValidateAndSet(aMatrixInit.mM22, aMatrixInit.mD, "m22", "d", 1);
+ ValidateAndSet(aMatrixInit.mM41, aMatrixInit.mE, "m41", "e", 0);
+ ValidateAndSet(aMatrixInit.mM42, aMatrixInit.mF, "m42", "f", 0);
+
+ return true;
+
+#undef ValidateAliases
+#undef SetFromAliasOrDefault
+#undef ValidateAndSet
+}
+
+// https://drafts.fxtf.org/geometry/#matrix-validate-and-fixup
+static bool
+ValidateAndFixupMatrixInit(DOMMatrixInit& aMatrixInit, ErrorResult& aRv)
+{
+#define Check3DField(field, fieldName, defaultValue) \
+ if ((field) != (defaultValue)) { \
+ if (!aMatrixInit.mIs2D.WasPassed()) { \
+ aMatrixInit.mIs2D.Construct(false); \
+ return true; \
+ } \
+ if (aMatrixInit.mIs2D.Value()) { \
+ aRv.ThrowTypeError<MSG_MATRIX_INIT_EXCEEDS_2D>( \
+ NS_LITERAL_STRING(fieldName)); \
+ return false; \
+ } \
+ }
+
+ if (!ValidateAndFixupMatrix2DInit(aMatrixInit, aRv)) {
+ return false;
+ }
+
+ Check3DField(aMatrixInit.mM13, "m13", 0);
+ Check3DField(aMatrixInit.mM14, "m14", 0);
+ Check3DField(aMatrixInit.mM23, "m23", 0);
+ Check3DField(aMatrixInit.mM24, "m24", 0);
+ Check3DField(aMatrixInit.mM31, "m31", 0);
+ Check3DField(aMatrixInit.mM32, "m32", 0);
+ Check3DField(aMatrixInit.mM34, "m34", 0);
+ Check3DField(aMatrixInit.mM43, "m43", 0);
+ Check3DField(aMatrixInit.mM33, "m33", 1);
+ Check3DField(aMatrixInit.mM44, "m44", 1);
+
+ if (!aMatrixInit.mIs2D.WasPassed()) {
+ aMatrixInit.mIs2D.Construct(true);
+ }
+ return true;
+
+#undef Check3DField
+}
+
+void
+DOMMatrixReadOnly::SetDataFromMatrixInit(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();
+ } else {
+ mMatrix3D->_11 = aMatrixInit.mM11.Value();
+ mMatrix3D->_12 = aMatrixInit.mM12.Value();
+ mMatrix3D->_13 = aMatrixInit.mM13;
+ mMatrix3D->_14 = aMatrixInit.mM14;
+ mMatrix3D->_21 = aMatrixInit.mM21.Value();
+ mMatrix3D->_22 = aMatrixInit.mM22.Value();
+ mMatrix3D->_23 = aMatrixInit.mM23;
+ mMatrix3D->_24 = aMatrixInit.mM24;
+ mMatrix3D->_31 = aMatrixInit.mM31;
+ mMatrix3D->_32 = aMatrixInit.mM32;
+ mMatrix3D->_33 = aMatrixInit.mM33;
+ mMatrix3D->_34 = aMatrixInit.mM34;
+ mMatrix3D->_41 = aMatrixInit.mM41.Value();
+ mMatrix3D->_42 = aMatrixInit.mM42.Value();
+ mMatrix3D->_43 = aMatrixInit.mM43;
+ mMatrix3D->_44 = aMatrixInit.mM44;
+ }
+}
+
+already_AddRefed<DOMMatrixReadOnly>
+DOMMatrixReadOnly::FromMatrix(const GlobalObject& aGlobal, const DOMMatrixInit& aMatrixInit, ErrorResult& aRv)
+{
+ DOMMatrixInit matrixInit(aMatrixInit);
+ if (!ValidateAndFixupMatrixInit(matrixInit, aRv)) {
+ return nullptr;
+ };
+
+ RefPtr<DOMMatrixReadOnly> rval =
+ new DOMMatrixReadOnly(aGlobal.GetAsSupports(), matrixInit.mIs2D.Value());
+ rval->SetDataFromMatrixInit(matrixInit);
+ return rval.forget();
+}
+
already_AddRefed<DOMMatrixReadOnly>
DOMMatrixReadOnly::Constructor(
const GlobalObject& aGlobal,
@@ -182,10 +308,10 @@ DOMMatrixReadOnly::SkewY(double aSy) const
}
already_AddRefed<DOMMatrix>
-DOMMatrixReadOnly::Multiply(const DOMMatrix& other) const
+DOMMatrixReadOnly::Multiply(const DOMMatrixInit& other, ErrorResult& aRv) const
{
RefPtr<DOMMatrix> retval = new DOMMatrix(mParent, *this);
- retval->MultiplySelf(other);
+ retval->MultiplySelf(other, aRv);
return retval.forget();
}
@@ -427,6 +553,27 @@ DOMMatrixReadOnly::ReadStructuredCloneElements(JSStructuredCloneReader* aReader,
}
already_AddRefed<DOMMatrix>
+DOMMatrix::FromMatrix(nsISupports* aParent, const DOMMatrixInit& aMatrixInit, ErrorResult& aRv)
+{
+ DOMMatrixInit matrixInit(aMatrixInit);
+ if (!ValidateAndFixupMatrixInit(matrixInit, aRv)) {
+ return nullptr;
+ };
+
+ RefPtr<DOMMatrix> matrix = new DOMMatrix(aParent, matrixInit.mIs2D.Value());
+ matrix->SetDataFromMatrixInit(matrixInit);
+ return matrix.forget();
+}
+
+already_AddRefed<DOMMatrix>
+DOMMatrix::FromMatrix(const GlobalObject& aGlobal, const DOMMatrixInit& aMatrixInit, ErrorResult& aRv)
+{
+ RefPtr<DOMMatrix> matrix =
+ FromMatrix(aGlobal.GetAsSupports(), aMatrixInit, aRv);
+ return matrix.forget();
+}
+
+already_AddRefed<DOMMatrix>
DOMMatrix::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
{
RefPtr<DOMMatrix> obj = new DOMMatrix(aGlobal.GetAsSupports());
@@ -546,42 +693,44 @@ DOMMatrixReadOnly::Ensure3DMatrix()
}
DOMMatrix*
-DOMMatrix::MultiplySelf(const DOMMatrix& aOther)
+DOMMatrix::MultiplySelf(const DOMMatrixInit& aOtherInit, ErrorResult& aRv)
{
- if (aOther.Identity()) {
+ RefPtr<DOMMatrix> other = FromMatrix(mParent, aOtherInit, aRv);
+ if (other->Identity()) {
return this;
}
- if (aOther.Is2D()) {
+ if (other->Is2D()) {
if (mMatrix3D) {
- *mMatrix3D = gfx::Matrix4x4::From2D(*aOther.mMatrix2D) * *mMatrix3D;
+ *mMatrix3D = gfx::Matrix4x4::From2D(*other->mMatrix2D) * *mMatrix3D;
} else {
- *mMatrix2D = *aOther.mMatrix2D * *mMatrix2D;
+ *mMatrix2D = *other->mMatrix2D * *mMatrix2D;
}
} else {
Ensure3DMatrix();
- *mMatrix3D = *aOther.mMatrix3D * *mMatrix3D;
+ *mMatrix3D = *other->mMatrix3D * *mMatrix3D;
}
return this;
}
DOMMatrix*
-DOMMatrix::PreMultiplySelf(const DOMMatrix& aOther)
+DOMMatrix::PreMultiplySelf(const DOMMatrixInit& aOtherInit, ErrorResult& aRv)
{
- if (aOther.Identity()) {
+ RefPtr<DOMMatrix> other = FromMatrix(mParent, aOtherInit, aRv);
+ if (other->Identity()) {
return this;
}
- if (aOther.Is2D()) {
+ if (other->Is2D()) {
if (mMatrix3D) {
- *mMatrix3D = *mMatrix3D * gfx::Matrix4x4::From2D(*aOther.mMatrix2D);
+ *mMatrix3D = *mMatrix3D * gfx::Matrix4x4::From2D(*other->mMatrix2D);
} else {
- *mMatrix2D = *mMatrix2D * *aOther.mMatrix2D;
+ *mMatrix2D = *mMatrix2D * *other->mMatrix2D;
}
} else {
Ensure3DMatrix();
- *mMatrix3D = *mMatrix3D * *aOther.mMatrix3D;
+ *mMatrix3D = *mMatrix3D * *other->mMatrix3D;
}
return this;
diff --git a/dom/base/DOMMatrix.h b/dom/base/DOMMatrix.h
index fe1325c594..9bbdef688f 100644
--- a/dom/base/DOMMatrix.h
+++ b/dom/base/DOMMatrix.h
@@ -25,6 +25,7 @@ class DOMMatrix;
class DOMPoint;
class StringOrUnrestrictedDoubleSequence;
struct DOMPointInit;
+struct DOMMatrixInit;
class DOMMatrixReadOnly : public nsWrapperCache
{
@@ -57,6 +58,9 @@ public:
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
static already_AddRefed<DOMMatrixReadOnly>
+ FromMatrix(const GlobalObject& aGlobal, const DOMMatrixInit& aMatrixInit, ErrorResult& aRv);
+
+ static already_AddRefed<DOMMatrixReadOnly>
Constructor(const GlobalObject& aGlobal, const Optional<StringOrUnrestrictedDoubleSequence>& aArg, ErrorResult& aRv);
static already_AddRefed<DOMMatrixReadOnly>
@@ -180,7 +184,8 @@ public:
double aAngle) const;
already_AddRefed<DOMMatrix> SkewX(double aSx) const;
already_AddRefed<DOMMatrix> SkewY(double aSy) const;
- already_AddRefed<DOMMatrix> Multiply(const DOMMatrix& aOther) const;
+ already_AddRefed<DOMMatrix> Multiply(const DOMMatrixInit& aOther,
+ ErrorResult& aRv) const;
already_AddRefed<DOMMatrix> FlipX() const;
already_AddRefed<DOMMatrix> FlipY() const;
already_AddRefed<DOMMatrix> Inverse() const;
@@ -204,6 +209,13 @@ protected:
virtual ~DOMMatrixReadOnly() {}
+ /**
+ * Sets data from a fully validated and fixed-up matrix init,
+ * where all of its members are properly defined.
+ * The init dictionary's dimension must match the matrix one.
+ */
+ void SetDataFromMatrixInit(DOMMatrixInit& aMatrixInit);
+
DOMMatrixReadOnly* SetMatrixValue(const nsAString& aTransformList, ErrorResult& aRv);
void Ensure3DMatrix();
@@ -237,6 +249,11 @@ public:
{}
static already_AddRefed<DOMMatrix>
+ FromMatrix(nsISupports* aParent, const DOMMatrixInit& aMatrixInit, ErrorResult& aRv);
+ static already_AddRefed<DOMMatrix>
+ FromMatrix(const GlobalObject& aGlobal, const DOMMatrixInit& aMatrixInit, ErrorResult& aRv);
+
+ static already_AddRefed<DOMMatrix>
Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
static already_AddRefed<DOMMatrix>
Constructor(const GlobalObject& aGlobal, const nsAString& aTransformList, ErrorResult& aRv);
@@ -254,8 +271,8 @@ public:
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
- DOMMatrix* MultiplySelf(const DOMMatrix& aOther);
- DOMMatrix* PreMultiplySelf(const DOMMatrix& aOther);
+ DOMMatrix* MultiplySelf(const DOMMatrixInit& aOther, ErrorResult& aRv);
+ DOMMatrix* PreMultiplySelf(const DOMMatrixInit& aOther, ErrorResult& aRv);
DOMMatrix* TranslateSelf(double aTx,
double aTy,
double aTz = 0);
diff --git a/dom/base/WebKitCSSMatrix.cpp b/dom/base/WebKitCSSMatrix.cpp
index fe26b74554..003fdfea30 100644
--- a/dom/base/WebKitCSSMatrix.cpp
+++ b/dom/base/WebKitCSSMatrix.cpp
@@ -115,10 +115,10 @@ WebKitCSSMatrix::SetMatrixValue(const nsAString& aTransformList,
}
already_AddRefed<WebKitCSSMatrix>
-WebKitCSSMatrix::Multiply(const WebKitCSSMatrix& other) const
+WebKitCSSMatrix::Multiply(const DOMMatrixInit& aOtherInit, ErrorResult& aRv) const
{
RefPtr<WebKitCSSMatrix> retval = new WebKitCSSMatrix(mParent, *this);
- retval->MultiplySelf(other);
+ retval->MultiplySelf(aOtherInit, aRv);
return retval.forget();
}
diff --git a/dom/base/WebKitCSSMatrix.h b/dom/base/WebKitCSSMatrix.h
index e50c617260..590548b767 100644
--- a/dom/base/WebKitCSSMatrix.h
+++ b/dom/base/WebKitCSSMatrix.h
@@ -40,7 +40,8 @@ public:
WebKitCSSMatrix* SetMatrixValue(const nsAString& aTransformList,
ErrorResult& aRv);
- already_AddRefed<WebKitCSSMatrix> Multiply(const WebKitCSSMatrix& aOther) const;
+ already_AddRefed<WebKitCSSMatrix> Multiply(const DOMMatrixInit& aOtherInit,
+ ErrorResult& aRv) const;
already_AddRefed<WebKitCSSMatrix> Inverse(ErrorResult& aRv) const;
already_AddRefed<WebKitCSSMatrix> Translate(double aTx,
double aTy,