Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/web_ui/lib/src/engine/canvaskit/color_filter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'dart:typed_data';

import 'package:ui/src/engine/vector_math.dart';
import 'package:ui/ui.dart' as ui;

import '../color_filter.dart';
Expand Down Expand Up @@ -79,6 +80,9 @@ abstract class CkColorFilter implements CkManagedSkImageFilterConvertible {
borrow(skImageFilter);
skImageFilter.delete();
}

@override
Matrix4 get transform => Matrix4.identity();
}

/// A reusable identity transform matrix.
Expand Down
10 changes: 10 additions & 0 deletions lib/web_ui/lib/src/engine/canvaskit/image_filter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ typedef SkImageFilterBorrow = void Function(SkImageFilter);
/// Currently implemented by [CkImageFilter] and [CkColorFilter].
abstract class CkManagedSkImageFilterConvertible implements ui.ImageFilter {
void imageFilter(SkImageFilterBorrow borrow);

Matrix4 get transform;
}

/// The CanvasKit implementation of [ui.ImageFilter].
Expand All @@ -40,6 +42,9 @@ abstract class CkImageFilter implements CkManagedSkImageFilterConvertible {
required ui.FilterQuality filterQuality}) = _CkMatrixImageFilter;

CkImageFilter._();

@override
Matrix4 get transform => Matrix4.identity();
}

class CkColorFilterImageFilter extends CkImageFilter {
Expand Down Expand Up @@ -149,6 +154,7 @@ class _CkMatrixImageFilter extends CkImageFilter {
_CkMatrixImageFilter(
{required Float64List matrix, required this.filterQuality})
: matrix = Float64List.fromList(matrix),
_transform = Matrix4.fromFloat32List(toMatrix32(matrix)),
super._() {
final SkImageFilter skImageFilter = canvasKit.ImageFilter.MakeMatrixTransform(
toSkMatrixFromFloat64(matrix),
Expand All @@ -160,6 +166,7 @@ class _CkMatrixImageFilter extends CkImageFilter {

final Float64List matrix;
final ui.FilterQuality filterQuality;
final Matrix4 _transform;

late final UniqueRef<SkImageFilter> _ref;

Expand All @@ -183,4 +190,7 @@ class _CkMatrixImageFilter extends CkImageFilter {

@override
String toString() => 'ImageFilter.matrix($matrix, $filterQuality)';

@override
Matrix4 get transform => _transform;
}
12 changes: 12 additions & 0 deletions lib/web_ui/lib/src/engine/canvaskit/layer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:ui/ui.dart' as ui;
import '../vector_math.dart';
import 'canvas.dart';
import 'embedded_views.dart';
import 'image_filter.dart';
import 'n_way_canvas.dart';
import 'painting.dart';
import 'path.dart';
Expand Down Expand Up @@ -396,6 +397,17 @@ class ImageFilterEngineLayer extends ContainerLayer
final ui.Offset _offset;
final ui.ImageFilter _filter;

@override
void preroll(PrerollContext prerollContext, Matrix4 matrix) {
final Matrix4 transform = (_filter as CkManagedSkImageFilterConvertible).transform;
final Matrix4 childMatrix = matrix.multiplied(transform);
prerollContext.mutatorsStack.pushTransform(transform);
final ui.Rect childPaintBounds =
prerollChildren(prerollContext, childMatrix);
paintBounds = transform.transformRect(childPaintBounds);
prerollContext.mutatorsStack.pop();
}

@override
void paint(PaintContext paintContext) {
assert(needsPainting);
Expand Down
26 changes: 26 additions & 0 deletions lib/web_ui/test/canvaskit/layer_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,31 @@ void testMain() {
region: kDefaultRegion,
);
});

test('ImageFilter layer applies matrix in preroll', () async {
final CkPicture picture =
paintPicture(const ui.Rect.fromLTRB(0, 0, 100, 100), (CkCanvas canvas) {
canvas.drawRect(const ui.Rect.fromLTRB(0, 0, 100, 100),
CkPaint()..style = ui.PaintingStyle.fill);
});

final LayerSceneBuilder sb = LayerSceneBuilder();
sb.pushImageFilter(
ui.ImageFilter.matrix(
(
Matrix4.identity()
..scale(0.5, 0.5)
..translate(20)
).toFloat64(),
),
);
sb.addPicture(ui.Offset.zero, picture);

final LayerTree layerTree = sb.build().layerTree;
CanvasKitRenderer.instance.rasterizer.draw(layerTree);

final ImageFilterEngineLayer imageFilterLayer = layerTree.rootLayer.debugLayers.single as ImageFilterEngineLayer;
expect(imageFilterLayer.paintBounds, const ui.Rect.fromLTRB(10, 0, 60, 50));
});
});
}