// 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:async';
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' hide window;

import '../screenshot.dart';
import 'helper.dart';

const Rect bounds = Rect.fromLTWH(0, 0, 800, 600);

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

Future<void> testMain() async {
  setUpStableTestFonts();

  test('paints spans and lines correctly', () {
    final BitmapCanvas canvas = BitmapCanvas(bounds, RenderStrategy());

    Offset offset = Offset.zero;
    CanvasParagraph paragraph;

    // Single-line multi-span.
    paragraph = rich(EngineParagraphStyle(fontFamily: 'Roboto'), (CanvasParagraphBuilder builder) {
      builder.pushStyle(EngineTextStyle.only(color: blue));
      builder.addText('Lorem ');
      builder.pushStyle(EngineTextStyle.only(
        color: green,
        background: Paint()..color = red,
      ));
      builder.addText('ipsum ');
      builder.pop();
      builder.addText('.');
    })
      ..layout(constrain(double.infinity));
    canvas.drawParagraph(paragraph, offset);
    offset = offset.translate(0, paragraph.height + 10);

    // Multi-line single-span.
    paragraph = rich(EngineParagraphStyle(fontFamily: 'Roboto'), (CanvasParagraphBuilder builder) {
      builder.addText('Lorem ipsum dolor sit');
    })
      ..layout(constrain(90.0));
    canvas.drawParagraph(paragraph, offset);
    offset = offset.translate(0, paragraph.height + 10);

    // Multi-line multi-span.
    paragraph = rich(EngineParagraphStyle(fontFamily: 'Roboto'), (CanvasParagraphBuilder builder) {
      builder.pushStyle(EngineTextStyle.only(color: blue));
      builder.addText('Lorem ipsum ');
      builder.pushStyle(EngineTextStyle.only(background: Paint()..color = red));
      builder.pushStyle(EngineTextStyle.only(color: green));
      builder.addText('dolor ');
      builder.pop();
      builder.addText('sit');
    })
      ..layout(constrain(90.0));
    canvas.drawParagraph(paragraph, offset);
    offset = offset.translate(0, paragraph.height + 10);

    return takeScreenshot(canvas, bounds, 'canvas_paragraph_general');
  });

  test('respects alignment', () {
    final BitmapCanvas canvas = BitmapCanvas(bounds, RenderStrategy());

    Offset offset = Offset.zero;
    CanvasParagraph paragraph;

    void build(CanvasParagraphBuilder builder) {
      builder.pushStyle(EngineTextStyle.only(color: black));
      builder.addText('Lorem ');
      builder.pushStyle(EngineTextStyle.only(color: blue));
      builder.addText('ipsum ');
      builder.pushStyle(EngineTextStyle.only(color: green));
      builder.addText('dolor ');
      builder.pushStyle(EngineTextStyle.only(color: red));
      builder.addText('sit');
    }

    paragraph = rich(
      EngineParagraphStyle(fontFamily: 'Roboto', textAlign: TextAlign.left),
      build,
    )..layout(constrain(100.0));
    canvas.drawParagraph(paragraph, offset);
    offset = offset.translate(0, paragraph.height + 10);

    paragraph = rich(
      EngineParagraphStyle(fontFamily: 'Roboto', textAlign: TextAlign.center),
      build,
    )..layout(constrain(100.0));
    canvas.drawParagraph(paragraph, offset);
    offset = offset.translate(0, paragraph.height + 10);

    paragraph = rich(
      EngineParagraphStyle(fontFamily: 'Roboto', textAlign: TextAlign.right),
      build,
    )..layout(constrain(100.0));
    canvas.drawParagraph(paragraph, offset);
    offset = offset.translate(0, paragraph.height + 10);

    return takeScreenshot(canvas, bounds, 'canvas_paragraph_align');
  });

  test('respects alignment in DOM mode', () {
    final DomCanvas canvas = DomCanvas(domDocument.createElement('flt-picture'));

    Offset offset = Offset.zero;
    CanvasParagraph paragraph;

    void build(CanvasParagraphBuilder builder) {
      builder.pushStyle(EngineTextStyle.only(color: black));
      builder.addText('Lorem ');
      builder.pushStyle(EngineTextStyle.only(color: blue));
      builder.addText('ipsum ');
      builder.pushStyle(EngineTextStyle.only(color: green));
      builder.addText('dolor ');
      builder.pushStyle(EngineTextStyle.only(color: red));
      builder.addText('sit');
    }

    paragraph = rich(
      EngineParagraphStyle(fontFamily: 'Roboto', textAlign: TextAlign.left),
      build,
    )..layout(constrain(100.0));
    canvas.drawParagraph(paragraph, offset);
    offset = offset.translate(0, paragraph.height + 10);

    paragraph = rich(
      EngineParagraphStyle(fontFamily: 'Roboto', textAlign: TextAlign.center),
      build,
    )..layout(constrain(100.0));
    canvas.drawParagraph(paragraph, offset);
    offset = offset.translate(0, paragraph.height + 10);

    paragraph = rich(
      EngineParagraphStyle(fontFamily: 'Roboto', textAlign: TextAlign.right),
      build,
    )..layout(constrain(100.0));
    canvas.drawParagraph(paragraph, offset);
    offset = offset.translate(0, paragraph.height + 10);

    return takeScreenshot(canvas, bounds, 'canvas_paragraph_align_dom');
  });

  void testAlignAndTransform(EngineCanvas canvas) {
    CanvasParagraph paragraph;

    void build(CanvasParagraphBuilder builder) {
      builder.pushStyle(EngineTextStyle.only(color: white));
      builder.addText('Lorem ');
      builder.pushStyle(EngineTextStyle.only(color: red));
      builder.addText('ipsum\n');
      builder.pushStyle(EngineTextStyle.only(color: yellow));
      builder.addText('dolor');
    }

    void drawParagraphAt(Offset offset, TextAlign align) {
      paragraph = rich(
        EngineParagraphStyle(fontFamily: 'Roboto', fontSize: 20.0, textAlign: align),
        build,
      )..layout(constrain(150.0));
      canvas.save();
      canvas.translate(offset.dx, offset.dy);
      canvas.rotate(math.pi / 4);
      final Rect rect = Rect.fromLTRB(0.0, 0.0, 150.0, paragraph.height);
      canvas.drawRect(rect, SurfacePaintData()..color = black.value);
      canvas.drawParagraph(paragraph, Offset.zero);
      canvas.restore();
    }

    drawParagraphAt(const Offset(50.0, 0.0), TextAlign.left);
    drawParagraphAt(const Offset(150.0, 0.0), TextAlign.center);
    drawParagraphAt(const Offset(250.0, 0.0), TextAlign.right);
  }

  test('alignment and transform', () {
    final BitmapCanvas canvas = BitmapCanvas(bounds, RenderStrategy());
    testAlignAndTransform(canvas);
    return takeScreenshot(canvas, bounds, 'canvas_paragraph_align_transform');
  });

  test('alignment and transform (DOM)', () {
    final DomCanvas canvas = DomCanvas(domDocument.createElement('flt-picture'));
    testAlignAndTransform(canvas);
    return takeScreenshot(canvas, bounds, 'canvas_paragraph_align_transform_dom');
  });

  void testGiantParagraphStyles(EngineCanvas canvas) {
    final CanvasParagraph paragraph = rich(
      EngineParagraphStyle(fontFamily: 'Roboto', fontSize: 80.0),
      (CanvasParagraphBuilder builder) {
        builder.pushStyle(EngineTextStyle.only(color: yellow, fontSize: 24.0));
        builder.addText('Lorem ');
        builder.pushStyle(EngineTextStyle.only(color: red, fontSize: 32.0));
        builder.addText('ipsum');
      },
    )..layout(constrain(double.infinity));
    final Rect rect = Rect.fromLTRB(0.0, 0.0, paragraph.maxIntrinsicWidth, paragraph.height);
    canvas.drawRect(rect, SurfacePaintData()..color = black.value);
    canvas.drawParagraph(paragraph, Offset.zero);
  }

  test('giant paragraph style', () {
    const Rect bounds = Rect.fromLTWH(0, 0, 300, 200);
    final BitmapCanvas canvas = BitmapCanvas(bounds, RenderStrategy());
    testGiantParagraphStyles(canvas);
    return takeScreenshot(canvas, bounds, 'canvas_paragraph_giant_paragraph_style');
  });

  test('giant paragraph style (DOM)', () {
    const Rect bounds = Rect.fromLTWH(0, 0, 300, 200);
    final DomCanvas canvas = DomCanvas(domDocument.createElement('flt-picture'));
    testGiantParagraphStyles(canvas);
    return takeScreenshot(canvas, bounds, 'canvas_paragraph_giant_paragraph_style_dom');
  });

  test('giant font size on the body tag (DOM)', () async {
    const Rect bounds = Rect.fromLTWH(0, 0, 600, 200);

    // Store the old font size value on the body, and set a gaint font size.
    final String oldBodyFontSize = domDocument.body!.style.fontSize;
    domDocument.body!.style.fontSize = '100px';

    final DomCanvas canvas = DomCanvas(domDocument.createElement('flt-picture'));
    Offset offset = const Offset(10.0, 10.0);

    final CanvasParagraph paragraph = rich(
      EngineParagraphStyle(fontFamily: 'Roboto'),
      (CanvasParagraphBuilder builder) {
        builder.pushStyle(EngineTextStyle.only(color: yellow, fontSize: 24.0));
        builder.addText('Lorem ');
        builder.pushStyle(EngineTextStyle.only(color: red, fontSize: 48.0));
        builder.addText('ipsum');
      },
    )..layout(constrain(double.infinity));
    final Rect rect = Rect.fromLTWH(offset.dx, offset.dy, paragraph.maxIntrinsicWidth, paragraph.height);
    canvas.drawRect(rect, SurfacePaintData()..color = black.value);
    canvas.drawParagraph(paragraph, offset);
    offset = offset.translate(paragraph.maxIntrinsicWidth, 0.0);

    // Add some extra padding between the two paragraphs.
    offset = offset.translate(20.0, 0.0);

    // Use the same height as the previous paragraph so that the 2 paragraphs
    // look nice in the screenshot.
    final double placeholderHeight = paragraph.height;
    final double placeholderWidth = paragraph.height * 2;

    final CanvasParagraph paragraph2 = rich(
      EngineParagraphStyle(),
      (CanvasParagraphBuilder builder) {
        builder.addPlaceholder(placeholderWidth, placeholderHeight, PlaceholderAlignment.baseline, baseline: TextBaseline.alphabetic);
      },
    )..layout(constrain(double.infinity));
    final Rect rect2 = Rect.fromLTWH(offset.dx, offset.dy, paragraph2.maxIntrinsicWidth, paragraph2.height);
    canvas.drawRect(rect2, SurfacePaintData()..color = black.value);
    canvas.drawParagraph(paragraph2, offset);
    // Draw a rect in the placeholder.
    // Leave some padding around the placeholder to make the black paragraph
    // background visible.
    const double padding = 5;
    final TextBox placeholderBox = paragraph2.getBoxesForPlaceholders().single;
    canvas.drawRect(
      placeholderBox.toRect().shift(offset).deflate(padding),
      SurfacePaintData()..color = red.value,
    );

    await takeScreenshot(canvas, bounds, 'canvas_paragraph_giant_body_font_size_dom');

    // Restore the old font size value.
    domDocument.body!.style.fontSize = oldBodyFontSize;
  });

  test('paints spans with varying heights/baselines', () {
    final BitmapCanvas canvas = BitmapCanvas(bounds, RenderStrategy());

    final CanvasParagraph paragraph = rich(
      EngineParagraphStyle(fontFamily: 'Roboto'),
      (CanvasParagraphBuilder builder) {
        builder.pushStyle(EngineTextStyle.only(fontSize: 20.0));
        builder.addText('Lorem ');
        builder.pushStyle(EngineTextStyle.only(
          fontSize: 40.0,
          background: Paint()..color = green,
        ));
        builder.addText('ipsum ');
        builder.pushStyle(EngineTextStyle.only(
          fontSize: 10.0,
          color: white,
          background: Paint()..color = black,
        ));
        builder.addText('dolor ');
        builder.pushStyle(EngineTextStyle.only(fontSize: 30.0));
        builder.addText('sit ');
        builder.pop();
        builder.pop();
        builder.pushStyle(EngineTextStyle.only(
          fontSize: 20.0,
          background: Paint()..color = blue,
        ));
        builder.addText('amet');
      },
    )..layout(constrain(220.0));
    canvas.drawParagraph(paragraph, Offset.zero);

    return takeScreenshot(canvas, bounds, 'canvas_paragraph_varying_heights');
  });

  test('respects letter-spacing', () {
    final BitmapCanvas canvas = BitmapCanvas(bounds, RenderStrategy());

    final CanvasParagraph paragraph = rich(
      EngineParagraphStyle(fontFamily: 'Roboto'),
      (CanvasParagraphBuilder builder) {
        builder.pushStyle(EngineTextStyle.only(color: blue));
        builder.addText('Lorem ');
        builder.pushStyle(EngineTextStyle.only(color: green, letterSpacing: 1));
        builder.addText('Lorem ');
        builder.pushStyle(EngineTextStyle.only(color: red, letterSpacing: 3));
        builder.addText('Lorem');
      },
    )..layout(constrain(double.infinity));
    canvas.drawParagraph(paragraph, Offset.zero);

    return takeScreenshot(canvas, bounds, 'canvas_paragraph_letter_spacing');
  });

  test('draws text decorations', () {
    final BitmapCanvas canvas = BitmapCanvas(bounds, RenderStrategy());
    final List<TextDecorationStyle> decorationStyles = <TextDecorationStyle>[
      TextDecorationStyle.solid,
      TextDecorationStyle.double,
      TextDecorationStyle.dotted,
      TextDecorationStyle.dashed,
      TextDecorationStyle.wavy,
    ];

    final CanvasParagraph paragraph = rich(
      EngineParagraphStyle(fontFamily: 'Roboto'),
      (CanvasParagraphBuilder builder) {
        for (final TextDecorationStyle decorationStyle in decorationStyles) {
          builder.pushStyle(EngineTextStyle.only(
            color: const Color.fromRGBO(50, 50, 255, 1.0),
            decoration: TextDecoration.underline,
            decorationStyle: decorationStyle,
            decorationColor: red,
            fontFamily: 'Roboto',
            fontSize: 30,
          ));
          builder.addText('Hello World');
          builder.pop();
          builder.addText(' ');
        }
      },
    )..layout(constrain(double.infinity));

    canvas.drawParagraph(paragraph, Offset.zero);
    return takeScreenshot(canvas, bounds, 'canvas_paragraph_decoration');
  });

  void testFontFeatures(EngineCanvas canvas) {
    const String text = 'Bb Difficult ';
    const FontFeature enableSmallCaps = FontFeature('smcp');
    const FontFeature disableSmallCaps = FontFeature('smcp', 0);

    const String numeric = '123.4560';
    const FontFeature enableOnum = FontFeature('onum');

    const FontFeature disableLigatures = FontFeature('liga', 0);

    final CanvasParagraph paragraph = rich(
      EngineParagraphStyle(fontFamily: 'Roboto'),
      (CanvasParagraphBuilder builder) {
        // Small Caps
        builder.pushStyle(EngineTextStyle.only(
          height: 1.5,
          color: black,
          fontSize: 32.0,
        ));
        builder.pushStyle(EngineTextStyle.only(
          color: blue,
          fontFeatures: <FontFeature>[enableSmallCaps],
        ));
        builder.addText(text);
        // Make sure disabling a font feature also works.
        builder.pushStyle(EngineTextStyle.only(
          color: black,
          fontFeatures: <FontFeature>[disableSmallCaps],
        ));
        builder.addText(' (smcp)\n');
        builder.pop(); // disableSmallCaps
        builder.pop(); // enableSmallCaps

        // No ligatures
        builder.pushStyle(EngineTextStyle.only(
          color: blue,
          fontFeatures: <FontFeature>[disableLigatures],
        ));
        builder.addText(text);
        builder.pop(); // disableLigatures
        builder.addText(' (no liga)\n');

        // No font features
        builder.pushStyle(EngineTextStyle.only(
          color: blue,
        ));
        builder.addText(text);
        builder.pop(); // color: blue
        builder.addText(' (none)\n');

        // Onum
        builder.pushStyle(EngineTextStyle.only(
          color: blue,
          fontFeatures: <FontFeature>[enableOnum],
        ));
        builder.addText(numeric);
        builder.pop(); // enableOnum
        builder.addText(' (onum)\n');

        // No font features
        builder.pushStyle(EngineTextStyle.only(
          color: blue,
        ));
        builder.addText(numeric);
        builder.pop(); // color: blue
        builder.addText(' (none)\n\n');

        // Multiple font features
        builder.addText('Combined (smcp, onum):\n');
        builder.pushStyle(EngineTextStyle.only(
          color: blue,
          fontFeatures: <FontFeature>[
            enableSmallCaps,
            enableOnum,
          ],
        ));
        builder.addText('$text  $numeric');
        builder.pop(); // enableSmallCaps, enableOnum
      },
    )..layout(constrain(double.infinity));
    canvas.drawParagraph(paragraph, Offset.zero);
  }

  test('font features', () {
    const Rect bounds = Rect.fromLTWH(0, 0, 600, 500);
    final BitmapCanvas canvas = BitmapCanvas(bounds, RenderStrategy());
    testFontFeatures(canvas);
    return takeScreenshot(canvas, bounds, 'canvas_paragraph_font_features');
  });

  test('font features (DOM)', () {
    const Rect bounds = Rect.fromLTWH(0, 0, 600, 500);
    final DomCanvas canvas = DomCanvas(domDocument.createElement('flt-picture'));
    testFontFeatures(canvas);
    return takeScreenshot(canvas, bounds, 'canvas_paragraph_font_features_dom');
  });

  void testFontVariations(EngineCanvas canvas) {
    const String text = 'ABCDE 12345\n';
    FontVariation weight(double w) => FontVariation('wght', w);

    final CanvasParagraph paragraph = rich(
      EngineParagraphStyle(fontFamily: 'RobotoVariable'),
      (CanvasParagraphBuilder builder) {
        builder.pushStyle(EngineTextStyle.only(
          fontSize: 48.0,
        ));
        builder.addText(text);
        builder.pushStyle(EngineTextStyle.only(
          fontSize: 48.0,
          fontVariations: <FontVariation>[weight(900)],
        ));
        builder.addText(text);
        builder.pushStyle(EngineTextStyle.only(
          fontSize: 48.0,
          fontVariations: <FontVariation>[weight(200)],
        ));
        builder.addText(text);
        builder.pop();
        builder.pop();
        builder.pop();
      },
    )..layout(constrain(double.infinity));
    canvas.drawParagraph(paragraph, Offset.zero);
  }

  test('font variations', () {
    const Rect bounds = Rect.fromLTWH(0, 0, 600, 500);
    final BitmapCanvas canvas = BitmapCanvas(bounds, RenderStrategy());
    testFontVariations(canvas);
    return takeScreenshot(canvas, bounds, 'canvas_paragraph_font_variations');
  });

  test('font variations (DOM)', () {
    const Rect bounds = Rect.fromLTWH(0, 0, 600, 500);
    final DomCanvas canvas = DomCanvas(domDocument.createElement('flt-picture'));
    testFontVariations(canvas);
    return takeScreenshot(canvas, bounds, 'canvas_paragraph_font_variations_dom');
  });

  void testBackgroundStyle(EngineCanvas canvas) {
    final CanvasParagraph paragraph = rich(
      EngineParagraphStyle(fontFamily: 'Roboto', fontSize: 40.0),
      (CanvasParagraphBuilder builder) {
        builder.pushStyle(EngineTextStyle.only(color: black));
        builder.pushStyle(EngineTextStyle.only(background: Paint()..color = blue));
        builder.addText('Lor');
        builder.pushStyle(EngineTextStyle.only(background: Paint()..color = black, color: white));
        builder.addText('em ');
        builder.pop();
        builder.pushStyle(EngineTextStyle.only(background: Paint()..color = green));
        builder.addText('ipsu');
        builder.pushStyle(EngineTextStyle.only(background: Paint()..color = yellow));
        builder.addText('m\ndo');
        builder.pushStyle(EngineTextStyle.only(background: Paint()..color = red));
        builder.addText('lor sit');
      },
    );
    paragraph.layout(constrain(double.infinity));
    canvas.drawParagraph(paragraph, Offset.zero);
  }

  test('background style', () {
    const Rect bounds = Rect.fromLTWH(0, 0, 300, 200);
    final BitmapCanvas canvas = BitmapCanvas(bounds, RenderStrategy());
    testBackgroundStyle(canvas);
    return takeScreenshot(canvas, bounds, 'canvas_paragraph_background_style');
  });

  test('background style (DOM)', () {
    const Rect bounds = Rect.fromLTWH(0, 0, 300, 200);
    final DomCanvas canvas = DomCanvas(domDocument.createElement('flt-picture'));
    testBackgroundStyle(canvas);
    return takeScreenshot(canvas, bounds, 'canvas_paragraph_background_style_dom');
  });

  void testForegroundStyle(EngineCanvas canvas) {
    final CanvasParagraph paragraph = rich(
      EngineParagraphStyle(fontFamily: 'Roboto', fontSize: 40.0),
      (CanvasParagraphBuilder builder) {
        builder.pushStyle(EngineTextStyle.only(color: blue));
        builder.addText('Lorem');
        builder.pop();
        builder.pushStyle(EngineTextStyle.only(foreground: Paint()..color = red..style = PaintingStyle.stroke));
        builder.addText('ipsum\n');
        builder.pop();
        builder.pushStyle(EngineTextStyle.only(foreground: Paint()..color = blue..style = PaintingStyle.stroke..strokeWidth = 0.0));
        builder.addText('dolor');
        builder.pop();
        builder.pushStyle(EngineTextStyle.only(foreground: Paint()..color = green..style = PaintingStyle.stroke..strokeWidth = 2.0));
        builder.addText('sit\n');
        builder.pop();
        builder.pushStyle(EngineTextStyle.only(foreground: Paint()..color = yellow..style = PaintingStyle.stroke..strokeWidth = 4.0));
        builder.addText('amet');
      },
    );
    paragraph.layout(constrain(double.infinity));
    canvas.drawParagraph(paragraph, Offset.zero);
  }

  test('foreground style', () {
    const Rect bounds = Rect.fromLTWH(0, 0, 300, 200);
    final BitmapCanvas canvas = BitmapCanvas(bounds, RenderStrategy());
    testForegroundStyle(canvas);
    return takeScreenshot(canvas, bounds, 'canvas_paragraph_foreground_style');
  });

  test('foreground style (DOM)', () {
    const Rect bounds = Rect.fromLTWH(0, 0, 300, 200);
    final DomCanvas canvas = DomCanvas(domDocument.createElement('flt-picture'));
    testForegroundStyle(canvas);
    return takeScreenshot(canvas, bounds, 'canvas_paragraph_foreground_style_dom');
  });

  test('paragraph bounds hug the text inside the paragraph', () async {
    const Rect bounds = Rect.fromLTWH(0, 0, 150, 100);

    final CanvasParagraphBuilder builder = CanvasParagraphBuilder(EngineParagraphStyle(
      fontFamily: 'Ahem',
      fontSize: 20,
      textAlign: TextAlign.center,
    ));

    // Expected layout with center-alignment is something like this:
    //
    // _________________
    // |       A       |
    // |    |AAAAA|    |
    // |    | AAA |    |
    // |----|-----|----|
    // |    |<--->|    |
    // |      100      |
    // |               |
    // |<------------->|
    //        110
    //
    // The width of the paragraph is bigger than the actual content because the
    // longest line "AAAAA" is 100px, which is smaller than 110px specified in
    // the constraint. After the layout and centering the paint bounds would
    // "hug" the text inside the paragraph more tightly than the box allocated
    // for the paragraph.
    builder.addText('A AAAAA AAA');

    final CanvasParagraph paragraph = builder.build();
    paragraph.layout(const ParagraphConstraints(width: 110));
    final BitmapCanvas canvas = BitmapCanvas(bounds, RenderStrategy());
    canvas.translate(20, 20);
    canvas.drawParagraph(paragraph, Offset.zero);
    canvas.drawRect(
      Rect.fromLTRB(
        0,
        0,
        paragraph.width,
        paragraph.height,
      ),
      SurfacePaintData()
        ..style = PaintingStyle.stroke
        ..strokeWidth = 1,
    );

    canvas.drawRect(
      paragraph.paintBounds,
      SurfacePaintData()
        ..color = 0xFF00FF00
        ..style = PaintingStyle.stroke
        ..strokeWidth = 1,
    );

    await takeScreenshot(canvas, bounds, 'canvas_paragraph_bounds');
  });
}
