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

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

Issue 1994483002: Compute min-content width when hyphenation is enabled (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: eae review Created 4 years, 7 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
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 a1edc563a28cd844b0ffe4740927ae1547551cc4..7ced3b6879f26fc2fe983840bf9119d175e816cc 100644
--- a/third_party/WebKit/Source/core/layout/LayoutText.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutText.cpp
@@ -41,10 +41,12 @@
#include "core/layout/line/InlineTextBox.h"
#include "core/paint/PaintLayer.h"
#include "platform/LayoutTestSupport.h"
+#include "platform/fonts/CharacterRange.h"
#include "platform/fonts/FontCache.h"
#include "platform/geometry/FloatQuad.h"
#include "platform/text/BidiResolver.h"
#include "platform/text/Character.h"
+#include "platform/text/Hyphenation.h"
#include "platform/text/TextBreakIterator.h"
#include "platform/text/TextRunIterator.h"
#include "wtf/text/CharacterNames.h"
@@ -863,6 +865,37 @@ void LayoutText::computePreferredLogicalWidths(float leadWidth)
computePreferredLogicalWidths(leadWidth, fallbackFonts, glyphBounds);
}
+static float maxWordFragmentWidth(LayoutText* layoutText,
+ const ComputedStyle& style, const Font& font, TextDirection textDirection,
+ Hyphenation& hyphenation, unsigned wordOffset, unsigned wordLength,
+ int& suffixStart)
+{
+ suffixStart = 0;
+ if (wordLength <= Hyphenation::minimumSuffixLength)
+ return 0;
+
+ Vector<size_t, 8> hyphenLocations = hyphenation.hyphenLocations(
+ layoutText->text().createView(wordOffset, wordLength));
+ if (hyphenLocations.isEmpty())
+ return 0;
+
+ float minimumFragmentWidthToConsider = Hyphenation::minimumPrefixWidth(font);
+ float maxFragmentWidth = 0;
+ TextRun run = constructTextRun(font, layoutText, wordOffset, wordLength, style, textDirection);
+ size_t end = wordLength;
+ for (size_t start : hyphenLocations) {
+ float fragmentWidth = font.getCharacterRange(run, start, end).width();
+
+ if (fragmentWidth <= minimumFragmentWidthToConsider)
+ continue;
+
+ maxFragmentWidth = std::max(maxFragmentWidth, fragmentWidth);
+ end = start;
+ }
+ suffixStart = hyphenLocations.first();
+ return maxFragmentWidth + layoutText->hyphenWidth(font, textDirection);
+}
+
void LayoutText::computePreferredLogicalWidths(float leadWidth, HashSet<const SimpleFontData*>& fallbackFonts, FloatRect& glyphBounds)
{
ASSERT(m_hasTab || preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflowAndNoFallbackFonts);
@@ -901,6 +934,13 @@ void LayoutText::computePreferredLogicalWidths(float leadWidth, HashSet<const Si
bool breakAll = (styleToUse.wordBreak() == BreakAllWordBreak || styleToUse.wordBreak() == BreakWordBreak) && styleToUse.autoWrap();
bool keepAll = styleToUse.wordBreak() == KeepAllWordBreak && styleToUse.autoWrap();
+ Hyphenation* hyphenation = styleToUse.getHyphens() == HyphensAuto
+ ? Hyphenation::get(f.getFontDescription().locale()) : nullptr;
+ bool disableSoftHyphen = styleToUse.getHyphens() == HyphensNone;
+ float maxWordWidth = 0;
+ if (!hyphenation)
+ maxWordWidth = std::numeric_limits<float>::max();
+
BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver;
BidiCharacterRun* run;
TextDirection textDirection = styleToUse.direction();
@@ -974,7 +1014,7 @@ void LayoutText::computePreferredLogicalWidths(float leadWidth, HashSet<const Si
lastWordBoundary++;
continue;
}
- if (c == softHyphenCharacter) {
+ if (c == softHyphenCharacter && !disableSoftHyphen) {
currMaxWidth += widthFromFont(f, lastWordBoundary, i - lastWordBoundary, leadWidth, currMaxWidth, textDirection, &fallbackFonts, &glyphBounds);
lastWordBoundary = i + 1;
continue;
@@ -983,7 +1023,7 @@ void LayoutText::computePreferredLogicalWidths(float leadWidth, HashSet<const Si
bool hasBreak = breakIterator.isBreakable(i, nextBreakable, breakAll ? LineBreakType::BreakAll : keepAll ? LineBreakType::KeepAll : LineBreakType::Normal);
bool betweenWords = true;
int j = i;
- while (c != newlineCharacter && c != spaceCharacter && c != tabulationCharacter && (c != softHyphenCharacter)) {
+ while (c != newlineCharacter && c != spaceCharacter && c != tabulationCharacter && (c != softHyphenCharacter || disableSoftHyphen)) {
j++;
if (j == len)
break;
@@ -1018,10 +1058,27 @@ void LayoutText::computePreferredLogicalWidths(float leadWidth, HashSet<const Si
w = widthFromFont(f, i, wordLen + 1, leadWidth, currMaxWidth, textDirection, &fallbackFonts, &glyphBounds) - wordTrailingSpaceWidth;
} else {
w = widthFromFont(f, i, wordLen, leadWidth, currMaxWidth, textDirection, &fallbackFonts, &glyphBounds);
- if (c == softHyphenCharacter)
+ if (c == softHyphenCharacter && !disableSoftHyphen)
currMinWidth += hyphenWidth(f, textDirection);
}
+ if (w > maxWordWidth) {
+ int suffixStart;
+ float maxFragmentWidth = maxWordFragmentWidth(this, styleToUse, f, textDirection, *hyphenation, i, wordLen, suffixStart);
+ if (suffixStart) {
+ float suffixWidth;
+ if (wordTrailingSpaceWidth && isSpace)
+ suffixWidth = widthFromFont(f, i + suffixStart, wordLen - suffixStart + 1, leadWidth, currMaxWidth, textDirection, &fallbackFonts, &glyphBounds) - wordTrailingSpaceWidth;
+ else
+ suffixWidth = widthFromFont(f, i + suffixStart, wordLen - suffixStart, leadWidth, currMaxWidth, textDirection, &fallbackFonts, &glyphBounds);
+ maxFragmentWidth = std::max(maxFragmentWidth, suffixWidth);
+ currMinWidth += maxFragmentWidth - w;
+ maxWordWidth = std::max(maxWordWidth, maxFragmentWidth);
+ } else {
+ maxWordWidth = w;
+ }
+ }
+
currMinWidth += w;
if (betweenWords) {
if (lastWordBoundary == i)

Powered by Google App Engine
This is Rietveld 408576698