From fc594697eed0b0e9aca9824dfcd186190fd886f3 Mon Sep 17 00:00:00 2001 From: Aaron Krajeski Date: Thu, 6 May 2021 05:39:51 -0700 Subject: [PATCH] Implement colorMatrix filters for CanvasFilter objects The existing SVG interface has been copied exactly, even when it doesn't make a ton of sense, for example: ctx.filter = new CanvasFilter({colorMatrix: {type: "saturate", values: 0.5}}); Uses the key "values" instead of "value", even though it's only a single number. Bug: 1169216 Change-Id: I6242f1909645ee4a2f7a6258b6563b44f3eb76eb Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2855935 Commit-Queue: Aaron Krajeski Reviewed-by: Juanmi Huertas Reviewed-by: Yi Xu Cr-Commit-Position: refs/heads/master@{#879788} --- ...filter.canvasFilterObject.colorMatrix.html | 69 +++++++++++++++++++ ...filter.canvasFilterObject.colorMatrix.html | 68 ++++++++++++++++++ ...r.canvasFilterObject.colorMatrix.worker.js | 64 +++++++++++++++++ html/canvas/tools/yaml/element/filters.yaml | 48 +++++++++++++ html/canvas/tools/yaml/offscreen/filters.yaml | 48 +++++++++++++ 5 files changed, 297 insertions(+) create mode 100644 html/canvas/element/filters/2d.filter.canvasFilterObject.colorMatrix.html create mode 100644 html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.html create mode 100644 html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.worker.js diff --git a/html/canvas/element/filters/2d.filter.canvasFilterObject.colorMatrix.html b/html/canvas/element/filters/2d.filter.canvasFilterObject.colorMatrix.html new file mode 100644 index 00000000000000..ffb0dd2c0391ac --- /dev/null +++ b/html/canvas/element/filters/2d.filter.canvasFilterObject.colorMatrix.html @@ -0,0 +1,69 @@ + + +Canvas test: 2d.filter.canvasFilterObject.colorMatrix + + + + + + +

2d.filter.canvasFilterObject.colorMatrix

+

Test the functionality of ColorMatrix filters in CanvasFilter objects

+ + +

Actual output:

+

FAIL (fallback content)

+

Expected output:

+

    + + diff --git a/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.html b/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.html new file mode 100644 index 00000000000000..ed4fe910437b22 --- /dev/null +++ b/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.html @@ -0,0 +1,68 @@ + + +OffscreenCanvas test: 2d.filter.canvasFilterObject.colorMatrix + + + + +

    2d.filter.canvasFilterObject.colorMatrix

    +

    Test the functionality of ColorMatrix filters in CanvasFilter objects

    + + + diff --git a/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.worker.js b/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.worker.js new file mode 100644 index 00000000000000..a2f73e09e2f7f8 --- /dev/null +++ b/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.worker.js @@ -0,0 +1,64 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.filter.canvasFilterObject.colorMatrix +// Description:Test the functionality of ColorMatrix filters in CanvasFilter objects +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +var t = async_test("Test the functionality of ColorMatrix filters in CanvasFilter objects"); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + +var offscreenCanvas = new OffscreenCanvas(100, 50); +var ctx = offscreenCanvas.getContext('2d'); + +assert_throws_js(TypeError, function() { new CanvasFilter({colorMatrix: {values: undefined}}); }); +assert_throws_js(TypeError, function() { new CanvasFilter({colorMatrix: {values: "foo"}}); }); +assert_throws_js(TypeError, function() { new CanvasFilter({colorMatrix: {values: null}}); }); +assert_throws_js(TypeError, function() { new CanvasFilter({colorMatrix: {values: [1, 2, 3]}}); }); +assert_throws_js(TypeError, function() { new CanvasFilter({colorMatrix: {values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, "a"]}}); }); +assert_throws_js(TypeError, function() { new CanvasFilter({colorMatrix: {values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, Infinity]}}); }); +ctx.fillStyle = "#f00"; +ctx.filter = new CanvasFilter({colorMatrix: {type: "hueRotate", values: 0}}); +ctx.fillRect(0, 0, 100, 50); +_assertPixelApprox(offscreenCanvas, 10,10, 255,0,0,255, "10,10", "255,0,0,255", 2); +ctx.filter = new CanvasFilter({colorMatrix: {type: "hueRotate", values: 90}}); +ctx.fillRect(0, 0, 100, 50); +_assertPixelApprox(offscreenCanvas, 10,10, 0,91,0,255, "10,10", "0,91,0,255", 2); +ctx.filter = new CanvasFilter({colorMatrix: {type: "hueRotate", values: 180}}); +ctx.fillRect(0, 0, 100, 50); +_assertPixelApprox(offscreenCanvas, 10,10, 0,109,109,255, "10,10", "0,109,109,255", 2); +ctx.filter = new CanvasFilter({colorMatrix: {type: "hueRotate", values: 270}}); +ctx.fillRect(0, 0, 100, 50); +_assertPixelApprox(offscreenCanvas, 10,10, 109,18,255,255, "10,10", "109,18,255,255", 2); +ctx.filter = new CanvasFilter({colorMatrix: {type: "saturate", values: 0.5}}); +ctx.fillRect(0, 0, 100, 50); +_assertPixelApprox(offscreenCanvas, 10,10, 155,27,27,255, "10,10", "155,27,27,255", 2); +ctx.clearRect(0, 0, 100, 50); +ctx.filter = new CanvasFilter({colorMatrix: {type: "luminanceToAlpha"}}); +ctx.fillRect(0, 0, 100, 50); +_assertPixelApprox(offscreenCanvas, 10,10, 0,0,0,54, "10,10", "0,0,0,54", 2); +ctx.filter = new CanvasFilter({colorMatrix: {values: [ + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0 +]}}); +ctx.fillRect(0, 0, 50, 25); +ctx.fillStyle = "#0f0"; +ctx.fillRect(50, 0, 50, 25); +ctx.fillStyle = "#00f"; +ctx.fillRect(0, 25, 50, 25); +ctx.fillStyle = "#fff"; +ctx.fillRect(50, 25, 50, 25); +_assertPixelApprox(offscreenCanvas, 10,10, 0,255,0,255, "10,10", "0,255,0,255", 2); +_assertPixelApprox(offscreenCanvas, 60,10, 0,255,0,255, "60,10", "0,255,0,255", 2); +_assertPixelApprox(offscreenCanvas, 10,30, 0,255,0,255, "10,30", "0,255,0,255", 2); +_assertPixelApprox(offscreenCanvas, 60,30, 0,255,0,255, "60,30", "0,255,0,255", 2); +t.done(); +}); +done(); diff --git a/html/canvas/tools/yaml/element/filters.yaml b/html/canvas/tools/yaml/element/filters.yaml index 2c275d6d73b223..c4dabab60640f1 100644 --- a/html/canvas/tools/yaml/element/filters.yaml +++ b/html/canvas/tools/yaml/element/filters.yaml @@ -61,3 +61,51 @@ @assert throws TypeError ctx.filter = new CanvasFilter({blur: {}}); @assert throws TypeError ctx.filter = new CanvasFilter({blur: {stdDevation: null}}); @assert throws TypeError ctx.filter = new CanvasFilter({blur: {stdDeviation: "foo"}}); + +- name: 2d.filter.canvasFilterObject.colorMatrix + desc: Test the functionality of ColorMatrix filters in CanvasFilter objects + code: | + @assert throws TypeError new CanvasFilter({colorMatrix: {values: undefined}}); + @assert throws TypeError new CanvasFilter({colorMatrix: {values: "foo"}}); + @assert throws TypeError new CanvasFilter({colorMatrix: {values: null}}); + @assert throws TypeError new CanvasFilter({colorMatrix: {values: [1, 2, 3]}}); + @assert throws TypeError new CanvasFilter({colorMatrix: {values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, "a"]}}); + @assert throws TypeError new CanvasFilter({colorMatrix: {values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, Infinity]}}); + ctx.fillStyle = "#f00"; + ctx.filter = new CanvasFilter({colorMatrix: {type: "hueRotate", values: 0}}); + ctx.fillRect(0, 0, 100, 50); + @assert pixel 10,10 ==~ 255,0,0,255; + ctx.filter = new CanvasFilter({colorMatrix: {type: "hueRotate", values: 90}}); + ctx.fillRect(0, 0, 100, 50); + @assert pixel 10,10 ==~ 0,91,0,255; + ctx.filter = new CanvasFilter({colorMatrix: {type: "hueRotate", values: 180}}); + ctx.fillRect(0, 0, 100, 50); + @assert pixel 10,10 ==~ 0,109,109,255; + ctx.filter = new CanvasFilter({colorMatrix: {type: "hueRotate", values: 270}}); + ctx.fillRect(0, 0, 100, 50); + @assert pixel 10,10 ==~ 109,18,255,255; + ctx.filter = new CanvasFilter({colorMatrix: {type: "saturate", values: 0.5}}); + ctx.fillRect(0, 0, 100, 50); + @assert pixel 10,10 ==~ 155,27,27,255; + ctx.clearRect(0, 0, 100, 50); + ctx.filter = new CanvasFilter({colorMatrix: {type: "luminanceToAlpha"}}); + ctx.fillRect(0, 0, 100, 50); + @assert pixel 10,10 ==~ 0,0,0,54; + ctx.filter = new CanvasFilter({colorMatrix: {values: [ + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0 + ]}}); + ctx.fillRect(0, 0, 50, 25); + ctx.fillStyle = "#0f0"; + ctx.fillRect(50, 0, 50, 25); + ctx.fillStyle = "#00f"; + ctx.fillRect(0, 25, 50, 25); + ctx.fillStyle = "#fff"; + ctx.fillRect(50, 25, 50, 25); + @assert pixel 10,10 ==~ 0,255,0,255; + @assert pixel 60,10 ==~ 0,255,0,255; + @assert pixel 10,30 ==~ 0,255,0,255; + @assert pixel 60,30 ==~ 0,255,0,255; + expected: green \ No newline at end of file diff --git a/html/canvas/tools/yaml/offscreen/filters.yaml b/html/canvas/tools/yaml/offscreen/filters.yaml index 43062a66f405a3..dd11080b4ca893 100644 --- a/html/canvas/tools/yaml/offscreen/filters.yaml +++ b/html/canvas/tools/yaml/offscreen/filters.yaml @@ -29,3 +29,51 @@ @assert throws TypeError ctx.filter = new CanvasFilter({blur: {stdDevation: null}}); @assert throws TypeError ctx.filter = new CanvasFilter({blur: {stdDeviation: "foo"}}); t.done(); + +- name: 2d.filter.canvasFilterObject.colorMatrix + desc: Test the functionality of ColorMatrix filters in CanvasFilter objects + code: | + @assert throws TypeError new CanvasFilter({colorMatrix: {values: undefined}}); + @assert throws TypeError new CanvasFilter({colorMatrix: {values: "foo"}}); + @assert throws TypeError new CanvasFilter({colorMatrix: {values: null}}); + @assert throws TypeError new CanvasFilter({colorMatrix: {values: [1, 2, 3]}}); + @assert throws TypeError new CanvasFilter({colorMatrix: {values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, "a"]}}); + @assert throws TypeError new CanvasFilter({colorMatrix: {values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, Infinity]}}); + ctx.fillStyle = "#f00"; + ctx.filter = new CanvasFilter({colorMatrix: {type: "hueRotate", values: 0}}); + ctx.fillRect(0, 0, 100, 50); + @assert pixel 10,10 ==~ 255,0,0,255; + ctx.filter = new CanvasFilter({colorMatrix: {type: "hueRotate", values: 90}}); + ctx.fillRect(0, 0, 100, 50); + @assert pixel 10,10 ==~ 0,91,0,255; + ctx.filter = new CanvasFilter({colorMatrix: {type: "hueRotate", values: 180}}); + ctx.fillRect(0, 0, 100, 50); + @assert pixel 10,10 ==~ 0,109,109,255; + ctx.filter = new CanvasFilter({colorMatrix: {type: "hueRotate", values: 270}}); + ctx.fillRect(0, 0, 100, 50); + @assert pixel 10,10 ==~ 109,18,255,255; + ctx.filter = new CanvasFilter({colorMatrix: {type: "saturate", values: 0.5}}); + ctx.fillRect(0, 0, 100, 50); + @assert pixel 10,10 ==~ 155,27,27,255; + ctx.clearRect(0, 0, 100, 50); + ctx.filter = new CanvasFilter({colorMatrix: {type: "luminanceToAlpha"}}); + ctx.fillRect(0, 0, 100, 50); + @assert pixel 10,10 ==~ 0,0,0,54; + ctx.filter = new CanvasFilter({colorMatrix: {values: [ + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0 + ]}}); + ctx.fillRect(0, 0, 50, 25); + ctx.fillStyle = "#0f0"; + ctx.fillRect(50, 0, 50, 25); + ctx.fillStyle = "#00f"; + ctx.fillRect(0, 25, 50, 25); + ctx.fillStyle = "#fff"; + ctx.fillRect(50, 25, 50, 25); + @assert pixel 10,10 ==~ 0,255,0,255; + @assert pixel 60,10 ==~ 0,255,0,255; + @assert pixel 10,30 ==~ 0,255,0,255; + @assert pixel 60,30 ==~ 0,255,0,255; + t.done(); \ No newline at end of file