Skip to content

Commit

Permalink
New TextBreakIterator's default behavior breaks after space run
Browse files Browse the repository at this point in the history
Before this change, we were considering breaking opportunities before
space runs. This approach allowed us to avoid re-shaping in many cases,
which has an important advantage in terms of performance.

However, the Unicode spec (UAX#14) state that breaking before a space
character is not allowed [1], so we had to implement this logic after
our TextBreakIterator had already determined the best breaking
opportunity. This approach has been working fine so far for regular
spaces (white-space, tabs, ...), but it doesn't work correctly for
other BA [2] class characters; in the CSS Text specification, these are
known as "other space separators" [3].

In order to implement the correct behavior for any kind of space, we
would need to change our TextBreakIterator implementation so that
matches the Unicode rules, considering breaking opportunity after
space runs. This change should also consider the performance impact
of the extra re-shaping operations required to deal with trailing
spaces.

In order to prevent performance regressions, we'll store the position
of the 'end of non-hangable run', which will be used in case of items
with styles dictating rules to collapse trailing spaces.

[1] https://unicode-org.atlassian.net/browse/ICU-20843
[2] https://www.unicode.org/reports/tr14/tr14-39.html#BA
[3] https://drafts.csswg.org/css-text-3/#other-space-separators

Change-Id: Ie4a3890c75a3faff1a0155d4a40bcaa85bc6ac06
  • Loading branch information
javifernandez authored and chromium-wpt-export-bot committed Sep 14, 2020
1 parent 90ea6fe commit dcdf651
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 4 deletions.
@@ -0,0 +1,13 @@
<!doctype html>
<meta charset=utf-8>
<meta http-equiv="content-language" content="en, ja" />
<title>CSS test Reference</title>
<link rel="author" title="Javier Fernandez" href="mailto:jfernandez@igalia.com" />
<style>
div { white-space: pre; }
span { background: blue; }
</style>

<p>This test passes if the line is after the white space, which hangs (blue).

<div>ああ<span>&#x0020;<br>X</span></div>
Expand Up @@ -24,7 +24,5 @@
<section class="ideo">
<div><br></div>
<div><br></div>
<div><br></div>
<div><br></div>
</section>
</body>
@@ -0,0 +1,35 @@
<!doctype html>
<meta charset=utf-8>
<title>CSS Text test: hanging trailing spaces with white-space:pre-wrap</title>
<link rel="author" title="Javier Fernandez" href="mailto:jfernandez@igalia.com">
<link rel="help" title="3. White Space and Wrapping: the white-space property" href="https://drafts.csswg.org/css-text-3/#white-space-property">
<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-pre-wrap">
<link rel="help" title="4.1.3. Phase II: Trimming and Positioning" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2">
<link rel="help" title="5.2. Breaking Rules for Letters: the word-break property" href="https://drafts.csswg.org/css-text-3/#word-break-property">
<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-word-break-normal">
<link rel="match" href="reference/white-space-pre-wrap-trailing-spaces-004-ref.html">
<meta name="assert" content="Previous breaking opportunities are not considered if the overflow is caused by hanging trailing spaces.">
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
<style>
div {
font: 10px/1 Ahem;
}
.ref {
position: absolute;
color: red;
z-index: -1;
}
.ref span { color: green; }
span { background: green; }
.test {
color: green;

width: 4ch;
white-space: pre-wrap;
}
</style>

<p>This test passes if there is a green square and no red.
<div class="ref">XX<span>X</span>XX<br>XXXXX</span><br>XXXXX<br>XXXXX<br>XXXXX</div>
<div class="test">XX X<span> X</span><span>XX </span>XXXXX<br>XXXXX<br>XXXXX</div>

@@ -0,0 +1,24 @@
<!doctype html>
<meta charset=utf-8>
<meta http-equiv="content-language" content="en, ja" />
<title>CSS Text test: hanging trailing spaces with white-space:pre-wrap</title>
<link rel="author" title="Javier Fernandez" href="mailto:jfernandez@igalia.com">
<link rel="help" title="3. White Space and Wrapping: the white-space property" href="https://drafts.csswg.org/css-text-3/#white-space-property">
<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-pre-wrap">
<link rel="help" title="4.1.3. Phase II: Trimming and Positioning" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2">
<link rel="help" title="5.2. Breaking Rules for Letters: the word-break property" href="https://drafts.csswg.org/css-text-3/#word-break-property">
<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-word-break-normal">
<link rel="match" href="reference/white-space-pre-wrap-trailing-spaces-013-ref.html">
<meta name="assert" content="Previous breaking opportunities are not considered if the overflow is caused by hanging trailing spaces.">
<style>
div {
width: 2em;
white-space: pre-wrap;
}
span { background: blue; } /* If the space is removed instead of hanging, there will be no blue box*/
</style>

<p>This test passes if the line is after the white space, which hangs (blue).

<div>ああ<span>&#x0020;X<span></div>

@@ -0,0 +1,35 @@
<!doctype html>
<meta charset=utf-8>
<title>CSS Text test: hanging trailing spaces with white-space:pre-wrap</title>
<link rel="author" title="Javier Fernandez" href="mailto:jfernandez@igalia.com">
<link rel="help" title="3. White Space and Wrapping: the white-space property" href="https://drafts.csswg.org/css-text-3/#white-space-property">
<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-pre-wrap">
<link rel="help" title="4.1.3. Phase II: Trimming and Positioning" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2">
<link rel="help" title="5.2. Breaking Rules for Letters: the word-break property" href="https://drafts.csswg.org/css-text-3/#word-break-property">
<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-word-break-normal">
<link rel="match" href="reference/white-space-pre-wrap-trailing-spaces-004-ref.html">
<meta name="assert" content="Previous breaking opportunities are not considered if the overflow is caused by hanging trailing spaces.">
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
<style>
div {
font: 10px/1 Ahem;
}
.ref {
position: absolute;
color: red;
z-index: -1;
}
span { background: green; }
.ref span { color: green; }
.test {
color: green;

width: 4ch;
white-space: pre-wrap;
}
</style>

<p>This test passes if there is a green square and no red.
<div class="ref">XX<span>X</span>X<span>X</span><br>XXXXX</span><br>XXXXX<br>XXXXX<br>XXXXX</div>
<div class="test">XX<span> X</span> X<span>XX </span>XXXXX<br>XXXXX<br>XXXXX</div>

@@ -0,0 +1,35 @@
<!doctype html>
<meta charset=utf-8>
<title>CSS Text test: hanging trailing spaces with white-space:pre-wrap</title>
<link rel="author" title="Javier Fernandez" href="mailto:jfernandez@igalia.com">
<link rel="help" title="3. White Space and Wrapping: the white-space property" href="https://drafts.csswg.org/css-text-3/#white-space-property">
<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-pre-wrap">
<link rel="help" title="4.1.3. Phase II: Trimming and Positioning" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2">
<link rel="help" title="5.2. Breaking Rules for Letters: the word-break property" href="https://drafts.csswg.org/css-text-3/#word-break-property">
<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-word-break-normal">
<link rel="match" href="reference/white-space-pre-wrap-trailing-spaces-004-ref.html">
<meta name="assert" content="Previous breaking opportunities are not considered if the overflow is caused by hanging trailing spaces.">
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
<style>
div {
font: 10px/1 Ahem;
}
.ref {
position: absolute;
color: red;
z-index: -1;
}
span { background: green; }
.ref span { color: green; }
.test {
color: green;

width: 5ch;
white-space: pre-wrap;
}
</style>

<p>This test passes if there is a green square and no red.
<div class="ref">XX<span>XXX</span><br>XXX<span>X</span>X<br>XXXXX</span><br>XXXXX<br>XXXXX<br></div>
<div class="test">XX XX<span>X X</span><br>XXXXX<br>XXXXX<br>XXXXX</div>

Expand Up @@ -35,7 +35,5 @@
<section class="ideo">
<div><span class="nowrap"></span></div>
<div><span class="nowrap"></span><span class="normal"></span></div>
<div><span class="nowrap"><span class="normal"></span></span></div>
<div class="nowrap"><span class="normal"></span></div>
</section>
</body>

0 comments on commit dcdf651

Please sign in to comment.