Changeset 19621 in webkit


Ignore:
Timestamp:
Feb 14, 2007 6:10:31 AM (17 years ago)
Author:
weinig
Message:

LayoutTests:

Reviewed by Hyatt.

  • fast/text/break-word-expected.checksum: Added.
  • fast/text/break-word-expected.png: Added.
  • fast/text/break-word-expected.txt: Added.
  • fast/text/break-word.html: Added.

WebCore:

Reviewed by Hyatt.

Test: fast/text/break-word.html

The wrapW variable used to keep track of the width of the characters scanned
so far by adding up the widths of individual characters. Because of the
rounding hack, the total ended up being bigger than the width of the same characters
when measured together as a single run.

The fix is to use wrapW only as an upper bound, and once it overflows the line's width,
fall back on measuring everything from the beginning of the line as one run.

  • rendering/bidi.cpp: (WebCore::RenderBlock::findNextLineBreak): Implemented the above fix, including not measuring additional single characters once wrapW overflows the line. Also moved the assignment to breakNBSP out of the loop since it is constant for the entire text object, made breakWords and midWordBreak update only when they might change, and cleaned up a few things.
Location:
trunk
Files:
4 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r19620 r19621  
     12007-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
    1132007-02-14  Antti Koivisto  <antti@apple.com>
    214
  • trunk/WebCore/ChangeLog

    r19620 r19621  
     12007-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
    1242007-02-14  Antti Koivisto  <antti@apple.com>
    225
  • trunk/WebCore/rendering/bidi.cpp

    r19601 r19621  
    22152215                tmpW += o->width() + o->marginLeft() + o->marginRight() + inlineWidth(o);
    22162216        } else if (o->isText()) {
    2217             RenderText *t = static_cast<RenderText *>(o);
     2217            RenderText* t = static_cast<RenderText*>(o);
    22182218            int strlen = t->textLength();
    22192219            int len = strlen - pos;
     
    22212221
    22222222            const Font& f = t->style(m_firstLine)->font();
    2223             // proportional font, needs a bit more work.
     2223
    22242224            int lastSpace = pos;
    22252225            int wordSpacing = o->style()->wordSpacing();
     
    22302230            int wrapW = tmpW + inlineWidth(o, !appliedStartWidth, true);
    22312231            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;
    22322237           
    22332238            while (len) {
     
    22462251                        BidiIterator endMid;
    22472252                        if (pos > 0)
    2248                             endMid = BidiIterator(0, o, pos-1);
     2253                            endMid = BidiIterator(0, o, pos - 1);
    22492254                        else
    2250                             endMid = BidiIterator(0, previous, previous->isText() ? static_cast<RenderText *>(previous)->textLength() - 1 : 0);
     2255                            endMid = BidiIterator(0, previous, previous->isText() ? static_cast<RenderText*>(previous)->textLength() - 1 : 0);
    22512256                        // Two consecutive soft hyphens. Avoid overlapping midpoints.
    22522257                        if (sNumMidpoints && smidpoints->at(sNumMidpoints - 1).obj == endMid.obj && smidpoints->at(sNumMidpoints - 1).pos > endMid.pos)
     
    22562261                       
    22572262                        // 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;
    22592264                       
    22602265                        // For wrapping text only, include the hyphen.  We need to ensure it will fit
    22612266                        // on the line if it shows when we break.
    22622267                        if (autoWrap)
    2263                             tmpW += t->width(pos, 1, f, w+tmpW);
     2268                            tmpW += t->width(pos, 1, f, w + tmpW);
    22642269                       
    2265                         BidiIterator startMid(0, o, pos+1);
     2270                        BidiIterator startMid(0, o, pos + 1);
    22662271                        addMidpoint(startMid);
    22672272                    }
     
    22752280               
    22762281                bool applyWordSpacing = false;
    2277                 bool breakNBSP = autoWrap && o->style()->nbspMode() == SPACE;
    22782282               
    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 
    22822283                currentCharacterIsWS = currentCharacterIsSpace || (breakNBSP && c == noBreakSpace);
    22832284
    2284                 if (breakWords)
     2285                if (breakWords && !midWordBreak) {
    22852286                    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) {
    22892293                    bool stoppedIgnoringSpaces = false;
    22902294                    if (ignoringSpaces) {
     
    22952299                            lastSpaceWordSpacing = 0;
    22962300                            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);
    22982302                            addMidpoint(startMid);
    22992303                            stoppedIgnoringSpaces = true;
     
    23152319                    applyWordSpacing =  wordSpacing && currentCharacterIsSpace && !previousCharacterIsSpace;
    23162320
    2317                     if (autoWrap && w + tmpW > width && w == 0) {
     2321                    if (autoWrap && w + tmpW > width && !w) {
    23182322                        int fb = nearestFloatBottom(m_height);
    23192323                        int newLineWidth = lineWidth(fb);
     
    23932397                    }
    23942398
    2395                     if (autoWrap) {
     2399                    if (autoWrap && betweenWords) {
    23962400                        w += tmpW;
    23972401                        tmpW = 0;
    23982402                        lBreak.obj = o;
    23992403                        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;
    24002407                    }
    24012408                   
     
    24052412                        lBreak.obj = o;
    24062413                        lBreak.pos = pos;
     2414                        midWordBreak &= breakWords;
    24072415                    } else {
    24082416                        lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0;
     
    24572465            if (!ignoringSpaces)
    24582466                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);
    24622468        } else
    2463             ASSERT( false );
     2469            ASSERT_NOT_REACHED();
    24642470
    24652471        RenderObject* next = bidiNext(start.block, o, bidi);
     
    25282534        if (!last->isFloatingOrPositioned() && last->isReplaced() && autoWrap &&
    25292535            (!last->isListMarker() || static_cast<RenderListMarker*>(last)->isInside())) {
    2530             // Go ahead and add in tmpW.
    25312536            w += tmpW;
    25322537            tmpW = 0;
Note: See TracChangeset for help on using the changeset viewer.