From a7776ae195e154bffab498c954f0f0b1b7270006 Mon Sep 17 00:00:00 2001 From: Mouad Debbar Date: Mon, 10 Jan 2022 12:22:24 -0500 Subject: [PATCH] [web] Remove EngineParagraph and ParagraphGeometricStyle --- lib/web_ui/lib/src/engine/engine_canvas.dart | 6 +- .../lib/src/engine/html/bitmap_canvas.dart | 4 +- .../lib/src/engine/html/dom_canvas.dart | 4 +- .../lib/src/engine/html/recording_canvas.dart | 6 +- .../lib/src/engine/text/canvas_paragraph.dart | 18 ++- lib/web_ui/lib/src/engine/text/paragraph.dart | 26 --- lib/web_ui/lib/src/engine/text/ruler.dart | 150 +----------------- .../test/html/bitmap_canvas_golden_test.dart | 6 +- .../paragraph/text_overflow_golden_test.dart | 2 +- .../test/html/paragraph/text_scuba.dart | 4 +- 10 files changed, 28 insertions(+), 198 deletions(-) diff --git a/lib/web_ui/lib/src/engine/engine_canvas.dart b/lib/web_ui/lib/src/engine/engine_canvas.dart index 258ced6479440..13e75c36dee8e 100644 --- a/lib/web_ui/lib/src/engine/engine_canvas.dart +++ b/lib/web_ui/lib/src/engine/engine_canvas.dart @@ -12,7 +12,7 @@ import 'package:ui/ui.dart' as ui; import 'html/painting.dart'; import 'html/render_vertices.dart'; -import 'text/paragraph.dart'; +import 'text/canvas_paragraph.dart'; import 'util.dart'; import 'vector_math.dart'; @@ -76,7 +76,7 @@ abstract class EngineCanvas { void drawImageRect( ui.Image image, ui.Rect src, ui.Rect dst, SurfacePaintData paint); - void drawParagraph(EngineParagraph paragraph, ui.Offset offset); + void drawParagraph(CanvasParagraph paragraph, ui.Offset offset); void drawVertices( SurfaceVertices vertices, ui.BlendMode blendMode, SurfacePaintData paint); @@ -258,7 +258,7 @@ mixin SaveStackTracking on EngineCanvas { } html.Element drawParagraphElement( - EngineParagraph paragraph, + CanvasParagraph paragraph, ui.Offset offset, { Matrix4? transform, }) { diff --git a/lib/web_ui/lib/src/engine/html/bitmap_canvas.dart b/lib/web_ui/lib/src/engine/html/bitmap_canvas.dart index 17a3ff8cd0937..9b7bb4a011282 100644 --- a/lib/web_ui/lib/src/engine/html/bitmap_canvas.dart +++ b/lib/web_ui/lib/src/engine/html/bitmap_canvas.dart @@ -16,7 +16,7 @@ import '../engine_canvas.dart'; import '../frame_reference.dart'; import '../html_image_codec.dart'; import '../platform_dispatcher.dart'; -import '../text/paragraph.dart'; +import '../text/canvas_paragraph.dart'; import '../util.dart'; import '../vector_math.dart'; import '../window.dart'; @@ -936,7 +936,7 @@ class BitmapCanvas extends EngineCanvas { } @override - void drawParagraph(EngineParagraph paragraph, ui.Offset offset) { + void drawParagraph(CanvasParagraph paragraph, ui.Offset offset) { assert(paragraph.isLaidOut); /// - paragraph.drawOnCanvas checks that the text styling doesn't include diff --git a/lib/web_ui/lib/src/engine/html/dom_canvas.dart b/lib/web_ui/lib/src/engine/html/dom_canvas.dart index 3c769a9ed3a75..0d3250e27586b 100644 --- a/lib/web_ui/lib/src/engine/html/dom_canvas.dart +++ b/lib/web_ui/lib/src/engine/html/dom_canvas.dart @@ -12,7 +12,7 @@ import 'package:ui/ui.dart' as ui; import '../browser_detection.dart'; import '../engine_canvas.dart'; import '../html_image_codec.dart'; -import '../text/paragraph.dart'; +import '../text/canvas_paragraph.dart'; import '../util.dart'; import '../vector_math.dart'; import 'painting.dart'; @@ -127,7 +127,7 @@ class DomCanvas extends EngineCanvas with SaveElementStackTracking { @override void drawParagraph(ui.Paragraph paragraph, ui.Offset offset) { final html.Element paragraphElement = drawParagraphElement( - paragraph as EngineParagraph, offset, + paragraph as CanvasParagraph, offset, transform: currentTransform); currentElement.append(paragraphElement); } 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 b581557496082..13bfed38d5fef 100644 --- a/lib/web_ui/lib/src/engine/html/recording_canvas.dart +++ b/lib/web_ui/lib/src/engine/html/recording_canvas.dart @@ -11,7 +11,7 @@ import '../engine_canvas.dart'; import '../picture.dart'; import '../rrect_renderer.dart'; import '../shadow.dart'; -import '../text/paragraph.dart'; +import '../text/canvas_paragraph.dart'; import '../util.dart'; import '../vector_math.dart'; import 'bitmap_canvas.dart'; @@ -584,7 +584,7 @@ class RecordingCanvas { void drawParagraph(ui.Paragraph paragraph, ui.Offset offset) { assert(!_recordingEnded); - final EngineParagraph engineParagraph = paragraph as EngineParagraph; + final CanvasParagraph engineParagraph = paragraph as CanvasParagraph; if (!engineParagraph.isLaidOut) { // Ignore non-laid out paragraphs. This matches Flutter's behavior. return; @@ -1238,7 +1238,7 @@ class PaintDrawImageRect extends DrawCommand { } class PaintDrawParagraph extends DrawCommand { - final EngineParagraph paragraph; + final CanvasParagraph paragraph; final ui.Offset offset; PaintDrawParagraph(this.paragraph, this.offset); 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 84bf98cbec18b..309679a0839a5 100644 --- a/lib/web_ui/lib/src/engine/text/canvas_paragraph.dart +++ b/lib/web_ui/lib/src/engine/text/canvas_paragraph.dart @@ -22,7 +22,7 @@ const ui.Color _defaultTextColor = ui.Color(0xFFFF0000); /// [CanvasParagraph] doesn't use a DOM element to represent the structure of /// its spans and styles. Instead it uses a flat list of [ParagraphSpan] /// objects. -class CanvasParagraph implements EngineParagraph { +class CanvasParagraph implements ui.Paragraph { /// This class is created by the engine, and should not be instantiated /// or extended directly. /// @@ -47,7 +47,7 @@ class CanvasParagraph implements EngineParagraph { /// The number of placeholders in this paragraph. final int placeholderCount; - @override + /// Whether this paragraph can be drawn on a bitmap canvas. final bool drawOnCanvas; @override @@ -74,7 +74,7 @@ class CanvasParagraph implements EngineParagraph { @override bool get didExceedMaxLines => _layoutService.didExceedMaxLines; - @override + /// Whether this paragraph has been laid out or not. bool isLaidOut = false; bool get isRtl => paragraphStyle.effectiveTextDirection == ui.TextDirection.rtl; @@ -119,20 +119,24 @@ class CanvasParagraph implements EngineParagraph { // TODO(mdebbar): Returning true means we always require a bitmap canvas. Revisit // this decision once `CanvasParagraph` is fully implemented. - @override + /// Whether this paragraph is doing arbitrary paint operations that require + /// a bitmap canvas, and can't be expressed in a DOM canvas. bool get hasArbitraryPaint => true; - @override + /// Paints this paragraph instance on a [canvas] at the given [offset]. void paint(BitmapCanvas canvas, ui.Offset offset) { _paintService.paint(canvas, offset); } - @override + /// Generates a flat string computed from all the spans of the paragraph. String toPlainText() => plainText; html.HtmlElement? _cachedDomElement; - @override + /// Returns a DOM element that represents the entire paragraph and its + /// children. + /// + /// Generates a new DOM element on every invocation. html.HtmlElement toDomElement() { assert(isLaidOut); final html.HtmlElement? domElement = _cachedDomElement; diff --git a/lib/web_ui/lib/src/engine/text/paragraph.dart b/lib/web_ui/lib/src/engine/text/paragraph.dart index dea366f081a69..58f1e97487e44 100644 --- a/lib/web_ui/lib/src/engine/text/paragraph.dart +++ b/lib/web_ui/lib/src/engine/text/paragraph.dart @@ -9,7 +9,6 @@ import 'package:ui/ui.dart' as ui; import '../browser_detection.dart'; import '../embedder.dart'; -import '../html/bitmap_canvas.dart'; import '../util.dart'; import 'layout_service.dart'; import 'ruler.dart'; @@ -182,31 +181,6 @@ class EngineLineMetrics implements ui.LineMetrics { } } -/// Common interface for all the implementations of [ui.Paragraph] in the web -/// engine. -abstract class EngineParagraph implements ui.Paragraph { - /// Whether this paragraph has been laid out or not. - bool get isLaidOut; - - /// Whether this paragraph can be drawn on a bitmap canvas. - bool get drawOnCanvas; - - /// Whether this paragraph is doing arbitrary paint operations that require - /// a bitmap canvas, and can't be expressed in a DOM canvas. - bool get hasArbitraryPaint; - - void paint(BitmapCanvas canvas, ui.Offset offset); - - /// Generates a flat string computed from all the spans of the paragraph. - String toPlainText(); - - /// Returns a DOM element that represents the entire paragraph and its - /// children. - /// - /// Generates a new DOM element on every invocation. - html.HtmlElement toDomElement(); -} - /// The web implementation of [ui.ParagraphStyle]. class EngineParagraphStyle implements ui.ParagraphStyle { /// Creates a new instance of [EngineParagraphStyle]. diff --git a/lib/web_ui/lib/src/engine/text/ruler.dart b/lib/web_ui/lib/src/engine/text/ruler.dart index 9ef928d15a1e6..1bb267b91c80b 100644 --- a/lib/web_ui/lib/src/engine/text/ruler.dart +++ b/lib/web_ui/lib/src/engine/text/ruler.dart @@ -47,157 +47,9 @@ String buildCssFontString({ return result.toString(); } -/// Contains the subset of [ui.ParagraphStyle] properties that affect layout. -class ParagraphGeometricStyle { - ParagraphGeometricStyle({ - required this.textDirection, - required this.textAlign, - this.fontWeight, - this.fontStyle, - this.fontFamily, - this.fontSize, - this.lineHeight, - this.maxLines, - this.letterSpacing, - this.wordSpacing, - this.decoration, - this.ellipsis, - this.shadows, - }); - - final ui.TextDirection textDirection; - final ui.TextAlign textAlign; - final ui.FontWeight? fontWeight; - final ui.FontStyle? fontStyle; - final String? fontFamily; - final double? fontSize; - final double? lineHeight; - final int? maxLines; - final double? letterSpacing; - final double? wordSpacing; - final String? decoration; - final String? ellipsis; - final List? shadows; - - // Since all fields above are primitives, cache hashcode since ruler lookups - // use this style as key. - int? _cachedHashCode; - - /// Returns the font-family that should be used to style the paragraph. It may - /// or may not be different from [fontFamily]: - /// - /// - Always returns "Ahem" in tests. - /// - Provides correct defaults when [fontFamily] doesn't have a value. - String get effectiveFontFamily { - if (assertionsEnabled) { - // In widget tests we use a predictable-size font "Ahem". This makes - // widget tests predictable and less flaky. - if (ui.debugEmulateFlutterTesterEnvironment) { - return 'Ahem'; - } - } - final String? localFontFamily = fontFamily; - if (localFontFamily == null || localFontFamily.isEmpty) { - return FlutterViewEmbedder.defaultFontFamily; - } - return localFontFamily; - } - - String? _cssFontString; - - /// Cached font string that can be used in CSS. - /// - /// See . - String get cssFontString { - return _cssFontString ??= buildCssFontString( - fontStyle: fontStyle, - fontWeight: fontWeight, - fontSize: fontSize, - fontFamily: effectiveFontFamily, - ); - } - - TextHeightStyle? _cachedHeightStyle; - - TextHeightStyle get textHeightStyle { - TextHeightStyle? style = _cachedHeightStyle; - if (style == null) { - style = TextHeightStyle( - fontFamily: effectiveFontFamily, - fontSize: fontSize ?? FlutterViewEmbedder.defaultFontSize, - height: lineHeight, - // TODO(mdebbar): Pass the actual value when font features become supported - // https://github.com/flutter/flutter/issues/64595 - fontFeatures: null, - ); - _cachedHeightStyle = style; - } - return style; - } - - @override - bool operator ==(Object other) { - if (identical(this, other)) { - return true; - } - if (other.runtimeType != runtimeType) { - return false; - } - return other is ParagraphGeometricStyle - && other.textDirection == textDirection - && other.textAlign == textAlign - && other.fontWeight == fontWeight - && other.fontStyle == fontStyle - && other.fontFamily == fontFamily - && other.fontSize == fontSize - && other.lineHeight == lineHeight - && other.maxLines == maxLines - && other.letterSpacing == letterSpacing - && other.wordSpacing == wordSpacing - && other.decoration == decoration - && other.ellipsis == ellipsis; - } - - @override - int get hashCode => _cachedHashCode ??= ui.hashValues( - textDirection, - textAlign, - fontWeight, - fontStyle, - fontFamily, - fontSize, - lineHeight, - maxLines, - letterSpacing, - wordSpacing, - decoration, - ellipsis, - ); - - @override - String toString() { - if (assertionsEnabled) { - return '$runtimeType(textDirection: $textDirection, textAlign: $textAlign,' - ' fontWeight: $fontWeight,' - ' fontStyle: $fontStyle,' - ' fontFamily: $fontFamily, fontSize: $fontSize,' - ' lineHeight: $lineHeight,' - ' maxLines: $maxLines,' - ' letterSpacing: $letterSpacing,' - ' wordSpacing: $wordSpacing,' - ' decoration: $decoration,' - ' ellipsis: $ellipsis,' - ')'; - } else { - return super.toString(); - } - } -} - /// Contains all styles that have an effect on the height of text. /// -/// This is useful as a cache key for [TextHeightRuler]. It's more efficient -/// than using the entire [ParagraphGeometricStyle] as a cache key. +/// This is useful as a cache key for [TextHeightRuler]. class TextHeightStyle { TextHeightStyle({ required this.fontFamily, diff --git a/lib/web_ui/test/html/bitmap_canvas_golden_test.dart b/lib/web_ui/test/html/bitmap_canvas_golden_test.dart index 4521c6c700857..5e339c8615274 100644 --- a/lib/web_ui/test/html/bitmap_canvas_golden_test.dart +++ b/lib/web_ui/test/html/bitmap_canvas_golden_test.dart @@ -147,9 +147,9 @@ Future testMain() async { // // More details: https://github.com/flutter/flutter/issues/32274 test('renders clipped DOM text with high quality', () async { - final EngineParagraph paragraph = + final CanvasParagraph paragraph = (ParagraphBuilder(ParagraphStyle(fontFamily: 'Roboto')) - ..addText('Am I blurry?')).build() as EngineParagraph; + ..addText('Am I blurry?')).build() as CanvasParagraph; paragraph.layout(const ParagraphConstraints(width: 1000)); final Rect canvasSize = Rect.fromLTRB( @@ -199,7 +199,7 @@ Future testMain() async { 'breaks into multiple lines.'; builder.addText(text); - final EngineParagraph paragraph = builder.build() as EngineParagraph; + final CanvasParagraph paragraph = builder.build() as CanvasParagraph; paragraph.layout(const ParagraphConstraints(width: 100)); final Rect canvasSize = Offset.zero & const Size(500, 500); 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 234df6027d4c0..4ab9588d30b06 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 @@ -30,7 +30,7 @@ Future testMain() async { testEachCanvas('maxLines clipping', (EngineCanvas canvas) { Offset offset = Offset.zero; - EngineParagraph p; + CanvasParagraph p; // All three lines are rendered. p = paragraph(threeLines); diff --git a/lib/web_ui/test/html/paragraph/text_scuba.dart b/lib/web_ui/test/html/paragraph/text_scuba.dart index 6766456f43ffa..178e30bc6dbf8 100644 --- a/lib/web_ui/test/html/paragraph/text_scuba.dart +++ b/lib/web_ui/test/html/paragraph/text_scuba.dart @@ -108,7 +108,7 @@ final ui.TextStyle _defaultTextStyle = ui.TextStyle( fontSize: 14, ); -EngineParagraph paragraph( +CanvasParagraph paragraph( String text, { ui.ParagraphStyle? paragraphStyle, ui.TextStyle? textStyle, @@ -119,7 +119,7 @@ EngineParagraph paragraph( builder.pushStyle(textStyle ?? _defaultTextStyle); builder.addText(text); builder.pop(); - final EngineParagraph paragraph = builder.build() as EngineParagraph; + final CanvasParagraph paragraph = builder.build() as CanvasParagraph; paragraph.layout(ui.ParagraphConstraints(width: maxWidth)); return paragraph; }