Allow breaking line after space with white-space: break-spaces (#33376)

`white-space: break-spaces` should allow a soft wrap opportunity *after*
every preserved white space. Then, to avoid breaking before the first
white space, `TextRunSegment::shape_text()` has some logic to separate
it from the following spaces and put it with the preceding text instead.

The problem was that, when combined with `word-break: keep-all`, we were
then only checking whether there were more white spaces afterwards,
ignoring the soft wrap opportunity after the first one.

Also removing a duplicated `can_break_anywhere` variable.

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
Oriol Brufau 2024-09-10 13:06:40 +02:00 committed by GitHub
parent 6d6cd0f2dc
commit 9d3d009895
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 40 additions and 4 deletions

View file

@ -225,6 +225,7 @@ impl TextRunSegment {
let mut whitespace = slice.end..slice.end;
let mut rev_char_indices = word.char_indices().rev().peekable();
let mut ends_with_whitespace = false;
let ends_with_newline = rev_char_indices
.peek()
.map_or(false, |&(_, character)| character == '\n');
@ -232,6 +233,7 @@ impl TextRunSegment {
.take_while(|&(_, character)| char_is_whitespace(character))
.last()
{
ends_with_whitespace = true;
whitespace.start = slice.start + first_white_space_index;
// If line breaking for a piece of text that has `white-space-collapse: break-spaces` there
@ -252,10 +254,7 @@ impl TextRunSegment {
// If there's no whitespace and `word-break` is set to `keep-all`, try increasing the slice.
// TODO: This should only happen for CJK text.
let can_break_anywhere = text_style.word_break == WordBreak::BreakAll ||
text_style.overflow_wrap == OverflowWrap::Anywhere ||
text_style.overflow_wrap == OverflowWrap::BreakWord;
if whitespace.is_empty() &&
if !ends_with_whitespace &&
*break_index != self.range.end &&
text_style.word_break == WordBreak::KeepAll &&
!can_break_anywhere