Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 7220afd

Browse files
committed
Apply the transform of an image filter layer to paint bounds in the CanvasKit backend
Fixes flutter/flutter#128788
1 parent 8d03c4f commit 7220afd

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed

lib/web_ui/lib/src/engine/canvaskit/image_filter.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ abstract class CkImageFilter implements CkManagedSkImageFilterConvertible {
4040
required ui.FilterQuality filterQuality}) = _CkMatrixImageFilter;
4141

4242
CkImageFilter._();
43+
44+
Matrix4 get transform => Matrix4.identity();
4345
}
4446

4547
class CkColorFilterImageFilter extends CkImageFilter {
@@ -149,6 +151,7 @@ class _CkMatrixImageFilter extends CkImageFilter {
149151
_CkMatrixImageFilter(
150152
{required Float64List matrix, required this.filterQuality})
151153
: matrix = Float64List.fromList(matrix),
154+
_transform = Matrix4.fromFloat32List(toMatrix32(matrix)),
152155
super._() {
153156
final SkImageFilter skImageFilter = canvasKit.ImageFilter.MakeMatrixTransform(
154157
toSkMatrixFromFloat64(matrix),
@@ -160,6 +163,7 @@ class _CkMatrixImageFilter extends CkImageFilter {
160163

161164
final Float64List matrix;
162165
final ui.FilterQuality filterQuality;
166+
final Matrix4 _transform;
163167

164168
late final UniqueRef<SkImageFilter> _ref;
165169

@@ -183,4 +187,7 @@ class _CkMatrixImageFilter extends CkImageFilter {
183187

184188
@override
185189
String toString() => 'ImageFilter.matrix($matrix, $filterQuality)';
190+
191+
@override
192+
Matrix4 get transform => _transform;
186193
}

lib/web_ui/lib/src/engine/canvaskit/layer.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'package:ui/ui.dart' as ui;
77
import '../vector_math.dart';
88
import 'canvas.dart';
99
import 'embedded_views.dart';
10+
import 'image_filter.dart';
1011
import 'n_way_canvas.dart';
1112
import 'painting.dart';
1213
import 'path.dart';
@@ -396,6 +397,17 @@ class ImageFilterEngineLayer extends ContainerLayer
396397
final ui.Offset _offset;
397398
final ui.ImageFilter _filter;
398399

400+
@override
401+
void preroll(PrerollContext prerollContext, Matrix4 matrix) {
402+
final Matrix4 transform = (_filter as CkImageFilter).transform;
403+
final Matrix4 childMatrix = matrix.multiplied(transform);
404+
prerollContext.mutatorsStack.pushTransform(transform);
405+
final ui.Rect childPaintBounds =
406+
prerollChildren(prerollContext, childMatrix);
407+
paintBounds = transform.transformRect(childPaintBounds);
408+
prerollContext.mutatorsStack.pop();
409+
}
410+
399411
@override
400412
void paint(PaintContext paintContext) {
401413
assert(needsPainting);

lib/web_ui/test/canvaskit/layer_test.dart

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,5 +72,31 @@ void testMain() {
7272
region: kDefaultRegion,
7373
);
7474
});
75+
76+
test('ImageFilter layer applies matrix in preroll', () async {
77+
final CkPicture picture =
78+
paintPicture(const ui.Rect.fromLTRB(0, 0, 100, 100), (CkCanvas canvas) {
79+
canvas.drawRect(const ui.Rect.fromLTRB(0, 0, 100, 100),
80+
CkPaint()..style = ui.PaintingStyle.fill);
81+
});
82+
83+
final LayerSceneBuilder sb = LayerSceneBuilder();
84+
sb.pushImageFilter(
85+
ui.ImageFilter.matrix(
86+
(
87+
Matrix4.identity()
88+
..scale(0.5, 0.5)
89+
..translate(20)
90+
).toFloat64(),
91+
),
92+
);
93+
sb.addPicture(ui.Offset.zero, picture);
94+
95+
final LayerTree layerTree = sb.build().layerTree;
96+
CanvasKitRenderer.instance.rasterizer.draw(layerTree);
97+
98+
final ImageFilterEngineLayer imageFilterLayer = layerTree.rootLayer.debugLayers.single as ImageFilterEngineLayer;
99+
expect(imageFilterLayer.paintBounds, const ui.Rect.fromLTRB(10, 0, 60, 50));
100+
});
75101
});
76102
}

0 commit comments

Comments
 (0)