Skip to content

Commit

Permalink
[web] Fix linear gradient transformation matrix (flutter#25545)
Browse files Browse the repository at this point in the history
  • Loading branch information
ferhatb authored Apr 13, 2021
1 parent a798a2b commit 0d94874
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 7 deletions.
2 changes: 1 addition & 1 deletion lib/web_ui/dev/goldens_lock.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
repository: https://github.com/flutter/goldens.git
revision: f868ee6b6faef13469498e9b160b45fed9fdc567
revision: 6d0f8e73356fe57e7a87eaae9f7257435fda3489
1 change: 1 addition & 0 deletions lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,7 @@ class SkShaderNamespace {
Uint32List colors,
Float32List colorStops,
SkTileMode tileMode,
Float32List? matrix,
);

external SkShader MakeRadialGradient(
Expand Down
6 changes: 4 additions & 2 deletions lib/web_ui/lib/src/engine/canvaskit/shader.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,14 @@ class CkGradientLinear extends CkShader implements ui.Gradient {
this.colors,
this.colorStops,
this.tileMode,
Float64List? matrix,
Float32List? matrix,
) : assert(_offsetIsValid(from)),
assert(_offsetIsValid(to)),
assert(colors != null), // ignore: unnecessary_null_comparison
assert(tileMode != null), // ignore: unnecessary_null_comparison
this.matrix4 = matrix {
if (assertionsEnabled) {
assert(matrix4 == null || _matrix4IsValid(matrix4!));
_validateColorStops(colors, colorStops);
}
}
Expand All @@ -81,7 +82,7 @@ class CkGradientLinear extends CkShader implements ui.Gradient {
final List<ui.Color> colors;
final List<double>? colorStops;
final ui.TileMode tileMode;
final Float64List? matrix4;
final Float32List? matrix4;

@override
SkShader createDefault() {
Expand All @@ -93,6 +94,7 @@ class CkGradientLinear extends CkShader implements ui.Gradient {
toFlatColors(colors),
toSkColorStops(colorStops),
toSkTileMode(tileMode),
matrix4 != null ? toSkMatrixFromFloat32(matrix4!) : null,
);
}

Expand Down
12 changes: 8 additions & 4 deletions lib/web_ui/lib/src/ui/painting.dart
Original file line number Diff line number Diff line change
Expand Up @@ -278,10 +278,14 @@ abstract class Gradient extends Shader {
List<double>? colorStops,
TileMode tileMode = TileMode.clamp,
Float64List? matrix4,
]) => engine.useCanvasKit
? engine.CkGradientLinear(from, to, colors, colorStops, tileMode, matrix4)
: engine.GradientLinear(from, to, colors, colorStops, tileMode,
matrix4 == null ? null : engine.toMatrix32(matrix4));
]) {
Float32List? matrix = matrix4 == null ? null : engine.toMatrix32(matrix4);
return engine.useCanvasKit
? engine.CkGradientLinear(
from, to, colors, colorStops, tileMode, matrix)
: engine.GradientLinear(from, to, colors, colorStops, tileMode, matrix);
}

factory Gradient.radial(
Offset center,
double radius,
Expand Down
1 change: 1 addition & 0 deletions lib/web_ui/test/canvaskit/canvaskit_api_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ SkShader _makeTestShader() {
Uint32List.fromList(<int>[0xff0000ff]),
Float32List.fromList([0, 1]),
canvasKit.TileMode.Repeat,
null,
);
}

Expand Down
108 changes: 108 additions & 0 deletions lib/web_ui/test/canvaskit/linear_gradient_golden_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// 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 'dart:math' as math;

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> matchPictureGolden(String goldenFile, CkPicture picture,
{bool write = false}) async {
final EnginePlatformDispatcher dispatcher =
ui.window.platformDispatcher as EnginePlatformDispatcher;
final LayerSceneBuilder sb = LayerSceneBuilder();
sb.pushOffset(0, 0);
sb.addPicture(ui.Offset.zero, picture);
dispatcher.rasterizer!.draw(sb.build().layerTree);
await matchGoldenFile(goldenFile, region: region, write: write);
}

void testMain() {
group('Linear', () {
setUpCanvasKitTest();

test('is correctly rendered', () async {
final CkPictureRecorder recorder = CkPictureRecorder();
final CkCanvas canvas = recorder.beginRecording(region);

final CkGradientLinear gradient = CkGradientLinear(
ui.Offset(region.left + region.width / 4, region.height / 2),
ui.Offset(region.right - region.width / 8, region.height / 2),
<ui.Color>[
ui.Color(0xFF4285F4),
ui.Color(0xFF34A853),
ui.Color(0xFFFBBC05),
ui.Color(0xFFEA4335),
ui.Color(0xFF4285F4),
],
<double>[
0.0,
0.25,
0.5,
0.75,
1.0,
],
ui.TileMode.clamp,
null);

final CkPaint paint = CkPaint()..shader = gradient;

canvas.drawRect(region, paint);

await matchPictureGolden(
'canvaskit_linear_gradient.png',
recorder.endRecording(),
);
});

test('is correctly rendered when rotated', () async {
final CkPictureRecorder recorder = CkPictureRecorder();
final CkCanvas canvas = recorder.beginRecording(region);

final CkGradientLinear gradient = CkGradientLinear(
ui.Offset(region.left + region.width / 4, region.height / 2),
ui.Offset(region.right - region.width / 8, region.height / 2),
<ui.Color>[
ui.Color(0xFF4285F4),
ui.Color(0xFF34A853),
ui.Color(0xFFFBBC05),
ui.Color(0xFFEA4335),
ui.Color(0xFF4285F4),
],
<double>[
0.0,
0.25,
0.5,
0.75,
1.0,
],
ui.TileMode.clamp,
Matrix4.rotationZ(math.pi / 6.0).storage);

final CkPaint paint = CkPaint()..shader = gradient;

canvas.drawRect(region, paint);

await matchPictureGolden(
'canvaskit_linear_gradient_rotated.png',
recorder.endRecording(),
);
});
// TODO: https://github.com/flutter/flutter/issues/60040
// TODO: https://github.com/flutter/flutter/issues/71520
}, skip: isIosSafari || isFirefox);
}

0 comments on commit 0d94874

Please sign in to comment.