Bug 1565997 - CanvasPattern.setTransform should take a DOMMatrix2DInit r=emilio,lsalzman

Differential Revision: https://phabricator.services.mozilla.com/D80058
This commit is contained in:
longsonr 2020-06-24 21:19:12 +00:00
Родитель ff42324cf4
Коммит bcf51974c1
11 изменённых файлов: 192 добавлений и 18 удалений

Просмотреть файл

@ -20,7 +20,7 @@ class SourceSurface;
} // namespace gfx } // namespace gfx
namespace dom { namespace dom {
class SVGMatrix; struct DOMMatrix2DInit;
class CanvasPattern final : public nsWrapperCache { class CanvasPattern final : public nsWrapperCache {
~CanvasPattern() = default; ~CanvasPattern() = default;
@ -51,7 +51,7 @@ class CanvasPattern final : public nsWrapperCache {
CanvasRenderingContext2D* GetParentObject() { return mContext; } CanvasRenderingContext2D* GetParentObject() { return mContext; }
// WebIDL // WebIDL
void SetTransform(SVGMatrix& matrix); void SetTransform(const DOMMatrix2DInit& aInit, ErrorResult& aError);
RefPtr<CanvasRenderingContext2D> mContext; RefPtr<CanvasRenderingContext2D> mContext;
RefPtr<gfx::SourceSurface> mSurface; RefPtr<gfx::SourceSurface> mSurface;

Просмотреть файл

@ -104,9 +104,7 @@
#include "mozilla/dom/HTMLImageElement.h" #include "mozilla/dom/HTMLImageElement.h"
#include "mozilla/dom/HTMLVideoElement.h" #include "mozilla/dom/HTMLVideoElement.h"
#include "mozilla/dom/SVGImageElement.h" #include "mozilla/dom/SVGImageElement.h"
#include "mozilla/dom/SVGMatrix.h"
#include "mozilla/dom/TextMetrics.h" #include "mozilla/dom/TextMetrics.h"
#include "mozilla/dom/SVGMatrix.h"
#include "mozilla/FloatingPoint.h" #include "mozilla/FloatingPoint.h"
#include "nsGlobalWindow.h" #include "nsGlobalWindow.h"
#include "nsFilterInstance.h" #include "nsFilterInstance.h"
@ -703,8 +701,18 @@ class AdjustedTarget {
UniquePtr<AdjustedTargetForFilter> mFilterTarget; UniquePtr<AdjustedTargetForFilter> mFilterTarget;
}; };
void CanvasPattern::SetTransform(SVGMatrix& aMatrix) { void CanvasPattern::SetTransform(const DOMMatrix2DInit& aInit,
mTransform = ToMatrix(aMatrix.GetMatrix()); ErrorResult& aError) {
RefPtr<DOMMatrixReadOnly> matrix =
DOMMatrixReadOnly::FromMatrix(GetParentObject(), aInit, aError);
if (aError.Failed()) {
return;
}
const auto* matrix2D = matrix->GetInternal2D();
if (!matrix2D->IsFinite()) {
return;
}
mTransform = Matrix(*matrix2D);
} }
void CanvasGradient::AddColorStop(float aOffset, const nsACString& aColorstr, void CanvasGradient::AddColorStop(float aOffset, const nsACString& aColorstr,

Просмотреть файл

@ -28,7 +28,6 @@ function isPixel(ctx, x,y, r,g,b,a, d) {
<p>Canvas test: 2d.composite.canvaspattern.setTransform</p> <p>Canvas test: 2d.composite.canvaspattern.setTransform</p>
<canvas id="ctx" width="100" height="50"><p class="fallback">FAIL <canvas id="ctx" width="100" height="50"><p class="fallback">FAIL
(fallback content)</p></canvas> (fallback content)</p></canvas>
<svg id="svg1"></svg>
<img src="image_rgrg-256x256.png" id="rgrg-256x256.png" width="32" <img src="image_rgrg-256x256.png" id="rgrg-256x256.png" width="32"
height="32" class="resource"> height="32" class="resource">
@ -42,8 +41,7 @@ function test_2d_canvaspattern_setTransform() {
var img = document.getElementById("rgrg-256x256.png"); var img = document.getElementById("rgrg-256x256.png");
var pat = ctx.createPattern(img,"repeat"); var pat = ctx.createPattern(img,"repeat");
var svg = document.getElementById("svg1"); var mtx = new DOMMatrix()
var mtx = svg1.createSVGMatrix();
pat.setTransform(mtx.rotate(-45).scale(0.1)); pat.setTransform(mtx.rotate(-45).scale(0.1));
ctx.fillStyle = pat; ctx.fillStyle = pat;
ctx.fillRect(0, 0, 100, 50); ctx.fillRect(0, 0, 100, 50);

Просмотреть файл

@ -67,10 +67,6 @@ class SVGMatrix final : public nsWrapperCache {
explicit SVGMatrix(const gfxMatrix& aMatrix) : mMatrix(aMatrix) {} explicit SVGMatrix(const gfxMatrix& aMatrix) : mMatrix(aMatrix) {}
const gfxMatrix& GetMatrix() const {
return mTransform ? mTransform->Matrixgfx() : mMatrix;
}
// WebIDL // WebIDL
DOMSVGTransform* GetParentObject() const; DOMSVGTransform* GetParentObject() const;
virtual JSObject* WrapObject(JSContext* aCx, virtual JSObject* WrapObject(JSContext* aCx,
@ -105,6 +101,10 @@ class SVGMatrix final : public nsWrapperCache {
private: private:
~SVGMatrix() = default; ~SVGMatrix() = default;
const gfxMatrix& GetMatrix() const {
return mTransform ? mTransform->Matrixgfx() : mMatrix;
}
void SetMatrix(const gfxMatrix& aMatrix) { void SetMatrix(const gfxMatrix& aMatrix) {
if (mTransform) { if (mTransform) {
mTransform->SetMatrix(aMatrix); mTransform->SetMatrix(aMatrix);

Просмотреть файл

@ -348,8 +348,8 @@ interface CanvasPattern {
// [Throws, LenientFloat] - could not do this overload because of bug 1020975 // [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); // void setTransform(double a, double b, double c, double d, double e, double f);
// No throw necessary here - SVGMatrix is always good. [Throws]
void setTransform(SVGMatrix matrix); void setTransform(optional DOMMatrix2DInit matrix = {});
}; };
[Exposed=Window] [Exposed=Window]

Просмотреть файл

@ -675,9 +675,6 @@ prefs: [dom.security.featurePolicy.enabled:true, dom.security.featurePolicy.expe
[OffscreenCanvasRenderingContext2D interface: operation fillText(DOMString, unrestricted double, unrestricted double, optional unrestricted double)] [OffscreenCanvasRenderingContext2D interface: operation fillText(DOMString, unrestricted double, unrestricted double, optional unrestricted double)]
expected: FAIL expected: FAIL
[CanvasPattern interface: operation setTransform(optional DOMMatrix2DInit)]
expected: FAIL
[ElementInternals interface: operation setFormValue((File or USVString or FormData)?, optional (File or USVString or FormData)?)] [ElementInternals interface: operation setFormValue((File or USVString or FormData)?, optional (File or USVString or FormData)?)]
expected: FAIL expected: FAIL

Просмотреть файл

@ -0,0 +1,42 @@
<!DOCTYPE html>
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
<title>Canvas test: 2d.pattern.transform.identity</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/html/canvas/resources/canvas-tests.js"></script>
<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
<body class="show_output">
<h1>2d.pattern.transform.identity</h1>
<p class="desc"></p>
<p class="output">Actual output:</p>
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
<ul id="d"></ul>
<script>
var t = async_test("");
_addTest(function(canvas, ctx) {
var canvas2 = document.createElement('canvas');
canvas2.width = 100;
canvas2.height = 50;
var pattern = ctx.createPattern(canvas2, 'no-repeat');
pattern.setTransform(new DOMMatrix());
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = '#f00';
ctx.fillStyle = pattern;
ctx.fillRect(0, 0, 100, 50);
_assertPixel(canvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255");
_assertPixel(canvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255");
_assertPixel(canvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255");
_assertPixel(canvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255");
});
</script>

Просмотреть файл

@ -0,0 +1,42 @@
<!DOCTYPE html>
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
<title>Canvas test: 2d.pattern.transform.infinity</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/html/canvas/resources/canvas-tests.js"></script>
<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
<body class="show_output">
<h1>2d.pattern.transform.infinity</h1>
<p class="desc"></p>
<p class="output">Actual output:</p>
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
<ul id="d"></ul>
<script>
var t = async_test("");
_addTest(function(canvas, ctx) {
var canvas2 = document.createElement('canvas');
canvas2.width = 100;
canvas2.height = 50;
var pattern = ctx.createPattern(canvas2, 'no-repeat');
pattern.setTransform({a: Infinity});
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = '#f00';
ctx.fillStyle = pattern;
ctx.fillRect(0, 0, 100, 50);
_assertPixel(canvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255");
_assertPixel(canvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255");
_assertPixel(canvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255");
_assertPixel(canvas, 98,48, 0,255,0,255, "98,48", "0,255,0,255");
});
</script>

Просмотреть файл

@ -0,0 +1,31 @@
<!DOCTYPE html>
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
<title>Canvas test: 2d.pattern.transform.invalid</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/html/canvas/resources/canvas-tests.js"></script>
<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
<body class="show_output">
<h1>2d.pattern.transform.invalid</h1>
<p class="desc"></p>
<p class="output">Actual output:</p>
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
<ul id="d"></ul>
<script>
var t = async_test("");
_addTest(function(canvas, ctx) {
var canvas2 = document.createElement('canvas');
canvas2.width = 100;
canvas2.height = 50;
var pattern = ctx.createPattern(canvas2, 'no-repeat');
assert_throws_js(TypeError, function() { pattern.setTransform({a: 1, m11: 2}); });
});
</script>

Просмотреть файл

@ -269,6 +269,8 @@ assertions:
- id: 2d.pattern.modify - id: 2d.pattern.modify
text: "Modifying this image after calling the createPattern() method *must* not affect the pattern<^>." text: "Modifying this image after calling the createPattern() method *must* not affect the pattern<^>."
- id: 2d.pattern.transform
text: "The setTransform(transform) method, when invoked, must run these steps:"
- id: 2d.pattern.missing - id: 2d.pattern.missing
text: "If the empty string is specified, repeat *must* be assumed<^>." text: "If the empty string is specified, repeat *must* be assumed<^>."
- id: 2d.pattern.unrecognised - id: 2d.pattern.unrecognised

Просмотреть файл

@ -1284,6 +1284,60 @@
@assert pixel 98,48 == 0,255,0,255; @assert pixel 98,48 == 0,255,0,255;
expected: green expected: green
- name: 2d.pattern.transform.identity
testing:
- 2d.pattern.transform
code: |
var canvas2 = document.createElement('canvas');
canvas2.width = 100;
canvas2.height = 50;
var pattern = ctx.createPattern(canvas2, 'no-repeat');
pattern.setTransform(new DOMMatrix());
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = '#f00';
ctx.fillStyle = pattern;
ctx.fillRect(0, 0, 100, 50);
@assert pixel 1,1 == 0,255,0,255;
@assert pixel 98,1 == 0,255,0,255;
@assert pixel 1,48 == 0,255,0,255;
@assert pixel 98,48 == 0,255,0,255;
expected: green
- name: 2d.pattern.transform.infinity
testing:
- 2d.pattern.transform
code: |
var canvas2 = document.createElement('canvas');
canvas2.width = 100;
canvas2.height = 50;
var pattern = ctx.createPattern(canvas2, 'no-repeat');
pattern.setTransform({a: Infinity});
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = '#f00';
ctx.fillStyle = pattern;
ctx.fillRect(0, 0, 100, 50);
@assert pixel 1,1 == 0,255,0,255;
@assert pixel 98,1 == 0,255,0,255;
@assert pixel 1,48 == 0,255,0,255;
@assert pixel 98,48 == 0,255,0,255;
expected: green
- name: 2d.pattern.transform.invalid
testing:
- 2d.pattern.transform
code: |
var canvas2 = document.createElement('canvas');
canvas2.width = 100;
canvas2.height = 50;
var pattern = ctx.createPattern(canvas2, 'no-repeat');
@assert throws TypeError pattern.setTransform({a: 1, m11: 2});
- name: 2d.pattern.image.undefined - name: 2d.pattern.image.undefined
testing: testing:
- 2d.pattern.IDL - 2d.pattern.IDL