15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All right reserved.
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2010 Google Inc. All rights reserved.
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
25a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#include "core/accessibility/AXObjectCache.h"
26c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/rendering/BidiRunForLine.h"
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderCounter.h"
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderFlowThread.h"
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderLayer.h"
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderListMarker.h"
31197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/rendering/RenderObjectInlines.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderRegion.h"
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderRubyRun.h"
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderView.h"
35c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/rendering/TextRunConstructor.h"
3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/TrailingFloatsRootInlineBox.h"
3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/VerticalPositionCache.h"
3851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/rendering/line/BreakingContextInlineHeaders.h"
3909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/rendering/line/LineLayoutState.h"
4009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/rendering/line/LineWidth.h"
415d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/rendering/line/RenderTextInfo.h"
425d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/rendering/line/WordMeasurement.h"
4393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "core/rendering/svg/SVGRootInlineBox.h"
4409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/fonts/Character.h"
451e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/text/BidiResolver.h"
4602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "wtf/RefCountedLeakCounter.h"
4702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "wtf/StdLibExtras.h"
4802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "wtf/Vector.h"
4902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "wtf/unicode/CharacterNames.h"
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
51c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)using namespace WTF::Unicode;
541e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline InlineBox* createInlineBoxForRenderer(RenderObject* obj, bool isRootLineBox, bool isOnlyRun = false)
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isRootLineBox)
5809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return toRenderBlockFlow(obj)->createAndAppendRootInlineBox();
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (obj->isText()) {
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        InlineTextBox* textBox = toRenderText(obj)->createInlineTextBox();
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // We only treat a box as text for a <br> if we are on a line by ourself or in strict mode
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // (Note the use of strict mode.  In "almost strict" mode, we don't treat the box for <br> as text.)
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (obj->isBR())
658abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            textBox->setIsText(isOnlyRun || obj->document().inNoQuirksMode());
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return textBox;
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (obj->isBox())
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return toRenderBox(obj)->createInlineBox();
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return toRenderInline(obj)->createAndAppendInlineFlowBox();
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline void dirtyLineBoxesForRenderer(RenderObject* o, bool fullLayout)
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (o->isText()) {
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderText* renderText = toRenderText(o);
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        renderText->dirtyLineBoxes(fullLayout);
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        toRenderInline(o)->dirtyLineBoxes(fullLayout);
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool parentIsConstructedOrHaveNext(InlineFlowBox* parentBox)
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    do {
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (parentBox->isConstructed() || parentBox->nextOnLine())
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return true;
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        parentBox = parentBox->parent();
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } while (parentBox);
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9410f88d5669dbd969c059d61ba09fa37dd72ac559Ben MurdochInlineFlowBox* RenderBlockFlow::createLineBoxes(RenderObject* obj, const LineInfo& lineInfo, InlineBox* childBox)
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // See if we have an unconstructed line box for this object that is also
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // the last item on the line.
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned lineDepth = 1;
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InlineFlowBox* parentBox = 0;
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InlineFlowBox* result = 0;
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool hasDefaultLineBoxContain = style()->lineBoxContain() == RenderStyle::initialLineBoxContain();
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    do {
103926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        ASSERT_WITH_SECURITY_IMPLICATION(obj->isRenderInline() || obj == this);
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderInline* inlineFlow = (obj != this) ? toRenderInline(obj) : 0;
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Get the last box we made for this render object.
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        parentBox = inlineFlow ? inlineFlow->lastLineBox() : toRenderBlock(obj)->lastLineBox();
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If this box or its ancestor is constructed then it is from a previous line, and we need
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // to make a new box for our line.  If this box or its ancestor is unconstructed but it has
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // something following it on the line, then we know we have to make a new box
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // as well.  In this situation our inline has actually been split in two on
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // the same line (this can happen with very fancy language mixtures).
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool constructedNewBox = false;
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool allowedToConstructNewBox = !hasDefaultLineBoxContain || !inlineFlow || inlineFlow->alwaysCreateLineBoxes();
11710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        bool canUseExistingParentBox = parentBox && !parentIsConstructedOrHaveNext(parentBox);
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (allowedToConstructNewBox && !canUseExistingParentBox) {
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // We need to make a new box for this render object.  Once
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // made, we need to place it at the end of the current line.
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            InlineBox* newBox = createInlineBoxForRenderer(obj, obj == this);
122926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            ASSERT_WITH_SECURITY_IMPLICATION(newBox->isInlineFlowBox());
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            parentBox = toInlineFlowBox(newBox);
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            parentBox->setFirstLineStyleBit(lineInfo.isFirstLine());
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            parentBox->setIsHorizontal(isHorizontalWritingMode());
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!hasDefaultLineBoxContain)
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                parentBox->clearDescendantsHaveSameLineHeightAndBaseline();
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            constructedNewBox = true;
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (constructedNewBox || canUseExistingParentBox) {
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!result)
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                result = parentBox;
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // If we have hit the block itself, then |box| represents the root
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // inline box for the line, and it doesn't have to be appended to any parent
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // inline.
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (childBox)
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                parentBox->addToLine(childBox);
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!constructedNewBox || obj == this)
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            childBox = parentBox;
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If we've exceeded our line depth, then jump straight to the root and skip all the remaining
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // intermediate inline flows.
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        obj = (++lineDepth >= cMaxLineDepth) ? this : obj->parent();
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } while (true);
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result;
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <typename CharacterType>
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline bool endsWithASCIISpaces(const CharacterType* characters, unsigned pos, unsigned end)
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (isASCIISpace(characters[pos])) {
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        pos++;
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (pos >= end)
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return true;
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool reachedEndOfTextRenderer(const BidiRunList<BidiRun>& bidiRuns)
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    BidiRun* run = bidiRuns.logicallyLastRun();
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!run)
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned pos = run->stop();
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* r = run->m_object;
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!r->isText() || r->isBR())
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderText* renderText = toRenderText(r);
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned length = renderText->textLength();
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (pos >= length)
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (renderText->is8Bit())
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return endsWithASCIISpaces(renderText->characters8(), pos, length);
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return endsWithASCIISpaces(renderText->characters16(), pos, length);
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
186f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)RootInlineBox* RenderBlockFlow::constructLine(BidiRunList<BidiRun>& bidiRuns, const LineInfo& lineInfo)
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(bidiRuns.firstRun());
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool rootHasSelectedChildren = false;
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InlineFlowBox* parentBox = 0;
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int runCount = bidiRuns.runCount() - lineInfo.runsFromLeadingWhitespace();
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (BidiRun* r = bidiRuns.firstRun(); r; r = r->next()) {
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Create a box for our object.
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool isOnlyRun = (runCount == 1);
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (runCount == 2 && !r->m_object->isListMarker())
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            isOnlyRun = (!style()->isLeftToRightDirection() ? bidiRuns.lastRun() : bidiRuns.firstRun())->m_object->isListMarker();
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (lineInfo.isEmpty())
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        InlineBox* box = createInlineBoxForRenderer(r->m_object, false, isOnlyRun);
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        r->m_box = box;
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(box);
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!box)
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
209d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (!rootHasSelectedChildren && box->renderer().selectionState() != RenderObject::SelectionNone)
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            rootHasSelectedChildren = true;
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If we have no parent box yet, or if the run is not simply a sibling,
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // then we need to construct inline boxes as necessary to properly enclose the
214926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // run's inline box. Segments can only be siblings at the root level, as
215926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // they are positioned separately.
21610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        if (!parentBox || parentBox->renderer() != r->m_object->parent()) {
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Create new inline boxes all the way back to the appropriate insertion point.
21810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            parentBox = createLineBoxes(r->m_object->parent(), lineInfo, box);
21910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        } else {
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Append the inline box to this line.
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            parentBox->addToLine(box);
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool visuallyOrdered = r->m_object->style()->rtlOrdering() == VisualOrder;
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        box->setBidiLevel(r->level());
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (box->isInlineTextBox()) {
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            InlineTextBox* text = toInlineTextBox(box);
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            text->setStart(r->m_start);
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            text->setLen(r->m_stop - r->m_start);
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            text->setDirOverride(r->dirOverride(visuallyOrdered));
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (r->m_hasHyphen)
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                text->setHasHyphen(true);
234a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
235a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            if (AXObjectCache* cache = document().existingAXObjectCache())
236a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                cache->inlineTextBoxesUpdated(r->m_object);
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We should have a root inline box.  It should be unconstructed and
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // be the last continuation of our line list.
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(lastLineBox() && !lastLineBox()->isConstructed());
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Set the m_selectedChildren flag on the root inline box if one of the leaf inline box
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // from the bidi runs walk above has a selection state.
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (rootHasSelectedChildren)
247d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        lastLineBox()->root().setHasSelectedChildren(true);
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Set bits on our inline flow boxes that indicate which sides should
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // paint borders/margins/padding.  This knowledge will ultimately be used when
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // we determine the horizontal positions and widths of all the inline boxes on
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // the line.
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isLogicallyLastRunWrapped = bidiRuns.logicallyLastRun()->m_object && bidiRuns.logicallyLastRun()->m_object->isText() ? !reachedEndOfTextRenderer(bidiRuns) : true;
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    lastLineBox()->determineSpacingForFlowBoxes(lineInfo.isLastLine(), isLogicallyLastRunWrapped, bidiRuns.logicallyLastRun()->m_object);
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Now mark the line boxes as being constructed.
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    lastLineBox()->setConstructed();
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Return the last line.
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return lastRootBox();
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
263a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)ETextAlign RenderBlockFlow::textAlignmentForLine(bool endsWithSoftBreak) const
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ETextAlign alignment = style()->textAlign();
26619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    if (endsWithSoftBreak)
26719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        return alignment;
26819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
26919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    if (!RuntimeEnabledFeatures::css3TextEnabled())
27019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        return (alignment == JUSTIFY) ? TASTART : alignment;
27119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
272c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (alignment != JUSTIFY)
273c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return alignment;
274c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
27519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    TextAlignLast alignmentLast = style()->textAlignLast();
27619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    switch (alignmentLast) {
27719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    case TextAlignLastStart:
27819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        return TASTART;
27919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    case TextAlignLastEnd:
28019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        return TAEND;
28119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    case TextAlignLastLeft:
28219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        return LEFT;
28319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    case TextAlignLastRight:
28419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        return RIGHT;
28519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    case TextAlignLastCenter:
28619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        return CENTER;
28719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    case TextAlignLastJustify:
28819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        return JUSTIFY;
28919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    case TextAlignLastAuto:
29019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        if (style()->textJustify() == TextJustifyDistribute)
29119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            return JUSTIFY;
29219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        return TASTART;
29319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    }
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return alignment;
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void updateLogicalWidthForLeftAlignedBlock(bool isLeftToRightDirection, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float availableLogicalWidth)
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The direction of the block should determine what happens with wide lines.
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // In particular with RTL blocks, wide lines should still spill out to the left.
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isLeftToRightDirection) {
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun)
304197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            trailingSpaceRun->m_box->setLogicalWidth(std::max<float>(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (trailingSpaceRun)
3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        trailingSpaceRun->m_box->setLogicalWidth(0);
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else if (totalLogicalWidth > availableLogicalWidth)
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        logicalLeft -= (totalLogicalWidth - availableLogicalWidth);
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void updateLogicalWidthForRightAlignedBlock(bool isLeftToRightDirection, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float availableLogicalWidth)
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Wide lines spill out of the block based off direction.
3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // So even if text-align is right, if direction is LTR, wide lines should overflow out of the right
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // side of the block.
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isLeftToRightDirection) {
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (trailingSpaceRun) {
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            trailingSpaceRun->m_box->setLogicalWidth(0);
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (totalLogicalWidth < availableLogicalWidth)
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            logicalLeft += availableLogicalWidth - totalLogicalWidth;
3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun) {
330197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        trailingSpaceRun->m_box->setLogicalWidth(std::max<float>(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        logicalLeft += availableLogicalWidth - totalLogicalWidth;
3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void updateLogicalWidthForCenterAlignedBlock(bool isLeftToRightDirection, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float availableLogicalWidth)
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float trailingSpaceWidth = 0;
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (trailingSpaceRun) {
3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
341197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        trailingSpaceWidth = std::min(trailingSpaceRun->m_box->logicalWidth(), (availableLogicalWidth - totalLogicalWidth + 1) / 2);
342197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        trailingSpaceRun->m_box->setLogicalWidth(std::max<float>(0, trailingSpaceWidth));
3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isLeftToRightDirection)
345197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        logicalLeft += std::max<float>((availableLogicalWidth - totalLogicalWidth) / 2, 0);
3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        logicalLeft += totalLogicalWidth > availableLogicalWidth ? (availableLogicalWidth - totalLogicalWidth) : (availableLogicalWidth - totalLogicalWidth) / 2 - trailingSpaceWidth;
3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
350f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void RenderBlockFlow::setMarginsForRubyRun(BidiRun* run, RenderRubyRun* renderer, RenderObject* previousObject, const LineInfo& lineInfo)
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int startOverhang;
3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int endOverhang;
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* nextObject = 0;
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (BidiRun* runWithNextObject = run->next(); runWithNextObject; runWithNextObject = runWithNextObject->next()) {
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!runWithNextObject->m_object->isOutOfFlowPositioned() && !runWithNextObject->m_box->isLineBreak()) {
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            nextObject = runWithNextObject->m_object;
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    renderer->getOverhang(lineInfo.isFirstLine(), renderer->style()->isLeftToRightDirection() ? previousObject : nextObject, renderer->style()->isLeftToRightDirection() ? nextObject : previousObject, startOverhang, endOverhang);
3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setMarginStartForChild(renderer, -startOverhang);
3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setMarginEndForChild(renderer, -endOverhang);
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* run, RenderText* renderer, float xPos, const LineInfo& lineInfo,
3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                             GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache, WordMeasurements& wordMeasurements)
3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HashSet<const SimpleFontData*> fallbackFonts;
3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    GlyphOverflow glyphOverflow;
37102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Font& font = renderer->style(lineInfo.isFirstLine())->font();
3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Always compute glyph overflow if the block's line-box-contain value is "glyphs".
3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (lineBox->fitsToGlyphs()) {
3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If we don't stick out of the root line's font box, then don't bother computing our glyph overflow. This optimization
3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // will keep us from computing glyph bounds in nearly all cases.
3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool includeRootLine = lineBox->includesRootLineBoxFontOrLeading();
3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int baselineShift = lineBox->verticalPositionForBox(run->m_box, verticalPositionCache);
3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int rootDescent = includeRootLine ? font.fontMetrics().descent() : 0;
3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int rootAscent = includeRootLine ? font.fontMetrics().ascent() : 0;
3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int boxAscent = font.fontMetrics().ascent() - baselineShift;
3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int boxDescent = font.fontMetrics().descent() + baselineShift;
3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (boxAscent > rootDescent ||  boxDescent > rootAscent)
38402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch            glyphOverflow.computeBounds = true;
3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
38602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit hyphenWidth = 0;
3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (toInlineTextBox(run->m_box)->hasHyphen()) {
3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const Font& font = renderer->style(lineInfo.isFirstLine())->font();
39009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        hyphenWidth = measureHyphenWidth(renderer, font, run->direction());
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float measuredWidth = 0;
3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
39409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    bool kerningIsEnabled = font.fontDescription().typesettingFeatures() & Kerning;
39553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
3968abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#if OS(MACOSX)
39753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // FIXME: Having any font feature settings enabled can lead to selection gaps on
39853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // Chromium-mac. https://bugs.webkit.org/show_bug.cgi?id=113418
39953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    bool canUseSimpleFontCodePath = renderer->canUseSimpleFontCodePath() && !font.fontDescription().featureSettings();
40053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#else
40153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    bool canUseSimpleFontCodePath = renderer->canUseSimpleFontCodePath();
40253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#endif
40302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Since we don't cache glyph overflows, we need to re-measure the run if
4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // the style is linebox-contain: glyph.
40602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
40753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!lineBox->fitsToGlyphs() && canUseSimpleFontCodePath) {
4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int lastEndOffset = run->m_start;
4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (size_t i = 0, size = wordMeasurements.size(); i < size && lastEndOffset < run->m_stop; ++i) {
4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            const WordMeasurement& wordMeasurement = wordMeasurements[i];
4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (wordMeasurement.width <=0 || wordMeasurement.startOffset == wordMeasurement.endOffset)
4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (wordMeasurement.renderer != renderer || wordMeasurement.startOffset != lastEndOffset || wordMeasurement.endOffset > run->m_stop)
4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            lastEndOffset = wordMeasurement.endOffset;
4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (kerningIsEnabled && lastEndOffset == run->m_stop) {
418926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                int wordLength = lastEndOffset - wordMeasurement.startOffset;
41909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                measuredWidth += renderer->width(wordMeasurement.startOffset, wordLength, xPos, run->direction(), lineInfo.isFirstLine());
420926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (i > 0 && wordLength == 1 && renderer->characterAt(wordMeasurement.startOffset) == ' ')
4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    measuredWidth += renderer->style()->wordSpacing();
4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            } else
4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                measuredWidth += wordMeasurement.width;
4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!wordMeasurement.fallbackFonts.isEmpty()) {
4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                HashSet<const SimpleFontData*>::const_iterator end = wordMeasurement.fallbackFonts.end();
4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                for (HashSet<const SimpleFontData*>::const_iterator it = wordMeasurement.fallbackFonts.begin(); it != end; ++it)
4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    fallbackFonts.add(*it);
4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (measuredWidth && lastEndOffset != run->m_stop) {
4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // If we don't have enough cached data, we'll measure the run again.
4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            measuredWidth = 0;
4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            fallbackFonts.clear();
4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!measuredWidth)
43809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        measuredWidth = renderer->width(run->m_start, run->m_stop - run->m_start, xPos, run->direction(), lineInfo.isFirstLine(), &fallbackFonts, &glyphOverflow);
4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    run->m_box->setLogicalWidth(measuredWidth + hyphenWidth);
4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!fallbackFonts.isEmpty()) {
4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(run->m_box->isText());
443197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        GlyphOverflowAndFallbackFontsMap::ValueType* it = textBoxDataMap.add(toInlineTextBox(run->m_box), std::make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).storedValue;
4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(it->value.first.isEmpty());
4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        copyToVector(fallbackFonts, it->value.first);
4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        run->m_box->parent()->clearDescendantsHaveSameLineHeightAndBaseline();
4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
448c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!glyphOverflow.isZero()) {
4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(run->m_box->isText());
450197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        GlyphOverflowAndFallbackFontsMap::ValueType* it = textBoxDataMap.add(toInlineTextBox(run->m_box), std::make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).storedValue;
4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        it->value.second = glyphOverflow;
4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        run->m_box->clearKnownToHaveNoOverflow();
4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline void computeExpansionForJustifiedText(BidiRun* firstRun, BidiRun* trailingSpaceRun, Vector<unsigned, 16>& expansionOpportunities, unsigned expansionOpportunityCount, float& totalLogicalWidth, float availableLogicalWidth)
4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!expansionOpportunityCount || availableLogicalWidth <= totalLogicalWidth)
4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t i = 0;
4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (BidiRun* r = firstRun; r; r = r->next()) {
4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!r->m_box || r == trailingSpaceRun)
4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
46502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (r->m_object->isText()) {
4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            unsigned opportunitiesInRun = expansionOpportunities[i++];
46802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(opportunitiesInRun <= expansionOpportunityCount);
47002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
471d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            // Don't justify for white-space: pre.
472d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            if (r->m_object->style()->whiteSpace() != PRE) {
4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                InlineTextBox* textBox = toInlineTextBox(r->m_box);
4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                int expansion = (availableLogicalWidth - totalLogicalWidth) * opportunitiesInRun / expansionOpportunityCount;
4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                textBox->setExpansion(expansion);
4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                totalLogicalWidth += expansion;
4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            expansionOpportunityCount -= opportunitiesInRun;
4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!expansionOpportunityCount)
4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
485f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liuvoid RenderBlockFlow::updateLogicalWidthForAlignment(const ETextAlign& textAlign, const RootInlineBox* rootInlineBox, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, unsigned expansionOpportunityCount)
4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4878abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    TextDirection direction;
488d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (rootInlineBox && rootInlineBox->renderer().style()->unicodeBidi() == Plaintext)
4898abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        direction = rootInlineBox->direction();
4908abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    else
4918abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        direction = style()->direction();
4928abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Armed with the total width of the line (without justification),
4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // we now examine our text-align property in order to determine where to position the
4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // objects horizontally. The total width of the line can be increased if we end up
4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // justifying text.
4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (textAlign) {
4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case LEFT:
4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case WEBKIT_LEFT:
5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case RIGHT:
5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case WEBKIT_RIGHT:
5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        updateLogicalWidthForRightAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CENTER:
5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case WEBKIT_CENTER:
5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        updateLogicalWidthForCenterAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case JUSTIFY:
5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        adjustInlineDirectionLineBounds(expansionOpportunityCount, logicalLeft, availableLogicalWidth);
5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (expansionOpportunityCount) {
5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (trailingSpaceRun) {
5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
5155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                trailingSpaceRun->m_box->setLogicalWidth(0);
5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Fall through
5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case TASTART:
5218abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        if (direction == LTR)
5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
5235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else
5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            updateLogicalWidthForRightAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case TAEND:
5278abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        if (direction == LTR)
5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            updateLogicalWidthForRightAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else
5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
533d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
534d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        logicalLeft += verticalScrollbarWidth();
5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
537f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)static void updateLogicalInlinePositions(RenderBlockFlow* block, float& lineLogicalLeft, float& lineLogicalRight, float& availableLogicalWidth, bool firstLine, IndentTextOrNot shouldIndentText, LayoutUnit boxLogicalHeight)
538926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
53906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    LayoutUnit lineLogicalHeight = block->minLineHeightForReplacedRenderer(firstLine, boxLogicalHeight);
540d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    lineLogicalLeft = block->logicalLeftOffsetForLine(block->logicalHeight(), shouldIndentText == IndentText, lineLogicalHeight).toFloat();
541f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    lineLogicalRight = block->logicalRightOffsetForLine(block->logicalHeight(), shouldIndentText == IndentText, lineLogicalHeight).toFloat();
542926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    availableLogicalWidth = lineLogicalRight - lineLogicalLeft;
543926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
544926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
545f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void RenderBlockFlow::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox, const LineInfo& lineInfo, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd,
5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                         GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache, WordMeasurements& wordMeasurements)
5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ETextAlign textAlign = textAlignmentForLine(!reachedEnd && !lineBox->endsWithBreak());
54953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
55053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // 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
5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // box is only affected if it is the first child of its parent element."
552c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    // CSS3 "text-indent", "each-line" affects the first line of the block container as well as each line after a forced line break,
55353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // but does not affect lines after a soft wrap break.
554d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    bool isFirstLine = lineInfo.isFirstLine() && !(isAnonymousBlock() && parent()->slowFirstChild() != this);
55553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    bool isAfterHardLineBreak = lineBox->prevRootBox() && lineBox->prevRootBox()->endsWithBreak();
55653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    IndentTextOrNot shouldIndentText = requiresIndent(isFirstLine, isAfterHardLineBreak, style());
557926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    float lineLogicalLeft;
558926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    float lineLogicalRight;
559926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    float availableLogicalWidth;
56053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    updateLogicalInlinePositions(this, lineLogicalLeft, lineLogicalRight, availableLogicalWidth, isFirstLine, shouldIndentText, 0);
561926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    bool needsWordSpacing;
5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
563926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (firstRun && firstRun->m_object->isReplaced()) {
564926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        RenderBox* renderBox = toRenderBox(firstRun->m_object);
56553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        updateLogicalInlinePositions(this, lineLogicalLeft, lineLogicalRight, availableLogicalWidth, isFirstLine, shouldIndentText, renderBox->logicalHeight());
566926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
567926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
568926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    computeInlineDirectionPositionsForSegment(lineBox, lineInfo, textAlign, lineLogicalLeft, availableLogicalWidth, firstRun, trailingSpaceRun, textBoxDataMap, verticalPositionCache, wordMeasurements);
569926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // The widths of all runs are now known. We can now place every inline box (and
570926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // compute accurate widths for the inline flow boxes).
5717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    needsWordSpacing = lineBox->isLeftToRightDirection() ? false: true;
572c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    lineBox->placeBoxesInInlineDirection(lineLogicalLeft, needsWordSpacing);
573926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
574926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
575f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)BidiRun* RenderBlockFlow::computeInlineDirectionPositionsForSegment(RootInlineBox* lineBox, const LineInfo& lineInfo, ETextAlign textAlign, float& logicalLeft,
576926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    float& availableLogicalWidth, BidiRun* firstRun, BidiRun* trailingSpaceRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache,
577926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    WordMeasurements& wordMeasurements)
578926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
5795d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    bool needsWordSpacing = true;
580d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    float totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth().toFloat();
5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned expansionOpportunityCount = 0;
5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isAfterExpansion = true;
5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<unsigned, 16> expansionOpportunities;
5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* previousObject = 0;
58519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    TextJustify textJustify = style()->textJustify();
5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
587926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    BidiRun* r = firstRun;
588926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    for (; r; r = r->next()) {
5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!r->m_box || r->m_object->isOutOfFlowPositioned() || r->m_box->isLineBreak())
5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue; // Positioned objects are only participating to figure out their
5915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                      // correct static x position.  They have no effect on the width.
5925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                      // Similarly, line break boxes have no effect on the width.
5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (r->m_object->isText()) {
5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderText* rt = toRenderText(r->m_object);
59519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            if (textAlign == JUSTIFY && r != trailingSpaceRun && textJustify != TextJustifyNone) {
5965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (!isAfterExpansion)
5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    toInlineTextBox(r->m_box)->setCanHaveLeadingExpansion(true);
5985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                unsigned opportunitiesInRun;
5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (rt->is8Bit())
60009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    opportunitiesInRun = Character::expansionOpportunityCount(rt->characters8() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), isAfterExpansion);
6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                else
60209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    opportunitiesInRun = Character::expansionOpportunityCount(rt->characters16() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), isAfterExpansion);
6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                expansionOpportunities.append(opportunitiesInRun);
6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                expansionOpportunityCount += opportunitiesInRun;
6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6075d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            if (rt->textLength()) {
6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (!r->m_start && needsWordSpacing && isSpaceOrNewline(rt->characterAt(r->m_start)))
60909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    totalLogicalWidth += rt->style(lineInfo.isFirstLine())->font().fontDescription().wordSpacing();
6105d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)                needsWordSpacing = !isSpaceOrNewline(rt->characterAt(r->m_stop - 1));
6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            setLogicalWidthForTextRun(lineBox, r, rt, totalLogicalWidth, lineInfo, textBoxDataMap, verticalPositionCache, wordMeasurements);
6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            isAfterExpansion = false;
6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!r->m_object->isRenderInline()) {
6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                RenderBox* renderBox = toRenderBox(r->m_object);
6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (renderBox->isRubyRun())
6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    setMarginsForRubyRun(r, toRenderRubyRun(renderBox), previousObject, lineInfo);
620d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                r->m_box->setLogicalWidth(logicalWidthForChild(renderBox).toFloat());
6215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                totalLogicalWidth += marginStartForChild(renderBox) + marginEndForChild(renderBox);
6225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
6235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
6245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        totalLogicalWidth += r->m_box->logicalWidth();
6265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        previousObject = r->m_object;
6275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isAfterExpansion && !expansionOpportunities.isEmpty()) {
6305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        expansionOpportunities.last()--;
6315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        expansionOpportunityCount--;
6325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6348abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    updateLogicalWidthForAlignment(textAlign, lineBox, trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth, expansionOpportunityCount);
6355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    computeExpansionForJustifiedText(firstRun, trailingSpaceRun, expansionOpportunities, expansionOpportunityCount, totalLogicalWidth, availableLogicalWidth);
6375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
638926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return r;
6395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
641f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void RenderBlockFlow::computeBlockDirectionPositionsForLine(RootInlineBox* lineBox, BidiRun* firstRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap,
6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                        VerticalPositionCache& verticalPositionCache)
6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setLogicalHeight(lineBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, verticalPositionCache));
6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Now make sure we place replaced render objects correctly.
6475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (BidiRun* r = firstRun; r; r = r->next()) {
6485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(r->m_box);
6495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!r->m_box)
6505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue; // Skip runs with no line boxes.
6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Align positioned boxes with the top of the line box.  This is
6535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // a reasonable approximation of an appropriate y position.
6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (r->m_object->isOutOfFlowPositioned())
655d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            r->m_box->setLogicalTop(logicalHeight().toFloat());
6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Position is used to properly position both replaced elements and
6585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // to update the static normal flow x/y of positioned elements.
6595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (r->m_object->isText())
6605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            toRenderText(r->m_object)->positionLineBox(r->m_box);
6615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else if (r->m_object->isBox())
6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            toRenderBox(r->m_object)->positionLineBox(r->m_box);
6635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
666f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void RenderBlockFlow::appendFloatingObjectToLastLine(FloatingObject* floatingObject)
6675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
668e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT(!floatingObject->originatingLine());
669e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    floatingObject->setOriginatingLine(lastRootBox());
6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    lastRootBox()->appendFloat(floatingObject->renderer());
6715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This function constructs line boxes for all of the text runs in the resolver and computes their position.
674f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)RootInlineBox* RenderBlockFlow::createLineBoxesFromBidiRuns(unsigned bidiLevel, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& end, LineInfo& lineInfo, VerticalPositionCache& verticalPositionCache, BidiRun* trailingSpaceRun, WordMeasurements& wordMeasurements)
6755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!bidiRuns.runCount())
6775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
6785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: Why is this only done when we had runs?
68051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    lineInfo.setLastLine(!end.object());
6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RootInlineBox* lineBox = constructLine(bidiRuns, lineInfo);
6835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!lineBox)
6845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6868abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    lineBox->setBidiLevel(bidiLevel);
6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    lineBox->setEndsWithBreak(lineInfo.previousLineBrokeCleanly());
68893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
6895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isSVGRootInlineBox = lineBox->isSVGRootInlineBox();
69093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
6915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    GlyphOverflowAndFallbackFontsMap textBoxDataMap;
69293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
6935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Now we position all of our text runs horizontally.
6945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!isSVGRootInlineBox)
6955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        computeInlineDirectionPositionsForLine(lineBox, lineInfo, bidiRuns.firstRun(), trailingSpaceRun, end.atEnd(), textBoxDataMap, verticalPositionCache, wordMeasurements);
69693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
6975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Now position our text runs vertically.
6985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    computeBlockDirectionPositionsForLine(lineBox, bidiRuns.firstRun(), textBoxDataMap, verticalPositionCache);
69993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
7005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // SVG text layout code computes vertical & horizontal positions on its own.
7015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Note that we still need to execute computeVerticalPositionsForLine() as
7025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // it calls InlineTextBox::positionLineBox(), which tracks whether the box
7035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // contains reversed text or not. If we wouldn't do that editing and thus
7045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // text selection in RTL boxes would not work as expected.
7055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isSVGRootInlineBox) {
7065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(isSVGText());
7079bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        toSVGRootInlineBox(lineBox)->computePerCharacterLayoutInformation();
7085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
70993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
7105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Compute our overflow now.
7115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    lineBox->computeOverflow(lineBox->lineTop(), lineBox->lineBottom(), textBoxDataMap);
71253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
7135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return lineBox;
7145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
716f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)static void deleteLineRange(LineLayoutState& layoutState, RootInlineBox* startLine, RootInlineBox* stopLine = 0)
7175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RootInlineBox* boxToDelete = startLine;
7195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (boxToDelete && boxToDelete != stopLine) {
7209e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        layoutState.updatePaintInvalidationRangeFromBox(boxToDelete);
721f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        // Note: deleteLineRange(firstRootBox()) is not identical to deleteLineBoxTree().
7225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // deleteLineBoxTree uses nextLineBox() instead of nextRootBox() when traversing.
7235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RootInlineBox* next = boxToDelete->nextRootBox();
724f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        boxToDelete->deleteLine();
7255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        boxToDelete = next;
7265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
72909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void RenderBlockFlow::layoutRunsAndFloats(LineLayoutState& layoutState)
7305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We want to skip ahead to the first dirty line
7325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InlineBidiResolver resolver;
7335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RootInlineBox* startLine = determineStartPosition(layoutState, resolver);
7345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
735926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (containsFloats())
736d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        layoutState.setLastFloat(m_floatingObjects->set().last().get());
7375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We also find the first clean line and extract these lines.  We will add them back
7395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // if we determine that we're able to synchronize after handling all our dirty lines.
7405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InlineIterator cleanLineStart;
7415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    BidiStatus cleanLineBidiStatus;
7425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!layoutState.isFullLayout() && startLine)
7435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        determineEndPosition(layoutState, startLine, cleanLineStart, cleanLineBidiStatus);
7445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (startLine) {
7469e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        if (!layoutState.usesPaintInvalidationBounds())
7479e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            layoutState.setPaintInvalidationRange(logicalHeight());
748f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        deleteLineRange(layoutState, startLine);
7495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!layoutState.isFullLayout() && lastRootBox() && lastRootBox()->endsWithBreak()) {
7525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If the last line before the start line ends with a line break that clear floats,
7535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // adjust the height accordingly.
7545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // A line break can be either the first or the last object on a line, depending on its direction.
7555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (InlineBox* lastLeafChild = lastRootBox()->lastLeafChild()) {
756d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            RenderObject* lastObject = &lastLeafChild->renderer();
7575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!lastObject->isBR())
758d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                lastObject = &lastRootBox()->firstLeafChild()->renderer();
7595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (lastObject->isBR()) {
7605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                EClear clear = lastObject->style()->clear();
7615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (clear != CNONE)
7621e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                    clearFloats(clear);
7635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
7645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
7655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
767c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    layoutRunsAndFloatsInRange(layoutState, resolver, cleanLineStart, cleanLineBidiStatus);
7685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    linkToEndLineIfNeeded(layoutState);
7699e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    markDirtyFloatsForPaintInvalidation(layoutState.floats());
7705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
772926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Before restarting the layout loop with a new logicalHeight, remove all floats that were added and reset the resolver.
773f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)inline const InlineIterator& RenderBlockFlow::restartLayoutRunsAndFloatsInRange(LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight,  FloatingObject* lastFloatFromPreviousLine, InlineBidiResolver& resolver,  const InlineIterator& oldEnd)
774926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
775926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    removeFloatingObjectsBelow(lastFloatFromPreviousLine, oldLogicalHeight);
776926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    setLogicalHeight(newLogicalHeight);
777926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    resolver.setPositionIgnoringNestedIsolates(oldEnd);
778926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return oldEnd;
779926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
780926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
781c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void RenderBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState,
782c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    InlineBidiResolver& resolver, const InlineIterator& cleanLineStart,
783c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    const BidiStatus& cleanLineBidiStatus)
7845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderStyle* styleToUse = style();
7865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool paginated = view()->layoutState() && view()->layoutState()->isPaginated();
7875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LineMidpointState& lineMidpointState = resolver.midpointState();
78851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    InlineIterator endOfLine = resolver.position();
7895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool checkForEndLineMatch = layoutState.endLine();
7905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderTextInfo renderTextInfo;
7915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    VerticalPositionCache verticalPositionCache;
7925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LineBreaker lineBreaker(this);
7945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
79551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    while (!endOfLine.atEnd()) {
7965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // FIXME: Is this check necessary before the first iteration or can it be moved to the end?
7975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (checkForEndLineMatch) {
7985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            layoutState.setEndLineMatched(matchedEndLine(layoutState, resolver, cleanLineStart, cleanLineBidiStatus));
7995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (layoutState.endLineMatched()) {
8005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0);
8015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
8025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
8035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
8045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        lineMidpointState.reset();
8065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        layoutState.lineInfo().setEmpty(true);
8085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        layoutState.lineInfo().resetRunsFromLeadingWhitespace();
8095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
81051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        const InlineIterator previousEndofLine = endOfLine;
8115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool isNewUBAParagraph = layoutState.lineInfo().previousLineBrokeCleanly();
812d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        FloatingObject* lastFloatFromPreviousLine = (containsFloats()) ? m_floatingObjects->set().last().get() : 0;
813fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
8145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        WordMeasurements wordMeasurements;
815c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        endOfLine = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(), renderTextInfo,
816c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            lastFloatFromPreviousLine, wordMeasurements);
81753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        renderTextInfo.m_lineBreakIterator.resetPriorContext();
8185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (resolver.position().atEnd()) {
8195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // FIXME: We shouldn't be creating any runs in nextLineBreak to begin with!
8205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Once BidiRunList is separated from BidiResolver this will not be needed.
8215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            resolver.runs().deleteRuns();
8225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed).
8235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            layoutState.setCheckForFloatsFromLastLine(true);
8245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0);
8255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
8265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
8275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
82851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ASSERT(endOfLine != resolver.position());
829591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
8305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // This is a short-cut for empty lines.
8315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (layoutState.lineInfo().isEmpty()) {
8325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (lastRootBox())
83309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                lastRootBox()->setLineBreakInfo(endOfLine.object(), endOfLine.offset(), resolver.status());
8345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
8355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            VisualDirectionOverride override = (styleToUse->rtlOrdering() == VisualOrder ? (styleToUse->direction() == LTR ? VisualLeftToRightOverride : VisualRightToLeftOverride) : NoVisualOverride);
8365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (isNewUBAParagraph && styleToUse->unicodeBidi() == Plaintext && !resolver.context()->parent()) {
837c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)                TextDirection direction = determinePlaintextDirectionality(resolver.position().root(), resolver.position().object(), resolver.position().offset());
8385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                resolver.setStatus(BidiStatus(direction, isOverride(styleToUse->unicodeBidi())));
8395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
8405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // FIXME: This ownership is reversed. We should own the BidiRunList and pass it to createBidiRunsForLine.
8415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            BidiRunList<BidiRun>& bidiRuns = resolver.runs();
842c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            constructBidiRunsForLine(resolver, bidiRuns, endOfLine, override, layoutState.lineInfo().previousLineBrokeCleanly(), isNewUBAParagraph);
84351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ASSERT(resolver.position() == endOfLine);
8445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
84509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            BidiRun* trailingSpaceRun = resolver.trailingSpaceRun();
8465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
847c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            if (bidiRuns.runCount() && lineBreaker.lineWasHyphenated())
8485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                bidiRuns.logicallyLastRun()->m_hasHyphen = true;
8495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Now that the runs have been ordered, we create the line boxes.
8515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // At the same time we figure out where border/padding/margin should be applied for
8525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // inline flow boxes.
8535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            LayoutUnit oldLogicalHeight = logicalHeight();
85551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            RootInlineBox* lineBox = createLineBoxesFromBidiRuns(resolver.status().context->level(), bidiRuns, endOfLine, layoutState.lineInfo(), verticalPositionCache, trailingSpaceRun, wordMeasurements);
8565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            bidiRuns.deleteRuns();
8585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed).
8595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (lineBox) {
86109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                lineBox->setLineBreakInfo(endOfLine.object(), endOfLine.offset(), resolver.status());
8629e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                if (layoutState.usesPaintInvalidationBounds())
8639e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                    layoutState.updatePaintInvalidationRangeFromBox(lineBox);
8645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (paginated) {
8665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    LayoutUnit adjustment = 0;
867926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    adjustLinePositionForPagination(lineBox, adjustment, layoutState.flowThread());
8685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (adjustment) {
8695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        LayoutUnit oldLineWidth = availableLogicalWidthForLine(oldLogicalHeight, layoutState.lineInfo().isFirstLine());
870d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        lineBox->adjustBlockDirectionPosition(adjustment.toFloat());
8719e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                        if (layoutState.usesPaintInvalidationBounds())
8729e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                            layoutState.updatePaintInvalidationRangeFromBox(lineBox);
8735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        if (availableLogicalWidthForLine(oldLogicalHeight + adjustment, layoutState.lineInfo().isFirstLine()) != oldLineWidth) {
8755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            // We have to delete this line, remove all floats that got added, and let line layout re-run.
876f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                            lineBox->deleteLine();
87751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                            endOfLine = restartLayoutRunsAndFloatsInRange(oldLogicalHeight, oldLogicalHeight + adjustment, lastFloatFromPreviousLine, resolver, previousEndofLine);
8785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            continue;
8795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        }
8805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        setLogicalHeight(lineBox->lineBottomWithLeading());
8825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    }
8835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
8845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
885926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
8865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
887926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        for (size_t i = 0; i < lineBreaker.positionedObjects().size(); ++i)
888926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            setStaticPositions(this, lineBreaker.positionedObjects()[i]);
8895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
890926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (!layoutState.lineInfo().isEmpty()) {
8915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            layoutState.lineInfo().setFirstLine(false);
8921e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            clearFloats(lineBreaker.clear());
8935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
8945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8951fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        if (m_floatingObjects && lastRootBox()) {
8961fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch            const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
8975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            FloatingObjectSetIterator it = floatingObjectSet.begin();
8985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            FloatingObjectSetIterator end = floatingObjectSet.end();
8995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (layoutState.lastFloat()) {
9005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                FloatingObjectSetIterator lastFloatIterator = floatingObjectSet.find(layoutState.lastFloat());
9015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                ASSERT(lastFloatIterator != end);
9025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                ++lastFloatIterator;
9035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                it = lastFloatIterator;
9045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
9055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (; it != end; ++it) {
906d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                FloatingObject* f = it->get();
9075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                appendFloatingObjectToLastLine(f);
908e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                ASSERT(f->renderer() == layoutState.floats()[layoutState.floatIndex()].object);
9095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // If a float's geometry has changed, give up on syncing with clean lines.
9105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (layoutState.floats()[layoutState.floatIndex()].rect != f->frameRect())
9115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    checkForEndLineMatch = false;
9125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                layoutState.setFloatIndex(layoutState.floatIndex() + 1);
9135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
914d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            layoutState.setLastFloat(!floatingObjectSet.isEmpty() ? floatingObjectSet.last().get() : 0);
9155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
9165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        lineMidpointState.reset();
91851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        resolver.setPosition(endOfLine, numberOfIsolateAncestors(endOfLine));
9195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
920926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
921bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    // In case we already adjusted the line positions during this layout to avoid widows
922bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    // then we need to ignore the possibility of having a new widows situation.
923bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    // Otherwise, we risk leaving empty containers which is against the block fragmentation principles.
924bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    if (paginated && !style()->hasAutoWidows() && !didBreakAtLineToAvoidWidow()) {
925926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // Check the line boxes to make sure we didn't create unacceptable widows.
926926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // However, we'll prioritize orphans - so nothing we do here should create
927926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // a new orphan.
928926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
929926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        RootInlineBox* lineBox = lastRootBox();
930926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
931926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // Count from the end of the block backwards, to see how many hanging
932926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // lines we have.
933926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        RootInlineBox* firstLineInBlock = firstRootBox();
934926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        int numLinesHanging = 1;
935926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        while (lineBox && lineBox != firstLineInBlock && !lineBox->isFirstAfterPageBreak()) {
936926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            ++numLinesHanging;
937926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            lineBox = lineBox->prevRootBox();
938926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
939926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
940926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // If there were no breaks in the block, we didn't create any widows.
941926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (!lineBox || !lineBox->isFirstAfterPageBreak() || lineBox == firstLineInBlock)
942926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            return;
943926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
944926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (numLinesHanging < style()->widows()) {
945926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            // We have detected a widow. Now we need to work out how many
946926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            // lines there are on the previous page, and how many we need
947926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            // to steal.
948926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            int numLinesNeeded = style()->widows() - numLinesHanging;
949926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            RootInlineBox* currentFirstLineOfNewPage = lineBox;
950926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
951926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            // Count the number of lines in the previous page.
952926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            lineBox = lineBox->prevRootBox();
953926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            int numLinesInPreviousPage = 1;
954926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            while (lineBox && lineBox != firstLineInBlock && !lineBox->isFirstAfterPageBreak()) {
955926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                ++numLinesInPreviousPage;
956926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                lineBox = lineBox->prevRootBox();
957926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            }
958926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
959926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            // If there was an explicit value for orphans, respect that. If not, we still
960926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            // shouldn't create a situation where we make an orphan bigger than the initial value.
961926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            // This means that setting widows implies we also care about orphans, but given
962926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            // the specification says the initial orphan value is non-zero, this is ok. The
963926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            // author is always free to set orphans explicitly as well.
964926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            int orphans = style()->hasAutoOrphans() ? style()->initialOrphans() : style()->orphans();
965926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            int numLinesAvailable = numLinesInPreviousPage - orphans;
966926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            if (numLinesAvailable <= 0)
967926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                return;
968926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
969197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            int numLinesToTake = std::min(numLinesAvailable, numLinesNeeded);
970926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            // Wind back from our first widowed line.
971926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            lineBox = currentFirstLineOfNewPage;
972926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            for (int i = 0; i < numLinesToTake; ++i)
973926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                lineBox = lineBox->prevRootBox();
974926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
975926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            // We now want to break at this line. Remember for next layout and trigger relayout.
976bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            setBreakAtLineToAvoidWidow(lineCount(lineBox));
977926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            markLinesDirtyInBlockRange(lastRootBox()->lineBottomWithLeading(), lineBox->lineBottomWithLeading(), lineBox);
978926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
979926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
980bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
981bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    clearDidBreakAtLineToAvoidWidow();
9825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
984f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void RenderBlockFlow::linkToEndLineIfNeeded(LineLayoutState& layoutState)
9855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (layoutState.endLine()) {
9875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (layoutState.endLineMatched()) {
9885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            bool paginated = view()->layoutState() && view()->layoutState()->isPaginated();
9895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Attach all the remaining lines, and then adjust their y-positions as needed.
9905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            LayoutUnit delta = logicalHeight() - layoutState.endLineLogicalTop();
9915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (RootInlineBox* line = layoutState.endLine(); line; line = line->nextRootBox()) {
9925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                line->attachLine();
9935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (paginated) {
9945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    delta -= line->paginationStrut();
995926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    adjustLinePositionForPagination(line, delta, layoutState.flowThread());
9965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
9975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (delta) {
9989e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                    layoutState.updatePaintInvalidationRangeFromBox(line, delta);
999d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    line->adjustBlockDirectionPosition(delta.toFloat());
10005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
10015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) {
10025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    Vector<RenderBox*>::iterator end = cleanLineFloats->end();
10035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    for (Vector<RenderBox*>::iterator f = cleanLineFloats->begin(); f != end; ++f) {
10045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        FloatingObject* floatingObject = insertFloatingObject(*f);
1005e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                        ASSERT(!floatingObject->originatingLine());
1006e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                        floatingObject->setOriginatingLine(line);
10075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        setLogicalHeight(logicalTopForChild(*f) - marginBeforeForChild(*f) + delta);
10085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        positionNewFloats();
10095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    }
10105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
10115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
10125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            setLogicalHeight(lastRootBox()->lineBottomWithLeading());
10135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
10145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Delete all the remaining lines.
1015f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)            deleteLineRange(layoutState, layoutState.endLine());
10165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
10175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
101802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
10191fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    if (m_floatingObjects && (layoutState.checkForFloatsFromLastLine() || positionNewFloats()) && lastRootBox()) {
10205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // In case we have a float on the last line, it might not be positioned up to now.
10215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // This has to be done before adding in the bottom border/padding, or the float will
10225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // include the padding incorrectly. -dwh
10237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
10247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        FloatingObjectSetIterator it = floatingObjectSet.begin();
10257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        FloatingObjectSetIterator end = floatingObjectSet.end();
10267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (layoutState.lastFloat()) {
10277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            FloatingObjectSetIterator lastFloatIterator = floatingObjectSet.find(layoutState.lastFloat());
10287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            ASSERT(lastFloatIterator != end);
10297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            ++lastFloatIterator;
10307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            it = lastFloatIterator;
10317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        }
10327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        layoutState.setLastFloat(!floatingObjectSet.isEmpty() ? floatingObjectSet.last().get() : 0);
10337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
10347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (it == end)
10357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return;
10367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
10375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (layoutState.checkForFloatsFromLastLine()) {
10385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            LayoutUnit bottomVisualOverflow = lastRootBox()->logicalBottomVisualOverflow();
10395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            LayoutUnit bottomLayoutOverflow = lastRootBox()->logicalBottomLayoutOverflow();
1040d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            TrailingFloatsRootInlineBox* trailingFloatsLineBox = new TrailingFloatsRootInlineBox(*this);
10415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_lineBoxes.appendLineBox(trailingFloatsLineBox);
10425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            trailingFloatsLineBox->setConstructed();
10435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            GlyphOverflowAndFallbackFontsMap textBoxDataMap;
10445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            VerticalPositionCache verticalPositionCache;
10455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            LayoutUnit blockLogicalHeight = logicalHeight();
10465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            trailingFloatsLineBox->alignBoxesInBlockDirection(blockLogicalHeight, textBoxDataMap, verticalPositionCache);
10475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            trailingFloatsLineBox->setLineTopBottomPositions(blockLogicalHeight, blockLogicalHeight, blockLogicalHeight, blockLogicalHeight);
104809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            trailingFloatsLineBox->setPaginatedLineWidth(availableLogicalWidthForContent());
10495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            LayoutRect logicalLayoutOverflow(0, blockLogicalHeight, 1, bottomLayoutOverflow - blockLogicalHeight);
10505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            LayoutRect logicalVisualOverflow(0, blockLogicalHeight, 1, bottomVisualOverflow - blockLogicalHeight);
10515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            trailingFloatsLineBox->setOverflowFromLogicalRects(logicalLayoutOverflow, logicalVisualOverflow, trailingFloatsLineBox->lineTop(), trailingFloatsLineBox->lineBottom());
10525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
10535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (; it != end; ++it)
1055d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            appendFloatingObjectToLastLine(it->get());
10565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10599e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)void RenderBlockFlow::markDirtyFloatsForPaintInvalidation(Vector<FloatWithRect>& floats)
10605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
10615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t floatCount = floats.size();
1062f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    // Floats that did not have layout did not paint invalidations when we laid them out. They would have
10635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // painted by now if they had moved, but if they stayed at (0, 0), they still need to be
10645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // painted.
10655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < floatCount; ++i) {
10665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!floats[i].everHadLayout) {
10675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderBox* f = floats[i].object;
10685d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            if (!f->x() && !f->y() && f->checkForPaintInvalidation()) {
1069197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                f->setShouldDoFullPaintInvalidation(true);
1070a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            }
10715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
10725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1075d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)struct InlineMinMaxIterator {
1076d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)/* InlineMinMaxIterator is a class that will iterate over all render objects that contribute to
1077d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)   inline min/max width calculations.  Note the following about the way it walks:
1078d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)   (1) Positioned content is skipped (since it does not contribute to min/max width of a block)
1079d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)   (2) We do not drill into the children of floats or replaced elements, since you can't break
1080d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)       in the middle of such an element.
1081d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)   (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side can have
1082d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)       distinct borders/margin/padding that contribute to the min/max width.
1083d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)*/
1084d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RenderObject* parent;
1085d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RenderObject* current;
1086d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    bool endOfInline;
1087d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1088d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    InlineMinMaxIterator(RenderObject* p, bool end = false)
1089d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        : parent(p), current(p), endOfInline(end)
1090d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    {
1091d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1092d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
1093d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1094d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RenderObject* next();
1095d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)};
1096d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1097d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)RenderObject* InlineMinMaxIterator::next()
1098d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
1099d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RenderObject* result = 0;
1100d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    bool oldEndOfInline = endOfInline;
1101d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    endOfInline = false;
1102d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    while (current || current == parent) {
1103d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (!oldEndOfInline && (current == parent || (!current->isFloating() && !current->isReplaced() && !current->isOutOfFlowPositioned())))
1104d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            result = current->slowFirstChild();
1105d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1106d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (!result) {
1107d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // We hit the end of our inline. (It was empty, e.g., <span></span>.)
1108d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if (!oldEndOfInline && current->isRenderInline()) {
1109d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                result = current;
1110d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                endOfInline = true;
1111d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                break;
1112d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            }
1113d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1114d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            while (current && current != parent) {
1115d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                result = current->nextSibling();
1116d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (result)
1117d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    break;
1118d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                current = current->parent();
1119d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (current && current != parent && current->isRenderInline()) {
1120d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    result = current;
1121d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    endOfInline = true;
1122d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    break;
1123d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                }
1124d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            }
1125d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        }
1126d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1127d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (!result)
1128d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            break;
1129d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1130d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (!result->isOutOfFlowPositioned() && (result->isText() || result->isFloating() || result->isReplaced() || result->isRenderInline()))
1131d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            break;
1132d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1133d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        current = result;
1134d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        result = 0;
1135d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
1136d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1137d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Update our position.
1138d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    current = result;
1139d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return current;
1140d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
1141d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1142d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)static LayoutUnit getBPMWidth(LayoutUnit childValue, Length cssUnit)
1143d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
1144d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (cssUnit.type() != Auto)
1145d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return (cssUnit.isFixed() ? static_cast<LayoutUnit>(cssUnit.value()) : childValue);
1146d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return 0;
1147d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
1148d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1149d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)static LayoutUnit getBorderPaddingMargin(RenderBoxModelObject* child, bool endOfInline)
1150d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
1151d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RenderStyle* childStyle = child->style();
1152d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (endOfInline) {
1153d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return getBPMWidth(child->marginEnd(), childStyle->marginEnd()) +
1154d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            getBPMWidth(child->paddingEnd(), childStyle->paddingEnd()) +
1155d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            child->borderEnd();
1156d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
1157d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return getBPMWidth(child->marginStart(), childStyle->marginStart()) +
1158d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        getBPMWidth(child->paddingStart(), childStyle->paddingStart()) +
1159d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        child->borderStart();
1160d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
1161d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1162d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)static inline void stripTrailingSpace(float& inlineMax, float& inlineMin, RenderObject* trailingSpaceChild)
1163d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
1164d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (trailingSpaceChild && trailingSpaceChild->isText()) {
1165d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        // Collapse away the trailing space at the end of a block.
1166d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        RenderText* t = toRenderText(trailingSpaceChild);
1167d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        const UChar space = ' ';
1168d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        const Font& font = t->style()->font(); // FIXME: This ignores first-line.
1169c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        float spaceWidth = font.width(constructTextRun(t, font, &space, 1, t->style(), LTR));
1170d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        inlineMax -= spaceWidth + font.fontDescription().wordSpacing();
1171d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (inlineMin > inlineMax)
1172d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            inlineMin = inlineMax;
1173d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
1174d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
1175d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1176d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)static inline void updatePreferredWidth(LayoutUnit& preferredWidth, float& result)
1177d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
1178d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    LayoutUnit snappedResult = LayoutUnit::fromFloatCeil(result);
1179197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    preferredWidth = std::max(snappedResult, preferredWidth);
1180d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
1181d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1182d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// When converting between floating point and LayoutUnits we risk losing precision
1183d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// with each conversion. When this occurs while accumulating our preferred widths,
1184d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// we can wind up with a line width that's larger than our maxPreferredWidth due to
1185d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// pure float accumulation.
1186d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)static inline LayoutUnit adjustFloatForSubPixelLayout(float value)
1187d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
1188d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return LayoutUnit::fromFloatCeil(value);
1189d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
1190d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1191d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// FIXME: This function should be broken into something less monolithic.
1192d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// FIXME: The main loop here is very similar to LineBreaker::nextSegmentBreak. They can probably reuse code.
1193d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void RenderBlockFlow::computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth)
1194d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
1195d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    float inlineMax = 0;
1196d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    float inlineMin = 0;
1197d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1198d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RenderStyle* styleToUse = style();
1199d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RenderBlock* containingBlock = this->containingBlock();
1200d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    LayoutUnit cw = containingBlock ? containingBlock->contentLogicalWidth() : LayoutUnit();
1201d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1202d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // If we are at the start of a line, we want to ignore all white-space.
1203d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Also strip spaces if we previously had text that ended in a trailing space.
1204d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    bool stripFrontSpaces = true;
1205d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RenderObject* trailingSpaceChild = 0;
1206d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1207d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Firefox and Opera will allow a table cell to grow to fit an image inside it under
1208d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // very specific cirucumstances (in order to match common WinIE renderings).
1209d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
1210d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    bool allowImagesToBreak = !document().inQuirksMode() || !isTableCell() || !styleToUse->logicalWidth().isIntrinsicOrAuto();
1211d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1212d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    bool autoWrap, oldAutoWrap;
1213d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    autoWrap = oldAutoWrap = styleToUse->autoWrap();
1214d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1215d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    InlineMinMaxIterator childIterator(this);
1216d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1217d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Only gets added to the max preffered width once.
1218d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    bool addedTextIndent = false;
1219d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Signals the text indent was more negative than the min preferred width
1220d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    bool hasRemainingNegativeTextIndent = false;
1221d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1222d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    LayoutUnit textIndent = minimumValueForLength(styleToUse->textIndent(), cw);
1223d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RenderObject* prevFloat = 0;
1224d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    bool isPrevChildInlineFlow = false;
1225d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    bool shouldBreakLineAfterText = false;
1226d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    while (RenderObject* child = childIterator.next()) {
1227d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        autoWrap = child->isReplaced() ? child->parent()->style()->autoWrap() :
1228d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            child->style()->autoWrap();
1229d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1230d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (!child->isBR()) {
1231d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // Step One: determine whether or not we need to go ahead and
1232d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // terminate our current line. Each discrete chunk can become
1233d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // the new min-width, if it is the widest chunk seen so far, and
1234d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // it can also become the max-width.
1235d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1236d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // Children fall into three categories:
1237d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // (1) An inline flow object. These objects always have a min/max of 0,
1238d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // and are included in the iteration solely so that their margins can
1239d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // be added in.
1240d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            //
1241d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // (2) An inline non-text non-flow object, e.g., an inline replaced element.
1242d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // These objects can always be on a line by themselves, so in this situation
1243d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // we need to go ahead and break the current line, and then add in our own
1244d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // margins and min/max width on its own line, and then terminate the line.
1245d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            //
1246d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // (3) A text object. Text runs can have breakable characters at the start,
1247d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // the middle or the end. They may also lose whitespace off the front if
1248d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // we're already ignoring whitespace. In order to compute accurate min-width
1249d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // information, we need three pieces of information.
1250d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // (a) the min-width of the first non-breakable run. Should be 0 if the text string
1251d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // starts with whitespace.
1252d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // (b) the min-width of the last non-breakable run. Should be 0 if the text string
1253d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // ends with whitespace.
1254d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // (c) the min/max width of the string (trimmed for whitespace).
1255d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            //
1256d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // If the text string starts with whitespace, then we need to go ahead and
1257d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // terminate our current line (unless we're already in a whitespace stripping
1258d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // mode.
1259d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            //
1260d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // If the text string has a breakable character in the middle, but didn't start
1261d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // with whitespace, then we add the width of the first non-breakable run and
1262d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // then end the current line. We then need to use the intermediate min/max width
1263d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // values (if any of them are larger than our current min/max). We then look at
1264d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // the width of the last non-breakable run and use that to start a new line
1265d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // (unless we end in whitespace).
1266d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            RenderStyle* childStyle = child->style();
1267d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            float childMin = 0;
1268d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            float childMax = 0;
1269d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1270d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if (!child->isText()) {
1271d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                // Case (1) and (2). Inline replaced and inline flow elements.
1272d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (child->isRenderInline()) {
1273d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    // Add in padding/border/margin from the appropriate side of
1274d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    // the element.
1275d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    float bpm = getBorderPaddingMargin(toRenderInline(child), childIterator.endOfInline).toFloat();
1276d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    childMin += bpm;
1277d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    childMax += bpm;
1278d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1279d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    inlineMin += childMin;
1280d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    inlineMax += childMax;
1281d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1282d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    child->clearPreferredLogicalWidthsDirty();
1283d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                } else {
1284d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    // Inline replaced elts add in their margins to their min/max values.
1285d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    LayoutUnit margins = 0;
1286d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    Length startMargin = childStyle->marginStart();
1287d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    Length endMargin = childStyle->marginEnd();
1288d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    if (startMargin.isFixed())
1289d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        margins += adjustFloatForSubPixelLayout(startMargin.value());
1290d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    if (endMargin.isFixed())
1291d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        margins += adjustFloatForSubPixelLayout(endMargin.value());
1292d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    childMin += margins.ceilToFloat();
1293d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    childMax += margins.ceilToFloat();
1294d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                }
1295d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            }
1296d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1297d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if (!child->isRenderInline() && !child->isText()) {
1298d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                // Case (2). Inline replaced elements and floats.
1299d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                // Go ahead and terminate the current line as far as
1300d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                // minwidth is concerned.
1301d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                LayoutUnit childMinPreferredLogicalWidth, childMaxPreferredLogicalWidth;
1302d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (child->isBox() && child->isHorizontalWritingMode() != isHorizontalWritingMode()) {
1303d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    RenderBox* childBox = toRenderBox(child);
1304d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    LogicalExtentComputedValues computedValues;
1305d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    childBox->computeLogicalHeight(childBox->borderAndPaddingLogicalHeight(), 0, computedValues);
1306d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    childMinPreferredLogicalWidth = childMaxPreferredLogicalWidth = computedValues.m_extent;
1307d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                } else {
1308d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    childMinPreferredLogicalWidth = child->minPreferredLogicalWidth();
1309d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    childMaxPreferredLogicalWidth = child->maxPreferredLogicalWidth();
1310d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                }
1311d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                childMin += childMinPreferredLogicalWidth.ceilToFloat();
1312d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                childMax += childMaxPreferredLogicalWidth.ceilToFloat();
1313d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1314d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                bool clearPreviousFloat;
1315d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (child->isFloating()) {
1316d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    clearPreviousFloat = (prevFloat
1317d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        && ((prevFloat->style()->floating() == LeftFloat && (childStyle->clear() & CLEFT))
1318d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                            || (prevFloat->style()->floating() == RightFloat && (childStyle->clear() & CRIGHT))));
1319d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    prevFloat = child;
1320d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                } else {
1321d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    clearPreviousFloat = false;
1322d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                }
1323d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1324d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak;
1325d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if ((canBreakReplacedElement && (autoWrap || oldAutoWrap) && (!isPrevChildInlineFlow || shouldBreakLineAfterText)) || clearPreviousFloat) {
1326d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    updatePreferredWidth(minLogicalWidth, inlineMin);
1327d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    inlineMin = 0;
1328d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                }
1329d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1330d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                // If we're supposed to clear the previous float, then terminate maxwidth as well.
1331d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (clearPreviousFloat) {
1332d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    updatePreferredWidth(maxLogicalWidth, inlineMax);
1333d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    inlineMax = 0;
1334d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                }
1335d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1336d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                // Add in text-indent. This is added in only once.
1337d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (!addedTextIndent && !child->isFloating()) {
1338d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    float ceiledTextIndent = textIndent.ceilToFloat();
1339d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    childMin += ceiledTextIndent;
1340d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    childMax += ceiledTextIndent;
1341d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1342d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    if (childMin < 0)
1343d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        textIndent = adjustFloatForSubPixelLayout(childMin);
1344d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    else
1345d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        addedTextIndent = true;
1346d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                }
1347d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1348d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                // Add our width to the max.
1349197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                inlineMax += std::max<float>(0, childMax);
1350d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1351d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (!autoWrap || !canBreakReplacedElement || (isPrevChildInlineFlow && !shouldBreakLineAfterText)) {
1352d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    if (child->isFloating())
1353d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        updatePreferredWidth(minLogicalWidth, childMin);
1354d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    else
1355d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        inlineMin += childMin;
1356d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                } else {
1357d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    // Now check our line.
1358d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    updatePreferredWidth(minLogicalWidth, childMin);
1359d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1360d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    // Now start a new line.
1361d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    inlineMin = 0;
1362d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                }
1363d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1364d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (autoWrap && canBreakReplacedElement && isPrevChildInlineFlow) {
1365d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    updatePreferredWidth(minLogicalWidth, inlineMin);
1366d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    inlineMin = 0;
1367d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                }
1368d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1369d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                // We are no longer stripping whitespace at the start of
1370d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                // a line.
1371d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (!child->isFloating()) {
1372d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    stripFrontSpaces = false;
1373d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    trailingSpaceChild = 0;
1374d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                }
1375d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            } else if (child->isText()) {
1376d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                // Case (3). Text.
1377d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                RenderText* t = toRenderText(child);
1378d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1379d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (t->isWordBreak()) {
1380d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    updatePreferredWidth(minLogicalWidth, inlineMin);
1381d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    inlineMin = 0;
1382d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    continue;
1383d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                }
1384d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1385d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (t->style()->hasTextCombine() && t->isCombineText())
1386d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    toRenderCombineText(t)->combineText();
1387d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1388d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                // Determine if we have a breakable character. Pass in
1389d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                // whether or not we should ignore any spaces at the front
1390d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                // of the string. If those are going to be stripped out,
1391d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                // then they shouldn't be considered in the breakable char
1392d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                // check.
1393d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                bool hasBreakableChar, hasBreak;
1394d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                float firstLineMinWidth, lastLineMinWidth;
1395d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                bool hasBreakableStart, hasBreakableEnd;
1396d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                float firstLineMaxWidth, lastLineMaxWidth;
1397d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                t->trimmedPrefWidths(inlineMax,
1398d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    firstLineMinWidth, hasBreakableStart, lastLineMinWidth, hasBreakableEnd,
1399d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    hasBreakableChar, hasBreak, firstLineMaxWidth, lastLineMaxWidth,
1400d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    childMin, childMax, stripFrontSpaces, styleToUse->direction());
1401d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1402d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                // This text object will not be rendered, but it may still provide a breaking opportunity.
1403d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (!hasBreak && !childMax) {
1404d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    if (autoWrap && (hasBreakableStart || hasBreakableEnd)) {
1405d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        updatePreferredWidth(minLogicalWidth, inlineMin);
1406d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        inlineMin = 0;
1407d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    }
1408d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    continue;
1409d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                }
1410d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1411d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (stripFrontSpaces)
1412d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    trailingSpaceChild = child;
1413d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                else
1414d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    trailingSpaceChild = 0;
1415d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1416d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                // Add in text-indent. This is added in only once.
1417d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                float ti = 0;
1418d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (!addedTextIndent || hasRemainingNegativeTextIndent) {
1419d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    ti = textIndent.ceilToFloat();
1420d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    childMin += ti;
1421d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    firstLineMinWidth += ti;
1422d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1423d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    // It the text indent negative and larger than the child minimum, we re-use the remainder
1424d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    // in future minimum calculations, but using the negative value again on the maximum
1425d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    // will lead to under-counting the max pref width.
1426d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    if (!addedTextIndent) {
1427d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        childMax += ti;
1428d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        firstLineMaxWidth += ti;
1429d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        addedTextIndent = true;
1430d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    }
1431d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1432d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    if (childMin < 0) {
1433d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        textIndent = childMin;
1434d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        hasRemainingNegativeTextIndent = true;
1435d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    }
1436d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                }
1437d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1438d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                // If we have no breakable characters at all,
1439d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                // then this is the easy case. We add ourselves to the current
1440d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                // min and max and continue.
1441d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (!hasBreakableChar) {
1442d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    inlineMin += childMin;
1443d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                } else {
1444d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    if (hasBreakableStart) {
1445d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        updatePreferredWidth(minLogicalWidth, inlineMin);
1446d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    } else {
1447d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        inlineMin += firstLineMinWidth;
1448d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        updatePreferredWidth(minLogicalWidth, inlineMin);
1449d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        childMin -= ti;
1450d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    }
1451d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1452d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    inlineMin = childMin;
1453d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1454d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    if (hasBreakableEnd) {
1455d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        updatePreferredWidth(minLogicalWidth, inlineMin);
1456d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        inlineMin = 0;
1457d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        shouldBreakLineAfterText = false;
1458d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    } else {
1459d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        updatePreferredWidth(minLogicalWidth, inlineMin);
1460d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        inlineMin = lastLineMinWidth;
1461d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        shouldBreakLineAfterText = true;
1462d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    }
1463d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                }
1464d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1465d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (hasBreak) {
1466d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    inlineMax += firstLineMaxWidth;
1467d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    updatePreferredWidth(maxLogicalWidth, inlineMax);
1468d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    updatePreferredWidth(maxLogicalWidth, childMax);
1469d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    inlineMax = lastLineMaxWidth;
1470d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    addedTextIndent = true;
1471d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                } else {
1472197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                    inlineMax += std::max<float>(0, childMax);
1473d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                }
1474d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            }
1475d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1476d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // Ignore spaces after a list marker.
1477d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if (child->isListMarker())
1478d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                stripFrontSpaces = true;
1479d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        } else {
1480d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            updatePreferredWidth(minLogicalWidth, inlineMin);
1481d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            updatePreferredWidth(maxLogicalWidth, inlineMax);
1482d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            inlineMin = inlineMax = 0;
1483d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            stripFrontSpaces = true;
1484d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            trailingSpaceChild = 0;
1485d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            addedTextIndent = true;
1486d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        }
1487d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1488d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (!child->isText() && child->isRenderInline())
1489d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            isPrevChildInlineFlow = true;
1490d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        else
1491d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            isPrevChildInlineFlow = false;
1492d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1493d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        oldAutoWrap = autoWrap;
1494d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
1495d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1496d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (styleToUse->collapseWhiteSpace())
1497d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        stripTrailingSpace(inlineMax, inlineMin, trailingSpaceChild);
1498d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1499d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    updatePreferredWidth(minLogicalWidth, inlineMin);
1500d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    updatePreferredWidth(maxLogicalWidth, inlineMax);
1501d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
1502d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
15039e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)void RenderBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& paintInvalidationLogicalTop, LayoutUnit& paintInvalidationLogicalBottom, LayoutUnit afterEdge)
15045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1505926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RenderFlowThread* flowThread = flowThreadContainingBlock();
1506926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    bool clearLinesForPagination = firstLineBox() && flowThread && !flowThread->hasRegions();
1507926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
15085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Figure out if we should clear out our line boxes.
15095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: Handle resize eventually!
1510926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    bool isFullLayout = !firstLineBox() || selfNeedsLayout() || relayoutChildren || clearLinesForPagination;
15119e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    LineLayoutState layoutState(isFullLayout, paintInvalidationLogicalTop, paintInvalidationLogicalBottom, flowThread);
15125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1513197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (isFullLayout) {
1514197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // Ensure the old line boxes will be erased.
1515197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (firstLineBox())
1516197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            setShouldDoFullPaintInvalidation(true);
1517f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        lineBoxes()->deleteLineBoxes();
1518197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
15195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1520926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // Text truncation kicks in in two cases:
1521926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    //     1) If your overflow isn't visible and your text-overflow-mode isn't clip.
15229bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    //     2) If you're an anonymous block with a block parent that satisfies #1 that was created
15239bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    //        to accomodate a block that has inline and block children. This excludes parents where
15249bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    //        canCollapseAnonymousBlockChild is false, notabley flex items and grid items.
15255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: CSS3 says that descendants that are clipped must also know how to truncate.  This is insanely
1526926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // difficult to figure out in general (especially in the middle of doing layout), so we only handle the
1527926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // simple case of an anonymous block truncating when it's parent is clipped.
1528926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    bool hasTextOverflow = (style()->textOverflow() && hasOverflowClip())
15299bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        || (isAnonymousBlock() && parent() && parent()->isRenderBlock() && toRenderBlock(parent())->canCollapseAnonymousBlockChild()
15309bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            && parent()->style()->textOverflow() && parent()->hasOverflowClip());
15315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Walk all the lines and delete our ellipsis line boxes if they exist.
15335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasTextOverflow)
15345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)         deleteEllipsisLineBoxes();
15355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (firstChild()) {
15375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // In full layout mode, clear the line boxes of children upfront. Otherwise,
15385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // siblings can run into stale root lineboxes during layout. Then layout
15395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // the replaced elements later. In partial layout mode, line boxes are not
15405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // deleted and only dirtied. In that case, we can layout the replaced
15415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // elements at the same time.
15425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Vector<RenderBox*> replacedChildren;
15435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) {
15445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderObject* o = walker.current();
154551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
154609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (!layoutState.hasInlineChild() && o->isInline())
154709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                layoutState.setHasInlineChild(true);
15485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (o->isReplaced() || o->isFloating() || o->isOutOfFlowPositioned()) {
15505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                RenderBox* box = toRenderBox(o);
15515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
155209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, box);
15535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (o->isOutOfFlowPositioned())
15555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    o->containingBlock()->insertPositionedObject(box);
15565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                else if (o->isFloating())
15575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    layoutState.floats().append(FloatWithRect(box));
15585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                else if (isFullLayout || o->needsLayout()) {
15595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    // Replaced element.
15605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    box->dirtyLineBoxes(isFullLayout);
15615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (isFullLayout)
15625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        replacedChildren.append(box);
15635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    else
15645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        o->layoutIfNeeded();
15655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
15665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            } else if (o->isText() || (o->isRenderInline() && !walker.atEndOfInline())) {
15675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (!o->isText())
15685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    toRenderInline(o)->updateAlwaysCreateLineBoxes(layoutState.isFullLayout());
15695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (layoutState.isFullLayout() || o->selfNeedsLayout())
15705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    dirtyLineBoxesForRenderer(o, layoutState.isFullLayout());
15713c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch                o->clearNeedsLayout();
15725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
15735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
15745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (size_t i = 0; i < replacedChildren.size(); i++)
15768abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            replacedChildren[i]->layoutIfNeeded();
15775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
157809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        layoutRunsAndFloats(layoutState);
15795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
15805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Expand the last line to accommodate Ruby and emphasis marks.
15825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int lastLineAnnotationsAdjustment = 0;
15835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (lastRootBox()) {
1584197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        LayoutUnit lowestAllowedPosition = std::max(lastRootBox()->lineBottom(), logicalHeight() + paddingAfter());
15855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!style()->isFlippedLinesWritingMode())
15865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            lastLineAnnotationsAdjustment = lastRootBox()->computeUnderAnnotationAdjustment(lowestAllowedPosition);
15875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else
15885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            lastLineAnnotationsAdjustment = lastRootBox()->computeOverAnnotationAdjustment(lowestAllowedPosition);
15895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
15905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Now add in the bottom border/padding.
159209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    setLogicalHeight(logicalHeight() + lastLineAnnotationsAdjustment + afterEdge);
15935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!firstLineBox() && hasLineIfEmpty())
15955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setLogicalHeight(logicalHeight() + lineHeight(true, isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
15965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // See if we have any lines that spill out of our block.  If we do, then we will possibly need to
15985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // truncate text.
15995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasTextOverflow)
16005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        checkLinesForTextOverflow();
1601197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
1602197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // Ensure the new line boxes will be painted.
1603197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (isFullLayout && firstLineBox())
1604197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        setShouldDoFullPaintInvalidation(true);
16055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1607f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void RenderBlockFlow::checkFloatsInCleanLine(RootInlineBox* line, Vector<FloatWithRect>& floats, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByFloat)
16085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
16095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<RenderBox*>* cleanLineFloats = line->floatsPtr();
16105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!cleanLineFloats)
16115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
16125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<RenderBox*>::iterator end = cleanLineFloats->end();
16145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (Vector<RenderBox*>::iterator it = cleanLineFloats->begin(); it != end; ++it) {
16155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderBox* floatingBox = *it;
16165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        floatingBox->layoutIfNeeded();
16175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LayoutSize newSize(floatingBox->width() + floatingBox->marginWidth(), floatingBox->height() + floatingBox->marginHeight());
16185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (floats[floatIndex].object != floatingBox) {
16195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            encounteredNewFloat = true;
16205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
16215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
16225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (floats[floatIndex].rect.size() != newSize) {
16245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            LayoutUnit floatTop = isHorizontalWritingMode() ? floats[floatIndex].rect.y() : floats[floatIndex].rect.x();
1625197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            LayoutUnit floatHeight = isHorizontalWritingMode() ? std::max(floats[floatIndex].rect.height(), newSize.height())
1626197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                : std::max(floats[floatIndex].rect.width(), newSize.width());
1627197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            floatHeight = std::min(floatHeight, LayoutUnit::max() - floatTop);
16285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            line->markDirty();
16295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            markLinesDirtyInBlockRange(line->lineBottomWithLeading(), floatTop + floatHeight, line);
16305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            floats[floatIndex].rect.setSize(newSize);
16315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            dirtiedByFloat = true;
16325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
16335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        floatIndex++;
16345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
16355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1637f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)RootInlineBox* RenderBlockFlow::determineStartPosition(LineLayoutState& layoutState, InlineBidiResolver& resolver)
16385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
16395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RootInlineBox* curr = 0;
16405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RootInlineBox* last = 0;
16415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: This entire float-checking block needs to be broken into a new function.
16435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool dirtiedByFloat = false;
16445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!layoutState.isFullLayout()) {
16455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Paginate all of the clean lines.
16465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool paginated = view()->layoutState() && view()->layoutState()->isPaginated();
16475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LayoutUnit paginationDelta = 0;
16485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        size_t floatIndex = 0;
16495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (curr = firstRootBox(); curr && !curr->isDirty(); curr = curr->nextRootBox()) {
16505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (paginated) {
16515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                paginationDelta -= curr->paginationStrut();
1652926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                adjustLinePositionForPagination(curr, paginationDelta, layoutState.flowThread());
16535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (paginationDelta) {
16545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (containsFloats() || !layoutState.floats().isEmpty()) {
16555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        // FIXME: Do better eventually.  For now if we ever shift because of pagination and floats are present just go to a full layout.
16565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        layoutState.markForFullLayout();
16575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        break;
16585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    }
16595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16609e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                    layoutState.updatePaintInvalidationRangeFromBox(curr, paginationDelta);
1661d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    curr->adjustBlockDirectionPosition(paginationDelta.toFloat());
16625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
16635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
16645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // If a new float has been inserted before this line or before its last known float, just do a full layout.
16665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            bool encounteredNewFloat = false;
16675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            checkFloatsInCleanLine(curr, layoutState.floats(), floatIndex, encounteredNewFloat, dirtiedByFloat);
16685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (encounteredNewFloat)
16695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                layoutState.markForFullLayout();
16705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (dirtiedByFloat || layoutState.isFullLayout())
16725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
16735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
16745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Check if a new float has been inserted after the last known float.
16755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!curr && floatIndex < layoutState.floats().size())
16765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            layoutState.markForFullLayout();
16775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
16785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (layoutState.isFullLayout()) {
1680f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        // If we encountered a new float and have inline children, mark ourself to force us to issue paint invalidations.
168109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (layoutState.hasInlineChild() && !selfNeedsLayout()) {
16825d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            setNeedsLayoutAndFullPaintInvalidation(MarkOnlyThis);
1683197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            setShouldDoFullPaintInvalidation(true);
168409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
168509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
16865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // FIXME: This should just call deleteLineBoxTree, but that causes
16875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // crashes for fast/repaint tests.
16885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        curr = firstRootBox();
16895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        while (curr) {
16905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Note: This uses nextRootBox() insted of nextLineBox() like deleteLineBoxTree does.
16915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RootInlineBox* next = curr->nextRootBox();
1692f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)            curr->deleteLine();
16935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            curr = next;
16945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
16955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(!firstLineBox() && !lastLineBox());
16965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
16975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (curr) {
16985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // We have a dirty line.
16995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (RootInlineBox* prevRootBox = curr->prevRootBox()) {
17005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // We have a previous line.
1701926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (!dirtiedByFloat && (!prevRootBox->endsWithBreak() || !prevRootBox->lineBreakObj() || (prevRootBox->lineBreakObj()->isText() && prevRootBox->lineBreakPos() >= toRenderText(prevRootBox->lineBreakObj())->textLength())))
17025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    // The previous line didn't break cleanly or broke at a newline
17035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    // that has been deleted, so treat it as dirty too.
17045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    curr = prevRootBox;
17055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
17065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
17075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // No dirty lines were found.
17085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // If the last line didn't break cleanly, treat it as dirty.
17095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (lastRootBox() && !lastRootBox()->endsWithBreak())
17105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                curr = lastRootBox();
17115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
17125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If we have no dirty lines, then last is just the last root box.
17145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        last = curr ? curr->prevRootBox() : lastRootBox();
17155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
17165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned numCleanFloats = 0;
17185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!layoutState.floats().isEmpty()) {
17195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LayoutUnit savedLogicalHeight = logicalHeight();
17205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Restore floats from clean lines.
17215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RootInlineBox* line = firstRootBox();
17225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        while (line != curr) {
17235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) {
17245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                Vector<RenderBox*>::iterator end = cleanLineFloats->end();
17255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                for (Vector<RenderBox*>::iterator f = cleanLineFloats->begin(); f != end; ++f) {
17265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    FloatingObject* floatingObject = insertFloatingObject(*f);
1727e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                    ASSERT(!floatingObject->originatingLine());
1728e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                    floatingObject->setOriginatingLine(line);
17295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    setLogicalHeight(logicalTopForChild(*f) - marginBeforeForChild(*f));
17305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    positionNewFloats();
17315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    ASSERT(layoutState.floats()[numCleanFloats].object == *f);
17325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    numCleanFloats++;
17335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
17345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
17355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            line = line->nextRootBox();
17365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
17375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setLogicalHeight(savedLogicalHeight);
17385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
17395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    layoutState.setFloatIndex(numCleanFloats);
17405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    layoutState.lineInfo().setFirstLine(!last);
17425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    layoutState.lineInfo().setPreviousLineBrokeCleanly(!last || last->endsWithBreak());
17435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (last) {
17455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setLogicalHeight(last->lineBottomWithLeading());
17465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        InlineIterator iter = InlineIterator(this, last->lineBreakObj(), last->lineBreakPos());
17475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        resolver.setPosition(iter, numberOfIsolateAncestors(iter));
17485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        resolver.setStatus(last->lineBreakBidiStatus());
17495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
17505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        TextDirection direction = style()->direction();
17515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (style()->unicodeBidi() == Plaintext)
1752c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)            direction = determinePlaintextDirectionality(this);
17535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        resolver.setStatus(BidiStatus(direction, isOverride(style()->unicodeBidi())));
1754c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        InlineIterator iter = InlineIterator(this, bidiFirstSkippingEmptyInlines(this, resolver.runs(), &resolver), 0);
17555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        resolver.setPosition(iter, numberOfIsolateAncestors(iter));
17565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
17575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return curr;
17585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1760f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void RenderBlockFlow::determineEndPosition(LineLayoutState& layoutState, RootInlineBox* startLine, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus)
17615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!layoutState.endLine());
17635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t floatIndex = layoutState.floatIndex();
17645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RootInlineBox* last = 0;
17655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (RootInlineBox* curr = startLine->nextRootBox(); curr; curr = curr->nextRootBox()) {
17665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!curr->isDirty()) {
17675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            bool encounteredNewFloat = false;
17685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            bool dirtiedByFloat = false;
17695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            checkFloatsInCleanLine(curr, layoutState.floats(), floatIndex, encounteredNewFloat, dirtiedByFloat);
17705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (encounteredNewFloat)
17715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return;
17725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
17735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (curr->isDirty())
17745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            last = 0;
17755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else if (!last)
17765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            last = curr;
17775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
17785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!last)
17805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
17815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // At this point, |last| is the first line in a run of clean lines that ends with the last line
17835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // in the block.
17845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RootInlineBox* prev = last->prevRootBox();
17865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    cleanLineStart = InlineIterator(this, prev->lineBreakObj(), prev->lineBreakPos());
17875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    cleanLineBidiStatus = prev->lineBreakBidiStatus();
17885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    layoutState.setEndLineLogicalTop(prev->lineBottomWithLeading());
17895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (RootInlineBox* line = last; line; line = line->nextRootBox())
17915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        line->extractLine(); // Disconnect all line boxes from their render objects while preserving
17925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                             // their connections to one another.
17935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    layoutState.setEndLine(last);
17955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1797f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)bool RenderBlockFlow::checkPaginationAndFloatsAtEndLine(LineLayoutState& layoutState)
17985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit lineDelta = logicalHeight() - layoutState.endLineLogicalTop();
18005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool paginated = view()->layoutState() && view()->layoutState()->isPaginated();
1802926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (paginated && layoutState.flowThread()) {
18035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Check all lines from here to the end, and see if the hypothetical new position for the lines will result
18045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // in a different available line width.
18055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (RootInlineBox* lineBox = layoutState.endLine(); lineBox; lineBox = lineBox->nextRootBox()) {
18065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (paginated) {
18075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // This isn't the real move we're going to do, so don't update the line box's pagination
18085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // strut yet.
18095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                LayoutUnit oldPaginationStrut = lineBox->paginationStrut();
18105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                lineDelta -= oldPaginationStrut;
1811926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                adjustLinePositionForPagination(lineBox, lineDelta, layoutState.flowThread());
18125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                lineBox->setPaginationStrut(oldPaginationStrut);
18135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
18145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
18155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
181602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
18171fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    if (!lineDelta || !m_floatingObjects)
18185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
181902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
18205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // See if any floats end in the range along which we want to shift the lines vertically.
1821197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    LayoutUnit logicalTop = std::min(logicalHeight(), layoutState.endLineLogicalTop());
18225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RootInlineBox* lastLine = layoutState.endLine();
18245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (RootInlineBox* nextLine = lastLine->nextRootBox())
18255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        lastLine = nextLine;
18265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit logicalBottom = lastLine->lineBottomWithLeading() + absoluteValue(lineDelta);
18285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18291fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
18305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FloatingObjectSetIterator end = floatingObjectSet.end();
18315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
1832d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        FloatingObject* floatingObject = it->get();
1833f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        if (logicalBottomForFloat(floatingObject) >= logicalTop && logicalBottomForFloat(floatingObject) < logicalBottom)
18345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
18355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
18365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
18385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
18395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1840f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)bool RenderBlockFlow::matchedEndLine(LineLayoutState& layoutState, const InlineBidiResolver& resolver, const InlineIterator& endLineStart, const BidiStatus& endLineStatus)
18415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
18425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (resolver.position() == endLineStart) {
18435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (resolver.status() != endLineStatus)
18445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
18455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return checkPaginationAndFloatsAtEndLine(layoutState);
18465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
18475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The first clean line doesn't match, but we can check a handful of following lines to try
18495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // to match back up.
18505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    static int numLines = 8; // The # of lines we're willing to match against.
18515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RootInlineBox* originalEndLine = layoutState.endLine();
18525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RootInlineBox* line = originalEndLine;
18535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (int i = 0; i < numLines && line; i++, line = line->nextRootBox()) {
185409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (line->lineBreakObj() == resolver.position().object() && line->lineBreakPos() == resolver.position().offset()) {
18555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // We have a match.
18565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (line->lineBreakBidiStatus() != resolver.status())
18575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return false; // ...but the bidi state doesn't match.
185802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
18595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            bool matched = false;
18605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RootInlineBox* result = line->nextRootBox();
18615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            layoutState.setEndLine(result);
18625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (result) {
18635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                layoutState.setEndLineLogicalTop(line->lineBottomWithLeading());
18645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                matched = checkPaginationAndFloatsAtEndLine(layoutState);
18655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
18665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Now delete the lines that we failed to sync.
1868f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)            deleteLineRange(layoutState, originalEndLine, result);
18695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return matched;
18705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
18715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
18725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
18745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
18755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
187651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)bool RenderBlockFlow::generatesLineBoxesForInlineChild(RenderObject* inlineObj)
18775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
18795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(inlineObj->parent() == this);
18805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InlineIterator it(this, inlineObj, 0);
18825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: We should pass correct value for WhitespacePosition.
18835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (!it.atEnd() && !requiresLineBox(it))
18845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        it.increment();
18855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return !it.atEnd();
18875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
18885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1890a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)void RenderBlockFlow::addOverflowFromInlineChildren()
18915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
18925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit endPadding = hasOverflowClip() ? paddingEnd() : LayoutUnit();
18935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: Need to find another way to do this, since scrollbars could show when we don't want them to.
18945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasOverflowClip() && !endPadding && node() && node()->isRootEditableElement() && style()->isLeftToRightDirection())
18955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        endPadding = 1;
18965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
18975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        addLayoutOverflow(curr->paddedLayoutOverflowRect(endPadding));
18983c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        LayoutRect visualOverflow = curr->visualOverflowRect(curr->lineTop(), curr->lineBottom());
18993c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        addContentsVisualOverflow(visualOverflow);
19005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
19015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
19025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1903f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void RenderBlockFlow::deleteEllipsisLineBoxes()
19045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
19055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ETextAlign textAlign = style()->textAlign();
19065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool ltr = style()->isLeftToRightDirection();
19075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool firstLine = true;
19085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
19095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (curr->hasEllipsisBox()) {
19105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            curr->clearTruncation();
19115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Shift the line back where it belongs if we cannot accomodate an ellipsis.
1913f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)            float logicalLeft = logicalLeftOffsetForLine(curr->lineTop(), firstLine).toFloat();
19145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            float availableLogicalWidth = logicalRightOffsetForLine(curr->lineTop(), false) - logicalLeft;
19155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            float totalLogicalWidth = curr->logicalWidth();
19168abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            updateLogicalWidthForAlignment(textAlign, curr, 0, logicalLeft, totalLogicalWidth, availableLogicalWidth, 0);
19175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (ltr)
19195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                curr->adjustLogicalPosition((logicalLeft - curr->logicalLeft()), 0);
19205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            else
19215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                curr->adjustLogicalPosition(-(curr->logicalLeft() - logicalLeft), 0);
19225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
19235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        firstLine = false;
19245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
19255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
19265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1927f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void RenderBlockFlow::checkLinesForTextOverflow()
19285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
19295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Determine the width of the ellipsis using the current font.
19305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: CSS3 says this is configurable, also need to use 0x002E (FULL STOP) if horizontal ellipsis is "not renderable"
19315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Font& font = style()->font();
19325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DEFINE_STATIC_LOCAL(AtomicString, ellipsisStr, (&horizontalEllipsis, 1));
19335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Font& firstLineFont = firstLineStyle()->font();
193409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // FIXME: We should probably not hard-code the direction here. https://crbug.com/333004
193509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    TextDirection ellipsisDirection = LTR;
1936f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    float firstLineEllipsisWidth = firstLineFont.width(constructTextRun(this, firstLineFont, &horizontalEllipsis, 1, firstLineStyle(), ellipsisDirection));
1937f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    float ellipsisWidth = (font == firstLineFont) ? firstLineEllipsisWidth : font.width(constructTextRun(this, font, &horizontalEllipsis, 1, style(), ellipsisDirection));
19385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // For LTR text truncation, we want to get the right edge of our padding box, and then we want to see
19405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // if the right edge of a line box exceeds that.  For RTL, we use the left edge of the padding box and
19415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // check the left edge of the line box to see if it is less
19425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Include the scrollbar for overflow blocks, which means we want to use "contentWidth()"
19435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool ltr = style()->isLeftToRightDirection();
19445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ETextAlign textAlign = style()->textAlign();
19455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool firstLine = true;
19465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
194709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        float currLogicalLeft = curr->logicalLeft();
1948f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        LayoutUnit blockRightEdge = logicalRightOffsetForLine(curr->lineTop(), firstLine);
1949f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        LayoutUnit blockLeftEdge = logicalLeftOffsetForLine(curr->lineTop(), firstLine);
1950f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        LayoutUnit lineBoxEdge = ltr ? currLogicalLeft + curr->logicalWidth() : currLogicalLeft;
19515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if ((ltr && lineBoxEdge > blockRightEdge) || (!ltr && lineBoxEdge < blockLeftEdge)) {
19525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // This line spills out of our box in the appropriate direction.  Now we need to see if the line
19535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // can be truncated.  In order for truncation to be possible, the line must have sufficient space to
19545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // accommodate our truncation string, and no replaced elements (images, tables) can overlap the ellipsis
19555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // space.
19565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            LayoutUnit width = firstLine ? firstLineEllipsisWidth : ellipsisWidth;
19585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            LayoutUnit blockEdge = ltr ? blockRightEdge : blockLeftEdge;
19595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (curr->lineCanAccommodateEllipsis(ltr, blockEdge, lineBoxEdge, width)) {
1960f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)                float totalLogicalWidth = curr->placeEllipsis(ellipsisStr, ltr, blockLeftEdge.toFloat(), blockRightEdge.toFloat(), width.toFloat());
19615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                float logicalLeft = 0; // We are only intersted in the delta from the base position.
1963f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)                float availableLogicalWidth = (blockRightEdge - blockLeftEdge).toFloat();
196409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                updateLogicalWidthForAlignment(textAlign, curr, 0, logicalLeft, totalLogicalWidth, availableLogicalWidth, 0);
19655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (ltr)
19665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    curr->adjustLogicalPosition(logicalLeft, 0);
19675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                else
196809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    curr->adjustLogicalPosition(logicalLeft - (availableLogicalWidth - totalLogicalWidth), 0);
19695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
19705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
19715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        firstLine = false;
19725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
19735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
19745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1975f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)bool RenderBlockFlow::positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine, LineInfo& lineInfo, LineWidth& width)
19765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
19775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!positionNewFloats())
19785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
19795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    width.shrinkAvailableWidthForNewFloatIfNeeded(newFloat);
19815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We only connect floats to lines for pagination purposes if the floats occur at the start of
19835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // the line and the previous line had a hard break (so this line is either the first in the block
19845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // or follows a <br>).
1985e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    if (!newFloat->paginationStrut() || !lineInfo.previousLineBrokeCleanly() || !lineInfo.isEmpty())
19865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
19875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19881fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
19895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(floatingObjectSet.last() == newFloat);
19905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1991f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    LayoutUnit floatLogicalTop = logicalTopForFloat(newFloat);
1992e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    int paginationStrut = newFloat->paginationStrut();
19935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (floatLogicalTop - paginationStrut != logicalHeight() + lineInfo.floatPaginationStrut())
19955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
19965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FloatingObjectSetIterator it = floatingObjectSet.end();
19985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    --it; // Last float is newFloat, skip that one.
19995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FloatingObjectSetIterator begin = floatingObjectSet.begin();
20005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (it != begin) {
20015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        --it;
2002d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        FloatingObject* floatingObject = it->get();
2003f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        if (floatingObject == lastFloatFromPreviousLine)
20045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
2005f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        if (logicalTopForFloat(floatingObject) == logicalHeight() + lineInfo.floatPaginationStrut()) {
2006f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            floatingObject->setPaginationStrut(paginationStrut + floatingObject->paginationStrut());
2007f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            RenderBox* floatBox = floatingObject->renderer();
2008f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            setLogicalTopForChild(floatBox, logicalTopForChild(floatBox) + marginBeforeForChild(floatBox) + paginationStrut);
2009f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            if (floatBox->isRenderBlock())
2010f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)                floatBox->forceChildLayout();
2011e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            else
2012f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)                floatBox->layoutIfNeeded();
20135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Save the old logical top before calling removePlacedObject which will set
20145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // isPlaced to false. Otherwise it will trigger an assert in logicalTopForFloat.
2015f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            LayoutUnit oldLogicalTop = logicalTopForFloat(floatingObject);
2016f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            m_floatingObjects->removePlacedObject(floatingObject);
2017f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            setLogicalTopForFloat(floatingObject, oldLogicalTop + paginationStrut);
2018f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            m_floatingObjects->addPlacedObject(floatingObject);
20195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
20205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
20215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Just update the line info's pagination strut without altering our logical height yet. If the line ends up containing
20235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // no content, then we don't want to improperly grow the height of the block.
20245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    lineInfo.setFloatPaginationStrut(lineInfo.floatPaginationStrut() + paginationStrut);
20255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
20265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
20275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
202851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)LayoutUnit RenderBlockFlow::startAlignedOffsetForLine(LayoutUnit position, bool firstLine)
20295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
20305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ETextAlign textAlign = style()->textAlign();
20315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (textAlign == TASTART) // FIXME: Handle TAEND here
20335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return startOffsetForLine(position, firstLine);
20345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // updateLogicalWidthForAlignment() handles the direction of the block so no need to consider it here
20365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float totalLogicalWidth = 0;
2037d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false).toFloat();
20385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), false) - logicalLeft;
20398abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWidth, availableLogicalWidth, 0);
20405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!style()->isLeftToRightDirection())
20425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return logicalWidth() - logicalLeft;
20435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return logicalLeft;
20445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
20455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2047