| // 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 'package:test/bootstrap/browser.dart'; |
| import 'package:test/test.dart'; |
| import 'package:ui/src/engine.dart'; |
| import 'package:ui/ui.dart' hide window; |
| |
| import '../../common/test_initialization.dart'; |
| import 'helper.dart'; |
| |
| const String _rtlWord1 = 'واحد'; |
| const String _rtlWord2 = 'اثنان'; |
| |
| void main() { |
| internalBootstrapBrowserTest(() => testMain); |
| } |
| |
| Future<void> testMain() async { |
| setUpUnitTests( |
| emulateTesterEnvironment: false, |
| setUpTestViewDimensions: false, |
| ); |
| |
| void paintBasicBidiStartingWithLtr( |
| EngineCanvas canvas, |
| Rect bounds, |
| double y, |
| TextDirection textDirection, |
| TextAlign textAlign, |
| ) { |
| // The text starts with a left-to-right word. |
| const String text = 'One 12 $_rtlWord1 $_rtlWord2 34 two 56'; |
| |
| final EngineParagraphStyle paragraphStyle = EngineParagraphStyle( |
| fontFamily: 'Roboto', |
| fontSize: 20.0, |
| textDirection: textDirection, |
| textAlign: textAlign, |
| ); |
| final CanvasParagraph paragraph = plain( |
| paragraphStyle, |
| text, |
| textStyle: EngineTextStyle.only(color: blue), |
| ); |
| final double maxWidth = bounds.width - 10; |
| paragraph.layout(constrain(maxWidth)); |
| canvas.drawParagraph(paragraph, Offset(bounds.left + 5, bounds.top + y + 5)); |
| } |
| |
| test('basic bidi starting with ltr', () { |
| const Rect bounds = Rect.fromLTWH(0, 0, 340, 600); |
| final BitmapCanvas canvas = BitmapCanvas(bounds, RenderStrategy()); |
| |
| const double height = 40; |
| |
| // Border for ltr paragraphs. |
| final Rect ltrBox = const Rect.fromLTWH(0, 0, 320, 5 * height).inflate(5).translate(10, 10); |
| canvas.drawRect( |
| ltrBox, |
| SurfacePaintData() |
| ..color = black.value |
| ..style = PaintingStyle.stroke, |
| ); |
| // LTR with different text align values: |
| paintBasicBidiStartingWithLtr(canvas, ltrBox, 0 * height, TextDirection.ltr, TextAlign.left); |
| paintBasicBidiStartingWithLtr(canvas, ltrBox, 1 * height, TextDirection.ltr, TextAlign.right); |
| paintBasicBidiStartingWithLtr(canvas, ltrBox, 2 * height, TextDirection.ltr, TextAlign.center); |
| paintBasicBidiStartingWithLtr(canvas, ltrBox, 3 * height, TextDirection.ltr, TextAlign.start); |
| paintBasicBidiStartingWithLtr(canvas, ltrBox, 4 * height, TextDirection.ltr, TextAlign.end); |
| |
| // Border for rtl paragraphs. |
| final Rect rtlBox = ltrBox.translate(0, ltrBox.height + 10); |
| canvas.drawRect( |
| rtlBox, |
| SurfacePaintData() |
| ..color = black.value |
| ..style = PaintingStyle.stroke, |
| ); |
| // RTL with different text align values: |
| paintBasicBidiStartingWithLtr(canvas, rtlBox, 0 * height, TextDirection.rtl, TextAlign.left); |
| paintBasicBidiStartingWithLtr(canvas, rtlBox, 1 * height, TextDirection.rtl, TextAlign.right); |
| paintBasicBidiStartingWithLtr(canvas, rtlBox, 2 * height, TextDirection.rtl, TextAlign.center); |
| paintBasicBidiStartingWithLtr(canvas, rtlBox, 3 * height, TextDirection.rtl, TextAlign.start); |
| paintBasicBidiStartingWithLtr(canvas, rtlBox, 4 * height, TextDirection.rtl, TextAlign.end); |
| |
| return takeScreenshot(canvas, bounds, 'canvas_paragraph_bidi_start_ltr'); |
| }); |
| |
| test('basic bidi starting with ltr (DOM)', () { |
| const Rect bounds = Rect.fromLTWH(0, 0, 340, 600); |
| final DomCanvas canvas = DomCanvas(domDocument.createElement('flt-picture')); |
| |
| const double height = 40; |
| |
| // Border for ltr paragraphs. |
| final Rect ltrBox = const Rect.fromLTWH(0, 0, 320, 5 * height).inflate(5).translate(10, 10); |
| canvas.drawRect( |
| ltrBox, |
| SurfacePaintData() |
| ..color = black.value |
| ..style = PaintingStyle.stroke, |
| ); |
| // LTR with different text align values: |
| paintBasicBidiStartingWithLtr(canvas, ltrBox, 0 * height, TextDirection.ltr, TextAlign.left); |
| paintBasicBidiStartingWithLtr(canvas, ltrBox, 1 * height, TextDirection.ltr, TextAlign.right); |
| paintBasicBidiStartingWithLtr(canvas, ltrBox, 2 * height, TextDirection.ltr, TextAlign.center); |
| paintBasicBidiStartingWithLtr(canvas, ltrBox, 3 * height, TextDirection.ltr, TextAlign.start); |
| paintBasicBidiStartingWithLtr(canvas, ltrBox, 4 * height, TextDirection.ltr, TextAlign.end); |
| |
| // Border for rtl paragraphs. |
| final Rect rtlBox = ltrBox.translate(0, ltrBox.height + 10); |
| canvas.drawRect( |
| rtlBox, |
| SurfacePaintData() |
| ..color = black.value |
| ..style = PaintingStyle.stroke, |
| ); |
| // RTL with different text align values: |
| paintBasicBidiStartingWithLtr(canvas, rtlBox, 0 * height, TextDirection.rtl, TextAlign.left); |
| paintBasicBidiStartingWithLtr(canvas, rtlBox, 1 * height, TextDirection.rtl, TextAlign.right); |
| paintBasicBidiStartingWithLtr(canvas, rtlBox, 2 * height, TextDirection.rtl, TextAlign.center); |
| paintBasicBidiStartingWithLtr(canvas, rtlBox, 3 * height, TextDirection.rtl, TextAlign.start); |
| paintBasicBidiStartingWithLtr(canvas, rtlBox, 4 * height, TextDirection.rtl, TextAlign.end); |
| |
| return takeScreenshot(canvas, bounds, 'canvas_paragraph_bidi_start_ltr_dom'); |
| }); |
| |
| void paintBasicBidiStartingWithRtl( |
| EngineCanvas canvas, |
| Rect bounds, |
| double y, |
| TextDirection textDirection, |
| TextAlign textAlign, |
| ) { |
| // The text starts with a right-to-left word. |
| const String text = '$_rtlWord1 12 one 34 $_rtlWord2 56 two'; |
| |
| final EngineParagraphStyle paragraphStyle = EngineParagraphStyle( |
| fontFamily: 'Roboto', |
| fontSize: 20.0, |
| textDirection: textDirection, |
| textAlign: textAlign, |
| ); |
| final CanvasParagraph paragraph = plain( |
| paragraphStyle, |
| text, |
| textStyle: EngineTextStyle.only(color: blue), |
| ); |
| final double maxWidth = bounds.width - 10; |
| paragraph.layout(constrain(maxWidth)); |
| canvas.drawParagraph(paragraph, Offset(bounds.left + 5, bounds.top + y + 5)); |
| } |
| |
| test('basic bidi starting with rtl', () { |
| const Rect bounds = Rect.fromLTWH(0, 0, 340, 600); |
| final BitmapCanvas canvas = BitmapCanvas(bounds, RenderStrategy()); |
| |
| const double height = 40; |
| |
| // Border for ltr paragraphs. |
| final Rect ltrBox = const Rect.fromLTWH(0, 0, 320, 5 * height).inflate(5).translate(10, 10); |
| canvas.drawRect( |
| ltrBox, |
| SurfacePaintData() |
| ..color = black.value |
| ..style = PaintingStyle.stroke, |
| ); |
| // LTR with different text align values: |
| paintBasicBidiStartingWithRtl(canvas, ltrBox, 0 * height, TextDirection.ltr, TextAlign.left); |
| paintBasicBidiStartingWithRtl(canvas, ltrBox, 1 * height, TextDirection.ltr, TextAlign.right); |
| paintBasicBidiStartingWithRtl(canvas, ltrBox, 2 * height, TextDirection.ltr, TextAlign.center); |
| paintBasicBidiStartingWithRtl(canvas, ltrBox, 3 * height, TextDirection.ltr, TextAlign.start); |
| paintBasicBidiStartingWithRtl(canvas, ltrBox, 4 * height, TextDirection.ltr, TextAlign.end); |
| |
| // Border for rtl paragraphs. |
| final Rect rtlBox = ltrBox.translate(0, ltrBox.height + 10); |
| canvas.drawRect( |
| rtlBox, |
| SurfacePaintData() |
| ..color = black.value |
| ..style = PaintingStyle.stroke, |
| ); |
| // RTL with different text align values: |
| paintBasicBidiStartingWithRtl(canvas, rtlBox, 0 * height, TextDirection.rtl, TextAlign.left); |
| paintBasicBidiStartingWithRtl(canvas, rtlBox, 1 * height, TextDirection.rtl, TextAlign.right); |
| paintBasicBidiStartingWithRtl(canvas, rtlBox, 2 * height, TextDirection.rtl, TextAlign.center); |
| paintBasicBidiStartingWithRtl(canvas, rtlBox, 3 * height, TextDirection.rtl, TextAlign.start); |
| paintBasicBidiStartingWithRtl(canvas, rtlBox, 4 * height, TextDirection.rtl, TextAlign.end); |
| |
| return takeScreenshot(canvas, bounds, 'canvas_paragraph_bidi_start_rtl'); |
| }); |
| |
| test('basic bidi starting with rtl (DOM)', () { |
| const Rect bounds = Rect.fromLTWH(0, 0, 340, 600); |
| final DomCanvas canvas = DomCanvas(domDocument.createElement('flt-picture')); |
| |
| const double height = 40; |
| |
| // Border for ltr paragraphs. |
| final Rect ltrBox = const Rect.fromLTWH(0, 0, 320, 5 * height).inflate(5).translate(10, 10); |
| canvas.drawRect( |
| ltrBox, |
| SurfacePaintData() |
| ..color = black.value |
| ..style = PaintingStyle.stroke, |
| ); |
| // LTR with different text align values: |
| paintBasicBidiStartingWithRtl(canvas, ltrBox, 0 * height, TextDirection.ltr, TextAlign.left); |
| paintBasicBidiStartingWithRtl(canvas, ltrBox, 1 * height, TextDirection.ltr, TextAlign.right); |
| paintBasicBidiStartingWithRtl(canvas, ltrBox, 2 * height, TextDirection.ltr, TextAlign.center); |
| paintBasicBidiStartingWithRtl(canvas, ltrBox, 3 * height, TextDirection.ltr, TextAlign.start); |
| paintBasicBidiStartingWithRtl(canvas, ltrBox, 4 * height, TextDirection.ltr, TextAlign.end); |
| |
| // Border for rtl paragraphs. |
| final Rect rtlBox = ltrBox.translate(0, ltrBox.height + 10); |
| canvas.drawRect( |
| rtlBox, |
| SurfacePaintData() |
| ..color = black.value |
| ..style = PaintingStyle.stroke, |
| ); |
| // RTL with different text align values: |
| paintBasicBidiStartingWithRtl(canvas, rtlBox, 0 * height, TextDirection.rtl, TextAlign.left); |
| paintBasicBidiStartingWithRtl(canvas, rtlBox, 1 * height, TextDirection.rtl, TextAlign.right); |
| paintBasicBidiStartingWithRtl(canvas, rtlBox, 2 * height, TextDirection.rtl, TextAlign.center); |
| paintBasicBidiStartingWithRtl(canvas, rtlBox, 3 * height, TextDirection.rtl, TextAlign.start); |
| paintBasicBidiStartingWithRtl(canvas, rtlBox, 4 * height, TextDirection.rtl, TextAlign.end); |
| |
| return takeScreenshot(canvas, bounds, 'canvas_paragraph_bidi_start_rtl_dom'); |
| }); |
| |
| void paintMultilineBidi( |
| EngineCanvas canvas, |
| Rect bounds, |
| double y, |
| TextDirection textDirection, |
| TextAlign textAlign, |
| ) { |
| // ''' |
| // Lorem 12 $_rtlWord1 |
| // $_rtlWord2 34 ipsum |
| // dolor 56 |
| // ''' |
| const String text = 'Lorem 12 $_rtlWord1 $_rtlWord2 34 ipsum dolor 56'; |
| |
| final EngineParagraphStyle paragraphStyle = EngineParagraphStyle( |
| fontFamily: 'Roboto', |
| fontSize: 20.0, |
| textDirection: textDirection, |
| textAlign: textAlign, |
| ); |
| final CanvasParagraph paragraph = plain( |
| paragraphStyle, |
| text, |
| textStyle: EngineTextStyle.only(color: blue), |
| ); |
| final double maxWidth = bounds.width - 10; |
| paragraph.layout(constrain(maxWidth)); |
| canvas.drawParagraph(paragraph, Offset(bounds.left + 5, bounds.top + y + 5)); |
| } |
| |
| test('multiline bidi', () { |
| const Rect bounds = Rect.fromLTWH(0, 0, 400, 500); |
| final BitmapCanvas canvas = BitmapCanvas(bounds, RenderStrategy()); |
| |
| const double height = 95; |
| |
| // Border for ltr paragraphs. |
| final Rect ltrBox = const Rect.fromLTWH(0, 0, 150, 5 * height).inflate(5).translate(10, 10); |
| canvas.drawRect( |
| ltrBox, |
| SurfacePaintData() |
| ..color = black.value |
| ..style = PaintingStyle.stroke, |
| ); |
| // LTR with different text align values: |
| paintMultilineBidi(canvas, ltrBox, 0 * height, TextDirection.ltr, TextAlign.left); |
| paintMultilineBidi(canvas, ltrBox, 1 * height, TextDirection.ltr, TextAlign.right); |
| paintMultilineBidi(canvas, ltrBox, 2 * height, TextDirection.ltr, TextAlign.center); |
| paintMultilineBidi(canvas, ltrBox, 3 * height, TextDirection.ltr, TextAlign.start); |
| paintMultilineBidi(canvas, ltrBox, 4 * height, TextDirection.ltr, TextAlign.end); |
| |
| // Border for rtl paragraphs. |
| final Rect rtlBox = ltrBox.translate(ltrBox.width + 10, 0); |
| canvas.drawRect( |
| rtlBox, |
| SurfacePaintData() |
| ..color = black.value |
| ..style = PaintingStyle.stroke, |
| ); |
| // RTL with different text align values: |
| paintMultilineBidi(canvas, rtlBox, 0 * height, TextDirection.rtl, TextAlign.left); |
| paintMultilineBidi(canvas, rtlBox, 1 * height, TextDirection.rtl, TextAlign.right); |
| paintMultilineBidi(canvas, rtlBox, 2 * height, TextDirection.rtl, TextAlign.center); |
| paintMultilineBidi(canvas, rtlBox, 3 * height, TextDirection.rtl, TextAlign.start); |
| paintMultilineBidi(canvas, rtlBox, 4 * height, TextDirection.rtl, TextAlign.end); |
| |
| return takeScreenshot(canvas, bounds, 'canvas_paragraph_bidi_multiline'); |
| }); |
| |
| test('multiline bidi (DOM)', () { |
| const Rect bounds = Rect.fromLTWH(0, 0, 400, 500); |
| final DomCanvas canvas = DomCanvas(domDocument.createElement('flt-picture')); |
| |
| const double height = 95; |
| |
| final Rect ltrBox = const Rect.fromLTWH(0, 0, 150, 5 * height).inflate(5).translate(10, 10); |
| canvas.drawRect( |
| ltrBox, |
| SurfacePaintData() |
| ..color = black.value |
| ..style = PaintingStyle.stroke, |
| ); |
| // LTR with different text align values: |
| paintMultilineBidi(canvas, ltrBox, 0 * height, TextDirection.ltr, TextAlign.left); |
| paintMultilineBidi(canvas, ltrBox, 1 * height, TextDirection.ltr, TextAlign.right); |
| paintMultilineBidi(canvas, ltrBox, 2 * height, TextDirection.ltr, TextAlign.center); |
| paintMultilineBidi(canvas, ltrBox, 3 * height, TextDirection.ltr, TextAlign.start); |
| paintMultilineBidi(canvas, ltrBox, 4 * height, TextDirection.ltr, TextAlign.end); |
| |
| // Border for rtl paragraphs. |
| final Rect rtlBox = ltrBox.translate(ltrBox.width + 10, 0); |
| canvas.drawRect( |
| rtlBox, |
| SurfacePaintData() |
| ..color = black.value |
| ..style = PaintingStyle.stroke, |
| ); |
| // RTL with different text align values: |
| paintMultilineBidi(canvas, rtlBox, 0 * height, TextDirection.rtl, TextAlign.left); |
| paintMultilineBidi(canvas, rtlBox, 1 * height, TextDirection.rtl, TextAlign.right); |
| paintMultilineBidi(canvas, rtlBox, 2 * height, TextDirection.rtl, TextAlign.center); |
| paintMultilineBidi(canvas, rtlBox, 3 * height, TextDirection.rtl, TextAlign.start); |
| paintMultilineBidi(canvas, rtlBox, 4 * height, TextDirection.rtl, TextAlign.end); |
| |
| return takeScreenshot(canvas, bounds, 'canvas_paragraph_bidi_multiline_dom'); |
| }); |
| |
| void paintMultSpanBidi( |
| EngineCanvas canvas, |
| Rect bounds, |
| double y, |
| TextDirection textDirection, |
| TextAlign textAlign, |
| ) { |
| final EngineParagraphStyle paragraphStyle = EngineParagraphStyle( |
| fontFamily: 'Roboto', |
| fontSize: 20.0, |
| textDirection: textDirection, |
| textAlign: textAlign, |
| ); |
| // ''' |
| // Lorem 12 $_rtlWord1 |
| // $_rtlWord2 34 ipsum |
| // dolor 56 |
| // ''' |
| final CanvasParagraph paragraph = rich(paragraphStyle, (CanvasParagraphBuilder builder) { |
| builder.pushStyle(EngineTextStyle.only(color: blue)); |
| builder.addText('Lorem '); |
| builder.pushStyle(EngineTextStyle.only(color: green)); |
| builder.addText('12 '); |
| builder.pushStyle(EngineTextStyle.only(color: red)); |
| builder.addText('$_rtlWord1 '); |
| builder.pushStyle(EngineTextStyle.only(color: black)); |
| builder.addText('$_rtlWord2 '); |
| builder.pushStyle(EngineTextStyle.only(color: blue)); |
| builder.addText('34 ipsum '); |
| builder.pushStyle(EngineTextStyle.only(color: green)); |
| builder.addText('dolor 56 '); |
| }); |
| final double maxWidth = bounds.width - 10; |
| paragraph.layout(constrain(maxWidth)); |
| canvas.drawParagraph(paragraph, Offset(bounds.left + 5, bounds.top + y + 5)); |
| } |
| |
| test('multi span bidi', () { |
| const Rect bounds = Rect.fromLTWH(0, 0, 400, 900); |
| final BitmapCanvas canvas = BitmapCanvas(bounds, RenderStrategy()); |
| |
| const double height = 95; |
| |
| // Border for ltr paragraphs. |
| final Rect ltrBox = const Rect.fromLTWH(0, 0, 150, 5 * height).inflate(5).translate(10, 10); |
| canvas.drawRect( |
| ltrBox, |
| SurfacePaintData() |
| ..color = black.value |
| ..style = PaintingStyle.stroke, |
| ); |
| // LTR with different text align values: |
| paintMultSpanBidi(canvas, ltrBox, 0 * height, TextDirection.ltr, TextAlign.left); |
| paintMultSpanBidi(canvas, ltrBox, 1 * height, TextDirection.ltr, TextAlign.right); |
| paintMultSpanBidi(canvas, ltrBox, 2 * height, TextDirection.ltr, TextAlign.center); |
| paintMultSpanBidi(canvas, ltrBox, 3 * height, TextDirection.ltr, TextAlign.start); |
| paintMultSpanBidi(canvas, ltrBox, 4 * height, TextDirection.ltr, TextAlign.end); |
| |
| // Border for rtl paragraphs. |
| final Rect rtlBox = ltrBox.translate(ltrBox.width + 10, 0); |
| canvas.drawRect( |
| rtlBox, |
| SurfacePaintData() |
| ..color = black.value |
| ..style = PaintingStyle.stroke, |
| ); |
| // RTL with different text align values: |
| paintMultSpanBidi(canvas, rtlBox, 0 * height, TextDirection.rtl, TextAlign.left); |
| paintMultSpanBidi(canvas, rtlBox, 1 * height, TextDirection.rtl, TextAlign.right); |
| paintMultSpanBidi(canvas, rtlBox, 2 * height, TextDirection.rtl, TextAlign.center); |
| paintMultSpanBidi(canvas, rtlBox, 3 * height, TextDirection.rtl, TextAlign.start); |
| paintMultSpanBidi(canvas, rtlBox, 4 * height, TextDirection.rtl, TextAlign.end); |
| |
| return takeScreenshot(canvas, bounds, 'canvas_paragraph_bidi_multispan'); |
| }); |
| |
| test('multi span bidi (DOM)', () { |
| const Rect bounds = Rect.fromLTWH(0, 0, 400, 900); |
| final DomCanvas canvas = DomCanvas(domDocument.createElement('flt-picture')); |
| |
| const double height = 95; |
| |
| // Border for ltr paragraphs. |
| final Rect ltrBox = const Rect.fromLTWH(0, 0, 150, 5 * height).inflate(5).translate(10, 10); |
| canvas.drawRect( |
| ltrBox, |
| SurfacePaintData() |
| ..color = black.value |
| ..style = PaintingStyle.stroke, |
| ); |
| // LTR with different text align values: |
| paintMultSpanBidi(canvas, ltrBox, 0 * height, TextDirection.ltr, TextAlign.left); |
| paintMultSpanBidi(canvas, ltrBox, 1 * height, TextDirection.ltr, TextAlign.right); |
| paintMultSpanBidi(canvas, ltrBox, 2 * height, TextDirection.ltr, TextAlign.center); |
| paintMultSpanBidi(canvas, ltrBox, 3 * height, TextDirection.ltr, TextAlign.start); |
| paintMultSpanBidi(canvas, ltrBox, 4 * height, TextDirection.ltr, TextAlign.end); |
| |
| // Border for rtl paragraphs. |
| final Rect rtlBox = ltrBox.translate(ltrBox.width + 10, 0); |
| canvas.drawRect( |
| rtlBox, |
| SurfacePaintData() |
| ..color = black.value |
| ..style = PaintingStyle.stroke, |
| ); |
| // RTL with different text align values: |
| paintMultSpanBidi(canvas, rtlBox, 0 * height, TextDirection.rtl, TextAlign.left); |
| paintMultSpanBidi(canvas, rtlBox, 1 * height, TextDirection.rtl, TextAlign.right); |
| paintMultSpanBidi(canvas, rtlBox, 2 * height, TextDirection.rtl, TextAlign.center); |
| paintMultSpanBidi(canvas, rtlBox, 3 * height, TextDirection.rtl, TextAlign.start); |
| paintMultSpanBidi(canvas, rtlBox, 4 * height, TextDirection.rtl, TextAlign.end); |
| |
| return takeScreenshot(canvas, bounds, 'canvas_paragraph_bidi_multispan_dom'); |
| }); |
| |
| void paintBidiWithSelection( |
| EngineCanvas canvas, |
| Rect bounds, |
| double y, |
| TextDirection textDirection, |
| TextAlign textAlign, |
| ) { |
| // ''' |
| // Lorem 12 $_rtlWord1 |
| // $_rtlWord2 34 ipsum |
| // dolor 56 |
| // ''' |
| const String text = 'Lorem 12 $_rtlWord1 $_rtlWord2 34 ipsum dolor 56'; |
| |
| final EngineParagraphStyle paragraphStyle = EngineParagraphStyle( |
| fontFamily: 'Roboto', |
| fontSize: 20.0, |
| textDirection: textDirection, |
| textAlign: textAlign, |
| ); |
| final CanvasParagraph paragraph = plain( |
| paragraphStyle, |
| text, |
| textStyle: EngineTextStyle.only(color: blue), |
| ); |
| |
| final double maxWidth = bounds.width - 10; |
| paragraph.layout(constrain(maxWidth)); |
| |
| final Offset offset = Offset(bounds.left + 5, bounds.top + y + 5); |
| |
| // Range for "em 12 " and the first character of `_rtlWord1`. |
| fillBoxes(canvas, offset, paragraph.getBoxesForRange(3, 10), lightBlue); |
| // Range for the second half of `_rtlWord1` and all of `_rtlWord2` and " 3". |
| fillBoxes(canvas, offset, paragraph.getBoxesForRange(11, 21), lightPurple); |
| // Range for "psum dolo". |
| fillBoxes(canvas, offset, paragraph.getBoxesForRange(24, 33), green); |
| |
| canvas.drawParagraph(paragraph, offset); |
| } |
| |
| test('bidi with selection', () { |
| const Rect bounds = Rect.fromLTWH(0, 0, 400, 500); |
| final BitmapCanvas canvas = BitmapCanvas(bounds, RenderStrategy()); |
| |
| const double height = 95; |
| |
| // Border for ltr paragraphs. |
| final Rect ltrBox = const Rect.fromLTWH(0, 0, 150, 5 * height).inflate(5).translate(10, 10); |
| canvas.drawRect( |
| ltrBox, |
| SurfacePaintData() |
| ..color = black.value |
| ..style = PaintingStyle.stroke, |
| ); |
| // LTR with different text align values: |
| paintBidiWithSelection(canvas, ltrBox, 0 * height, TextDirection.ltr, TextAlign.left); |
| paintBidiWithSelection(canvas, ltrBox, 1 * height, TextDirection.ltr, TextAlign.right); |
| paintBidiWithSelection(canvas, ltrBox, 2 * height, TextDirection.ltr, TextAlign.center); |
| paintBidiWithSelection(canvas, ltrBox, 3 * height, TextDirection.ltr, TextAlign.start); |
| paintBidiWithSelection(canvas, ltrBox, 4 * height, TextDirection.ltr, TextAlign.end); |
| |
| // Border for rtl paragraphs. |
| final Rect rtlBox = ltrBox.translate(ltrBox.width + 10, 0); |
| canvas.drawRect( |
| rtlBox, |
| SurfacePaintData() |
| ..color = black.value |
| ..style = PaintingStyle.stroke, |
| ); |
| // RTL with different text align values: |
| paintBidiWithSelection(canvas, rtlBox, 0 * height, TextDirection.rtl, TextAlign.left); |
| paintBidiWithSelection(canvas, rtlBox, 1 * height, TextDirection.rtl, TextAlign.right); |
| paintBidiWithSelection(canvas, rtlBox, 2 * height, TextDirection.rtl, TextAlign.center); |
| paintBidiWithSelection(canvas, rtlBox, 3 * height, TextDirection.rtl, TextAlign.start); |
| paintBidiWithSelection(canvas, rtlBox, 4 * height, TextDirection.rtl, TextAlign.end); |
| |
| return takeScreenshot(canvas, bounds, 'canvas_paragraph_bidi_selection'); |
| }); |
| |
| test('bidi with selection (DOM)', () { |
| const Rect bounds = Rect.fromLTWH(0, 0, 400, 500); |
| final DomCanvas canvas = DomCanvas(domDocument.createElement('flt-picture')); |
| |
| const double height = 95; |
| |
| // Border for ltr paragraphs. |
| final Rect ltrBox = const Rect.fromLTWH(0, 0, 150, 5 * height).inflate(5).translate(10, 10); |
| canvas.drawRect( |
| ltrBox, |
| SurfacePaintData() |
| ..color = black.value |
| ..style = PaintingStyle.stroke, |
| ); |
| // LTR with different text align values: |
| paintBidiWithSelection(canvas, ltrBox, 0 * height, TextDirection.ltr, TextAlign.left); |
| paintBidiWithSelection(canvas, ltrBox, 1 * height, TextDirection.ltr, TextAlign.right); |
| paintBidiWithSelection(canvas, ltrBox, 2 * height, TextDirection.ltr, TextAlign.center); |
| paintBidiWithSelection(canvas, ltrBox, 3 * height, TextDirection.ltr, TextAlign.start); |
| paintBidiWithSelection(canvas, ltrBox, 4 * height, TextDirection.ltr, TextAlign.end); |
| |
| // Border for rtl paragraphs. |
| final Rect rtlBox = ltrBox.translate(ltrBox.width + 10, 0); |
| canvas.drawRect( |
| rtlBox, |
| SurfacePaintData() |
| ..color = black.value |
| ..style = PaintingStyle.stroke, |
| ); |
| // RTL with different text align values: |
| paintBidiWithSelection(canvas, rtlBox, 0 * height, TextDirection.rtl, TextAlign.left); |
| paintBidiWithSelection(canvas, rtlBox, 1 * height, TextDirection.rtl, TextAlign.right); |
| paintBidiWithSelection(canvas, rtlBox, 2 * height, TextDirection.rtl, TextAlign.center); |
| paintBidiWithSelection(canvas, rtlBox, 3 * height, TextDirection.rtl, TextAlign.start); |
| paintBidiWithSelection(canvas, rtlBox, 4 * height, TextDirection.rtl, TextAlign.end); |
| |
| return takeScreenshot(canvas, bounds, 'canvas_paragraph_bidi_selection_dom'); |
| }); |
| } |