Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright (C) 2000 Lars Knoll (knoll (at) kde.org)
      3  * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All right reserved.
      4  * Copyright (C) 2010 Google Inc. All rights reserved.
      5  *
      6  * This library is free software; you can redistribute it and/or
      7  * modify it under the terms of the GNU Library General Public
      8  * License as published by the Free Software Foundation; either
      9  * version 2 of the License, or (at your option) any later version.
     10  *
     11  * This library is distributed in the hope that it will be useful,
     12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14  * Library General Public License for more details.
     15  *
     16  * You should have received a copy of the GNU Library General Public License
     17  * along with this library; see the file COPYING.LIB.  If not, write to
     18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     19  * Boston, MA 02110-1301, USA.
     20  *
     21  */
     22 
     23 #include "config.h"
     24 
     25 #include "core/accessibility/AXObjectCache.h"
     26 #include "core/rendering/RenderCounter.h"
     27 #include "core/rendering/RenderFlowThread.h"
     28 #include "core/rendering/RenderLayer.h"
     29 #include "core/rendering/RenderListMarker.h"
     30 #include "core/rendering/RenderRegion.h"
     31 #include "core/rendering/RenderRubyRun.h"
     32 #include "core/rendering/RenderView.h"
     33 #include "core/rendering/TrailingFloatsRootInlineBox.h"
     34 #include "core/rendering/VerticalPositionCache.h"
     35 #include "core/rendering/line/BreakingContextInlineHeaders.h"
     36 #include "core/rendering/line/LineLayoutState.h"
     37 #include "core/rendering/line/LineWidth.h"
     38 #include "core/rendering/line/RenderTextInfo.h"
     39 #include "core/rendering/line/WordMeasurement.h"
     40 #include "core/rendering/svg/SVGRootInlineBox.h"
     41 #include "platform/fonts/Character.h"
     42 #include "platform/text/BidiResolver.h"
     43 #include "wtf/RefCountedLeakCounter.h"
     44 #include "wtf/StdLibExtras.h"
     45 #include "wtf/Vector.h"
     46 #include "wtf/unicode/CharacterNames.h"
     47 
     48 namespace WebCore {
     49 
     50 using namespace std;
     51 using namespace WTF::Unicode;
     52 
     53 static RenderObject* firstRenderObjectForDirectionalityDetermination(RenderObject* root, RenderObject* current = 0)
     54 {
     55     RenderObject* next = current;
     56     while (current) {
     57         if (isIsolated(current->style()->unicodeBidi())
     58             && (current->isRenderInline() || current->isRenderBlock())) {
     59             if (current != root)
     60                 current = 0;
     61             else
     62                 current = next;
     63             break;
     64         }
     65         current = current->parent();
     66     }
     67 
     68     if (!current)
     69         current = root->slowFirstChild();
     70 
     71     while (current) {
     72         next = 0;
     73         if (isIteratorTarget(current) && !(current->isText() && toRenderText(current)->isAllCollapsibleWhitespace()))
     74             break;
     75 
     76         if (!isIteratorTarget(current) && !isIsolated(current->style()->unicodeBidi()))
     77             next = current->slowFirstChild();
     78 
     79         if (!next) {
     80             while (current && current != root) {
     81                 next = current->nextSibling();
     82                 if (next)
     83                     break;
     84                 current = current->parent();
     85             }
     86         }
     87 
     88         if (!next)
     89             break;
     90 
     91         current = next;
     92     }
     93 
     94     return current;
     95 }
     96 
     97 static TextDirection determinePlaintextDirectionality(RenderObject* root, RenderObject* current = 0, unsigned pos = 0)
     98 {
     99     InlineIterator iter(root, firstRenderObjectForDirectionalityDetermination(root, current), pos);
    100     InlineBidiResolver observer;
    101     observer.setStatus(BidiStatus(root->style()->direction(), isOverride(root->style()->unicodeBidi())));
    102     observer.setPositionIgnoringNestedIsolates(iter);
    103     return observer.determineParagraphDirectionality();
    104 }
    105 
    106 static inline InlineBox* createInlineBoxForRenderer(RenderObject* obj, bool isRootLineBox, bool isOnlyRun = false)
    107 {
    108     if (isRootLineBox)
    109         return toRenderBlockFlow(obj)->createAndAppendRootInlineBox();
    110 
    111     if (obj->isText()) {
    112         InlineTextBox* textBox = toRenderText(obj)->createInlineTextBox();
    113         // We only treat a box as text for a <br> if we are on a line by ourself or in strict mode
    114         // (Note the use of strict mode.  In "almost strict" mode, we don't treat the box for <br> as text.)
    115         if (obj->isBR())
    116             textBox->setIsText(isOnlyRun || obj->document().inNoQuirksMode());
    117         return textBox;
    118     }
    119 
    120     if (obj->isBox())
    121         return toRenderBox(obj)->createInlineBox();
    122 
    123     return toRenderInline(obj)->createAndAppendInlineFlowBox();
    124 }
    125 
    126 static inline void dirtyLineBoxesForRenderer(RenderObject* o, bool fullLayout)
    127 {
    128     if (o->isText()) {
    129         RenderText* renderText = toRenderText(o);
    130         renderText->dirtyLineBoxes(fullLayout);
    131     } else
    132         toRenderInline(o)->dirtyLineBoxes(fullLayout);
    133 }
    134 
    135 static bool parentIsConstructedOrHaveNext(InlineFlowBox* parentBox)
    136 {
    137     do {
    138         if (parentBox->isConstructed() || parentBox->nextOnLine())
    139             return true;
    140         parentBox = parentBox->parent();
    141     } while (parentBox);
    142     return false;
    143 }
    144 
    145 InlineFlowBox* RenderBlockFlow::createLineBoxes(RenderObject* obj, const LineInfo& lineInfo, InlineBox* childBox)
    146 {
    147     // See if we have an unconstructed line box for this object that is also
    148     // the last item on the line.
    149     unsigned lineDepth = 1;
    150     InlineFlowBox* parentBox = 0;
    151     InlineFlowBox* result = 0;
    152     bool hasDefaultLineBoxContain = style()->lineBoxContain() == RenderStyle::initialLineBoxContain();
    153     do {
    154         ASSERT_WITH_SECURITY_IMPLICATION(obj->isRenderInline() || obj == this);
    155 
    156         RenderInline* inlineFlow = (obj != this) ? toRenderInline(obj) : 0;
    157 
    158         // Get the last box we made for this render object.
    159         parentBox = inlineFlow ? inlineFlow->lastLineBox() : toRenderBlock(obj)->lastLineBox();
    160 
    161         // If this box or its ancestor is constructed then it is from a previous line, and we need
    162         // to make a new box for our line.  If this box or its ancestor is unconstructed but it has
    163         // something following it on the line, then we know we have to make a new box
    164         // as well.  In this situation our inline has actually been split in two on
    165         // the same line (this can happen with very fancy language mixtures).
    166         bool constructedNewBox = false;
    167         bool allowedToConstructNewBox = !hasDefaultLineBoxContain || !inlineFlow || inlineFlow->alwaysCreateLineBoxes();
    168         bool canUseExistingParentBox = parentBox && !parentIsConstructedOrHaveNext(parentBox);
    169         if (allowedToConstructNewBox && !canUseExistingParentBox) {
    170             // We need to make a new box for this render object.  Once
    171             // made, we need to place it at the end of the current line.
    172             InlineBox* newBox = createInlineBoxForRenderer(obj, obj == this);
    173             ASSERT_WITH_SECURITY_IMPLICATION(newBox->isInlineFlowBox());
    174             parentBox = toInlineFlowBox(newBox);
    175             parentBox->setFirstLineStyleBit(lineInfo.isFirstLine());
    176             parentBox->setIsHorizontal(isHorizontalWritingMode());
    177             if (!hasDefaultLineBoxContain)
    178                 parentBox->clearDescendantsHaveSameLineHeightAndBaseline();
    179             constructedNewBox = true;
    180         }
    181 
    182         if (constructedNewBox || canUseExistingParentBox) {
    183             if (!result)
    184                 result = parentBox;
    185 
    186             // If we have hit the block itself, then |box| represents the root
    187             // inline box for the line, and it doesn't have to be appended to any parent
    188             // inline.
    189             if (childBox)
    190                 parentBox->addToLine(childBox);
    191 
    192             if (!constructedNewBox || obj == this)
    193                 break;
    194 
    195             childBox = parentBox;
    196         }
    197 
    198         // If we've exceeded our line depth, then jump straight to the root and skip all the remaining
    199         // intermediate inline flows.
    200         obj = (++lineDepth >= cMaxLineDepth) ? this : obj->parent();
    201 
    202     } while (true);
    203 
    204     return result;
    205 }
    206 
    207 template <typename CharacterType>
    208 static inline bool endsWithASCIISpaces(const CharacterType* characters, unsigned pos, unsigned end)
    209 {
    210     while (isASCIISpace(characters[pos])) {
    211         pos++;
    212         if (pos >= end)
    213             return true;
    214     }
    215     return false;
    216 }
    217 
    218 static bool reachedEndOfTextRenderer(const BidiRunList<BidiRun>& bidiRuns)
    219 {
    220     BidiRun* run = bidiRuns.logicallyLastRun();
    221     if (!run)
    222         return true;
    223     unsigned pos = run->stop();
    224     RenderObject* r = run->m_object;
    225     if (!r->isText() || r->isBR())
    226         return false;
    227     RenderText* renderText = toRenderText(r);
    228     unsigned length = renderText->textLength();
    229     if (pos >= length)
    230         return true;
    231 
    232     if (renderText->is8Bit())
    233         return endsWithASCIISpaces(renderText->characters8(), pos, length);
    234     return endsWithASCIISpaces(renderText->characters16(), pos, length);
    235 }
    236 
    237 RootInlineBox* RenderBlockFlow::constructLine(BidiRunList<BidiRun>& bidiRuns, const LineInfo& lineInfo)
    238 {
    239     ASSERT(bidiRuns.firstRun());
    240 
    241     bool rootHasSelectedChildren = false;
    242     InlineFlowBox* parentBox = 0;
    243     int runCount = bidiRuns.runCount() - lineInfo.runsFromLeadingWhitespace();
    244     for (BidiRun* r = bidiRuns.firstRun(); r; r = r->next()) {
    245         // Create a box for our object.
    246         bool isOnlyRun = (runCount == 1);
    247         if (runCount == 2 && !r->m_object->isListMarker())
    248             isOnlyRun = (!style()->isLeftToRightDirection() ? bidiRuns.lastRun() : bidiRuns.firstRun())->m_object->isListMarker();
    249 
    250         if (lineInfo.isEmpty())
    251             continue;
    252 
    253         InlineBox* box = createInlineBoxForRenderer(r->m_object, false, isOnlyRun);
    254         r->m_box = box;
    255 
    256         ASSERT(box);
    257         if (!box)
    258             continue;
    259 
    260         if (!rootHasSelectedChildren && box->renderer().selectionState() != RenderObject::SelectionNone)
    261             rootHasSelectedChildren = true;
    262 
    263         // If we have no parent box yet, or if the run is not simply a sibling,
    264         // then we need to construct inline boxes as necessary to properly enclose the
    265         // run's inline box. Segments can only be siblings at the root level, as
    266         // they are positioned separately.
    267         if (!parentBox || parentBox->renderer() != r->m_object->parent()) {
    268             // Create new inline boxes all the way back to the appropriate insertion point.
    269             parentBox = createLineBoxes(r->m_object->parent(), lineInfo, box);
    270         } else {
    271             // Append the inline box to this line.
    272             parentBox->addToLine(box);
    273         }
    274 
    275         bool visuallyOrdered = r->m_object->style()->rtlOrdering() == VisualOrder;
    276         box->setBidiLevel(r->level());
    277 
    278         if (box->isInlineTextBox()) {
    279             InlineTextBox* text = toInlineTextBox(box);
    280             text->setStart(r->m_start);
    281             text->setLen(r->m_stop - r->m_start);
    282             text->setDirOverride(r->dirOverride(visuallyOrdered));
    283             if (r->m_hasHyphen)
    284                 text->setHasHyphen(true);
    285 
    286             if (AXObjectCache* cache = document().existingAXObjectCache())
    287                 cache->inlineTextBoxesUpdated(r->m_object);
    288         }
    289     }
    290 
    291     // We should have a root inline box.  It should be unconstructed and
    292     // be the last continuation of our line list.
    293     ASSERT(lastLineBox() && !lastLineBox()->isConstructed());
    294 
    295     // Set the m_selectedChildren flag on the root inline box if one of the leaf inline box
    296     // from the bidi runs walk above has a selection state.
    297     if (rootHasSelectedChildren)
    298         lastLineBox()->root().setHasSelectedChildren(true);
    299 
    300     // Set bits on our inline flow boxes that indicate which sides should
    301     // paint borders/margins/padding.  This knowledge will ultimately be used when
    302     // we determine the horizontal positions and widths of all the inline boxes on
    303     // the line.
    304     bool isLogicallyLastRunWrapped = bidiRuns.logicallyLastRun()->m_object && bidiRuns.logicallyLastRun()->m_object->isText() ? !reachedEndOfTextRenderer(bidiRuns) : true;
    305     lastLineBox()->determineSpacingForFlowBoxes(lineInfo.isLastLine(), isLogicallyLastRunWrapped, bidiRuns.logicallyLastRun()->m_object);
    306 
    307     // Now mark the line boxes as being constructed.
    308     lastLineBox()->setConstructed();
    309 
    310     // Return the last line.
    311     return lastRootBox();
    312 }
    313 
    314 ETextAlign RenderBlockFlow::textAlignmentForLine(bool endsWithSoftBreak) const
    315 {
    316     ETextAlign alignment = style()->textAlign();
    317     if (endsWithSoftBreak)
    318         return alignment;
    319 
    320     if (!RuntimeEnabledFeatures::css3TextEnabled())
    321         return (alignment == JUSTIFY) ? TASTART : alignment;
    322 
    323     TextAlignLast alignmentLast = style()->textAlignLast();
    324     switch (alignmentLast) {
    325     case TextAlignLastStart:
    326         return TASTART;
    327     case TextAlignLastEnd:
    328         return TAEND;
    329     case TextAlignLastLeft:
    330         return LEFT;
    331     case TextAlignLastRight:
    332         return RIGHT;
    333     case TextAlignLastCenter:
    334         return CENTER;
    335     case TextAlignLastJustify:
    336         return JUSTIFY;
    337     case TextAlignLastAuto:
    338         if (alignment != JUSTIFY)
    339             return alignment;
    340         if (style()->textJustify() == TextJustifyDistribute)
    341             return JUSTIFY;
    342         return TASTART;
    343     }
    344 
    345     return alignment;
    346 }
    347 
    348 static void updateLogicalWidthForLeftAlignedBlock(bool isLeftToRightDirection, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float availableLogicalWidth)
    349 {
    350     // The direction of the block should determine what happens with wide lines.
    351     // In particular with RTL blocks, wide lines should still spill out to the left.
    352     if (isLeftToRightDirection) {
    353         if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun)
    354             trailingSpaceRun->m_box->setLogicalWidth(max<float>(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
    355         return;
    356     }
    357 
    358     if (trailingSpaceRun)
    359         trailingSpaceRun->m_box->setLogicalWidth(0);
    360     else if (totalLogicalWidth > availableLogicalWidth)
    361         logicalLeft -= (totalLogicalWidth - availableLogicalWidth);
    362 }
    363 
    364 static void updateLogicalWidthForRightAlignedBlock(bool isLeftToRightDirection, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float availableLogicalWidth)
    365 {
    366     // Wide lines spill out of the block based off direction.
    367     // So even if text-align is right, if direction is LTR, wide lines should overflow out of the right
    368     // side of the block.
    369     if (isLeftToRightDirection) {
    370         if (trailingSpaceRun) {
    371             totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
    372             trailingSpaceRun->m_box->setLogicalWidth(0);
    373         }
    374         if (totalLogicalWidth < availableLogicalWidth)
    375             logicalLeft += availableLogicalWidth - totalLogicalWidth;
    376         return;
    377     }
    378 
    379     if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun) {
    380         trailingSpaceRun->m_box->setLogicalWidth(max<float>(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
    381         totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
    382     } else
    383         logicalLeft += availableLogicalWidth - totalLogicalWidth;
    384 }
    385 
    386 static void updateLogicalWidthForCenterAlignedBlock(bool isLeftToRightDirection, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float availableLogicalWidth)
    387 {
    388     float trailingSpaceWidth = 0;
    389     if (trailingSpaceRun) {
    390         totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
    391         trailingSpaceWidth = min(trailingSpaceRun->m_box->logicalWidth(), (availableLogicalWidth - totalLogicalWidth + 1) / 2);
    392         trailingSpaceRun->m_box->setLogicalWidth(max<float>(0, trailingSpaceWidth));
    393     }
    394     if (isLeftToRightDirection)
    395         logicalLeft += max<float>((availableLogicalWidth - totalLogicalWidth) / 2, 0);
    396     else
    397         logicalLeft += totalLogicalWidth > availableLogicalWidth ? (availableLogicalWidth - totalLogicalWidth) : (availableLogicalWidth - totalLogicalWidth) / 2 - trailingSpaceWidth;
    398 }
    399 
    400 void RenderBlockFlow::setMarginsForRubyRun(BidiRun* run, RenderRubyRun* renderer, RenderObject* previousObject, const LineInfo& lineInfo)
    401 {
    402     int startOverhang;
    403     int endOverhang;
    404     RenderObject* nextObject = 0;
    405     for (BidiRun* runWithNextObject = run->next(); runWithNextObject; runWithNextObject = runWithNextObject->next()) {
    406         if (!runWithNextObject->m_object->isOutOfFlowPositioned() && !runWithNextObject->m_box->isLineBreak()) {
    407             nextObject = runWithNextObject->m_object;
    408             break;
    409         }
    410     }
    411     renderer->getOverhang(lineInfo.isFirstLine(), renderer->style()->isLeftToRightDirection() ? previousObject : nextObject, renderer->style()->isLeftToRightDirection() ? nextObject : previousObject, startOverhang, endOverhang);
    412     setMarginStartForChild(renderer, -startOverhang);
    413     setMarginEndForChild(renderer, -endOverhang);
    414 }
    415 
    416 static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* run, RenderText* renderer, float xPos, const LineInfo& lineInfo,
    417                                              GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache, WordMeasurements& wordMeasurements)
    418 {
    419     HashSet<const SimpleFontData*> fallbackFonts;
    420     GlyphOverflow glyphOverflow;
    421 
    422     const Font& font = renderer->style(lineInfo.isFirstLine())->font();
    423     // Always compute glyph overflow if the block's line-box-contain value is "glyphs".
    424     if (lineBox->fitsToGlyphs()) {
    425         // If we don't stick out of the root line's font box, then don't bother computing our glyph overflow. This optimization
    426         // will keep us from computing glyph bounds in nearly all cases.
    427         bool includeRootLine = lineBox->includesRootLineBoxFontOrLeading();
    428         int baselineShift = lineBox->verticalPositionForBox(run->m_box, verticalPositionCache);
    429         int rootDescent = includeRootLine ? font.fontMetrics().descent() : 0;
    430         int rootAscent = includeRootLine ? font.fontMetrics().ascent() : 0;
    431         int boxAscent = font.fontMetrics().ascent() - baselineShift;
    432         int boxDescent = font.fontMetrics().descent() + baselineShift;
    433         if (boxAscent > rootDescent ||  boxDescent > rootAscent)
    434             glyphOverflow.computeBounds = true;
    435     }
    436 
    437     LayoutUnit hyphenWidth = 0;
    438     if (toInlineTextBox(run->m_box)->hasHyphen()) {
    439         const Font& font = renderer->style(lineInfo.isFirstLine())->font();
    440         hyphenWidth = measureHyphenWidth(renderer, font, run->direction());
    441     }
    442     float measuredWidth = 0;
    443 
    444     bool kerningIsEnabled = font.fontDescription().typesettingFeatures() & Kerning;
    445 
    446 #if OS(MACOSX)
    447     // FIXME: Having any font feature settings enabled can lead to selection gaps on
    448     // Chromium-mac. https://bugs.webkit.org/show_bug.cgi?id=113418
    449     bool canUseSimpleFontCodePath = renderer->canUseSimpleFontCodePath() && !font.fontDescription().featureSettings();
    450 #else
    451     bool canUseSimpleFontCodePath = renderer->canUseSimpleFontCodePath();
    452 #endif
    453 
    454     // Since we don't cache glyph overflows, we need to re-measure the run if
    455     // the style is linebox-contain: glyph.
    456 
    457     if (!lineBox->fitsToGlyphs() && canUseSimpleFontCodePath) {
    458         int lastEndOffset = run->m_start;
    459         for (size_t i = 0, size = wordMeasurements.size(); i < size && lastEndOffset < run->m_stop; ++i) {
    460             const WordMeasurement& wordMeasurement = wordMeasurements[i];
    461             if (wordMeasurement.width <=0 || wordMeasurement.startOffset == wordMeasurement.endOffset)
    462                 continue;
    463             if (wordMeasurement.renderer != renderer || wordMeasurement.startOffset != lastEndOffset || wordMeasurement.endOffset > run->m_stop)
    464                 continue;
    465 
    466             lastEndOffset = wordMeasurement.endOffset;
    467             if (kerningIsEnabled && lastEndOffset == run->m_stop) {
    468                 int wordLength = lastEndOffset - wordMeasurement.startOffset;
    469                 measuredWidth += renderer->width(wordMeasurement.startOffset, wordLength, xPos, run->direction(), lineInfo.isFirstLine());
    470                 if (i > 0 && wordLength == 1 && renderer->characterAt(wordMeasurement.startOffset) == ' ')
    471                     measuredWidth += renderer->style()->wordSpacing();
    472             } else
    473                 measuredWidth += wordMeasurement.width;
    474             if (!wordMeasurement.fallbackFonts.isEmpty()) {
    475                 HashSet<const SimpleFontData*>::const_iterator end = wordMeasurement.fallbackFonts.end();
    476                 for (HashSet<const SimpleFontData*>::const_iterator it = wordMeasurement.fallbackFonts.begin(); it != end; ++it)
    477                     fallbackFonts.add(*it);
    478             }
    479         }
    480         if (measuredWidth && lastEndOffset != run->m_stop) {
    481             // If we don't have enough cached data, we'll measure the run again.
    482             measuredWidth = 0;
    483             fallbackFonts.clear();
    484         }
    485     }
    486 
    487     if (!measuredWidth)
    488         measuredWidth = renderer->width(run->m_start, run->m_stop - run->m_start, xPos, run->direction(), lineInfo.isFirstLine(), &fallbackFonts, &glyphOverflow);
    489 
    490     run->m_box->setLogicalWidth(measuredWidth + hyphenWidth);
    491     if (!fallbackFonts.isEmpty()) {
    492         ASSERT(run->m_box->isText());
    493         GlyphOverflowAndFallbackFontsMap::ValueType* it = textBoxDataMap.add(toInlineTextBox(run->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).storedValue;
    494         ASSERT(it->value.first.isEmpty());
    495         copyToVector(fallbackFonts, it->value.first);
    496         run->m_box->parent()->clearDescendantsHaveSameLineHeightAndBaseline();
    497     }
    498     if ((glyphOverflow.top || glyphOverflow.bottom || glyphOverflow.left || glyphOverflow.right)) {
    499         ASSERT(run->m_box->isText());
    500         GlyphOverflowAndFallbackFontsMap::ValueType* it = textBoxDataMap.add(toInlineTextBox(run->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).storedValue;
    501         it->value.second = glyphOverflow;
    502         run->m_box->clearKnownToHaveNoOverflow();
    503     }
    504 }
    505 
    506 static inline void computeExpansionForJustifiedText(BidiRun* firstRun, BidiRun* trailingSpaceRun, Vector<unsigned, 16>& expansionOpportunities, unsigned expansionOpportunityCount, float& totalLogicalWidth, float availableLogicalWidth)
    507 {
    508     if (!expansionOpportunityCount || availableLogicalWidth <= totalLogicalWidth)
    509         return;
    510 
    511     size_t i = 0;
    512     for (BidiRun* r = firstRun; r; r = r->next()) {
    513         if (!r->m_box || r == trailingSpaceRun)
    514             continue;
    515 
    516         if (r->m_object->isText()) {
    517             unsigned opportunitiesInRun = expansionOpportunities[i++];
    518 
    519             ASSERT(opportunitiesInRun <= expansionOpportunityCount);
    520 
    521             // Don't justify for white-space: pre.
    522             if (r->m_object->style()->whiteSpace() != PRE) {
    523                 InlineTextBox* textBox = toInlineTextBox(r->m_box);
    524                 int expansion = (availableLogicalWidth - totalLogicalWidth) * opportunitiesInRun / expansionOpportunityCount;
    525                 textBox->setExpansion(expansion);
    526                 totalLogicalWidth += expansion;
    527             }
    528             expansionOpportunityCount -= opportunitiesInRun;
    529             if (!expansionOpportunityCount)
    530                 break;
    531         }
    532     }
    533 }
    534 
    535 void RenderBlockFlow::updateLogicalWidthForAlignment(const ETextAlign& textAlign, const RootInlineBox* rootInlineBox, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, unsigned expansionOpportunityCount)
    536 {
    537     TextDirection direction;
    538     if (rootInlineBox && rootInlineBox->renderer().style()->unicodeBidi() == Plaintext)
    539         direction = rootInlineBox->direction();
    540     else
    541         direction = style()->direction();
    542 
    543     // Armed with the total width of the line (without justification),
    544     // we now examine our text-align property in order to determine where to position the
    545     // objects horizontally. The total width of the line can be increased if we end up
    546     // justifying text.
    547     switch (textAlign) {
    548     case LEFT:
    549     case WEBKIT_LEFT:
    550         updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
    551         break;
    552     case RIGHT:
    553     case WEBKIT_RIGHT:
    554         updateLogicalWidthForRightAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
    555         break;
    556     case CENTER:
    557     case WEBKIT_CENTER:
    558         updateLogicalWidthForCenterAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
    559         break;
    560     case JUSTIFY:
    561         adjustInlineDirectionLineBounds(expansionOpportunityCount, logicalLeft, availableLogicalWidth);
    562         if (expansionOpportunityCount) {
    563             if (trailingSpaceRun) {
    564                 totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
    565                 trailingSpaceRun->m_box->setLogicalWidth(0);
    566             }
    567             break;
    568         }
    569         // Fall through
    570     case TASTART:
    571         if (direction == LTR)
    572             updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
    573         else
    574             updateLogicalWidthForRightAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
    575         break;
    576     case TAEND:
    577         if (direction == LTR)
    578             updateLogicalWidthForRightAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
    579         else
    580             updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
    581         break;
    582     }
    583     if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
    584         logicalLeft += verticalScrollbarWidth();
    585 }
    586 
    587 static void updateLogicalInlinePositions(RenderBlockFlow* block, float& lineLogicalLeft, float& lineLogicalRight, float& availableLogicalWidth, bool firstLine, IndentTextOrNot shouldIndentText, LayoutUnit boxLogicalHeight)
    588 {
    589     LayoutUnit lineLogicalHeight = block->minLineHeightForReplacedRenderer(firstLine, boxLogicalHeight);
    590     lineLogicalLeft = block->logicalLeftOffsetForLine(block->logicalHeight(), shouldIndentText == IndentText, lineLogicalHeight).toFloat();
    591     lineLogicalRight = block->logicalRightOffsetForLine(block->logicalHeight(), shouldIndentText == IndentText, lineLogicalHeight).toFloat();
    592     availableLogicalWidth = lineLogicalRight - lineLogicalLeft;
    593 }
    594 
    595 void RenderBlockFlow::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox, const LineInfo& lineInfo, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd,
    596                                                          GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache, WordMeasurements& wordMeasurements)
    597 {
    598     ETextAlign textAlign = textAlignmentForLine(!reachedEnd && !lineBox->endsWithBreak());
    599 
    600     // CSS 2.1: "'Text-indent' only affects a line if it is the first formatted line of an element. For example, the first line of an anonymous block
    601     // box is only affected if it is the first child of its parent element."
    602     // CSS3 "text-indent", "each-line" affects the first line of the block container as well as each line after a forced line break,
    603     // but does not affect lines after a soft wrap break.
    604     bool isFirstLine = lineInfo.isFirstLine() && !(isAnonymousBlock() && parent()->slowFirstChild() != this);
    605     bool isAfterHardLineBreak = lineBox->prevRootBox() && lineBox->prevRootBox()->endsWithBreak();
    606     IndentTextOrNot shouldIndentText = requiresIndent(isFirstLine, isAfterHardLineBreak, style());
    607     float lineLogicalLeft;
    608     float lineLogicalRight;
    609     float availableLogicalWidth;
    610     updateLogicalInlinePositions(this, lineLogicalLeft, lineLogicalRight, availableLogicalWidth, isFirstLine, shouldIndentText, 0);
    611     bool needsWordSpacing;
    612 
    613     if (firstRun && firstRun->m_object->isReplaced()) {
    614         RenderBox* renderBox = toRenderBox(firstRun->m_object);
    615         updateLogicalInlinePositions(this, lineLogicalLeft, lineLogicalRight, availableLogicalWidth, isFirstLine, shouldIndentText, renderBox->logicalHeight());
    616     }
    617 
    618     computeInlineDirectionPositionsForSegment(lineBox, lineInfo, textAlign, lineLogicalLeft, availableLogicalWidth, firstRun, trailingSpaceRun, textBoxDataMap, verticalPositionCache, wordMeasurements);
    619     // The widths of all runs are now known. We can now place every inline box (and
    620     // compute accurate widths for the inline flow boxes).
    621     needsWordSpacing = false;
    622     lineBox->placeBoxesInInlineDirection(lineLogicalLeft, needsWordSpacing, textBoxDataMap);
    623 }
    624 
    625 BidiRun* RenderBlockFlow::computeInlineDirectionPositionsForSegment(RootInlineBox* lineBox, const LineInfo& lineInfo, ETextAlign textAlign, float& logicalLeft,
    626     float& availableLogicalWidth, BidiRun* firstRun, BidiRun* trailingSpaceRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache,
    627     WordMeasurements& wordMeasurements)
    628 {
    629     bool needsWordSpacing = true;
    630     float totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth().toFloat();
    631     unsigned expansionOpportunityCount = 0;
    632     bool isAfterExpansion = true;
    633     Vector<unsigned, 16> expansionOpportunities;
    634     RenderObject* previousObject = 0;
    635     TextJustify textJustify = style()->textJustify();
    636 
    637     BidiRun* r = firstRun;
    638     for (; r; r = r->next()) {
    639         if (!r->m_box || r->m_object->isOutOfFlowPositioned() || r->m_box->isLineBreak())
    640             continue; // Positioned objects are only participating to figure out their
    641                       // correct static x position.  They have no effect on the width.
    642                       // Similarly, line break boxes have no effect on the width.
    643         if (r->m_object->isText()) {
    644             RenderText* rt = toRenderText(r->m_object);
    645             if (textAlign == JUSTIFY && r != trailingSpaceRun && textJustify != TextJustifyNone) {
    646                 if (!isAfterExpansion)
    647                     toInlineTextBox(r->m_box)->setCanHaveLeadingExpansion(true);
    648                 unsigned opportunitiesInRun;
    649                 if (rt->is8Bit())
    650                     opportunitiesInRun = Character::expansionOpportunityCount(rt->characters8() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), isAfterExpansion);
    651                 else
    652                     opportunitiesInRun = Character::expansionOpportunityCount(rt->characters16() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), isAfterExpansion);
    653                 expansionOpportunities.append(opportunitiesInRun);
    654                 expansionOpportunityCount += opportunitiesInRun;
    655             }
    656 
    657             if (rt->textLength()) {
    658                 if (!r->m_start && needsWordSpacing && isSpaceOrNewline(rt->characterAt(r->m_start)))
    659                     totalLogicalWidth += rt->style(lineInfo.isFirstLine())->font().fontDescription().wordSpacing();
    660                 needsWordSpacing = !isSpaceOrNewline(rt->characterAt(r->m_stop - 1));
    661             }
    662 
    663             setLogicalWidthForTextRun(lineBox, r, rt, totalLogicalWidth, lineInfo, textBoxDataMap, verticalPositionCache, wordMeasurements);
    664         } else {
    665             isAfterExpansion = false;
    666             if (!r->m_object->isRenderInline()) {
    667                 RenderBox* renderBox = toRenderBox(r->m_object);
    668                 if (renderBox->isRubyRun())
    669                     setMarginsForRubyRun(r, toRenderRubyRun(renderBox), previousObject, lineInfo);
    670                 r->m_box->setLogicalWidth(logicalWidthForChild(renderBox).toFloat());
    671                 totalLogicalWidth += marginStartForChild(renderBox) + marginEndForChild(renderBox);
    672             }
    673         }
    674 
    675         totalLogicalWidth += r->m_box->logicalWidth();
    676         previousObject = r->m_object;
    677     }
    678 
    679     if (isAfterExpansion && !expansionOpportunities.isEmpty()) {
    680         expansionOpportunities.last()--;
    681         expansionOpportunityCount--;
    682     }
    683 
    684     updateLogicalWidthForAlignment(textAlign, lineBox, trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth, expansionOpportunityCount);
    685 
    686     computeExpansionForJustifiedText(firstRun, trailingSpaceRun, expansionOpportunities, expansionOpportunityCount, totalLogicalWidth, availableLogicalWidth);
    687 
    688     return r;
    689 }
    690 
    691 void RenderBlockFlow::computeBlockDirectionPositionsForLine(RootInlineBox* lineBox, BidiRun* firstRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap,
    692                                                         VerticalPositionCache& verticalPositionCache)
    693 {
    694     setLogicalHeight(lineBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, verticalPositionCache));
    695 
    696     // Now make sure we place replaced render objects correctly.
    697     for (BidiRun* r = firstRun; r; r = r->next()) {
    698         ASSERT(r->m_box);
    699         if (!r->m_box)
    700             continue; // Skip runs with no line boxes.
    701 
    702         // Align positioned boxes with the top of the line box.  This is
    703         // a reasonable approximation of an appropriate y position.
    704         if (r->m_object->isOutOfFlowPositioned())
    705             r->m_box->setLogicalTop(logicalHeight().toFloat());
    706 
    707         // Position is used to properly position both replaced elements and
    708         // to update the static normal flow x/y of positioned elements.
    709         if (r->m_object->isText())
    710             toRenderText(r->m_object)->positionLineBox(r->m_box);
    711         else if (r->m_object->isBox())
    712             toRenderBox(r->m_object)->positionLineBox(r->m_box);
    713     }
    714 }
    715 
    716 void RenderBlockFlow::appendFloatingObjectToLastLine(FloatingObject* floatingObject)
    717 {
    718     ASSERT(!floatingObject->originatingLine());
    719     floatingObject->setOriginatingLine(lastRootBox());
    720     lastRootBox()->appendFloat(floatingObject->renderer());
    721 }
    722 
    723 // FIXME: This should be a BidiStatus constructor or create method.
    724 static inline BidiStatus statusWithDirection(TextDirection textDirection, bool isOverride)
    725 {
    726     WTF::Unicode::Direction direction = textDirection == LTR ? LeftToRight : RightToLeft;
    727     RefPtr<BidiContext> context = BidiContext::create(textDirection == LTR ? 0 : 1, direction, isOverride, FromStyleOrDOM);
    728 
    729     // This copies BidiStatus and may churn the ref on BidiContext I doubt it matters.
    730     return BidiStatus(direction, direction, direction, context.release());
    731 }
    732 
    733 static inline void setupResolverToResumeInIsolate(InlineBidiResolver& resolver, RenderObject* root, RenderObject* startObject)
    734 {
    735     if (root != startObject) {
    736         RenderObject* parent = startObject->parent();
    737         setupResolverToResumeInIsolate(resolver, root, parent);
    738         notifyObserverEnteredObject(&resolver, startObject);
    739     }
    740 }
    741 
    742 static void restoreIsolatedMidpointStates(InlineBidiResolver& topResolver, InlineBidiResolver& isolatedResolver)
    743 {
    744     while (!isolatedResolver.isolatedRuns().isEmpty()) {
    745         BidiRun* run = isolatedResolver.isolatedRuns().last();
    746         isolatedResolver.isolatedRuns().removeLast();
    747         topResolver.setMidpointStateForIsolatedRun(run, isolatedResolver.midpointStateForIsolatedRun(run));
    748     }
    749 }
    750 
    751 // FIXME: BidiResolver should have this logic.
    752 static inline void constructBidiRunsForLine(const RenderBlockFlow* block, InlineBidiResolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfLine, VisualDirectionOverride override, bool previousLineBrokeCleanly, bool isNewUBAParagraph)
    753 {
    754     // FIXME: We should pass a BidiRunList into createBidiRunsForLine instead
    755     // of the resolver owning the runs.
    756     ASSERT(&topResolver.runs() == &bidiRuns);
    757     ASSERT(topResolver.position() != endOfLine);
    758     RenderObject* currentRoot = topResolver.position().root();
    759     topResolver.createBidiRunsForLine(endOfLine, override, previousLineBrokeCleanly);
    760 
    761     while (!topResolver.isolatedRuns().isEmpty()) {
    762         // It does not matter which order we resolve the runs as long as we resolve them all.
    763         BidiRun* isolatedRun = topResolver.isolatedRuns().last();
    764         topResolver.isolatedRuns().removeLast();
    765 
    766         RenderObject* startObj = isolatedRun->object();
    767 
    768         // Only inlines make sense with unicode-bidi: isolate (blocks are already isolated).
    769         // FIXME: Because enterIsolate is not passed a RenderObject, we have to crawl up the
    770         // tree to see which parent inline is the isolate. We could change enterIsolate
    771         // to take a RenderObject and do this logic there, but that would be a layering
    772         // violation for BidiResolver (which knows nothing about RenderObject).
    773         RenderInline* isolatedInline = toRenderInline(highestContainingIsolateWithinRoot(startObj, currentRoot));
    774         ASSERT(isolatedInline);
    775 
    776         InlineBidiResolver isolatedResolver;
    777         LineMidpointState& isolatedLineMidpointState = isolatedResolver.midpointState();
    778         isolatedLineMidpointState = topResolver.midpointStateForIsolatedRun(isolatedRun);
    779         EUnicodeBidi unicodeBidi = isolatedInline->style()->unicodeBidi();
    780         TextDirection direction;
    781         if (unicodeBidi == Plaintext) {
    782             if (isNewUBAParagraph)
    783                 direction = determinePlaintextDirectionality(isolatedInline, startObj);
    784             else
    785                 direction = determinePlaintextDirectionality(isolatedInline);
    786         } else {
    787             ASSERT(unicodeBidi == Isolate || unicodeBidi == IsolateOverride);
    788             direction = isolatedInline->style()->direction();
    789         }
    790         isolatedResolver.setStatus(statusWithDirection(direction, isOverride(unicodeBidi)));
    791 
    792         setupResolverToResumeInIsolate(isolatedResolver, isolatedInline, startObj);
    793 
    794         // The starting position is the beginning of the first run within the isolate that was identified
    795         // during the earlier call to createBidiRunsForLine. This can be but is not necessarily the
    796         // first run within the isolate.
    797         InlineIterator iter = InlineIterator(isolatedInline, startObj, isolatedRun->m_start);
    798         isolatedResolver.setPositionIgnoringNestedIsolates(iter);
    799         // We stop at the next end of line; we may re-enter this isolate in the next call to constructBidiRuns().
    800         // FIXME: What should end and previousLineBrokeCleanly be?
    801         // rniwa says previousLineBrokeCleanly is just a WinIE hack and could always be false here?
    802         isolatedResolver.createBidiRunsForLine(endOfLine, NoVisualOverride, previousLineBrokeCleanly);
    803 
    804         ASSERT(isolatedResolver.runs().runCount());
    805         if (isolatedResolver.runs().runCount())
    806             bidiRuns.replaceRunWithRuns(isolatedRun, isolatedResolver.runs());
    807 
    808         // If we encountered any nested isolate runs, just move them
    809         // to the top resolver's list for later processing.
    810         if (!isolatedResolver.isolatedRuns().isEmpty()) {
    811             topResolver.isolatedRuns().appendVector(isolatedResolver.isolatedRuns());
    812             currentRoot = isolatedInline;
    813             restoreIsolatedMidpointStates(topResolver, isolatedResolver);
    814         }
    815     }
    816 }
    817 
    818 // This function constructs line boxes for all of the text runs in the resolver and computes their position.
    819 RootInlineBox* RenderBlockFlow::createLineBoxesFromBidiRuns(unsigned bidiLevel, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& end, LineInfo& lineInfo, VerticalPositionCache& verticalPositionCache, BidiRun* trailingSpaceRun, WordMeasurements& wordMeasurements)
    820 {
    821     if (!bidiRuns.runCount())
    822         return 0;
    823 
    824     // FIXME: Why is this only done when we had runs?
    825     lineInfo.setLastLine(!end.object());
    826 
    827     RootInlineBox* lineBox = constructLine(bidiRuns, lineInfo);
    828     if (!lineBox)
    829         return 0;
    830 
    831     lineBox->setBidiLevel(bidiLevel);
    832     lineBox->setEndsWithBreak(lineInfo.previousLineBrokeCleanly());
    833 
    834     bool isSVGRootInlineBox = lineBox->isSVGRootInlineBox();
    835 
    836     GlyphOverflowAndFallbackFontsMap textBoxDataMap;
    837 
    838     // Now we position all of our text runs horizontally.
    839     if (!isSVGRootInlineBox)
    840         computeInlineDirectionPositionsForLine(lineBox, lineInfo, bidiRuns.firstRun(), trailingSpaceRun, end.atEnd(), textBoxDataMap, verticalPositionCache, wordMeasurements);
    841 
    842     // Now position our text runs vertically.
    843     computeBlockDirectionPositionsForLine(lineBox, bidiRuns.firstRun(), textBoxDataMap, verticalPositionCache);
    844 
    845     // SVG text layout code computes vertical & horizontal positions on its own.
    846     // Note that we still need to execute computeVerticalPositionsForLine() as
    847     // it calls InlineTextBox::positionLineBox(), which tracks whether the box
    848     // contains reversed text or not. If we wouldn't do that editing and thus
    849     // text selection in RTL boxes would not work as expected.
    850     if (isSVGRootInlineBox) {
    851         ASSERT(isSVGText());
    852         toSVGRootInlineBox(lineBox)->computePerCharacterLayoutInformation();
    853     }
    854 
    855     // Compute our overflow now.
    856     lineBox->computeOverflow(lineBox->lineTop(), lineBox->lineBottom(), textBoxDataMap);
    857 
    858     return lineBox;
    859 }
    860 
    861 static void deleteLineRange(LineLayoutState& layoutState, RootInlineBox* startLine, RootInlineBox* stopLine = 0)
    862 {
    863     RootInlineBox* boxToDelete = startLine;
    864     while (boxToDelete && boxToDelete != stopLine) {
    865         layoutState.updateRepaintRangeFromBox(boxToDelete);
    866         // Note: deleteLineRange(firstRootBox()) is not identical to deleteLineBoxTree().
    867         // deleteLineBoxTree uses nextLineBox() instead of nextRootBox() when traversing.
    868         RootInlineBox* next = boxToDelete->nextRootBox();
    869         boxToDelete->deleteLine();
    870         boxToDelete = next;
    871     }
    872 }
    873 
    874 void RenderBlockFlow::layoutRunsAndFloats(LineLayoutState& layoutState)
    875 {
    876     // We want to skip ahead to the first dirty line
    877     InlineBidiResolver resolver;
    878     RootInlineBox* startLine = determineStartPosition(layoutState, resolver);
    879 
    880     unsigned consecutiveHyphenatedLines = 0;
    881     if (startLine) {
    882         for (RootInlineBox* line = startLine->prevRootBox(); line && line->isHyphenated(); line = line->prevRootBox())
    883             consecutiveHyphenatedLines++;
    884     }
    885 
    886     if (containsFloats())
    887         layoutState.setLastFloat(m_floatingObjects->set().last().get());
    888 
    889     // We also find the first clean line and extract these lines.  We will add them back
    890     // if we determine that we're able to synchronize after handling all our dirty lines.
    891     InlineIterator cleanLineStart;
    892     BidiStatus cleanLineBidiStatus;
    893     if (!layoutState.isFullLayout() && startLine)
    894         determineEndPosition(layoutState, startLine, cleanLineStart, cleanLineBidiStatus);
    895 
    896     if (startLine) {
    897         if (!layoutState.usesRepaintBounds())
    898             layoutState.setRepaintRange(logicalHeight());
    899         deleteLineRange(layoutState, startLine);
    900     }
    901 
    902     if (!layoutState.isFullLayout() && lastRootBox() && lastRootBox()->endsWithBreak()) {
    903         // If the last line before the start line ends with a line break that clear floats,
    904         // adjust the height accordingly.
    905         // A line break can be either the first or the last object on a line, depending on its direction.
    906         if (InlineBox* lastLeafChild = lastRootBox()->lastLeafChild()) {
    907             RenderObject* lastObject = &lastLeafChild->renderer();
    908             if (!lastObject->isBR())
    909                 lastObject = &lastRootBox()->firstLeafChild()->renderer();
    910             if (lastObject->isBR()) {
    911                 EClear clear = lastObject->style()->clear();
    912                 if (clear != CNONE)
    913                     clearFloats(clear);
    914             }
    915         }
    916     }
    917 
    918     layoutRunsAndFloatsInRange(layoutState, resolver, cleanLineStart, cleanLineBidiStatus, consecutiveHyphenatedLines);
    919     linkToEndLineIfNeeded(layoutState);
    920     repaintDirtyFloats(layoutState.floats());
    921 }
    922 
    923 // Before restarting the layout loop with a new logicalHeight, remove all floats that were added and reset the resolver.
    924 inline const InlineIterator& RenderBlockFlow::restartLayoutRunsAndFloatsInRange(LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight,  FloatingObject* lastFloatFromPreviousLine, InlineBidiResolver& resolver,  const InlineIterator& oldEnd)
    925 {
    926     removeFloatingObjectsBelow(lastFloatFromPreviousLine, oldLogicalHeight);
    927     setLogicalHeight(newLogicalHeight);
    928     resolver.setPositionIgnoringNestedIsolates(oldEnd);
    929     return oldEnd;
    930 }
    931 
    932 void RenderBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, InlineBidiResolver& resolver, const InlineIterator& cleanLineStart, const BidiStatus& cleanLineBidiStatus, unsigned consecutiveHyphenatedLines)
    933 {
    934     RenderStyle* styleToUse = style();
    935     bool paginated = view()->layoutState() && view()->layoutState()->isPaginated();
    936     LineMidpointState& lineMidpointState = resolver.midpointState();
    937     InlineIterator endOfLine = resolver.position();
    938     bool checkForEndLineMatch = layoutState.endLine();
    939     RenderTextInfo renderTextInfo;
    940     VerticalPositionCache verticalPositionCache;
    941 
    942     LineBreaker lineBreaker(this);
    943 
    944     LayoutSize logicalOffsetFromShapeContainer;
    945 
    946     while (!endOfLine.atEnd()) {
    947         // FIXME: Is this check necessary before the first iteration or can it be moved to the end?
    948         if (checkForEndLineMatch) {
    949             layoutState.setEndLineMatched(matchedEndLine(layoutState, resolver, cleanLineStart, cleanLineBidiStatus));
    950             if (layoutState.endLineMatched()) {
    951                 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0);
    952                 break;
    953             }
    954         }
    955 
    956         lineMidpointState.reset();
    957 
    958         layoutState.lineInfo().setEmpty(true);
    959         layoutState.lineInfo().resetRunsFromLeadingWhitespace();
    960 
    961         const InlineIterator previousEndofLine = endOfLine;
    962         bool isNewUBAParagraph = layoutState.lineInfo().previousLineBrokeCleanly();
    963         FloatingObject* lastFloatFromPreviousLine = (containsFloats()) ? m_floatingObjects->set().last().get() : 0;
    964 
    965         WordMeasurements wordMeasurements;
    966         endOfLine = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(), renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements);
    967         renderTextInfo.m_lineBreakIterator.resetPriorContext();
    968         if (resolver.position().atEnd()) {
    969             // FIXME: We shouldn't be creating any runs in nextLineBreak to begin with!
    970             // Once BidiRunList is separated from BidiResolver this will not be needed.
    971             resolver.runs().deleteRuns();
    972             resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed).
    973             layoutState.setCheckForFloatsFromLastLine(true);
    974             resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0);
    975             break;
    976         }
    977 
    978         ASSERT(endOfLine != resolver.position());
    979 
    980         // This is a short-cut for empty lines.
    981         if (layoutState.lineInfo().isEmpty()) {
    982             if (lastRootBox())
    983                 lastRootBox()->setLineBreakInfo(endOfLine.object(), endOfLine.offset(), resolver.status());
    984         } else {
    985             VisualDirectionOverride override = (styleToUse->rtlOrdering() == VisualOrder ? (styleToUse->direction() == LTR ? VisualLeftToRightOverride : VisualRightToLeftOverride) : NoVisualOverride);
    986             if (isNewUBAParagraph && styleToUse->unicodeBidi() == Plaintext && !resolver.context()->parent()) {
    987                 TextDirection direction = determinePlaintextDirectionality(resolver.position().root(), resolver.position().object(), resolver.position().offset());
    988                 resolver.setStatus(BidiStatus(direction, isOverride(styleToUse->unicodeBidi())));
    989             }
    990             // FIXME: This ownership is reversed. We should own the BidiRunList and pass it to createBidiRunsForLine.
    991             BidiRunList<BidiRun>& bidiRuns = resolver.runs();
    992             constructBidiRunsForLine(this, resolver, bidiRuns, endOfLine, override, layoutState.lineInfo().previousLineBrokeCleanly(), isNewUBAParagraph);
    993             ASSERT(resolver.position() == endOfLine);
    994 
    995             BidiRun* trailingSpaceRun = resolver.trailingSpaceRun();
    996 
    997             if (bidiRuns.runCount() && lineBreaker.lineWasHyphenated()) {
    998                 bidiRuns.logicallyLastRun()->m_hasHyphen = true;
    999                 consecutiveHyphenatedLines++;
   1000             } else
   1001                 consecutiveHyphenatedLines = 0;
   1002 
   1003             // Now that the runs have been ordered, we create the line boxes.
   1004             // At the same time we figure out where border/padding/margin should be applied for
   1005             // inline flow boxes.
   1006 
   1007             LayoutUnit oldLogicalHeight = logicalHeight();
   1008             RootInlineBox* lineBox = createLineBoxesFromBidiRuns(resolver.status().context->level(), bidiRuns, endOfLine, layoutState.lineInfo(), verticalPositionCache, trailingSpaceRun, wordMeasurements);
   1009 
   1010             bidiRuns.deleteRuns();
   1011             resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed).
   1012 
   1013             if (lineBox) {
   1014                 lineBox->setLineBreakInfo(endOfLine.object(), endOfLine.offset(), resolver.status());
   1015                 if (layoutState.usesRepaintBounds())
   1016                     layoutState.updateRepaintRangeFromBox(lineBox);
   1017 
   1018                 if (paginated) {
   1019                     LayoutUnit adjustment = 0;
   1020                     adjustLinePositionForPagination(lineBox, adjustment, layoutState.flowThread());
   1021                     if (adjustment) {
   1022                         LayoutUnit oldLineWidth = availableLogicalWidthForLine(oldLogicalHeight, layoutState.lineInfo().isFirstLine());
   1023                         lineBox->adjustBlockDirectionPosition(adjustment.toFloat());
   1024                         if (layoutState.usesRepaintBounds())
   1025                             layoutState.updateRepaintRangeFromBox(lineBox);
   1026 
   1027                         if (availableLogicalWidthForLine(oldLogicalHeight + adjustment, layoutState.lineInfo().isFirstLine()) != oldLineWidth) {
   1028                             // We have to delete this line, remove all floats that got added, and let line layout re-run.
   1029                             lineBox->deleteLine();
   1030                             endOfLine = restartLayoutRunsAndFloatsInRange(oldLogicalHeight, oldLogicalHeight + adjustment, lastFloatFromPreviousLine, resolver, previousEndofLine);
   1031                             continue;
   1032                         }
   1033 
   1034                         setLogicalHeight(lineBox->lineBottomWithLeading());
   1035                     }
   1036                 }
   1037             }
   1038         }
   1039 
   1040         for (size_t i = 0; i < lineBreaker.positionedObjects().size(); ++i)
   1041             setStaticPositions(this, lineBreaker.positionedObjects()[i]);
   1042 
   1043         if (!layoutState.lineInfo().isEmpty()) {
   1044             layoutState.lineInfo().setFirstLine(false);
   1045             clearFloats(lineBreaker.clear());
   1046         }
   1047 
   1048         if (m_floatingObjects && lastRootBox()) {
   1049             const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   1050             FloatingObjectSetIterator it = floatingObjectSet.begin();
   1051             FloatingObjectSetIterator end = floatingObjectSet.end();
   1052             if (layoutState.lastFloat()) {
   1053                 FloatingObjectSetIterator lastFloatIterator = floatingObjectSet.find(layoutState.lastFloat());
   1054                 ASSERT(lastFloatIterator != end);
   1055                 ++lastFloatIterator;
   1056                 it = lastFloatIterator;
   1057             }
   1058             for (; it != end; ++it) {
   1059                 FloatingObject* f = it->get();
   1060                 appendFloatingObjectToLastLine(f);
   1061                 ASSERT(f->renderer() == layoutState.floats()[layoutState.floatIndex()].object);
   1062                 // If a float's geometry has changed, give up on syncing with clean lines.
   1063                 if (layoutState.floats()[layoutState.floatIndex()].rect != f->frameRect())
   1064                     checkForEndLineMatch = false;
   1065                 layoutState.setFloatIndex(layoutState.floatIndex() + 1);
   1066             }
   1067             layoutState.setLastFloat(!floatingObjectSet.isEmpty() ? floatingObjectSet.last().get() : 0);
   1068         }
   1069 
   1070         lineMidpointState.reset();
   1071         resolver.setPosition(endOfLine, numberOfIsolateAncestors(endOfLine));
   1072     }
   1073 
   1074     // In case we already adjusted the line positions during this layout to avoid widows
   1075     // then we need to ignore the possibility of having a new widows situation.
   1076     // Otherwise, we risk leaving empty containers which is against the block fragmentation principles.
   1077     if (paginated && !style()->hasAutoWidows() && !didBreakAtLineToAvoidWidow()) {
   1078         // Check the line boxes to make sure we didn't create unacceptable widows.
   1079         // However, we'll prioritize orphans - so nothing we do here should create
   1080         // a new orphan.
   1081 
   1082         RootInlineBox* lineBox = lastRootBox();
   1083 
   1084         // Count from the end of the block backwards, to see how many hanging
   1085         // lines we have.
   1086         RootInlineBox* firstLineInBlock = firstRootBox();
   1087         int numLinesHanging = 1;
   1088         while (lineBox && lineBox != firstLineInBlock && !lineBox->isFirstAfterPageBreak()) {
   1089             ++numLinesHanging;
   1090             lineBox = lineBox->prevRootBox();
   1091         }
   1092 
   1093         // If there were no breaks in the block, we didn't create any widows.
   1094         if (!lineBox || !lineBox->isFirstAfterPageBreak() || lineBox == firstLineInBlock)
   1095             return;
   1096 
   1097         if (numLinesHanging < style()->widows()) {
   1098             // We have detected a widow. Now we need to work out how many
   1099             // lines there are on the previous page, and how many we need
   1100             // to steal.
   1101             int numLinesNeeded = style()->widows() - numLinesHanging;
   1102             RootInlineBox* currentFirstLineOfNewPage = lineBox;
   1103 
   1104             // Count the number of lines in the previous page.
   1105             lineBox = lineBox->prevRootBox();
   1106             int numLinesInPreviousPage = 1;
   1107             while (lineBox && lineBox != firstLineInBlock && !lineBox->isFirstAfterPageBreak()) {
   1108                 ++numLinesInPreviousPage;
   1109                 lineBox = lineBox->prevRootBox();
   1110             }
   1111 
   1112             // If there was an explicit value for orphans, respect that. If not, we still
   1113             // shouldn't create a situation where we make an orphan bigger than the initial value.
   1114             // This means that setting widows implies we also care about orphans, but given
   1115             // the specification says the initial orphan value is non-zero, this is ok. The
   1116             // author is always free to set orphans explicitly as well.
   1117             int orphans = style()->hasAutoOrphans() ? style()->initialOrphans() : style()->orphans();
   1118             int numLinesAvailable = numLinesInPreviousPage - orphans;
   1119             if (numLinesAvailable <= 0)
   1120                 return;
   1121 
   1122             int numLinesToTake = min(numLinesAvailable, numLinesNeeded);
   1123             // Wind back from our first widowed line.
   1124             lineBox = currentFirstLineOfNewPage;
   1125             for (int i = 0; i < numLinesToTake; ++i)
   1126                 lineBox = lineBox->prevRootBox();
   1127 
   1128             // We now want to break at this line. Remember for next layout and trigger relayout.
   1129             setBreakAtLineToAvoidWidow(lineCount(lineBox));
   1130             markLinesDirtyInBlockRange(lastRootBox()->lineBottomWithLeading(), lineBox->lineBottomWithLeading(), lineBox);
   1131         }
   1132     }
   1133 
   1134     clearDidBreakAtLineToAvoidWidow();
   1135 }
   1136 
   1137 void RenderBlockFlow::linkToEndLineIfNeeded(LineLayoutState& layoutState)
   1138 {
   1139     if (layoutState.endLine()) {
   1140         if (layoutState.endLineMatched()) {
   1141             bool paginated = view()->layoutState() && view()->layoutState()->isPaginated();
   1142             // Attach all the remaining lines, and then adjust their y-positions as needed.
   1143             LayoutUnit delta = logicalHeight() - layoutState.endLineLogicalTop();
   1144             for (RootInlineBox* line = layoutState.endLine(); line; line = line->nextRootBox()) {
   1145                 line->attachLine();
   1146                 if (paginated) {
   1147                     delta -= line->paginationStrut();
   1148                     adjustLinePositionForPagination(line, delta, layoutState.flowThread());
   1149                 }
   1150                 if (delta) {
   1151                     layoutState.updateRepaintRangeFromBox(line, delta);
   1152                     line->adjustBlockDirectionPosition(delta.toFloat());
   1153                 }
   1154                 if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) {
   1155                     Vector<RenderBox*>::iterator end = cleanLineFloats->end();
   1156                     for (Vector<RenderBox*>::iterator f = cleanLineFloats->begin(); f != end; ++f) {
   1157                         FloatingObject* floatingObject = insertFloatingObject(*f);
   1158                         ASSERT(!floatingObject->originatingLine());
   1159                         floatingObject->setOriginatingLine(line);
   1160                         setLogicalHeight(logicalTopForChild(*f) - marginBeforeForChild(*f) + delta);
   1161                         positionNewFloats();
   1162                     }
   1163                 }
   1164             }
   1165             setLogicalHeight(lastRootBox()->lineBottomWithLeading());
   1166         } else {
   1167             // Delete all the remaining lines.
   1168             deleteLineRange(layoutState, layoutState.endLine());
   1169         }
   1170     }
   1171 
   1172     if (m_floatingObjects && (layoutState.checkForFloatsFromLastLine() || positionNewFloats()) && lastRootBox()) {
   1173         // In case we have a float on the last line, it might not be positioned up to now.
   1174         // This has to be done before adding in the bottom border/padding, or the float will
   1175         // include the padding incorrectly. -dwh
   1176         if (layoutState.checkForFloatsFromLastLine()) {
   1177             LayoutUnit bottomVisualOverflow = lastRootBox()->logicalBottomVisualOverflow();
   1178             LayoutUnit bottomLayoutOverflow = lastRootBox()->logicalBottomLayoutOverflow();
   1179             TrailingFloatsRootInlineBox* trailingFloatsLineBox = new TrailingFloatsRootInlineBox(*this);
   1180             m_lineBoxes.appendLineBox(trailingFloatsLineBox);
   1181             trailingFloatsLineBox->setConstructed();
   1182             GlyphOverflowAndFallbackFontsMap textBoxDataMap;
   1183             VerticalPositionCache verticalPositionCache;
   1184             LayoutUnit blockLogicalHeight = logicalHeight();
   1185             trailingFloatsLineBox->alignBoxesInBlockDirection(blockLogicalHeight, textBoxDataMap, verticalPositionCache);
   1186             trailingFloatsLineBox->setLineTopBottomPositions(blockLogicalHeight, blockLogicalHeight, blockLogicalHeight, blockLogicalHeight);
   1187             trailingFloatsLineBox->setPaginatedLineWidth(availableLogicalWidthForContent());
   1188             LayoutRect logicalLayoutOverflow(0, blockLogicalHeight, 1, bottomLayoutOverflow - blockLogicalHeight);
   1189             LayoutRect logicalVisualOverflow(0, blockLogicalHeight, 1, bottomVisualOverflow - blockLogicalHeight);
   1190             trailingFloatsLineBox->setOverflowFromLogicalRects(logicalLayoutOverflow, logicalVisualOverflow, trailingFloatsLineBox->lineTop(), trailingFloatsLineBox->lineBottom());
   1191         }
   1192 
   1193         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   1194         FloatingObjectSetIterator it = floatingObjectSet.begin();
   1195         FloatingObjectSetIterator end = floatingObjectSet.end();
   1196         if (layoutState.lastFloat()) {
   1197             FloatingObjectSetIterator lastFloatIterator = floatingObjectSet.find(layoutState.lastFloat());
   1198             ASSERT(lastFloatIterator != end);
   1199             ++lastFloatIterator;
   1200             it = lastFloatIterator;
   1201         }
   1202         for (; it != end; ++it)
   1203             appendFloatingObjectToLastLine(it->get());
   1204         layoutState.setLastFloat(!floatingObjectSet.isEmpty() ? floatingObjectSet.last().get() : 0);
   1205     }
   1206 }
   1207 
   1208 void RenderBlockFlow::repaintDirtyFloats(Vector<FloatWithRect>& floats)
   1209 {
   1210     size_t floatCount = floats.size();
   1211     // Floats that did not have layout did not paint invalidations when we laid them out. They would have
   1212     // painted by now if they had moved, but if they stayed at (0, 0), they still need to be
   1213     // painted.
   1214     for (size_t i = 0; i < floatCount; ++i) {
   1215         if (!floats[i].everHadLayout) {
   1216             RenderBox* f = floats[i].object;
   1217             if (!f->x() && !f->y() && f->checkForPaintInvalidation()) {
   1218                 if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
   1219                     f->setShouldDoFullPaintInvalidationAfterLayout(true);
   1220                 else
   1221                     f->paintInvalidationForWholeRenderer();
   1222             }
   1223         }
   1224     }
   1225 }
   1226 
   1227 struct InlineMinMaxIterator {
   1228 /* InlineMinMaxIterator is a class that will iterate over all render objects that contribute to
   1229    inline min/max width calculations.  Note the following about the way it walks:
   1230    (1) Positioned content is skipped (since it does not contribute to min/max width of a block)
   1231    (2) We do not drill into the children of floats or replaced elements, since you can't break
   1232        in the middle of such an element.
   1233    (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side can have
   1234        distinct borders/margin/padding that contribute to the min/max width.
   1235 */
   1236     RenderObject* parent;
   1237     RenderObject* current;
   1238     bool endOfInline;
   1239 
   1240     InlineMinMaxIterator(RenderObject* p, bool end = false)
   1241         : parent(p), current(p), endOfInline(end)
   1242     {
   1243 
   1244     }
   1245 
   1246     RenderObject* next();
   1247 };
   1248 
   1249 RenderObject* InlineMinMaxIterator::next()
   1250 {
   1251     RenderObject* result = 0;
   1252     bool oldEndOfInline = endOfInline;
   1253     endOfInline = false;
   1254     while (current || current == parent) {
   1255         if (!oldEndOfInline && (current == parent || (!current->isFloating() && !current->isReplaced() && !current->isOutOfFlowPositioned())))
   1256             result = current->slowFirstChild();
   1257 
   1258         if (!result) {
   1259             // We hit the end of our inline. (It was empty, e.g., <span></span>.)
   1260             if (!oldEndOfInline && current->isRenderInline()) {
   1261                 result = current;
   1262                 endOfInline = true;
   1263                 break;
   1264             }
   1265 
   1266             while (current && current != parent) {
   1267                 result = current->nextSibling();
   1268                 if (result)
   1269                     break;
   1270                 current = current->parent();
   1271                 if (current && current != parent && current->isRenderInline()) {
   1272                     result = current;
   1273                     endOfInline = true;
   1274                     break;
   1275                 }
   1276             }
   1277         }
   1278 
   1279         if (!result)
   1280             break;
   1281 
   1282         if (!result->isOutOfFlowPositioned() && (result->isText() || result->isFloating() || result->isReplaced() || result->isRenderInline()))
   1283             break;
   1284 
   1285         current = result;
   1286         result = 0;
   1287     }
   1288 
   1289     // Update our position.
   1290     current = result;
   1291     return current;
   1292 }
   1293 
   1294 static LayoutUnit getBPMWidth(LayoutUnit childValue, Length cssUnit)
   1295 {
   1296     if (cssUnit.type() != Auto)
   1297         return (cssUnit.isFixed() ? static_cast<LayoutUnit>(cssUnit.value()) : childValue);
   1298     return 0;
   1299 }
   1300 
   1301 static LayoutUnit getBorderPaddingMargin(RenderBoxModelObject* child, bool endOfInline)
   1302 {
   1303     RenderStyle* childStyle = child->style();
   1304     if (endOfInline) {
   1305         return getBPMWidth(child->marginEnd(), childStyle->marginEnd()) +
   1306             getBPMWidth(child->paddingEnd(), childStyle->paddingEnd()) +
   1307             child->borderEnd();
   1308     }
   1309     return getBPMWidth(child->marginStart(), childStyle->marginStart()) +
   1310         getBPMWidth(child->paddingStart(), childStyle->paddingStart()) +
   1311         child->borderStart();
   1312 }
   1313 
   1314 static inline void stripTrailingSpace(float& inlineMax, float& inlineMin, RenderObject* trailingSpaceChild)
   1315 {
   1316     if (trailingSpaceChild && trailingSpaceChild->isText()) {
   1317         // Collapse away the trailing space at the end of a block.
   1318         RenderText* t = toRenderText(trailingSpaceChild);
   1319         const UChar space = ' ';
   1320         const Font& font = t->style()->font(); // FIXME: This ignores first-line.
   1321         float spaceWidth = font.width(RenderBlockFlow::constructTextRun(t, font, &space, 1, t->style(), LTR));
   1322         inlineMax -= spaceWidth + font.fontDescription().wordSpacing();
   1323         if (inlineMin > inlineMax)
   1324             inlineMin = inlineMax;
   1325     }
   1326 }
   1327 
   1328 static inline void updatePreferredWidth(LayoutUnit& preferredWidth, float& result)
   1329 {
   1330     LayoutUnit snappedResult = LayoutUnit::fromFloatCeil(result);
   1331     preferredWidth = max(snappedResult, preferredWidth);
   1332 }
   1333 
   1334 // When converting between floating point and LayoutUnits we risk losing precision
   1335 // with each conversion. When this occurs while accumulating our preferred widths,
   1336 // we can wind up with a line width that's larger than our maxPreferredWidth due to
   1337 // pure float accumulation.
   1338 static inline LayoutUnit adjustFloatForSubPixelLayout(float value)
   1339 {
   1340     return LayoutUnit::fromFloatCeil(value);
   1341 }
   1342 
   1343 // FIXME: This function should be broken into something less monolithic.
   1344 // FIXME: The main loop here is very similar to LineBreaker::nextSegmentBreak. They can probably reuse code.
   1345 void RenderBlockFlow::computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth)
   1346 {
   1347     float inlineMax = 0;
   1348     float inlineMin = 0;
   1349 
   1350     RenderStyle* styleToUse = style();
   1351     RenderBlock* containingBlock = this->containingBlock();
   1352     LayoutUnit cw = containingBlock ? containingBlock->contentLogicalWidth() : LayoutUnit();
   1353 
   1354     // If we are at the start of a line, we want to ignore all white-space.
   1355     // Also strip spaces if we previously had text that ended in a trailing space.
   1356     bool stripFrontSpaces = true;
   1357     RenderObject* trailingSpaceChild = 0;
   1358 
   1359     // Firefox and Opera will allow a table cell to grow to fit an image inside it under
   1360     // very specific cirucumstances (in order to match common WinIE renderings).
   1361     // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
   1362     bool allowImagesToBreak = !document().inQuirksMode() || !isTableCell() || !styleToUse->logicalWidth().isIntrinsicOrAuto();
   1363 
   1364     bool autoWrap, oldAutoWrap;
   1365     autoWrap = oldAutoWrap = styleToUse->autoWrap();
   1366 
   1367     InlineMinMaxIterator childIterator(this);
   1368 
   1369     // Only gets added to the max preffered width once.
   1370     bool addedTextIndent = false;
   1371     // Signals the text indent was more negative than the min preferred width
   1372     bool hasRemainingNegativeTextIndent = false;
   1373 
   1374     LayoutUnit textIndent = minimumValueForLength(styleToUse->textIndent(), cw);
   1375     RenderObject* prevFloat = 0;
   1376     bool isPrevChildInlineFlow = false;
   1377     bool shouldBreakLineAfterText = false;
   1378     while (RenderObject* child = childIterator.next()) {
   1379         autoWrap = child->isReplaced() ? child->parent()->style()->autoWrap() :
   1380             child->style()->autoWrap();
   1381 
   1382         if (!child->isBR()) {
   1383             // Step One: determine whether or not we need to go ahead and
   1384             // terminate our current line. Each discrete chunk can become
   1385             // the new min-width, if it is the widest chunk seen so far, and
   1386             // it can also become the max-width.
   1387 
   1388             // Children fall into three categories:
   1389             // (1) An inline flow object. These objects always have a min/max of 0,
   1390             // and are included in the iteration solely so that their margins can
   1391             // be added in.
   1392             //
   1393             // (2) An inline non-text non-flow object, e.g., an inline replaced element.
   1394             // These objects can always be on a line by themselves, so in this situation
   1395             // we need to go ahead and break the current line, and then add in our own
   1396             // margins and min/max width on its own line, and then terminate the line.
   1397             //
   1398             // (3) A text object. Text runs can have breakable characters at the start,
   1399             // the middle or the end. They may also lose whitespace off the front if
   1400             // we're already ignoring whitespace. In order to compute accurate min-width
   1401             // information, we need three pieces of information.
   1402             // (a) the min-width of the first non-breakable run. Should be 0 if the text string
   1403             // starts with whitespace.
   1404             // (b) the min-width of the last non-breakable run. Should be 0 if the text string
   1405             // ends with whitespace.
   1406             // (c) the min/max width of the string (trimmed for whitespace).
   1407             //
   1408             // If the text string starts with whitespace, then we need to go ahead and
   1409             // terminate our current line (unless we're already in a whitespace stripping
   1410             // mode.
   1411             //
   1412             // If the text string has a breakable character in the middle, but didn't start
   1413             // with whitespace, then we add the width of the first non-breakable run and
   1414             // then end the current line. We then need to use the intermediate min/max width
   1415             // values (if any of them are larger than our current min/max). We then look at
   1416             // the width of the last non-breakable run and use that to start a new line
   1417             // (unless we end in whitespace).
   1418             RenderStyle* childStyle = child->style();
   1419             float childMin = 0;
   1420             float childMax = 0;
   1421 
   1422             if (!child->isText()) {
   1423                 // Case (1) and (2). Inline replaced and inline flow elements.
   1424                 if (child->isRenderInline()) {
   1425                     // Add in padding/border/margin from the appropriate side of
   1426                     // the element.
   1427                     float bpm = getBorderPaddingMargin(toRenderInline(child), childIterator.endOfInline).toFloat();
   1428                     childMin += bpm;
   1429                     childMax += bpm;
   1430 
   1431                     inlineMin += childMin;
   1432                     inlineMax += childMax;
   1433 
   1434                     child->clearPreferredLogicalWidthsDirty();
   1435                 } else {
   1436                     // Inline replaced elts add in their margins to their min/max values.
   1437                     LayoutUnit margins = 0;
   1438                     Length startMargin = childStyle->marginStart();
   1439                     Length endMargin = childStyle->marginEnd();
   1440                     if (startMargin.isFixed())
   1441                         margins += adjustFloatForSubPixelLayout(startMargin.value());
   1442                     if (endMargin.isFixed())
   1443                         margins += adjustFloatForSubPixelLayout(endMargin.value());
   1444                     childMin += margins.ceilToFloat();
   1445                     childMax += margins.ceilToFloat();
   1446                 }
   1447             }
   1448 
   1449             if (!child->isRenderInline() && !child->isText()) {
   1450                 // Case (2). Inline replaced elements and floats.
   1451                 // Go ahead and terminate the current line as far as
   1452                 // minwidth is concerned.
   1453                 LayoutUnit childMinPreferredLogicalWidth, childMaxPreferredLogicalWidth;
   1454                 if (child->isBox() && child->isHorizontalWritingMode() != isHorizontalWritingMode()) {
   1455                     RenderBox* childBox = toRenderBox(child);
   1456                     LogicalExtentComputedValues computedValues;
   1457                     childBox->computeLogicalHeight(childBox->borderAndPaddingLogicalHeight(), 0, computedValues);
   1458                     childMinPreferredLogicalWidth = childMaxPreferredLogicalWidth = computedValues.m_extent;
   1459                 } else {
   1460                     childMinPreferredLogicalWidth = child->minPreferredLogicalWidth();
   1461                     childMaxPreferredLogicalWidth = child->maxPreferredLogicalWidth();
   1462                 }
   1463                 childMin += childMinPreferredLogicalWidth.ceilToFloat();
   1464                 childMax += childMaxPreferredLogicalWidth.ceilToFloat();
   1465 
   1466                 bool clearPreviousFloat;
   1467                 if (child->isFloating()) {
   1468                     clearPreviousFloat = (prevFloat
   1469                         && ((prevFloat->style()->floating() == LeftFloat && (childStyle->clear() & CLEFT))
   1470                             || (prevFloat->style()->floating() == RightFloat && (childStyle->clear() & CRIGHT))));
   1471                     prevFloat = child;
   1472                 } else {
   1473                     clearPreviousFloat = false;
   1474                 }
   1475 
   1476                 bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak;
   1477                 if ((canBreakReplacedElement && (autoWrap || oldAutoWrap) && (!isPrevChildInlineFlow || shouldBreakLineAfterText)) || clearPreviousFloat) {
   1478                     updatePreferredWidth(minLogicalWidth, inlineMin);
   1479                     inlineMin = 0;
   1480                 }
   1481 
   1482                 // If we're supposed to clear the previous float, then terminate maxwidth as well.
   1483                 if (clearPreviousFloat) {
   1484                     updatePreferredWidth(maxLogicalWidth, inlineMax);
   1485                     inlineMax = 0;
   1486                 }
   1487 
   1488                 // Add in text-indent. This is added in only once.
   1489                 if (!addedTextIndent && !child->isFloating()) {
   1490                     float ceiledTextIndent = textIndent.ceilToFloat();
   1491                     childMin += ceiledTextIndent;
   1492                     childMax += ceiledTextIndent;
   1493 
   1494                     if (childMin < 0)
   1495                         textIndent = adjustFloatForSubPixelLayout(childMin);
   1496                     else
   1497                         addedTextIndent = true;
   1498                 }
   1499 
   1500                 // Add our width to the max.
   1501                 inlineMax += max<float>(0, childMax);
   1502 
   1503                 if (!autoWrap || !canBreakReplacedElement || (isPrevChildInlineFlow && !shouldBreakLineAfterText)) {
   1504                     if (child->isFloating())
   1505                         updatePreferredWidth(minLogicalWidth, childMin);
   1506                     else
   1507                         inlineMin += childMin;
   1508                 } else {
   1509                     // Now check our line.
   1510                     updatePreferredWidth(minLogicalWidth, childMin);
   1511 
   1512                     // Now start a new line.
   1513                     inlineMin = 0;
   1514                 }
   1515 
   1516                 if (autoWrap && canBreakReplacedElement && isPrevChildInlineFlow) {
   1517                     updatePreferredWidth(minLogicalWidth, inlineMin);
   1518                     inlineMin = 0;
   1519                 }
   1520 
   1521                 // We are no longer stripping whitespace at the start of
   1522                 // a line.
   1523                 if (!child->isFloating()) {
   1524                     stripFrontSpaces = false;
   1525                     trailingSpaceChild = 0;
   1526                 }
   1527             } else if (child->isText()) {
   1528                 // Case (3). Text.
   1529                 RenderText* t = toRenderText(child);
   1530 
   1531                 if (t->isWordBreak()) {
   1532                     updatePreferredWidth(minLogicalWidth, inlineMin);
   1533                     inlineMin = 0;
   1534                     continue;
   1535                 }
   1536 
   1537                 if (t->style()->hasTextCombine() && t->isCombineText())
   1538                     toRenderCombineText(t)->combineText();
   1539 
   1540                 // Determine if we have a breakable character. Pass in
   1541                 // whether or not we should ignore any spaces at the front
   1542                 // of the string. If those are going to be stripped out,
   1543                 // then they shouldn't be considered in the breakable char
   1544                 // check.
   1545                 bool hasBreakableChar, hasBreak;
   1546                 float firstLineMinWidth, lastLineMinWidth;
   1547                 bool hasBreakableStart, hasBreakableEnd;
   1548                 float firstLineMaxWidth, lastLineMaxWidth;
   1549                 t->trimmedPrefWidths(inlineMax,
   1550                     firstLineMinWidth, hasBreakableStart, lastLineMinWidth, hasBreakableEnd,
   1551                     hasBreakableChar, hasBreak, firstLineMaxWidth, lastLineMaxWidth,
   1552                     childMin, childMax, stripFrontSpaces, styleToUse->direction());
   1553 
   1554                 // This text object will not be rendered, but it may still provide a breaking opportunity.
   1555                 if (!hasBreak && !childMax) {
   1556                     if (autoWrap && (hasBreakableStart || hasBreakableEnd)) {
   1557                         updatePreferredWidth(minLogicalWidth, inlineMin);
   1558                         inlineMin = 0;
   1559                     }
   1560                     continue;
   1561                 }
   1562 
   1563                 if (stripFrontSpaces)
   1564                     trailingSpaceChild = child;
   1565                 else
   1566                     trailingSpaceChild = 0;
   1567 
   1568                 // Add in text-indent. This is added in only once.
   1569                 float ti = 0;
   1570                 if (!addedTextIndent || hasRemainingNegativeTextIndent) {
   1571                     ti = textIndent.ceilToFloat();
   1572                     childMin += ti;
   1573                     firstLineMinWidth += ti;
   1574 
   1575                     // It the text indent negative and larger than the child minimum, we re-use the remainder
   1576                     // in future minimum calculations, but using the negative value again on the maximum
   1577                     // will lead to under-counting the max pref width.
   1578                     if (!addedTextIndent) {
   1579                         childMax += ti;
   1580                         firstLineMaxWidth += ti;
   1581                         addedTextIndent = true;
   1582                     }
   1583 
   1584                     if (childMin < 0) {
   1585                         textIndent = childMin;
   1586                         hasRemainingNegativeTextIndent = true;
   1587                     }
   1588                 }
   1589 
   1590                 // If we have no breakable characters at all,
   1591                 // then this is the easy case. We add ourselves to the current
   1592                 // min and max and continue.
   1593                 if (!hasBreakableChar) {
   1594                     inlineMin += childMin;
   1595                 } else {
   1596                     if (hasBreakableStart) {
   1597                         updatePreferredWidth(minLogicalWidth, inlineMin);
   1598                     } else {
   1599                         inlineMin += firstLineMinWidth;
   1600                         updatePreferredWidth(minLogicalWidth, inlineMin);
   1601                         childMin -= ti;
   1602                     }
   1603 
   1604                     inlineMin = childMin;
   1605 
   1606                     if (hasBreakableEnd) {
   1607                         updatePreferredWidth(minLogicalWidth, inlineMin);
   1608                         inlineMin = 0;
   1609                         shouldBreakLineAfterText = false;
   1610                     } else {
   1611                         updatePreferredWidth(minLogicalWidth, inlineMin);
   1612                         inlineMin = lastLineMinWidth;
   1613                         shouldBreakLineAfterText = true;
   1614                     }
   1615                 }
   1616 
   1617                 if (hasBreak) {
   1618                     inlineMax += firstLineMaxWidth;
   1619                     updatePreferredWidth(maxLogicalWidth, inlineMax);
   1620                     updatePreferredWidth(maxLogicalWidth, childMax);
   1621                     inlineMax = lastLineMaxWidth;
   1622                     addedTextIndent = true;
   1623                 } else {
   1624                     inlineMax += max<float>(0, childMax);
   1625                 }
   1626             }
   1627 
   1628             // Ignore spaces after a list marker.
   1629             if (child->isListMarker())
   1630                 stripFrontSpaces = true;
   1631         } else {
   1632             updatePreferredWidth(minLogicalWidth, inlineMin);
   1633             updatePreferredWidth(maxLogicalWidth, inlineMax);
   1634             inlineMin = inlineMax = 0;
   1635             stripFrontSpaces = true;
   1636             trailingSpaceChild = 0;
   1637             addedTextIndent = true;
   1638         }
   1639 
   1640         if (!child->isText() && child->isRenderInline())
   1641             isPrevChildInlineFlow = true;
   1642         else
   1643             isPrevChildInlineFlow = false;
   1644 
   1645         oldAutoWrap = autoWrap;
   1646     }
   1647 
   1648     if (styleToUse->collapseWhiteSpace())
   1649         stripTrailingSpace(inlineMax, inlineMin, trailingSpaceChild);
   1650 
   1651     updatePreferredWidth(minLogicalWidth, inlineMin);
   1652     updatePreferredWidth(maxLogicalWidth, inlineMax);
   1653 }
   1654 
   1655 void RenderBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom, LayoutUnit afterEdge)
   1656 {
   1657     RenderFlowThread* flowThread = flowThreadContainingBlock();
   1658     bool clearLinesForPagination = firstLineBox() && flowThread && !flowThread->hasRegions();
   1659 
   1660     // Figure out if we should clear out our line boxes.
   1661     // FIXME: Handle resize eventually!
   1662     bool isFullLayout = !firstLineBox() || selfNeedsLayout() || relayoutChildren || clearLinesForPagination;
   1663     LineLayoutState layoutState(isFullLayout, repaintLogicalTop, repaintLogicalBottom, flowThread);
   1664 
   1665     if (isFullLayout)
   1666         lineBoxes()->deleteLineBoxes();
   1667 
   1668     // Text truncation kicks in in two cases:
   1669     //     1) If your overflow isn't visible and your text-overflow-mode isn't clip.
   1670     //     2) If you're an anonymous block with a block parent that satisfies #1 that was created
   1671     //        to accomodate a block that has inline and block children. This excludes parents where
   1672     //        canCollapseAnonymousBlockChild is false, notabley flex items and grid items.
   1673     // FIXME: CSS3 says that descendants that are clipped must also know how to truncate.  This is insanely
   1674     // difficult to figure out in general (especially in the middle of doing layout), so we only handle the
   1675     // simple case of an anonymous block truncating when it's parent is clipped.
   1676     bool hasTextOverflow = (style()->textOverflow() && hasOverflowClip())
   1677         || (isAnonymousBlock() && parent() && parent()->isRenderBlock() && toRenderBlock(parent())->canCollapseAnonymousBlockChild()
   1678             && parent()->style()->textOverflow() && parent()->hasOverflowClip());
   1679 
   1680     // Walk all the lines and delete our ellipsis line boxes if they exist.
   1681     if (hasTextOverflow)
   1682          deleteEllipsisLineBoxes();
   1683 
   1684     if (firstChild()) {
   1685         // In full layout mode, clear the line boxes of children upfront. Otherwise,
   1686         // siblings can run into stale root lineboxes during layout. Then layout
   1687         // the replaced elements later. In partial layout mode, line boxes are not
   1688         // deleted and only dirtied. In that case, we can layout the replaced
   1689         // elements at the same time.
   1690         Vector<RenderBox*> replacedChildren;
   1691         for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) {
   1692             RenderObject* o = walker.current();
   1693 
   1694             if (!layoutState.hasInlineChild() && o->isInline())
   1695                 layoutState.setHasInlineChild(true);
   1696 
   1697             if (o->isReplaced() || o->isFloating() || o->isOutOfFlowPositioned()) {
   1698                 RenderBox* box = toRenderBox(o);
   1699 
   1700                 updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, box);
   1701 
   1702                 if (o->isOutOfFlowPositioned())
   1703                     o->containingBlock()->insertPositionedObject(box);
   1704                 else if (o->isFloating())
   1705                     layoutState.floats().append(FloatWithRect(box));
   1706                 else if (isFullLayout || o->needsLayout()) {
   1707                     // Replaced element.
   1708                     box->dirtyLineBoxes(isFullLayout);
   1709                     if (isFullLayout)
   1710                         replacedChildren.append(box);
   1711                     else
   1712                         o->layoutIfNeeded();
   1713                 }
   1714             } else if (o->isText() || (o->isRenderInline() && !walker.atEndOfInline())) {
   1715                 if (!o->isText())
   1716                     toRenderInline(o)->updateAlwaysCreateLineBoxes(layoutState.isFullLayout());
   1717                 if (layoutState.isFullLayout() || o->selfNeedsLayout())
   1718                     dirtyLineBoxesForRenderer(o, layoutState.isFullLayout());
   1719                 o->clearNeedsLayout();
   1720             }
   1721         }
   1722 
   1723         for (size_t i = 0; i < replacedChildren.size(); i++)
   1724             replacedChildren[i]->layoutIfNeeded();
   1725 
   1726         layoutRunsAndFloats(layoutState);
   1727     }
   1728 
   1729     // Expand the last line to accommodate Ruby and emphasis marks.
   1730     int lastLineAnnotationsAdjustment = 0;
   1731     if (lastRootBox()) {
   1732         LayoutUnit lowestAllowedPosition = max(lastRootBox()->lineBottom(), logicalHeight() + paddingAfter());
   1733         if (!style()->isFlippedLinesWritingMode())
   1734             lastLineAnnotationsAdjustment = lastRootBox()->computeUnderAnnotationAdjustment(lowestAllowedPosition);
   1735         else
   1736             lastLineAnnotationsAdjustment = lastRootBox()->computeOverAnnotationAdjustment(lowestAllowedPosition);
   1737     }
   1738 
   1739     // Now add in the bottom border/padding.
   1740     setLogicalHeight(logicalHeight() + lastLineAnnotationsAdjustment + afterEdge);
   1741 
   1742     if (!firstLineBox() && hasLineIfEmpty())
   1743         setLogicalHeight(logicalHeight() + lineHeight(true, isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
   1744 
   1745     // See if we have any lines that spill out of our block.  If we do, then we will possibly need to
   1746     // truncate text.
   1747     if (hasTextOverflow)
   1748         checkLinesForTextOverflow();
   1749 }
   1750 
   1751 void RenderBlockFlow::checkFloatsInCleanLine(RootInlineBox* line, Vector<FloatWithRect>& floats, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByFloat)
   1752 {
   1753     Vector<RenderBox*>* cleanLineFloats = line->floatsPtr();
   1754     if (!cleanLineFloats)
   1755         return;
   1756 
   1757     Vector<RenderBox*>::iterator end = cleanLineFloats->end();
   1758     for (Vector<RenderBox*>::iterator it = cleanLineFloats->begin(); it != end; ++it) {
   1759         RenderBox* floatingBox = *it;
   1760         floatingBox->layoutIfNeeded();
   1761         LayoutSize newSize(floatingBox->width() + floatingBox->marginWidth(), floatingBox->height() + floatingBox->marginHeight());
   1762         if (floats[floatIndex].object != floatingBox) {
   1763             encounteredNewFloat = true;
   1764             return;
   1765         }
   1766 
   1767         if (floats[floatIndex].rect.size() != newSize) {
   1768             LayoutUnit floatTop = isHorizontalWritingMode() ? floats[floatIndex].rect.y() : floats[floatIndex].rect.x();
   1769             LayoutUnit floatHeight = isHorizontalWritingMode() ? max(floats[floatIndex].rect.height(), newSize.height())
   1770                                                                  : max(floats[floatIndex].rect.width(), newSize.width());
   1771             floatHeight = min(floatHeight, LayoutUnit::max() - floatTop);
   1772             line->markDirty();
   1773             markLinesDirtyInBlockRange(line->lineBottomWithLeading(), floatTop + floatHeight, line);
   1774             floats[floatIndex].rect.setSize(newSize);
   1775             dirtiedByFloat = true;
   1776         }
   1777         floatIndex++;
   1778     }
   1779 }
   1780 
   1781 RootInlineBox* RenderBlockFlow::determineStartPosition(LineLayoutState& layoutState, InlineBidiResolver& resolver)
   1782 {
   1783     RootInlineBox* curr = 0;
   1784     RootInlineBox* last = 0;
   1785 
   1786     // FIXME: This entire float-checking block needs to be broken into a new function.
   1787     bool dirtiedByFloat = false;
   1788     if (!layoutState.isFullLayout()) {
   1789         // Paginate all of the clean lines.
   1790         bool paginated = view()->layoutState() && view()->layoutState()->isPaginated();
   1791         LayoutUnit paginationDelta = 0;
   1792         size_t floatIndex = 0;
   1793         for (curr = firstRootBox(); curr && !curr->isDirty(); curr = curr->nextRootBox()) {
   1794             if (paginated) {
   1795                 paginationDelta -= curr->paginationStrut();
   1796                 adjustLinePositionForPagination(curr, paginationDelta, layoutState.flowThread());
   1797                 if (paginationDelta) {
   1798                     if (containsFloats() || !layoutState.floats().isEmpty()) {
   1799                         // FIXME: Do better eventually.  For now if we ever shift because of pagination and floats are present just go to a full layout.
   1800                         layoutState.markForFullLayout();
   1801                         break;
   1802                     }
   1803 
   1804                     layoutState.updateRepaintRangeFromBox(curr, paginationDelta);
   1805                     curr->adjustBlockDirectionPosition(paginationDelta.toFloat());
   1806                 }
   1807             }
   1808 
   1809             // If a new float has been inserted before this line or before its last known float, just do a full layout.
   1810             bool encounteredNewFloat = false;
   1811             checkFloatsInCleanLine(curr, layoutState.floats(), floatIndex, encounteredNewFloat, dirtiedByFloat);
   1812             if (encounteredNewFloat)
   1813                 layoutState.markForFullLayout();
   1814 
   1815             if (dirtiedByFloat || layoutState.isFullLayout())
   1816                 break;
   1817         }
   1818         // Check if a new float has been inserted after the last known float.
   1819         if (!curr && floatIndex < layoutState.floats().size())
   1820             layoutState.markForFullLayout();
   1821     }
   1822 
   1823     if (layoutState.isFullLayout()) {
   1824         // If we encountered a new float and have inline children, mark ourself to force us to issue paint invalidations.
   1825         if (layoutState.hasInlineChild() && !selfNeedsLayout()) {
   1826             setNeedsLayoutAndFullPaintInvalidation(MarkOnlyThis);
   1827             if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
   1828                 setShouldDoFullPaintInvalidationAfterLayout(true);
   1829         }
   1830 
   1831         // FIXME: This should just call deleteLineBoxTree, but that causes
   1832         // crashes for fast/repaint tests.
   1833         curr = firstRootBox();
   1834         while (curr) {
   1835             // Note: This uses nextRootBox() insted of nextLineBox() like deleteLineBoxTree does.
   1836             RootInlineBox* next = curr->nextRootBox();
   1837             curr->deleteLine();
   1838             curr = next;
   1839         }
   1840         ASSERT(!firstLineBox() && !lastLineBox());
   1841     } else {
   1842         if (curr) {
   1843             // We have a dirty line.
   1844             if (RootInlineBox* prevRootBox = curr->prevRootBox()) {
   1845                 // We have a previous line.
   1846                 if (!dirtiedByFloat && (!prevRootBox->endsWithBreak() || !prevRootBox->lineBreakObj() || (prevRootBox->lineBreakObj()->isText() && prevRootBox->lineBreakPos() >= toRenderText(prevRootBox->lineBreakObj())->textLength())))
   1847                     // The previous line didn't break cleanly or broke at a newline
   1848                     // that has been deleted, so treat it as dirty too.
   1849                     curr = prevRootBox;
   1850             }
   1851         } else {
   1852             // No dirty lines were found.
   1853             // If the last line didn't break cleanly, treat it as dirty.
   1854             if (lastRootBox() && !lastRootBox()->endsWithBreak())
   1855                 curr = lastRootBox();
   1856         }
   1857 
   1858         // If we have no dirty lines, then last is just the last root box.
   1859         last = curr ? curr->prevRootBox() : lastRootBox();
   1860     }
   1861 
   1862     unsigned numCleanFloats = 0;
   1863     if (!layoutState.floats().isEmpty()) {
   1864         LayoutUnit savedLogicalHeight = logicalHeight();
   1865         // Restore floats from clean lines.
   1866         RootInlineBox* line = firstRootBox();
   1867         while (line != curr) {
   1868             if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) {
   1869                 Vector<RenderBox*>::iterator end = cleanLineFloats->end();
   1870                 for (Vector<RenderBox*>::iterator f = cleanLineFloats->begin(); f != end; ++f) {
   1871                     FloatingObject* floatingObject = insertFloatingObject(*f);
   1872                     ASSERT(!floatingObject->originatingLine());
   1873                     floatingObject->setOriginatingLine(line);
   1874                     setLogicalHeight(logicalTopForChild(*f) - marginBeforeForChild(*f));
   1875                     positionNewFloats();
   1876                     ASSERT(layoutState.floats()[numCleanFloats].object == *f);
   1877                     numCleanFloats++;
   1878                 }
   1879             }
   1880             line = line->nextRootBox();
   1881         }
   1882         setLogicalHeight(savedLogicalHeight);
   1883     }
   1884     layoutState.setFloatIndex(numCleanFloats);
   1885 
   1886     layoutState.lineInfo().setFirstLine(!last);
   1887     layoutState.lineInfo().setPreviousLineBrokeCleanly(!last || last->endsWithBreak());
   1888 
   1889     if (last) {
   1890         setLogicalHeight(last->lineBottomWithLeading());
   1891         InlineIterator iter = InlineIterator(this, last->lineBreakObj(), last->lineBreakPos());
   1892         resolver.setPosition(iter, numberOfIsolateAncestors(iter));
   1893         resolver.setStatus(last->lineBreakBidiStatus());
   1894     } else {
   1895         TextDirection direction = style()->direction();
   1896         if (style()->unicodeBidi() == Plaintext)
   1897             direction = determinePlaintextDirectionality(this);
   1898         resolver.setStatus(BidiStatus(direction, isOverride(style()->unicodeBidi())));
   1899         InlineIterator iter = InlineIterator(this, bidiFirstSkippingEmptyInlines(this, &resolver), 0);
   1900         resolver.setPosition(iter, numberOfIsolateAncestors(iter));
   1901     }
   1902     return curr;
   1903 }
   1904 
   1905 void RenderBlockFlow::determineEndPosition(LineLayoutState& layoutState, RootInlineBox* startLine, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus)
   1906 {
   1907     ASSERT(!layoutState.endLine());
   1908     size_t floatIndex = layoutState.floatIndex();
   1909     RootInlineBox* last = 0;
   1910     for (RootInlineBox* curr = startLine->nextRootBox(); curr; curr = curr->nextRootBox()) {
   1911         if (!curr->isDirty()) {
   1912             bool encounteredNewFloat = false;
   1913             bool dirtiedByFloat = false;
   1914             checkFloatsInCleanLine(curr, layoutState.floats(), floatIndex, encounteredNewFloat, dirtiedByFloat);
   1915             if (encounteredNewFloat)
   1916                 return;
   1917         }
   1918         if (curr->isDirty())
   1919             last = 0;
   1920         else if (!last)
   1921             last = curr;
   1922     }
   1923 
   1924     if (!last)
   1925         return;
   1926 
   1927     // At this point, |last| is the first line in a run of clean lines that ends with the last line
   1928     // in the block.
   1929 
   1930     RootInlineBox* prev = last->prevRootBox();
   1931     cleanLineStart = InlineIterator(this, prev->lineBreakObj(), prev->lineBreakPos());
   1932     cleanLineBidiStatus = prev->lineBreakBidiStatus();
   1933     layoutState.setEndLineLogicalTop(prev->lineBottomWithLeading());
   1934 
   1935     for (RootInlineBox* line = last; line; line = line->nextRootBox())
   1936         line->extractLine(); // Disconnect all line boxes from their render objects while preserving
   1937                              // their connections to one another.
   1938 
   1939     layoutState.setEndLine(last);
   1940 }
   1941 
   1942 bool RenderBlockFlow::checkPaginationAndFloatsAtEndLine(LineLayoutState& layoutState)
   1943 {
   1944     LayoutUnit lineDelta = logicalHeight() - layoutState.endLineLogicalTop();
   1945 
   1946     bool paginated = view()->layoutState() && view()->layoutState()->isPaginated();
   1947     if (paginated && layoutState.flowThread()) {
   1948         // Check all lines from here to the end, and see if the hypothetical new position for the lines will result
   1949         // in a different available line width.
   1950         for (RootInlineBox* lineBox = layoutState.endLine(); lineBox; lineBox = lineBox->nextRootBox()) {
   1951             if (paginated) {
   1952                 // This isn't the real move we're going to do, so don't update the line box's pagination
   1953                 // strut yet.
   1954                 LayoutUnit oldPaginationStrut = lineBox->paginationStrut();
   1955                 lineDelta -= oldPaginationStrut;
   1956                 adjustLinePositionForPagination(lineBox, lineDelta, layoutState.flowThread());
   1957                 lineBox->setPaginationStrut(oldPaginationStrut);
   1958             }
   1959         }
   1960     }
   1961 
   1962     if (!lineDelta || !m_floatingObjects)
   1963         return true;
   1964 
   1965     // See if any floats end in the range along which we want to shift the lines vertically.
   1966     LayoutUnit logicalTop = min(logicalHeight(), layoutState.endLineLogicalTop());
   1967 
   1968     RootInlineBox* lastLine = layoutState.endLine();
   1969     while (RootInlineBox* nextLine = lastLine->nextRootBox())
   1970         lastLine = nextLine;
   1971 
   1972     LayoutUnit logicalBottom = lastLine->lineBottomWithLeading() + absoluteValue(lineDelta);
   1973 
   1974     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   1975     FloatingObjectSetIterator end = floatingObjectSet.end();
   1976     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   1977         FloatingObject* floatingObject = it->get();
   1978         if (logicalBottomForFloat(floatingObject) >= logicalTop && logicalBottomForFloat(floatingObject) < logicalBottom)
   1979             return false;
   1980     }
   1981 
   1982     return true;
   1983 }
   1984 
   1985 bool RenderBlockFlow::matchedEndLine(LineLayoutState& layoutState, const InlineBidiResolver& resolver, const InlineIterator& endLineStart, const BidiStatus& endLineStatus)
   1986 {
   1987     if (resolver.position() == endLineStart) {
   1988         if (resolver.status() != endLineStatus)
   1989             return false;
   1990         return checkPaginationAndFloatsAtEndLine(layoutState);
   1991     }
   1992 
   1993     // The first clean line doesn't match, but we can check a handful of following lines to try
   1994     // to match back up.
   1995     static int numLines = 8; // The # of lines we're willing to match against.
   1996     RootInlineBox* originalEndLine = layoutState.endLine();
   1997     RootInlineBox* line = originalEndLine;
   1998     for (int i = 0; i < numLines && line; i++, line = line->nextRootBox()) {
   1999         if (line->lineBreakObj() == resolver.position().object() && line->lineBreakPos() == resolver.position().offset()) {
   2000             // We have a match.
   2001             if (line->lineBreakBidiStatus() != resolver.status())
   2002                 return false; // ...but the bidi state doesn't match.
   2003 
   2004             bool matched = false;
   2005             RootInlineBox* result = line->nextRootBox();
   2006             layoutState.setEndLine(result);
   2007             if (result) {
   2008                 layoutState.setEndLineLogicalTop(line->lineBottomWithLeading());
   2009                 matched = checkPaginationAndFloatsAtEndLine(layoutState);
   2010             }
   2011 
   2012             // Now delete the lines that we failed to sync.
   2013             deleteLineRange(layoutState, originalEndLine, result);
   2014             return matched;
   2015         }
   2016     }
   2017 
   2018     return false;
   2019 }
   2020 
   2021 bool RenderBlockFlow::generatesLineBoxesForInlineChild(RenderObject* inlineObj)
   2022 
   2023 {
   2024     ASSERT(inlineObj->parent() == this);
   2025 
   2026     InlineIterator it(this, inlineObj, 0);
   2027     // FIXME: We should pass correct value for WhitespacePosition.
   2028     while (!it.atEnd() && !requiresLineBox(it))
   2029         it.increment();
   2030 
   2031     return !it.atEnd();
   2032 }
   2033 
   2034 
   2035 void RenderBlockFlow::addOverflowFromInlineChildren()
   2036 {
   2037     LayoutUnit endPadding = hasOverflowClip() ? paddingEnd() : LayoutUnit();
   2038     // FIXME: Need to find another way to do this, since scrollbars could show when we don't want them to.
   2039     if (hasOverflowClip() && !endPadding && node() && node()->isRootEditableElement() && style()->isLeftToRightDirection())
   2040         endPadding = 1;
   2041     for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
   2042         addLayoutOverflow(curr->paddedLayoutOverflowRect(endPadding));
   2043         LayoutRect visualOverflow = curr->visualOverflowRect(curr->lineTop(), curr->lineBottom());
   2044         addContentsVisualOverflow(visualOverflow);
   2045     }
   2046 }
   2047 
   2048 void RenderBlockFlow::deleteEllipsisLineBoxes()
   2049 {
   2050     ETextAlign textAlign = style()->textAlign();
   2051     bool ltr = style()->isLeftToRightDirection();
   2052     bool firstLine = true;
   2053     for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
   2054         if (curr->hasEllipsisBox()) {
   2055             curr->clearTruncation();
   2056 
   2057             // Shift the line back where it belongs if we cannot accomodate an ellipsis.
   2058             float logicalLeft = logicalLeftOffsetForLine(curr->lineTop(), firstLine).toFloat();
   2059             float availableLogicalWidth = logicalRightOffsetForLine(curr->lineTop(), false) - logicalLeft;
   2060             float totalLogicalWidth = curr->logicalWidth();
   2061             updateLogicalWidthForAlignment(textAlign, curr, 0, logicalLeft, totalLogicalWidth, availableLogicalWidth, 0);
   2062 
   2063             if (ltr)
   2064                 curr->adjustLogicalPosition((logicalLeft - curr->logicalLeft()), 0);
   2065             else
   2066                 curr->adjustLogicalPosition(-(curr->logicalLeft() - logicalLeft), 0);
   2067         }
   2068         firstLine = false;
   2069     }
   2070 }
   2071 
   2072 void RenderBlockFlow::checkLinesForTextOverflow()
   2073 {
   2074     // Determine the width of the ellipsis using the current font.
   2075     // FIXME: CSS3 says this is configurable, also need to use 0x002E (FULL STOP) if horizontal ellipsis is "not renderable"
   2076     const Font& font = style()->font();
   2077     DEFINE_STATIC_LOCAL(AtomicString, ellipsisStr, (&horizontalEllipsis, 1));
   2078     const Font& firstLineFont = firstLineStyle()->font();
   2079     // FIXME: We should probably not hard-code the direction here. https://crbug.com/333004
   2080     TextDirection ellipsisDirection = LTR;
   2081     float firstLineEllipsisWidth = firstLineFont.width(constructTextRun(this, firstLineFont, &horizontalEllipsis, 1, firstLineStyle(), ellipsisDirection));
   2082     float ellipsisWidth = (font == firstLineFont) ? firstLineEllipsisWidth : font.width(constructTextRun(this, font, &horizontalEllipsis, 1, style(), ellipsisDirection));
   2083 
   2084     // For LTR text truncation, we want to get the right edge of our padding box, and then we want to see
   2085     // if the right edge of a line box exceeds that.  For RTL, we use the left edge of the padding box and
   2086     // check the left edge of the line box to see if it is less
   2087     // Include the scrollbar for overflow blocks, which means we want to use "contentWidth()"
   2088     bool ltr = style()->isLeftToRightDirection();
   2089     ETextAlign textAlign = style()->textAlign();
   2090     bool firstLine = true;
   2091     for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
   2092         float currLogicalLeft = curr->logicalLeft();
   2093         LayoutUnit blockRightEdge = logicalRightOffsetForLine(curr->lineTop(), firstLine);
   2094         LayoutUnit blockLeftEdge = logicalLeftOffsetForLine(curr->lineTop(), firstLine);
   2095         LayoutUnit lineBoxEdge = ltr ? currLogicalLeft + curr->logicalWidth() : currLogicalLeft;
   2096         if ((ltr && lineBoxEdge > blockRightEdge) || (!ltr && lineBoxEdge < blockLeftEdge)) {
   2097             // This line spills out of our box in the appropriate direction.  Now we need to see if the line
   2098             // can be truncated.  In order for truncation to be possible, the line must have sufficient space to
   2099             // accommodate our truncation string, and no replaced elements (images, tables) can overlap the ellipsis
   2100             // space.
   2101 
   2102             LayoutUnit width = firstLine ? firstLineEllipsisWidth : ellipsisWidth;
   2103             LayoutUnit blockEdge = ltr ? blockRightEdge : blockLeftEdge;
   2104             if (curr->lineCanAccommodateEllipsis(ltr, blockEdge, lineBoxEdge, width)) {
   2105                 float totalLogicalWidth = curr->placeEllipsis(ellipsisStr, ltr, blockLeftEdge.toFloat(), blockRightEdge.toFloat(), width.toFloat());
   2106 
   2107                 float logicalLeft = 0; // We are only intersted in the delta from the base position.
   2108                 float availableLogicalWidth = (blockRightEdge - blockLeftEdge).toFloat();
   2109                 updateLogicalWidthForAlignment(textAlign, curr, 0, logicalLeft, totalLogicalWidth, availableLogicalWidth, 0);
   2110                 if (ltr)
   2111                     curr->adjustLogicalPosition(logicalLeft, 0);
   2112                 else
   2113                     curr->adjustLogicalPosition(logicalLeft - (availableLogicalWidth - totalLogicalWidth), 0);
   2114             }
   2115         }
   2116         firstLine = false;
   2117     }
   2118 }
   2119 
   2120 bool RenderBlockFlow::positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine, LineInfo& lineInfo, LineWidth& width)
   2121 {
   2122     if (!positionNewFloats())
   2123         return false;
   2124 
   2125     width.shrinkAvailableWidthForNewFloatIfNeeded(newFloat);
   2126 
   2127     // We only connect floats to lines for pagination purposes if the floats occur at the start of
   2128     // the line and the previous line had a hard break (so this line is either the first in the block
   2129     // or follows a <br>).
   2130     if (!newFloat->paginationStrut() || !lineInfo.previousLineBrokeCleanly() || !lineInfo.isEmpty())
   2131         return true;
   2132 
   2133     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   2134     ASSERT(floatingObjectSet.last() == newFloat);
   2135 
   2136     LayoutUnit floatLogicalTop = logicalTopForFloat(newFloat);
   2137     int paginationStrut = newFloat->paginationStrut();
   2138 
   2139     if (floatLogicalTop - paginationStrut != logicalHeight() + lineInfo.floatPaginationStrut())
   2140         return true;
   2141 
   2142     FloatingObjectSetIterator it = floatingObjectSet.end();
   2143     --it; // Last float is newFloat, skip that one.
   2144     FloatingObjectSetIterator begin = floatingObjectSet.begin();
   2145     while (it != begin) {
   2146         --it;
   2147         FloatingObject* floatingObject = it->get();
   2148         if (floatingObject == lastFloatFromPreviousLine)
   2149             break;
   2150         if (logicalTopForFloat(floatingObject) == logicalHeight() + lineInfo.floatPaginationStrut()) {
   2151             floatingObject->setPaginationStrut(paginationStrut + floatingObject->paginationStrut());
   2152             RenderBox* floatBox = floatingObject->renderer();
   2153             setLogicalTopForChild(floatBox, logicalTopForChild(floatBox) + marginBeforeForChild(floatBox) + paginationStrut);
   2154             if (floatBox->isRenderBlock())
   2155                 floatBox->forceChildLayout();
   2156             else
   2157                 floatBox->layoutIfNeeded();
   2158             // Save the old logical top before calling removePlacedObject which will set
   2159             // isPlaced to false. Otherwise it will trigger an assert in logicalTopForFloat.
   2160             LayoutUnit oldLogicalTop = logicalTopForFloat(floatingObject);
   2161             m_floatingObjects->removePlacedObject(floatingObject);
   2162             setLogicalTopForFloat(floatingObject, oldLogicalTop + paginationStrut);
   2163             m_floatingObjects->addPlacedObject(floatingObject);
   2164         }
   2165     }
   2166 
   2167     // Just update the line info's pagination strut without altering our logical height yet. If the line ends up containing
   2168     // no content, then we don't want to improperly grow the height of the block.
   2169     lineInfo.setFloatPaginationStrut(lineInfo.floatPaginationStrut() + paginationStrut);
   2170     return true;
   2171 }
   2172 
   2173 LayoutUnit RenderBlockFlow::startAlignedOffsetForLine(LayoutUnit position, bool firstLine)
   2174 {
   2175     ETextAlign textAlign = style()->textAlign();
   2176 
   2177     if (textAlign == TASTART) // FIXME: Handle TAEND here
   2178         return startOffsetForLine(position, firstLine);
   2179 
   2180     // updateLogicalWidthForAlignment() handles the direction of the block so no need to consider it here
   2181     float totalLogicalWidth = 0;
   2182     float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false).toFloat();
   2183     float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), false) - logicalLeft;
   2184     updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWidth, availableLogicalWidth, 0);
   2185 
   2186     if (!style()->isLeftToRightDirection())
   2187         return logicalWidth() - logicalLeft;
   2188     return logicalLeft;
   2189 }
   2190 
   2191 }
   2192