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

[web] Add new line break type (prohibited) #22771

Merged
merged 1 commit into from
Nov 30, 2020
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
17 changes: 16 additions & 1 deletion lib/web_ui/lib/src/engine/text/line_breaker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ enum LineBreakType {
/// Indicates that a line break is possible but not mandatory.
opportunity,

/// Indicates that a line break isn't possible.
prohibited,

/// Indicates that this is a hard line break that can't be skipped.
mandatory,

Expand Down Expand Up @@ -74,6 +77,9 @@ class LineBreakResult {
/// to decide whether to take the line break or not.
final LineBreakType type;

bool get isHard =>
type == LineBreakType.mandatory || type == LineBreakType.endOfText;

@override
int get hashCode => ui.hashValues(
index,
Expand Down Expand Up @@ -160,7 +166,7 @@ bool _hasEastAsianWidthFWH(int charCode) {
///
/// * https://www.unicode.org/reports/tr14/tr14-45.html#Algorithm
/// * https://www.unicode.org/Public/11.0.0/ucd/LineBreak.txt
LineBreakResult nextLineBreak(String text, int index) {
LineBreakResult nextLineBreak(String text, int index, {int? maxEnd}) {
int? codePoint = getCodePoint(text, index);
LineCharProperty curr = lineLookup.findForChar(codePoint);

Expand Down Expand Up @@ -199,6 +205,15 @@ LineBreakResult nextLineBreak(String text, int index) {
// Always break at the end of text.
// LB3: ! eot
while (index < text.length) {
if (index == maxEnd) {
return LineBreakResult(
index,
lastNonNewlineIndex,
lastNonSpaceIndex,
LineBreakType.prohibited,
);
}

// Keep count of the RI (regional indicator) sequence.
if (curr == LineCharProperty.RI) {
regionalIndicatorCount++;
Expand Down
10 changes: 3 additions & 7 deletions lib/web_ui/lib/src/engine/text/measurement.dart
Original file line number Diff line number Diff line change
Expand Up @@ -771,8 +771,6 @@ class LinesCalculator {
/// This method should be called for every line break. As soon as it reaches
/// the maximum number of lines required
void update(LineBreakResult brk) {
final bool isHardBreak = brk.type == LineBreakType.mandatory ||
brk.type == LineBreakType.endOfText;
final int chunkEnd = brk.index;
final int chunkEndWithoutNewlines = brk.indexWithoutTrailingNewlines;
final int chunkEndWithoutSpace = brk.indexWithoutTrailingSpaces;
Expand Down Expand Up @@ -855,7 +853,7 @@ class LinesCalculator {
return;
}

if (isHardBreak) {
if (brk.isHard) {
_addLineBreak(brk);
}
_lastBreak = brk;
Expand All @@ -872,15 +870,13 @@ class LinesCalculator {
lineWidth: lineWidth,
maxWidth: _maxWidth,
);
final bool isHardBreak = brk.type == LineBreakType.mandatory ||
brk.type == LineBreakType.endOfText;

final EngineLineMetrics metrics = EngineLineMetrics.withText(
_text!.substring(_lineStart, brk.indexWithoutTrailingNewlines),
startIndex: _lineStart,
endIndex: brk.index,
endIndexWithoutNewlines: brk.indexWithoutTrailingNewlines,
hardBreak: isHardBreak,
hardBreak: brk.isHard,
width: lineWidth,
widthWithTrailingSpaces: lineWidthWithTrailingSpaces,
left: alignOffset,
Expand Down Expand Up @@ -995,7 +991,7 @@ class MaxIntrinsicCalculator {
/// intrinsic width calculated so far. When the whole text is consumed,
/// [value] will contain the final maximum intrinsic width.
void update(LineBreakResult brk) {
if (brk.type == LineBreakType.opportunity) {
if (!brk.isHard) {
return;
}

Expand Down
15 changes: 15 additions & 0 deletions lib/web_ui/test/text/line_breaker_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,14 @@ void testMain() {
'"$text"\n'
'\nExpected line break at {$lastLineBreak - $i} but found line break at {$lastLineBreak - ${result.index}}.',
);

// Since this is a line break, passing a `maxEnd` that's greater
// should return the same line break.
final LineBreakResult maxEndResult =
nextLineBreak(text, lastLineBreak, maxEnd: i + 1);
expect(maxEndResult.index, i);
expect(maxEndResult.type, isNot(LineBreakType.prohibited));

lastLineBreak = i;
} else {
// This isn't a line break opportunity so the line break should be
Expand All @@ -264,6 +272,13 @@ void testMain() {
'"$text"\n'
'\nUnexpected line break found at {$lastLineBreak - $i}.',
);

// Since this isn't a line break, passing it as a `maxEnd` should
// return `maxEnd` as a prohibited line break type.
final LineBreakResult maxEndResult =
nextLineBreak(text, lastLineBreak, maxEnd: i);
expect(maxEndResult.index, i);
expect(maxEndResult.type, LineBreakType.prohibited);
}
}
}
Expand Down