Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 2b4c58f

Browse files
committed
Add line boundary information to Paragraph
1 parent 02a4790 commit 2b4c58f

File tree

5 files changed

+56
-5
lines changed

5 files changed

+56
-5
lines changed

lib/ui/text.dart

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,6 +1593,8 @@ class LineMetrics {
15931593
this.left,
15941594
this.baseline,
15951595
this.lineNumber,
1596+
this.startIndex,
1597+
this.endIndex,
15961598
});
15971599

15981600
@pragma('vm:entry-point')
@@ -1606,6 +1608,8 @@ class LineMetrics {
16061608
this.left,
16071609
this.baseline,
16081610
this.lineNumber,
1611+
this.startIndex,
1612+
this.endIndex,
16091613
);
16101614

16111615
/// True if this line ends with an explicit line break (e.g. '\n') or is the end
@@ -1673,6 +1677,13 @@ class LineMetrics {
16731677
///
16741678
/// For example, the first line is line 0, second line is line 1.
16751679
final int lineNumber;
1680+
1681+
/// The starting text index for this line, in Unicode code points.
1682+
final int startIndex;
1683+
1684+
/// The ending text index, including the newline for this line, in Unicode
1685+
/// code points.
1686+
final int endIndex;
16761687
}
16771688

16781689
/// A paragraph of text.
@@ -1786,6 +1797,16 @@ class Paragraph extends NativeFieldWrapperClass2 {
17861797
/// http://www.unicode.org/reports/tr29/#Word_Boundaries
17871798
List<int> getWordBoundary(int offset) native 'Paragraph_getWordBoundary';
17881799

1800+
/// Returns the [start, end] of the line at the given offset.
1801+
///
1802+
/// The newline (if any) is returned as part of the range.
1803+
///
1804+
/// This can potentially be expensive, since it needs to compute the line
1805+
/// metrics, so use it sparingly. If higher performance is needed, caching the
1806+
/// results of [computeLineMetrics] is recommended (which also contains the
1807+
/// start and end of each line).
1808+
List<int> getLineBoundary(int offset) native 'Paragraph_getLineBoundary';
1809+
17891810
// Redirecting the paint function in this way solves some dependency problems
17901811
// in the C++ code. If we straighten out the C++ dependencies, we can remove
17911812
// this indirection.

lib/ui/text/line_metrics.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Dart_Handle GetLineMetricsType() {
2727

2828
Dart_Handle DartConverter<flutter::LineMetrics>::ToDart(
2929
const flutter::LineMetrics& val) {
30-
constexpr int argc = 9;
30+
constexpr int argc = 11;
3131

3232
Dart_Handle argv[argc] = {
3333
tonic::ToDart(*val.hard_break), tonic::ToDart(*val.ascent),
@@ -37,7 +37,9 @@ Dart_Handle DartConverter<flutter::LineMetrics>::ToDart(
3737
// than the one in LibTxt.
3838
tonic::ToDart(round(*val.ascent + *val.descent)),
3939
tonic::ToDart(*val.width), tonic::ToDart(*val.left),
40-
tonic::ToDart(*val.baseline), tonic::ToDart(*val.line_number)};
40+
tonic::ToDart(*val.baseline), tonic::ToDart(*val.line_number),
41+
tonic::ToDart(*val.start_index), tonic::ToDart(*val.end_index)
42+
};
4143
return Dart_New(GetLineMetricsType(), tonic::ToDart("_"), argc, argv);
4244
}
4345

lib/ui/text/line_metrics.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ struct LineMetrics {
3434
const double* baseline;
3535
// Zero indexed line number.
3636
const size_t* line_number;
37+
// The starting text index for this line.
38+
const size_t* start_index;
39+
// The ending index for this line, including the newline, if any.
40+
const size_t* end_index;
3741

3842
LineMetrics();
3943

@@ -45,7 +49,9 @@ struct LineMetrics {
4549
const double* width,
4650
const double* left,
4751
const double* baseline,
48-
const size_t* line_number)
52+
const size_t* line_number,
53+
const size_t* start_index,
54+
const size_t* end_index)
4955
: hard_break(hard_break),
5056
ascent(ascent),
5157
descent(descent),
@@ -54,7 +60,9 @@ struct LineMetrics {
5460
width(width),
5561
left(left),
5662
baseline(baseline),
57-
line_number(line_number) {}
63+
line_number(line_number),
64+
start_index(start_index),
65+
end_index(end_index) {}
5866
};
5967

6068
} // namespace flutter

lib/ui/text/paragraph.cc

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ IMPLEMENT_WRAPPERTYPEINFO(ui, Paragraph);
3131
V(Paragraph, layout) \
3232
V(Paragraph, paint) \
3333
V(Paragraph, getWordBoundary) \
34+
V(Paragraph, getLineBoundary) \
3435
V(Paragraph, getRectsForRange) \
3536
V(Paragraph, getRectsForPlaceholders) \
3637
V(Paragraph, getPositionForOffset) \
@@ -134,13 +135,31 @@ Dart_Handle Paragraph::getWordBoundary(unsigned offset) {
134135
return result;
135136
}
136137

138+
Dart_Handle Paragraph::getLineBoundary(unsigned offset) {
139+
std::vector<txt::LineMetrics> metrics = m_paragraph->GetLineMetrics();
140+
int line_start = -1;
141+
int line_end = -1;
142+
for (txt::LineMetrics& line : metrics) {
143+
if (offset >= line.start_index && offset < line.end_index) {
144+
line_start = line.start_index;
145+
line_end = line.end_index;
146+
break;
147+
}
148+
}
149+
Dart_Handle result = Dart_NewListOf(Dart_CoreType_Int, 2);
150+
Dart_ListSetAt(result, 0, ToDart(line_start));
151+
Dart_ListSetAt(result, 1, ToDart(line_end));
152+
return result;
153+
}
154+
137155
std::vector<LineMetrics> Paragraph::computeLineMetrics() {
138156
std::vector<LineMetrics> result;
139157
std::vector<txt::LineMetrics> metrics = m_paragraph->GetLineMetrics();
140158
for (txt::LineMetrics& line : metrics) {
141159
result.emplace_back(&line.hard_break, &line.ascent, &line.descent,
142160
&line.unscaled_ascent, &line.height, &line.width,
143-
&line.left, &line.baseline, &line.line_number);
161+
&line.left, &line.baseline, &line.line_number,
162+
&line.start_index, &line.end_index);
144163
}
145164
return result;
146165
}

lib/ui/text/paragraph.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class Paragraph : public RefCountedDartWrappable<Paragraph> {
4949
std::vector<TextBox> getRectsForPlaceholders();
5050
Dart_Handle getPositionForOffset(double dx, double dy);
5151
Dart_Handle getWordBoundary(unsigned offset);
52+
Dart_Handle getLineBoundary(unsigned offset);
5253
std::vector<LineMetrics> computeLineMetrics();
5354

5455
size_t GetAllocationSize() override;

0 commit comments

Comments
 (0)