| // 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:js_util' as js_util; |
| |
| import 'package:test/bootstrap/browser.dart'; |
| import 'package:test/test.dart'; |
| import 'package:ui/src/engine.dart'; |
| import 'package:ui/ui.dart' hide TextStyle; |
| |
| import '../../common/test_initialization.dart'; |
| import '../screenshot.dart'; |
| |
| // TODO(yjbanov): unskip Firefox tests when Firefox implements WebGL in headless mode. |
| // https://github.com/flutter/flutter/issues/86623 |
| |
| void main() { |
| internalBootstrapBrowserTest(() => testMain); |
| } |
| |
| Future<void> testMain() async { |
| const double screenWidth = 400.0; |
| const double screenHeight = 400.0; |
| const Rect screenRect = Rect.fromLTWH(0, 0, screenWidth, screenHeight); |
| final HtmlImage testImage = createTestImage(); |
| |
| setUpUnitTests( |
| setUpTestViewDimensions: false, |
| ); |
| |
| void drawShapes(RecordingCanvas rc, SurfacePaint paint, Rect shaderRect) { |
| /// Rect. |
| rc.drawRect(shaderRect, paint); |
| shaderRect = shaderRect.translate(100, 0); |
| |
| /// Circle. |
| rc.drawCircle(shaderRect.center, shaderRect.width / 2, paint); |
| shaderRect = shaderRect.translate(110, 0); |
| |
| /// Oval. |
| rc.drawOval(Rect.fromLTWH(shaderRect.left, shaderRect.top, shaderRect.width, shaderRect.height / 2), paint); |
| shaderRect = shaderRect.translate(-210, 120); |
| |
| /// Path. |
| final Path path = Path() |
| ..moveTo(shaderRect.center.dx, shaderRect.top) |
| ..lineTo(shaderRect.right, shaderRect.bottom) |
| ..lineTo(shaderRect.left, shaderRect.bottom) |
| ..close(); |
| rc.drawPath(path, paint); |
| shaderRect = shaderRect.translate(100, 0); |
| |
| /// RRect. |
| rc.drawRRect(RRect.fromRectXY(shaderRect, 10, 20), paint); |
| shaderRect = shaderRect.translate(110, 0); |
| |
| /// DRRect. |
| rc.drawDRRect(RRect.fromRectXY(shaderRect, 20, 30), |
| RRect.fromRectXY(shaderRect.deflate(24), 16, 24), |
| paint); |
| shaderRect = shaderRect.translate(-200, 120); |
| } |
| |
| Future<void> testImageShader( |
| TileMode tmx, TileMode tmy, String fileName) async { |
| final RecordingCanvas rc = |
| RecordingCanvas(const Rect.fromLTRB(0, 0, screenWidth, screenHeight)); |
| //Rect shaderRect = const Rect.fromLTRB(20, 20, 100, 100); |
| const Rect shaderRect = Rect.fromLTRB(0, 0, 100, 100); |
| final SurfacePaint paint = Paint() as SurfacePaint; |
| paint.shader = |
| ImageShader(testImage, tmx, tmy, Matrix4.identity().toFloat64() |
| , filterQuality: FilterQuality.high); |
| |
| drawShapes(rc, paint, shaderRect); |
| |
| expect(rc.renderStrategy.hasArbitraryPaint, isTrue); |
| await canvasScreenshot(rc, fileName, |
| region: screenRect); |
| } |
| |
| test('Should draw with tiled imageshader.', () async { |
| await testImageShader( |
| TileMode.repeated, TileMode.repeated, 'image_shader_tiled'); |
| }); |
| |
| test('Should draw with horizontally mirrored imageshader.', () async { |
| await testImageShader( |
| TileMode.mirror, TileMode.repeated, 'image_shader_horiz_mirror'); |
| }); |
| |
| test('Should draw with vertically mirrored imageshader.', () async { |
| await testImageShader( |
| TileMode.repeated, TileMode.mirror, 'image_shader_vert_mirror'); |
| }); |
| |
| test('Should draw with mirrored imageshader.', () async { |
| await testImageShader( |
| TileMode.mirror, TileMode.mirror, 'image_shader_mirror'); |
| }); |
| |
| test('Should draw with horizontal clamp imageshader.', () async { |
| await testImageShader( |
| TileMode.clamp, TileMode.repeated, 'image_shader_clamp_horiz'); |
| }, skip: isFirefox); |
| |
| test('Should draw with vertical clamp imageshader.', () async { |
| await testImageShader( |
| TileMode.repeated, TileMode.clamp, 'image_shader_clamp_vertical'); |
| }, skip: isFirefox); |
| |
| test('Should draw with clamp imageshader.', () async { |
| await testImageShader( |
| TileMode.clamp, TileMode.clamp, 'image_shader_clamp'); |
| }, skip: isFirefox); |
| } |
| |
| HtmlImage createTestImage() { |
| const int width = 16; |
| const int width2 = width ~/ 2; |
| const int height = 16; |
| final DomCanvasElement canvas = |
| createDomCanvasElement(width: width, height: height); |
| final DomCanvasRenderingContext2D ctx = canvas.context2D; |
| ctx.fillStyle = '#E04040'; |
| ctx.fillRect(0, 0, width2, width2); |
| ctx.fill(); |
| ctx.fillStyle = '#40E080'; |
| ctx.fillRect(width2, 0, width2, width2); |
| ctx.fill(); |
| ctx.fillStyle = '#2040E0'; |
| ctx.fillRect(width2, width2, width2, width2); |
| ctx.fill(); |
| final DomHTMLImageElement imageElement = createDomHTMLImageElement(); |
| imageElement.src = js_util.callMethod<String>(canvas, 'toDataURL', <dynamic>[]); |
| return HtmlImage(imageElement, width, height); |
| } |