mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Implement pushColorFilter in CanvasKit (flutter/engine#22838)
* Implement pushColorFilter in CanvasKit * Add test * Update goldens lock
This commit is contained in:
parent
d5b0abfac2
commit
eac028036e
@ -1,2 +1,2 @@
|
||||
repository: https://github.com/flutter/goldens.git
|
||||
revision: ac75f12c6e93461369e1391da6cc20bf8cb08829
|
||||
revision: c808c28c81b6c3143ae969e8c49bed4a6d49aabb
|
||||
|
||||
@ -449,8 +449,8 @@ class PhysicalShapeLayer extends ContainerLayer
|
||||
assert(needsPainting);
|
||||
|
||||
if (_elevation != 0) {
|
||||
drawShadow(paintContext.leafNodesCanvas!, _path, _shadowColor!, _elevation,
|
||||
_color.alpha != 0xff);
|
||||
drawShadow(paintContext.leafNodesCanvas!, _path, _shadowColor!,
|
||||
_elevation, _color.alpha != 0xff);
|
||||
}
|
||||
|
||||
final CkPaint paint = CkPaint()..color = _color;
|
||||
@ -497,6 +497,25 @@ class PhysicalShapeLayer extends ContainerLayer
|
||||
}
|
||||
}
|
||||
|
||||
/// A layer which contains a [ui.ColorFilter].
|
||||
class ColorFilterLayer extends ContainerLayer {
|
||||
ColorFilterLayer(this.filter);
|
||||
|
||||
final ui.ColorFilter filter;
|
||||
|
||||
@override
|
||||
void paint(PaintContext paintContext) {
|
||||
assert(needsPainting);
|
||||
|
||||
CkPaint paint = CkPaint();
|
||||
paint.colorFilter = filter;
|
||||
|
||||
paintContext.internalNodesCanvas.saveLayer(paintBounds, paint);
|
||||
paintChildren(paintContext);
|
||||
paintContext.internalNodesCanvas.restore();
|
||||
}
|
||||
}
|
||||
|
||||
/// A layer which renders a platform view (an HTML element in this case).
|
||||
class PlatformViewLayer extends Layer {
|
||||
PlatformViewLayer(this.viewId, this.offset, this.width, this.height);
|
||||
|
||||
@ -138,12 +138,13 @@ class LayerSceneBuilder implements ui.SceneBuilder {
|
||||
}
|
||||
|
||||
@override
|
||||
ui.ColorFilterEngineLayer pushColorFilter(
|
||||
ui.ColorFilterEngineLayer? pushColorFilter(
|
||||
ui.ColorFilter filter, {
|
||||
ui.ColorFilterEngineLayer? oldLayer,
|
||||
}) {
|
||||
assert(filter != null); // ignore: unnecessary_null_comparison
|
||||
throw UnimplementedError();
|
||||
pushLayer(ColorFilterLayer(filter));
|
||||
return null;
|
||||
}
|
||||
|
||||
ui.ImageFilterEngineLayer? pushImageFilter(
|
||||
|
||||
@ -0,0 +1,78 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.12
|
||||
import 'package:test/bootstrap/browser.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:ui/src/engine.dart';
|
||||
import 'package:ui/ui.dart' as ui;
|
||||
|
||||
import 'package:web_engine_tester/golden_tester.dart';
|
||||
|
||||
import 'common.dart';
|
||||
|
||||
void main() {
|
||||
internalBootstrapBrowserTest(() => testMain);
|
||||
}
|
||||
|
||||
const ui.Rect region = const ui.Rect.fromLTRB(0, 0, 500, 250);
|
||||
|
||||
Future<void> matchSceneGolden(String goldenFile, LayerScene scene,
|
||||
{bool write = false}) async {
|
||||
final EnginePlatformDispatcher dispatcher =
|
||||
ui.window.platformDispatcher as EnginePlatformDispatcher;
|
||||
dispatcher.rasterizer!.draw(scene.layerTree);
|
||||
await matchGoldenFile(goldenFile, region: region, write: write);
|
||||
}
|
||||
|
||||
void testMain() {
|
||||
group('ColorFilter', () {
|
||||
setUpCanvasKitTest();
|
||||
|
||||
test('ColorFilter.matrix applies a color filter', () async {
|
||||
final LayerSceneBuilder builder = LayerSceneBuilder();
|
||||
|
||||
builder.pushOffset(0, 0);
|
||||
|
||||
// Draw a red circle and apply it to the scene.
|
||||
final CkPictureRecorder recorder = CkPictureRecorder();
|
||||
final CkCanvas canvas = recorder.beginRecording(region);
|
||||
|
||||
canvas.drawCircle(
|
||||
ui.Offset(75, 125),
|
||||
50,
|
||||
CkPaint()..color = ui.Color.fromARGB(255, 255, 0, 0),
|
||||
);
|
||||
final CkPicture redCircle = recorder.endRecording();
|
||||
|
||||
builder.addPicture(ui.Offset.zero, redCircle);
|
||||
|
||||
// Apply a "greyscale" color filter.
|
||||
builder.pushColorFilter(ui.ColorFilter.matrix([
|
||||
0.2126, 0.7152, 0.0722, 0, 0, //
|
||||
0.2126, 0.7152, 0.0722, 0, 0, //
|
||||
0.2126, 0.7152, 0.0722, 0, 0, //
|
||||
0, 0, 0, 1, 0, //
|
||||
]));
|
||||
|
||||
// Draw another red circle and apply it to the scene.
|
||||
// This one should be grey since we have the color filter.
|
||||
final CkPictureRecorder recorder2 = CkPictureRecorder();
|
||||
final CkCanvas canvas2 = recorder2.beginRecording(region);
|
||||
|
||||
canvas2.drawCircle(
|
||||
ui.Offset(425, 125),
|
||||
50,
|
||||
CkPaint()..color = ui.Color.fromARGB(255, 255, 0, 0),
|
||||
);
|
||||
final CkPicture greyCircle = recorder2.endRecording();
|
||||
|
||||
builder.addPicture(ui.Offset.zero, greyCircle);
|
||||
|
||||
await matchSceneGolden('canvaskit_colorfilter.png', builder.build());
|
||||
});
|
||||
// TODO: https://github.com/flutter/flutter/issues/60040
|
||||
// TODO: https://github.com/flutter/flutter/issues/71520
|
||||
}, skip: isIosSafari || isFirefox);
|
||||
}
|
||||
@ -49,6 +49,17 @@ void testMain() {
|
||||
final ui.Image sceneImage = await scene.toImage(100, 100);
|
||||
expect(sceneImage, isA<CkImage>());
|
||||
});
|
||||
// TODO: https://github.com/flutter/flutter/issues/60040
|
||||
|
||||
test('pushColorFilter does not throw', () async {
|
||||
final ui.SceneBuilder builder = ui.SceneBuilder();
|
||||
expect(builder, isA<LayerSceneBuilder>());
|
||||
|
||||
builder.pushOffset(0, 0);
|
||||
builder.pushColorFilter(ui.ColorFilter.srgbToLinearGamma());
|
||||
|
||||
final ui.Scene scene = builder.build();
|
||||
expect(scene, isNotNull);
|
||||
});
|
||||
// TODO: https://github.com/flutter/flutter/issues/60040
|
||||
}, skip: isIosSafari);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user