Changeset 19621 in webkit
- Timestamp:
- Feb 14, 2007 6:10:31 AM (17 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r19620 r19621 1 2007-02-14 Mitz Pettel <mitz@webkit.org> 2 3 Reviewed by Hyatt. 4 5 - test for http://bugs.webkit.org/show_bug.cgi?id=12726 6 REGRESSION (r12073): Text wraps in the middle of a word instead of wrapping at the space before the word 7 8 * fast/text/break-word-expected.checksum: Added. 9 * fast/text/break-word-expected.png: Added. 10 * fast/text/break-word-expected.txt: Added. 11 * fast/text/break-word.html: Added. 12 1 13 2007-02-14 Antti Koivisto <antti@apple.com> 2 14 -
trunk/WebCore/ChangeLog
r19620 r19621 1 2007-02-14 Mitz Pettel <mitz@webkit.org> 2 3 Reviewed by Hyatt. 4 5 - fix http://bugs.webkit.org/show_bug.cgi?id=12726 6 REGRESSION (r12073): Text wraps in the middle of a word instead of wrapping at the space before the word 7 8 Test: fast/text/break-word.html 9 10 The wrapW variable used to keep track of the width of the characters scanned 11 so far by adding up the widths of individual characters. Because of the 12 rounding hack, the total ended up being bigger than the width of the same characters 13 when measured together as a single run. 14 15 The fix is to use wrapW only as an upper bound, and once it overflows the line's width, 16 fall back on measuring everything from the beginning of the line as one run. 17 18 * rendering/bidi.cpp: 19 (WebCore::RenderBlock::findNextLineBreak): Implemented the above fix, including not measuring 20 additional single characters once wrapW overflows the line. Also moved the assignment 21 to breakNBSP out of the loop since it is constant for the entire text object, made breakWords and 22 midWordBreak update only when they might change, and cleaned up a few things. 23 1 24 2007-02-14 Antti Koivisto <antti@apple.com> 2 25 -
trunk/WebCore/rendering/bidi.cpp
r19601 r19621 2215 2215 tmpW += o->width() + o->marginLeft() + o->marginRight() + inlineWidth(o); 2216 2216 } else if (o->isText()) { 2217 RenderText *t = static_cast<RenderText*>(o);2217 RenderText* t = static_cast<RenderText*>(o); 2218 2218 int strlen = t->textLength(); 2219 2219 int len = strlen - pos; … … 2221 2221 2222 2222 const Font& f = t->style(m_firstLine)->font(); 2223 // proportional font, needs a bit more work. 2223 2224 2224 int lastSpace = pos; 2225 2225 int wordSpacing = o->style()->wordSpacing(); … … 2230 2230 int wrapW = tmpW + inlineWidth(o, !appliedStartWidth, true); 2231 2231 int nextBreakable = -1; 2232 bool breakNBSP = autoWrap && o->style()->nbspMode() == SPACE; 2233 // Auto-wrapping text should wrap in the middle of a word only if it could not wrap before the word, 2234 // which is only possible if the word is the first thing on the line, that is, if |w| is zero. 2235 bool breakWords = o->style()->wordWrap() == BREAK_WORD && ((autoWrap && !w) || currWS == PRE); 2236 bool midWordBreak = false; 2232 2237 2233 2238 while (len) { … … 2246 2251 BidiIterator endMid; 2247 2252 if (pos > 0) 2248 endMid = BidiIterator(0, o, pos -1);2253 endMid = BidiIterator(0, o, pos - 1); 2249 2254 else 2250 endMid = BidiIterator(0, previous, previous->isText() ? static_cast<RenderText 2255 endMid = BidiIterator(0, previous, previous->isText() ? static_cast<RenderText*>(previous)->textLength() - 1 : 0); 2251 2256 // Two consecutive soft hyphens. Avoid overlapping midpoints. 2252 2257 if (sNumMidpoints && smidpoints->at(sNumMidpoints - 1).obj == endMid.obj && smidpoints->at(sNumMidpoints - 1).pos > endMid.pos) … … 2256 2261 2257 2262 // Add the width up to but not including the hyphen. 2258 tmpW += t->width(lastSpace, pos - lastSpace, f, w +tmpW) + lastSpaceWordSpacing;2263 tmpW += t->width(lastSpace, pos - lastSpace, f, w + tmpW) + lastSpaceWordSpacing; 2259 2264 2260 2265 // For wrapping text only, include the hyphen. We need to ensure it will fit 2261 2266 // on the line if it shows when we break. 2262 2267 if (autoWrap) 2263 tmpW += t->width(pos, 1, f, w +tmpW);2268 tmpW += t->width(pos, 1, f, w + tmpW); 2264 2269 2265 BidiIterator startMid(0, o, pos +1);2270 BidiIterator startMid(0, o, pos + 1); 2266 2271 addMidpoint(startMid); 2267 2272 } … … 2275 2280 2276 2281 bool applyWordSpacing = false; 2277 bool breakNBSP = autoWrap && o->style()->nbspMode() == SPACE;2278 2282 2279 // FIXME: This check looks suspicious. Why does w have to be 0?2280 bool breakWords = o->style()->wordWrap() == BREAK_WORD && ((autoWrap && w == 0) || currWS == PRE);2281 2282 2283 currentCharacterIsWS = currentCharacterIsSpace || (breakNBSP && c == noBreakSpace); 2283 2284 2284 if (breakWords )2285 if (breakWords && !midWordBreak) { 2285 2286 wrapW += t->width(pos, 1, f, w+wrapW); 2286 bool midWordBreak = breakWords && (w + wrapW > width); 2287 2288 if (c == '\n' || (currWS != PRE && isBreakable(str, pos, strlen, nextBreakable, breakNBSP)) || midWordBreak) { 2287 midWordBreak = w + wrapW > width; 2288 } 2289 2290 bool betweenWords = c == '\n' || (currWS != PRE && isBreakable(str, pos, strlen, nextBreakable, breakNBSP)); 2291 2292 if (betweenWords || midWordBreak) { 2289 2293 bool stoppedIgnoringSpaces = false; 2290 2294 if (ignoringSpaces) { … … 2295 2299 lastSpaceWordSpacing = 0; 2296 2300 lastSpace = pos; // e.g., "Foo goo", don't add in any of the ignored spaces. 2297 BidiIterator startMid ( 0, o, pos);2301 BidiIterator startMid(0, o, pos); 2298 2302 addMidpoint(startMid); 2299 2303 stoppedIgnoringSpaces = true; … … 2315 2319 applyWordSpacing = wordSpacing && currentCharacterIsSpace && !previousCharacterIsSpace; 2316 2320 2317 if (autoWrap && w + tmpW > width && w == 0) {2321 if (autoWrap && w + tmpW > width && !w) { 2318 2322 int fb = nearestFloatBottom(m_height); 2319 2323 int newLineWidth = lineWidth(fb); … … 2393 2397 } 2394 2398 2395 if (autoWrap ) {2399 if (autoWrap && betweenWords) { 2396 2400 w += tmpW; 2397 2401 tmpW = 0; 2398 2402 lBreak.obj = o; 2399 2403 lBreak.pos = pos; 2404 // Auto-wrapping text should not wrap in the middle of a word once it has had an 2405 // opportunity to break after a word. 2406 breakWords = false; 2400 2407 } 2401 2408 … … 2405 2412 lBreak.obj = o; 2406 2413 lBreak.pos = pos; 2414 midWordBreak &= breakWords; 2407 2415 } else { 2408 2416 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0; … … 2457 2465 if (!ignoringSpaces) 2458 2466 tmpW += t->width(lastSpace, pos - lastSpace, f, w+tmpW) + lastSpaceWordSpacing; 2459 if (!appliedStartWidth) 2460 tmpW += inlineWidth(o, true, false); 2461 tmpW += inlineWidth(o, false, true); 2467 tmpW += inlineWidth(o, !appliedStartWidth, true); 2462 2468 } else 2463 ASSERT ( false);2469 ASSERT_NOT_REACHED(); 2464 2470 2465 2471 RenderObject* next = bidiNext(start.block, o, bidi); … … 2528 2534 if (!last->isFloatingOrPositioned() && last->isReplaced() && autoWrap && 2529 2535 (!last->isListMarker() || static_cast<RenderListMarker*>(last)->isInside())) { 2530 // Go ahead and add in tmpW.2531 2536 w += tmpW; 2532 2537 tmpW = 0;
Note: See TracChangeset
for help on using the changeset viewer.