blob: 38379087867e2dfb991e96d2e59ea8d7d5c3837f [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' hide TextStyle;
import 'package:ui/src/engine.dart';
import 'package:test/test.dart';
import '../../matchers.dart';
import 'package:web_engine_tester/golden_tester.dart';
void main() async {
const double screenWidth = 600.0;
const double screenHeight = 800.0;
const Rect screenRect = Rect.fromLTWH(0, 0, screenWidth, screenHeight);
const Color black12Color = Color(0x1F000000);
const Color redAccentColor = Color(0xFFFF1744);
const double kDashLength = 5.0;
// Commit a recording canvas to a bitmap, and compare with the expected
Future<void> _checkScreenshot(RecordingCanvas rc, String fileName,
{Rect region = const Rect.fromLTWH(0, 0, 500, 500),
bool write = false}) async {
final EngineCanvas engineCanvas = BitmapCanvas(screenRect);
rc.apply(engineCanvas);
// Wrap in <flt-scene> so that our CSS selectors kick in.
final html.Element sceneElement = html.Element.tag('flt-scene');
try {
sceneElement.append(engineCanvas.rootElement);
html.document.body.append(sceneElement);
await matchGoldenFile('$fileName.png', region: region);
} finally {
// The page is reused across tests, so remove the element after taking the
// Scuba screenshot.
sceneElement.remove();
}
}
setUp(() async {
debugEmulateFlutterTesterEnvironment = true;
await webOnlyInitializePlatform();
webOnlyFontCollection.debugRegisterTestFonts();
await webOnlyFontCollection.ensureFontsLoaded();
});
test('Should calculate tangent on line', () async {
final Path path = Path();
path.moveTo(50, 130);
path.lineTo(150, 20);
PathMetric metric = path.computeMetrics().first;
Tangent t = metric.getTangentForOffset(50.0);
expect(t.position.dx, within(from: 83.633, distance: 0.01));
expect(t.position.dy, within(from: 93.0, distance: 0.01));
expect(t.vector.dx, within(from: 0.672, distance: 0.01));
expect(t.vector.dy, within(from: -0.739, distance: 0.01));
});
test('Should calculate tangent on cubic curve', () async {
final Path path = Path();
double p1x = 240;
double p1y = 120;
double p2x = 320;
double p2y = 25;
path.moveTo(150, 20);
path.quadraticBezierTo(p1x, p1y, p2x, p2y);
PathMetric metric = path.computeMetrics().first;
Tangent t = metric.getTangentForOffset(50.0);
expect(t.position.dx, within(from: 187.25, distance: 0.01));
expect(t.position.dy, within(from: 53.33, distance: 0.01));
expect(t.vector.dx, within(from: 0.82, distance: 0.01));
expect(t.vector.dy, within(from: 0.56, distance: 0.01));
});
test('Should calculate tangent on quadratic curve', () async {
final Path path = Path();
double p0x = 150;
double p0y = 20;
double p1x = 320;
double p1y = 25;
path.moveTo(150, 20);
path.quadraticBezierTo(p0x, p0y, p1x, p1y);
PathMetric metric = path.computeMetrics().first;
Tangent t = metric.getTangentForOffset(50.0);
expect(t.position.dx, within(from: 199.82, distance: 0.01));
expect(t.position.dy, within(from: 21.46, distance: 0.01));
expect(t.vector.dx, within(from: 0.99, distance: 0.01));
expect(t.vector.dy, within(from: 0.02, distance: 0.01));
});
// Test for extractPath to draw 5 pixel length dashed line using quad curve.
test('Should draw dashed line on quadratic curve.', () async {
final RecordingCanvas rc =
RecordingCanvas(const Rect.fromLTRB(0, 0, 500, 500));
final Paint paint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = 3
..color = black12Color;
final Paint redPaint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = 1
..color = redAccentColor;
final Path path = Path();
path.moveTo(50, 130);
path.lineTo(150, 20);
double p1x = 240;
double p1y = 120;
double p2x = 320;
double p2y = 25;
path.quadraticBezierTo(p1x, p1y, p2x, p2y);
rc.drawPath(path, paint);
double t0 = 0.2;
double t1 = 0.7;
List<PathMetric> metrics = path.computeMetrics().toList();
double totalLength = 0;
for (PathMetric m in metrics) {
totalLength += m.length;
}
Path dashedPath = Path();
for (final PathMetric measurePath in path.computeMetrics()) {
double distance = totalLength * t0;
bool draw = true;
while (distance < measurePath.length * t1) {
final double length = kDashLength;
if (draw) {
dashedPath.addPath(
measurePath.extractPath(distance, distance + length),
Offset.zero);
}
distance += length;
draw = !draw;
}
}
rc.drawPath(dashedPath, redPaint);
await _checkScreenshot(rc, 'path_dash_quadratic');
});
// Test for extractPath to draw 5 pixel length dashed line using cubic curve.
test('Should draw dashed line on cubic curve.', () async {
final RecordingCanvas rc =
RecordingCanvas(const Rect.fromLTRB(0, 0, 500, 500));
final Paint paint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = 3
..color = black12Color;
final Paint redPaint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = 1
..color = redAccentColor;
final Path path = Path();
path.moveTo(50, 130);
path.lineTo(150, 20);
double p1x = 40;
double p1y = 120;
double p2x = 300;
double p2y = 130;
double p3x = 320;
double p3y = 25;
path.cubicTo(p1x, p1y, p2x, p2y, p3x, p3y);
rc.drawPath(path, paint);
double t0 = 0.2;
double t1 = 0.7;
List<PathMetric> metrics = path.computeMetrics().toList();
double totalLength = 0;
for (PathMetric m in metrics) {
totalLength += m.length;
}
Path dashedPath = Path();
for (final PathMetric measurePath in path.computeMetrics()) {
double distance = totalLength * t0;
bool draw = true;
while (distance < measurePath.length * t1) {
final double length = kDashLength;
if (draw) {
dashedPath.addPath(
measurePath.extractPath(distance, distance + length),
Offset.zero);
}
distance += length;
draw = !draw;
}
}
rc.drawPath(dashedPath, redPaint);
await _checkScreenshot(rc, 'path_dash_cubic');
});
}