зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1565997 - CanvasPattern.setTransform should take a DOMMatrix2DInit r=emilio,lsalzman
Differential Revision: https://phabricator.services.mozilla.com/D80058
This commit is contained in:
Родитель
ff42324cf4
Коммит
bcf51974c1
|
@ -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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче