blob: 5ca14f831a03c651cde236b413946221bc36e6d6 [file] [log] [blame]
// 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.
import 'dart:typed_data';
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 'common.dart';
void main() {
internalBootstrapBrowserTest(() => testMain);
}
void testMain() {
List<CkColorFilter> createColorFilters() {
return <CkColorFilter>[
createCkColorFilter(const EngineColorFilter.mode(ui.Color(0x12345678), ui.BlendMode.srcOver))!,
createCkColorFilter(const EngineColorFilter.mode(ui.Color(0x12345678), ui.BlendMode.dstOver))!,
createCkColorFilter(const EngineColorFilter.mode(ui.Color(0x87654321), ui.BlendMode.dstOver))!,
createCkColorFilter(const EngineColorFilter.matrix(<double>[
1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 1, 0, 0,
0, 0, 0, 1, 0,
]))!,
createCkColorFilter(EngineColorFilter.matrix(Float32List.fromList(<double>[
2, 0, 0, 0, 0,
0, 2, 0, 0, 0,
0, 0, 2, 0, 0,
0, 0, 0, 2, 0,
])))!,
createCkColorFilter(const EngineColorFilter.linearToSrgbGamma())!,
createCkColorFilter(const EngineColorFilter.srgbToLinearGamma())!,
];
}
List<CkImageFilter> createImageFilters() {
return <CkImageFilter>[
CkImageFilter.blur(sigmaX: 5, sigmaY: 6, tileMode: ui.TileMode.clamp),
CkImageFilter.blur(sigmaX: 6, sigmaY: 5, tileMode: ui.TileMode.clamp),
CkImageFilter.blur(sigmaX: 6, sigmaY: 5, tileMode: ui.TileMode.decal),
for (final CkColorFilter colorFilter in createColorFilters()) CkImageFilter.color(colorFilter: colorFilter),
];
}
setUpCanvasKitTest();
group('ImageFilters', () {
test('can be constructed', () {
final CkImageFilter imageFilter = CkImageFilter.blur(sigmaX: 5, sigmaY: 10, tileMode: ui.TileMode.clamp);
expect(imageFilter, isA<CkImageFilter>());
SkImageFilter? skFilter;
imageFilter.imageFilter((SkImageFilter value) {
skFilter = value;
});
expect(skFilter, isNotNull);
});
test('== operator', () {
final List<ui.ImageFilter> filters1 = <ui.ImageFilter>[
...createImageFilters(),
...createColorFilters(),
];
final List<ui.ImageFilter> filters2 = <ui.ImageFilter>[
...createImageFilters(),
...createColorFilters(),
];
for (int index1 = 0; index1 < filters1.length; index1 += 1) {
final ui.ImageFilter imageFilter1 = filters1[index1];
expect(imageFilter1 == imageFilter1, isTrue);
for (int index2 = 0; index2 < filters2.length; index2 += 1) {
final ui.ImageFilter imageFilter2 = filters2[index2];
expect(imageFilter1 == imageFilter2, imageFilter2 == imageFilter1);
expect(imageFilter1 == imageFilter2, index1 == index2);
}
}
});
test('reuses the Skia filter', () {
final CkPaint paint = CkPaint();
paint.imageFilter = CkImageFilter.blur(sigmaX: 5, sigmaY: 10, tileMode: ui.TileMode.clamp);
final CkManagedSkImageFilterConvertible managedFilter1 = paint.imageFilter! as CkManagedSkImageFilterConvertible;
paint.imageFilter = CkImageFilter.blur(sigmaX: 5, sigmaY: 10, tileMode: ui.TileMode.clamp);
final CkManagedSkImageFilterConvertible managedFilter2 = paint.imageFilter! as CkManagedSkImageFilterConvertible;
expect(managedFilter1, same(managedFilter2));
});
test('does not throw for both sigmaX and sigmaY set to 0', () async {
final CkImageFilter imageFilter = CkImageFilter.blur(sigmaX: 0, sigmaY: 0, tileMode: ui.TileMode.clamp);
expect(imageFilter, isNotNull);
const ui.Rect region = ui.Rect.fromLTRB(0, 0, 500, 250);
final LayerSceneBuilder builder = LayerSceneBuilder();
builder.pushOffset(0,0);
final CkPictureRecorder recorder = CkPictureRecorder();
final CkCanvas canvas = recorder.beginRecording(region);
canvas.drawCircle(
const ui.Offset(75, 125),
50,
CkPaint()..color = const ui.Color.fromARGB(255, 255, 0, 0),
);
final CkPicture redCircle1 = recorder.endRecording();
builder.addPicture(ui.Offset.zero, redCircle1);
builder.pushImageFilter(imageFilter);
// Draw another red circle and apply it to the scene.
// This one should also be red with the image filter doing nothing
final CkPictureRecorder recorder2 = CkPictureRecorder();
final CkCanvas canvas2 = recorder2.beginRecording(region);
canvas2.drawCircle(
const ui.Offset(425, 125),
50,
CkPaint()..color = const ui.Color.fromARGB(255, 255, 0, 0),
);
final CkPicture redCircle2 = recorder2.endRecording();
builder.addPicture(ui.Offset.zero, redCircle2);
await matchSceneGolden('canvaskit_zero_sigma_blur.png', builder.build(), region: region);
});
test('using a colorFilter', () async {
final CkColorFilter colorFilter = createCkColorFilter(
const EngineColorFilter.mode(
ui.Color.fromARGB(255, 0, 255, 0),
ui.BlendMode.srcIn
))!;
const ui.Rect region = ui.Rect.fromLTRB(0, 0, 500, 250);
final LayerSceneBuilder builder = LayerSceneBuilder();
builder.pushOffset(0,0);
builder.pushImageFilter(colorFilter);
final CkPictureRecorder recorder = CkPictureRecorder();
final CkCanvas canvas = recorder.beginRecording(region);
canvas.drawCircle(
const ui.Offset(75, 125),
50,
CkPaint()..color = const ui.Color.fromARGB(255, 255, 0, 0),
);
final CkPicture redCircle1 = recorder.endRecording();
builder.addPicture(ui.Offset.zero, redCircle1);
// The drawn red circle should actually be green with the colorFilter.
await matchSceneGolden('canvaskit_imageFilter_using_colorFilter.png', builder.build(), region: region);
});
});
group('MaskFilter', () {
test('with 0 sigma can be set on a Paint', () {
final ui.Paint paint = ui.Paint();
const ui.MaskFilter filter = ui.MaskFilter.blur(ui.BlurStyle.normal, 0);
expect(() => paint.maskFilter = filter, isNot(throwsException));
});
});
}