Skip to content

Commit

Permalink
Make canvas filter input a flat dictionary
Browse files Browse the repository at this point in the history
As initially specced, CanvasFilter inputs had a single key that was the
name of the filter:

ctx.filter = new CanvasFilter({gaussianBlur: {stdDeviation: 5}});

As the result of the debate here
(whatwg/html#6763) the interface is changed to
have a "filter" key that names the filter type:

ctx.filter = new CanvasFilter(
  {filter: "gaussianBlur", stdDeviation: 5});

Bug: 1169216
Change-Id: If3fdd9185c1f02dd2dece7db0c92aba76f2d97e1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3098009
Commit-Queue: Aaron Krajeski <[email protected]>
Reviewed-by: Fernando Serboncini <[email protected]>
Cr-Commit-Position: refs/heads/main@{#916494}
NOKEYCHECK=True
GitOrigin-RevId: 833d2100d38c8656a28bb72109f07aa5158e9f9c
  • Loading branch information
mysteryDate authored and copybara-github committed Aug 30, 2021
1 parent 23b6832 commit 1ece459
Show file tree
Hide file tree
Showing 40 changed files with 285 additions and 272 deletions.
2 changes: 2 additions & 0 deletions blink/renderer/bindings/generated_in_core.gni
Original file line number Diff line number Diff line change
Expand Up @@ -1607,6 +1607,8 @@ generated_union_sources_in_core = [
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_node_string_trustedscript.h",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_object_string.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_object_string.h",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_object_objectarray.h",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_object_objectarray.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_performancemeasureoptions_string.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_performancemeasureoptions_string.h",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_readablebytestreamcontroller_readablestreamdefaultcontroller.cc",
Expand Down
2 changes: 0 additions & 2 deletions blink/renderer/bindings/generated_in_modules.gni
Original file line number Diff line number Diff line change
Expand Up @@ -2508,8 +2508,6 @@ generated_union_sources_in_modules = [
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_boolean_mediatrackconstraints.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_canvasfilter_string.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_canvasfilter_string.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_canvasfilterdictionary_canvasfilterdictionaryarray.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_canvasfilterdictionary_canvasfilterdictionaryarray.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_canvasrenderingcontext2d_gpucanvascontext_imagebitmaprenderingcontext_webgl2renderingcontext_webglrenderingcontext.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_canvasrenderingcontext2d_gpucanvascontext_imagebitmaprenderingcontext_webgl2renderingcontext_webglrenderingcontext.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_client_messageport_serviceworker.cc",
Expand Down
18 changes: 7 additions & 11 deletions blink/renderer/modules/canvas/canvas2d/canvas_filter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_filter.h"

#include "third_party/blink/renderer/bindings/modules/v8/v8_union_canvasfilterdictionary_canvasfilterdictionaryarray.h"
#include "third_party/blink/renderer/core/css/parser/css_parser.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_filter_operation_resolver.h"

Expand All @@ -13,19 +12,16 @@ namespace blink {
CanvasFilter::CanvasFilter(FilterOperations filter_operations)
: filter_operations_(filter_operations) {}

CanvasFilter* CanvasFilter::Create(
const V8UnionCanvasFilterDictionaryOrCanvasFilterDictionaryArray* init,
ExceptionState& exception_state) {
HeapVector<Member<CanvasFilterDictionary>> filter_array;
CanvasFilter* CanvasFilter::Create(const V8CanvasFilterInput* init,
ExceptionState& exception_state) {
HeapVector<ScriptValue> filter_array;

switch (init->GetContentType()) {
case V8UnionCanvasFilterDictionaryOrCanvasFilterDictionaryArray::
ContentType::kCanvasFilterDictionary:
filter_array.push_back(init->GetAsCanvasFilterDictionary());
case V8CanvasFilterInput::ContentType::kObject:
filter_array.push_back(init->GetAsObject());
break;
case V8UnionCanvasFilterDictionaryOrCanvasFilterDictionaryArray::
ContentType::kCanvasFilterDictionaryArray:
filter_array = init->GetAsCanvasFilterDictionaryArray();
case V8CanvasFilterInput::ContentType::kObjectArray:
filter_array = init->GetAsObjectArray();
break;
}

Expand Down
10 changes: 6 additions & 4 deletions blink/renderer/modules/canvas/canvas2d/canvas_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_FILTER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_FILTER_H_

#include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_union_object_objectarray.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
#include "third_party/blink/renderer/core/style/filter_operations.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"

namespace blink {

class ExceptionState;
class V8UnionCanvasFilterDictionaryOrCanvasFilterDictionaryArray;
// class V8UnionCanvasFilterDictionaryOrCanvasFilterDictionaryArray;

// This class stores an unresolved filter on CanvasRenderingContext2DState that
// has been created from the CanvasFilter javascript object. It will be parsed
Expand All @@ -21,9 +24,8 @@ class MODULES_EXPORT CanvasFilter final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();

public:
static CanvasFilter* Create(
const V8UnionCanvasFilterDictionaryOrCanvasFilterDictionaryArray* init,
ExceptionState& exception_state);
static CanvasFilter* Create(const V8CanvasFilterInput* init,
ExceptionState& exception_state);

explicit CanvasFilter(FilterOperations filter_operations);

Expand Down
4 changes: 2 additions & 2 deletions blink/renderer/modules/canvas/canvas2d/canvas_filter.idl
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

typedef (object or FrozenArray<object>) CanvasFilterInput;
[
Exposed=(Window,Worker), RuntimeEnabled=NewCanvas2DAPI
] interface CanvasFilter {

[RaisesException] constructor((CanvasFilterDictionary or FrozenArray<CanvasFilterDictionary>) init);

[RaisesException] constructor(CanvasFilterInput init);
};
Original file line number Diff line number Diff line change
Expand Up @@ -169,32 +169,34 @@ ComponentTransferFilterOperation* ResolveComponentTransfer(
} // namespace

FilterOperations CanvasFilterOperationResolver::CreateFilterOperations(
HeapVector<Member<CanvasFilterDictionary>> filters,
HeapVector<ScriptValue> filters,
ExceptionState& exception_state) {
FilterOperations operations;

for (auto filter : filters) {
if (filter->hasBlur()) {
if (auto* blur_operation =
ResolveBlur(Dictionary(filter->blur()), exception_state)) {
Dictionary filter_dict = Dictionary(filter);
absl::optional<String> name =
filter_dict.Get<IDLString>("filter", exception_state);
if (!name)
continue;

if (name == "gaussianBlur") {
if (auto* blur_operation = ResolveBlur(filter_dict, exception_state)) {
operations.Operations().push_back(blur_operation);
}
}
if (filter->hasColorMatrix()) {
Dictionary colormatrix_dict(filter->colorMatrix());
String type = colormatrix_dict.Get<IDLString>("type", exception_state)
if (name == "colorMatrix") {
String type = filter_dict.Get<IDLString>("type", exception_state)
.value_or("matrix");
if (type == "hueRotate") {
double amount =
colormatrix_dict.Get<IDLDouble>("values", exception_state)
.value_or(0);
filter_dict.Get<IDLDouble>("values", exception_state).value_or(0);
operations.Operations().push_back(
MakeGarbageCollected<BasicColorMatrixFilterOperation>(
amount, FilterOperation::HUE_ROTATE));
} else if (type == "saturate") {
double amount =
colormatrix_dict.Get<IDLDouble>("values", exception_state)
.value_or(0);
filter_dict.Get<IDLDouble>("values", exception_state).value_or(0);
operations.Operations().push_back(
MakeGarbageCollected<BasicColorMatrixFilterOperation>(
amount, FilterOperation::SATURATE));
Expand All @@ -203,19 +205,19 @@ FilterOperations CanvasFilterOperationResolver::CreateFilterOperations(
MakeGarbageCollected<BasicColorMatrixFilterOperation>(
0, FilterOperation::LUMINANCE_TO_ALPHA));
} else if (auto* color_matrix_operation =
ResolveColorMatrix(colormatrix_dict, exception_state)) {
ResolveColorMatrix(filter_dict, exception_state)) {
operations.Operations().push_back(color_matrix_operation);
}
}
if (filter->hasConvolveMatrix()) {
if (auto* convolve_operation = ResolveConvolveMatrix(
Dictionary(filter->convolveMatrix()), exception_state)) {
if (name == "convolveMatrix") {
if (auto* convolve_operation =
ResolveConvolveMatrix(filter_dict, exception_state)) {
operations.Operations().push_back(convolve_operation);
}
}
if (filter->hasComponentTransfer()) {
if (auto* component_transfer_operation = ResolveComponentTransfer(
Dictionary(filter->componentTransfer()), exception_state)) {
if (name == "componentTransfer") {
if (auto* component_transfer_operation =
ResolveComponentTransfer(filter_dict, exception_state)) {
operations.Operations().push_back(component_transfer_operation);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_FILTER_OPERATION_RESOLVER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_FILTER_OPERATION_RESOLVER_H_

#include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_canvas_filter_dictionary.h"
#include "third_party/blink/renderer/core/css_value_keywords.h"
Expand All @@ -26,9 +27,8 @@ class MODULES_EXPORT CanvasFilterOperationResolver {
STATIC_ONLY(CanvasFilterOperationResolver);

public:
static FilterOperations CreateFilterOperations(
HeapVector<Member<CanvasFilterDictionary>>,
ExceptionState&);
static FilterOperations CreateFilterOperations(HeapVector<ScriptValue>,
ExceptionState&);
};

} // namespace blink
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ <h1>2d.filter.canvasFilterObject.blur.exceptions</h1>
var t = async_test("Test exceptions on CanvasFilter() blur.object");
_addTest(function(canvas, ctx) {

assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({blur: null}); });
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({blur: {}}); });
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({blur: {stdDevation: null}}); });
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({blur: {stdDeviation: "foo"}}); });
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur"}); });
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDevation: null}); });
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: "foo"}); });


});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,44 +13,44 @@ <h1>2d.filter.canvasFilterObject.colorMatrix</h1>

<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("Test the functionality of ColorMatrix filters in CanvasFilter objects");
_addTest(function(canvas, ctx) {

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]}}); });
assert_throws_js(TypeError, function() { new CanvasFilter({filter: "colorMatrix", values: undefined}); });
assert_throws_js(TypeError, function() { new CanvasFilter({filter: "colorMatrix", values: "foo"}); });
assert_throws_js(TypeError, function() { new CanvasFilter({filter: "colorMatrix", values: null}); });
assert_throws_js(TypeError, function() { new CanvasFilter({filter: "colorMatrix", values: [1, 2, 3]}); });
assert_throws_js(TypeError, function() { new CanvasFilter({filter: "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({filter: "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.filter = new CanvasFilter({filter: "colorMatrix", type: "hueRotate", values: 0});
ctx.fillRect(0, 0, 100, 50);
_assertPixelApprox(canvas, 10,10, 255,0,0,255, "10,10", "255,0,0,255", 2);
ctx.filter = new CanvasFilter({colorMatrix: {type: "hueRotate", values: 90}});
ctx.filter = new CanvasFilter({filter: "colorMatrix", type: "hueRotate", values: 90});
ctx.fillRect(0, 0, 100, 50);
_assertPixelApprox(canvas, 10,10, 0,91,0,255, "10,10", "0,91,0,255", 2);
ctx.filter = new CanvasFilter({colorMatrix: {type: "hueRotate", values: 180}});
ctx.filter = new CanvasFilter({filter: "colorMatrix", type: "hueRotate", values: 180});
ctx.fillRect(0, 0, 100, 50);
_assertPixelApprox(canvas, 10,10, 0,109,109,255, "10,10", "0,109,109,255", 2);
ctx.filter = new CanvasFilter({colorMatrix: {type: "hueRotate", values: 270}});
ctx.filter = new CanvasFilter({filter: "colorMatrix", type: "hueRotate", values: 270});
ctx.fillRect(0, 0, 100, 50);
_assertPixelApprox(canvas, 10,10, 109,18,255,255, "10,10", "109,18,255,255", 2);
ctx.filter = new CanvasFilter({colorMatrix: {type: "saturate", values: 0.5}});
ctx.filter = new CanvasFilter({filter: "colorMatrix", type: "saturate", values: 0.5});
ctx.fillRect(0, 0, 100, 50);
_assertPixelApprox(canvas, 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.filter = new CanvasFilter({filter: "colorMatrix", type: "luminanceToAlpha"});
ctx.fillRect(0, 0, 100, 50);
_assertPixelApprox(canvas, 10,10, 0,0,0,54, "10,10", "0,0,0,54", 2);
ctx.filter = new CanvasFilter({colorMatrix: {values: [
ctx.filter = new CanvasFilter({filter: "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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ <h1>2d.filter.canvasFilterObject.componentTransfer.discrete</h1>
tableValuesR = [0, 0, 1, 1];
tableValuesG = [2, 0, 0.5, 3];
tableValuesB = [1, -1, 5, 0];
ctx.filter = new CanvasFilter({componentTransfer: {
ctx.filter = new CanvasFilter({filter: "componentTransfer",
funcR: {type: "discrete", tableValues: tableValuesR},
funcG: {type: "discrete", tableValues: tableValuesG},
funcB: {type: "discrete", tableValues: tableValuesB},
}});
});

const inputColors = [
[255, 255, 255],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ <h1>2d.filter.canvasFilterObject.componentTransfer.gamma</h1>
const amplitudes = [2, 1.1, 0.5];
const exponents = [5, 3, 1];
const offsets = [0.25, 0, 0.5];
ctx.filter = new CanvasFilter({componentTransfer: {
ctx.filter = new CanvasFilter({filter: "componentTransfer",
funcR: {type: "gamma", amplitude: amplitudes[0], exponent: exponents[0], offset: offsets[0]},
funcG: {type: "gamma", amplitude: amplitudes[1], exponent: exponents[1], offset: offsets[1]},
funcB: {type: "gamma", amplitude: amplitudes[2], exponent: exponents[2], offset: offsets[2]},
}});
});

const inputColors = [
[255, 255, 255],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ <h1>2d.filter.canvasFilterObject.componentTransfer.identity</h1>
var t = async_test("Test pixels on CanvasFilter() componentTransfer with identity type");
_addTest(function(canvas, ctx) {

ctx.filter = new CanvasFilter({componentTransfer: {
ctx.filter = new CanvasFilter({filter: "componentTransfer",
funcR: {type: "identity"},
funcG: {type: "identity"},
funcB: {type: "identity"},
}});
});

const inputColors = [
[255, 255, 255],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ <h1>2d.filter.canvasFilterObject.componentTransfer.linear</h1>

const slopes = [0.5, 1.2, -0.2];
const intercepts = [0.25, 0, 0.5];
ctx.filter = new CanvasFilter({componentTransfer: {
ctx.filter = new CanvasFilter({filter: "componentTransfer",
funcR: {type: "linear", slope: slopes[0], intercept: intercepts[0]},
funcG: {type: "linear", slope: slopes[1], intercept: intercepts[1]},
funcB: {type: "linear", slope: slopes[2], intercept: intercepts[2]},
}});
});

const inputColors = [
[255, 255, 255],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ <h1>2d.filter.canvasFilterObject.componentTransfer.table</h1>
tableValuesR = [0, 0, 1, 1];
tableValuesG = [2, 0, 0.5, 3];
tableValuesB = [1, -1, 5, 0];
ctx.filter = new CanvasFilter({componentTransfer: {
ctx.filter = new CanvasFilter({filter: "componentTransfer",
funcR: {type: "table", tableValues: tableValuesR},
funcG: {type: "table", tableValues: tableValuesG},
funcB: {type: "table", tableValues: tableValuesB},
}});
});

const inputColors = [
[255, 255, 255],
Expand All @@ -60,6 +60,7 @@ <h1>2d.filter.canvasFilterObject.componentTransfer.table</h1>
ctx.fillRect(0, 0, 10, 10);
_assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, "5,5", `${outputColor[0]},${outputColor[1]},${outputColor[2]}`, 2);
}
t.done()


});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,17 @@ <h1>2d.filter.canvasFilterObject.convolveMatrix.exceptions</h1>
var t = async_test("Test exceptions on CanvasFilter() convolveMatrix");
_addTest(function(canvas, ctx) {

assert_throws_js(TypeError, function() { new CanvasFilter({convolveMatrix: {}}); });
assert_throws_js(TypeError, function() { new CanvasFilter({convolveMatrix: null}); });
assert_throws_js(TypeError, function() { new CanvasFilter({convolveMatrix: {divisor: 2}}); });
assert_throws_js(TypeError, function() { new CanvasFilter({convolveMatrix: {kernelMatrix: null}}); });
assert_throws_js(TypeError, function() { new CanvasFilter({convolveMatrix: {kernelMatrix: 1}}); });
assert_throws_js(TypeError, function() { new CanvasFilter({convolveMatrix: {kernelMatrix: [[1, 0], [0]]}}); });
assert_throws_js(TypeError, function() { new CanvasFilter({convolveMatrix: {kernelMatrix: [[1, "a"], [0]]}}); });
assert_throws_js(TypeError, function() { new CanvasFilter({convolveMatrix: {kernelMatrix: [[1, 0], 0]}}); });
assert_throws_js(TypeError, function() { new CanvasFilter({convolveMatrix: {kernelMatrix: [[1, 0], [0, Infinity]]}}); });
assert_throws_js(TypeError, function() { new CanvasFilter({convolveMatrix: {kernelMatrix: []}}); });
assert_throws_js(TypeError, function() { new CanvasFilter({filter: "convolveMatrix"}); });
assert_throws_js(TypeError, function() { new CanvasFilter({filter: "convolveMatrix", divisor: 2}); });
assert_throws_js(TypeError, function() { new CanvasFilter({filter: "convolveMatrix", kernelMatrix: null}); });
assert_throws_js(TypeError, function() { new CanvasFilter({filter: "convolveMatrix", kernelMatrix: 1}); });
assert_throws_js(TypeError, function() { new CanvasFilter({filter: "convolveMatrix", kernelMatrix: [[1, 0], [0]]}); });
assert_throws_js(TypeError, function() { new CanvasFilter({filter: "convolveMatrix", kernelMatrix: [[1, "a"], [0]]}); });
assert_throws_js(TypeError, function() { new CanvasFilter({filter: "convolveMatrix", kernelMatrix: [[1, 0], 0]}); });
assert_throws_js(TypeError, function() { new CanvasFilter({filter: "convolveMatrix", kernelMatrix: [[1, 0], [0, Infinity]]}); });
assert_throws_js(TypeError, function() { new CanvasFilter({filter: "convolveMatrix", kernelMatrix: []}); });
// This should not throw an error
ctx.filter = new CanvasFilter({convolveMatrix: {kernelMatrix: [[]]}});
ctx.filter = new CanvasFilter({filter: "convolveMatrix", kernelMatrix: [[]]});


});
Expand Down
Loading

0 comments on commit 1ece459

Please sign in to comment.