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