From 9b686cc7d762fb46f7207232ac58294d7b1ffc4d Mon Sep 17 00:00:00 2001 From: Mouad Debbar Date: Mon, 19 Apr 2021 14:35:56 -0700 Subject: [PATCH 1/2] [web] Migrate paragraph-related files to their own libs --- lib/web_ui/lib/src/engine.dart | 63 +- .../lib/src/engine/html/bitmap_canvas.dart | 40 +- .../lib/src/engine/html/scene_builder.dart | 4 +- .../lib/src/engine/platform_dispatcher.dart | 6 +- lib/web_ui/lib/src/engine/profiler.dart | 19 +- .../lib/src/engine/text/canvas_paragraph.dart | 94 +-- .../lib/src/engine/text/layout_service.dart | 34 +- .../engine/text/line_break_properties.dart | 2 +- .../lib/src/engine/text/line_breaker.dart | 6 +- .../lib/src/engine/text/measurement.dart | 110 +-- .../lib/src/engine/text/paint_service.dart | 23 +- lib/web_ui/lib/src/engine/text/paragraph.dart | 633 +++++++++--------- lib/web_ui/lib/src/engine/text/ruler.dart | 46 +- .../lib/src/engine/text/unicode_range.dart | 2 - .../engine/text/word_break_properties.dart | 2 +- .../lib/src/engine/text/word_breaker.dart | 5 +- lib/web_ui/tool/unicode_sync_script.dart | 2 +- 17 files changed, 582 insertions(+), 509 deletions(-) diff --git a/lib/web_ui/lib/src/engine.dart b/lib/web_ui/lib/src/engine.dart index 2c05b2db74069..f6cd187d1c416 100644 --- a/lib/web_ui/lib/src/engine.dart +++ b/lib/web_ui/lib/src/engine.dart @@ -115,6 +115,9 @@ export 'engine/pointer_binding.dart'; // import 'engine/pointer_converter.dart'; export 'engine/pointer_converter.dart'; +import 'engine/profiler.dart'; +export 'engine/profiler.dart'; + // This import is intentionally commented out because the analyzer says it's unused. // import 'engine/services/buffers.dart'; export 'engine/services/buffers.dart'; @@ -135,6 +138,48 @@ export 'engine/shadow.dart'; import 'engine/test_embedding.dart'; export 'engine/test_embedding.dart'; +import 'engine/text/layout_service.dart'; +export 'engine/text/layout_service.dart'; + +// This import is intentionally commented out because the analyzer says it's unused. +// import 'engine/text/line_break_properties.dart'; +export 'engine/text/line_break_properties.dart'; + +// This import is intentionally commented out because the analyzer says it's unused. +// import 'engine/text/line_breaker.dart'; +export 'engine/text/line_breaker.dart'; + +import 'engine/text/measurement.dart'; +export 'engine/text/measurement.dart'; + +// This import is intentionally commented out because the analyzer says it's unused. +// import 'engine/text/paint_service.dart'; +export 'engine/text/paint_service.dart'; + +import 'engine/text/paragraph.dart'; +export 'engine/text/paragraph.dart'; + +// This import is intentionally commented out because the analyzer says it's unused. +// import 'engine/text/canvas_paragraph.dart'; +export 'engine/text/canvas_paragraph.dart'; + +// This import is intentionally commented out because the analyzer says it's unused. +// import 'engine/text/ruler.dart'; +export 'engine/text/ruler.dart'; + +// This import is intentionally commented out because the analyzer says it's unused. +// import 'engine/text/unicode_range.dart'; +export 'engine/text/unicode_range.dart'; + +// This import is intentionally commented out because the analyzer says it's unused. +// import 'engine/text/word_break_properties.dart'; +export 'engine/text/word_break_properties.dart'; + +// This import is intentionally commented out because the analyzer says it's unused. +// import 'engine/text/word_breaker.dart'; +export 'engine/text/word_breaker.dart'; + + import 'engine/util.dart'; export 'engine/util.dart'; @@ -253,7 +298,6 @@ part 'engine/platform_views.dart'; part 'engine/platform_views/content_manager.dart'; part 'engine/platform_views/message_handler.dart'; part 'engine/platform_views/slots.dart'; -part 'engine/profiler.dart'; part 'engine/rrect_renderer.dart'; part 'engine/semantics/accessibility.dart'; part 'engine/semantics/checkable.dart'; @@ -267,17 +311,6 @@ part 'engine/semantics/semantics_helper.dart'; part 'engine/semantics/tappable.dart'; part 'engine/semantics/text_field.dart'; part 'engine/text/font_collection.dart'; -part 'engine/text/layout_service.dart'; -part 'engine/text/line_break_properties.dart'; -part 'engine/text/line_breaker.dart'; -part 'engine/text/measurement.dart'; -part 'engine/text/paint_service.dart'; -part 'engine/text/paragraph.dart'; -part 'engine/text/canvas_paragraph.dart'; -part 'engine/text/ruler.dart'; -part 'engine/text/unicode_range.dart'; -part 'engine/text/word_break_properties.dart'; -part 'engine/text/word_breaker.dart'; part 'engine/text_editing/autofill_hint.dart'; part 'engine/text_editing/input_type.dart'; part 'engine/text_editing/text_capitalization.dart'; @@ -364,7 +397,7 @@ void initializeEngine() { if (!waitingForAnimation) { waitingForAnimation = true; html.window.requestAnimationFrame((num highResTime) { - _frameTimingsOnVsync(); + frameTimingsOnVsync(); // Reset immediately, because `frameHandler` can schedule more frames. waitingForAnimation = false; @@ -379,10 +412,10 @@ void initializeEngine() { // In Flutter terminology "building a frame" consists of "beginning // frame" and "drawing frame". // - // We do not call `_frameTimingsOnBuildFinish` from here because + // We do not call `frameTimingsOnBuildFinish` from here because // part of the rasterization process, particularly in the HTML // renderer, takes place in the `SceneBuilder.build()`. - _frameTimingsOnBuildStart(); + frameTimingsOnBuildStart(); if (EnginePlatformDispatcher.instance._onBeginFrame != null) { EnginePlatformDispatcher.instance.invokeOnBeginFrame( Duration(microseconds: highResTimeMicroseconds)); 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 7029f37396c9d..a2e6584f69339 100644 --- a/lib/web_ui/lib/src/engine/html/bitmap_canvas.dart +++ b/lib/web_ui/lib/src/engine/html/bitmap_canvas.dart @@ -241,11 +241,11 @@ class BitmapCanvas extends EngineCanvas { } /// Sets the global paint styles to correspond to [paint]. - void _setUpPaint(SurfacePaintData paint, ui.Rect? shaderBounds) { + void setUpPaint(SurfacePaintData paint, ui.Rect? shaderBounds) { _canvasPool.contextHandle.setUpPaint(paint, shaderBounds); } - void _tearDownPaint() { + void tearDownPaint() { _canvasPool.contextHandle.tearDownPaint(); } @@ -383,9 +383,9 @@ class BitmapCanvas extends EngineCanvas { } else { ui.Rect? shaderBounds = (paint.shader != null) ? ui.Rect.fromPoints(p1, p2) : null; - _setUpPaint(paint, shaderBounds); + setUpPaint(paint, shaderBounds); _canvasPool.strokeLine(p1, p2); - _tearDownPaint(); + tearDownPaint(); } } @@ -396,9 +396,9 @@ class BitmapCanvas extends EngineCanvas { } else { ui.Rect? shaderBounds = (paint.shader != null) ? _computePictureBounds() : null; - _setUpPaint(paint, shaderBounds); + setUpPaint(paint, shaderBounds); _canvasPool.fill(); - _tearDownPaint(); + tearDownPaint(); } } @@ -413,9 +413,9 @@ class BitmapCanvas extends EngineCanvas { math.min(rect.left, rect.right), math.min(rect.top, rect.bottom)), paint); } else { - _setUpPaint(paint, rect); + setUpPaint(paint, rect); _canvasPool.drawRect(rect, paint.style); - _tearDownPaint(); + tearDownPaint(); } } @@ -458,17 +458,17 @@ class BitmapCanvas extends EngineCanvas { math.min(rect.left, rect.right), math.min(rect.top, rect.bottom)), paint); } else { - _setUpPaint(paint, rrect.outerRect); + setUpPaint(paint, rrect.outerRect); _canvasPool.drawRRect(rrect, paint.style); - _tearDownPaint(); + tearDownPaint(); } } @override void drawDRRect(ui.RRect outer, ui.RRect inner, SurfacePaintData paint) { - _setUpPaint(paint, outer.outerRect); + setUpPaint(paint, outer.outerRect); _canvasPool.drawDRRect(outer, inner, paint.style); - _tearDownPaint(); + tearDownPaint(); } @override @@ -484,9 +484,9 @@ class BitmapCanvas extends EngineCanvas { element.style.borderRadius = '${(rect.width / 2.0)}px / ${(rect.height / 2.0)}px'; } else { - _setUpPaint(paint, rect); + setUpPaint(paint, rect); _canvasPool.drawOval(rect, paint.style); - _tearDownPaint(); + tearDownPaint(); } } @@ -503,13 +503,13 @@ class BitmapCanvas extends EngineCanvas { paint); element.style.borderRadius = '50%'; } else { - _setUpPaint( + setUpPaint( paint, paint.shader != null ? ui.Rect.fromCircle(center: c, radius: radius) : null); _canvasPool.drawCircle(c, radius, paint.style); - _tearDownPaint(); + tearDownPaint(); } } @@ -560,13 +560,13 @@ class BitmapCanvas extends EngineCanvas { _applyFilter(svgElm, paint); _drawElement(svgElm, ui.Offset(0, 0), paint); } else { - _setUpPaint(paint, paint.shader != null ? path.getBounds() : null); + setUpPaint(paint, paint.shader != null ? path.getBounds() : null); if (paint.style == null && paint.strokeWidth != null) { _canvasPool.drawPath(path, ui.PaintingStyle.stroke); } else { _canvasPool.drawPath(path, paint.style); } - _tearDownPaint(); + tearDownPaint(); } } @@ -1009,10 +1009,10 @@ class BitmapCanvas extends EngineCanvas { final double strokeWidth = paint.strokeWidth == null ? 1.0 / dpr : paint.strokeWidth!; _drawPointsPaint.strokeWidth = strokeWidth; - _setUpPaint(_drawPointsPaint, null); + setUpPaint(_drawPointsPaint, null); // Draw point using circle with half radius. _canvasPool.drawPoints(pointMode, points, strokeWidth / 2.0); - _tearDownPaint(); + tearDownPaint(); } @override diff --git a/lib/web_ui/lib/src/engine/html/scene_builder.dart b/lib/web_ui/lib/src/engine/html/scene_builder.dart index 5fe793e5bb98c..067e294c84596 100644 --- a/lib/web_ui/lib/src/engine/html/scene_builder.dart +++ b/lib/web_ui/lib/src/engine/html/scene_builder.dart @@ -546,8 +546,8 @@ class SurfaceSceneBuilder implements ui.SceneBuilder { // In the HTML renderer we time the beginning of the rasterization phase // (counter-intuitively) in SceneBuilder.build because DOM updates happen // here. This is different from CanvasKit. - _frameTimingsOnBuildFinish(); - _frameTimingsOnRasterStart(); + frameTimingsOnBuildFinish(); + frameTimingsOnRasterStart(); timeAction(kProfilePrerollFrame, () { while (_surfaceStack.length > 1) { // Auto-pop layers that were pushed without a corresponding pop. diff --git a/lib/web_ui/lib/src/engine/platform_dispatcher.dart b/lib/web_ui/lib/src/engine/platform_dispatcher.dart index cfc6bdc5286d3..9d89d552828ff 100644 --- a/lib/web_ui/lib/src/engine/platform_dispatcher.dart +++ b/lib/web_ui/lib/src/engine/platform_dispatcher.dart @@ -568,8 +568,8 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher { // CanvasKit works differently from the HTML renderer in that in HTML // we update the DOM in SceneBuilder.build, which is these function calls // here are CanvasKit-only. - _frameTimingsOnBuildFinish(); - _frameTimingsOnRasterStart(); + frameTimingsOnBuildFinish(); + frameTimingsOnRasterStart(); final LayerScene layerScene = scene as LayerScene; rasterizer!.draw(layerScene.layerTree); @@ -577,7 +577,7 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher { final SurfaceScene surfaceScene = scene as SurfaceScene; domRenderer.renderScene(surfaceScene.webOnlyRootElement); } - _frameTimingsOnRasterFinish(); + frameTimingsOnRasterFinish(); } /// Additional accessibility features that may be enabled by the platform. diff --git a/lib/web_ui/lib/src/engine/profiler.dart b/lib/web_ui/lib/src/engine/profiler.dart index ed50fa3bd9cdc..d9091f178d468 100644 --- a/lib/web_ui/lib/src/engine/profiler.dart +++ b/lib/web_ui/lib/src/engine/profiler.dart @@ -2,7 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -part of engine; +import 'dart:async'; +import 'dart:html' as html; +import 'dart:js_util' as js_util; + +import 'package:ui/ui.dart' as ui; +import 'package:ui/src/engine.dart' show EnginePlatformDispatcher; /// A function that receives a benchmark [value] labeleb by [name]. typedef OnBenchmark = void Function(String name, double value); @@ -109,7 +114,7 @@ class Profiler { /// Whether we are collecting [ui.FrameTiming]s. bool get _frameTimingsEnabled { - return EnginePlatformDispatcher.instance._onReportTimings != null; + return EnginePlatformDispatcher.instance.onReportTimings != null; } /// Collects frame timings from frames. @@ -133,7 +138,7 @@ int _rasterStartMicros = -1; int _rasterFinishMicros = -1; /// Records the vsync timestamp for this frame. -void _frameTimingsOnVsync() { +void frameTimingsOnVsync() { if (!_frameTimingsEnabled) { return; } @@ -141,7 +146,7 @@ void _frameTimingsOnVsync() { } /// Records the time when the framework started building the frame. -void _frameTimingsOnBuildStart() { +void frameTimingsOnBuildStart() { if (!_frameTimingsEnabled) { return; } @@ -149,7 +154,7 @@ void _frameTimingsOnBuildStart() { } /// Records the time when the framework finished building the frame. -void _frameTimingsOnBuildFinish() { +void frameTimingsOnBuildFinish() { if (!_frameTimingsEnabled) { return; } @@ -170,7 +175,7 @@ void _frameTimingsOnBuildFinish() { /// /// CanvasKit captures everything because we control the rasterization /// process, so we know exactly when rasterization starts and ends. -void _frameTimingsOnRasterStart() { +void frameTimingsOnRasterStart() { if (!_frameTimingsEnabled) { return; } @@ -181,7 +186,7 @@ void _frameTimingsOnRasterStart() { /// /// See [_frameTimingsOnRasterStart] for more details on what rasterization /// timings mean on the web. -void _frameTimingsOnRasterFinish() { +void frameTimingsOnRasterFinish() { if (!_frameTimingsEnabled) { return; } 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 784f2a2976757..83ae56ed66289 100644 --- a/lib/web_ui/lib/src/engine/text/canvas_paragraph.dart +++ b/lib/web_ui/lib/src/engine/text/canvas_paragraph.dart @@ -2,7 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -part of engine; +import 'dart:html' as html; + +import 'package:ui/ui.dart' as ui; + +import 'package:ui/src/engine.dart' show BitmapCanvas, canonicalizeFontFamily, domRenderer, DomRenderer; + +import '../profiler.dart'; +import 'layout_service.dart'; +import 'paint_service.dart'; +import 'paragraph.dart'; +import 'word_breaker.dart'; /// A paragraph made up of a flat list of text spans and placeholders. /// @@ -150,7 +160,7 @@ class CanvasParagraph implements EngineParagraph { cssStyle.width = '${width}px'; } - if (paragraphStyle._maxLines != null || paragraphStyle._ellipsis != null) { + if (paragraphStyle.maxLines != null || paragraphStyle.ellipsis != null) { cssStyle ..overflowY = 'hidden' ..height = '${height}px'; @@ -175,7 +185,7 @@ class CanvasParagraph implements EngineParagraph { if (box.span != span) { span = box.span; element = domRenderer.createElement('span') as html.HtmlElement; - _applyTextStyleToElement( + applyTextStyleToElement( element: element, style: box.span.style, isSpan: true @@ -190,7 +200,7 @@ class CanvasParagraph implements EngineParagraph { element = rootElement; domRenderer.append( rootElement, - _createPlaceholderElement(placeholder: box.placeholder), + createPlaceholderElement(placeholder: box.placeholder), ); } else { throw UnimplementedError('Unknown box type: ${box.runtimeType}'); @@ -271,15 +281,15 @@ void _applyNecessaryParagraphStyles({ }) { final html.CssStyleDeclaration cssStyle = element.style; - if (style._textAlign != null) { + if (style.textAlign != null) { cssStyle.textAlign = textAlignToCssValue( - style._textAlign, style._textDirection ?? ui.TextDirection.ltr); + style.textAlign, style.textDirection ?? ui.TextDirection.ltr); } - if (style._lineHeight != null) { - cssStyle.lineHeight = '${style._lineHeight}'; + if (style.lineHeight != null) { + cssStyle.lineHeight = '${style.lineHeight}'; } - if (style._textDirection != null) { - cssStyle.direction = _textDirectionToCss(style._textDirection); + if (style.textDirection != null) { + cssStyle.direction = textDirectionToCss(style.textDirection); } } @@ -297,11 +307,11 @@ void _applySpanStylesToParagraph({ String? fontFamily; for (final ParagraphSpan span in spans) { if (span is FlatTextSpan) { - final double? spanFontSize = span.style._fontSize; + final double? spanFontSize = span.style.fontSize; if (spanFontSize != null && spanFontSize > fontSize) { fontSize = spanFontSize; - if (span.style._isFontFamilyProvided) { - fontFamily = span.style._effectiveFontFamily; + if (span.style.isFontFamilyProvided) { + fontFamily = span.style.effectiveFontFamily; } } } @@ -471,64 +481,64 @@ class ChildStyleNode extends StyleNode { // property isn't defined, go to the parent node. @override - ui.Color? get _color => style._color ?? (_foreground == null ? parent._color : null); + ui.Color? get _color => style.color ?? (_foreground == null ? parent._color : null); @override - ui.TextDecoration? get _decoration => style._decoration ?? parent._decoration; + ui.TextDecoration? get _decoration => style.decoration ?? parent._decoration; @override - ui.Color? get _decorationColor => style._decorationColor ?? parent._decorationColor; + ui.Color? get _decorationColor => style.decorationColor ?? parent._decorationColor; @override - ui.TextDecorationStyle? get _decorationStyle => style._decorationStyle ?? parent._decorationStyle; + ui.TextDecorationStyle? get _decorationStyle => style.decorationStyle ?? parent._decorationStyle; @override - double? get _decorationThickness => style._decorationThickness ?? parent._decorationThickness; + double? get _decorationThickness => style.decorationThickness ?? parent._decorationThickness; @override - ui.FontWeight? get _fontWeight => style._fontWeight ?? parent._fontWeight; + ui.FontWeight? get _fontWeight => style.fontWeight ?? parent._fontWeight; @override - ui.FontStyle? get _fontStyle => style._fontStyle ?? parent._fontStyle; + ui.FontStyle? get _fontStyle => style.fontStyle ?? parent._fontStyle; @override - ui.TextBaseline? get _textBaseline => style._textBaseline ?? parent._textBaseline; + ui.TextBaseline? get _textBaseline => style.textBaseline ?? parent._textBaseline; @override - List? get _fontFamilyFallback => style._fontFamilyFallback ?? parent._fontFamilyFallback; + List? get _fontFamilyFallback => style.fontFamilyFallback ?? parent._fontFamilyFallback; @override - List? get _fontFeatures => style._fontFeatures ?? parent._fontFeatures; + List? get _fontFeatures => style.fontFeatures ?? parent._fontFeatures; @override - double get _fontSize => style._fontSize ?? parent._fontSize; + double get _fontSize => style.fontSize ?? parent._fontSize; @override - double? get _letterSpacing => style._letterSpacing ?? parent._letterSpacing; + double? get _letterSpacing => style.letterSpacing ?? parent._letterSpacing; @override - double? get _wordSpacing => style._wordSpacing ?? parent._wordSpacing; + double? get _wordSpacing => style.wordSpacing ?? parent._wordSpacing; @override - double? get _height => style._height ?? parent._height; + double? get _height => style.height ?? parent._height; @override - ui.Locale? get _locale => style._locale ?? parent._locale; + ui.Locale? get _locale => style.locale ?? parent._locale; @override - ui.Paint? get _background => style._background ?? parent._background; + ui.Paint? get _background => style.background ?? parent._background; @override - ui.Paint? get _foreground => style._foreground ?? parent._foreground; + ui.Paint? get _foreground => style.foreground ?? parent._foreground; @override - List? get _shadows => style._shadows ?? parent._shadows; + List? get _shadows => style.shadows ?? parent._shadows; // Font family is slightly different from the other properties above. It's - // never null on the TextStyle object, so we use `_isFontFamilyProvided` to + // never null on the TextStyle object, so we use `isFontFamilyProvided` to // check if font family is defined or not. @override - String get _fontFamily => style._isFontFamilyProvided ? style._fontFamily : parent._fontFamily; + String get _fontFamily => style.isFontFamilyProvided ? style.fontFamily : parent._fontFamily; } /// The root style node for the paragraph. @@ -543,7 +553,7 @@ class RootStyleNode extends StyleNode { final EngineParagraphStyle paragraphStyle; @override - final ui.Color _color = _defaultTextColor; + final ui.Color _color = defaultTextColor; @override ui.TextDecoration? get _decoration => null; @@ -558,15 +568,15 @@ class RootStyleNode extends StyleNode { double? get _decorationThickness => null; @override - ui.FontWeight? get _fontWeight => paragraphStyle._fontWeight; + ui.FontWeight? get _fontWeight => paragraphStyle.fontWeight; @override - ui.FontStyle? get _fontStyle => paragraphStyle._fontStyle; + ui.FontStyle? get _fontStyle => paragraphStyle.fontStyle; @override ui.TextBaseline? get _textBaseline => null; @override - String get _fontFamily => paragraphStyle._fontFamily ?? DomRenderer.defaultFontFamily; + String get _fontFamily => paragraphStyle.fontFamily ?? DomRenderer.defaultFontFamily; @override List? get _fontFamilyFallback => null; @@ -575,7 +585,7 @@ class RootStyleNode extends StyleNode { List? get _fontFeatures => null; @override - double get _fontSize => paragraphStyle._fontSize ?? DomRenderer.defaultFontSize; + double get _fontSize => paragraphStyle.fontSize ?? DomRenderer.defaultFontSize; @override double? get _letterSpacing => null; @@ -584,10 +594,10 @@ class RootStyleNode extends StyleNode { double? get _wordSpacing => null; @override - double? get _height => paragraphStyle._height; + double? get _height => paragraphStyle.height; @override - ui.Locale? get _locale => paragraphStyle._locale; + ui.Locale? get _locale => paragraphStyle.locale; @override ui.Paint? get _background => null; @@ -680,14 +690,14 @@ class CanvasParagraphBuilder implements ui.ParagraphBuilder { final int end = _plainTextBuffer.length; if (_drawOnCanvas) { - final ui.TextDecoration? decoration = style._decoration; + final ui.TextDecoration? decoration = style.decoration; if (decoration != null && decoration != ui.TextDecoration.none) { _drawOnCanvas = false; } } if (_drawOnCanvas) { - final List? fontFeatures = style._fontFeatures; + final List? fontFeatures = style.fontFeatures; if (fontFeatures != null && fontFeatures.isNotEmpty) { _drawOnCanvas = false; } 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 65bcd230357d7..4e404a553a3c8 100644 --- a/lib/web_ui/lib/src/engine/text/layout_service.dart +++ b/lib/web_ui/lib/src/engine/text/layout_service.dart @@ -2,7 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -part of engine; +import 'dart:html' as html; +import 'dart:math' as math; + +import 'package:ui/ui.dart' as ui; +import 'package:meta/meta.dart'; + +import 'canvas_paragraph.dart'; +import 'line_breaker.dart'; +import 'measurement.dart'; +import 'paragraph.dart'; +import 'ruler.dart'; /// Performs layout on a [CanvasParagraph]. /// @@ -38,10 +48,10 @@ class TextLayoutService { // *** Convenient shortcuts used during layout *** // - int? get maxLines => paragraph.paragraphStyle._maxLines; + int? get maxLines => paragraph.paragraphStyle.maxLines; bool get unlimitedLines => maxLines == null; - String? get ellipsis => paragraph.paragraphStyle._ellipsis; + String? get ellipsis => paragraph.paragraphStyle.ellipsis; bool get hasEllipsis => ellipsis != null; /// Performs the layout on a paragraph given the [constraints]. @@ -191,7 +201,7 @@ class TextLayoutService { height += line.height; if (alphabeticBaseline == -1.0) { alphabeticBaseline = line.baseline; - ideographicBaseline = alphabeticBaseline * _baselineRatioHack; + ideographicBaseline = alphabeticBaseline * baselineRatioHack; } final double longestLineWidth = longestLine?.width ?? 0.0; if (longestLineWidth < line.width) { @@ -721,9 +731,9 @@ class LineBuilder { double get alignOffset { final double emptySpace = maxWidth - width; final ui.TextDirection textDirection = - paragraph.paragraphStyle._textDirection ?? ui.TextDirection.ltr; + paragraph.paragraphStyle.effectiveTextDirection; final ui.TextAlign textAlign = - paragraph.paragraphStyle._textAlign ?? ui.TextAlign.start; + paragraph.paragraphStyle.effectiveTextAlign; switch (textAlign) { case ui.TextAlign.center: @@ -846,7 +856,7 @@ class LineBuilder { placeholder, index: _boxStart, left: _boxLeft, - direction: paragraph.paragraphStyle._effectiveTextDirection, + direction: paragraph.paragraphStyle.effectiveTextDirection, )); } @@ -1021,7 +1031,7 @@ class LineBuilder { } ui.TextDirection get direction => - paragraph.paragraphStyle._effectiveTextDirection; + paragraph.paragraphStyle.effectiveTextDirection; /// Cuts a new box in the line. /// @@ -1044,7 +1054,7 @@ class LineBuilder { start: boxStart, end: boxEnd, left: _boxLeft, - direction: paragraph.paragraphStyle._effectiveTextDirection, + direction: paragraph.paragraphStyle.effectiveTextDirection, )); } @@ -1132,7 +1142,7 @@ class Spanometer { String _cssFontString = ''; - double? get letterSpacing => currentSpan.style._letterSpacing; + double? get letterSpacing => currentSpan.style.letterSpacing; TextHeightRuler? _currentRuler; FlatTextSpan? _currentSpan; @@ -1195,7 +1205,7 @@ class Spanometer { } double measureText(String text) { - return _measureSubstring(context, text, 0, text.length); + return measureSubstring(context, text, 0, text.length); } /// In a continuous, unbreakable block of text from [start] to [end], finds @@ -1257,7 +1267,7 @@ class Spanometer { assert(end >= span.start && end <= span.end); final String text = paragraph.toPlainText(); - return _measureSubstring( + return measureSubstring( context, text, start, diff --git a/lib/web_ui/lib/src/engine/text/line_break_properties.dart b/lib/web_ui/lib/src/engine/text/line_break_properties.dart index 647d461fe1071..fb4e5e284016f 100644 --- a/lib/web_ui/lib/src/engine/text/line_break_properties.dart +++ b/lib/web_ui/lib/src/engine/text/line_break_properties.dart @@ -12,7 +12,7 @@ // # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. // # For terms of use, see http://www.unicode.org/terms_of_use.html -part of engine; +import 'unicode_range.dart'; /// For an explanation of these enum values, see: /// diff --git a/lib/web_ui/lib/src/engine/text/line_breaker.dart b/lib/web_ui/lib/src/engine/text/line_breaker.dart index a4ce0e68cdc20..4f8d9589922d5 100644 --- a/lib/web_ui/lib/src/engine/text/line_breaker.dart +++ b/lib/web_ui/lib/src/engine/text/line_breaker.dart @@ -2,7 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -part of engine; +import 'package:ui/ui.dart' as ui; +import 'package:ui/src/engine.dart' show assertionsEnabled; + +import 'line_break_properties.dart'; +import 'unicode_range.dart'; /// Various types of line breaks as defined by the Unicode spec. enum LineBreakType { diff --git a/lib/web_ui/lib/src/engine/text/measurement.dart b/lib/web_ui/lib/src/engine/text/measurement.dart index 5d53027bec50b..e65a510904e75 100644 --- a/lib/web_ui/lib/src/engine/text/measurement.dart +++ b/lib/web_ui/lib/src/engine/text/measurement.dart @@ -2,7 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -part of engine; +import 'dart:async'; +import 'dart:html' as html; +import 'dart:math' as math; + +import 'package:meta/meta.dart'; +import 'package:ui/ui.dart' as ui; +import 'package:ui/src/engine.dart' show assertionsEnabled, domRenderer, registerHotRestartListener, window; + +import '../web_experiments.dart'; +import 'line_break_properties.dart'; +import 'line_breaker.dart'; +import 'paragraph.dart'; +import 'ruler.dart'; // TODO(yjbanov): this is a hack we use to compute ideographic baseline; this // number is the ratio ideographic/alphabetic for font Ahem, @@ -10,7 +22,7 @@ part of engine; // for any other font. We'll need to eventually fix this. That // said Flutter doesn't seem to use ideographic baseline for // anything as of this writing. -const double _baselineRatioHack = 1.1662499904632568; +const double baselineRatioHack = 1.1662499904632568; /// Signature of a function that takes a character and returns true or false. typedef CharPredicate = bool Function(int char); @@ -238,8 +250,8 @@ abstract class TextMeasurementService { // doesn't have any of the following styles: // - decoration // - word spacing - final ParagraphGeometricStyle style = paragraph._geometricStyle; - return paragraph._plainText != null && + final ParagraphGeometricStyle style = paragraph.geometricStyle; + return paragraph.plainText != null && style.decoration == null && style.wordSpacing == null; } @@ -250,12 +262,12 @@ abstract class TextMeasurementService { ui.ParagraphConstraints constraints, ) { assert(rulerManager != null); - final ParagraphGeometricStyle style = paragraph._geometricStyle; + final ParagraphGeometricStyle style = paragraph.geometricStyle; final ParagraphRuler ruler = TextMeasurementService.rulerManager!.findOrCreateRuler(style); if (assertionsEnabled) { - if (paragraph._plainText == null) { + if (paragraph.plainText == null) { domRenderer.debugRichTextLayout(); } else { domRenderer.debugPlainTextLayout(); @@ -290,12 +302,12 @@ abstract class TextMeasurementService { required double alignOffset, required ui.TextDirection textDirection, }) { - final ParagraphGeometricStyle style = paragraph._geometricStyle; + final ParagraphGeometricStyle style = paragraph.geometricStyle; final ParagraphRuler ruler = TextMeasurementService.rulerManager!.findOrCreateRuler(style); return ruler.measureBoxesForRange( - paragraph._plainText!, + paragraph.plainText!, constraints, start: start, end: end, @@ -349,7 +361,7 @@ class DomTextMeasurementService extends TextMeasurementService { ParagraphRuler ruler, ) { ruler.willMeasure(paragraph); - final String? plainText = paragraph._plainText; + final String? plainText = paragraph.plainText; ruler.measureAll(constraints); @@ -370,13 +382,13 @@ class DomTextMeasurementService extends TextMeasurementService { @override double measureSubstringWidth(DomParagraph paragraph, int start, int end) { - assert(paragraph._plainText != null); - final ParagraphGeometricStyle style = paragraph._geometricStyle; + assert(paragraph.plainText != null); + final ParagraphGeometricStyle style = paragraph.geometricStyle; final ParagraphRuler ruler = TextMeasurementService.rulerManager!.findOrCreateRuler(style); - final String text = paragraph._plainText!.substring(start, end); - final ui.Paragraph substringParagraph = paragraph._cloneWithText(text); + final String text = paragraph.plainText!.substring(start, end); + final ui.Paragraph substringParagraph = paragraph.cloneWithText(text); ruler.willMeasure(substringParagraph as DomParagraph); ruler.measureAsSingleLine(); @@ -389,11 +401,11 @@ class DomTextMeasurementService extends TextMeasurementService { ui.TextPosition getTextPositionForOffset(DomParagraph paragraph, ui.ParagraphConstraints? constraints, ui.Offset offset) { assert( - paragraph._measurementResult!.lines == null, + paragraph.measurementResult!.lines == null, 'should only be called when the faster lines-based approach is not possible', ); - final ParagraphGeometricStyle style = paragraph._geometricStyle; + final ParagraphGeometricStyle style = paragraph.geometricStyle; final ParagraphRuler ruler = TextMeasurementService.rulerManager!.findOrCreateRuler(style); ruler.willMeasure(paragraph); @@ -428,9 +440,9 @@ class DomTextMeasurementService extends TextMeasurementService { maxIntrinsicWidth = _applySubPixelRoundingHack(minIntrinsicWidth, maxIntrinsicWidth); - final double ideographicBaseline = alphabeticBaseline * _baselineRatioHack; + final double ideographicBaseline = alphabeticBaseline * baselineRatioHack; - final String? text = paragraph._plainText; + final String? text = paragraph.plainText; List? lines; if (text != null) { final double lineWidth = maxIntrinsicWidth; @@ -468,8 +480,8 @@ class DomTextMeasurementService extends TextMeasurementService { ideographicBaseline: ideographicBaseline, lines: lines, placeholderBoxes: ruler.measurePlaceholderBoxes(), - textAlign: paragraph._textAlign, - textDirection: paragraph._textDirection, + textAlign: paragraph.textAlign, + textDirection: paragraph.textDirection, ); } @@ -493,7 +505,7 @@ class DomTextMeasurementService extends TextMeasurementService { double height; double? lineHeight; - final int? maxLines = paragraph._geometricStyle.maxLines; + final int? maxLines = paragraph.geometricStyle.maxLines; if (maxLines == null) { height = naturalHeight; } else { @@ -505,7 +517,7 @@ class DomTextMeasurementService extends TextMeasurementService { maxIntrinsicWidth = _applySubPixelRoundingHack(minIntrinsicWidth, maxIntrinsicWidth); assert(minIntrinsicWidth <= maxIntrinsicWidth); - final double ideographicBaseline = alphabeticBaseline * _baselineRatioHack; + final double ideographicBaseline = alphabeticBaseline * baselineRatioHack; return MeasurementResult( constraints.width, isSingleLine: false, @@ -519,8 +531,8 @@ class DomTextMeasurementService extends TextMeasurementService { ideographicBaseline: ideographicBaseline, lines: null, placeholderBoxes: ruler.measurePlaceholderBoxes(), - textAlign: paragraph._textAlign, - textDirection: paragraph._textDirection, + textAlign: paragraph.textAlign, + textDirection: paragraph.textDirection, ); } @@ -572,8 +584,8 @@ class CanvasTextMeasurementService extends TextMeasurementService { ui.ParagraphConstraints constraints, ParagraphRuler ruler, ) { - final String text = paragraph._plainText!; - final ParagraphGeometricStyle style = paragraph._geometricStyle; + final String text = paragraph.plainText!; + final ParagraphGeometricStyle style = paragraph.geometricStyle; assert(text != null); // ignore: unnecessary_null_comparison // TODO(mdebbar): Check if the whole text can fit in a single-line. Then avoid all this ceremony. @@ -619,7 +631,7 @@ class CanvasTextMeasurementService extends TextMeasurementService { constraints.width, isSingleLine: lineCount == 1, alphabeticBaseline: alphabeticBaseline, - ideographicBaseline: alphabeticBaseline * _baselineRatioHack, + ideographicBaseline: alphabeticBaseline * baselineRatioHack, height: height, naturalHeight: naturalHeight, lineHeight: lineHeight, @@ -632,24 +644,24 @@ class CanvasTextMeasurementService extends TextMeasurementService { width: constraints.width, lines: linesCalculator.lines, placeholderBoxes: [], - textAlign: paragraph._textAlign, - textDirection: paragraph._textDirection, + textAlign: paragraph.textAlign, + textDirection: paragraph.textDirection, ); return result; } @override double measureSubstringWidth(DomParagraph paragraph, int start, int end) { - assert(paragraph._plainText != null); - final String text = paragraph._plainText!; - final ParagraphGeometricStyle style = paragraph._geometricStyle; + assert(paragraph.plainText != null); + final String text = paragraph.plainText!; + final ParagraphGeometricStyle style = paragraph.geometricStyle; _canvasContext.font = style.cssFontString; - return _measureSubstring( + return measureSubstring( _canvasContext, text, start, end, - letterSpacing: paragraph._geometricStyle.letterSpacing, + letterSpacing: paragraph.geometricStyle.letterSpacing, ); } @@ -661,7 +673,7 @@ class CanvasTextMeasurementService extends TextMeasurementService { } } -// These global variables are used to memoize calls to [_measureSubstring]. They +// These global variables are used to memoize calls to [measureSubstring]. They // are used to remember the last arguments passed to it, and the last return // value. // They are being initialized so that the compiler knows they'll never be null. @@ -676,7 +688,7 @@ double _lastWidth = -1; /// /// This method assumes that the correct font has already been set on /// [_canvasContext]. -double _measureSubstring( +double measureSubstring( html.CanvasRenderingContext2D _canvasContext, String text, int start, @@ -760,8 +772,8 @@ class LinesCalculator { final DomParagraph _paragraph; final double _maxWidth; - String? get _text => _paragraph._plainText; - ParagraphGeometricStyle get _style => _paragraph._geometricStyle; + String? get _text => _paragraph.plainText; + ParagraphGeometricStyle get _style => _paragraph.geometricStyle; /// The lines that have been consumed so far. List lines = []; @@ -799,7 +811,7 @@ class LinesCalculator { // doesn't fit in a single line. That's why we need a loop. while (!_reachedMaxLines) { final double lineWidth = - measureSubstring(_lineStart, chunkEndWithoutSpace); + measureSubstringWidth(_lineStart, chunkEndWithoutSpace); // The current chunk doesn't reach the maximum width, so we stop here and // wait for the next line break. @@ -827,7 +839,7 @@ class LinesCalculator { end: chunkEndWithoutSpace, ); final double widthOfResultingLine = - measureSubstring(_lineStart, breakingPoint) + _ellipsisWidth; + measureSubstringWidth(_lineStart, breakingPoint) + _ellipsisWidth; final double alignOffset = _calculateAlignOffsetForLine( paragraph: _paragraph, lineWidth: widthOfResultingLine, @@ -882,9 +894,9 @@ class LinesCalculator { void _addLineBreak(LineBreakResult brk) { final int lineNumber = lines.length; final double lineWidth = - measureSubstring(_lineStart, brk.indexWithoutTrailingSpaces); + measureSubstringWidth(_lineStart, brk.indexWithoutTrailingSpaces); final double lineWidthWithTrailingSpaces = - measureSubstring(_lineStart, brk.indexWithoutTrailingNewlines); + measureSubstringWidth(_lineStart, brk.indexWithoutTrailingNewlines); final double alignOffset = _calculateAlignOffsetForLine( paragraph: _paragraph, lineWidth: lineWidth, @@ -914,8 +926,8 @@ class LinesCalculator { /// /// This method uses [_text], [_style] and [_canvasContext] to perform the /// measurement. - double measureSubstring(int start, int end) { - return _measureSubstring( + double measureSubstringWidth(int start, int end) { + return measureSubstring( _canvasContext, _text!, start, @@ -944,7 +956,7 @@ class LinesCalculator { int high = end; do { final int mid = (low + high) ~/ 2; - final double width = measureSubstring(start, mid); + final double width = measureSubstringWidth(start, mid); if (width < maxWidth) { low = mid; } else if (width > maxWidth) { @@ -978,7 +990,7 @@ class MinIntrinsicCalculator { /// [value] will contain the final minimum intrinsic width. void update(LineBreakResult brk) { final int chunkEnd = brk.index; - final double width = _measureSubstring( + final double width = measureSubstring( _canvasContext, _text, _lastChunkEnd, @@ -1015,7 +1027,7 @@ class MaxIntrinsicCalculator { return; } - final double lineWidth = _measureSubstring( + final double lineWidth = measureSubstring( _canvasContext, _text, _lastHardLineEnd, @@ -1038,17 +1050,17 @@ double _calculateAlignOffsetForLine({ final double emptySpace = maxWidth - lineWidth; // WARNING: the [paragraph] may not be laid out yet at this point. This // function must not use layout metrics, such as [paragraph.height]. - switch (paragraph._textAlign) { + switch (paragraph.textAlign) { case ui.TextAlign.center: return emptySpace / 2.0; case ui.TextAlign.right: return emptySpace; case ui.TextAlign.start: - return paragraph._textDirection == ui.TextDirection.rtl + return paragraph.textDirection == ui.TextDirection.rtl ? emptySpace : 0.0; case ui.TextAlign.end: - return paragraph._textDirection == ui.TextDirection.rtl + return paragraph.textDirection == ui.TextDirection.rtl ? 0.0 : emptySpace; default: 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 ba20a1cb1dfdb..f7b2e110258c9 100644 --- a/lib/web_ui/lib/src/engine/text/paint_service.dart +++ b/lib/web_ui/lib/src/engine/text/paint_service.dart @@ -2,7 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -part of engine; +import 'package:ui/ui.dart' as ui; +import 'package:ui/src/engine.dart' show BitmapCanvas, SurfacePaint; + +import 'canvas_paragraph.dart'; +import 'layout_service.dart'; +import 'paragraph.dart'; /// Responsible for painting a [CanvasParagraph] on a [BitmapCanvas]. class TextPaintService { @@ -35,7 +40,7 @@ class TextPaintService { final FlatTextSpan span = box.span; // Paint the background of the box, if the span has a background. - final SurfacePaint? background = span.style._background as SurfacePaint?; + final SurfacePaint? background = span.style.background as SurfacePaint?; if (background != null) { canvas.drawRect( box.toTextBox(line).toRect().shift(offset), @@ -51,9 +56,9 @@ class TextPaintService { box.start.index, box.end.indexWithoutTrailingNewlines, ); - final double? letterSpacing = span.style._letterSpacing; + final double? letterSpacing = span.style.letterSpacing; if (letterSpacing == null || letterSpacing == 0.0) { - canvas.fillText(text, x, y, shadows: span.style._shadows); + canvas.fillText(text, x, y, shadows: span.style.shadows); } else { // TODO(mdebbar): Implement letter-spacing on canvas more efficiently: // https://github.com/flutter/flutter/issues/51234 @@ -62,7 +67,7 @@ class TextPaintService { for (int i = 0; i < len; i++) { final String char = text[i]; canvas.fillText(char, charX.roundToDouble(), y, - shadows: span.style._shadows); + shadows: span.style.shadows); charX += letterSpacing + canvas.measureText(char).width!; } } @@ -74,20 +79,20 @@ class TextPaintService { canvas.fillText(ellipsis, x, y); } - canvas._tearDownPaint(); + canvas.tearDownPaint(); } } void _applySpanStyleToCanvas(FlatTextSpan span, BitmapCanvas canvas) { final SurfacePaint? paint; - final ui.Paint? foreground = span.style._foreground; + final ui.Paint? foreground = span.style.foreground; if (foreground != null) { paint = foreground as SurfacePaint; } else { - paint = (ui.Paint()..color = span.style._color!) as SurfacePaint; + paint = (ui.Paint()..color = span.style.color!) as SurfacePaint; } canvas.setCssFont(span.style.cssFontString); - canvas._setUpPaint(paint.paintData, null); + canvas.setUpPaint(paint.paintData, null); } } diff --git a/lib/web_ui/lib/src/engine/text/paragraph.dart b/lib/web_ui/lib/src/engine/text/paragraph.dart index 84e38ebb18537..632f9fb71dd34 100644 --- a/lib/web_ui/lib/src/engine/text/paragraph.dart +++ b/lib/web_ui/lib/src/engine/text/paragraph.dart @@ -2,11 +2,25 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -part of engine; +import 'dart:html' as html; +import 'dart:js_util' as js_util; +import 'dart:math' as math; -const ui.Color _defaultTextColor = ui.Color(0xFFFF0000); +import 'package:ui/ui.dart' as ui; +import 'package:ui/src/engine.dart' show assertionsEnabled, BitmapCanvas, colorToCssString, canonicalizeFontFamily, domRenderer, DomRenderer, SurfacePaint; -const String _placeholderClass = 'paragraph-placeholder'; +import '../browser_detection.dart'; +import '../profiler.dart'; +import '../util.dart'; +import 'canvas_paragraph.dart'; +import 'layout_service.dart'; +import 'measurement.dart'; +import 'ruler.dart'; +import 'word_breaker.dart'; + +const ui.Color defaultTextColor = ui.Color(0xFFFF0000); + +const String placeholderClass = 'paragraph-placeholder'; class EngineLineMetrics implements ui.LineMetrics { EngineLineMetrics({ @@ -264,13 +278,13 @@ class DomParagraph implements EngineParagraph { final int placeholderCount; - @visibleForTesting String? get plainText => _plainText; - @visibleForTesting html.HtmlElement get paragraphElement => _paragraphElement; - @visibleForTesting + ui.TextAlign get textAlign => _textAlign; + ui.TextDirection get textDirection => _textDirection; + ParagraphGeometricStyle get geometricStyle => _geometricStyle; /// The instance of [TextMeasurementService] to be used to measure this @@ -279,6 +293,7 @@ class DomParagraph implements EngineParagraph { TextMeasurementService.forParagraph(this); /// The measurement result of the last layout operation. + MeasurementResult? get measurementResult => _measurementResult; MeasurementResult? _measurementResult; bool get _hasLineMetrics => _measurementResult?.lines != null; @@ -423,14 +438,14 @@ class DomParagraph implements EngineParagraph { canvas.setCssFont(_geometricStyle.cssFontString); // Then paint the text. - canvas._setUpPaint(_paint!.paintData, null); + canvas.setUpPaint(_paint!.paintData, null); double y = offset.dy + alphabeticBaseline; final int len = lines.length; for (int i = 0; i < len; i++) { _paintLine(canvas, lines[i], offset.dx, y); y += _lineHeight; } - canvas._tearDownPaint(); + canvas.tearDownPaint(); } void _paintLine( @@ -542,7 +557,7 @@ class DomParagraph implements EngineParagraph { /// /// Ignores properties that do not affect layout, such as /// [ParagraphStyle.textAlign]. - bool _debugHasSameRootStyle(ParagraphGeometricStyle style) { + bool debugHasSameRootStyle(ParagraphGeometricStyle style) { assert(() { if (style != _geometricStyle) { throw Exception('Attempted to measure a paragraph whose style is ' @@ -644,7 +659,7 @@ class DomParagraph implements EngineParagraph { ); } - ui.Paragraph _cloneWithText(String plainText) { + ui.Paragraph cloneWithText(String plainText) { return DomParagraph( plainText: plainText, paragraphElement: _paragraphElement.clone(true) as html.HtmlElement, @@ -798,49 +813,38 @@ class DomParagraph implements EngineParagraph { class EngineParagraphStyle implements ui.ParagraphStyle { /// Creates a new instance of [EngineParagraphStyle]. EngineParagraphStyle({ - ui.TextAlign? textAlign, - ui.TextDirection? textDirection, - int? maxLines, - String? fontFamily, - double? fontSize, - double? height, + this.textAlign, + this.textDirection, + this.maxLines, + this.fontFamily, + this.fontSize, + this.height, ui.TextHeightBehavior? textHeightBehavior, - ui.FontWeight? fontWeight, - ui.FontStyle? fontStyle, + this.fontWeight, + this.fontStyle, ui.StrutStyle? strutStyle, - String? ellipsis, - ui.Locale? locale, - }) : _textAlign = textAlign, - _textDirection = textDirection, - _fontWeight = fontWeight, - _fontStyle = fontStyle, - _maxLines = maxLines, - _fontFamily = fontFamily, - _fontSize = fontSize, - _height = height, - _textHeightBehavior = textHeightBehavior, + this.ellipsis, + this.locale, + }) : _textHeightBehavior = textHeightBehavior, // TODO(b/128317744): add support for strut style. - _strutStyle = strutStyle as EngineStrutStyle?, - _ellipsis = ellipsis, - _locale = locale; - - final ui.TextAlign? _textAlign; - final ui.TextDirection? _textDirection; - final ui.FontWeight? _fontWeight; - final ui.FontStyle? _fontStyle; - final int? _maxLines; - final String? _fontFamily; - final double? _fontSize; - final double? _height; + _strutStyle = strutStyle as EngineStrutStyle?; + + final ui.TextAlign? textAlign; + final ui.TextDirection? textDirection; + final ui.FontWeight? fontWeight; + final ui.FontStyle? fontStyle; + final int? maxLines; + final String? fontFamily; + final double? fontSize; + final double? height; final ui.TextHeightBehavior? _textHeightBehavior; final EngineStrutStyle? _strutStyle; - final String? _ellipsis; - final ui.Locale? _locale; + final String? ellipsis; + final ui.Locale? locale; // The effective style attributes should be consistent with paragraph_style.h. - ui.TextAlign get _effectiveTextAlign => _textAlign ?? ui.TextAlign.start; - ui.TextDirection get _effectiveTextDirection => - _textDirection ?? ui.TextDirection.ltr; + ui.TextAlign get effectiveTextAlign => textAlign ?? ui.TextAlign.start; + ui.TextDirection get effectiveTextDirection => textDirection ?? ui.TextDirection.ltr; String get _effectiveFontFamily { if (assertionsEnabled) { @@ -850,21 +854,21 @@ class EngineParagraphStyle implements ui.ParagraphStyle { return 'Ahem'; } } - final String? fontFamily = _fontFamily; + final String? fontFamily = this.fontFamily; if (fontFamily == null || fontFamily.isEmpty) { return DomRenderer.defaultFontFamily; } return fontFamily; } - double? get _lineHeight { + double? get lineHeight { // TODO(mdebbar): Implement proper support for strut styles. // https://github.com/flutter/flutter/issues/32243 if (_strutStyle == null || _strutStyle!._height == null || _strutStyle!._height == 0) { // When there's no strut height, always use paragraph style height. - return _height; + return height; } if (_strutStyle!._forceStrutHeight == true) { // When strut height is forced, ignore paragraph style height. @@ -872,7 +876,7 @@ class EngineParagraphStyle implements ui.ParagraphStyle { } // In this case, strut height acts as a minimum height for all parts of the // paragraph. So we take the max of strut height and paragraph style height. - return math.max(_strutStyle!._height!, _height ?? 0.0); + return math.max(_strutStyle!._height!, height ?? 0.0); } @override @@ -884,50 +888,50 @@ class EngineParagraphStyle implements ui.ParagraphStyle { return false; } return other is EngineParagraphStyle && - other._textAlign == _textAlign && - other._textDirection == _textDirection && - other._fontWeight == _fontWeight && - other._fontStyle == _fontStyle && - other._maxLines == _maxLines && - other._fontFamily == _fontFamily && - other._fontSize == _fontSize && - other._height == _height && + other.textAlign == textAlign && + other.textDirection == textDirection && + other.fontWeight == fontWeight && + other.fontStyle == fontStyle && + other.maxLines == maxLines && + other.fontFamily == fontFamily && + other.fontSize == fontSize && + other.height == height && other._textHeightBehavior == _textHeightBehavior && - other._ellipsis == _ellipsis && - other._locale == _locale; + other.ellipsis == ellipsis && + other.locale == locale; } @override int get hashCode { return ui.hashValues( - _textAlign, - _textDirection, - _fontWeight, - _fontStyle, - _maxLines, - _fontFamily, - _fontSize, - _height, + textAlign, + textDirection, + fontWeight, + fontStyle, + maxLines, + fontFamily, + fontSize, + height, _textHeightBehavior, - _ellipsis, - _locale); + ellipsis, + locale); } @override String toString() { if (assertionsEnabled) { return 'ParagraphStyle(' - 'textAlign: ${_textAlign ?? "unspecified"}, ' - 'textDirection: ${_textDirection ?? "unspecified"}, ' - 'fontWeight: ${_fontWeight ?? "unspecified"}, ' - 'fontStyle: ${_fontStyle ?? "unspecified"}, ' - 'maxLines: ${_maxLines ?? "unspecified"}, ' + 'textAlign: ${textAlign ?? "unspecified"}, ' + 'textDirection: ${textDirection ?? "unspecified"}, ' + 'fontWeight: ${fontWeight ?? "unspecified"}, ' + 'fontStyle: ${fontStyle ?? "unspecified"}, ' + 'maxLines: ${maxLines ?? "unspecified"}, ' 'textHeightBehavior: ${_textHeightBehavior ?? "unspecified"}, ' - 'fontFamily: ${_fontFamily ?? "unspecified"}, ' - 'fontSize: ${_fontSize != null ? _fontSize!.toStringAsFixed(1) : "unspecified"}, ' - 'height: ${_height != null ? "${_height!.toStringAsFixed(1)}x" : "unspecified"}, ' - 'ellipsis: ${_ellipsis != null ? "\"$_ellipsis\"" : "unspecified"}, ' - 'locale: ${_locale ?? "unspecified"}' + 'fontFamily: ${fontFamily ?? "unspecified"}, ' + 'fontSize: ${fontSize != null ? fontSize!.toStringAsFixed(1) : "unspecified"}, ' + 'height: ${height != null ? "${height!.toStringAsFixed(1)}x" : "unspecified"}, ' + 'ellipsis: ${ellipsis != null ? "\"$ellipsis\"" : "unspecified"}, ' + 'locale: ${locale ?? "unspecified"}' ')'; } else { return super.toString(); @@ -969,50 +973,31 @@ class EngineTextStyle implements ui.TextStyle { /// This constructor should be used sparingly in tests, for example. Or when /// we know for sure that not all properties are needed. EngineTextStyle.only({ - ui.Color? color, - ui.TextDecoration? decoration, - ui.Color? decorationColor, - ui.TextDecorationStyle? decorationStyle, - double? decorationThickness, - ui.FontWeight? fontWeight, - ui.FontStyle? fontStyle, - ui.TextBaseline? textBaseline, + this.color, + this.decoration, + this.decorationColor, + this.decorationStyle, + this.decorationThickness, + this.fontWeight, + this.fontStyle, + this.textBaseline, String? fontFamily, - List? fontFamilyFallback, - double? fontSize, - double? letterSpacing, - double? wordSpacing, - double? height, - ui.Locale? locale, - ui.Paint? background, - ui.Paint? foreground, - List? shadows, - List? fontFeatures, + this.fontFamilyFallback, + this.fontSize, + this.letterSpacing, + this.wordSpacing, + this.height, + this.locale, + this.background, + this.foreground, + this.shadows, + this.fontFeatures, }) : assert( color == null || foreground == null, 'Cannot provide both a color and a foreground\n' 'The color argument is just a shorthand for "foreground: new Paint()..color = color".'), - _color = color, - _decoration = decoration, - _decorationColor = decorationColor, - _decorationStyle = decorationStyle, - _decorationThickness = decorationThickness, - _fontWeight = fontWeight, - _fontStyle = fontStyle, - _textBaseline = textBaseline, - _isFontFamilyProvided = fontFamily != null, - _fontFamily = fontFamily ?? '', - _fontFamilyFallback = fontFamilyFallback, - // TODO: https://github.com/flutter/flutter/issues/56707 - _fontFeatures = fontFeatures, - _fontSize = fontSize, - _letterSpacing = letterSpacing, - _wordSpacing = wordSpacing, - _height = height, - _locale = locale, - _background = background, - _foreground = foreground, - _shadows = shadows; + isFontFamilyProvided = fontFamily != null, + fontFamily = fontFamily ?? ''; /// Constructs an [EngineTextStyle] by reading properties from an /// [EngineParagraphStyle]. @@ -1020,37 +1005,37 @@ class EngineTextStyle implements ui.TextStyle { EngineParagraphStyle paragraphStyle, ) { return EngineTextStyle.only( - fontWeight: paragraphStyle._fontWeight, - fontStyle: paragraphStyle._fontStyle, - fontFamily: paragraphStyle._fontFamily, - fontSize: paragraphStyle._fontSize, - height: paragraphStyle._height, - locale: paragraphStyle._locale, + fontWeight: paragraphStyle.fontWeight, + fontStyle: paragraphStyle.fontStyle, + fontFamily: paragraphStyle.fontFamily, + fontSize: paragraphStyle.fontSize, + height: paragraphStyle.height, + locale: paragraphStyle.locale, ); } - final ui.Color? _color; - final ui.TextDecoration? _decoration; - final ui.Color? _decorationColor; - final ui.TextDecorationStyle? _decorationStyle; - final double? _decorationThickness; - final ui.FontWeight? _fontWeight; - final ui.FontStyle? _fontStyle; - final ui.TextBaseline? _textBaseline; - final bool _isFontFamilyProvided; - final String _fontFamily; - final List? _fontFamilyFallback; - final List? _fontFeatures; - final double? _fontSize; - final double? _letterSpacing; - final double? _wordSpacing; - final double? _height; - final ui.Locale? _locale; - final ui.Paint? _background; - final ui.Paint? _foreground; - final List? _shadows; - - String get _effectiveFontFamily { + final ui.Color? color; + final ui.TextDecoration? decoration; + final ui.Color? decorationColor; + final ui.TextDecorationStyle? decorationStyle; + final double? decorationThickness; + final ui.FontWeight? fontWeight; + final ui.FontStyle? fontStyle; + final ui.TextBaseline? textBaseline; + final bool isFontFamilyProvided; + final String fontFamily; + final List? fontFamilyFallback; + final List? fontFeatures; + final double? fontSize; + final double? letterSpacing; + final double? wordSpacing; + final double? height; + final ui.Locale? locale; + final ui.Paint? background; + final ui.Paint? foreground; + final List? shadows; + + String get effectiveFontFamily { if (assertionsEnabled) { // In the flutter tester environment, we use a predictable-size font // "Ahem". This makes widget tests predictable and less flaky. @@ -1058,10 +1043,10 @@ class EngineTextStyle implements ui.TextStyle { return 'Ahem'; } } - if (_fontFamily.isEmpty) { + if (fontFamily.isEmpty) { return DomRenderer.defaultFontFamily; } - return _fontFamily; + return fontFamily; } String? _cssFontString; @@ -1070,11 +1055,11 @@ class EngineTextStyle implements ui.TextStyle { /// /// See . String get cssFontString { - return _cssFontString ??= _buildCssFontString( - fontStyle: _fontStyle, - fontWeight: _fontWeight, - fontSize: _fontSize, - fontFamily: _effectiveFontFamily, + return _cssFontString ??= buildCssFontString( + fontStyle: fontStyle, + fontWeight: fontWeight, + fontSize: fontSize, + fontFamily: effectiveFontFamily, ); } @@ -1082,9 +1067,9 @@ class EngineTextStyle implements ui.TextStyle { TextHeightStyle _createHeightStyle() { return TextHeightStyle( - fontFamily: _effectiveFontFamily, - fontSize: _fontSize ?? DomRenderer.defaultFontSize, - height: _height, + fontFamily: effectiveFontFamily, + fontSize: fontSize ?? DomRenderer.defaultFontSize, + height: height, // TODO(mdebbar): Pass the actual value when font features become supported // https://github.com/flutter/flutter/issues/64595 fontFeatures: null, @@ -1100,70 +1085,70 @@ class EngineTextStyle implements ui.TextStyle { return false; } return other is EngineTextStyle && - other._color == _color && - other._decoration == _decoration && - other._decorationColor == _decorationColor && - other._decorationStyle == _decorationStyle && - other._fontWeight == _fontWeight && - other._fontStyle == _fontStyle && - other._textBaseline == _textBaseline && - other._fontFamily == _fontFamily && - other._fontSize == _fontSize && - other._letterSpacing == _letterSpacing && - other._wordSpacing == _wordSpacing && - other._height == _height && - other._locale == _locale && - other._background == _background && - other._foreground == _foreground && - listEquals(other._shadows, _shadows) && - listEquals(other._fontFamilyFallback, _fontFamilyFallback); + other.color == color && + other.decoration == decoration && + other.decorationColor == decorationColor && + other.decorationStyle == decorationStyle && + other.fontWeight == fontWeight && + other.fontStyle == fontStyle && + other.textBaseline == textBaseline && + other.fontFamily == fontFamily && + other.fontSize == fontSize && + other.letterSpacing == letterSpacing && + other.wordSpacing == wordSpacing && + other.height == height && + other.locale == locale && + other.background == background && + other.foreground == foreground && + listEquals(other.shadows, shadows) && + listEquals(other.fontFamilyFallback, fontFamilyFallback); } @override int get hashCode => ui.hashValues( - _color, - _decoration, - _decorationColor, - _decorationStyle, - _decorationThickness, - _fontWeight, - _fontStyle, - _textBaseline, - _fontFamily, - _fontFamilyFallback, - _fontSize, - _letterSpacing, - _wordSpacing, - _height, - _locale, - _background, - _foreground, - _shadows, + color, + decoration, + decorationColor, + decorationStyle, + decorationThickness, + fontWeight, + fontStyle, + textBaseline, + fontFamily, + fontFamilyFallback, + fontSize, + letterSpacing, + wordSpacing, + height, + locale, + background, + foreground, + shadows, ); @override String toString() { if (assertionsEnabled) { return 'TextStyle(' - 'color: ${_color != null ? _color : "unspecified"}, ' - 'decoration: ${_decoration ?? "unspecified"}, ' - 'decorationColor: ${_decorationColor ?? "unspecified"}, ' - 'decorationStyle: ${_decorationStyle ?? "unspecified"}, ' - 'decorationThickness: ${_decorationThickness ?? "unspecified"}, ' - 'fontWeight: ${_fontWeight ?? "unspecified"}, ' - 'fontStyle: ${_fontStyle ?? "unspecified"}, ' - 'textBaseline: ${_textBaseline ?? "unspecified"}, ' - 'fontFamily: ${_isFontFamilyProvided && _fontFamily != '' ? _fontFamily : "unspecified"}, ' - 'fontFamilyFallback: ${_isFontFamilyProvided && _fontFamilyFallback != null && _fontFamilyFallback!.isNotEmpty ? _fontFamilyFallback : "unspecified"}, ' - 'fontSize: ${_fontSize != null ? _fontSize!.toStringAsFixed(1) : "unspecified"}, ' - 'letterSpacing: ${_letterSpacing != null ? "${_letterSpacing}x" : "unspecified"}, ' - 'wordSpacing: ${_wordSpacing != null ? "${_wordSpacing}x" : "unspecified"}, ' - 'height: ${_height != null ? "${_height!.toStringAsFixed(1)}x" : "unspecified"}, ' - 'locale: ${_locale ?? "unspecified"}, ' - 'background: ${_background ?? "unspecified"}, ' - 'foreground: ${_foreground ?? "unspecified"}, ' - 'shadows: ${_shadows ?? "unspecified"}, ' - 'fontFeatures: ${_fontFeatures ?? "unspecified"}' + 'color: ${color != null ? color : "unspecified"}, ' + 'decoration: ${decoration ?? "unspecified"}, ' + 'decorationColor: ${decorationColor ?? "unspecified"}, ' + 'decorationStyle: ${decorationStyle ?? "unspecified"}, ' + 'decorationThickness: ${decorationThickness ?? "unspecified"}, ' + 'fontWeight: ${fontWeight ?? "unspecified"}, ' + 'fontStyle: ${fontStyle ?? "unspecified"}, ' + 'textBaseline: ${textBaseline ?? "unspecified"}, ' + 'fontFamily: ${isFontFamilyProvided && fontFamily != '' ? fontFamily : "unspecified"}, ' + 'fontFamilyFallback: ${isFontFamilyProvided && fontFamilyFallback != null && fontFamilyFallback!.isNotEmpty ? fontFamilyFallback : "unspecified"}, ' + 'fontSize: ${fontSize != null ? fontSize!.toStringAsFixed(1) : "unspecified"}, ' + 'letterSpacing: ${letterSpacing != null ? "${letterSpacing}x" : "unspecified"}, ' + 'wordSpacing: ${wordSpacing != null ? "${wordSpacing}x" : "unspecified"}, ' + 'height: ${height != null ? "${height!.toStringAsFixed(1)}x" : "unspecified"}, ' + 'locale: ${locale ?? "unspecified"}, ' + 'background: ${background ?? "unspecified"}, ' + 'foreground: ${foreground ?? "unspecified"}, ' + 'shadows: ${shadows ?? "unspecified"}, ' + 'fontFeatures: ${fontFeatures ?? "unspecified"}' ')'; } else { return super.toString(); @@ -1362,21 +1347,20 @@ class DomParagraphBuilder implements ui.ParagraphBuilder { ui.Color? decorationColor; ui.TextDecorationStyle? decorationStyle; double? decorationThickness; - ui.FontWeight? fontWeight = _paragraphStyle._fontWeight; - ui.FontStyle? fontStyle = _paragraphStyle._fontStyle; + ui.FontWeight? fontWeight = _paragraphStyle.fontWeight; + ui.FontStyle? fontStyle = _paragraphStyle.fontStyle; ui.TextBaseline? textBaseline; String fontFamily = - _paragraphStyle._fontFamily ?? DomRenderer.defaultFontFamily; + _paragraphStyle.fontFamily ?? DomRenderer.defaultFontFamily; List? fontFamilyFallback; List? fontFeatures; - double fontSize = _paragraphStyle._fontSize ?? DomRenderer.defaultFontSize; - final ui.TextAlign textAlign = _paragraphStyle._effectiveTextAlign; - final ui.TextDirection textDirection = - _paragraphStyle._effectiveTextDirection; + double fontSize = _paragraphStyle.fontSize ?? DomRenderer.defaultFontSize; + final ui.TextAlign textAlign = _paragraphStyle.effectiveTextAlign; + final ui.TextDirection textDirection = _paragraphStyle.effectiveTextDirection; double? letterSpacing; double? wordSpacing; double? height; - ui.Locale? locale = _paragraphStyle._locale; + ui.Locale? locale = _paragraphStyle.locale; ui.Paint? background; ui.Paint? foreground; List? shadows; @@ -1389,66 +1373,66 @@ class DomParagraphBuilder implements ui.ParagraphBuilder { // loop to run once then move on to aggregating text. while (i < _ops.length && _ops[i] is EngineTextStyle) { final EngineTextStyle style = _ops[i]; - if (style._color != null) { - color = style._color!; + if (style.color != null) { + color = style.color!; } - if (style._decoration != null) { - decoration = style._decoration; + if (style.decoration != null) { + decoration = style.decoration; } - if (style._decorationColor != null) { - decorationColor = style._decorationColor; + if (style.decorationColor != null) { + decorationColor = style.decorationColor; } - if (style._decorationStyle != null) { - decorationStyle = style._decorationStyle; + if (style.decorationStyle != null) { + decorationStyle = style.decorationStyle; } - if (style._decorationThickness != null) { - decorationThickness = style._decorationThickness; + if (style.decorationThickness != null) { + decorationThickness = style.decorationThickness; } - if (style._fontWeight != null) { - fontWeight = style._fontWeight; + if (style.fontWeight != null) { + fontWeight = style.fontWeight; } - if (style._fontStyle != null) { - fontStyle = style._fontStyle; + if (style.fontStyle != null) { + fontStyle = style.fontStyle; } - if (style._textBaseline != null) { - textBaseline = style._textBaseline; + if (style.textBaseline != null) { + textBaseline = style.textBaseline; } - fontFamily = style._fontFamily; - if (style._fontFamilyFallback != null) { - fontFamilyFallback = style._fontFamilyFallback; + fontFamily = style.fontFamily; + if (style.fontFamilyFallback != null) { + fontFamilyFallback = style.fontFamilyFallback; } - if (style._fontFeatures != null) { - fontFeatures = style._fontFeatures; + if (style.fontFeatures != null) { + fontFeatures = style.fontFeatures; } - if (style._fontSize != null) { - fontSize = style._fontSize!; + if (style.fontSize != null) { + fontSize = style.fontSize!; } - if (style._letterSpacing != null) { - letterSpacing = style._letterSpacing; + if (style.letterSpacing != null) { + letterSpacing = style.letterSpacing; } - if (style._wordSpacing != null) { - wordSpacing = style._wordSpacing; + if (style.wordSpacing != null) { + wordSpacing = style.wordSpacing; } - if (style._height != null) { - height = style._height; + if (style.height != null) { + height = style.height; } - if (style._locale != null) { - locale = style._locale; + if (style.locale != null) { + locale = style.locale; } - if (style._background != null) { - background = style._background; + if (style.background != null) { + background = style.background; } - if (style._foreground != null) { - foreground = style._foreground; + if (style.foreground != null) { + foreground = style.foreground; } - if (style._shadows != null) { - shadows = style._shadows; + if (style.shadows != null) { + shadows = style.shadows; } i++; } if (color == null && foreground == null) { - color = _defaultTextColor; + color = defaultTextColor; } final EngineTextStyle cumulativeStyle = EngineTextStyle( @@ -1483,30 +1467,30 @@ class DomParagraphBuilder implements ui.ParagraphBuilder { if (i >= _ops.length) { // Empty paragraph. - _applyTextStyleToElement( + applyTextStyleToElement( element: _paragraphElement, style: cumulativeStyle); return DomParagraph( paragraphElement: _paragraphElement, geometricStyle: ParagraphGeometricStyle( - textDirection: _paragraphStyle._effectiveTextDirection, - textAlign: _paragraphStyle._effectiveTextAlign, + textDirection: _paragraphStyle.effectiveTextDirection, + textAlign: _paragraphStyle.effectiveTextAlign, fontFamily: fontFamily, fontWeight: fontWeight, fontStyle: fontStyle, fontSize: fontSize, lineHeight: height, - maxLines: _paragraphStyle._maxLines, + maxLines: _paragraphStyle.maxLines, letterSpacing: letterSpacing, wordSpacing: wordSpacing, decoration: _textDecorationToCssString(decoration, decorationStyle), - ellipsis: _paragraphStyle._ellipsis, + ellipsis: _paragraphStyle.ellipsis, shadows: shadows, ), plainText: '', paint: paint, textAlign: textAlign, textDirection: textDirection, - background: cumulativeStyle._background, + background: cumulativeStyle.background, placeholderCount: placeholderCount, ); } @@ -1534,36 +1518,36 @@ class DomParagraphBuilder implements ui.ParagraphBuilder { final String plainText = plainTextBuffer.toString(); domRenderer.appendText(_paragraphElement, plainText); - _applyTextStyleToElement( + applyTextStyleToElement( element: _paragraphElement, style: cumulativeStyle); // Since this is a plain paragraph apply background color to paragraph tag // instead of individual spans. - if (cumulativeStyle._background != null) { + if (cumulativeStyle.background != null) { _applyTextBackgroundToElement( element: _paragraphElement, style: cumulativeStyle); } return DomParagraph( paragraphElement: _paragraphElement, geometricStyle: ParagraphGeometricStyle( - textDirection: _paragraphStyle._effectiveTextDirection, - textAlign: _paragraphStyle._effectiveTextAlign, + textDirection: _paragraphStyle.effectiveTextDirection, + textAlign: _paragraphStyle.effectiveTextAlign, fontFamily: fontFamily, fontWeight: fontWeight, fontStyle: fontStyle, fontSize: fontSize, lineHeight: height, - maxLines: _paragraphStyle._maxLines, + maxLines: _paragraphStyle.maxLines, letterSpacing: letterSpacing, wordSpacing: wordSpacing, decoration: _textDecorationToCssString(decoration, decorationStyle), - ellipsis: _paragraphStyle._ellipsis, + ellipsis: _paragraphStyle.ellipsis, shadows: shadows, ), plainText: plainText, paint: paint, textAlign: textAlign, textDirection: textDirection, - background: cumulativeStyle._background, + background: cumulativeStyle.background, placeholderCount: placeholderCount, ); } @@ -1577,10 +1561,9 @@ class DomParagraphBuilder implements ui.ParagraphBuilder { for (int i = 0; i < _ops.length; i++) { final dynamic op = _ops[i]; if (op is EngineTextStyle) { - final html.SpanElement span = - domRenderer.createElement('span') as html.SpanElement; - _applyTextStyleToElement(element: span, style: op, isSpan: true); - if (op._background != null) { + final html.SpanElement span = domRenderer.createElement('span') as html.SpanElement; + applyTextStyleToElement(element: span, style: op, isSpan: true); + if (op.background != null) { _applyTextBackgroundToElement(element: span, style: op); } domRenderer.append(currentElement(), span); @@ -1590,7 +1573,7 @@ class DomParagraphBuilder implements ui.ParagraphBuilder { } else if (op is ParagraphPlaceholder) { domRenderer.append( currentElement(), - _createPlaceholderElement(placeholder: op), + createPlaceholderElement(placeholder: op), ); } else if (identical(op, _paragraphBuilderPop)) { elementStack.removeLast(); @@ -1602,20 +1585,20 @@ class DomParagraphBuilder implements ui.ParagraphBuilder { return DomParagraph( paragraphElement: _paragraphElement, geometricStyle: ParagraphGeometricStyle( - textDirection: _paragraphStyle._effectiveTextDirection, - textAlign: _paragraphStyle._effectiveTextAlign, - fontFamily: _paragraphStyle._fontFamily, - fontWeight: _paragraphStyle._fontWeight, - fontStyle: _paragraphStyle._fontStyle, - fontSize: _paragraphStyle._fontSize, - lineHeight: _paragraphStyle._height, - maxLines: _paragraphStyle._maxLines, - ellipsis: _paragraphStyle._ellipsis, + textDirection: _paragraphStyle.effectiveTextDirection, + textAlign: _paragraphStyle.effectiveTextAlign, + fontFamily: _paragraphStyle.fontFamily, + fontWeight: _paragraphStyle.fontWeight, + fontStyle: _paragraphStyle.fontStyle, + fontSize: _paragraphStyle.fontSize, + lineHeight: _paragraphStyle.height, + maxLines: _paragraphStyle.maxLines, + ellipsis: _paragraphStyle.ellipsis, ), plainText: null, paint: null, - textAlign: _paragraphStyle._effectiveTextAlign, - textDirection: _paragraphStyle._effectiveTextDirection, + textAlign: _paragraphStyle.effectiveTextAlign, + textDirection: _paragraphStyle.effectiveTextDirection, background: null, placeholderCount: placeholderCount, ); @@ -1703,25 +1686,25 @@ void _applyParagraphStyleToElement({ // TODO(yjbanov): What do we do about ParagraphStyle._locale and ellipsis? final html.CssStyleDeclaration cssStyle = element.style; - if (style._textAlign != null) { + if (style.textAlign != null) { cssStyle.textAlign = textAlignToCssValue( - style._textAlign, style._textDirection ?? ui.TextDirection.ltr); + style.textAlign, style.textDirection ?? ui.TextDirection.ltr); } - if (style._lineHeight != null) { - cssStyle.lineHeight = '${style._lineHeight}'; + if (style.lineHeight != null) { + cssStyle.lineHeight = '${style.lineHeight}'; } - if (style._textDirection != null) { - cssStyle.direction = _textDirectionToCss(style._textDirection); + if (style.textDirection != null) { + cssStyle.direction = textDirectionToCss(style.textDirection); } - if (style._fontSize != null) { - cssStyle.fontSize = '${style._fontSize!.floor()}px'; + if (style.fontSize != null) { + cssStyle.fontSize = '${style.fontSize!.floor()}px'; } - if (style._fontWeight != null) { - cssStyle.fontWeight = fontWeightToCss(style._fontWeight); + if (style.fontWeight != null) { + cssStyle.fontWeight = fontWeightToCss(style.fontWeight); } - if (style._fontStyle != null) { + if (style.fontStyle != null) { cssStyle.fontStyle = - style._fontStyle == ui.FontStyle.normal ? 'normal' : 'italic'; + style.fontStyle == ui.FontStyle.normal ? 'normal' : 'italic'; } cssStyle.fontFamily = canonicalizeFontFamily(style._effectiveFontFamily); } @@ -1731,7 +1714,7 @@ void _applyParagraphStyleToElement({ /// /// If [isSpan] is true, the text element is a span within richtext and /// should not assign effectiveFontFamily if fontFamily was not specified. -void _applyTextStyleToElement({ +void applyTextStyleToElement({ required html.HtmlElement element, required EngineTextStyle style, bool isSpan = false, @@ -1741,47 +1724,47 @@ void _applyTextStyleToElement({ bool updateDecoration = false; final html.CssStyleDeclaration cssStyle = element.style; - final ui.Color? color = style._foreground?.color ?? style._color; + final ui.Color? color = style.foreground?.color ?? style.color; if (color != null) { cssStyle.color = colorToCssString(color); } - if (style._height != null) { - cssStyle.lineHeight = '${style._height}'; + if (style.height != null) { + cssStyle.lineHeight = '${style.height}'; } - if (style._fontSize != null) { - cssStyle.fontSize = '${style._fontSize!.floor()}px'; + if (style.fontSize != null) { + cssStyle.fontSize = '${style.fontSize!.floor()}px'; } - if (style._fontWeight != null) { - cssStyle.fontWeight = fontWeightToCss(style._fontWeight); + if (style.fontWeight != null) { + cssStyle.fontWeight = fontWeightToCss(style.fontWeight); } - if (style._fontStyle != null) { + if (style.fontStyle != null) { cssStyle.fontStyle = - style._fontStyle == ui.FontStyle.normal ? 'normal' : 'italic'; + style.fontStyle == ui.FontStyle.normal ? 'normal' : 'italic'; } // For test environment use effectiveFontFamily since we need to // consistently use Ahem font. if (isSpan && !ui.debugEmulateFlutterTesterEnvironment) { - cssStyle.fontFamily = canonicalizeFontFamily(style._fontFamily); + cssStyle.fontFamily = canonicalizeFontFamily(style.fontFamily); } else { - cssStyle.fontFamily = canonicalizeFontFamily(style._effectiveFontFamily); + cssStyle.fontFamily = canonicalizeFontFamily(style.effectiveFontFamily); } - if (style._letterSpacing != null) { - cssStyle.letterSpacing = '${style._letterSpacing}px'; + if (style.letterSpacing != null) { + cssStyle.letterSpacing = '${style.letterSpacing}px'; } - if (style._wordSpacing != null) { - cssStyle.wordSpacing = '${style._wordSpacing}px'; + if (style.wordSpacing != null) { + cssStyle.wordSpacing = '${style.wordSpacing}px'; } - if (style._decoration != null) { + if (style.decoration != null) { updateDecoration = true; } - if (style._shadows != null) { - cssStyle.textShadow = _shadowListToCss(style._shadows!); + if (style.shadows != null) { + cssStyle.textShadow = _shadowListToCss(style.shadows!); } if (updateDecoration) { - if (style._decoration != null) { + if (style.decoration != null) { final String? textDecoration = - _textDecorationToCssString(style._decoration, style._decorationStyle); + _textDecorationToCssString(style.decoration, style.decorationStyle); if (textDecoration != null) { if (browserEngine == BrowserEngine.webkit) { DomRenderer.setElementStyle( @@ -1789,7 +1772,7 @@ void _applyTextStyleToElement({ } else { cssStyle.textDecoration = textDecoration; } - final ui.Color? decorationColor = style._decorationColor; + final ui.Color? decorationColor = style.decorationColor; if (decorationColor != null) { cssStyle.textDecorationColor = colorToCssString(decorationColor)!; } @@ -1797,17 +1780,17 @@ void _applyTextStyleToElement({ } } - final List? fontFeatures = style._fontFeatures; + final List? fontFeatures = style.fontFeatures; if (fontFeatures != null && fontFeatures.isNotEmpty) { cssStyle.fontFeatureSettings = _fontFeatureListToCss(fontFeatures); } } -html.Element _createPlaceholderElement({ +html.Element createPlaceholderElement({ required ParagraphPlaceholder placeholder, }) { final html.Element element = domRenderer.createElement('span'); - element.className = _placeholderClass; + element.className = placeholderClass; final html.CssStyleDeclaration style = element.style; style ..display = 'inline-block' @@ -1892,7 +1875,7 @@ void _applyTextBackgroundToElement({ required html.HtmlElement element, required EngineTextStyle style, }) { - final ui.Paint? newBackground = style._background; + final ui.Paint? newBackground = style.background; if (newBackground != null) { DomRenderer.setElementStyle( element, 'background-color', colorToCssString(newBackground.color)); @@ -1944,7 +1927,7 @@ String? _decorationStyleToCssString(ui.TextDecorationStyle decorationStyle) { /// ```css /// direction: rtl; /// ``` -String? _textDirectionToCss(ui.TextDirection? textDirection) { +String? textDirectionToCss(ui.TextDirection? textDirection) { if (textDirection == null) { return null; } diff --git a/lib/web_ui/lib/src/engine/text/ruler.dart b/lib/web_ui/lib/src/engine/text/ruler.dart index d2b67e0039492..819ef198950ca 100644 --- a/lib/web_ui/lib/src/engine/text/ruler.dart +++ b/lib/web_ui/lib/src/engine/text/ruler.dart @@ -2,9 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -part of engine; +import 'dart:html' as html; -String _buildCssFontString({ +import 'package:meta/meta.dart'; +import 'package:ui/ui.dart' as ui; +import 'package:ui/src/engine.dart' show assertionsEnabled, canonicalizeFontFamily, domRenderer, DomRenderer; + +import '../browser_detection.dart'; +import 'measurement.dart'; +import 'paragraph.dart'; + +String buildCssFontString({ required ui.FontStyle? fontStyle, required ui.FontWeight? fontWeight, required double? fontSize, @@ -101,7 +109,7 @@ class ParagraphGeometricStyle { /// /// See . String get cssFontString { - return _cssFontString ??= _buildCssFontString( + return _cssFontString ??= buildCssFontString( fontStyle: fontStyle, fontWeight: fontWeight, fontSize: fontSize, @@ -245,7 +253,7 @@ class TextDimensions { void updateText(DomParagraph from, ParagraphGeometricStyle style) { assert(from != null); // ignore: unnecessary_null_comparison assert(_element != null); // ignore: unnecessary_null_comparison - assert(from._debugHasSameRootStyle(style)); + assert(from.debugHasSameRootStyle(style)); assert(() { final bool wasEmptyOrPlainText = _element.childNodes.isEmpty || (_element.childNodes.length == 1 && @@ -261,7 +269,7 @@ class TextDimensions { }()); _invalidateBoundsCache(); - final String? plainText = from._plainText; + final String? plainText = from.plainText; if (plainText != null) { // Plain text: just set the string. The paragraph's style is assumed to // match the style set on the `element`. Setting text as plain string is @@ -278,7 +286,7 @@ class TextDimensions { } else { // Rich text: deeply copy contents. This is the slow case that should be // avoided if fast layout performance is desired. - final html.Element copy = from._paragraphElement.clone(true) as html.Element; + final html.Element copy = from.paragraphElement.clone(true) as html.Element; _element.nodes.addAll(copy.nodes); } } @@ -319,7 +327,7 @@ class TextDimensions { void applyStyle(ParagraphGeometricStyle style) { final html.CssStyleDeclaration elementStyle = _element.style; elementStyle - ..direction = _textDirectionToCss(style.textDirection) + ..direction = textDirectionToCss(style.textDirection) ..textAlign = textAlignToCssValue(style.textAlign, style.textDirection) ..fontSize = style.fontSize != null ? '${style.fontSize!.floor()}px' : null ..fontFamily = canonicalizeFontFamily(style.effectiveFontFamily) @@ -675,7 +683,7 @@ class ParagraphRuler { } return true; }()); - assert(paragraph._debugHasSameRootStyle(style)); + assert(paragraph.debugHasSameRootStyle(style)); _paragraph = paragraph; } @@ -701,7 +709,7 @@ class ParagraphRuler { // which doesn't work. So we need to replace it with a whitespace. The // correct fix would be to do line height and baseline measurements and // cache them separately. - if (_paragraph!._plainText == '') { + if (_paragraph!.plainText == '') { singleLineDimensions.updateTextToSpace(); } else { singleLineDimensions.updateText(_paragraph!, style); @@ -739,14 +747,16 @@ class ParagraphRuler { List measurePlaceholderBoxes() { assert(!_debugIsDisposed); - assert(_paragraph != null); - if (_paragraph!.placeholderCount == 0) { + final DomParagraph? paragraph = _paragraph; + assert(paragraph != null); + + if (paragraph!.placeholderCount == 0) { return const []; } final List placeholderElements = - constrainedDimensions._element.querySelectorAll('.$_placeholderClass'); + constrainedDimensions._element.querySelectorAll('.$placeholderClass'); final List boxes = []; for (final html.Element element in placeholderElements) { @@ -756,7 +766,7 @@ class ParagraphRuler { rect.top as double, rect.right as double, rect.bottom as double, - _paragraph!._textDirection, + paragraph.textDirection, )); } return boxes; @@ -842,7 +852,7 @@ class ParagraphRuler { // // We do not do this for plain text, because replacing plain text is more // expensive than paying the cost of the DOM mutation to clean it. - if (_paragraph!._plainText == null) { + if (_paragraph!.plainText == null) { domRenderer ..clearDom(singleLineDimensions._element) ..clearDom(minIntrinsicDimensions._element) @@ -953,7 +963,7 @@ class ParagraphRuler { static const int _constraintCacheSize = 8; void cacheMeasurement(DomParagraph paragraph, MeasurementResult? item) { - final String? plainText = paragraph._plainText; + final String? plainText = paragraph.plainText; final List constraintCache = _measurementCache[plainText] ??= []; constraintCache.add(item); @@ -972,7 +982,7 @@ class ParagraphRuler { MeasurementResult? cacheLookup( DomParagraph paragraph, ui.ParagraphConstraints constraints) { - final String? plainText = paragraph._plainText; + final String? plainText = paragraph.plainText; if (plainText == null) { // Multi span paragraph, do not use cache item. return null; @@ -986,8 +996,8 @@ class ParagraphRuler { for (int i = 0; i < len; i++) { final MeasurementResult item = constraintCache[i]!; if (item.constraintWidth == constraints.width && - item.textAlign == paragraph._textAlign && - item.textDirection == paragraph._textDirection) { + item.textAlign == paragraph.textAlign && + item.textDirection == paragraph.textDirection) { return item; } } diff --git a/lib/web_ui/lib/src/engine/text/unicode_range.dart b/lib/web_ui/lib/src/engine/text/unicode_range.dart index 7c28f5c71c45f..4c96d6043efae 100644 --- a/lib/web_ui/lib/src/engine/text/unicode_range.dart +++ b/lib/web_ui/lib/src/engine/text/unicode_range.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. -part of engine; - const int _kChar_0 = 48; const int _kChar_9 = 57; const int _kChar_A = 65; diff --git a/lib/web_ui/lib/src/engine/text/word_break_properties.dart b/lib/web_ui/lib/src/engine/text/word_break_properties.dart index 6dd5ce28f60bf..6c94e513ece2e 100644 --- a/lib/web_ui/lib/src/engine/text/word_break_properties.dart +++ b/lib/web_ui/lib/src/engine/text/word_break_properties.dart @@ -12,7 +12,7 @@ // # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. // # For terms of use, see http://www.unicode.org/terms_of_use.html -part of engine; +import 'unicode_range.dart'; /// For an explanation of these enum values, see: /// diff --git a/lib/web_ui/lib/src/engine/text/word_breaker.dart b/lib/web_ui/lib/src/engine/text/word_breaker.dart index ad67af32ebd97..c57273f7c6f18 100644 --- a/lib/web_ui/lib/src/engine/text/word_breaker.dart +++ b/lib/web_ui/lib/src/engine/text/word_breaker.dart @@ -2,7 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -part of engine; + +import 'package:ui/src/engine.dart' show clampInt; + +import 'word_break_properties.dart'; class _FindBreakDirection { static const _FindBreakDirection forward = _FindBreakDirection(step: 1); diff --git a/lib/web_ui/tool/unicode_sync_script.dart b/lib/web_ui/tool/unicode_sync_script.dart index 8655038758f96..679ad6dfe55ab 100644 --- a/lib/web_ui/tool/unicode_sync_script.dart +++ b/lib/web_ui/tool/unicode_sync_script.dart @@ -205,7 +205,7 @@ abstract class PropertiesSyncer { // Source: // ${header.join('\n// ')} -part of engine; +import 'unicode_range.dart'; /// For an explanation of these enum values, see: /// From baaa9c2d191f57c8468b8630e926776522ca8b0b Mon Sep 17 00:00:00 2001 From: Mouad Debbar Date: Wed, 23 Jun 2021 12:52:58 -0700 Subject: [PATCH 2/2] remove unnecessary comments --- lib/web_ui/lib/src/engine.dart | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/lib/web_ui/lib/src/engine.dart b/lib/web_ui/lib/src/engine.dart index f6cd187d1c416..a8542b8b1e8fc 100644 --- a/lib/web_ui/lib/src/engine.dart +++ b/lib/web_ui/lib/src/engine.dart @@ -141,42 +141,26 @@ export 'engine/test_embedding.dart'; import 'engine/text/layout_service.dart'; export 'engine/text/layout_service.dart'; -// This import is intentionally commented out because the analyzer says it's unused. -// import 'engine/text/line_break_properties.dart'; export 'engine/text/line_break_properties.dart'; -// This import is intentionally commented out because the analyzer says it's unused. -// import 'engine/text/line_breaker.dart'; export 'engine/text/line_breaker.dart'; import 'engine/text/measurement.dart'; export 'engine/text/measurement.dart'; -// This import is intentionally commented out because the analyzer says it's unused. -// import 'engine/text/paint_service.dart'; export 'engine/text/paint_service.dart'; import 'engine/text/paragraph.dart'; export 'engine/text/paragraph.dart'; -// This import is intentionally commented out because the analyzer says it's unused. -// import 'engine/text/canvas_paragraph.dart'; export 'engine/text/canvas_paragraph.dart'; -// This import is intentionally commented out because the analyzer says it's unused. -// import 'engine/text/ruler.dart'; export 'engine/text/ruler.dart'; -// This import is intentionally commented out because the analyzer says it's unused. -// import 'engine/text/unicode_range.dart'; export 'engine/text/unicode_range.dart'; -// This import is intentionally commented out because the analyzer says it's unused. -// import 'engine/text/word_break_properties.dart'; export 'engine/text/word_break_properties.dart'; -// This import is intentionally commented out because the analyzer says it's unused. -// import 'engine/text/word_breaker.dart'; export 'engine/text/word_breaker.dart';