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

Side by Side 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 949 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 960
961 return m_maxWidth; 961 return m_maxWidth;
962 } 962 }
963 963
964 void LayoutText::computePreferredLogicalWidths(float leadWidth) { 964 void LayoutText::computePreferredLogicalWidths(float leadWidth) {
965 HashSet<const SimpleFontData*> fallbackFonts; 965 HashSet<const SimpleFontData*> fallbackFonts;
966 FloatRect glyphBounds; 966 FloatRect glyphBounds;
967 computePreferredLogicalWidths(leadWidth, fallbackFonts, glyphBounds); 967 computePreferredLogicalWidths(leadWidth, fallbackFonts, glyphBounds);
968 } 968 }
969 969
970 static float minWordFragmentWidthForBreakAll(LayoutText* layoutText,
971 const ComputedStyle& style,
972 const Font& font,
973 TextDirection textDirection,
974 int start,
975 int length) {
976 DCHECK_GT(length, 0);
977 LazyLineBreakIterator breakIterator(layoutText->text(), style.locale());
978 int nextBreakable = -1;
979 float min = std::numeric_limits<float>::max();
980 int end = start + length;
981 for (int i = start; i < end;) {
982 breakIterator.isBreakable(i + 1, nextBreakable, LineBreakType::BreakAll);
983 int fragmentLength = (nextBreakable > i ? nextBreakable : length) - i;
984 // The correct behavior is to measure width without re-shaping, but we
985 // reshape each fragment here because a) the current line breaker does not
986 // support it, b) getCharacterRange() can reshape if the text is too long
987 // to fit in the cache, and c) each fragment here is almost 1 char and thus
988 // reshape is fast.
989 TextRun run = constructTextRun(font, layoutText, i, fragmentLength, style,
990 textDirection);
991 float fragmentWidth = font.width(run);
992 min = std::min(min, fragmentWidth);
993 i += fragmentLength;
994 }
995 return min;
996 }
997
970 static float maxWordFragmentWidth(LayoutText* layoutText, 998 static float maxWordFragmentWidth(LayoutText* layoutText,
971 const ComputedStyle& style, 999 const ComputedStyle& style,
972 const Font& font, 1000 const Font& font,
973 TextDirection textDirection, 1001 TextDirection textDirection,
974 Hyphenation& hyphenation, 1002 Hyphenation& hyphenation,
975 unsigned wordOffset, 1003 unsigned wordOffset,
976 unsigned wordLength, 1004 unsigned wordLength,
977 int& suffixStart) { 1005 int& suffixStart) {
978 suffixStart = 0; 1006 suffixStart = 0;
979 if (wordLength <= Hyphenation::minimumSuffixLength) 1007 if (wordLength <= Hyphenation::minimumSuffixLength)
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1134 if (c == softHyphenCharacter && !disableSoftHyphen) { 1162 if (c == softHyphenCharacter && !disableSoftHyphen) {
1135 currMaxWidth += widthFromFont(f, lastWordBoundary, i - lastWordBoundary, 1163 currMaxWidth += widthFromFont(f, lastWordBoundary, i - lastWordBoundary,
1136 leadWidth, currMaxWidth, textDirection, 1164 leadWidth, currMaxWidth, textDirection,
1137 &fallbackFonts, &glyphBounds); 1165 &fallbackFonts, &glyphBounds);
1138 lastWordBoundary = i + 1; 1166 lastWordBoundary = i + 1;
1139 continue; 1167 continue;
1140 } 1168 }
1141 1169
1142 bool hasBreak = breakIterator.isBreakable( 1170 bool hasBreak = breakIterator.isBreakable(
1143 i, nextBreakable, 1171 i, nextBreakable,
1144 breakAll ? LineBreakType::BreakAll 1172 keepAll ? LineBreakType::KeepAll : LineBreakType::Normal);
1145 : keepAll ? LineBreakType::KeepAll : LineBreakType::Normal);
1146 bool betweenWords = true; 1173 bool betweenWords = true;
1147 int j = i; 1174 int j = i;
1148 while (c != newlineCharacter && c != spaceCharacter && 1175 while (c != newlineCharacter && c != spaceCharacter &&
1149 c != tabulationCharacter && 1176 c != tabulationCharacter &&
1150 (c != softHyphenCharacter || disableSoftHyphen)) { 1177 (c != softHyphenCharacter || disableSoftHyphen)) {
1151 j++; 1178 j++;
1152 if (j == len) 1179 if (j == len)
1153 break; 1180 break;
1154 c = uncheckedCharacterAt(j); 1181 c = uncheckedCharacterAt(j);
1155 if (breakIterator.isBreakable(j, nextBreakable) && 1182 if (breakIterator.isBreakable(j, nextBreakable) &&
1156 characterAt(j - 1) != softHyphenCharacter) 1183 characterAt(j - 1) != softHyphenCharacter)
1157 break; 1184 break;
1158 if (breakAll) {
1159 betweenWords = false;
1160 break;
1161 }
1162 } 1185 }
1163 1186
1164 // Terminate word boundary at bidi run boundary. 1187 // Terminate word boundary at bidi run boundary.
1165 if (run) 1188 if (run)
1166 j = std::min(j, run->stop() + 1); 1189 j = std::min(j, run->stop() + 1);
1167 int wordLen = j - i; 1190 int wordLen = j - i;
1168 if (wordLen) { 1191 if (wordLen) {
1169 bool isSpace = (j < len) && c == spaceCharacter; 1192 bool isSpace = (j < len) && c == spaceCharacter;
1170 1193
1171 // Non-zero only when kerning is enabled, in which case we measure words 1194 // Non-zero only when kerning is enabled, in which case we measure words
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1213 f, i + suffixStart, wordLen - suffixStart, leadWidth, 1236 f, i + suffixStart, wordLen - suffixStart, leadWidth,
1214 currMaxWidth, textDirection, &fallbackFonts, &glyphBounds); 1237 currMaxWidth, textDirection, &fallbackFonts, &glyphBounds);
1215 maxFragmentWidth = std::max(maxFragmentWidth, suffixWidth); 1238 maxFragmentWidth = std::max(maxFragmentWidth, suffixWidth);
1216 currMinWidth += maxFragmentWidth - w; 1239 currMinWidth += maxFragmentWidth - w;
1217 maxWordWidth = std::max(maxWordWidth, maxFragmentWidth); 1240 maxWordWidth = std::max(maxWordWidth, maxFragmentWidth);
1218 } else { 1241 } else {
1219 maxWordWidth = w; 1242 maxWordWidth = w;
1220 } 1243 }
1221 } 1244 }
1222 1245
1223 currMinWidth += w; 1246 if (breakAll) {
1247 // Because sum of character widths may not be equal to the word width,
1248 // we need to measure twice; once with normal break for max width,
1249 // another with break-all for min width.
1250 currMinWidth = minWordFragmentWidthForBreakAll(
1251 this, styleToUse, f, textDirection, i, wordLen);
1252 } else {
1253 currMinWidth += w;
1254 }
1224 if (betweenWords) { 1255 if (betweenWords) {
1225 if (lastWordBoundary == i) 1256 if (lastWordBoundary == i)
1226 currMaxWidth += w; 1257 currMaxWidth += w;
1227 else 1258 else
1228 currMaxWidth += widthFromFont( 1259 currMaxWidth += widthFromFont(
1229 f, lastWordBoundary, j - lastWordBoundary, leadWidth, 1260 f, lastWordBoundary, j - lastWordBoundary, leadWidth,
1230 currMaxWidth, textDirection, &fallbackFonts, &glyphBounds); 1261 currMaxWidth, textDirection, &fallbackFonts, &glyphBounds);
1231 lastWordBoundary = j; 1262 lastWordBoundary = j;
1232 } 1263 }
1233 1264
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after
1952 LayoutRect rect = LayoutRect( 1983 LayoutRect rect = LayoutRect(
1953 IntRect(firstRunX(), firstRunY(), linesBox.width(), linesBox.height())); 1984 IntRect(firstRunX(), firstRunY(), linesBox.width(), linesBox.height()));
1954 LayoutBlock* block = containingBlock(); 1985 LayoutBlock* block = containingBlock();
1955 if (block && hasTextBoxes()) 1986 if (block && hasTextBoxes())
1956 block->adjustChildDebugRect(rect); 1987 block->adjustChildDebugRect(rect);
1957 1988
1958 return rect; 1989 return rect;
1959 } 1990 }
1960 1991
1961 } // namespace blink 1992 } // namespace blink
OLDNEW
« 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