From 33b31a4ffdd9d0dff0f5f1d68aa40e8f54350e77 Mon Sep 17 00:00:00 2001 From: Mouad Debbar Date: Mon, 26 Sep 2022 15:24:04 -0400 Subject: [PATCH 1/2] [web] Some cleanup for text tests --- lib/web_ui/lib/src/engine/engine_canvas.dart | 2 +- .../lib/src/engine/html/recording_canvas.dart | 2 +- .../lib/src/engine/text/canvas_paragraph.dart | 92 +++++-------------- .../lib/src/engine/text/layout_service.dart | 5 +- .../lib/src/engine/text/paint_service.dart | 19 ++-- lib/web_ui/lib/src/engine/text/paragraph.dart | 12 +-- .../test/html/paragraph/bidi_golden_test.dart | 4 - .../html/paragraph/general_golden_test.dart | 2 - lib/web_ui/test/html/paragraph/helper.dart | 18 +++- .../html/paragraph/overflow_golden_test.dart | 2 - .../paragraph/placeholders_golden_test.dart | 2 - .../paragraph/text_overflow_golden_test.dart | 2 - .../text_placeholders_golden_test.dart | 16 +--- .../test/html/paragraph/text_scuba.dart | 4 +- .../text/canvas_paragraph_builder_test.dart | 56 +++++------ .../test/text/canvas_paragraph_test.dart | 15 --- .../test/text/layout_fragmenter_test.dart | 17 ++-- .../test/text/layout_service_plain_test.dart | 23 +---- .../test/text/layout_service_rich_test.dart | 13 --- lib/web_ui/test/text/line_breaker_test.dart | 15 +-- 20 files changed, 97 insertions(+), 224 deletions(-) diff --git a/lib/web_ui/lib/src/engine/engine_canvas.dart b/lib/web_ui/lib/src/engine/engine_canvas.dart index ba956254ce40f..297319a082371 100644 --- a/lib/web_ui/lib/src/engine/engine_canvas.dart +++ b/lib/web_ui/lib/src/engine/engine_canvas.dart @@ -264,7 +264,7 @@ DomElement drawParagraphElement( }) { assert(paragraph.isLaidOut); - final DomHTMLElement paragraphElement = paragraph.toDomElement(); + final DomElement paragraphElement = paragraph.toDomElement(); if (transform != null) { setElementTransform( diff --git a/lib/web_ui/lib/src/engine/html/recording_canvas.dart b/lib/web_ui/lib/src/engine/html/recording_canvas.dart index 836ce83bb14a0..280ebbdc45bba 100644 --- a/lib/web_ui/lib/src/engine/html/recording_canvas.dart +++ b/lib/web_ui/lib/src/engine/html/recording_canvas.dart @@ -1246,7 +1246,7 @@ class PaintDrawParagraph extends DrawCommand { @override String toString() { if (assertionsEnabled) { - return 'DrawParagraph(${paragraph.toPlainText()}, $offset)'; + return 'DrawParagraph(${paragraph.plainText}, $offset)'; } else { return super.toString(); } diff --git a/lib/web_ui/lib/src/engine/text/canvas_paragraph.dart b/lib/web_ui/lib/src/engine/text/canvas_paragraph.dart index 59cfc57d0c0f7..272781147c78d 100644 --- a/lib/web_ui/lib/src/engine/text/canvas_paragraph.dart +++ b/lib/web_ui/lib/src/engine/text/canvas_paragraph.dart @@ -17,7 +17,7 @@ import 'word_breaker.dart'; const ui.Color _defaultTextColor = ui.Color(0xFFFF0000); -final String _placeholderChar = String.fromCharCode(0xFFFC); +final String placeholderChar = String.fromCharCode(0xFFFC); /// A paragraph made up of a flat list of text spans and placeholders. /// @@ -33,7 +33,6 @@ class CanvasParagraph implements ui.Paragraph { this.spans, { required this.paragraphStyle, required this.plainText, - required this.placeholderCount, required this.canDrawOnCanvas, }) : assert(spans.isNotEmpty); @@ -46,9 +45,6 @@ class CanvasParagraph implements ui.Paragraph { /// The full textual content of the paragraph. late String plainText; - /// The number of placeholders in this paragraph. - final int placeholderCount; - /// Whether this paragraph can be drawn on a bitmap canvas. /// /// Some text features cannot be rendered into a 2D canvas and must use HTML, @@ -87,8 +83,6 @@ class CanvasParagraph implements ui.Paragraph { /// Whether this paragraph has been laid out or not. bool isLaidOut = false; - bool get isRtl => paragraphStyle.effectiveTextDirection == ui.TextDirection.rtl; - ui.ParagraphConstraints? _lastUsedConstraints; late final TextLayoutService _layoutService = TextLayoutService(this); @@ -138,27 +132,23 @@ class CanvasParagraph implements ui.Paragraph { _paintService.paint(canvas, offset); } - /// Generates a flat string computed from all the spans of the paragraph. - String toPlainText() => plainText; - - DomHTMLElement? _cachedDomElement; + DomElement? _cachedDomElement; /// Returns a DOM element that represents the entire paragraph and its /// children. /// /// Generates a new DOM element on every invocation. - DomHTMLElement toDomElement() { + DomElement toDomElement() { assert(isLaidOut); - final DomHTMLElement? domElement = _cachedDomElement; + final DomElement? domElement = _cachedDomElement; if (domElement == null) { return _cachedDomElement ??= _createDomElement(); } - return domElement.cloneNode(true) as DomHTMLElement; + return domElement.cloneNode(true) as DomElement; } - DomHTMLElement _createDomElement() { - final DomHTMLElement rootElement = - domDocument.createElement('flt-paragraph') as DomHTMLElement; + DomElement _createDomElement() { + final DomElement rootElement = domDocument.createElement('flt-paragraph'); // 1. Set paragraph-level styles. @@ -183,12 +173,8 @@ class CanvasParagraph implements ui.Paragraph { continue; } - final DomHTMLElement spanElement = domDocument.createElement('flt-span') as DomHTMLElement; - applyTextStyleToElement( - element: spanElement, - style: fragment.style, - isSpan: true, - ); + final DomElement spanElement = domDocument.createElement('flt-span'); + applyTextStyleToElement(element: spanElement, style: fragment.style); _positionSpanElement(spanElement, line, fragment); spanElement.appendText(text); @@ -221,7 +207,6 @@ class CanvasParagraph implements ui.Paragraph { @override ui.TextRange getWordBoundary(ui.TextPosition position) { - final String text = toPlainText(); final int characterPosition; switch (position.affinity) { case ui.TextAffinity.upstream: @@ -231,8 +216,8 @@ class CanvasParagraph implements ui.Paragraph { characterPosition = position.offset; break; } - final int start = WordBreaker.prevBreakIndex(text, characterPosition + 1); - final int end = WordBreaker.nextBreakIndex(text, characterPosition); + final int start = WordBreaker.prevBreakIndex(plainText, characterPosition + 1); + final int end = WordBreaker.nextBreakIndex(plainText, characterPosition); return ui.TextRange(start: start, end: end); } @@ -288,51 +273,30 @@ void _positionSpanElement(DomElement element, ParagraphLine line, LayoutFragment ..lineHeight = '${boxRect.height}px'; } -/// A common interface for all types of spans that make up a paragraph. -/// -/// These spans are stored as a flat list in the paragraph object. -abstract class ParagraphSpan { - /// The index of the beginning of the range of text represented by this span. - int get start; - - /// The index of the end of the range of text represented by this span. - int get end; - - /// The resolved style of the span. - EngineTextStyle get style; -} - -/// Represent a span of text in the paragraph. -/// -/// It's a "flat" text span as opposed to the framework text spans that are -/// hierarchical. +/// Represents a span in the paragraph. /// /// Instead of keeping spans and styles in a tree hierarchy like the framework /// does, we flatten the structure and resolve/merge all the styles from parent /// nodes. -class FlatTextSpan implements ParagraphSpan { - /// Creates a [FlatTextSpan] with the given [style], representing the span of +/// +/// These spans are stored as a flat list in the paragraph object. +class ParagraphSpan { + /// Creates a [ParagraphSpan] with the given [style], representing the span of /// text in the range between [start] and [end]. - FlatTextSpan({ + ParagraphSpan({ required this.style, required this.start, required this.end, }); - @override + /// The resolved style of the span. final EngineTextStyle style; - @override + /// The index of the beginning of the range of text represented by this span. final int start; - @override + /// The index of the end of the range of text represented by this span. final int end; - - String textOf(CanvasParagraph paragraph) { - final String text = paragraph.toPlainText(); - assert(end <= text.length); - return text.substring(start, end); - } } class PlaceholderSpan extends ParagraphPlaceholder implements ParagraphSpan { @@ -622,16 +586,13 @@ class CanvasParagraphBuilder implements ui.ParagraphBuilder { double? baselineOffset, ui.TextBaseline? baseline, }) { - // TODO(mdebbar): for measurement of placeholders, look at: - // - https://github.com/flutter/engine/blob/c0f7e8acf9318d264ad6a235facd097de597ffcc/third_party/txt/src/txt/paragraph_txt.cc#L325-L350 - // Require a baseline to be specified if using a baseline-based alignment. assert(!(alignment == ui.PlaceholderAlignment.aboveBaseline || alignment == ui.PlaceholderAlignment.belowBaseline || alignment == ui.PlaceholderAlignment.baseline) || baseline != null); final int start = _plainTextBuffer.length; - _plainTextBuffer.write(_placeholderChar); + _plainTextBuffer.write(placeholderChar); final int end = _plainTextBuffer.length; final EngineTextStyle style = _currentStyleNode.resolveStyle(); @@ -674,7 +635,7 @@ class CanvasParagraphBuilder implements ui.ParagraphBuilder { final EngineTextStyle style = _currentStyleNode.resolveStyle(); _updateCanDrawOnCanvas(style); - _spans.add(FlatTextSpan(style: style, start: start, end: end)); + _spans.add(ParagraphSpan(style: style, start: start, end: end)); } void _updateCanDrawOnCanvas(EngineTextStyle style) { @@ -708,18 +669,15 @@ class CanvasParagraphBuilder implements ui.ParagraphBuilder { // // We want the paragraph to always have a non-empty list of spans to match // the expectations of the [LayoutFragmenter]. - _spans.add(FlatTextSpan( - style: _rootStyleNode.resolveStyle(), - start: 0, - end: 0, - )); + _spans.add( + ParagraphSpan(style: _rootStyleNode.resolveStyle(), start: 0, end: 0), + ); } return CanvasParagraph( _spans, paragraphStyle: _paragraphStyle, plainText: _plainTextBuffer.toString(), - placeholderCount: _placeholderCount, canDrawOnCanvas: _canDrawOnCanvas, ); } diff --git a/lib/web_ui/lib/src/engine/text/layout_service.dart b/lib/web_ui/lib/src/engine/text/layout_service.dart index b3bdb624ade32..b289abc13c5d1 100644 --- a/lib/web_ui/lib/src/engine/text/layout_service.dart +++ b/lib/web_ui/lib/src/engine/text/layout_service.dart @@ -360,7 +360,7 @@ class TextLayoutService { return []; } - final int length = paragraph.toPlainText().length; + final int length = paragraph.plainText.length; // Ranges that are out of bounds should return an empty list. if (start > length || end > length) { return []; @@ -1046,10 +1046,9 @@ class Spanometer { assert(start >= currentSpan.start && start <= currentSpan.end); assert(end >= currentSpan.start && end <= currentSpan.end); - final String text = paragraph.toPlainText(); return measureSubstring( context, - text, + paragraph.plainText, start, end, letterSpacing: letterSpacing, diff --git a/lib/web_ui/lib/src/engine/text/paint_service.dart b/lib/web_ui/lib/src/engine/text/paint_service.dart index 857d55a2d53f3..1fb4d688044ff 100644 --- a/lib/web_ui/lib/src/engine/text/paint_service.dart +++ b/lib/web_ui/lib/src/engine/text/paint_service.dart @@ -36,15 +36,16 @@ class TextPaintService { ui.Offset offset, LayoutFragment fragment, ) { - final ParagraphSpan span = fragment.span; - if (span is FlatTextSpan) { - // Paint the background of the box, if the span has a background. - final SurfacePaint? background = span.style.background as SurfacePaint?; - if (background != null) { - final ui.Rect rect = fragment.toPaintingTextBox().toRect(); - if (!rect.isEmpty) { - canvas.drawRect(rect.shift(offset), background.paintData); - } + if (fragment.isPlaceholder) { + return; + } + + // Paint the background of the box, if the span has a background. + final SurfacePaint? background = fragment.style.background as SurfacePaint?; + if (background != null) { + final ui.Rect rect = fragment.toPaintingTextBox().toRect(); + if (!rect.isEmpty) { + canvas.drawRect(rect.shift(offset), background.paintData); } } } diff --git a/lib/web_ui/lib/src/engine/text/paragraph.dart b/lib/web_ui/lib/src/engine/text/paragraph.dart index ef0d55961d06b..c24b476290049 100644 --- a/lib/web_ui/lib/src/engine/text/paragraph.dart +++ b/lib/web_ui/lib/src/engine/text/paragraph.dart @@ -774,13 +774,9 @@ String fontWeightIndexToCss({int fontWeightIndex = 3}) { /// Applies a text [style] to an [element], translating the properties to their /// corresponding CSS equivalents. -/// -/// If [isSpan] is true, the text element is a span within richtext and -/// should not assign effectiveFontFamily if fontFamily was not specified. void applyTextStyleToElement({ - required DomHTMLElement element, + required DomElement element, required EngineTextStyle style, - bool isSpan = false, }) { assert(element != null); assert(style != null); @@ -822,10 +818,10 @@ void applyTextStyleToElement({ } // For test environment use effectiveFontFamily since we need to // consistently use Ahem font. - if (isSpan && !ui.debugEmulateFlutterTesterEnvironment) { - cssStyle.fontFamily = canonicalizeFontFamily(style.fontFamily)!; - } else { + if (ui.debugEmulateFlutterTesterEnvironment) { cssStyle.fontFamily = canonicalizeFontFamily(style.effectiveFontFamily)!; + } else { + cssStyle.fontFamily = canonicalizeFontFamily(style.fontFamily)!; } if (style.letterSpacing != null) { cssStyle.letterSpacing = '${style.letterSpacing}px'; diff --git a/lib/web_ui/test/html/paragraph/bidi_golden_test.dart b/lib/web_ui/test/html/paragraph/bidi_golden_test.dart index fb25b1adf6202..e4d0f18e1dfe9 100644 --- a/lib/web_ui/test/html/paragraph/bidi_golden_test.dart +++ b/lib/web_ui/test/html/paragraph/bidi_golden_test.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:async'; - import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; @@ -12,8 +10,6 @@ import 'package:ui/ui.dart' hide window; import '../screenshot.dart'; import 'helper.dart'; -typedef CanvasTest = FutureOr Function(EngineCanvas canvas); - const String _rtlWord1 = 'واحد'; const String _rtlWord2 = 'اثنان'; diff --git a/lib/web_ui/test/html/paragraph/general_golden_test.dart b/lib/web_ui/test/html/paragraph/general_golden_test.dart index 4ad87aea5c0d2..caff7f814d466 100644 --- a/lib/web_ui/test/html/paragraph/general_golden_test.dart +++ b/lib/web_ui/test/html/paragraph/general_golden_test.dart @@ -13,8 +13,6 @@ import 'package:ui/ui.dart' hide window; import '../screenshot.dart'; import 'helper.dart'; -typedef CanvasTest = FutureOr Function(EngineCanvas canvas); - const Rect bounds = Rect.fromLTWH(0, 0, 800, 600); void main() { diff --git a/lib/web_ui/test/html/paragraph/helper.dart b/lib/web_ui/test/html/paragraph/helper.dart index fde2dd6d9165b..e9cb07f5b889a 100644 --- a/lib/web_ui/test/html/paragraph/helper.dart +++ b/lib/web_ui/test/html/paragraph/helper.dart @@ -2,10 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:async'; + import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart'; import 'package:web_engine_tester/golden_tester.dart'; +typedef CanvasTest = FutureOr Function(EngineCanvas canvas); + const LineBreakType prohibited = LineBreakType.prohibited; const LineBreakType opportunity = LineBreakType.opportunity; const LineBreakType mandatory = LineBreakType.mandatory; @@ -32,6 +36,11 @@ const Color blue = Color(0xFF0000FF); const Color yellow = Color(0xFFFFEB3B); const Color lightPurple = Color(0xFFE1BEE7); +final EngineParagraphStyle ahemStyle = EngineParagraphStyle( + fontFamily: 'ahem', + fontSize: 10, +); + ParagraphConstraints constrain(double width) { return ParagraphConstraints(width: width); } @@ -73,10 +82,7 @@ Future takeScreenshot( try { sceneElement.append(canvas.rootElement); domDocument.body!.append(sceneElement); - await matchGoldenFile( - '$fileName.png', - region: region, - ); + await matchGoldenFile('$fileName.png', region: region); } finally { // The page is reused across tests, so remove the element after taking the // Scuba screenshot. @@ -109,3 +115,7 @@ void fillBoxes(EngineCanvas canvas, Offset offset, List boxes, Color co canvas.drawRect(rect, SurfacePaintData()..color = color); } } + +String getSpanText(CanvasParagraph paragraph, ParagraphSpan span) { + return paragraph.plainText.substring(span.start, span.end); +} diff --git a/lib/web_ui/test/html/paragraph/overflow_golden_test.dart b/lib/web_ui/test/html/paragraph/overflow_golden_test.dart index 9f1e8bc7befd8..3e6e130a50723 100644 --- a/lib/web_ui/test/html/paragraph/overflow_golden_test.dart +++ b/lib/web_ui/test/html/paragraph/overflow_golden_test.dart @@ -12,8 +12,6 @@ import 'package:ui/ui.dart' hide window; import '../screenshot.dart'; import 'helper.dart'; -typedef CanvasTest = FutureOr Function(EngineCanvas canvas); - void main() { internalBootstrapBrowserTest(() => testMain); } diff --git a/lib/web_ui/test/html/paragraph/placeholders_golden_test.dart b/lib/web_ui/test/html/paragraph/placeholders_golden_test.dart index 073ce409b0b94..7f90cde8a3243 100644 --- a/lib/web_ui/test/html/paragraph/placeholders_golden_test.dart +++ b/lib/web_ui/test/html/paragraph/placeholders_golden_test.dart @@ -12,8 +12,6 @@ import 'package:ui/ui.dart' hide window; import '../screenshot.dart'; import 'helper.dart'; -typedef CanvasTest = FutureOr Function(EngineCanvas canvas); - const Rect bounds = Rect.fromLTWH(0, 0, 800, 600); void main() { diff --git a/lib/web_ui/test/html/paragraph/text_overflow_golden_test.dart b/lib/web_ui/test/html/paragraph/text_overflow_golden_test.dart index 46f5538387c84..a97bce79940f6 100644 --- a/lib/web_ui/test/html/paragraph/text_overflow_golden_test.dart +++ b/lib/web_ui/test/html/paragraph/text_overflow_golden_test.dart @@ -11,8 +11,6 @@ import 'package:ui/ui.dart' hide window; import '../screenshot.dart'; import 'text_scuba.dart'; -typedef CanvasTest = FutureOr Function(EngineCanvas canvas); - const String threeLines = 'First\nSecond\nThird'; const String veryLong = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'; diff --git a/lib/web_ui/test/html/paragraph/text_placeholders_golden_test.dart b/lib/web_ui/test/html/paragraph/text_placeholders_golden_test.dart index 37e456f4406f9..4474bba0b9f33 100644 --- a/lib/web_ui/test/html/paragraph/text_placeholders_golden_test.dart +++ b/lib/web_ui/test/html/paragraph/text_placeholders_golden_test.dart @@ -7,19 +7,13 @@ import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart'; import '../screenshot.dart'; +import 'helper.dart'; import 'text_scuba.dart'; -typedef PaintTest = void Function(RecordingCanvas recordingCanvas); - void main() { internalBootstrapBrowserTest(() => testMain); } -/// Whether we are running on iOS Safari. -// TODO(mdebbar): https://github.com/flutter/flutter/issues/66656 -bool get isIosSafari => browserEngine == BrowserEngine.webkit && - operatingSystem == OperatingSystem.iOs; - Future testMain() async { final EngineScubaTester scuba = await EngineScubaTester.initialize( viewportSize: const Size(600, 600), @@ -46,9 +40,7 @@ Future testMain() async { } recordingCanvas.endRecording(); recordingCanvas.apply(canvas, screenRect); - if (!isIosSafari) { - return scuba.diffCanvasScreenshot(canvas, 'text_with_placeholders'); - } + return scuba.diffCanvasScreenshot(canvas, 'text_with_placeholders'); }); testEachCanvas('text alignment and placeholders', (EngineCanvas canvas) { @@ -85,10 +77,6 @@ Future testMain() async { }); } -const Color black = Color(0xFF000000); -const Color blue = Color(0xFF0000FF); -const Color red = Color(0xFFFF0000); - const Size placeholderSize = Size(80.0, 50.0); void _paintTextWithPlaceholder( diff --git a/lib/web_ui/test/html/paragraph/text_scuba.dart b/lib/web_ui/test/html/paragraph/text_scuba.dart index 9bd21d7cc394e..1f2c5cbb352c6 100644 --- a/lib/web_ui/test/html/paragraph/text_scuba.dart +++ b/lib/web_ui/test/html/paragraph/text_scuba.dart @@ -10,6 +10,8 @@ import 'package:ui/ui.dart' as ui; import 'package:web_engine_tester/golden_tester.dart'; +import 'helper.dart'; + /// Class that controls some details of how screenshotting is made. /// /// (For Googlers: Not really related with internal Scuba anymore) @@ -85,8 +87,6 @@ class EngineScubaTester { } } -typedef CanvasTest = FutureOr Function(EngineCanvas canvas); - /// Runs the given test [body] with each type of canvas. void testEachCanvas(String description, CanvasTest body) { const ui.Rect bounds = ui.Rect.fromLTWH(0, 0, 600, 800); diff --git a/lib/web_ui/test/text/canvas_paragraph_builder_test.dart b/lib/web_ui/test/text/canvas_paragraph_builder_test.dart index 2a7040fddfdb1..b8d92315da7d2 100644 --- a/lib/web_ui/test/text/canvas_paragraph_builder_test.dart +++ b/lib/web_ui/test/text/canvas_paragraph_builder_test.dart @@ -9,10 +9,6 @@ import 'package:ui/ui.dart'; import '../html/paragraph/helper.dart'; -bool get isIosSafari => - browserEngine == BrowserEngine.webkit && - operatingSystem == OperatingSystem.iOs; - /// Some text measurements are sensitive to browser implementations. Position /// info in the following tests only pass in Chrome, they are slightly different /// on each browser. So we need to ignore position info on non-Chrome browsers @@ -67,7 +63,7 @@ Future testMain() async { final CanvasParagraph paragraph = builder.build(); expect(paragraph.paragraphStyle, style); - expect(paragraph.toPlainText(), 'Hello'); + expect(paragraph.plainText, 'Hello'); expect(paragraph.spans, hasLength(1)); paragraph.layout(const ParagraphConstraints(width: double.infinity)); @@ -97,10 +93,8 @@ Future testMain() async { ); final ParagraphSpan span = paragraph.spans.single; - expect(span, isA()); - final FlatTextSpan textSpan = span as FlatTextSpan; - expect(textSpan.textOf(paragraph), 'Hello'); - expect(textSpan.style, styleWithDefaults(fontSize: 13.0)); + expect(getSpanText(paragraph, span), 'Hello'); + expect(span.style, styleWithDefaults(fontSize: 13.0)); }); test('Correct defaults', () { @@ -111,7 +105,7 @@ Future testMain() async { final CanvasParagraph paragraph = builder.build(); expect(paragraph.paragraphStyle, style); - expect(paragraph.toPlainText(), 'Hello'); + expect(paragraph.plainText, 'Hello'); expect(paragraph.spans, hasLength(1)); paragraph.layout(const ParagraphConstraints(width: double.infinity)); @@ -125,8 +119,8 @@ Future testMain() async { ignorePositions: !isBlink, ); - final FlatTextSpan textSpan = paragraph.spans.single as FlatTextSpan; - expect(textSpan.style, styleWithDefaults()); + final ParagraphSpan span = paragraph.spans.single; + expect(span.style, styleWithDefaults()); }); test('Sets correct styles for max-lines', () { @@ -137,7 +131,7 @@ Future testMain() async { final CanvasParagraph paragraph = builder.build(); expect(paragraph.paragraphStyle, style); - expect(paragraph.toPlainText(), 'Hello'); + expect(paragraph.plainText, 'Hello'); paragraph.layout(const ParagraphConstraints(width: double.infinity)); expectOuterHtml( @@ -159,7 +153,7 @@ Future testMain() async { final CanvasParagraph paragraph = builder.build(); expect(paragraph.paragraphStyle, style); - expect(paragraph.toPlainText(), 'HelloWorld'); + expect(paragraph.plainText, 'HelloWorld'); paragraph.layout(const ParagraphConstraints(width: 100.0)); expectOuterHtml( @@ -190,7 +184,7 @@ Future testMain() async { builder.addText('Hello'); final CanvasParagraph paragraph = builder.build(); - expect(paragraph.toPlainText(), 'Hello'); + expect(paragraph.plainText, 'Hello'); expect(paragraph.spans, hasLength(1)); paragraph.layout(const ParagraphConstraints(width: double.infinity)); @@ -204,8 +198,8 @@ Future testMain() async { ignorePositions: !isBlink, ); - final FlatTextSpan span = paragraph.spans.single as FlatTextSpan; - expect(span.textOf(paragraph), 'Hello'); + final ParagraphSpan span = paragraph.spans.single; + expect(getSpanText(paragraph, span), 'Hello'); expect( span.style, styleWithDefaults( @@ -229,7 +223,7 @@ Future testMain() async { builder.addText(' world'); final CanvasParagraph paragraph = builder.build(); - expect(paragraph.toPlainText(), 'Hello world'); + expect(paragraph.plainText, 'Hello world'); expect(paragraph.spans, hasLength(2)); paragraph.layout(const ParagraphConstraints(width: double.infinity)); @@ -267,8 +261,8 @@ Future testMain() async { ignorePositions: !isBlink, ); - final FlatTextSpan hello = paragraph.spans.first as FlatTextSpan; - expect(hello.textOf(paragraph), 'Hello'); + final ParagraphSpan hello = paragraph.spans.first; + expect(getSpanText(paragraph, hello), 'Hello'); expect( hello.style, styleWithDefaults( @@ -277,8 +271,8 @@ Future testMain() async { ), ); - final FlatTextSpan world = paragraph.spans.last as FlatTextSpan; - expect(world.textOf(paragraph), ' world'); + final ParagraphSpan world = paragraph.spans.last; + expect(getSpanText(paragraph, world), ' world'); expect( world.style, styleWithDefaults( @@ -302,7 +296,7 @@ Future testMain() async { builder.addText('!'); final CanvasParagraph paragraph = builder.build(); - expect(paragraph.toPlainText(), 'Hello world!'); + expect(paragraph.plainText, 'Hello world!'); expect(paragraph.spans, hasLength(3)); paragraph.layout(const ParagraphConstraints(width: double.infinity)); @@ -325,8 +319,8 @@ Future testMain() async { ignorePositions: !isBlink, ); - final FlatTextSpan hello = paragraph.spans[0] as FlatTextSpan; - expect(hello.textOf(paragraph), 'Hello'); + final ParagraphSpan hello = paragraph.spans[0]; + expect(getSpanText(paragraph, hello), 'Hello'); expect( hello.style, styleWithDefaults( @@ -336,8 +330,8 @@ Future testMain() async { ), ); - final FlatTextSpan world = paragraph.spans[1] as FlatTextSpan; - expect(world.textOf(paragraph), ' world'); + final ParagraphSpan world = paragraph.spans[1]; + expect(getSpanText(paragraph, world), ' world'); expect( world.style, styleWithDefaults( @@ -347,8 +341,8 @@ Future testMain() async { ), ); - final FlatTextSpan bang = paragraph.spans[2] as FlatTextSpan; - expect(bang.textOf(paragraph), '!'); + final ParagraphSpan bang = paragraph.spans[2]; + expect(getSpanText(paragraph, bang), '!'); expect( bang.style, styleWithDefaults( @@ -368,7 +362,7 @@ Future testMain() async { builder.addText('ThirdLongLine'); final CanvasParagraph paragraph = builder.build(); - expect(paragraph.toPlainText(), 'First\nSecond ThirdLongLine'); + expect(paragraph.plainText, 'First\nSecond ThirdLongLine'); expect(paragraph.spans, hasLength(2)); // There's a new line between "First" and "Second", but "Second" and @@ -430,7 +424,7 @@ Future testMain() async { builder.addText('Third'); final CanvasParagraph paragraph = builder.build(); - expect(paragraph.toPlainText(), 'First Second Third'); + expect(paragraph.plainText, 'First Second Third'); expect(paragraph.spans, hasLength(3)); // The paragraph should take the font size and family from the span with the diff --git a/lib/web_ui/test/text/canvas_paragraph_test.dart b/lib/web_ui/test/text/canvas_paragraph_test.dart index c661016758f9d..c97ad8fb2b953 100644 --- a/lib/web_ui/test/text/canvas_paragraph_test.dart +++ b/lib/web_ui/test/text/canvas_paragraph_test.dart @@ -9,21 +9,6 @@ import 'package:ui/ui.dart' as ui; import '../html/paragraph/helper.dart'; -const ui.Color white = ui.Color(0xFFFFFFFF); -const ui.Color black = ui.Color(0xFF000000); -const ui.Color red = ui.Color(0xFFFF0000); -const ui.Color green = ui.Color(0xFF00FF00); -const ui.Color blue = ui.Color(0xFF0000FF); - -final EngineParagraphStyle ahemStyle = EngineParagraphStyle( - fontFamily: 'ahem', - fontSize: 10, -); - -ui.ParagraphConstraints constrain(double width) { - return ui.ParagraphConstraints(width: width); -} - void main() { internalBootstrapBrowserTest(() => testMain); } diff --git a/lib/web_ui/test/text/layout_fragmenter_test.dart b/lib/web_ui/test/text/layout_fragmenter_test.dart index 0c315ce01cd61..d9e619a0423e4 100644 --- a/lib/web_ui/test/text/layout_fragmenter_test.dart +++ b/lib/web_ui/test/text/layout_fragmenter_test.dart @@ -207,21 +207,19 @@ Future testMain() async { }, ); - final String placeholderChar = String.fromCharCode(0xFFFC); - expect(split(paragraph), <_Fragment>[ - _Fragment(placeholderChar, opportunity, ltr, ffLtr, null), + _Fragment(placeholderChar, opportunity, ltr, ffLtr, defaultStyle), _Fragment('Lorem', opportunity, ltr, ffLtr, style1), - _Fragment(placeholderChar, opportunity, ltr, ffLtr, null), + _Fragment(placeholderChar, opportunity, ltr, ffLtr, defaultStyle), _Fragment('ipsum', prohibited, ltr, ffLtr, style1), _Fragment('\n', mandatory, null, ffSandwich, style1, nl: 1, sp: 1), - _Fragment(placeholderChar, opportunity, ltr, ffLtr, null), + _Fragment(placeholderChar, opportunity, ltr, ffLtr, defaultStyle), _Fragment(rtlWord1, prohibited, rtl, ffRtl, style2), _Fragment(' ', opportunity, null, ffSandwich, style2, sp: 1), - _Fragment(placeholderChar, prohibited, ltr, ffLtr, null), + _Fragment(placeholderChar, prohibited, ltr, ffLtr, defaultStyle), _Fragment('\n', mandatory, null, ffSandwich, style2, nl: 1, sp: 1), _Fragment('sit', opportunity, ltr, ffLtr, style2), - _Fragment(placeholderChar, endOfText, ltr, ffLtr, null), + _Fragment(placeholderChar, endOfText, ltr, ffLtr, defaultStyle), ]); }); }); @@ -235,13 +233,12 @@ class _Fragment { }); factory _Fragment._fromLayoutFragment(String text, LayoutFragment layoutFragment) { - final ParagraphSpan span = layoutFragment.span; return _Fragment( text.substring(layoutFragment.start, layoutFragment.end), layoutFragment.type, layoutFragment.textDirection, layoutFragment.fragmentFlow, - span is FlatTextSpan ? span.style : null, + layoutFragment.style, nl: layoutFragment.trailingNewlines, sp: layoutFragment.trailingSpaces, ); @@ -251,7 +248,7 @@ class _Fragment { final LineBreakType type; final TextDirection? textDirection; final FragmentFlow fragmentFlow; - final EngineTextStyle? style; + final EngineTextStyle style; /// The number of trailing new line characters. final int nl; diff --git a/lib/web_ui/test/text/layout_service_plain_test.dart b/lib/web_ui/test/text/layout_service_plain_test.dart index 777c80c11e4da..e67291e6ad958 100644 --- a/lib/web_ui/test/text/layout_service_plain_test.dart +++ b/lib/web_ui/test/text/layout_service_plain_test.dart @@ -7,32 +7,11 @@ import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart' as ui; +import '../html/paragraph/helper.dart'; import 'layout_service_helper.dart'; const bool skipWordSpacing = true; -final EngineParagraphStyle ahemStyle = EngineParagraphStyle( - fontFamily: 'ahem', - fontSize: 10, -); - -ui.ParagraphConstraints constrain(double width) { - return ui.ParagraphConstraints(width: width); -} - -CanvasParagraph plain( - EngineParagraphStyle style, - String text, { - EngineTextStyle? textStyle, -}) { - final CanvasParagraphBuilder builder = CanvasParagraphBuilder(style); - if (textStyle != null) { - builder.pushStyle(textStyle); - } - builder.addText(text); - return builder.build(); -} - void main() { internalBootstrapBrowserTest(() => testMain); } diff --git a/lib/web_ui/test/text/layout_service_rich_test.dart b/lib/web_ui/test/text/layout_service_rich_test.dart index f1d38160c431b..9843d154bf8a2 100644 --- a/lib/web_ui/test/text/layout_service_rich_test.dart +++ b/lib/web_ui/test/text/layout_service_rich_test.dart @@ -11,19 +11,6 @@ import 'package:ui/ui.dart' as ui; import '../html/paragraph/helper.dart'; import 'layout_service_helper.dart'; -final String placeholderChar = String.fromCharCode(0xFFFC); - -const ui.Color white = ui.Color(0xFFFFFFFF); -const ui.Color black = ui.Color(0xFF000000); -const ui.Color red = ui.Color(0xFFFF0000); -const ui.Color green = ui.Color(0xFF00FF00); -const ui.Color blue = ui.Color(0xFF0000FF); - -final EngineParagraphStyle ahemStyle = EngineParagraphStyle( - fontFamily: 'ahem', - fontSize: 10, -); - void main() { internalBootstrapBrowserTest(() => testMain); } diff --git a/lib/web_ui/test/text/line_breaker_test.dart b/lib/web_ui/test/text/line_breaker_test.dart index b536bd4c7b5fe..9f2a684c6210f 100644 --- a/lib/web_ui/test/text/line_breaker_test.dart +++ b/lib/web_ui/test/text/line_breaker_test.dart @@ -12,8 +12,6 @@ import '../html/paragraph/helper.dart'; import 'line_breaker_test_helper.dart'; import 'line_breaker_test_raw_data.dart'; -final String placeholderChar = String.fromCharCode(0xFFFC); - void main() { internalBootstrapBrowserTest(() => testMain); } @@ -237,7 +235,7 @@ void testMain() { final String placeholderChar = String.fromCharCode(0xFFFC); - expect(splitParagraph(paragraph), [ + expect(split(paragraph.plainText), [ Line(placeholderChar, opportunity), Line('Lorem', opportunity), Line(placeholderChar, opportunity), @@ -260,7 +258,7 @@ void testMain() { final String placeholderChar = String.fromCharCode(0xFFFC); - expect(splitParagraph(paragraph), [ + expect(split(paragraph.plainText), [ Line(placeholderChar, endOfText), ]); }); @@ -279,7 +277,7 @@ void testMain() { }, ); - expect(splitParagraph(paragraph), [ + expect(split(paragraph.plainText), [ Line('$placeholderChar ', opportunity, sp: 2), Line('Lorem ', opportunity, sp: 2), Line('$placeholderChar \n', mandatory, nl: 1, sp: 3), @@ -456,10 +454,3 @@ List split(String text) { Line.fromLineBreakFragment(text, fragment) ]; } - -List splitParagraph(CanvasParagraph paragraph) { - return [ - for (final LineBreakFragment fragment in LineBreakFragmenter(paragraph.plainText).fragment()) - Line.fromLineBreakFragment(paragraph.toPlainText(), fragment) - ]; -} From 90e1b4ca0b7d1f7c5d346f8a31884799f731db4c Mon Sep 17 00:00:00 2001 From: Mouad Debbar Date: Wed, 19 Oct 2022 10:20:18 -0400 Subject: [PATCH 2/2] fix test --- lib/web_ui/test/text/layout_fragmenter_test.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/web_ui/test/text/layout_fragmenter_test.dart b/lib/web_ui/test/text/layout_fragmenter_test.dart index d9e619a0423e4..a36dc89433db7 100644 --- a/lib/web_ui/test/text/layout_fragmenter_test.dart +++ b/lib/web_ui/test/text/layout_fragmenter_test.dart @@ -208,15 +208,15 @@ Future testMain() async { ); expect(split(paragraph), <_Fragment>[ - _Fragment(placeholderChar, opportunity, ltr, ffLtr, defaultStyle), + _Fragment(placeholderChar, opportunity, ltr, ffLtr, style1), _Fragment('Lorem', opportunity, ltr, ffLtr, style1), - _Fragment(placeholderChar, opportunity, ltr, ffLtr, defaultStyle), + _Fragment(placeholderChar, opportunity, ltr, ffLtr, style1), _Fragment('ipsum', prohibited, ltr, ffLtr, style1), _Fragment('\n', mandatory, null, ffSandwich, style1, nl: 1, sp: 1), - _Fragment(placeholderChar, opportunity, ltr, ffLtr, defaultStyle), + _Fragment(placeholderChar, opportunity, ltr, ffLtr, style1), _Fragment(rtlWord1, prohibited, rtl, ffRtl, style2), _Fragment(' ', opportunity, null, ffSandwich, style2, sp: 1), - _Fragment(placeholderChar, prohibited, ltr, ffLtr, defaultStyle), + _Fragment(placeholderChar, prohibited, ltr, ffLtr, style2), _Fragment('\n', mandatory, null, ffSandwich, style2, nl: 1, sp: 1), _Fragment('sit', opportunity, ltr, ffLtr, style2), _Fragment(placeholderChar, endOfText, ltr, ffLtr, defaultStyle),