// 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:html' as html;
import 'dart:math' as math;
import 'dart:typed_data';

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 'package:web_engine_tester/golden_tester.dart';

import '../common.dart';
import '../matchers.dart';

void main() {
  internalBootstrapBrowserTest(() => testMain);
}

Future<void> testMain() async {
  const double screenWidth = 600.0;
  const double screenHeight = 800.0;
  const Rect screenRect = Rect.fromLTWH(0, 0, screenWidth, screenHeight);
  final SurfacePaint testPaint = SurfacePaint()..color = const Color(0xFFFF0000);

  // 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,
        RenderStrategy());

    // Draws the estimated bounds so we can spot the bug in Scuba.
    engineCanvas
      ..save()
      ..drawRect(
        rc.pictureBounds!,
        SurfacePaintData()
          ..color = const Color.fromRGBO(0, 0, 255, 1.0)
          ..style = PaintingStyle.stroke
          ..strokeWidth = 1.0,
      )
      ..restore();

    rc.apply(engineCanvas, screenRect);

    // Wrap in <flt-scene> so that our CSS selectors kick in.
    final html.Element sceneElement = html.Element.tag('flt-scene');
    if (isIosSafari) {
      // Shrink to fit on the iPhone screen.
      sceneElement.style.position = 'absolute';
      sceneElement.style.transformOrigin = '0 0 0';
      sceneElement.style.transform = 'scale(0.3)';
    }
    try {
      sceneElement.append(engineCanvas.rootElement);
      html.document.body!.append(sceneElement);
      await matchGoldenFile('paint_bounds_for_$fileName.png', region: region,
        write: write);
    } finally {
      // The page is reused across tests, so remove the element after taking the
      // Scuba screenshot.
      sceneElement.remove();
    }
  }

  setUpAll(() async {
    debugEmulateFlutterTesterEnvironment = true;
    await webOnlyInitializePlatform();
    fontCollection.debugRegisterTestFonts();
    await fontCollection.ensureFontsLoaded();
  });

  test('Empty canvas reports correct paint bounds', () async {
    final RecordingCanvas rc =
        RecordingCanvas(const Rect.fromLTWH(1, 2, 300, 400));
    rc.endRecording();
    expect(rc.pictureBounds, Rect.zero);
    await _checkScreenshot(rc, 'empty_canvas');
  });

  test('Computes paint bounds for draw line', () async {
    final RecordingCanvas rc = RecordingCanvas(screenRect);
    rc.drawLine(const Offset(50, 100), const Offset(120, 140), testPaint);
    rc.endRecording();
    // The off by one is due to the minimum stroke width of 1.
    expect(rc.pictureBounds, const Rect.fromLTRB(49, 99, 121, 141));
    await _checkScreenshot(rc, 'draw_line');
  });

  test('Computes paint bounds for draw line when line exceeds limits',
      () async {
    // Uses max bounds when computing paint bounds
    final RecordingCanvas rc = RecordingCanvas(screenRect);
    rc.drawLine(const Offset(50, 100), const Offset(screenWidth + 100.0, 140),
        testPaint);
    rc.endRecording();
    // The off by one is due to the minimum stroke width of 1.
    expect(
        rc.pictureBounds, const Rect.fromLTRB(49.0, 99.0, screenWidth, 141.0));
    await _checkScreenshot(rc, 'draw_line_exceeding_limits');
  });

  test('Computes paint bounds for draw rect', () async {
    final RecordingCanvas rc = RecordingCanvas(screenRect);
    rc.drawRect(const Rect.fromLTRB(10, 20, 30, 40), testPaint);
    rc.endRecording();
    expect(rc.pictureBounds, const Rect.fromLTRB(10, 20, 30, 40));
    await _checkScreenshot(rc, 'draw_rect');
  });

  test('Computes paint bounds for draw rect when exceeds limits', () async {
    // Uses max bounds when computing paint bounds
    RecordingCanvas rc = RecordingCanvas(screenRect);
    rc.drawRect(
        const Rect.fromLTRB(10, 20, 30 + screenWidth, 40 + screenHeight),
        testPaint);
    rc.endRecording();
    expect(rc.pictureBounds,
        const Rect.fromLTRB(10, 20, screenWidth, screenHeight));

    rc = RecordingCanvas(screenRect);
    rc.drawRect(const Rect.fromLTRB(-200, -100, 30, 40), testPaint);
    rc.endRecording();
    expect(rc.pictureBounds, const Rect.fromLTRB(0, 0, 30, 40));
    await _checkScreenshot(rc, 'draw_rect_exceeding_limits');
  });

  test('Computes paint bounds for translate', () async {
    final RecordingCanvas rc = RecordingCanvas(screenRect);
    rc.translate(5, 7);
    rc.drawRect(const Rect.fromLTRB(10, 20, 30, 40), testPaint);
    rc.endRecording();
    expect(rc.pictureBounds, const Rect.fromLTRB(15, 27, 35, 47));
    await _checkScreenshot(rc, 'translate');
  });

  test('Computes paint bounds for scale', () async {
    final RecordingCanvas rc = RecordingCanvas(screenRect);
    rc.scale(2, 2);
    rc.drawRect(const Rect.fromLTRB(10, 20, 30, 40), testPaint);
    rc.endRecording();
    expect(rc.pictureBounds, const Rect.fromLTRB(20, 40, 60, 80));
    await _checkScreenshot(rc, 'scale');
  });

  test('Computes paint bounds for rotate', () async {
    final RecordingCanvas rc = RecordingCanvas(screenRect);
    rc.rotate(math.pi / 4.0);
    rc.drawLine(
        const Offset(1, 0), Offset(50 * math.sqrt(2) - 1, 0), testPaint);
    rc.endRecording();
    // The extra 0.7 is due to stroke width of 1 rotated by 45 degrees.
    expect(rc.pictureBounds,
        within(distance: 0.1, from: const Rect.fromLTRB(0, 0, 50.7, 50.7)));
    await _checkScreenshot(rc, 'rotate');
  });

  test('Computes paint bounds for horizontal skew', () async {
    final RecordingCanvas rc = RecordingCanvas(screenRect);
    rc.skew(1.0, 0.0);
    rc.drawRect(const Rect.fromLTRB(20, 20, 40, 40), testPaint);
    rc.endRecording();
    expect(
        rc.pictureBounds,
        within(
            distance: 0.1, from: const Rect.fromLTRB(40.0, 20.0, 80.0, 40.0)));
    await _checkScreenshot(rc, 'skew_horizontally');
  });

  test('Computes paint bounds for vertical skew', () async {
    final RecordingCanvas rc = RecordingCanvas(screenRect);
    rc.skew(0.0, 1.0);
    rc.drawRect(const Rect.fromLTRB(20, 20, 40, 40), testPaint);
    rc.endRecording();
    expect(
        rc.pictureBounds,
        within(
            distance: 0.1, from: const Rect.fromLTRB(20.0, 40.0, 40.0, 80.0)));
    await _checkScreenshot(rc, 'skew_vertically');
  });

  test('Computes paint bounds for a complex transform', () async {
    final RecordingCanvas rc = RecordingCanvas(screenRect);
    final Float32List matrix = Float32List(16);
    // translate(210, 220) , scale(2, 3), rotate(math.pi / 4.0)
    matrix[0] = 1.4;
    matrix[1] = 2.12;
    matrix[2] = 0.0;
    matrix[3] = 0.0;
    matrix[4] = -1.4;
    matrix[5] = 2.12;
    matrix[6] = 0.0;
    matrix[7] = 0.0;
    matrix[8] = 0.0;
    matrix[9] = 0.0;
    matrix[10] = 2.0;
    matrix[11] = 0.0;
    matrix[12] = 210.0;
    matrix[13] = 220.0;
    matrix[14] = 0.0;
    matrix[15] = 1.0;
    rc.transform(matrix);
    rc.drawRect(const Rect.fromLTRB(10, 20, 30, 40), testPaint);
    rc.endRecording();
    expect(
        rc.pictureBounds,
        within(
            distance: 0.001,
            from: const Rect.fromLTRB(168.0, 283.6, 224.0, 368.4)));
    await _checkScreenshot(rc, 'complex_transform');
  });

  test('drawPaint should cover full size', () async {
    final RecordingCanvas rc = RecordingCanvas(screenRect);
    rc.drawPaint(testPaint);
    rc.drawRect(const Rect.fromLTRB(10, 20, 30, 40), testPaint);
    rc.endRecording();
    expect(rc.pictureBounds, screenRect);
    await _checkScreenshot(rc, 'draw_paint');
  });

  test('drawColor should cover full size', () async {
    final RecordingCanvas rc = RecordingCanvas(screenRect);
    final SurfacePaint testPaint = SurfacePaint()..color = const Color(0xFF80FF00);
    rc.drawRect(const Rect.fromLTRB(10, 20, 30, 40), testPaint);
    rc.drawColor(const Color(0xFFFF0000), BlendMode.multiply);
    rc.drawRect(const Rect.fromLTRB(10, 60, 30, 80), testPaint);
    rc.endRecording();
    expect(rc.pictureBounds, screenRect);
    await _checkScreenshot(rc, 'draw_color');
  });

  test('Computes paint bounds for draw oval', () async {
    final RecordingCanvas rc = RecordingCanvas(screenRect);
    rc.drawOval(const Rect.fromLTRB(10, 20, 30, 40), testPaint);
    rc.endRecording();
    expect(rc.pictureBounds, const Rect.fromLTRB(10, 20, 30, 40));
    await _checkScreenshot(rc, 'draw_oval');
  });

  test('Computes paint bounds for draw round rect', () async {
    final RecordingCanvas rc = RecordingCanvas(screenRect);
    rc.drawRRect(
        RRect.fromRectAndRadius(
            const Rect.fromLTRB(10, 20, 30, 40), const Radius.circular(5.0)),
        testPaint);
    rc.endRecording();
    expect(rc.pictureBounds, const Rect.fromLTRB(10, 20, 30, 40));
    await _checkScreenshot(rc, 'draw_round_rect');
  });

  test(
      'Computes empty paint bounds when inner rect outside of outer rect for '
      'drawDRRect', () async {
    final RecordingCanvas rc = RecordingCanvas(screenRect);
    rc.drawDRRect(RRect.fromRectAndCorners(const Rect.fromLTRB(10, 20, 30, 40)),
        RRect.fromRectAndCorners(const Rect.fromLTRB(1, 2, 3, 4)), testPaint);
    rc.endRecording();
    expect(rc.pictureBounds, const Rect.fromLTRB(0, 0, 0, 0));
    await _checkScreenshot(rc, 'draw_drrect_empty');
  });

  test('Computes paint bounds using outer rect for drawDRRect', () async {
    final RecordingCanvas rc = RecordingCanvas(screenRect);
    rc.drawDRRect(
        RRect.fromRectAndCorners(const Rect.fromLTRB(10, 20, 30, 40)),
        RRect.fromRectAndCorners(const Rect.fromLTRB(12, 22, 28, 38)),
        testPaint);
    rc.endRecording();
    expect(rc.pictureBounds, const Rect.fromLTRB(10, 20, 30, 40));
    await _checkScreenshot(rc, 'draw_drrect');
  });

  test('Computes paint bounds for draw circle', () async {
    // Paint bounds of one circle.
    RecordingCanvas rc = RecordingCanvas(screenRect);
    rc.drawCircle(const Offset(20, 20), 10.0, testPaint);
    rc.endRecording();
    expect(rc.pictureBounds, const Rect.fromLTRB(10.0, 10.0, 30.0, 30.0));

    // Paint bounds of a union of two circles.
    rc = RecordingCanvas(screenRect);
    rc.drawCircle(const Offset(20, 20), 10.0, testPaint);
    rc.drawCircle(const Offset(200, 300), 100.0, testPaint);
    rc.endRecording();
    expect(rc.pictureBounds, const Rect.fromLTRB(10.0, 10.0, 300.0, 400.0));
    await _checkScreenshot(rc, 'draw_circle');
  });

  test('Computes paint bounds for draw image', () {
    final RecordingCanvas rc = RecordingCanvas(screenRect);
    rc.drawImage(TestImage(), const Offset(50, 100), SurfacePaint());
    rc.endRecording();
    expect(rc.pictureBounds, const Rect.fromLTRB(50.0, 100.0, 70.0, 110.0));
  });

  test('Computes paint bounds for draw image rect', () {
    final RecordingCanvas rc = RecordingCanvas(screenRect);
    rc.drawImageRect(TestImage(), const Rect.fromLTRB(1, 1, 20, 10),
        const Rect.fromLTRB(5, 6, 400, 500), SurfacePaint());
    rc.endRecording();
    expect(rc.pictureBounds, const Rect.fromLTRB(5.0, 6.0, 400.0, 500.0));
  });

  test('Computes paint bounds for single-line draw paragraph', () async {
    final RecordingCanvas rc = RecordingCanvas(screenRect);
    final Paragraph paragraph = createTestParagraph();
    const double textLeft = 5.0;
    const double textTop = 7.0;
    const double widthConstraint = 300.0;
    paragraph.layout(const ParagraphConstraints(width: widthConstraint));
    rc.drawParagraph(paragraph, const Offset(textLeft, textTop));
    rc.endRecording();
    expect(
      rc.pictureBounds,
      const Rect.fromLTRB(textLeft, textTop, textLeft + widthConstraint, 21.0),
    );
    await _checkScreenshot(rc, 'draw_paragraph');
  },  // TODO(mdebbar): https://github.com/flutter/flutter/issues/65789
      skip: browserEngine == BrowserEngine.webkit &&
          operatingSystem == OperatingSystem.iOs);

  test('Computes paint bounds for multi-line draw paragraph', () async {
    final RecordingCanvas rc = RecordingCanvas(screenRect);
    final Paragraph paragraph = createTestParagraph();
    const double textLeft = 5.0;
    const double textTop = 7.0;
    // Do not go lower than the shortest word.
    const double widthConstraint = 130.0;
    paragraph.layout(const ParagraphConstraints(width: widthConstraint));
    rc.drawParagraph(paragraph, const Offset(textLeft, textTop));
    rc.endRecording();
    expect(
      rc.pictureBounds,
      const Rect.fromLTRB(textLeft, textTop, textLeft + widthConstraint, 35.0),
    );
    await _checkScreenshot(rc, 'draw_paragraph_multi_line');
  },  // TODO(mdebbar): https://github.com/flutter/flutter/issues/65789
      skip: browserEngine == BrowserEngine.webkit &&
          operatingSystem == OperatingSystem.iOs);

  test('Should exclude painting outside simple clipRect', () async {
    // One clipped line.
    RecordingCanvas rc = RecordingCanvas(screenRect);
    rc.clipRect(const Rect.fromLTRB(50, 50, 100, 100), ClipOp.intersect);
    rc.drawLine(const Offset(10, 11), const Offset(20, 21), testPaint);
    rc.endRecording();
    expect(rc.pictureBounds, Rect.zero);

    // Two clipped lines.
    rc = RecordingCanvas(screenRect);
    rc.clipRect(const Rect.fromLTRB(50, 50, 100, 100), ClipOp.intersect);
    rc.drawLine(const Offset(10, 11), const Offset(20, 21), testPaint);
    rc.drawLine(const Offset(52, 53), const Offset(55, 56), testPaint);
    rc.endRecording();

    // Extra pixel due to default line length
    expect(rc.pictureBounds, const Rect.fromLTRB(51, 52, 56, 57));
    await _checkScreenshot(rc, 'clip_rect_simple');
  });

  test('Should include intersection of clipRect and painting', () async {
    RecordingCanvas rc = RecordingCanvas(screenRect);
    rc.clipRect(const Rect.fromLTRB(50, 50, 100, 100), ClipOp.intersect);
    rc.drawRect(const Rect.fromLTRB(20, 60, 120, 70), testPaint);
    rc.endRecording();
    expect(rc.pictureBounds, const Rect.fromLTRB(50, 60, 100, 70));
    await _checkScreenshot(rc, 'clip_rect_intersects_paint_left_to_right');

    rc = RecordingCanvas(screenRect);
    rc.clipRect(const Rect.fromLTRB(50, 50, 100, 100), ClipOp.intersect);
    rc.drawRect(const Rect.fromLTRB(60, 20, 70, 200), testPaint);
    rc.endRecording();
    expect(rc.pictureBounds, const Rect.fromLTRB(60, 50, 70, 100));
    await _checkScreenshot(rc, 'clip_rect_intersects_paint_top_to_bottom');
  });

  test('Should intersect rects for multiple clipRect calls', () async {
    final RecordingCanvas rc = RecordingCanvas(screenRect);
    rc.clipRect(const Rect.fromLTRB(50, 50, 100, 100), ClipOp.intersect);
    rc.scale(2.0, 2.0);
    rc.clipRect(const Rect.fromLTRB(30, 30, 45, 45), ClipOp.intersect);
    rc.drawRect(const Rect.fromLTRB(10, 30, 60, 35), testPaint);
    rc.endRecording();

    expect(rc.pictureBounds, const Rect.fromLTRB(60, 60, 90, 70));
    await _checkScreenshot(rc, 'clip_rects_intersect');
  });

  // drawShadow
  test('Computes paint bounds for drawShadow', () async {
    final RecordingCanvas rc = RecordingCanvas(screenRect);
    final Path path = Path();
    path.addRect(const Rect.fromLTRB(20, 30, 100, 110));
    rc.drawShadow(path, const Color(0xFFFF0000), 2.0, true);
    rc.endRecording();

    expect(
      rc.pictureBounds,
      within(
          distance: 0.05, from: const Rect.fromLTRB(17.9, 28.5, 103.5, 114.1)),
    );
    await _checkScreenshot(rc, 'path_with_shadow');
  });

  test('Clip with negative scale reports correct paint bounds', () async {
    // The following draws a filled rectangle that occupies the bottom half of
    // the canvas. Notice that both the clip and the rectangle are drawn
    // forward. What makes them appear at the bottom is the translation and a
    // vertical flip via a negative scale. This replicates the Material
    // overscroll glow effect at the bottom of a list, where it is drawn upside
    // down.
    final RecordingCanvas rc =
        RecordingCanvas(const Rect.fromLTRB(0, 0, 100, 100));
    rc
      ..translate(0, 100)
      ..scale(1, -1)
      ..clipRect(const Rect.fromLTRB(0, 0, 100, 50), ClipOp.intersect)
      ..drawRect(const Rect.fromLTRB(0, 0, 100, 100), SurfacePaint());
    rc.endRecording();

    expect(rc.pictureBounds, const Rect.fromLTRB(0.0, 50.0, 100.0, 100.0));
    await _checkScreenshot(rc, 'scale_negative');
  });

  test('Clip with a rotation reports correct paint bounds', () async {
    final RecordingCanvas rc =
        RecordingCanvas(const Rect.fromLTRB(0, 0, 100, 100));
    rc
      ..translate(50, 50)
      ..rotate(math.pi / 4.0)
      ..clipRect(const Rect.fromLTWH(-20, -20, 40, 40), ClipOp.intersect)
      ..drawRect(const Rect.fromLTWH(-80, -80, 160, 160), SurfacePaint());
    rc.endRecording();

    expect(
      rc.pictureBounds,
      within(
          distance: 0.001,
          from: Rect.fromCircle(
              center: const Offset(50, 50), radius: 20 * math.sqrt(2))),
    );
    await _checkScreenshot(rc, 'clip_rect_rotated');
  });

  test('Rotated line reports correct paint bounds', () async {
    final RecordingCanvas rc =
        RecordingCanvas(const Rect.fromLTRB(0, 0, 100, 100));
    rc
      ..translate(50, 50)
      ..rotate(math.pi / 4.0)
      ..drawLine(const Offset(0, 0), const Offset(20, 20), SurfacePaint());
    rc.endRecording();

    expect(
      rc.pictureBounds,
      within(distance: 0.1, from: const Rect.fromLTRB(34.4, 48.6, 65.6, 79.7)),
    );
    await _checkScreenshot(rc, 'line_rotated');
  });

  test('Should support reusing path and reset when drawing into canvas.',
      () async {
    final RecordingCanvas rc =
        RecordingCanvas(const Rect.fromLTRB(0, 0, 100, 100));

    final Path path = Path();
    path.moveTo(3, 0);
    path.lineTo(100, 97);
    rc.drawPath(
        path,
        SurfacePaint()
          ..style = PaintingStyle.stroke
          ..strokeWidth = 2.0
          ..color = const Color(0xFFFF0000));
    path.reset();
    path.moveTo(0, 3);
    path.lineTo(97, 100);
    rc.drawPath(
        path,
        SurfacePaint()
          ..style = PaintingStyle.stroke
          ..strokeWidth = 2.0
          ..color = const Color(0xFF00FF00));
    rc.endRecording();
    await _checkScreenshot(rc, 'reuse_path');
  });

  test('Should draw RRect after line when beginning new path.', () async {
    final RecordingCanvas rc =
        RecordingCanvas(const Rect.fromLTRB(0, 0, 200, 400));
    rc.save();
    rc.translate(50.0, 100.0);
    final Path path = Path();
    // Draw a vertical small line (caret).
    path.moveTo(8, 4);
    path.lineTo(8, 24);
    // Draw round rect below caret.
    path.addRRect(
        RRect.fromLTRBR(0.5, 100.5, 80.7, 150.7, const Radius.circular(10)));
    rc.drawPath(
        path,
        SurfacePaint()
          ..style = PaintingStyle.stroke
          ..strokeWidth = 2.0
          ..color = const Color(0xFF404000));
    rc.restore();
    rc.endRecording();
    await _checkScreenshot(rc, 'path_with_line_and_roundrect');
  });

  // Regression test for https://github.com/flutter/flutter/issues/64371.
  test('Should draw line following a polygon without closing path.', () async {
    final RecordingCanvas rc =
    RecordingCanvas(const Rect.fromLTRB(0, 0, 200, 400));
    rc.save();
    rc.translate(50.0, 100.0);
    final Path path = Path();
    // Draw a vertical small line (caret).
    path.addPolygon(const <Offset>[Offset(0, 10), Offset(20,5), Offset(50,10)],
        false);
    path.lineTo(60, 80);
    path.lineTo(0, 80);
    path.close();
    rc.drawPath(
        path,
        SurfacePaint()
          ..style = PaintingStyle.stroke
          ..strokeWidth = 2.0
          ..color = const Color(0xFF404000));
    rc.restore();
    rc.endRecording();
    await _checkScreenshot(rc, 'path_with_addpolygon');
  });

  test('should include paint spread in bounds estimates', () async {
    final SurfaceSceneBuilder sb = SurfaceSceneBuilder();

    final List<PaintSpreadPainter> painters = <PaintSpreadPainter>[
      (RecordingCanvas canvas, SurfacePaint paint) {
        canvas.drawLine(
          const Offset(0.0, 0.0),
          const Offset(20.0, 20.0),
          paint,
        );
      },
      (RecordingCanvas canvas, SurfacePaint paint) {
        canvas.drawRect(
          const Rect.fromLTRB(0.0, 0.0, 20.0, 20.0),
          paint,
        );
      },
      (RecordingCanvas canvas, SurfacePaint paint) {
        canvas.drawRRect(
          RRect.fromLTRBR(0.0, 0.0, 20.0, 20.0, const Radius.circular(7.0)),
          paint,
        );
      },
      (RecordingCanvas canvas, SurfacePaint paint) {
        canvas.drawDRRect(
          RRect.fromLTRBR(0.0, 0.0, 20.0, 20.0, const Radius.circular(5.0)),
          RRect.fromLTRBR(4.0, 4.0, 16.0, 16.0, const Radius.circular(5.0)),
          paint,
        );
      },
      (RecordingCanvas canvas, SurfacePaint paint) {
        canvas.drawOval(
          const Rect.fromLTRB(0.0, 5.0, 20.0, 15.0),
          paint,
        );
      },
      (RecordingCanvas canvas, SurfacePaint paint) {
        canvas.drawCircle(
          const Offset(10.0, 10.0),
          10.0,
          paint,
        );
      },
      (RecordingCanvas canvas, SurfacePaint paint) {
        final SurfacePath path = SurfacePath()
          ..moveTo(10, 0)
          ..lineTo(20, 10)
          ..lineTo(10, 20)
          ..lineTo(0, 10)
          ..close();
        canvas.drawPath(path, paint);
      },

      // Images are not affected by mask filter or stroke width. They use image
      // filter instead.
      (RecordingCanvas canvas, SurfacePaint paint) {
        canvas.drawImage(_createRealTestImage(), Offset.zero, paint);
      },
      (RecordingCanvas canvas, SurfacePaint paint) {
        canvas.drawImageRect(
          _createRealTestImage(),
          const Rect.fromLTRB(0, 0, 20, 20),
          const Rect.fromLTRB(5, 5, 15, 15),
          paint,
        );
      },
    ];

    Picture drawBounds(Rect bounds) {
      final EnginePictureRecorder recorder = EnginePictureRecorder();
      final RecordingCanvas canvas = recorder.beginRecording(Rect.largest);
      canvas.drawRect(
        bounds,
        SurfacePaint()
          ..style = PaintingStyle.stroke
          ..strokeWidth = 1.0
          ..color = const Color.fromARGB(255, 0, 255, 0),
      );
      return recorder.endRecording();
    }

    for (int i = 0; i < painters.length; i++) {
      sb.pushOffset(0.0, 20.0 + 60.0 * i);
      final PaintSpreadPainter painter = painters[i];

      // Paint with zero paint spread.
      {
        sb.pushOffset(20.0, 0.0);
        final EnginePictureRecorder recorder = EnginePictureRecorder();
        final RecordingCanvas canvas = recorder.beginRecording(Rect.largest);
        final SurfacePaint zeroSpreadPaint = SurfacePaint();
        painter(canvas, zeroSpreadPaint);
        sb.addPicture(Offset.zero, recorder.endRecording());
        sb.addPicture(Offset.zero, drawBounds(canvas.pictureBounds!));
        sb.pop();
      }

      // Paint with a thick stroke paint.
      {
        sb.pushOffset(80.0, 0.0);
        final EnginePictureRecorder recorder = EnginePictureRecorder();
        final RecordingCanvas canvas = recorder.beginRecording(Rect.largest);
        final SurfacePaint thickStrokePaint = SurfacePaint()
          ..style = PaintingStyle.stroke
          ..strokeWidth = 5.0;
        painter(canvas, thickStrokePaint);
        sb.addPicture(Offset.zero, recorder.endRecording());
        sb.addPicture(Offset.zero, drawBounds(canvas.pictureBounds!));
        sb.pop();
      }

      // Paint with a mask filter blur.
      {
        sb.pushOffset(140.0, 0.0);
        final EnginePictureRecorder recorder = EnginePictureRecorder();
        final RecordingCanvas canvas = recorder.beginRecording(Rect.largest);
        final SurfacePaint maskFilterBlurPaint = SurfacePaint()
          ..maskFilter = const MaskFilter.blur(BlurStyle.normal, 5.0);
        painter(canvas, maskFilterBlurPaint);
        sb.addPicture(Offset.zero, recorder.endRecording());
        sb.addPicture(Offset.zero, drawBounds(canvas.pictureBounds!));
        sb.pop();
      }

      // Paint with a thick stroke paint and a mask filter blur.
      {
        sb.pushOffset(200.0, 0.0);
        final EnginePictureRecorder recorder = EnginePictureRecorder();
        final RecordingCanvas canvas = recorder.beginRecording(Rect.largest);
        final SurfacePaint thickStrokeAndBlurPaint = SurfacePaint()
          ..style = PaintingStyle.stroke
          ..strokeWidth = 5.0
          ..maskFilter = const MaskFilter.blur(BlurStyle.normal, 5.0);
        painter(canvas, thickStrokeAndBlurPaint);
        sb.addPicture(Offset.zero, recorder.endRecording());
        sb.addPicture(Offset.zero, drawBounds(canvas.pictureBounds!));
        sb.pop();
      }

      sb.pop();
    }

    final html.Element sceneElement = sb.build().webOnlyRootElement!;
    html.document.body!.append(sceneElement);
    try {
      await matchGoldenFile(
        'paint_spread_bounds.png',
        region: const Rect.fromLTRB(0, 0, 250, 600),
        maxDiffRatePercent: 0.21,
        pixelComparison: PixelComparison.precise,
      );
    } finally {
      sceneElement.remove();
    }
  });
}

