blob: de4c52cebb1d24835da1ab1d83817c3e24cbf2fe [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.
// @dart = 2.6
import 'dart:html' as html;
import 'package:ui/ui.dart';
import 'package:ui/src/engine.dart';
import 'package:test/test.dart';
import 'package:web_engine_tester/golden_tester.dart';
final Rect region = Rect.fromLTWH(0, 0, 500, 100);
void main() async {
setUp(() async {
debugShowClipLayers = true;
SurfaceSceneBuilder.debugForgetFrameScene();
for (html.Node scene in html.document.querySelectorAll('flt-scene')) {
scene.remove();
}
await webOnlyInitializePlatform();
webOnlyFontCollection.debugRegisterTestFonts();
await webOnlyFontCollection.ensureFontsLoaded();
});
test('draw growing picture across frames', () async {
final SurfaceSceneBuilder builder = SurfaceSceneBuilder();
builder.pushClipRect(
const Rect.fromLTRB(0, 0, 100, 100),
);
_drawTestPicture(builder, 100, false);
builder.pop();
html.Element elm1 = builder.build().webOnlyRootElement;
html.document.body.append(elm1);
// Now draw picture again but at larger size.
final SurfaceSceneBuilder builder2 = SurfaceSceneBuilder();
builder2.pushClipRect(
const Rect.fromLTRB(0, 0, 100, 100),
);
// Now draw the picture at original target size, which will use a
// different code path that should normally not have width/height set
// on image element.
_drawTestPicture(builder2, 20, false);
builder2.pop();
elm1.remove();
html.document.body.append(builder2.build().webOnlyRootElement);
await matchGoldenFile('canvas_draw_picture_acrossframes.png',
region: region);
});
test('draw growing picture across frames clipped', () async {
final SurfaceSceneBuilder builder = SurfaceSceneBuilder();
builder.pushClipRect(
const Rect.fromLTRB(0, 0, 100, 100),
);
_drawTestPicture(builder, 100, true);
builder.pop();
html.Element elm1 = builder.build().webOnlyRootElement;
html.document.body.append(elm1);
// Now draw picture again but at larger size.
final SurfaceSceneBuilder builder2 = SurfaceSceneBuilder();
builder2.pushClipRect(
const Rect.fromLTRB(0, 0, 100, 100),
);
_drawTestPicture(builder2, 20, true);
builder2.pop();
elm1.remove();
html.document.body.append(builder2.build().webOnlyRootElement);
await matchGoldenFile('canvas_draw_picture_acrossframes_clipped.png',
region: region);
});
}
HtmlImage sharedImage;
void _drawTestPicture(SceneBuilder builder, double targetSize, bool clipped) {
sharedImage ??= _createRealTestImage();
final EnginePictureRecorder recorder = PictureRecorder();
final RecordingCanvas canvas =
recorder.beginRecording(const Rect.fromLTRB(0, 0, 100, 100));
canvas.debugEnforceArbitraryPaint();
if (clipped) {
canvas.clipRRect(
RRect.fromLTRBR(0, 0, targetSize, targetSize, Radius.circular(4)));
}
canvas.drawImageRect(sharedImage, Rect.fromLTWH(0, 0, 20, 20),
Rect.fromLTWH(0, 0, targetSize, targetSize), Paint());
final Picture picture = recorder.endRecording();
builder.addPicture(
Offset.zero,
picture,
);
}
typedef PaintCallback = void Function(RecordingCanvas canvas);
const String _base64Encoded20x20TestImage =
'iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAC4jAAAuIwF4pT92AAAA'
'B3RJTUUH5AMFFBksg4i3gQAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAAj'
'SURBVDjLY2TAC/7jlWVioACMah4ZmhnxpyHG0QAb1UyZZgBjWAIm/clP0AAAAABJRU5ErkJggg==';
HtmlImage _createRealTestImage() {
return HtmlImage(
html.ImageElement()
..src = 'data:text/plain;base64,$_base64Encoded20x20TestImage',
20,
20,
);
}