Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 77 additions & 1 deletion lib/ui/text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,67 @@ 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 adjacent boxes.
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.
///
/// {@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
/// and 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 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,
}

/// A paragraph of text.
///
/// A paragraph retains the size and position of each glyph in the text and can
Expand Down Expand Up @@ -1010,7 +1071,22 @@ class Paragraph extends NativeFieldWrapperClass2 {
void _layout(double width) native 'Paragraph_layout';

/// Returns a list of text boxes that enclose the given text range.
List<TextBox> getBoxesForRange(int start, int end) native 'Paragraph_getRectsForRange';
///
/// 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<TextBox> 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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assert that the arguments aren't null (and mention in the docs that they must not be null)

}

List<TextBox> _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) {
Expand Down
9 changes: 6 additions & 3 deletions lib/ui/text/paragraph.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,13 @@ void Paragraph::paint(Canvas* canvas, double x, double y) {
m_paragraphImpl->paint(canvas, x, y);
}

std::vector<TextBox> Paragraph::getRectsForRange(unsigned start, unsigned end) {
std::vector<TextBox> 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<txt::Paragraph::RectHeightStyle>(boxHeightStyle),
static_cast<txt::Paragraph::RectWidthStyle>(boxWidthStyle));
}

Dart_Handle Paragraph::getPositionForOffset(double dx, double dy) {
Expand Down
5 changes: 4 additions & 1 deletion lib/ui/text/paragraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ class Paragraph : public RefCountedDartWrappable<Paragraph> {
void layout(double width);
void paint(Canvas* canvas, double x, double y);

std::vector<TextBox> getRectsForRange(unsigned start, unsigned end);
std::vector<TextBox> getRectsForRange(unsigned start,
unsigned end,
unsigned boxHeightStyle,
unsigned boxWidthStyle);
Dart_Handle getPositionForOffset(double dx, double dy);
Dart_Handle getWordBoundary(unsigned offset);

Expand Down