Commit 40525a18 authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

[LayoutNG] Fix line breaker when spaces are across elements

This patch fixes NGLineBreaker not to freeze when all of the
following conditions met:
* 'word-wrap: break-word' is set.
* 'whitespace: pre-wrap' is set.
* Two or more adjacent preserved spaces are split to two or
  more elements, and is the last space to fit in the line.

e.g.,
<div style="whitespace: pre-wrap; word-break: break-word">
  <span>xxx <span> yyyy
</div>
and "yyyy" does not fit.

We need to handle trailing spaces not only when spaces follow
a break opportunity but also spaces are after spaces.

Bug: 903909
Change-Id: Ie4346a670ec22d35cca3a290b9a423161537e4e8
Reviewed-on: https://chromium-review.googlesource.com/c/1343466Reviewed-by: default avatarMorten Stenshorne <mstensho@chromium.org>
Commit-Queue: Koji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#609709}
parent a43b2e63
...@@ -316,9 +316,15 @@ void NGLineBreaker::HandleText(const NGInlineItem& item) { ...@@ -316,9 +316,15 @@ void NGLineBreaker::HandleText(const NGInlineItem& item) {
DCHECK(item.TextShapeResult()); DCHECK(item.TextShapeResult());
// If we're trailing, only trailing spaces can be included in this line. // If we're trailing, only trailing spaces can be included in this line.
if (state_ == LineBreakState::kTrailing && if (state_ == LineBreakState::kTrailing) {
CanBreakAfterLast(*item_results_)) { if (CanBreakAfterLast(*item_results_))
return HandleTrailingSpaces(item); return HandleTrailingSpaces(item);
// When a run of preserved spaces are across items, |CanBreakAfterLast| is
// false for between spaces. But we still need to handle them as trailing
// spaces.
const String& text = Text();
if (offset_ < text.length() && text[offset_] == kSpaceCharacter)
return HandleTrailingSpaces(item);
} }
// Skip leading collapsible spaces. // Skip leading collapsible spaces.
......
...@@ -211,6 +211,29 @@ TEST_F(NGLineBreakerTest, OverflowMargin) { ...@@ -211,6 +211,29 @@ TEST_F(NGLineBreakerTest, OverflowMargin) {
EXPECT_EQ("789", ToString(lines[2], node)); EXPECT_EQ("789", ToString(lines[2], node));
} }
TEST_F(NGLineBreakerTest, OverflowAfterSpacesAcrossElements) {
LoadAhem();
NGInlineNode node = CreateInlineNode(R"HTML(
<!DOCTYPE html>
<style>
div {
font: 10px/1 Ahem;
white-space: pre-wrap;
width: 10ch;
word-wrap: break-word;
}
</style>
<div id=container><span>12345 </span> 1234567890123</div>
)HTML");
Vector<NGInlineItemResults> lines;
lines = BreakLines(node, LayoutUnit(100));
EXPECT_EQ(3u, lines.size());
EXPECT_EQ("12345 ", ToString(lines[0], node));
EXPECT_EQ("1234567890", ToString(lines[1], node));
EXPECT_EQ("123", ToString(lines[2], node));
}
// Tests when the last word in a node wraps, and another node continues. // Tests when the last word in a node wraps, and another node continues.
TEST_F(NGLineBreakerTest, WrapLastWord) { TEST_F(NGLineBreakerTest, WrapLastWord) {
LoadAhem(); LoadAhem();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment