From 81c875cfda41322e3f96ecb5e0245d1c0971e5b8 Mon Sep 17 00:00:00 2001 From: GaryQian Date: Tue, 23 Oct 2018 11:29:29 -0700 Subject: [PATCH 1/4] Add API for GetBoxesForRange styles. --- lib/ui/text.dart | 68 +++++++++++++++++++++++++++++++++++++++- lib/ui/text/paragraph.cc | 9 ++++-- lib/ui/text/paragraph.h | 5 ++- 3 files changed, 77 insertions(+), 5 deletions(-) diff --git a/lib/ui/text.dart b/lib/ui/text.dart index 664cbaedef276..beef94bcb23cf 100644 --- a/lib/ui/text.dart +++ b/lib/ui/text.dart @@ -947,6 +947,68 @@ class ParagraphConstraints { String toString() => '$runtimeType(width: $width)'; } +/// Defines various ways to vertically bound the boxes returned by +/// [Paragraph.getBoxesForRange]. +enum BoxHeightStyle { + /// Provide tight bounding boxes that fit heights per run. This style may result + /// in uneven bounding boxes that do not nicely connect with the boxes above, + /// below, and adjacent. + tight, + + /// The height of the boxes will be the maximum height of all runs in the + /// line. All boxes in the same line will be the same height. This does not + /// guarantee that the boxes will cover the entire vertical height of the line + /// when there is additional line spacing. + /// + /// See [RectHeightStyle.includeLineSpacingTop], [RectHeightStyle.includeLineSpacingMiddle], + /// and [RectHeightStyle.includeLineSpacingBottom] for styles that will cover + /// the entire line. + max, + + /// Extends the top and bottom edge of the bounds to fully cover any line + /// spacing. + /// + /// The top and bottom of each box will cover half of the + /// space above and half of the space below the line. The text should be + /// centered vertically within the box. + /// + /// {@template flutter.dart:ui.boxHeightStyle.includeLineSpacing} + /// The top edge of each line should be the same as the bottom edge + /// of the line above. There should be no gaps in vertical coverage given any + /// amount of line spacing. Line spacing is not included above the first line + /// below the last line due to no additional space present there. + /// {@endtemplate} + includeLineSpacingMiddle, + + /// Extends the top edge of the bounds to fully cover any line spacing. + /// + /// The line spacing will be added to the top of the box. + /// + /// {@macro flutter.dart:ui.rectHeightStyle.includeLineSpacing} + includeLineSpacingTop, + + /// Extends the bottom edge of the bounds to fully cover any line spacing. + /// + /// The line spacing will be added to the bottom of the box. + /// + /// {@macro flutter.dart:ui.boxHeightStyle.includeLineSpacing} + includeLineSpacingBottom, +} + +/// Defines various ways to horizontally bound the boxes returned by +/// [Paragraph.getBoxesForRange]. +enum BoxWidthStyle { + // Provide tight bounding boxes that fit widths to the runs of each line + // independently. + tight, + + /// Adds up to two additional boxes as needed at the beginning and/or end + /// of each line so that the widths of the boxes in line are the same width + /// as the widest line in the paragraph. The additional boxes are only added + /// when the first/last box does not span the max width of the paragraph. + max, +} + /// A paragraph of text. /// /// A paragraph retains the size and position of each glyph in the text and can @@ -1010,7 +1072,11 @@ class Paragraph extends NativeFieldWrapperClass2 { void _layout(double width) native 'Paragraph_layout'; /// Returns a list of text boxes that enclose the given text range. - List getBoxesForRange(int start, int end) native 'Paragraph_getRectsForRange'; + List getBoxesForRange(int start, int end, {BoxHeightStyle boxHeightStyle = BoxHeightStyle.tight, BoxWidthStyle boxWidthStyle = BoxWidthStyle.tight}) { + return _getBoxesForRange(start, end, boxHeightStyle.index, boxWidthStyle.index); + } + + List _getBoxesForRange(int start, int end, int boxHeightStyle, int boxWidthStyle) native 'Paragraph_getRectsForRange'; /// Returns the text position closest to the given offset. TextPosition getPositionForOffset(Offset offset) { diff --git a/lib/ui/text/paragraph.cc b/lib/ui/text/paragraph.cc index 1821bf9dd3a7a..46d30fa7934d0 100644 --- a/lib/ui/text/paragraph.cc +++ b/lib/ui/text/paragraph.cc @@ -84,10 +84,13 @@ void Paragraph::paint(Canvas* canvas, double x, double y) { m_paragraphImpl->paint(canvas, x, y); } -std::vector Paragraph::getRectsForRange(unsigned start, unsigned end) { +std::vector Paragraph::getRectsForRange(unsigned start, + unsigned end, + unsigned boxHeightStyle, + unsigned boxWidthStyle) { return m_paragraphImpl->getRectsForRange( - start, end, txt::Paragraph::RectHeightStyle::kTight, - txt::Paragraph::RectWidthStyle::kTight); + start, end, static_cast(boxHeightStyle), + static_cast(boxWidthStyle)); } Dart_Handle Paragraph::getPositionForOffset(double dx, double dy) { diff --git a/lib/ui/text/paragraph.h b/lib/ui/text/paragraph.h index e5f5e2bddb703..d8c0c4a89d462 100644 --- a/lib/ui/text/paragraph.h +++ b/lib/ui/text/paragraph.h @@ -42,7 +42,10 @@ class Paragraph : public RefCountedDartWrappable { void layout(double width); void paint(Canvas* canvas, double x, double y); - std::vector getRectsForRange(unsigned start, unsigned end); + std::vector getRectsForRange(unsigned start, + unsigned end, + unsigned boxHeightStyle, + unsigned boxWidthStyle); Dart_Handle getPositionForOffset(double dx, double dy); Dart_Handle getWordBoundary(unsigned offset); From bf49003aa9e9377e7c47a079666729578dc3897c Mon Sep 17 00:00:00 2001 From: GaryQian Date: Tue, 23 Oct 2018 16:22:25 -0700 Subject: [PATCH 2/4] Additional docs --- lib/ui/text.dart | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/ui/text.dart b/lib/ui/text.dart index beef94bcb23cf..05e63255df65c 100644 --- a/lib/ui/text.dart +++ b/lib/ui/text.dart @@ -1072,6 +1072,13 @@ class Paragraph extends NativeFieldWrapperClass2 { void _layout(double width) native 'Paragraph_layout'; /// Returns a list of text boxes that enclose the given text range. + /// + /// [boxHeightStyle] and [boxWidthStyle] allow customization of how the boxes + /// are bound vertically and horizontally. Both style parameters default to + /// the tight option, which will provide close fitting boxes and will not + /// account for any line spacing. + /// + /// See [BoxHeightStyle] and [BoxWidthStyle] for full descriptions of each option. List getBoxesForRange(int start, int end, {BoxHeightStyle boxHeightStyle = BoxHeightStyle.tight, BoxWidthStyle boxWidthStyle = BoxWidthStyle.tight}) { return _getBoxesForRange(start, end, boxHeightStyle.index, boxWidthStyle.index); } From d0a955f675763db1b7a62a414ac07c05cbabe6c3 Mon Sep 17 00:00:00 2001 From: GaryQian Date: Wed, 24 Oct 2018 13:34:41 -0700 Subject: [PATCH 3/4] Docs fixes --- lib/ui/text.dart | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/ui/text.dart b/lib/ui/text.dart index 05e63255df65c..95673a605e641 100644 --- a/lib/ui/text.dart +++ b/lib/ui/text.dart @@ -951,8 +951,7 @@ class ParagraphConstraints { /// [Paragraph.getBoxesForRange]. enum BoxHeightStyle { /// Provide tight bounding boxes that fit heights per run. This style may result - /// in uneven bounding boxes that do not nicely connect with the boxes above, - /// below, and adjacent. + /// in uneven bounding boxes that do not nicely connect with adjacent boxes. tight, /// The height of the boxes will be the maximum height of all runs in the @@ -969,14 +968,13 @@ enum BoxHeightStyle { /// spacing. /// /// The top and bottom of each box will cover half of the - /// space above and half of the space below the line. The text should be - /// centered vertically within the box. + /// space above and half of the space below the line. /// /// {@template flutter.dart:ui.boxHeightStyle.includeLineSpacing} /// The top edge of each line should be the same as the bottom edge /// of the line above. There should be no gaps in vertical coverage given any /// amount of line spacing. Line spacing is not included above the first line - /// below the last line due to no additional space present there. + /// and below the last line due to no additional space present there. /// {@endtemplate} includeLineSpacingMiddle, From fc64089160b9de473b35cd17ce1143f79467b5d6 Mon Sep 17 00:00:00 2001 From: GaryQian Date: Wed, 24 Oct 2018 15:03:00 -0700 Subject: [PATCH 4/4] More docs and assert styles are not null --- lib/ui/text.dart | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/ui/text.dart b/lib/ui/text.dart index 95673a605e641..44d2261db59d0 100644 --- a/lib/ui/text.dart +++ b/lib/ui/text.dart @@ -1002,8 +1002,9 @@ enum BoxWidthStyle { /// Adds up to two additional boxes as needed at the beginning and/or end /// of each line so that the widths of the boxes in line are the same width - /// as the widest line in the paragraph. The additional boxes are only added - /// when the first/last box does not span the max width of the paragraph. + /// as the widest line in the paragraph. The additional boxes on each line + /// are only added when the relevant box at the relevant edge of that line + /// does not span the maximum width of the paragraph. max, } @@ -1071,13 +1072,17 @@ class Paragraph extends NativeFieldWrapperClass2 { /// Returns a list of text boxes that enclose the given text range. /// - /// [boxHeightStyle] and [boxWidthStyle] allow customization of how the boxes - /// are bound vertically and horizontally. Both style parameters default to - /// the tight option, which will provide close fitting boxes and will not - /// account for any line spacing. + /// The [boxHeightStyle] and [boxWidthStyle] parameters allow customization + /// of how the boxes are bound vertically and horizontally. Both style + /// parameters default to the tight option, which will provide close-fitting + /// boxes and will not account for any line spacing. + /// + /// The [boxHeightStyle] and [boxWidthStyle] parameters must not be null. /// /// See [BoxHeightStyle] and [BoxWidthStyle] for full descriptions of each option. List getBoxesForRange(int start, int end, {BoxHeightStyle boxHeightStyle = BoxHeightStyle.tight, BoxWidthStyle boxWidthStyle = BoxWidthStyle.tight}) { + assert(boxHeightStyle != null); + assert(boxWidthStyle != null); return _getBoxesForRange(start, end, boxHeightStyle.index, boxWidthStyle.index); }