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

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutText.cpp

Issue 2681633002: Fix min-content sizing for 'word-break: break-word' (Closed)
Patch Set: Created 3 years, 10 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * (C) 1999 Lars Knoll (knoll@kde.org) 2 * (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 2000 Dirk Mueller (mueller@kde.org) 3 * (C) 2000 Dirk Mueller (mueller@kde.org)
4 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. 4 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
5 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) 5 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
6 * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com) 6 * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public 9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
(...skipping 980 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 HashSet<const SimpleFontData*> fallbackFonts; 991 HashSet<const SimpleFontData*> fallbackFonts;
992 FloatRect glyphBounds; 992 FloatRect glyphBounds;
993 computePreferredLogicalWidths(leadWidth, fallbackFonts, glyphBounds); 993 computePreferredLogicalWidths(leadWidth, fallbackFonts, glyphBounds);
994 } 994 }
995 995
996 static float minWordFragmentWidthForBreakAll(LayoutText* layoutText, 996 static float minWordFragmentWidthForBreakAll(LayoutText* layoutText,
997 const ComputedStyle& style, 997 const ComputedStyle& style,
998 const Font& font, 998 const Font& font,
999 TextDirection textDirection, 999 TextDirection textDirection,
1000 int start, 1000 int start,
1001 int length) { 1001 int length,
1002 EWordBreak breakAllOrBreakWord) {
1002 DCHECK_GT(length, 0); 1003 DCHECK_GT(length, 0);
1003 LazyLineBreakIterator breakIterator(layoutText->text(), style.locale()); 1004 LazyLineBreakIterator breakIterator(layoutText->text(), style.locale());
1004 int nextBreakable = -1; 1005 int nextBreakable = -1;
1005 float min = std::numeric_limits<float>::max(); 1006 float min = std::numeric_limits<float>::max();
1006 int end = start + length; 1007 int end = start + length;
1007 for (int i = start; i < end;) { 1008 for (int i = start; i < end;) {
1008 breakIterator.isBreakable(i + 1, nextBreakable, LineBreakType::BreakAll); 1009 int fragmentLength;
1009 int fragmentLength = (nextBreakable > i ? nextBreakable : length) - i; 1010 if (breakAllOrBreakWord == EWordBreak::BreakAllWordBreak) {
1011 breakIterator.isBreakable(i + 1, nextBreakable, LineBreakType::BreakAll);
1012 fragmentLength = (nextBreakable > i ? nextBreakable : length) - i;
1013 } else {
1014 fragmentLength = U16_LENGTH(layoutText->codepointAt(i));
1015 }
1010 // The correct behavior is to measure width without re-shaping, but we 1016 // The correct behavior is to measure width without re-shaping, but we
1011 // reshape each fragment here because a) the current line breaker does not 1017 // reshape each fragment here because a) the current line breaker does not
1012 // support it, b) getCharacterRange() can reshape if the text is too long 1018 // support it, b) getCharacterRange() can reshape if the text is too long
1013 // to fit in the cache, and c) each fragment here is almost 1 char and thus 1019 // to fit in the cache, and c) each fragment here is almost 1 char and thus
1014 // reshape is fast. 1020 // reshape is fast.
1015 TextRun run = constructTextRun(font, layoutText, i, fragmentLength, style, 1021 TextRun run = constructTextRun(font, layoutText, i, fragmentLength, style,
1016 textDirection); 1022 textDirection);
1017 float fragmentWidth = font.width(run); 1023 float fragmentWidth = font.width(run);
1018 min = std::min(min, fragmentWidth); 1024 min = std::min(min, fragmentWidth);
1019 i += fragmentLength; 1025 i += fragmentLength;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 LazyLineBreakIterator breakIterator(m_text, styleToUse.locale()); 1093 LazyLineBreakIterator breakIterator(m_text, styleToUse.locale());
1088 bool needsWordSpacing = false; 1094 bool needsWordSpacing = false;
1089 bool ignoringSpaces = false; 1095 bool ignoringSpaces = false;
1090 bool isSpace = false; 1096 bool isSpace = false;
1091 bool firstWord = true; 1097 bool firstWord = true;
1092 bool firstLine = true; 1098 bool firstLine = true;
1093 int nextBreakable = -1; 1099 int nextBreakable = -1;
1094 int lastWordBoundary = 0; 1100 int lastWordBoundary = 0;
1095 float cachedWordTrailingSpaceWidth[2] = {0, 0}; // LTR, RTL 1101 float cachedWordTrailingSpaceWidth[2] = {0, 0}; // LTR, RTL
1096 1102
1097 bool breakAll = (styleToUse.wordBreak() == BreakAllWordBreak || 1103 EWordBreak breakAllOrBreakWord = EWordBreak::NormalWordBreak;
1098 styleToUse.wordBreak() == BreakWordBreak) && 1104 LineBreakType lineBreakType = LineBreakType::Normal;
1099 styleToUse.autoWrap(); 1105 if (styleToUse.autoWrap()) {
1100 bool keepAll = 1106 if (styleToUse.wordBreak() == BreakAllWordBreak ||
1101 styleToUse.wordBreak() == KeepAllWordBreak && styleToUse.autoWrap(); 1107 styleToUse.wordBreak() == BreakWordBreak) {
1108 breakAllOrBreakWord = styleToUse.wordBreak();
1109 } else if (styleToUse.wordBreak() == KeepAllWordBreak) {
1110 lineBreakType = LineBreakType::KeepAll;
1111 }
1112 }
1102 1113
1103 Hyphenation* hyphenation = 1114 Hyphenation* hyphenation =
1104 styleToUse.autoWrap() ? styleToUse.getHyphenation() : nullptr; 1115 styleToUse.autoWrap() ? styleToUse.getHyphenation() : nullptr;
1105 bool disableSoftHyphen = styleToUse.getHyphens() == HyphensNone; 1116 bool disableSoftHyphen = styleToUse.getHyphens() == HyphensNone;
1106 float maxWordWidth = 0; 1117 float maxWordWidth = 0;
1107 if (!hyphenation) 1118 if (!hyphenation)
1108 maxWordWidth = std::numeric_limits<float>::infinity(); 1119 maxWordWidth = std::numeric_limits<float>::infinity();
1109 1120
1110 BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver; 1121 BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver;
1111 BidiCharacterRun* run; 1122 BidiCharacterRun* run;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1187 continue; 1198 continue;
1188 } 1199 }
1189 if (c == softHyphenCharacter && !disableSoftHyphen) { 1200 if (c == softHyphenCharacter && !disableSoftHyphen) {
1190 currMaxWidth += widthFromFont(f, lastWordBoundary, i - lastWordBoundary, 1201 currMaxWidth += widthFromFont(f, lastWordBoundary, i - lastWordBoundary,
1191 leadWidth, currMaxWidth, textDirection, 1202 leadWidth, currMaxWidth, textDirection,
1192 &fallbackFonts, &glyphBounds); 1203 &fallbackFonts, &glyphBounds);
1193 lastWordBoundary = i + 1; 1204 lastWordBoundary = i + 1;
1194 continue; 1205 continue;
1195 } 1206 }
1196 1207
1197 bool hasBreak = breakIterator.isBreakable( 1208 bool hasBreak = breakIterator.isBreakable(i, nextBreakable, lineBreakType);
1198 i, nextBreakable,
1199 keepAll ? LineBreakType::KeepAll : LineBreakType::Normal);
1200 bool betweenWords = true; 1209 bool betweenWords = true;
1201 int j = i; 1210 int j = i;
1202 while (c != newlineCharacter && c != spaceCharacter && 1211 while (c != newlineCharacter && c != spaceCharacter &&
1203 c != tabulationCharacter && 1212 c != tabulationCharacter &&
1204 (c != softHyphenCharacter || disableSoftHyphen)) { 1213 (c != softHyphenCharacter || disableSoftHyphen)) {
1205 j++; 1214 j++;
1206 if (j == len) 1215 if (j == len)
1207 break; 1216 break;
1208 c = uncheckedCharacterAt(j); 1217 c = uncheckedCharacterAt(j);
1209 if (breakIterator.isBreakable(j, nextBreakable) && 1218 if (breakIterator.isBreakable(j, nextBreakable) &&
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1267 f, i + suffixStart, wordLen - suffixStart, leadWidth, 1276 f, i + suffixStart, wordLen - suffixStart, leadWidth,
1268 currMaxWidth, textDirection, &fallbackFonts, &glyphBounds); 1277 currMaxWidth, textDirection, &fallbackFonts, &glyphBounds);
1269 maxFragmentWidth = std::max(maxFragmentWidth, suffixWidth); 1278 maxFragmentWidth = std::max(maxFragmentWidth, suffixWidth);
1270 currMinWidth += maxFragmentWidth - w; 1279 currMinWidth += maxFragmentWidth - w;
1271 maxWordWidth = std::max(maxWordWidth, maxFragmentWidth); 1280 maxWordWidth = std::max(maxWordWidth, maxFragmentWidth);
1272 } else { 1281 } else {
1273 maxWordWidth = w; 1282 maxWordWidth = w;
1274 } 1283 }
1275 } 1284 }
1276 1285
1277 if (breakAll) { 1286 if (breakAllOrBreakWord != EWordBreak::NormalWordBreak) {
1278 // Because sum of character widths may not be equal to the word width, 1287 // Because sum of character widths may not be equal to the word width,
1279 // we need to measure twice; once with normal break for max width, 1288 // we need to measure twice; once with normal break for max width,
1280 // another with break-all for min width. 1289 // another with break-all for min width.
1281 currMinWidth = minWordFragmentWidthForBreakAll( 1290 currMinWidth =
1282 this, styleToUse, f, textDirection, i, wordLen); 1291 minWordFragmentWidthForBreakAll(this, styleToUse, f, textDirection,
1292 i, wordLen, breakAllOrBreakWord);
1283 } else { 1293 } else {
1284 currMinWidth += w; 1294 currMinWidth += w;
1285 } 1295 }
1286 if (betweenWords) { 1296 if (betweenWords) {
1287 if (lastWordBoundary == i) 1297 if (lastWordBoundary == i)
1288 currMaxWidth += w; 1298 currMaxWidth += w;
1289 else 1299 else
1290 currMaxWidth += widthFromFont( 1300 currMaxWidth += widthFromFont(
1291 f, lastWordBoundary, j - lastWordBoundary, leadWidth, 1301 f, lastWordBoundary, j - lastWordBoundary, leadWidth,
1292 currMaxWidth, textDirection, &fallbackFonts, &glyphBounds); 1302 currMaxWidth, textDirection, &fallbackFonts, &glyphBounds);
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after
2009 LayoutRect rect = LayoutRect( 2019 LayoutRect rect = LayoutRect(
2010 IntRect(firstRunX(), firstRunY(), linesBox.width(), linesBox.height())); 2020 IntRect(firstRunX(), firstRunY(), linesBox.width(), linesBox.height()));
2011 LayoutBlock* block = containingBlock(); 2021 LayoutBlock* block = containingBlock();
2012 if (block && hasTextBoxes()) 2022 if (block && hasTextBoxes())
2013 block->adjustChildDebugRect(rect); 2023 block->adjustChildDebugRect(rect);
2014 2024
2015 return rect; 2025 return rect;
2016 } 2026 }
2017 2027
2018 } // namespace blink 2028 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/LayoutTests/fast/css3-text/css3-word-break/word-break-break-word-fit-content-expected.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698