mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[web] Add new line break type (prohibited) (flutter/engine#22771)
This commit is contained in:
parent
a2f762549a
commit
482bad112c
@ -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,
|
||||
|
||||
@ -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,
|
||||
@ -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);
|
||||
|
||||
@ -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++;
|
||||
|
||||
@ -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;
|
||||
@ -855,7 +853,7 @@ class LinesCalculator {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isHardBreak) {
|
||||
if (brk.isHard) {
|
||||
_addLineBreak(brk);
|
||||
}
|
||||
_lastBreak = brk;
|
||||
@ -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,
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user