Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(863)

Unified Diff: third_party/WebKit/Source/core/layout/LayoutText.cpp

Issue 2438683006: Fix max preferred width for LayoutText when break-all (Closed)
Patch Set: Rebaseline Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/LayoutTests/platform/win/fast/text/word-break-soft-hyphen-expected.txt ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
« no previous file with comments | « third_party/WebKit/LayoutTests/platform/win/fast/text/word-break-soft-hyphen-expected.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698