| Index: third_party/WebKit/Source/core/layout/LayoutText.cpp
|
| diff --git a/third_party/WebKit/Source/core/layout/LayoutText.cpp b/third_party/WebKit/Source/core/layout/LayoutText.cpp
|
| index a524f21e5166f32b51ee07716c6c958384762ea0..c399d9841f7a8c1e9b7ab6191946f807ac57238c 100644
|
| --- a/third_party/WebKit/Source/core/layout/LayoutText.cpp
|
| +++ b/third_party/WebKit/Source/core/layout/LayoutText.cpp
|
| @@ -967,6 +967,34 @@ void LayoutText::computePreferredLogicalWidths(float leadWidth) {
|
| computePreferredLogicalWidths(leadWidth, fallbackFonts, glyphBounds);
|
| }
|
|
|
| +static float minWordFragmentWidthForBreakAll(LayoutText* layoutText,
|
| + const ComputedStyle& style,
|
| + const Font& font,
|
| + TextDirection textDirection,
|
| + int start,
|
| + int length) {
|
| + DCHECK_GT(length, 0);
|
| + LazyLineBreakIterator breakIterator(layoutText->text(), style.locale());
|
| + int nextBreakable = -1;
|
| + float min = std::numeric_limits<float>::max();
|
| + int end = start + length;
|
| + for (int i = start; i < end;) {
|
| + breakIterator.isBreakable(i + 1, nextBreakable, LineBreakType::BreakAll);
|
| + int fragmentLength = (nextBreakable > i ? nextBreakable : length) - i;
|
| + // The correct behavior is to measure width without re-shaping, but we
|
| + // reshape each fragment here because a) the current line breaker does not
|
| + // support it, b) getCharacterRange() can reshape if the text is too long
|
| + // to fit in the cache, and c) each fragment here is almost 1 char and thus
|
| + // reshape is fast.
|
| + TextRun run = constructTextRun(font, layoutText, i, fragmentLength, style,
|
| + textDirection);
|
| + float fragmentWidth = font.width(run);
|
| + min = std::min(min, fragmentWidth);
|
| + i += fragmentLength;
|
| + }
|
| + return min;
|
| +}
|
| +
|
| static float maxWordFragmentWidth(LayoutText* layoutText,
|
| const ComputedStyle& style,
|
| const Font& font,
|
| @@ -1141,8 +1169,7 @@ void LayoutText::computePreferredLogicalWidths(
|
|
|
| bool hasBreak = breakIterator.isBreakable(
|
| i, nextBreakable,
|
| - breakAll ? LineBreakType::BreakAll
|
| - : keepAll ? LineBreakType::KeepAll : LineBreakType::Normal);
|
| + keepAll ? LineBreakType::KeepAll : LineBreakType::Normal);
|
| bool betweenWords = true;
|
| int j = i;
|
| while (c != newlineCharacter && c != spaceCharacter &&
|
| @@ -1155,10 +1182,6 @@ void LayoutText::computePreferredLogicalWidths(
|
| if (breakIterator.isBreakable(j, nextBreakable) &&
|
| characterAt(j - 1) != softHyphenCharacter)
|
| break;
|
| - if (breakAll) {
|
| - betweenWords = false;
|
| - break;
|
| - }
|
| }
|
|
|
| // Terminate word boundary at bidi run boundary.
|
| @@ -1220,7 +1243,15 @@ void LayoutText::computePreferredLogicalWidths(
|
| }
|
| }
|
|
|
| - currMinWidth += w;
|
| + if (breakAll) {
|
| + // Because sum of character widths may not be equal to the word width,
|
| + // we need to measure twice; once with normal break for max width,
|
| + // another with break-all for min width.
|
| + currMinWidth = minWordFragmentWidthForBreakAll(
|
| + this, styleToUse, f, textDirection, i, wordLen);
|
| + } else {
|
| + currMinWidth += w;
|
| + }
|
| if (betweenWords) {
|
| if (lastWordBoundary == i)
|
| currMaxWidth += w;
|
|
|