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

[web] Improve line breaker test exceptions #37244

Merged
merged 5 commits into from
Nov 4, 2022
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
56 changes: 29 additions & 27 deletions lib/web_ui/lib/src/engine/text/line_breaker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,6 @@ List<LineBreakFragment> _computeLineBreakFragments(String text) {
int? codePoint = getCodePoint(text, 0);
LineCharProperty? curr = lineLookup.findForChar(codePoint);

// When there's a sequence of spaces, this variable contains the base property
// i.e. the property of the character preceding the sequence.
LineCharProperty baseOfSpaceSequence = LineCharProperty.WJ;

// When there's a sequence of combining marks, this variable contains the base
// property i.e. the property of the character preceding the sequence.
LineCharProperty baseOfCombiningMarks = LineCharProperty.AL;
Expand All @@ -146,6 +142,9 @@ List<LineBreakFragment> _computeLineBreakFragments(String text) {
type == LineBreakType.endOfText ? text.length : index;
assert(fragmentEnd >= fragmentStart);

// Uncomment the following line to help debug line breaking.
// print('{$fragmentStart:$fragmentEnd} [$debugRuleNumber] -- $type');

if (prev1 == LineCharProperty.SP) {
trailingSpaces++;
} else if (_isHardBreak(prev1) || prev1 == LineCharProperty.CR) {
Expand Down Expand Up @@ -244,13 +243,6 @@ List<LineBreakFragment> _computeLineBreakFragments(String text) {
break;
}

// Establish the base for the space sequence.
if (prev1 != LineCharProperty.SP) {
// When the text/line starts with SP, we should treat the beginning of text/line
// as if it were a WJ (word joiner).
baseOfSpaceSequence = prev1 ?? LineCharProperty.WJ;
}

// Do not break before spaces or zero width space.
// LB7: × SP
// × ZW
Expand All @@ -259,11 +251,17 @@ List<LineBreakFragment> _computeLineBreakFragments(String text) {
continue;
}

// Break after spaces.
// LB18: SP ÷
if (prev1 == LineCharProperty.SP) {
setBreak(LineBreakType.opportunity, 18);
continue;
}

// Break before any character following a zero-width space, even if one or
// more spaces intervene.
// LB8: ZW SP* ÷
if (prev1 == LineCharProperty.ZW ||
baseOfSpaceSequence == LineCharProperty.ZW) {
if (prev1 == LineCharProperty.ZW) {
setBreak(LineBreakType.opportunity, 8);
continue;
}
Expand Down Expand Up @@ -343,6 +341,8 @@ List<LineBreakFragment> _computeLineBreakFragments(String text) {
// The above is a quote from unicode.org. In our implementation, we did the
// following modification: When there are spaces present, we consider it a
// line break opportunity.
//
// We made this modification to match the browser behavior.
if (prev1 != LineCharProperty.SP &&
(curr == LineCharProperty.CL ||
curr == LineCharProperty.CP ||
Expand All @@ -358,6 +358,8 @@ List<LineBreakFragment> _computeLineBreakFragments(String text) {
//
// The above is a quote from unicode.org. In our implementation, we did the
// following modification: Allow breaks when there are spaces.
//
// We made this modification to match the browser behavior.
if (prev1 == LineCharProperty.OP) {
setBreak(LineBreakType.prohibited, 14);
continue;
Expand All @@ -368,6 +370,8 @@ List<LineBreakFragment> _computeLineBreakFragments(String text) {
//
// The above is a quote from unicode.org. In our implementation, we did the
// following modification: Allow breaks when there are spaces.
//
// We made this modification to match the browser behavior.
if (prev1 == LineCharProperty.QU && curr == LineCharProperty.OP) {
setBreak(LineBreakType.prohibited, 15);
continue;
Expand All @@ -376,31 +380,29 @@ List<LineBreakFragment> _computeLineBreakFragments(String text) {
// Do not break between closing punctuation and a nonstarter, even with
// intervening spaces.
// LB16: (CL | CP) SP* × NS
if ((prev1 == LineCharProperty.CL ||
baseOfSpaceSequence == LineCharProperty.CL ||
prev1 == LineCharProperty.CP ||
baseOfSpaceSequence == LineCharProperty.CP) &&
//
// The above is a quote from unicode.org. In our implementation, we did the
// following modification: Allow breaks when there are spaces.
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we have details about why we modified it documented anywhere? Maybe expand on it here a bit?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. We modified it to match Chrome's behavior (which makes more sense to me than the unicode spec in these cases). I'll explain it in the comment.

//
// We made this modification to match the browser behavior.
if ((prev1 == LineCharProperty.CL || prev1 == LineCharProperty.CP) &&
curr == LineCharProperty.NS) {
setBreak(LineBreakType.prohibited, 16);
continue;
}

// Do not break within ‘——’, even with intervening spaces.
// LB17: B2 SP* × B2
if ((prev1 == LineCharProperty.B2 ||
baseOfSpaceSequence == LineCharProperty.B2) &&
curr == LineCharProperty.B2) {
//
// The above is a quote from unicode.org. In our implementation, we did the
// following modification: Allow breaks when there are spaces.
//
// We made this modification to match the browser behavior.
if (prev1 == LineCharProperty.B2 && curr == LineCharProperty.B2) {
setBreak(LineBreakType.prohibited, 17);
continue;
}

// Break after spaces.
// LB18: SP ÷
if (prev1 == LineCharProperty.SP) {
setBreak(LineBreakType.opportunity, 18);
continue;
}

// Do not break before or after quotation marks, such as ‘”’.
// LB19: × QU
// QU ×
Expand Down
Loading