Bug 1514538 - Support DOMMatrix2DInit for addPath r=bzbarsky

Differential Revision: https://phabricator.services.mozilla.com/D38054

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Kagami Sascha Rosylight 2019-07-16 16:35:26 +00:00
parent 0700383a62
commit 8f29f2145b
6 changed files with 34 additions and 276 deletions

View File

@ -26,6 +26,7 @@ class DOMRectReadOnly;
class DOMPoint;
struct DOMPointInit;
struct DOMQuadInit;
struct DOMRectInit;
class DOMQuad final : public nsWrapperCache {
~DOMQuad();

View File

@ -16,7 +16,7 @@ namespace mozilla {
namespace dom {
enum class CanvasWindingRule : uint8_t;
class SVGMatrix;
struct DOMMatrix2DInit;
class CanvasPath final : public nsWrapperCache {
public:
@ -65,8 +65,8 @@ class CanvasPath final : public nsWrapperCache {
CanvasPath(nsISupports* aParent,
already_AddRefed<gfx::PathBuilder> aPathBuilder);
void AddPath(CanvasPath& aCanvasPath,
const Optional<NonNull<SVGMatrix>>& aMatrix);
void AddPath(CanvasPath& aCanvasPath, const DOMMatrix2DInit& aInit,
ErrorResult& aError);
private:
virtual ~CanvasPath() {}

View File

@ -75,6 +75,7 @@
#include "mozilla/Assertions.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/dom/DOMMatrix.h"
#include "mozilla/dom/ImageBitmap.h"
#include "mozilla/dom/ImageData.h"
#include "mozilla/dom/PBrowserParent.h"
@ -5616,21 +5617,28 @@ void CanvasPath::BezierTo(const gfx::Point& aCP1, const gfx::Point& aCP2,
mPathBuilder->BezierTo(aCP1, aCP2, aCP3);
}
void CanvasPath::AddPath(CanvasPath& aCanvasPath,
const Optional<NonNull<SVGMatrix>>& aMatrix) {
void CanvasPath::AddPath(CanvasPath& aCanvasPath, const DOMMatrix2DInit& aInit,
ErrorResult& aError) {
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());
RefPtr<DOMMatrixReadOnly> matrix =
DOMMatrixReadOnly::FromMatrix(GetParentObject(), aInit, aError);
if (aError.Failed()) {
return;
}
if (!transform.IsIdentity()) {
RefPtr<PathBuilder> tempBuilder =
tempPath->TransformedCopyToBuilder(transform, FillRule::FILL_WINDING);
tempPath = tempBuilder->Finish();
}
Matrix transform(*(matrix->GetInternal2D()));
if (!transform.IsFinite()) {
return;
}
if (!transform.IsIdentity()) {
RefPtr<PathBuilder> tempBuilder =
tempPath->TransformedCopyToBuilder(transform, FillRule::FILL_WINDING);
tempPath = tempBuilder->Finish();
}
EnsurePathBuilder(); // in case a path is added to itself

View File

@ -395,6 +395,6 @@ interface TextMetrics {
Constructor(DOMString pathString)]
interface Path2D
{
void addPath(Path2D path, optional SVGMatrix transformation);
[Throws] void addPath(Path2D path, optional DOMMatrix2DInit transform = {});
};
Path2D implements CanvasPathMethods;

View File

@ -1,255 +0,0 @@
[DOMMatrix2DInit-validate-fixup.html]
[addPath({m13: 1, is2D: true})]
expected: FAIL
[addPath({m14: 1, is2D: true})]
expected: FAIL
[addPath({m23: 1, is2D: true})]
expected: FAIL
[addPath({m24: 1, is2D: true})]
expected: FAIL
[addPath({m31: 1, is2D: true})]
expected: FAIL
[addPath({m32: 1, is2D: true})]
expected: FAIL
[addPath({m33: 0, is2D: true})]
expected: FAIL
[addPath({m33: -0, is2D: true})]
expected: FAIL
[addPath({m33: -1, is2D: true})]
expected: FAIL
[addPath({m34: 1, is2D: true})]
expected: FAIL
[addPath({m43: 1, is2D: true})]
expected: FAIL
[addPath({m44: 0, is2D: true})]
expected: FAIL
[addPath({})]
expected: FAIL
[addPath({is2D: undefined})]
expected: FAIL
[addPath({a: 1, m11: 1})]
expected: FAIL
[addPath({b: 0, m12: undefined})]
expected: FAIL
[addPath({c: 0, m21: 0})]
expected: FAIL
[addPath({c: 0, m21: -0})]
expected: FAIL
[addPath({c: -0, m21: 0})]
expected: FAIL
[addPath({c: -0, m21: -0})]
expected: FAIL
[addPath({d: Infinity, m22: Infinity})]
expected: FAIL
[addPath({e: -Infinity, m41: -Infinity})]
expected: FAIL
[addPath({f: NaN, m42: NaN})]
expected: FAIL
[addPath({f: NaN, m42: NaN, is2D: true})]
expected: FAIL
[addPath({f: 0, m42: null})]
expected: FAIL
[addPath({f: -0, m42: null})]
expected: FAIL
[addPath({a: 2})]
expected: FAIL
[addPath({b: 2})]
expected: FAIL
[addPath({c: 2})]
expected: FAIL
[addPath({d: 2})]
expected: FAIL
[addPath({e: 2})]
expected: FAIL
[addPath({f: 2})]
expected: FAIL
[addPath({a: -0, b: -0, c: -0, d: -0, e: -0, f: -0})]
expected: FAIL
[addPath({a: -0, b: -0, c: -0, d: -0, e: -0, f: -0, is2D: true})]
expected: FAIL
[addPath({m11: 2})]
expected: FAIL
[addPath({m12: 2})]
expected: FAIL
[addPath({m21: 2})]
expected: FAIL
[addPath({m22: 2})]
expected: FAIL
[addPath({m41: 2})]
expected: FAIL
[addPath({m42: 2})]
expected: FAIL
[addPath({m11: -0, m12: -0, m21: -0, m22: -0, m41: -0, m42: -0})]
expected: FAIL
[addPath({m11: -0, m12: -0, m21: -0, m22: -0, m41: -0, m42: -0, is2D: true})]
expected: FAIL
[addPath({m13: 0, is2D: true})]
expected: FAIL
[addPath({m13: -0, is2D: true})]
expected: FAIL
[addPath({m14: 0, is2D: true})]
expected: FAIL
[addPath({m14: -0, is2D: true})]
expected: FAIL
[addPath({m23: 0, is2D: true})]
expected: FAIL
[addPath({m23: -0, is2D: true})]
expected: FAIL
[addPath({m24: 0, is2D: true})]
expected: FAIL
[addPath({m24: -0, is2D: true})]
expected: FAIL
[addPath({m31: 0, is2D: true})]
expected: FAIL
[addPath({m31: -0, is2D: true})]
expected: FAIL
[addPath({m32: 0, is2D: true})]
expected: FAIL
[addPath({m32: -0, is2D: true})]
expected: FAIL
[addPath({m33: 1, is2D: true})]
expected: FAIL
[addPath({m34: 0, is2D: true})]
expected: FAIL
[addPath({m34: -0, is2D: true})]
expected: FAIL
[addPath({m43: 0, is2D: true})]
expected: FAIL
[addPath({m43: -0, is2D: true})]
expected: FAIL
[addPath({m44: 1, is2D: true})]
expected: FAIL
[addPath({is2D: true})]
expected: FAIL
[addPath({m13: 1, is2D: false})]
expected: FAIL
[addPath({m14: 1, is2D: false})]
expected: FAIL
[addPath({m23: 1, is2D: false})]
expected: FAIL
[addPath({m24: 1, is2D: false})]
expected: FAIL
[addPath({m31: 1, is2D: false})]
expected: FAIL
[addPath({m32: 1, is2D: false})]
expected: FAIL
[addPath({m33: 0, is2D: false})]
expected: FAIL
[addPath({m33: -0, is2D: false})]
expected: FAIL
[addPath({m33: -1, is2D: false})]
expected: FAIL
[addPath({m34: 1, is2D: false})]
expected: FAIL
[addPath({m43: 1, is2D: false})]
expected: FAIL
[addPath({m44: 0, is2D: false})]
expected: FAIL
[addPath({m13: 1})]
expected: FAIL
[addPath({m14: 1})]
expected: FAIL
[addPath({m23: 1})]
expected: FAIL
[addPath({m24: 1})]
expected: FAIL
[addPath({m31: 1})]
expected: FAIL
[addPath({m32: 1})]
expected: FAIL
[addPath({m33: 0})]
expected: FAIL
[addPath({m34: 1})]
expected: FAIL
[addPath({m43: 1})]
expected: FAIL
[addPath({m44: 0})]
expected: FAIL
[addPath({is2D: false})]
expected: FAIL
[addPath({is2D: null})]
expected: FAIL

View File

@ -39,6 +39,8 @@ function drawRectWithAddPathTransform(ctx, transform) {
return window.canvas.toDataURL();
}
var emptyCanvasURL = window.canvas.toDataURL();
[
{a: 1, m11: 2},
{b: 0, m12: -1},
@ -95,10 +97,10 @@ test(() => {
[{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({})], // 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
[{d: Infinity, m22: Infinity}, null], // setTransform: silently ignore / addPath: silently halt
[{e: -Infinity, m41: -Infinity}, null], // setTransform: silently ignore / addPath: silently halt
[{f: NaN, m42: NaN}, null], // setTransform: silently ignore / addPath: silently halt
[{f: NaN, m42: NaN, is2D: true}, null], // setTransform: silently ignore / addPath: silently halt
[{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})],
@ -171,12 +173,14 @@ test(() => {
ctx.resetTransform();
ctx.setTransform(dict);
const matrix = ctx.getTransform();
checkMatrix(matrix, expected);
checkMatrix(matrix, expected || matrix2D({}));
}, `setTransform(${format_dict(dict)})`);
test(() => {
var expectedResultURL = drawRectWithSetTransform(ctx, expected);
var actualResultURL = drawRectWithAddPathTransform(ctx, expected);
var expectedResultURL = expected ?
drawRectWithSetTransform(ctx, expected) :
emptyCanvasURL;
var actualResultURL = drawRectWithAddPathTransform(ctx, dict);
assert_equals(actualResultURL, expectedResultURL);
}, `addPath(${format_dict(dict)})`);
});