[canvaskit] Add MatrixTransform ImageFilter

Change-Id: Ifcb73c331846abb3ffa9ac2f41236de8da4fdccc
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/254804
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
diff --git a/modules/canvaskit/CHANGELOG.md b/modules/canvaskit/CHANGELOG.md
index 5945c75..886ae31 100644
--- a/modules/canvaskit/CHANGELOG.md
+++ b/modules/canvaskit/CHANGELOG.md
@@ -10,7 +10,7 @@
    TypedArray backed by the C++ WASM memory. This can save a copy in some cases
    (e.g. SkColorFilter.MakeMatrix). This is an advanced feature, so use it with care.
  - `SkCanvas.clipRRect`, `SkCanvas.drawColor`
- - Blur, ColorFilter, Compose SkImageFilters. Can be used with `SkPaint.setImageFilter`.
+ - Blur, ColorFilter, Compose, MatrixTransform SkImageFilters. Can be used with `SkPaint.setImageFilter`.
  - `SkCanvas.saveLayer` now takes 3 or 4 params to include up to bounds, paint, SkImageFilter, flags.
  - `SkPath.rArcTo`, `SkPath.rConicTo`, `SkPath.rCubicTo`, `SkPath.rLineTo`, `SkPath.rMoveTo`,
    `SkPath.rQuadTo`. Like their non-relative siblings, these are chainable.
diff --git a/modules/canvaskit/canvaskit_bindings.cpp b/modules/canvaskit/canvaskit_bindings.cpp
index 632e5cf..962538a 100644
--- a/modules/canvaskit/canvaskit_bindings.cpp
+++ b/modules/canvaskit/canvaskit_bindings.cpp
@@ -1133,7 +1133,11 @@
             // Emscripten does not like default args nor SkIRect* much
             return SkImageFilters::ColorFilter(cf, input);
         }))
-        .class_function("MakeCompose", &SkImageFilters::Compose);
+        .class_function("MakeCompose", &SkImageFilters::Compose)
+        .class_function("MakeMatrixTransform", optional_override([](SimpleMatrix sm, SkFilterQuality fq,
+                                                                   sk_sp<SkImageFilter> input)->sk_sp<SkImageFilter> {
+            return SkImageFilters::MatrixTransform(toSkMatrix(sm), fq, input);
+        }));
 
     class_<SkMaskFilter>("SkMaskFilter")
         .smart_ptr<sk_sp<SkMaskFilter>>("sk_sp<SkMaskFilter>")
diff --git a/modules/canvaskit/externs.js b/modules/canvaskit/externs.js
index c0ee254..59b01ef 100644
--- a/modules/canvaskit/externs.js
+++ b/modules/canvaskit/externs.js
@@ -238,6 +238,7 @@
 		MakeBlur: function() {},
 		MakeColorFilter: function() {},
 		MakeCompose: function() {},
+		MakeMatrixTransform: function() {},
 	},
 
 	SkMatrix: {
diff --git a/modules/canvaskit/tests/core.spec.js b/modules/canvaskit/tests/core.spec.js
index abe82a8..5906ad2 100644
--- a/modules/canvaskit/tests/core.spec.js
+++ b/modules/canvaskit/tests/core.spec.js
@@ -257,9 +257,12 @@
                 const blurIF = CanvasKit.SkImageFilter.MakeBlur(8, 0.2, CanvasKit.TileMode.Decal, null);
                 const combined = CanvasKit.SkImageFilter.MakeCompose(redIF, blurIF);
 
-                paint.setImageFilter(combined);
+                // rotate 10 degrees centered on 200, 200
+                const m = CanvasKit.SkMatrix.rotated(Math.PI/18, 200, 200);
+                const rotated = CanvasKit.SkImageFilter.MakeMatrixTransform(m, CanvasKit.FilterQuality.Medium, combined);
+                paint.setImageFilter(rotated);
 
-                canvas.rotate(10, 200, 200);
+                //canvas.rotate(10, 200, 200);
                 canvas.drawImage(img, 0, 0, paint);
                 canvas.drawRect(CanvasKit.LTRBRect(5, 35, 45, 80), paint);
 
@@ -270,6 +273,7 @@
                 redCF.delete();
                 blurIF.delete();
                 combined.delete();
+                rotated.delete();
                 img.delete();
 
                 reportSurface(surface, 'combined_filters', done);