typedef PaintSpreadPainter = void Function(
    RecordingCanvas canvas, SurfacePaint paint);

const String _base64Encoded20x20TestImage = 'iVBORw0KGgoAAAANSUhEUgAAABQAAAAUC'
    'AIAAAAC64paAAAACXBIWXMAAC4jAAAuIwF4pT92AAAA'
    'B3RJTUUH5AMFFBksg4i3gQAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAAj'
    'SURBVDjLY2TAC/7jlWVioACMah4ZmhnxpyHG0QAb1UyZZgBjWAIm/clP0AAAAABJRU5ErkJggg==';

HtmlImage _createRealTestImage() {
  return HtmlImage(
    html.ImageElement()
      ..src = 'data:text/plain;base64,$_base64Encoded20x20TestImage',
    20,
    20,
  );
}

class TestImage implements Image {
  @override
  int get width => 20;

  @override
  int get height => 10;

  @override
  Future<ByteData> toByteData(
      {ImageByteFormat format = ImageByteFormat.rawRgba}) async {
    throw UnsupportedError('Cannot encode test image');
  }

  @override
  String toString() => '[$width\u00D7$height]';

  @override
  void dispose() {}

  @override
  bool get debugDisposed => false;

  @override
  Image clone() => this;

  @override
  bool isCloneOf(Image other) => other == this;

  @override
  List<StackTrace>/*?*/ debugGetOpenHandleStackTraces() => <StackTrace>[];
}

Paragraph createTestParagraph() {
  final ParagraphBuilder builder = ParagraphBuilder(ParagraphStyle(
    fontFamily: 'Ahem',
    fontStyle: FontStyle.normal,
    fontWeight: FontWeight.normal,
    fontSize: 14.0,
  ));
  builder.addText('A short sentence.');
  return builder.build();
}
