Normalize the translation column of the color matrix. (#161109)
`dart:ui` specifies that the translation column of the color matrix should be in the range 0..255. Skia expects a normalized range between 0 and 1. Skwasm was not normalizing this before passing it to Skia, but CanvasKit was. After writing a unit test, it appears that the HTML renderer has the same problem, so I also fixed that as well. This addresses https://github.com/flutter/flutter/issues/159697
This commit is contained in:
parent
132e298335
commit
1e9202e1ee
@ -312,7 +312,18 @@ class SvgFilter {
|
|||||||
|
|
||||||
SvgFilter svgFilterFromColorMatrix(List<double> matrix) {
|
SvgFilter svgFilterFromColorMatrix(List<double> matrix) {
|
||||||
final SvgFilterBuilder builder = SvgFilterBuilder();
|
final SvgFilterBuilder builder = SvgFilterBuilder();
|
||||||
builder.setFeColorMatrix(matrix, result: 'comp');
|
|
||||||
|
/// Flutter documentation says the translation column of the color matrix
|
||||||
|
/// is specified in unnormalized 0..255 space. `feColorMatrix` expects the
|
||||||
|
/// translation values to be normalized to 0..1 space.
|
||||||
|
///
|
||||||
|
/// See [https://api.flutter.dev/flutter/dart-ui/ColorFilter/ColorFilter.matrix.html]
|
||||||
|
final normalizedMatrix = List<double>.generate(
|
||||||
|
matrix.length,
|
||||||
|
(int i) => (i % 5 == 4) ? matrix[i] / 255.0 : matrix[i],
|
||||||
|
growable: false,
|
||||||
|
);
|
||||||
|
builder.setFeColorMatrix(normalizedMatrix, result: 'comp');
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:ffi';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:ui/src/engine.dart';
|
import 'package:ui/src/engine.dart';
|
||||||
@ -318,7 +319,18 @@ class SkwasmMatrixColorFilter extends SkwasmColorFilter {
|
|||||||
@override
|
@override
|
||||||
void withRawColorFilter(ColorFilterHandleBorrow borrow) {
|
void withRawColorFilter(ColorFilterHandleBorrow borrow) {
|
||||||
withStackScope((scope) {
|
withStackScope((scope) {
|
||||||
final rawColorFilter = colorFilterCreateMatrix(scope.convertDoublesToNative(matrix));
|
assert(matrix.length == 20);
|
||||||
|
final Pointer<Float> rawMatrix = scope.convertDoublesToNative(matrix);
|
||||||
|
|
||||||
|
/// Flutter documentation says the translation column of the color matrix
|
||||||
|
/// is specified in unnormalized 0..255 space. Skia expects the
|
||||||
|
/// translation values to be normalized to 0..1 space.
|
||||||
|
///
|
||||||
|
/// See [https://api.flutter.dev/flutter/dart-ui/ColorFilter/ColorFilter.matrix.html].
|
||||||
|
for (final i in <int>[4, 9, 14, 19]) {
|
||||||
|
rawMatrix[i] /= 255.0;
|
||||||
|
}
|
||||||
|
final rawColorFilter = colorFilterCreateMatrix(rawMatrix);
|
||||||
borrow(rawColorFilter);
|
borrow(rawColorFilter);
|
||||||
colorFilterDispose(rawColorFilter);
|
colorFilterDispose(rawColorFilter);
|
||||||
});
|
});
|
||||||
|
@ -146,32 +146,28 @@ Future<void> testMain() async {
|
|||||||
|
|
||||||
test('matrix color filter', () async {
|
test('matrix color filter', () async {
|
||||||
const ui.ColorFilter sepia = ui.ColorFilter.matrix(<double>[
|
const ui.ColorFilter sepia = ui.ColorFilter.matrix(<double>[
|
||||||
0.393,
|
0.393, 0.769, 0.189, 0, 0, // row
|
||||||
0.769,
|
0.349, 0.686, 0.168, 0, 0, // row
|
||||||
0.189,
|
0.272, 0.534, 0.131, 0, 0, // row
|
||||||
0,
|
0, 0, 0, 1, 0, // row
|
||||||
0,
|
|
||||||
0.349,
|
|
||||||
0.686,
|
|
||||||
0.168,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0.272,
|
|
||||||
0.534,
|
|
||||||
0.131,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
]);
|
]);
|
||||||
await drawTestImageWithPaint(ui.Paint()..colorFilter = sepia);
|
await drawTestImageWithPaint(ui.Paint()..colorFilter = sepia);
|
||||||
await matchGoldenFile('ui_filter_matrix_colorfilter.png', region: region);
|
await matchGoldenFile('ui_filter_matrix_colorfilter.png', region: region);
|
||||||
expect(sepia.toString(), startsWith('ColorFilter.matrix([0.393, 0.769, 0.189, '));
|
expect(sepia.toString(), startsWith('ColorFilter.matrix([0.393, 0.769, 0.189, '));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('matrix color filter with 0..255 translation values', () async {
|
||||||
|
const ui.ColorFilter sepia = ui.ColorFilter.matrix(<double>[
|
||||||
|
0.393, 0.769, 0.189, 0, 50.0, // row
|
||||||
|
0.349, 0.686, 0.168, 0, 50.0, // row
|
||||||
|
0.272, 0.534, 0.131, 0, 50.0, // row
|
||||||
|
0, 0, 0, 1, 0, // row
|
||||||
|
]);
|
||||||
|
await drawTestImageWithPaint(ui.Paint()..colorFilter = sepia);
|
||||||
|
await matchGoldenFile('ui_filter_matrix_colorfilter_with_translation.png', region: region);
|
||||||
|
expect(sepia.toString(), startsWith('ColorFilter.matrix([0.393, 0.769, 0.189, '));
|
||||||
|
});
|
||||||
|
|
||||||
test('invert colors', () async {
|
test('invert colors', () async {
|
||||||
await drawTestImageWithPaint(ui.Paint()..invertColors = true);
|
await drawTestImageWithPaint(ui.Paint()..invertColors = true);
|
||||||
await matchGoldenFile('ui_filter_invert_colors.png', region: region);
|
await matchGoldenFile('ui_filter_invert_colors.png', region: region);
|
||||||
@ -179,26 +175,10 @@ Future<void> testMain() async {
|
|||||||
|
|
||||||
test('invert colors with color filter', () async {
|
test('invert colors with color filter', () async {
|
||||||
const ui.ColorFilter sepia = ui.ColorFilter.matrix(<double>[
|
const ui.ColorFilter sepia = ui.ColorFilter.matrix(<double>[
|
||||||
0.393,
|
0.393, 0.769, 0.189, 0, 0, // row
|
||||||
0.769,
|
0.349, 0.686, 0.168, 0, 0, // row
|
||||||
0.189,
|
0.272, 0.534, 0.131, 0, 0, // row
|
||||||
0,
|
0, 0, 0, 1, 0, // row
|
||||||
0,
|
|
||||||
0.349,
|
|
||||||
0.686,
|
|
||||||
0.168,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0.272,
|
|
||||||
0.534,
|
|
||||||
0.131,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await drawTestImageWithPaint(
|
await drawTestImageWithPaint(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user