Changeset 85668 in webkit


Ignore:
Timestamp:
May 3, 2011 3:11:39 PM (13 years ago)
Author:
eric@webkit.org
Message:

2011-05-03 Eric Seidel <eric@webkit.org>

Reviewed by Ryosuke Niwa.

Split out layoutRunsAndFloats from layoutInlineChildren
https://bugs.webkit.org/show_bug.cgi?id=60052

No new tests, just moving code here. There should be
no change in behavior.

  • rendering/RenderBlock.h:
  • rendering/RenderBlockLineLayout.cpp: (WebCore::RenderBlock::layoutRunsAndFloats): (WebCore::RenderBlock::layoutInlineChildren):
Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r85661 r85668  
     12011-05-03  Eric Seidel  <eric@webkit.org>
     2
     3        Reviewed by Ryosuke Niwa.
     4
     5        Split out layoutRunsAndFloats from layoutInlineChildren
     6        https://bugs.webkit.org/show_bug.cgi?id=60052
     7
     8        No new tests, just moving code here.  There should be
     9        no change in behavior.
     10
     11        * rendering/RenderBlock.h:
     12        * rendering/RenderBlockLineLayout.cpp:
     13        (WebCore::RenderBlock::layoutRunsAndFloats):
     14        (WebCore::RenderBlock::layoutInlineChildren):
     15
    1162011-05-03  James Robinson  <jamesr@chromium.org>
    217
  • trunk/Source/WebCore/rendering/RenderBlock.h

    r85652 r85668  
    702702    // End helper functions and structs used by layoutBlockChildren.
    703703
     704    // Helper function for layoutInlineChildren()
     705    void layoutRunsAndFloats(bool fullLayout, bool hasInlineChild, Vector<FloatWithRect>&, int& repaintLogicalTop, int& repaintLogicalBottom);
     706
    704707    // Pagination routines.
    705708    int nextPageLogicalTop(int logicalOffset) const; // Returns the top of the next page following logicalOffset.
  • trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp

    r85652 r85668  
    6060// We don't let our line box tree for a single line get any deeper than this.
    6161const unsigned cMaxLineDepth = 200;
    62    
     62
    6363class LineInfo {
    6464public:
     
    132132                endpoint.m_pos--;
    133133        }
    134     }   
     134    }
    135135}
    136136
     
    163163        if (!(haveNextMidpoint && nextMidpoint.m_obj == obj))
    164164            return;
    165         // This is a new start point. Stop ignoring objects and 
     165        // This is a new start point. Stop ignoring objects and
    166166        // adjust our start.
    167167        lineMidpointState.betweenMidpoints = false;
     
    195195    if (isRootLineBox)
    196196        return toRenderBlock(obj)->createAndAppendRootInlineBox();
    197    
     197
    198198    if (obj->isText()) {
    199199        InlineTextBox* textBox = toRenderText(obj)->createInlineTextBox();
     
    204204        return textBox;
    205205    }
    206    
     206
    207207    if (obj->isBox())
    208208        return toRenderBox(obj)->createInlineBox();
    209    
     209
    210210    return toRenderInline(obj)->createAndAppendInlineFlowBox();
    211211}
     
    241241    do {
    242242        ASSERT(obj->isRenderInline() || obj == this);
    243        
     243
    244244        RenderInline* inlineFlow = (obj != this) ? toRenderInline(obj) : 0;
    245245
     
    281281                break;
    282282
    283             childBox = parentBox;       
     283            childBox = parentBox;
    284284        }
    285285
     
    477477                if (!r->m_start && needsWordSpacing && isSpaceOrNewline(rt->characters()[r->m_start]))
    478478                    totalLogicalWidth += rt->style(lineInfo.isFirstLine())->font().wordSpacing();
    479                 needsWordSpacing = !isSpaceOrNewline(rt->characters()[r->m_stop - 1]) && r->m_stop == length;         
     479                needsWordSpacing = !isSpaceOrNewline(rt->characters()[r->m_stop - 1]) && r->m_stop == length;
    480480            }
    481481            HashSet<const SimpleFontData*> fallbackFonts;
    482482            GlyphOverflow glyphOverflow;
    483            
     483
    484484            // Always compute glyph overflow if the block's line-box-contain value is "glyphs".
    485485            if (lineBox->fitsToGlyphs()) {
     
    493493                int boxDescent = rt->style(lineInfo.isFirstLine())->font().fontMetrics().descent() + baselineShift;
    494494                if (boxAscent > rootDescent ||  boxDescent > rootAscent)
    495                     glyphOverflow.computeBounds = true; 
     495                    glyphOverflow.computeBounds = true;
    496496            }
    497497
     
    752752}
    753753
     754void RenderBlock::layoutRunsAndFloats(bool fullLayout, bool hasInlineChild, Vector<FloatWithRect>& floats, int& repaintLogicalTop, int& repaintLogicalBottom)
     755{
     756    // We want to skip ahead to the first dirty line
     757    InlineBidiResolver resolver;
     758    unsigned floatIndex;
     759    LineInfo lineInfo;
     760    bool useRepaintBounds = false;
     761
     762    RootInlineBox* startLine = determineStartPosition(lineInfo, fullLayout, resolver, floats, floatIndex,
     763                                                      useRepaintBounds, repaintLogicalTop, repaintLogicalBottom);
     764
     765    // FIXME: This would make more sense outside of this function, but since
     766    // determineStartPosition can change the fullLayout flag we have to do this here. Failure to call
     767    // determineStartPosition first will break fast/repaint/line-flow-with-floats-9.html.
     768    if (fullLayout && hasInlineChild && !selfNeedsLayout()) {
     769        setNeedsLayout(true, false);  // Mark ourselves as needing a full layout. This way we'll repaint like
     770        // we're supposed to.
     771        RenderView* v = view();
     772        if (v && !v->doingFullRepaint() && hasLayer()) {
     773            // Because we waited until we were already inside layout to discover
     774            // that the block really needed a full layout, we missed our chance to repaint the layer
     775            // before layout started.  Luckily the layer has cached the repaint rect for its original
     776            // position and size, and so we can use that to make a repaint happen now.
     777            repaintUsingContainer(containerForRepaint(), layer()->repaintRect());
     778        }
     779    }
     780
     781    FloatingObject* lastFloat = (m_floatingObjects && !m_floatingObjects->set().isEmpty()) ? m_floatingObjects->set().last() : 0;
     782
     783    LineMidpointState& lineMidpointState = resolver.midpointState();
     784
     785    // We also find the first clean line and extract these lines.  We will add them back
     786    // if we determine that we're able to synchronize after handling all our dirty lines.
     787    InlineIterator cleanLineStart;
     788    BidiStatus cleanLineBidiStatus;
     789    int endLineLogicalTop = 0;
     790    RootInlineBox* endLine = (fullLayout || !startLine) ?
     791        0 : determineEndPosition(startLine, floats, floatIndex, cleanLineStart, cleanLineBidiStatus, endLineLogicalTop);
     792
     793    if (startLine) {
     794        if (!useRepaintBounds) {
     795            useRepaintBounds = true;
     796            repaintLogicalTop = logicalHeight();
     797            repaintLogicalBottom = logicalHeight();
     798        }
     799        RenderArena* arena = renderArena();
     800        RootInlineBox* box = startLine;
     801        while (box) {
     802            repaintLogicalTop = min(repaintLogicalTop, box->logicalTopVisualOverflow());
     803            repaintLogicalBottom = max(repaintLogicalBottom, box->logicalBottomVisualOverflow());
     804            RootInlineBox* next = box->nextRootBox();
     805            box->deleteLine(arena);
     806            box = next;
     807        }
     808    }
     809
     810    InlineIterator end = resolver.position();
     811
     812    if (!fullLayout && lastRootBox() && lastRootBox()->endsWithBreak()) {
     813        // If the last line before the start line ends with a line break that clear floats,
     814        // adjust the height accordingly.
     815        // A line break can be either the first or the last object on a line, depending on its direction.
     816        if (InlineBox* lastLeafChild = lastRootBox()->lastLeafChild()) {
     817            RenderObject* lastObject = lastLeafChild->renderer();
     818            if (!lastObject->isBR())
     819                lastObject = lastRootBox()->firstLeafChild()->renderer();
     820            if (lastObject->isBR()) {
     821                EClear clear = lastObject->style()->clear();
     822                if (clear != CNONE)
     823                    newLine(clear);
     824            }
     825        }
     826    }
     827
     828    bool endLineMatched = false;
     829    bool checkForEndLineMatch = endLine;
     830    bool checkForFloatsFromLastLine = false;
     831
     832    bool paginated = view()->layoutState() && view()->layoutState()->isPaginated();
     833
     834    LineBreakIteratorInfo lineBreakIteratorInfo;
     835    VerticalPositionCache verticalPositionCache;
     836
     837    while (!end.atEnd()) {
     838        // FIXME: Is this check necessary before the first iteration or can it be moved to the end?
     839        if (checkForEndLineMatch && (endLineMatched = matchedEndLine(resolver, cleanLineStart, cleanLineBidiStatus, endLine, endLineLogicalTop, repaintLogicalBottom, repaintLogicalTop)))
     840            break;
     841
     842        lineMidpointState.reset();
     843
     844        lineInfo.setEmpty(true);
     845
     846        EClear clear = CNONE;
     847        bool hyphenated;
     848        Vector<RenderBox*> positionedObjects;
     849
     850        InlineIterator oldEnd = end;
     851        FloatingObject* lastFloatFromPreviousLine = (m_floatingObjects && !m_floatingObjects->set().isEmpty()) ? m_floatingObjects->set().last() : 0;
     852        end = findNextLineBreak(resolver, lineInfo, lineBreakIteratorInfo, hyphenated, &clear, lastFloatFromPreviousLine, positionedObjects);
     853        if (resolver.position().atEnd()) {
     854            // FIXME: We shouldn't be creating any runs in findNextLineBreak to begin with!
     855            // Once BidiRunList is separated from BidiResolver this will not be needed.
     856            resolver.runs().deleteRuns();
     857            resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed).
     858            checkForFloatsFromLastLine = true;
     859            break;
     860        }
     861        ASSERT(end != resolver.position());
     862
     863        if (lineInfo.isEmpty()) {
     864            if (lastRootBox())
     865                lastRootBox()->setLineBreakInfo(end.m_obj, end.m_pos, resolver.status());
     866        } else {
     867            VisualDirectionOverride override = (style()->visuallyOrdered() ? (style()->direction() == LTR ? VisualLeftToRightOverride : VisualRightToLeftOverride) : NoVisualOverride);
     868            // FIXME: This ownership is reversed. We should own the BidiRunList and pass it to createBidiRunsForLine.
     869            BidiRunList<BidiRun>& bidiRuns = resolver.runs();
     870            resolver.createBidiRunsForLine(end, override, lineInfo.previousLineBrokeCleanly());
     871            ASSERT(resolver.position() == end);
     872
     873            BidiRun* trailingSpaceRun = !lineInfo.previousLineBrokeCleanly() ? handleTrailingSpaces(bidiRuns, resolver.context()) : 0;
     874
     875            // Now that the runs have been ordered, we create the line boxes.
     876            // At the same time we figure out where border/padding/margin should be applied for
     877            // inline flow boxes.
     878
     879            RootInlineBox* lineBox = 0;
     880            int oldLogicalHeight = logicalHeight();
     881            if (bidiRuns.runCount()) {
     882                if (hyphenated)
     883                    bidiRuns.logicallyLastRun()->m_hasHyphen = true;
     884                lineInfo.setLastLine(!end.m_obj);
     885                lineBox = constructLine(bidiRuns, lineInfo);
     886                if (lineBox) {
     887                    lineBox->setEndsWithBreak(lineInfo.previousLineBrokeCleanly());
     888
     889#if ENABLE(SVG)
     890                    bool isSVGRootInlineBox = lineBox->isSVGRootInlineBox();
     891#else
     892                    bool isSVGRootInlineBox = false;
     893#endif
     894
     895                    GlyphOverflowAndFallbackFontsMap textBoxDataMap;
     896
     897                    // Now we position all of our text runs horizontally.
     898                    if (!isSVGRootInlineBox)
     899                        computeInlineDirectionPositionsForLine(lineBox, lineInfo, bidiRuns.firstRun(), trailingSpaceRun, end.atEnd(), textBoxDataMap, verticalPositionCache);
     900
     901                    // Now position our text runs vertically.
     902                    computeBlockDirectionPositionsForLine(lineBox, bidiRuns.firstRun(), textBoxDataMap, verticalPositionCache);
     903
     904#if ENABLE(SVG)
     905                    // SVG text layout code computes vertical & horizontal positions on its own.
     906                    // Note that we still need to execute computeVerticalPositionsForLine() as
     907                    // it calls InlineTextBox::positionLineBox(), which tracks whether the box
     908                    // contains reversed text or not. If we wouldn't do that editing and thus
     909                    // text selection in RTL boxes would not work as expected.
     910                    if (isSVGRootInlineBox) {
     911                        ASSERT(isSVGText());
     912                        static_cast<SVGRootInlineBox*>(lineBox)->computePerCharacterLayoutInformation();
     913                    }
     914#endif
     915
     916                    // Compute our overflow now.
     917                    lineBox->computeOverflow(lineBox->lineTop(), lineBox->lineBottom(), textBoxDataMap);
     918
     919#if PLATFORM(MAC)
     920                    // Highlight acts as an overflow inflation.
     921                    if (style()->highlight() != nullAtom)
     922                        lineBox->addHighlightOverflow();
     923#endif
     924                }
     925            }
     926
     927            bidiRuns.deleteRuns();
     928            resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed).
     929
     930            if (lineBox) {
     931                lineBox->setLineBreakInfo(end.m_obj, end.m_pos, resolver.status());
     932                if (useRepaintBounds) {
     933                    repaintLogicalTop = min(repaintLogicalTop, lineBox->logicalTopVisualOverflow());
     934                    repaintLogicalBottom = max(repaintLogicalBottom, lineBox->logicalBottomVisualOverflow());
     935                }
     936
     937                if (paginated) {
     938                    int adjustment = 0;
     939                    adjustLinePositionForPagination(lineBox, adjustment);
     940                    if (adjustment) {
     941                        int oldLineWidth = availableLogicalWidthForLine(oldLogicalHeight, lineInfo.isFirstLine());
     942                        lineBox->adjustBlockDirectionPosition(adjustment);
     943                        if (useRepaintBounds) // This can only be a positive adjustment, so no need to update repaintTop.
     944                            repaintLogicalBottom = max(repaintLogicalBottom, lineBox->logicalBottomVisualOverflow());
     945
     946                        if (availableLogicalWidthForLine(oldLogicalHeight + adjustment, lineInfo.isFirstLine()) != oldLineWidth) {
     947                            // We have to delete this line, remove all floats that got added, and let line layout re-run.
     948                            lineBox->deleteLine(renderArena());
     949                            removeFloatingObjectsBelow(lastFloatFromPreviousLine, oldLogicalHeight);
     950                            setLogicalHeight(oldLogicalHeight + adjustment);
     951                            resolver.setPosition(oldEnd);
     952                            end = oldEnd;
     953                            continue;
     954                        }
     955
     956                        setLogicalHeight(lineBox->blockLogicalHeight());
     957                    }
     958                }
     959            }
     960
     961            for (size_t i = 0; i < positionedObjects.size(); ++i)
     962                setStaticPositions(this, positionedObjects[i]);
     963
     964            lineInfo.setFirstLine(false);
     965            newLine(clear);
     966        }
     967
     968        if (m_floatingObjects && lastRootBox()) {
     969            FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
     970            FloatingObjectSetIterator it = floatingObjectSet.begin();
     971            FloatingObjectSetIterator end = floatingObjectSet.end();
     972            if (lastFloat) {
     973                FloatingObjectSetIterator lastFloatIterator = floatingObjectSet.find(lastFloat);
     974                ASSERT(lastFloatIterator != end);
     975                ++lastFloatIterator;
     976                it = lastFloatIterator;
     977            }
     978            for (; it != end; ++it) {
     979                FloatingObject* f = *it;
     980                appendFloatingObjectToLastLine(f);
     981                ASSERT(f->m_renderer == floats[floatIndex].object);
     982                // If a float's geometry has changed, give up on syncing with clean lines.
     983                if (floats[floatIndex].rect != f->frameRect())
     984                    checkForEndLineMatch = false;
     985                floatIndex++;
     986            }
     987            lastFloat = !floatingObjectSet.isEmpty() ? floatingObjectSet.last() : 0;
     988        }
     989
     990        lineMidpointState.reset();
     991        resolver.setPosition(end);
     992    }
     993
     994    if (endLine) {
     995        if (endLineMatched) {
     996            // Attach all the remaining lines, and then adjust their y-positions as needed.
     997            int delta = logicalHeight() - endLineLogicalTop;
     998            for (RootInlineBox* line = endLine; line; line = line->nextRootBox()) {
     999                line->attachLine();
     1000                if (paginated) {
     1001                    delta -= line->paginationStrut();
     1002                    adjustLinePositionForPagination(line, delta);
     1003                }
     1004                if (delta) {
     1005                    repaintLogicalTop = min(repaintLogicalTop, line->logicalTopVisualOverflow() + min(delta, 0));
     1006                    repaintLogicalBottom = max(repaintLogicalBottom, line->logicalBottomVisualOverflow() + max(delta, 0));
     1007                    line->adjustBlockDirectionPosition(delta);
     1008                }
     1009                if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) {
     1010                    Vector<RenderBox*>::iterator end = cleanLineFloats->end();
     1011                    for (Vector<RenderBox*>::iterator f = cleanLineFloats->begin(); f != end; ++f) {
     1012                        insertFloatingObject(*f);
     1013                        setLogicalHeight(logicalTopForChild(*f) - marginBeforeForChild(*f) + delta);
     1014                        positionNewFloats();
     1015                    }
     1016                }
     1017            }
     1018            setLogicalHeight(lastRootBox()->blockLogicalHeight());
     1019        } else {
     1020            // Delete all the remaining lines.
     1021            RootInlineBox* line = endLine;
     1022            RenderArena* arena = renderArena();
     1023            while (line) {
     1024                repaintLogicalTop = min(repaintLogicalTop, line->logicalTopVisualOverflow());
     1025                repaintLogicalBottom = max(repaintLogicalBottom, line->logicalBottomVisualOverflow());
     1026                RootInlineBox* next = line->nextRootBox();
     1027                line->deleteLine(arena);
     1028                line = next;
     1029            }
     1030        }
     1031    }
     1032    if (m_floatingObjects && (checkForFloatsFromLastLine || positionNewFloats()) && lastRootBox()) {
     1033        // In case we have a float on the last line, it might not be positioned up to now.
     1034        // This has to be done before adding in the bottom border/padding, or the float will
     1035        // include the padding incorrectly. -dwh
     1036        if (checkForFloatsFromLastLine) {
     1037            int bottomVisualOverflow = lastRootBox()->logicalBottomVisualOverflow();
     1038            int bottomLayoutOverflow = lastRootBox()->logicalBottomLayoutOverflow();
     1039            TrailingFloatsRootInlineBox* trailingFloatsLineBox = new (renderArena()) TrailingFloatsRootInlineBox(this);
     1040            m_lineBoxes.appendLineBox(trailingFloatsLineBox);
     1041            trailingFloatsLineBox->setConstructed();
     1042            GlyphOverflowAndFallbackFontsMap textBoxDataMap;
     1043            VerticalPositionCache verticalPositionCache;
     1044            trailingFloatsLineBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, verticalPositionCache);
     1045            int blockLogicalHeight = logicalHeight();
     1046            IntRect logicalLayoutOverflow(0, blockLogicalHeight, 1, bottomLayoutOverflow - blockLogicalHeight);
     1047            IntRect logicalVisualOverflow(0, blockLogicalHeight, 1, bottomVisualOverflow - blockLogicalHeight);
     1048            trailingFloatsLineBox->setOverflowFromLogicalRects(logicalLayoutOverflow, logicalVisualOverflow, trailingFloatsLineBox->lineTop(), trailingFloatsLineBox->lineBottom());
     1049            trailingFloatsLineBox->setBlockLogicalHeight(logicalHeight());
     1050        }
     1051
     1052        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
     1053        FloatingObjectSetIterator it = floatingObjectSet.begin();
     1054        FloatingObjectSetIterator end = floatingObjectSet.end();
     1055        if (lastFloat) {
     1056            FloatingObjectSetIterator lastFloatIterator = floatingObjectSet.find(lastFloat);
     1057            ASSERT(lastFloatIterator != end);
     1058            ++lastFloatIterator;
     1059            it = lastFloatIterator;
     1060        }
     1061        for (; it != end; ++it)
     1062            appendFloatingObjectToLastLine(*it);
     1063        lastFloat = !floatingObjectSet.isEmpty() ? floatingObjectSet.last() : 0;
     1064    }
     1065    size_t floatCount = floats.size();
     1066    // Floats that did not have layout did not repaint when we laid them out. They would have
     1067    // painted by now if they had moved, but if they stayed at (0, 0), they still need to be
     1068    // painted.
     1069    for (size_t i = 0; i < floatCount; ++i) {
     1070        if (!floats[i].everHadLayout) {
     1071            RenderBox* f = floats[i].object;
     1072            if (!f->x() && !f->y() && f->checkForRepaintDuringLayout())
     1073                f->repaint();
     1074        }
     1075    }
     1076}
     1077
    7541078void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogicalTop, int& repaintLogicalBottom)
    7551079{
    756     bool useRepaintBounds = false;
    757    
    7581080    m_overflow.clear();
    759        
     1081
    7601082    setLogicalHeight(borderBefore() + paddingBefore());
    7611083
     
    7891111            if (o->isReplaced() || o->isFloating() || o->isPositioned()) {
    7901112                RenderBox* box = toRenderBox(o);
    791                
     1113
    7921114                if (relayoutChildren || o->style()->width().isPercent() || o->style()->height().isPercent())
    7931115                    o->setChildNeedsLayout(true, false);
    794                    
     1116
    7951117                // If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.
    7961118                if (relayoutChildren && (o->style()->paddingStart().isPercent() || o->style()->paddingEnd().isPercent()))
    7971119                    o->setPreferredLogicalWidthsDirty(true, false);
    798            
     1120
    7991121                if (o->isPositioned())
    8001122                    o->containingBlock()->insertPositionedObject(box);
     
    8161138        }
    8171139
    818         // We want to skip ahead to the first dirty line
    819         InlineBidiResolver resolver;
    820         unsigned floatIndex;
    821         LineInfo lineInfo;
    822         RootInlineBox* startLine = determineStartPosition(lineInfo, fullLayout, resolver, floats, floatIndex,
    823                                                           useRepaintBounds, repaintLogicalTop, repaintLogicalBottom);
    824 
    825         if (fullLayout && hasInlineChild && !selfNeedsLayout()) {
    826             setNeedsLayout(true, false);  // Mark ourselves as needing a full layout. This way we'll repaint like
    827                                           // we're supposed to.
    828             RenderView* v = view();
    829             if (v && !v->doingFullRepaint() && hasLayer()) {
    830                 // Because we waited until we were already inside layout to discover
    831                 // that the block really needed a full layout, we missed our chance to repaint the layer
    832                 // before layout started.  Luckily the layer has cached the repaint rect for its original
    833                 // position and size, and so we can use that to make a repaint happen now.
    834                 repaintUsingContainer(containerForRepaint(), layer()->repaintRect());
    835             }
    836         }
    837 
    838         FloatingObject* lastFloat = (m_floatingObjects && !m_floatingObjects->set().isEmpty()) ? m_floatingObjects->set().last() : 0;
    839 
    840         LineMidpointState& lineMidpointState = resolver.midpointState();
    841 
    842         // We also find the first clean line and extract these lines.  We will add them back
    843         // if we determine that we're able to synchronize after handling all our dirty lines.
    844         InlineIterator cleanLineStart;
    845         BidiStatus cleanLineBidiStatus;
    846         int endLineLogicalTop = 0;
    847         RootInlineBox* endLine = (fullLayout || !startLine) ?
    848                                  0 : determineEndPosition(startLine, floats, floatIndex, cleanLineStart, cleanLineBidiStatus, endLineLogicalTop);
    849 
    850         if (startLine) {
    851             if (!useRepaintBounds) {
    852                 useRepaintBounds = true;
    853                 repaintLogicalTop = logicalHeight();
    854                 repaintLogicalBottom = logicalHeight();
    855             }
    856             RenderArena* arena = renderArena();
    857             RootInlineBox* box = startLine;
    858             while (box) {
    859                 repaintLogicalTop = min(repaintLogicalTop, box->logicalTopVisualOverflow());
    860                 repaintLogicalBottom = max(repaintLogicalBottom, box->logicalBottomVisualOverflow());
    861                 RootInlineBox* next = box->nextRootBox();
    862                 box->deleteLine(arena);
    863                 box = next;
    864             }
    865         }
    866 
    867         InlineIterator end = resolver.position();
    868 
    869         if (!fullLayout && lastRootBox() && lastRootBox()->endsWithBreak()) {
    870             // If the last line before the start line ends with a line break that clear floats,
    871             // adjust the height accordingly.
    872             // A line break can be either the first or the last object on a line, depending on its direction.
    873             if (InlineBox* lastLeafChild = lastRootBox()->lastLeafChild()) {
    874                 RenderObject* lastObject = lastLeafChild->renderer();
    875                 if (!lastObject->isBR())
    876                     lastObject = lastRootBox()->firstLeafChild()->renderer();
    877                 if (lastObject->isBR()) {
    878                     EClear clear = lastObject->style()->clear();
    879                     if (clear != CNONE)
    880                         newLine(clear);
    881                 }
    882             }
    883         }
    884 
    885         bool endLineMatched = false;
    886         bool checkForEndLineMatch = endLine;
    887         bool checkForFloatsFromLastLine = false;
    888 
    889         bool paginated = view()->layoutState() && view()->layoutState()->isPaginated();
    890 
    891         LineBreakIteratorInfo lineBreakIteratorInfo;
    892         VerticalPositionCache verticalPositionCache;
    893 
    894         while (!end.atEnd()) {
    895             // FIXME: Is this check necessary before the first iteration or can it be moved to the end?
    896             if (checkForEndLineMatch && (endLineMatched = matchedEndLine(resolver, cleanLineStart, cleanLineBidiStatus, endLine, endLineLogicalTop, repaintLogicalBottom, repaintLogicalTop)))
    897                 break;
    898 
    899             lineMidpointState.reset();
    900            
    901             lineInfo.setEmpty(true);
    902            
    903             EClear clear = CNONE;
    904             bool hyphenated;
    905             Vector<RenderBox*> positionedObjects;
    906            
    907             InlineIterator oldEnd = end;
    908             FloatingObject* lastFloatFromPreviousLine = (m_floatingObjects && !m_floatingObjects->set().isEmpty()) ? m_floatingObjects->set().last() : 0;
    909             end = findNextLineBreak(resolver, lineInfo, lineBreakIteratorInfo, hyphenated, &clear, lastFloatFromPreviousLine, positionedObjects);
    910             if (resolver.position().atEnd()) {
    911                 // FIXME: We shouldn't be creating any runs in findNextLineBreak to begin with!
    912                 // Once BidiRunList is separated from BidiResolver this will not be needed.
    913                 resolver.runs().deleteRuns();
    914                 resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed).
    915                 checkForFloatsFromLastLine = true;
    916                 break;
    917             }
    918             ASSERT(end != resolver.position());
    919 
    920             if (lineInfo.isEmpty()) {
    921                 if (lastRootBox())
    922                     lastRootBox()->setLineBreakInfo(end.m_obj, end.m_pos, resolver.status());
    923             } else {
    924                 VisualDirectionOverride override = (style()->visuallyOrdered() ? (style()->direction() == LTR ? VisualLeftToRightOverride : VisualRightToLeftOverride) : NoVisualOverride);
    925                 // FIXME: This ownership is reversed. We should own the BidiRunList and pass it to createBidiRunsForLine.
    926                 BidiRunList<BidiRun>& bidiRuns = resolver.runs();
    927                 resolver.createBidiRunsForLine(end, override, lineInfo.previousLineBrokeCleanly());
    928                 ASSERT(resolver.position() == end);
    929 
    930                 BidiRun* trailingSpaceRun = !lineInfo.previousLineBrokeCleanly() ? handleTrailingSpaces(bidiRuns, resolver.context()) : 0;
    931 
    932                 // Now that the runs have been ordered, we create the line boxes.
    933                 // At the same time we figure out where border/padding/margin should be applied for
    934                 // inline flow boxes.
    935 
    936                 RootInlineBox* lineBox = 0;
    937                 int oldLogicalHeight = logicalHeight();
    938                 if (bidiRuns.runCount()) {
    939                     if (hyphenated)
    940                         bidiRuns.logicallyLastRun()->m_hasHyphen = true;
    941                     lineInfo.setLastLine(!end.m_obj);
    942                     lineBox = constructLine(bidiRuns, lineInfo);
    943                     if (lineBox) {
    944                         lineBox->setEndsWithBreak(lineInfo.previousLineBrokeCleanly());
    945 
    946 #if ENABLE(SVG)
    947                         bool isSVGRootInlineBox = lineBox->isSVGRootInlineBox();
    948 #else
    949                         bool isSVGRootInlineBox = false;
    950 #endif
    951 
    952                         GlyphOverflowAndFallbackFontsMap textBoxDataMap;
    953                    
    954                         // Now we position all of our text runs horizontally.
    955                         if (!isSVGRootInlineBox)
    956                             computeInlineDirectionPositionsForLine(lineBox, lineInfo, bidiRuns.firstRun(), trailingSpaceRun, end.atEnd(), textBoxDataMap, verticalPositionCache);
    957 
    958                         // Now position our text runs vertically.
    959                         computeBlockDirectionPositionsForLine(lineBox, bidiRuns.firstRun(), textBoxDataMap, verticalPositionCache);
    960 
    961 #if ENABLE(SVG)
    962                         // SVG text layout code computes vertical & horizontal positions on its own.
    963                         // Note that we still need to execute computeVerticalPositionsForLine() as
    964                         // it calls InlineTextBox::positionLineBox(), which tracks whether the box
    965                         // contains reversed text or not. If we wouldn't do that editing and thus
    966                         // text selection in RTL boxes would not work as expected.
    967                         if (isSVGRootInlineBox) {
    968                             ASSERT(isSVGText());
    969                             static_cast<SVGRootInlineBox*>(lineBox)->computePerCharacterLayoutInformation();
    970                         }
    971 #endif
    972 
    973                         // Compute our overflow now.
    974                         lineBox->computeOverflow(lineBox->lineTop(), lineBox->lineBottom(), textBoxDataMap);
    975    
    976 #if PLATFORM(MAC)
    977                         // Highlight acts as an overflow inflation.
    978                         if (style()->highlight() != nullAtom)
    979                             lineBox->addHighlightOverflow();
    980 #endif
    981                     }
    982                 }
    983 
    984                 bidiRuns.deleteRuns();
    985                 resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed).
    986 
    987                 if (lineBox) {
    988                     lineBox->setLineBreakInfo(end.m_obj, end.m_pos, resolver.status());
    989                     if (useRepaintBounds) {
    990                         repaintLogicalTop = min(repaintLogicalTop, lineBox->logicalTopVisualOverflow());
    991                         repaintLogicalBottom = max(repaintLogicalBottom, lineBox->logicalBottomVisualOverflow());
    992                     }
    993                    
    994                     if (paginated) {
    995                         int adjustment = 0;
    996                         adjustLinePositionForPagination(lineBox, adjustment);
    997                         if (adjustment) {
    998                             int oldLineWidth = availableLogicalWidthForLine(oldLogicalHeight, lineInfo.isFirstLine());
    999                             lineBox->adjustBlockDirectionPosition(adjustment);
    1000                             if (useRepaintBounds) // This can only be a positive adjustment, so no need to update repaintTop.
    1001                                 repaintLogicalBottom = max(repaintLogicalBottom, lineBox->logicalBottomVisualOverflow());
    1002                                
    1003                             if (availableLogicalWidthForLine(oldLogicalHeight + adjustment, lineInfo.isFirstLine()) != oldLineWidth) {
    1004                                 // We have to delete this line, remove all floats that got added, and let line layout re-run.
    1005                                 lineBox->deleteLine(renderArena());
    1006                                 removeFloatingObjectsBelow(lastFloatFromPreviousLine, oldLogicalHeight);
    1007                                 setLogicalHeight(oldLogicalHeight + adjustment);
    1008                                 resolver.setPosition(oldEnd);
    1009                                 end = oldEnd;
    1010                                 continue;
    1011                             }
    1012 
    1013                             setLogicalHeight(lineBox->blockLogicalHeight());
    1014                         }
    1015                     }
    1016                 }
    1017 
    1018                 for (size_t i = 0; i < positionedObjects.size(); ++i)
    1019                     setStaticPositions(this, positionedObjects[i]);
    1020 
    1021                 lineInfo.setFirstLine(false);
    1022                 newLine(clear);
    1023             }
    1024 
    1025             if (m_floatingObjects && lastRootBox()) {
    1026                 FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
    1027                 FloatingObjectSetIterator it = floatingObjectSet.begin();
    1028                 FloatingObjectSetIterator end = floatingObjectSet.end();
    1029                 if (lastFloat) {
    1030                     FloatingObjectSetIterator lastFloatIterator = floatingObjectSet.find(lastFloat);
    1031                     ASSERT(lastFloatIterator != end);
    1032                     ++lastFloatIterator;
    1033                     it = lastFloatIterator;
    1034                 }
    1035                 for (; it != end; ++it) {
    1036                     FloatingObject* f = *it;
    1037                     appendFloatingObjectToLastLine(f);
    1038                     ASSERT(f->m_renderer == floats[floatIndex].object);
    1039                     // If a float's geometry has changed, give up on syncing with clean lines.
    1040                     if (floats[floatIndex].rect != f->frameRect())
    1041                         checkForEndLineMatch = false;
    1042                     floatIndex++;
    1043                 }
    1044                 lastFloat = !floatingObjectSet.isEmpty() ? floatingObjectSet.last() : 0;
    1045             }
    1046 
    1047             lineMidpointState.reset();
    1048             resolver.setPosition(end);
    1049         }
    1050 
    1051         if (endLine) {
    1052             if (endLineMatched) {
    1053                 // Attach all the remaining lines, and then adjust their y-positions as needed.
    1054                 int delta = logicalHeight() - endLineLogicalTop;
    1055                 for (RootInlineBox* line = endLine; line; line = line->nextRootBox()) {
    1056                     line->attachLine();
    1057                     if (paginated) {
    1058                         delta -= line->paginationStrut();
    1059                         adjustLinePositionForPagination(line, delta);
    1060                     }
    1061                     if (delta) {
    1062                         repaintLogicalTop = min(repaintLogicalTop, line->logicalTopVisualOverflow() + min(delta, 0));
    1063                         repaintLogicalBottom = max(repaintLogicalBottom, line->logicalBottomVisualOverflow() + max(delta, 0));
    1064                         line->adjustBlockDirectionPosition(delta);
    1065                     }
    1066                     if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) {
    1067                         Vector<RenderBox*>::iterator end = cleanLineFloats->end();
    1068                         for (Vector<RenderBox*>::iterator f = cleanLineFloats->begin(); f != end; ++f) {
    1069                             insertFloatingObject(*f);
    1070                             setLogicalHeight(logicalTopForChild(*f) - marginBeforeForChild(*f) + delta);
    1071                             positionNewFloats();
    1072                         }
    1073                     }
    1074                 }
    1075                 setLogicalHeight(lastRootBox()->blockLogicalHeight());
    1076             } else {
    1077                 // Delete all the remaining lines.
    1078                 RootInlineBox* line = endLine;
    1079                 RenderArena* arena = renderArena();
    1080                 while (line) {
    1081                     repaintLogicalTop = min(repaintLogicalTop, line->logicalTopVisualOverflow());
    1082                     repaintLogicalBottom = max(repaintLogicalBottom, line->logicalBottomVisualOverflow());
    1083                     RootInlineBox* next = line->nextRootBox();
    1084                     line->deleteLine(arena);
    1085                     line = next;
    1086                 }
    1087             }
    1088         }
    1089         if (m_floatingObjects && (checkForFloatsFromLastLine || positionNewFloats()) && lastRootBox()) {
    1090             // In case we have a float on the last line, it might not be positioned up to now.
    1091             // This has to be done before adding in the bottom border/padding, or the float will
    1092             // include the padding incorrectly. -dwh
    1093             if (checkForFloatsFromLastLine) {
    1094                 int bottomVisualOverflow = lastRootBox()->logicalBottomVisualOverflow();
    1095                 int bottomLayoutOverflow = lastRootBox()->logicalBottomLayoutOverflow();
    1096                 TrailingFloatsRootInlineBox* trailingFloatsLineBox = new (renderArena()) TrailingFloatsRootInlineBox(this);
    1097                 m_lineBoxes.appendLineBox(trailingFloatsLineBox);
    1098                 trailingFloatsLineBox->setConstructed();
    1099                 GlyphOverflowAndFallbackFontsMap textBoxDataMap;
    1100                 VerticalPositionCache verticalPositionCache;
    1101                 trailingFloatsLineBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, verticalPositionCache);
    1102                 int blockLogicalHeight = logicalHeight();
    1103                 IntRect logicalLayoutOverflow(0, blockLogicalHeight, 1, bottomLayoutOverflow - blockLogicalHeight);
    1104                 IntRect logicalVisualOverflow(0, blockLogicalHeight, 1, bottomVisualOverflow - blockLogicalHeight);
    1105                 trailingFloatsLineBox->setOverflowFromLogicalRects(logicalLayoutOverflow, logicalVisualOverflow, trailingFloatsLineBox->lineTop(), trailingFloatsLineBox->lineBottom());
    1106                 trailingFloatsLineBox->setBlockLogicalHeight(logicalHeight());
    1107             }
    1108 
    1109             FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
    1110             FloatingObjectSetIterator it = floatingObjectSet.begin();
    1111             FloatingObjectSetIterator end = floatingObjectSet.end();
    1112             if (lastFloat) {
    1113                 FloatingObjectSetIterator lastFloatIterator = floatingObjectSet.find(lastFloat);
    1114                 ASSERT(lastFloatIterator != end);
    1115                 ++lastFloatIterator;
    1116                 it = lastFloatIterator;
    1117             }
    1118             for (; it != end; ++it)
    1119                 appendFloatingObjectToLastLine(*it);
    1120             lastFloat = !floatingObjectSet.isEmpty() ? floatingObjectSet.last() : 0;
    1121         }
    1122         size_t floatCount = floats.size();
    1123         // Floats that did not have layout did not repaint when we laid them out. They would have
    1124         // painted by now if they had moved, but if they stayed at (0, 0), they still need to be
    1125         // painted.
    1126         for (size_t i = 0; i < floatCount; ++i) {
    1127             if (!floats[i].everHadLayout) {
    1128                 RenderBox* f = floats[i].object;
    1129                 if (!f->x() && !f->y() && f->checkForRepaintDuringLayout())
    1130                     f->repaint();
    1131             }
    1132         }
     1140        layoutRunsAndFloats(fullLayout, hasInlineChild, floats, repaintLogicalTop, repaintLogicalBottom);
    11331141    }
    11341142
     
    11731181        if (floats[floatIndex].rect.size() != newSize) {
    11741182            int floatTop = isHorizontalWritingMode() ? floats[floatIndex].rect.y() : floats[floatIndex].rect.x();
    1175             int floatHeight = isHorizontalWritingMode() ? max(floats[floatIndex].rect.height(), newSize.height()) 
     1183            int floatHeight = isHorizontalWritingMode() ? max(floats[floatIndex].rect.height(), newSize.height())
    11761184                                                                 : max(floats[floatIndex].rect.width(), newSize.width());
    11771185            floatHeight = min(floatHeight, numeric_limits<int>::max() - floatTop);
     
    12041212                    if (containsFloats() || !floats.isEmpty()) {
    12051213                        // FIXME: Do better eventually.  For now if we ever shift because of pagination and floats are present just go to a full layout.
    1206                         fullLayout = true; 
     1214                        fullLayout = true;
    12071215                        break;
    12081216                    }
    1209                    
     1217
    12101218                    if (!useRepaintBounds)
    12111219                        useRepaintBounds = true;
    1212                        
     1220
    12131221                    repaintLogicalTop = min(repaintLogicalTop, curr->logicalTopVisualOverflow() + min(paginationDelta, 0));
    12141222                    repaintLogicalBottom = max(repaintLogicalBottom, curr->logicalBottomVisualOverflow() + max(paginationDelta, 0));
    12151223                    curr->adjustBlockDirectionPosition(paginationDelta);
    1216                 }               
     1224                }
    12171225            }
    12181226
     
    12311239        if (firstRootBox()) {
    12321240            RenderArena* arena = renderArena();
    1233             curr = firstRootBox(); 
     1241            curr = firstRootBox();
    12341242            while (curr) {
    12351243                RootInlineBox* next = curr->nextRootBox();
     
    14401448    // FIXME: Right now, we only allow line boxes for inlines that are truly empty.
    14411449    // We need to fix this, though, because at the very least, inlines containing only
    1442     // ignorable whitespace should should also have line boxes. 
     1450    // ignorable whitespace should should also have line boxes.
    14431451    return !flow->firstChild() && flow->hasInlineDirectionBordersPaddingOrMargin();
    14441452}
     
    14561464
    14571465    UChar current = it.current();
    1458     return current != ' ' && current != '\t' && current != softHyphen && (current != '\n' || it.m_obj->preservesNewline()) 
     1466    return current != ' ' && current != '\t' && current != softHyphen && (current != '\n' || it.m_obj->preservesNewline())
    14591467    && !skipNonBreakingSpace(it, lineInfo);
    14601468}
     
    15031511}
    15041512
    1505 // This is currently just used for list markers and inline flows that have line boxes. Neither should 
    1506 // have an effect on whitespace at the start of the line. 
     1513// This is currently just used for list markers and inline flows that have line boxes. Neither should
     1514// have an effect on whitespace at the start of the line.
    15071515static bool shouldSkipWhitespaceAfterStartObject(RenderBlock* block, RenderObject* o, LineMidpointState& lineMidpointState)
    15081516{
     
    17361744        lineMidpointState.midpoints[trailingSpaceMidpoint].m_pos--;
    17371745
    1738         // Now make sure every single trailingPositionedBox following the trailingSpaceMidpoint properly stops and starts 
     1746        // Now make sure every single trailingPositionedBox following the trailingSpaceMidpoint properly stops and starts
    17391747        // ignoring spaces.
    17401748        size_t currentMidpoint = trailingSpaceMidpoint + 1;
     
    17661774}
    17671775
    1768 InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, LineInfo& lineInfo, LineBreakIteratorInfo& lineBreakIteratorInfo, 
     1776InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, LineInfo& lineInfo, LineBreakIteratorInfo& lineBreakIteratorInfo,
    17691777                                              bool& hyphenated, EClear* clear, FloatingObject* lastFloatFromPreviousLine, Vector<RenderBox*>& positionedBoxes)
    17701778{
     
    17851793    bool ignoringSpaces = false;
    17861794    InlineIterator ignoreStart;
    1787    
     1795
    17881796    // This variable tracks whether the very last character we saw was a space.  We use
    17891797    // this to detect when we encounter a second space so we know we have to terminate
     
    18101818    bool autoWrapWasEverTrueOnLine = false;
    18111819    bool floatsFitOnLine = true;
    1812    
     1820
    18131821    // Firefox and Opera will allow a table cell to grow to fit an image inside it under
    1814     // very specific circumstances (in order to match common WinIE renderings). 
    1815     // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.) 
     1822    // very specific circumstances (in order to match common WinIE renderings).
     1823    // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
    18161824    bool allowImagesToBreak = !document()->inQuirksMode() || !isTableCell() || !style()->logicalWidth().isIntrinsicOrAuto();
    18171825
     
    18231831        currWS = o->isReplaced() ? o->parent()->style()->whiteSpace() : o->style()->whiteSpace();
    18241832        lastWS = last->isReplaced() ? last->parent()->style()->whiteSpace() : last->style()->whiteSpace();
    1825        
     1833
    18261834        bool autoWrap = RenderStyle::autoWrap(currWS);
    18271835        autoWrapWasEverTrueOnLine = autoWrapWasEverTrueOnLine || autoWrap;
     
    18341842
    18351843        bool collapseWhiteSpace = RenderStyle::collapseWhiteSpace(currWS);
    1836            
     1844
    18371845        if (o->isBR()) {
    18381846            if (width.fitsOnLine()) {
     
    18841892                    box->layer()->setStaticBlockPosition(logicalHeight());
    18851893                }
    1886                
     1894
    18871895                // If we're ignoring spaces, we have to stop and include this object and
    18881896                // then start ignoring spaces again.
     
    19011909            // Right now, we should only encounter empty inlines here.
    19021910            ASSERT(!o->firstChild());
    1903    
     1911
    19041912            RenderInline* flowBox = toRenderInline(o);
    1905            
    1906             // Now that some inline flows have line boxes, if we are already ignoring spaces, we need 
    1907             // to make sure that we stop to include this object and then start ignoring spaces again. 
    1908             // If this object is at the start of the line, we need to behave like list markers and 
     1913
     1914            // Now that some inline flows have line boxes, if we are already ignoring spaces, we need
     1915            // to make sure that we stop to include this object and then start ignoring spaces again.
     1916            // If this object is at the start of the line, we need to behave like list markers and
    19091917            // start ignoring spaces.
    19101918            if (inlineFlowRequiresLineBox(flowBox)) {
     
    19161924                } else if (style()->collapseWhiteSpace() && resolver.position().m_obj == o
    19171925                    && shouldSkipWhitespaceAfterStartObject(this, o, lineMidpointState)) {
    1918                     // Like with list markers, we start ignoring spaces to make sure that any 
     1926                    // Like with list markers, we start ignoring spaces to make sure that any
    19191927                    // additional spaces we see will be discarded.
    19201928                    currentCharacterIsSpace = true;
     
    19481956            if (o->isListMarker()) {
    19491957                if (style()->collapseWhiteSpace() && shouldSkipWhitespaceAfterStartObject(this, o, lineMidpointState)) {
    1950                     // Like with inline flows, we start ignoring spaces to make sure that any 
     1958                    // Like with inline flows, we start ignoring spaces to make sure that any
    19511959                    // additional spaces we see will be discarded.
    19521960                    currentCharacterIsSpace = true;
     
    20222030
    20232031                bool applyWordSpacing = false;
    2024                
     2032
    20252033                currentCharacterIsWS = currentCharacterIsSpace || (breakNBSP && c == noBreakSpace);
    20262034
     
    20672075                        appliedStartWidth = true;
    20682076                    }
    2069                    
     2077
    20702078                    applyWordSpacing =  wordSpacing && currentCharacterIsSpace && !previousCharacterIsSpace;
    20712079
     
    20802088                            float charWidth = textWidth(t, pos, 1, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace) + (applyWordSpacing ? wordSpacing : 0);
    20812089                            // Check if line is too big even without the extra space
    2082                             // at the end of the line. If it is not, do nothing. 
    2083                             // If the line needs the extra whitespace to be too long, 
    2084                             // then move the line break to the space and skip all 
     2090                            // at the end of the line. If it is not, do nothing.
     2091                            // If the line needs the extra whitespace to be too long,
     2092                            // then move the line break to the space and skip all
    20852093                            // additional whitespace.
    20862094                            if (!width.fitsOnLine(charWidth)) {
     
    21392147                        breakWords = false;
    21402148                    }
    2141                    
     2149
    21422150                    if (midWordBreak) {
    21432151                        // Remember this as a breakable position in case
     
    21512159                        lastSpace = pos;
    21522160                    }
    2153                    
     2161
    21542162                    if (!ignoringSpaces && o->style()->collapseWhiteSpace()) {
    21552163                        // If we encounter a newline, or if we encounter a
     
    21582166                        if (currentCharacterIsSpace && previousCharacterIsSpace) {
    21592167                            ignoringSpaces = true;
    2160                            
     2168
    21612169                            // We just entered a mode where we are ignoring
    21622170                            // spaces. Create a midpoint to terminate the run
    2163                             // before the second space. 
     2171                            // before the second space.
    21642172                            addMidpoint(lineMidpointState, ignoreStart);
    21652173                        }
     
    21932201                        lBreak.moveTo(o, pos, nextBreakable);
    21942202                }
    2195                
     2203
    21962204                if (collapseWhiteSpace && currentCharacterIsSpace && !ignoringSpaces)
    21972205                    trailingObjects.setTrailingWhitespace(static_cast<RenderText*>(o));
     
    22852293        if (!collapseWhiteSpace)
    22862294            currentCharacterIsSpace = false;
    2287        
     2295
    22882296        pos = 0;
    22892297        atStart = false;
    22902298    }
    2291    
     2299
    22922300    if (width.fitsOnLine() || lastWS == NOWRAP)
    22932301        lBreak.clear();
Note: See TracChangeset for help on using the changeset viewer.