--- a/dom/base/DOMMatrix.cpp
+++ b/dom/base/DOMMatrix.cpp
@@ -680,10 +680,70 @@ DOMMatrix::SetMatrixValue(const nsAStrin
}
JSObject*
DOMMatrix::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return DOMMatrixBinding::Wrap(aCx, this, aGivenProto);
}
+#define SAMEVALUEZERO(a, b)\
+ ((a == b) || (mozilla::IsNaN(a) && mozilla::IsNaN(b)) ||\
+ (a == -0 && b == 0) || (a == 0 && b == -0))
+
+#define SET_DOMMATRIXINIT_DICTIONARY_MEMBER(dict, m, dflt, fallback)\
+ if (!dict.m.WasPassed()) { \
+ if (dict.dflt.WasPassed()) { \
+ dict.m.Construct(dict.dflt.Value()); \
+ } else { \
+ dict.m.Construct(fallback); \
+ } \
+ }
+
+#define THROW_ON_DOMMATRIXINIT_MEMBER_MISMATCH(dict, a, b, aStr, bStr, err)\
+ if (dict.a.WasPassed() && dict.b.WasPassed() && \
+ !SAMEVALUEZERO(dict.a.Value(), dict.b.Value())) { \
+ err.ThrowTypeError<MSG_MISMATCHED_MATRIX_MEMBERS>( \
+ NS_LITERAL_STRING(aStr), NS_LITERAL_STRING(bStr)); \
+ return; \
+ }
+
+void
+ValidateAndFixupDOMMatrix2DInit(DOMMatrix2DInit& aInit, ErrorResult& aError)
+{
+ // Step 1
+ THROW_ON_DOMMATRIXINIT_MEMBER_MISMATCH(aInit, mA, mM11, "a", "m11", aError);
+ THROW_ON_DOMMATRIXINIT_MEMBER_MISMATCH(aInit, mB, mM12, "b", "m12", aError);
+ THROW_ON_DOMMATRIXINIT_MEMBER_MISMATCH(aInit, mC, mM21, "c", "m21", aError);
+ THROW_ON_DOMMATRIXINIT_MEMBER_MISMATCH(aInit, mD, mM22, "d", "m22", aError);
+ THROW_ON_DOMMATRIXINIT_MEMBER_MISMATCH(aInit, mE, mM41, "e", "m41", aError);
+ THROW_ON_DOMMATRIXINIT_MEMBER_MISMATCH(aInit, mF, mM42, "f", "m42", aError);
+
+ // Steps 2-7
+ SET_DOMMATRIXINIT_DICTIONARY_MEMBER(aInit, mM11, mA, 1.0);
+ SET_DOMMATRIXINIT_DICTIONARY_MEMBER(aInit, mM12, mB, 0.0);
+ SET_DOMMATRIXINIT_DICTIONARY_MEMBER(aInit, mM21, mC, 0.0);
+ SET_DOMMATRIXINIT_DICTIONARY_MEMBER(aInit, mM22, mD, 1.0);
+ SET_DOMMATRIXINIT_DICTIONARY_MEMBER(aInit, mM41, mE, 0.0);
+ SET_DOMMATRIXINIT_DICTIONARY_MEMBER(aInit, mM42, mF, 0.0);
+}
+
+bool
+InitMatrixFromDOMMatrix2DInit(const DOMMatrix2DInit& aInit,
+ gfx::Matrix& aMatrix,
+ ErrorResult& aError)
+{
+ DOMMatrix2DInit fixed(aInit);
+ ValidateAndFixupDOMMatrix2DInit(fixed, aError);
+ if (aError.Failed()) {
+ return false;
+ }
+ aMatrix._11 = fixed.mM11.Value();
+ aMatrix._12 = fixed.mM12.Value();
+ aMatrix._21 = fixed.mM21.Value();
+ aMatrix._22 = fixed.mM22.Value();
+ aMatrix._31 = fixed.mM41.Value();
+ aMatrix._32 = fixed.mM42.Value();
+ return true;
+}
+
} // namespace dom
} // namespace mozilla
--- a/dom/base/DOMMatrix.h
+++ b/dom/base/DOMMatrix.h
@@ -9,16 +9,17 @@
#include "nsWrapperCache.h"
#include "nsISupports.h"
#include "nsCycleCollectionParticipant.h"
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "nsCOMPtr.h"
#include "mozilla/dom/BindingDeclarations.h"
+#include "mozilla/dom/DOMMatrixBinding.h"
#include "mozilla/dom/TypedArray.h"
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
namespace mozilla {
namespace dom {
class GlobalObject;
class DOMMatrix;
@@ -257,12 +258,16 @@ public:
DOMMatrix* InvertSelf();
DOMMatrix* SetMatrixValue(const nsAString& aTransformList, ErrorResult& aRv);
protected:
void Ensure3DMatrix();
virtual ~DOMMatrix() {}
};
+bool InitMatrixFromDOMMatrix2DInit(const DOMMatrix2DInit& aInit,
+ gfx::Matrix& aMatrix,
+ ErrorResult& aError);
+
} // namespace dom
} // namespace mozilla
#endif /*MOZILLA_DOM_DOMMATRIX_H_*/
--- a/dom/bindings/Errors.msg
+++ b/dom/bindings/Errors.msg
@@ -98,8 +98,9 @@ MSG_DEF(MSG_INVALID_EASING_ERROR, 1, JSE
MSG_DEF(MSG_USELESS_SETTIMEOUT, 1, JSEXN_TYPEERR, "Useless {0} call (missing quotes around argument?)")
MSG_DEF(MSG_TOKENLIST_NO_SUPPORTED_TOKENS, 2, JSEXN_TYPEERR, "{0} attribute of <{1}> does not define any supported tokens")
MSG_DEF(MSG_CACHE_STREAM_CLOSED, 0, JSEXN_TYPEERR, "Response body is a cache file stream that has already been closed.")
MSG_DEF(MSG_TIME_VALUE_OUT_OF_RANGE, 1, JSEXN_TYPEERR, "{0} is outside the supported range for time values.")
MSG_DEF(MSG_ONLY_IF_CACHED_WITHOUT_SAME_ORIGIN, 1, JSEXN_TYPEERR, "Request mode '{0}' was used, but request cache mode 'only-if-cached' can only be used with request mode 'same-origin'.")
MSG_DEF(MSG_THRESHOLD_RANGE_ERROR, 0, JSEXN_RANGEERR, "Threshold values must all be in the range [0, 1].")
MSG_DEF(MSG_WORKER_THREAD_SHUTTING_DOWN, 0, JSEXN_TYPEERR, "The Worker thread is shutting down.")
MSG_DEF(MSG_CACHE_OPEN_FAILED, 0, JSEXN_TYPEERR, "CacheStorage.open() failed to access the storage system.")
+MSG_DEF(MSG_MISMATCHED_MATRIX_MEMBERS, 2, JSEXN_TYPEERR, "{0} and {1} must match if both are set.")
--- a/dom/canvas/BasicRenderingContext2D.h
+++ b/dom/canvas/BasicRenderingContext2D.h
@@ -1,16 +1,17 @@
/* 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/. */
#ifndef BasicRenderingContext2D_h
#define BasicRenderingContext2D_h
#include "mozilla/dom/CanvasRenderingContext2DBinding.h"
+#include "DOMMatrix.h"
namespace mozilla {
namespace dom {
class HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmap;
typedef HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmap
CanvasImageSource;
@@ -43,16 +44,18 @@ public:
mozilla::ErrorResult& aError) = 0;
virtual void SetTransform(double aM11,
double aM12,
double aM21,
double aM22,
double aDx,
double aDy,
mozilla::ErrorResult& aError) = 0;
+ virtual void SetTransform(const DOMMatrix2DInit& aTransform,
+ mozilla::ErrorResult& aError) = 0;
virtual void ResetTransform(mozilla::ErrorResult& aError) = 0;
//
// CanvasCompositing
//
virtual double GlobalAlpha() = 0;
virtual void SetGlobalAlpha(double aGlobalAlpha) = 0;
virtual void GetGlobalCompositeOperation(nsAString& aOp,
--- a/dom/canvas/CanvasPath.h
+++ b/dom/canvas/CanvasPath.h
@@ -5,16 +5,17 @@
#ifndef CanvasPath_h
#define CanvasPath_h
#include "mozilla/Attributes.h"
#include "mozilla/RefPtr.h"
#include "nsWrapperCache.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/dom/BindingDeclarations.h"
+#include "mozilla/dom/DOMMatrix.h"
#include "mozilla/ErrorResult.h"
namespace mozilla {
namespace dom {
enum class CanvasWindingRule : uint8_t;
class SVGMatrix;
@@ -65,17 +66,18 @@ public:
explicit CanvasPath(nsISupports* aParent);
// already_AddRefed arg because the return value from Path::CopyToBuilder()
// is passed directly and we can't drop the only ref to have a raw pointer.
CanvasPath(nsISupports* aParent,
already_AddRefed<gfx::PathBuilder> aPathBuilder);
void AddPath(CanvasPath& aCanvasPath,
- const Optional<NonNull<SVGMatrix>>& aMatrix);
+ const DOMMatrix2DInit& aTransform,
+ ErrorResult& aError);
private:
virtual ~CanvasPath() {}
nsCOMPtr<nsISupports> mParent;
static gfx::Float ToFloat(double aValue) { return gfx::Float(aValue); }
mutable RefPtr<gfx::Path> mPath;
--- a/dom/canvas/CanvasPattern.h
+++ b/dom/canvas/CanvasPattern.h
@@ -58,17 +58,17 @@ public:
}
CanvasRenderingContext2D* GetParentObject()
{
return mContext;
}
// WebIDL
- void SetTransform(SVGMatrix& matrix);
+ void SetTransform(const DOMMatrix2DInit& aTransform, ErrorResult& aError);
RefPtr<CanvasRenderingContext2D> mContext;
RefPtr<gfx::SourceSurface> mSurface;
nsCOMPtr<nsIPrincipal> mPrincipal;
mozilla::gfx::Matrix mTransform;
const bool mForceWriteOnly;
const bool mCORSUsed;
const RepeatMode mRepeat;
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -100,16 +100,17 @@
#include "mozilla/Telemetry.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/Unused.h"
#include "nsCCUncollectableMarker.h"
#include "nsWrapperCacheInlines.h"
#include "mozilla/dom/CanvasRenderingContext2DBinding.h"
#include "mozilla/dom/CanvasPath.h"
+#include "mozilla/dom/DOMMatrix.h"
#include "mozilla/dom/HTMLImageElement.h"
#include "mozilla/dom/HTMLVideoElement.h"
#include "mozilla/dom/SVGImageElement.h"
#include "mozilla/dom/SVGMatrix.h"
#include "mozilla/dom/TextMetrics.h"
#include "mozilla/dom/SVGMatrix.h"
#include "mozilla/FloatingPoint.h"
#include "nsGlobalWindow.h"
@@ -728,19 +729,24 @@ private:
}
RefPtr<DrawTarget> mTarget;
UniquePtr<AdjustedTargetForShadow> mShadowTarget;
UniquePtr<AdjustedTargetForFilter> mFilterTarget;
};
void
-CanvasPattern::SetTransform(SVGMatrix& aMatrix)
-{
- mTransform = ToMatrix(aMatrix.GetMatrix());
+CanvasPattern::SetTransform(const DOMMatrix2DInit& aTransform,
+ ErrorResult& aError)
+{
+ Matrix transform;
+ if (!InitMatrixFromDOMMatrix2DInit(aTransform, transform, aError)) {
+ return;
+ }
+ mTransform = transform;
}
void
CanvasGradient::AddColorStop(float aOffset, const nsAString& aColorstr, ErrorResult& aRv)
{
if (aOffset < 0.0 || aOffset > 1.0) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return;
@@ -2266,16 +2272,58 @@ CanvasRenderingContext2D::Transform(doub
}
Matrix newMatrix(aM11, aM12, aM21, aM22, aDx, aDy);
newMatrix *= mTarget->GetTransform();
SetTransformInternal(newMatrix);
}
+already_AddRefed<DOMMatrix>
+CanvasRenderingContext2D::GetTransform()
+{
+ TransformWillUpdate();
+ RefPtr<DOMMatrix> matrix;
+ matrix = new DOMMatrix(GetParentObject());
+ if (IsTargetValid()) {
+ Matrix currentMatrix = mTarget->GetTransform();
+ matrix->SetA(currentMatrix._11);
+ matrix->SetB(currentMatrix._12);
+ matrix->SetC(currentMatrix._21);
+ matrix->SetD(currentMatrix._22);
+ matrix->SetE(currentMatrix._31);
+ matrix->SetF(currentMatrix._32);
+ }
+ return matrix.forget();
+}
+
+void
+CanvasRenderingContext2D::SetTransform(const DOMMatrix2DInit& aTransform,
+ ErrorResult& aError)
+{
+ if (!Preferences::GetBool("canvas.transform_extensions.enabled")) {
+ aError.ThrowTypeError<MSG_MISSING_ARGUMENTS>(
+ NS_LITERAL_STRING("CanvasRenderingContext2D.setTransform"));
+ return;
+ }
+
+ Matrix transform;
+ if (!InitMatrixFromDOMMatrix2DInit(aTransform, transform, aError)) {
+ return;
+ }
+
+ TransformWillUpdate();
+ if (!IsTargetValid()) {
+ aError.Throw(NS_ERROR_FAILURE);
+ return;
+ }
+
+ SetTransformInternal(transform);
+}
+
void
CanvasRenderingContext2D::SetTransform(double aM11, double aM12,
double aM21, double aM22,
double aDx, double aDy,
ErrorResult& aError)
{
TransformWillUpdate();
if (!IsTargetValid()) {
@@ -6503,30 +6551,31 @@ CanvasPath::BezierTo(const gfx::Point& a
const gfx::Point& aCP3)
{
EnsurePathBuilder();
mPathBuilder->BezierTo(aCP1, aCP2, aCP3);
}
void
-CanvasPath::AddPath(CanvasPath& aCanvasPath, const Optional<NonNull<SVGMatrix>>& aMatrix)
-{
+CanvasPath::AddPath(CanvasPath& aCanvasPath, const DOMMatrix2DInit& aTransform,
+ ErrorResult& aError)
+{
+ Matrix transform;
+ if (!InitMatrixFromDOMMatrix2DInit(aTransform, transform, aError)) {
+ return;
+ }
+
RefPtr<gfx::Path> tempPath = aCanvasPath.GetPath(
CanvasWindingRule::Nonzero,
gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget().get());
- if (aMatrix.WasPassed()) {
- const SVGMatrix& m = aMatrix.Value();
- Matrix transform(m.A(), m.B(), m.C(), m.D(), m.E(), m.F());
-
- if (!transform.IsIdentity()) {
- RefPtr<PathBuilder> tempBuilder = tempPath->TransformedCopyToBuilder(transform, FillRule::FILL_WINDING);
- tempPath = tempBuilder->Finish();
- }
+ if (!transform.IsIdentity()) {
+ RefPtr<PathBuilder> tempBuilder = tempPath->TransformedCopyToBuilder(transform, FillRule::FILL_WINDING);
+ tempPath = tempBuilder->Finish();
}
EnsurePathBuilder(); // in case a path is added to itself
tempPath->StreamToSink(mPathBuilder);
}
already_AddRefed<gfx::Path>
CanvasPath::GetPath(const CanvasWindingRule& aWinding, const DrawTarget* aTarget) const
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -85,16 +85,19 @@ public:
void Save() override;
void Restore() override;
void Scale(double aX, double aY, mozilla::ErrorResult& aError) override;
void Rotate(double aAngle, mozilla::ErrorResult& aError) override;
void Translate(double aX, double aY, mozilla::ErrorResult& aError) override;
void Transform(double aM11, double aM12, double aM21, double aM22,
double aDx, double aDy, mozilla::ErrorResult& aError) override;
+ already_AddRefed<DOMMatrix> GetTransform();
+ void SetTransform(const DOMMatrix2DInit& aTransform,
+ mozilla::ErrorResult& aError) override;
void SetTransform(double aM11, double aM12, double aM21, double aM22,
double aDx, double aDy, mozilla::ErrorResult& aError) override;
void ResetTransform(mozilla::ErrorResult& aError) override;
double GlobalAlpha() override
{
return CurrentState().globalAlpha;
}
--- a/dom/webidl/CanvasRenderingContext2D.webidl
+++ b/dom/webidl/CanvasRenderingContext2D.webidl
@@ -146,25 +146,28 @@ interface CanvasState {
// state
void save(); // push state on state stack
void restore(); // pop state stack and restore state
};
[NoInterfaceObject]
interface CanvasTransform {
// transformations (default transform is the identity matrix)
-// NOT IMPLEMENTED attribute SVGMatrix currentTransform;
[Throws, LenientFloat]
void scale(double x, double y);
[Throws, LenientFloat]
void rotate(double angle);
[Throws, LenientFloat]
void translate(double x, double y);
[Throws, LenientFloat]
void transform(double a, double b, double c, double d, double e, double f);
+ [NewObject, Pref="layout.css.DOMMatrix.enabled"]
+ DOMMatrix getTransform();
+ [Throws, LenientFloat]
+ void setTransform(optional DOMMatrix2DInit transform);
[Throws, LenientFloat]
void setTransform(double a, double b, double c, double d, double e, double f);
[Throws]
void resetTransform();
};
[NoInterfaceObject]
interface CanvasCompositing {
@@ -348,21 +351,18 @@ interface CanvasGradient {
// opaque object
[Throws]
// addColorStop should take a double
void addColorStop(float offset, DOMString color);
};
interface CanvasPattern {
// opaque object
- // [Throws, LenientFloat] - could not do this overload because of bug 1020975
- // void setTransform(double a, double b, double c, double d, double e, double f);
-
- // No throw necessary here - SVGMatrix is always good.
- void setTransform(SVGMatrix matrix);
+ [Throws]
+ void setTransform(optional DOMMatrix2DInit transform);
};
interface TextMetrics {
// x-direction
readonly attribute double width; // advance width
/*
@@ -386,11 +386,12 @@ interface TextMetrics {
};
[Pref="canvas.path.enabled",
Constructor,
Constructor(Path2D other),
Constructor(DOMString pathString)]
interface Path2D
{
- void addPath(Path2D path, optional SVGMatrix transformation);
+ [Throws]
+ void addPath(Path2D path, optional DOMMatrix2DInit transformation);
};
Path2D implements CanvasPathMethods;
--- a/dom/webidl/DOMMatrix.webidl
+++ b/dom/webidl/DOMMatrix.webidl
@@ -141,8 +141,36 @@ interface DOMMatrix : DOMMatrixReadOnly
unrestricted double z,
unrestricted double angle);
DOMMatrix skewXSelf(unrestricted double sx);
DOMMatrix skewYSelf(unrestricted double sy);
DOMMatrix invertSelf();
[Throws] DOMMatrix setMatrixValue(DOMString transformList);
};
+dictionary DOMMatrix2DInit {
+ unrestricted double a;
+ unrestricted double b;
+ unrestricted double c;
+ unrestricted double d;
+ unrestricted double e;
+ unrestricted double f;
+ unrestricted double m11;
+ unrestricted double m12;
+ unrestricted double m21;
+ unrestricted double m22;
+ unrestricted double m41;
+ unrestricted double m42;
+};
+
+dictionary DOMMatrixInit : DOMMatrix2DInit {
+ unrestricted double m13 = 0;
+ unrestricted double m14 = 0;
+ unrestricted double m23 = 0;
+ unrestricted double m24 = 0;
+ unrestricted double m31 = 0;
+ unrestricted double m32 = 0;
+ unrestricted double m33 = 1;
+ unrestricted double m34 = 0;
+ unrestricted double m43 = 0;
+ unrestricted double m44 = 1;
+ boolean is2D;
+};
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -928,16 +928,17 @@ pref("ui.scrollToClick", 0);
// provide ability to turn on support for canvas focus rings
pref("canvas.focusring.enabled", true);
pref("canvas.customfocusring.enabled", false);
pref("canvas.hitregions.enabled", false);
pref("canvas.filters.enabled", true);
// Add support for canvas path objects
pref("canvas.path.enabled", true);
pref("canvas.capturestream.enabled", true);
+pref("canvas.transform_extensions.enabled", true);
// Disable the ImageBitmap-extensions for now.
pref("canvas.imagebitmap_extensions.enabled", false);
// We want the ability to forcibly disable platform a11y, because
// some non-a11y-related components attempt to bring it up. See bug
// 538530 for details about Windows; we have a pref here that allows it
// to be disabled for performance and testing resons.
--- a/testing/web-platform/meta/css/geometry-1/DOMMatrix2DInit-validate-fixup.html.ini
+++ b/testing/web-platform/meta/css/geometry-1/DOMMatrix2DInit-validate-fixup.html.ini
@@ -1,260 +1,3 @@
[DOMMatrix2DInit-validate-fixup.html]
type: testharness
- [Sanity check without dictionary]
- expected: FAIL
-
- [{m13: 1, is2D: true}]
- expected: FAIL
-
- [{m14: 1, is2D: true}]
- expected: FAIL
-
- [{m23: 1, is2D: true}]
- expected: FAIL
-
- [{m24: 1, is2D: true}]
- expected: FAIL
-
- [{m31: 1, is2D: true}]
- expected: FAIL
-
- [{m32: 1, is2D: true}]
- expected: FAIL
-
- [{m33: 0, is2D: true}]
- expected: FAIL
-
- [{m33: -0, is2D: true}]
- expected: FAIL
-
- [{m33: -1, is2D: true}]
- expected: FAIL
-
- [{m34: 1, is2D: true}]
- expected: FAIL
-
- [{m43: 1, is2D: true}]
- expected: FAIL
-
- [{m44: 0, is2D: true}]
- expected: FAIL
-
- [{}]
- expected: FAIL
-
- [{is2D: undefined}]
- expected: FAIL
-
- [{a: 1, m11: 1}]
- expected: FAIL
-
- [{b: 0, m12: undefined}]
- expected: FAIL
-
- [{c: 0, m21: 0}]
- expected: FAIL
-
- [{c: 0, m21: -0}]
- expected: FAIL
-
- [{c: -0, m21: 0}]
- expected: FAIL
-
- [{c: -0, m21: -0}]
- expected: FAIL
-
- [{d: Infinity, m22: Infinity}]
- expected: FAIL
-
- [{e: -Infinity, m41: -Infinity}]
- expected: FAIL
-
- [{f: NaN, m42: NaN}]
- expected: FAIL
-
- [{f: NaN, m42: NaN, is2D: true}]
- expected: FAIL
-
- [{f: 0, m42: null}]
- expected: FAIL
-
- [{f: -0, m42: null}]
- expected: FAIL
-
- [{a: 2}]
- expected: FAIL
-
- [{b: 2}]
- expected: FAIL
-
- [{c: 2}]
- expected: FAIL
-
- [{d: 2}]
- expected: FAIL
-
- [{e: 2}]
- expected: FAIL
-
- [{f: 2}]
- expected: FAIL
-
- [{a: -0, b: -0, c: -0, d: -0, e: -0, f: -0}]
- expected: FAIL
-
- [{a: -0, b: -0, c: -0, d: -0, e: -0, f: -0, is2D: true}]
- expected: FAIL
-
- [{m11: 2}]
- expected: FAIL
-
- [{m12: 2}]
- expected: FAIL
-
- [{m21: 2}]
- expected: FAIL
-
- [{m22: 2}]
- expected: FAIL
-
- [{m41: 2}]
- expected: FAIL
-
- [{m42: 2}]
- expected: FAIL
-
- [{m11: -0, m12: -0, m21: -0, m22: -0, m41: -0, m42: -0}]
- expected: FAIL
-
- [{m11: -0, m12: -0, m21: -0, m22: -0, m41: -0, m42: -0, is2D: true}]
- expected: FAIL
-
- [{m13: 0, is2D: true}]
- expected: FAIL
-
- [{m13: -0, is2D: true}]
- expected: FAIL
-
- [{m14: 0, is2D: true}]
- expected: FAIL
-
- [{m14: -0, is2D: true}]
- expected: FAIL
-
- [{m23: 0, is2D: true}]
- expected: FAIL
-
- [{m23: -0, is2D: true}]
- expected: FAIL
-
- [{m24: 0, is2D: true}]
- expected: FAIL
-
- [{m24: -0, is2D: true}]
- expected: FAIL
-
- [{m31: 0, is2D: true}]
- expected: FAIL
-
- [{m31: -0, is2D: true}]
- expected: FAIL
-
- [{m32: 0, is2D: true}]
- expected: FAIL
-
- [{m32: -0, is2D: true}]
- expected: FAIL
-
- [{m33: 1, is2D: true}]
- expected: FAIL
-
- [{m34: 0, is2D: true}]
- expected: FAIL
-
- [{m34: -0, is2D: true}]
- expected: FAIL
-
- [{m43: 0, is2D: true}]
- expected: FAIL
-
- [{m43: -0, is2D: true}]
- expected: FAIL
-
- [{m44: 1, is2D: true}]
- expected: FAIL
-
- [{is2D: true}]
- expected: FAIL
-
- [{m13: 1, is2D: false}]
- expected: FAIL
-
- [{m14: 1, is2D: false}]
- expected: FAIL
-
- [{m23: 1, is2D: false}]
- expected: FAIL
-
- [{m24: 1, is2D: false}]
- expected: FAIL
-
- [{m31: 1, is2D: false}]
- expected: FAIL
-
- [{m32: 1, is2D: false}]
- expected: FAIL
-
- [{m33: 0, is2D: false}]
- expected: FAIL
-
- [{m33: -0, is2D: false}]
- expected: FAIL
-
- [{m33: -1, is2D: false}]
- expected: FAIL
-
- [{m34: 1, is2D: false}]
- expected: FAIL
-
- [{m43: 1, is2D: false}]
- expected: FAIL
-
- [{m44: 0, is2D: false}]
- expected: FAIL
-
- [{m13: 1}]
- expected: FAIL
-
- [{m14: 1}]
- expected: FAIL
-
- [{m23: 1}]
- expected: FAIL
-
- [{m24: 1}]
- expected: FAIL
-
- [{m31: 1}]
- expected: FAIL
-
- [{m32: 1}]
- expected: FAIL
-
- [{m33: 0}]
- expected: FAIL
-
- [{m34: 1}]
- expected: FAIL
-
- [{m43: 1}]
- expected: FAIL
-
- [{m44: 0}]
- expected: FAIL
-
- [{is2D: false}]
- expected: FAIL
-
- [{is2D: null}]
- expected: FAIL
-
+ prefs: [canvas.transform_extensions.enabled:true]
--- a/testing/web-platform/meta/html/dom/interfaces.html.ini
+++ b/testing/web-platform/meta/html/dom/interfaces.html.ini
@@ -2186,37 +2186,16 @@
expected: FAIL
[Document interface: new Document() must inherit property "onmousewheel" with the proper type (135)]
expected: FAIL
[Document interface: new Document() must inherit property "onsort" with the proper type (148)]
expected: FAIL
- [HTMLSlotElement interface: existence and properties of interface object]
- expected: FAIL
-
- [HTMLSlotElement interface object length]
- expected: FAIL
-
- [HTMLSlotElement interface object name]
- expected: FAIL
-
- [HTMLSlotElement interface: existence and properties of interface prototype object]
- expected: FAIL
-
- [HTMLSlotElement interface: existence and properties of interface prototype object's "constructor" property]
- expected: FAIL
-
- [HTMLSlotElement interface: attribute name]
- expected: FAIL
-
- [HTMLSlotElement interface: operation assignedNodes(AssignedNodesOptions)]
- expected: FAIL
-
[HTMLSlotElement must be primary interface of document.createElement("slot")]
expected: FAIL
[Stringification of document.createElement("slot")]
expected: FAIL
[HTMLSlotElement interface: document.createElement("slot") must inherit property "name" with the proper type (0)]
expected: FAIL
@@ -2696,34 +2675,22 @@
expected: FAIL
[HTMLMediaElement interface: new Audio() must inherit property "audioTracks" with the proper type (38)]
expected: FAIL
[HTMLMediaElement interface: new Audio() must inherit property "videoTracks" with the proper type (39)]
expected: FAIL
- [CanvasRenderingContext2D interface: operation getTransform()]
- expected: FAIL
-
- [CanvasRenderingContext2D interface: operation setTransform(unrestricted double,unrestricted double,unrestricted double,unrestricted double,unrestricted double,unrestricted double)]
- expected: FAIL
-
- [CanvasRenderingContext2D interface: operation setTransform(DOMMatrixInit)]
- expected: FAIL
-
[CanvasRenderingContext2D interface: attribute imageSmoothingQuality]
expected: FAIL
[CanvasRenderingContext2D interface: operation clearHitRegions()]
expected: FAIL
- [CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "getTransform" with the proper type (7)]
- expected: FAIL
-
[CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "imageSmoothingQuality" with the proper type (14)]
expected: FAIL
[CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "resetClip" with the proper type (35)]
expected: FAIL
[CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "scrollPathIntoView" with the proper type (42)]
expected: FAIL
@@ -2738,19 +2705,16 @@
expected: FAIL
[CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "clearHitRegions" with the proper type (52)]
expected: FAIL
[CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "direction" with the proper type (68)]
expected: FAIL
- [CanvasPattern interface: operation setTransform(DOMMatrixInit)]
- expected: FAIL
-
[Window interface: window must inherit property "oncancel" with the proper type (40)]
expected: FAIL
[Window interface: window must inherit property "oncuechange" with the proper type (47)]
expected: FAIL
[Window interface: window must inherit property "onmousewheel" with the proper type (78)]
expected: FAIL
@@ -3899,43 +3863,31 @@
expected: FAIL
[HTMLCanvasElement interface: operation transferControlToOffscreen()]
expected: FAIL
[HTMLCanvasElement interface: document.createElement("canvas") must inherit property "transferControlToOffscreen()" with the proper type]
expected: FAIL
- [CanvasRenderingContext2D interface: operation setTransform(unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double)]
- expected: FAIL
-
- [CanvasRenderingContext2D interface: operation setTransform(DOMMatrix2DInit)]
- expected: FAIL
-
- [CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "getTransform()" with the proper type]
- expected: FAIL
-
[CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "imageSmoothingQuality" with the proper type]
expected: FAIL
[CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "resetClip()" with the proper type]
expected: FAIL
[CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "scrollPathIntoView()" with the proper type]
expected: FAIL
[CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "scrollPathIntoView(Path2D)" with the proper type]
expected: FAIL
[CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "direction" with the proper type]
expected: FAIL
- [CanvasPattern interface: operation setTransform(DOMMatrix2DInit)]
- expected: FAIL
-
[ImageBitmapRenderingContext interface: attribute canvas]
expected: FAIL
[OffscreenCanvas interface: existence and properties of interface object]
expected: FAIL
[OffscreenCanvas interface object length]
expected: FAIL
@@ -4349,11 +4301,8 @@
expected: FAIL
[HTMLFrameSetElement interface: document.createElement("frameset") must inherit property "onrejectionhandled" with the proper type]
expected: FAIL
[HTMLFrameSetElement interface: document.createElement("frameset") must inherit property "onunhandledrejection" with the proper type]
expected: FAIL
- [Test driver]
- expected: FAIL
-
--- a/testing/web-platform/tests/2dcontext/conformance-requirements/2d.missingargs.html
+++ b/testing/web-platform/tests/2dcontext/conformance-requirements/2d.missingargs.html
@@ -28,17 +28,16 @@ if (ctx.transform) { // (avoid spurious
assert_throws(new TypeError(), function() { ctx.transform(); });
assert_throws(new TypeError(), function() { ctx.transform(1); });
assert_throws(new TypeError(), function() { ctx.transform(1, 0); });
assert_throws(new TypeError(), function() { ctx.transform(1, 0, 0); });
assert_throws(new TypeError(), function() { ctx.transform(1, 0, 0, 1); });
assert_throws(new TypeError(), function() { ctx.transform(1, 0, 0, 1, 0); });
}
if (ctx.setTransform) {
- assert_throws(new TypeError(), function() { ctx.setTransform(); });
assert_throws(new TypeError(), function() { ctx.setTransform(1); });
assert_throws(new TypeError(), function() { ctx.setTransform(1, 0); });
assert_throws(new TypeError(), function() { ctx.setTransform(1, 0, 0); });
assert_throws(new TypeError(), function() { ctx.setTransform(1, 0, 0, 1); });
assert_throws(new TypeError(), function() { ctx.setTransform(1, 0, 0, 1, 0); });
}
assert_throws(new TypeError(), function() { ctx.createLinearGradient(); });
assert_throws(new TypeError(), function() { ctx.createLinearGradient(0); });
--- a/testing/web-platform/tests/css/geometry-1/DOMMatrix2DInit-validate-fixup.html
+++ b/testing/web-platform/tests/css/geometry-1/DOMMatrix2DInit-validate-fixup.html
@@ -5,38 +5,76 @@
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/dommatrix-test-util.js"></script>
<canvas id=canvas hidden></canvas>
<script>
setup(() => {
window.canvas = document.getElementById('canvas');
window.ctx = canvas.getContext('2d');
+ window.ctx.fillStyle = '#000';
});
+function clearCanvas(ctx) {
+ ctx.resetTransform();
+ ctx.clearRect(0, 0, window.canvas.width, window.canvas.height);
+}
+
+function drawRectWithSetTransform(ctx, transform) {
+ clearCanvas(ctx);
+ ctx.setTransform(transform);
+ ctx.fillRect(20, 20, 30, 30);
+ return window.canvas.toDataURL();
+}
+
+function drawRectWithAddPathTransform(ctx, transform) {
+ clearCanvas(ctx);
+ var path = new Path2D();
+ path.rect(20, 20, 30, 30);
+ var transformedPath = new Path2D();
+ if (transform === undefined) {
+ transformedPath.addPath(path);
+ } else {
+ transformedPath.addPath(path, transform);
+ }
+ ctx.fill(transformedPath);
+ return window.canvas.toDataURL();
+}
+
[
{a: 1, m11: 2},
{b: 0, m12: -1},
{c: Infinity, m21: -Infinity},
{d: 0, m22: NaN},
{e: 1, m41: 1.00000001},
{f: 0, m42: Number.MIN_VALUE},
].forEach(dict => {
test(() => {
ctx.resetTransform();
assert_throws(new TypeError(), () => ctx.setTransform(dict));
- }, `${format_dict(dict)} (invalid)`);
+ }, `setTransform(${format_dict(dict)}) (invalid)`);
+
+ test(() => {
+ assert_throws(new TypeError(), () => drawRectWithAddPathTransform(ctx, dict));
+ }, `addPath(${format_dict(dict)}) (invalid)`);
});
test(() => {
ctx.resetTransform();
ctx.setTransform(1, 2, 3, 4, 5, 6);
const matrix = ctx.getTransform();
checkMatrix(matrix, matrix2D({m11: 1, m12: 2, m21: 3, m22: 4, m41: 5, m42: 6}));
-}, `Sanity check without dictionary`);
+}, `setTransform (Sanity check without dictionary)`);
+
+test(() => {
+ var ident = matrix2D({});
+ var expectedResultURL = drawRectWithSetTransform(ctx, ident);
+ var actualResultURL = drawRectWithAddPathTransform(ctx);
+ assert_equals(actualResultURL, expectedResultURL);
+}, `addPath (Sanity check without second parameter)`);
[
// Input dict that would throw if ignore3D was false
[{m13: 1, is2D: true}, matrix2D({})],
[{m14: 1, is2D: true}, matrix2D({})],
[{m23: 1, is2D: true}, matrix2D({})],
[{m24: 1, is2D: true}, matrix2D({})],
[{m31: 1, is2D: true}, matrix2D({})],
@@ -52,20 +90,20 @@ test(() => {
[{}, matrix2D({})],
[{is2D: undefined}, matrix2D({})],
[{a: 1, m11: 1}, matrix2D({m11: 1})],
[{b: 0, m12: undefined}, matrix2D({m12: 0})],
[{c: 0, m21: 0}, matrix2D({m21: 0})],
[{c: 0, m21: -0}, matrix2D({m21: -0})],
[{c: -0, m21: 0}, matrix2D({m21: 0})],
[{c: -0, m21: -0}, matrix2D({m21: -0})],
- [{d: Infinity, m22: Infinity}, matrix2D({m22: Infinity})],
- [{e: -Infinity, m41: -Infinity}, matrix2D({m41: -Infinity})],
- [{f: NaN, m42: NaN}, matrix2D({m42: NaN})],
- [{f: NaN, m42: NaN, is2D: true}, matrix2D({m42: NaN})],
+ [{d: Infinity, m22: Infinity}, matrix2D({})], // should be silently ignored
+ [{e: -Infinity, m41: -Infinity}, matrix2D({})], // should be silently ignored
+ [{f: NaN, m42: NaN}, matrix2D({})], // should be silently ignored
+ [{f: NaN, m42: NaN, is2D: true}, matrix2D({})], // should be silently ignored
[{f: 0, m42: null}, matrix2D({m42: 0})], // null is converted to 0
[{f: -0, m42: null}, matrix2D({m42: 0})], // null is converted to 0
[{a: 2}, matrix2D({m11: 2})],
[{b: 2}, matrix2D({m12: 2})],
[{c: 2}, matrix2D({m21: 2})],
[{d: 2}, matrix2D({m22: 2})],
[{e: 2}, matrix2D({m41: 2})],
[{f: 2}, matrix2D({m42: 2})],
@@ -129,11 +167,17 @@ test(() => {
[{is2D: false}, matrix2D({})],
[{is2D: null}, matrix2D({})],
].forEach(([dict, expected]) => {
test(() => {
ctx.resetTransform();
ctx.setTransform(dict);
const matrix = ctx.getTransform();
checkMatrix(matrix, expected);
- }, `${format_dict(dict)}`);
-});
+ }, `setTransform(${format_dict(dict)})`);
+
+ test(() => {
+ var expectedResultURL = drawRectWithSetTransform(ctx, expected);
+ var actualResultURL = drawRectWithAddPathTransform(ctx, expected);
+ assert_equals(actualResultURL, expectedResultURL);
+ }, `addPath(${format_dict(dict)})`);
+ });
</script>
--- a/testing/web-platform/tests/html/dom/interfaces.html
+++ b/testing/web-platform/tests/html/dom/interfaces.html
@@ -27,17 +27,18 @@ setup(function() {
function createInput(type) {
var input = document.createElement('input');
input.type = type;
return input;
}
function doTest([html, dom, cssom, uievents, touchevents]) {
var idlArray = new IdlArray();
- idlArray.add_untested_idls(dom + cssom + uievents + touchevents);
+ var svg = "interface SVGElement : Element {};";
+ idlArray.add_untested_idls(dom + svg + cssom + uievents + touchevents);
idlArray.add_idls(html);
idlArray.add_objects({
NodeList: ['document.getElementsByName("name")'],
HTMLAllCollection: ['document.all'],
HTMLFormControlsCollection: ['document.createElement("form").elements'],
RadioNodeList: [],
HTMLOptionsCollection: ['document.createElement("select").options'],