Skip to content

Commit

Permalink
[web] Add new line break type (prohibited) (#22771)
Browse files Browse the repository at this point in the history
  • Loading branch information
mdebbar authored Nov 30, 2020
1 parent 609307d commit 587c023
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 8 deletions.
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

0 comments on commit 587c023

Please sign in to comment.