RenderBlock.cpp revision 2daae5fd11344eaa88a0d92b0f6d65f8d2255c00
18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 1999 Antti Koivisto (koivisto@kde.org)
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 2007 David Smith (catfish.man@gmail.com)
5d0825bca7fe65beaee391d30da42e937db621564Steve Block * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
6967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * Copyright (C) Research In Motion Limited 2010. All rights reserved.
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderBlock.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
275abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#include "ColumnInfo.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Element.h"
308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "FloatQuad.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameView.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "GraphicsContext.h"
345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "HTMLFormElement.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HitTestResult.h"
372bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "InlineIterator.h"
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "InlineTextBox.h"
3965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "PaintInfo.h"
402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "RenderCombineText.h"
41231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "RenderFlexibleBox.h"
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderImage.h"
43635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "RenderInline.h"
44545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch#include "RenderLayer.h"
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderMarquee.h"
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderReplica.h"
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderTableCell.h"
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderTextFragment.h"
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderTheme.h"
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderView.h"
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SelectionController.h"
525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "Settings.h"
53ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "TextRun.h"
54643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "TransformState.h"
55635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <wtf/StdLibExtras.h>
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_LAYOUT
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Settings.h"
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std;
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace WTF;
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace Unicode;
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames;
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttypedef WTF::HashMap<const RenderBox*, ColumnInfo*> ColumnInfoMap;
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic ColumnInfoMap* gColumnInfoMap = 0;
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttypedef WTF::HashMap<const RenderBlock*, HashSet<RenderBox*>*> PercentHeightDescendantsMap;
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic PercentHeightDescendantsMap* gPercentHeightDescendantsMap = 0;
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttypedef WTF::HashMap<const RenderBox*, HashSet<RenderBlock*>*> PercentHeightContainerMap;
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic PercentHeightContainerMap* gPercentHeightContainerMap = 0;
77635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qiantypedef WTF::HashMap<RenderBlock*, ListHashSet<RenderInline*>*> ContinuationOutlineTableMap;
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochtypedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet;
810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic int gDelayUpdateScrollInfo = 0;
820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0;
830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Our MarginInfo state used when laying out block children.
85bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenRenderBlock::MarginInfo::MarginInfo(RenderBlock* block, int beforeBorderPadding, int afterBorderPadding)
86bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    : m_atBeforeSideOfBlock(true)
87bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    , m_atAfterSideOfBlock(false)
88bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    , m_marginBeforeQuirk(false)
89bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    , m_marginAfterQuirk(false)
90bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    , m_determinedMarginBeforeQuirk(false)
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Whether or not we can collapse our own margins with our children.  We don't do this
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // if we had any border/padding (obviously), if we're the root or HTML elements, or if
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // we're positioned, floating, a table cell.
95bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_canCollapseWithChildren = !block->isRenderView() && !block->isRoot() && !block->isPositioned()
96bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        && !block->isFloating() && !block->isTableCell() && !block->hasOverflowClip() && !block->isInlineBlockOrInlineTable()
97a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        && !block->isWritingModeRoot();
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
99bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_canCollapseMarginBeforeWithChildren = m_canCollapseWithChildren && (beforeBorderPadding == 0) && block->style()->marginBeforeCollapse() != MSEPARATE;
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If any height other than auto is specified in CSS, then we don't collapse our bottom
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // margins with our children's margins.  To do otherwise would be to risk odd visual
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // effects when the children overflow out of the parent block and yet still collapse
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // with it.  We also don't collapse if we have any bottom border/padding.
105bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_canCollapseMarginAfterWithChildren = m_canCollapseWithChildren && (afterBorderPadding == 0) &&
106bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        (block->style()->logicalHeight().isAuto() && block->style()->logicalHeight().value() == 0) && block->style()->marginAfterCollapse() != MSEPARATE;
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
108bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_quirkContainer = block->isTableCell() || block->isBody() || block->style()->marginBeforeCollapse() == MDISCARD ||
109bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        block->style()->marginAfterCollapse() == MDISCARD;
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
111a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_positiveMargin = m_canCollapseMarginBeforeWithChildren ? block->maxPositiveMarginBefore() : 0;
112a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_negativeMargin = m_canCollapseMarginBeforeWithChildren ? block->maxNegativeMarginBefore() : 0;
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// -------------------------------------------------------------------------------------------------------
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderBlock::RenderBlock(Node* node)
1188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian      : RenderBox(node)
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project      , m_floatingObjects(0)
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project      , m_positionedObjects(0)
12168513a70bcd92384395513322f1b801e7bf9c729Steve Block      , m_rareData(0)
1228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian      , m_lineHeight(-1)
12365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch      , m_beingDestroyed(false)
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    setChildrenInline(true);
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderBlock::~RenderBlock()
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_floatingObjects)
13181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        deleteAllValues(m_floatingObjects->set());
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (hasColumns())
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        delete gColumnInfoMap->take(this);
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (gPercentHeightDescendantsMap) {
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->take(this)) {
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            HashSet<RenderBox*>::iterator end = descendantSet->end();
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (HashSet<RenderBox*>::iterator descendant = descendantSet->begin(); descendant != end; ++descendant) {
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(*descendant);
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                ASSERT(containerSet);
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!containerSet)
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                ASSERT(containerSet->contains(this));
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                containerSet->remove(this);
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (containerSet->isEmpty()) {
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    gPercentHeightContainerMap->remove(*descendant);
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    delete containerSet;
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            delete descendantSet;
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::destroy()
1578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
15865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // Mark as being destroyed to avoid trouble with merges in removeChild().
15965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_beingDestroyed = true;
16065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
161643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
162643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
163643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    children()->destroyLeftoverChildren();
1648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
165643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // Destroy our continuation before anything other than anonymous children.
166643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // The reason we don't destroy it before anonymous children is that they may
167643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // have continuations of their own that are anonymous children of our continuation.
168cad810f21b803229eb11403f9209855525a25d57Steve Block    RenderBoxModelObject* continuation = this->continuation();
169cad810f21b803229eb11403f9209855525a25d57Steve Block    if (continuation) {
170cad810f21b803229eb11403f9209855525a25d57Steve Block        continuation->destroy();
171cad810f21b803229eb11403f9209855525a25d57Steve Block        setContinuation(0);
172643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
173643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
1748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!documentBeingDestroyed()) {
1758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (firstLineBox()) {
1768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // We can't wait for RenderBox::destroy to clear the selection,
1778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // because by then we will have nuked the line boxes.
1788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // FIXME: The SelectionController should be responsible for this when it
1798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // is notified of DOM mutations.
1808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (isSelectionBorder())
1818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                view()->clearSelection();
1828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // If we are an anonymous block, then our line boxes might have children
1848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // that will outlast this block. In the non-anonymous block case those
1858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // children will be destroyed by the time we return from this function.
1868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (isAnonymousBlock()) {
187dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox()) {
1888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    while (InlineBox* childBox = box->firstChild())
1898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        childBox->remove();
1908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                }
1918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
1928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (isInline() && parent())
1938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            parent()->dirtyLinesFromChangedChild(this);
1948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_lineBoxes.deleteLineBoxes(renderArena());
1978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBox::destroy();
1998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
2008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
20365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    setReplaced(newStyle->isDisplayInlineType());
204635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
2058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (style() && parent() && diff == StyleDifferenceLayout && style()->position() != newStyle->position()) {
206635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (newStyle->position() == StaticPosition)
207635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // Clear our positioned objects list. Our absolutely positioned descendants will be
208635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // inserted into our containing block's positioned objects list during layout.
209635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            removePositionedObjects(0);
210635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        else if (style()->position() == StaticPosition) {
211635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // Remove our absolutely positioned descendants from their current containing block.
212635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // They will be inserted into our positioned objects list during layout.
213635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            RenderObject* cb = parent();
214635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            while (cb && (cb->style()->position() == StaticPosition || (cb->isInline() && !cb->isReplaced())) && !cb->isRenderView()) {
215635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (cb->style()->position() == RelativePosition && cb->isInline() && !cb->isReplaced()) {
216635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    cb = cb->containingBlock();
217635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    break;
218635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                }
219635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                cb = cb->parent();
220635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
221635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
222635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (cb->isRenderBlock())
2238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                toRenderBlock(cb)->removePositionedObjects(this);
224635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
225635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
226635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
2278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBox::styleWillChange(diff, newStyle);
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBox::styleDidChange(diff, oldStyle);
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
234545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (!isAnonymousBlock()) {
235545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // Ensure that all of our continuation blocks pick up the new style.
236545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        for (RenderBlock* currCont = blockElementContinuation(); currCont; currCont = currCont->blockElementContinuation()) {
237545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            RenderBoxModelObject* nextCont = currCont->continuation();
238545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            currCont->setContinuation(0);
239545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            currCont->setStyle(style());
240545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            currCont->setContinuation(nextCont);
241545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        }
242545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
243545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: We could save this call when the change only affected non-inherited properties
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (child->isAnonymousBlock()) {
2472bde8e466a4451c7319e3a072d118917957d6554Steve Block            RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
2485af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            if (style()->specifiesColumns()) {
2495af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                if (child->style()->specifiesColumns())
2505af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                    newStyle->inheritColumnPropertiesFrom(style());
2515af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                if (child->style()->columnSpan())
2525af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                    newStyle->setColumnSpan(true);
2535af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            }
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            newStyle->setDisplay(BLOCK);
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            child->setStyle(newStyle.release());
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_lineHeight = -1;
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Update pseudos for :before and :after now.
262635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!isAnonymous() && document()->usesBeforeAfterRules() && canHaveChildren()) {
2638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        updateBeforeAfterContent(BEFORE);
2648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        updateBeforeAfterContent(AFTER);
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::updateBeforeAfterContent(PseudoId pseudoId)
2698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
2708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If this is an anonymous wrapper, then the parent applies its own pseudo-element style to it.
2718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (parent() && parent()->createsAnonymousWrapper())
2728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
2738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return children()->updateBeforeAfterContent(this, pseudoId);
2748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
2755af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
276545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRenderBlock* RenderBlock::continuationBefore(RenderObject* beforeChild)
277545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
278545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (beforeChild && beforeChild->parent() == this)
279545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return this;
280545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
281545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBlock* curr = toRenderBlock(continuation());
282545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBlock* nextToLast = this;
283545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBlock* last = this;
284545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    while (curr) {
285545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (beforeChild && beforeChild->parent() == curr) {
286545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            if (curr->firstChild() == beforeChild)
287545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                return last;
288545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            return curr;
289545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        }
290545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
291545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        nextToLast = last;
292545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        last = curr;
293545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        curr = toRenderBlock(curr->continuation());
294545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
295545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
296545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (!beforeChild && !last->firstChild())
297545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return nextToLast;
298545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return last;
299545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
300545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
301545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid RenderBlock::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild)
302545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
303545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBlock* flow = continuationBefore(beforeChild);
304545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    ASSERT(!beforeChild || beforeChild->parent()->isAnonymousColumnSpanBlock() || beforeChild->parent()->isRenderBlock());
305545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBoxModelObject* beforeChildParent = 0;
306545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (beforeChild)
307545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        beforeChildParent = toRenderBoxModelObject(beforeChild->parent());
308545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    else {
309545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        RenderBoxModelObject* cont = flow->continuation();
310545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (cont)
311545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            beforeChildParent = cont;
312545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        else
313545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            beforeChildParent = flow;
314545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
315545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
316545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (newChild->isFloatingOrPositioned())
317545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
318545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
319545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // A continuation always consists of two potential candidates: a block or an anonymous
320545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // column span box holding column span children.
321545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    bool childIsNormal = newChild->isInline() || !newChild->style()->columnSpan();
322545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    bool bcpIsNormal = beforeChildParent->isInline() || !beforeChildParent->style()->columnSpan();
323545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    bool flowIsNormal = flow->isInline() || !flow->style()->columnSpan();
324545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
325545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (flow == beforeChildParent)
326545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return flow->addChildIgnoringContinuation(newChild, beforeChild);
327545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
328545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // The goal here is to match up if we can, so that we can coalesce and create the
329545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // minimal # of continuations needed for the inline.
330545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (childIsNormal == bcpIsNormal)
331545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
332545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (flowIsNormal == childIsNormal)
333545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return flow->addChildIgnoringContinuation(newChild, 0); // Just treat like an append.
334545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
335545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
336545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
337545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
3385af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
3395af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
3405af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    ASSERT(!continuation()); // We don't yet support column spans that aren't immediate children of the multi-column block.
3415af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
3425af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // The goal is to locate a suitable box in which to place our child.
343bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    RenderBlock* beforeChildParent = toRenderBlock(beforeChild && beforeChild->parent()->isRenderBlock() ? beforeChild->parent() : lastChild());
3448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3455af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // If the new child is floating or positioned it can just go in that block.
3465af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (newChild->isFloatingOrPositioned())
3475af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
3485af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
3495af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // See if the child can be placed in the box.
3505af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    bool newChildHasColumnSpan = newChild->style()->columnSpan() && !newChild->isInline();
3515af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    bool beforeChildParentHoldsColumnSpans = beforeChildParent->isAnonymousColumnSpanBlock();
3525af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
3535af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (newChildHasColumnSpan == beforeChildParentHoldsColumnSpans)
3545af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
3555af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
3565af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (!beforeChild) {
3575af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        // Create a new block of the correct type.
3585af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
3595af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        children()->appendChildNode(this, newBox);
3605af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
3615af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return;
3625af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    }
3635af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
3645af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderObject* immediateChild = beforeChild;
3655af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    bool isPreviousBlockViable = true;
3665af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    while (immediateChild->parent() != this) {
3675af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (isPreviousBlockViable)
3685af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            isPreviousBlockViable = !immediateChild->previousSibling();
3695af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        immediateChild = immediateChild->parent();
3705af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    }
3715af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (isPreviousBlockViable && immediateChild->previousSibling())
3725af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return toRenderBlock(immediateChild->previousSibling())->addChildIgnoringAnonymousColumnBlocks(newChild, 0); // Treat like an append.
3735af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
3745af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // Split our anonymous blocks.
3755af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderObject* newBeforeChild = splitAnonymousBlocksAroundChild(beforeChild);
3765af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
3775af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // Create a new anonymous box of the appropriate type.
3785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
3795af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    children()->insertChildNode(this, newBox, newBeforeChild);
3805af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
3815af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return;
3825af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
3835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
384545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRenderBlock* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBlock)
385545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
386545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    for (RenderObject* curr = this; curr; curr = curr->parent()) {
387545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (!curr->isRenderBlock() || curr->isFloatingOrPositioned() || curr->isTableCell() || curr->isRoot() || curr->isRenderView() || curr->hasOverflowClip()
388545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            || curr->isInlineBlockOrInlineTable())
389545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            return 0;
390545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
391545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        RenderBlock* currBlock = toRenderBlock(curr);
392545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (currBlock->style()->specifiesColumns() && (allowAnonymousColumnBlock || !currBlock->isAnonymousColumnsBlock()))
393545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            return currBlock;
394545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
395545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (currBlock->isAnonymousColumnSpanBlock())
396545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            return 0;
397545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
398545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return 0;
399545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
400545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
401545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRenderBlock* RenderBlock::clone() const
402545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
403cad810f21b803229eb11403f9209855525a25d57Steve Block    RenderBlock* cloneBlock;
404cad810f21b803229eb11403f9209855525a25d57Steve Block    if (isAnonymousBlock())
405cad810f21b803229eb11403f9209855525a25d57Steve Block        cloneBlock = createAnonymousBlock();
406cad810f21b803229eb11403f9209855525a25d57Steve Block    else {
407cad810f21b803229eb11403f9209855525a25d57Steve Block        cloneBlock = new (renderArena()) RenderBlock(node());
408cad810f21b803229eb11403f9209855525a25d57Steve Block        cloneBlock->setStyle(style());
409cad810f21b803229eb11403f9209855525a25d57Steve Block    }
410cad810f21b803229eb11403f9209855525a25d57Steve Block    cloneBlock->setChildrenInline(childrenInline());
411cad810f21b803229eb11403f9209855525a25d57Steve Block    return cloneBlock;
412545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
413545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
414545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
415545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                              RenderBlock* middleBlock,
416545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                              RenderObject* beforeChild, RenderBoxModelObject* oldCont)
417545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
418545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Create a clone of this inline.
419cad810f21b803229eb11403f9209855525a25d57Steve Block    RenderBlock* cloneBlock = clone();
420cad810f21b803229eb11403f9209855525a25d57Steve Block    if (!isAnonymousBlock())
4214a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        cloneBlock->setContinuation(oldCont);
422545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
423545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Now take all of the children from beforeChild to the end and remove
424545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // them from |this| and place them in the clone.
425545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (!beforeChild && isAfterContent(lastChild()))
426545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        beforeChild = lastChild();
427545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    moveChildrenTo(cloneBlock, beforeChild, 0);
428545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
429545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Hook |clone| up as the continuation of the middle block.
4304a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    if (!cloneBlock->isAnonymousBlock())
4314a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        middleBlock->setContinuation(cloneBlock);
432545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
433545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // We have been reparented and are now under the fromBlock.  We need
434545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // to walk up our block parent chain until we hit the containing anonymous columns block.
435545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Once we hit the anonymous columns block we're done.
436545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBoxModelObject* curr = toRenderBoxModelObject(parent());
437545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBoxModelObject* currChild = this;
438545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
439545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    while (curr && curr != fromBlock) {
4404a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        ASSERT(curr->isRenderBlock());
441545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
442545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        RenderBlock* blockCurr = toRenderBlock(curr);
443545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
444545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // Create a new clone.
445545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        RenderBlock* cloneChild = cloneBlock;
446cad810f21b803229eb11403f9209855525a25d57Steve Block        cloneBlock = blockCurr->clone();
447545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
448545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // Insert our child clone as the first child.
449545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        cloneBlock->children()->appendChildNode(cloneBlock, cloneChild);
450545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
451545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // Hook the clone up as a continuation of |curr|.  Note we do encounter
452545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // anonymous blocks possibly as we walk up the block chain.  When we split an
453545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // anonymous block, there's no need to do any continuation hookup, since we haven't
454545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // actually split a real element.
455545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (!blockCurr->isAnonymousBlock()) {
456545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            oldCont = blockCurr->continuation();
457545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            blockCurr->setContinuation(cloneBlock);
458545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            cloneBlock->setContinuation(oldCont);
459545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        }
460545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
461545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // Someone may have indirectly caused a <q> to split.  When this happens, the :after content
462545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // has to move into the inline continuation.  Call updateBeforeAfterContent to ensure that the inline's :after
463545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // content gets properly destroyed.
464545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (document()->usesBeforeAfterRules())
465545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            blockCurr->children()->updateBeforeAfterContent(blockCurr, AFTER);
466545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
467545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // Now we need to take all of the children starting from the first child
468545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // *after* currChild and append them all to the clone.
469545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        RenderObject* afterContent = isAfterContent(cloneBlock->lastChild()) ? cloneBlock->lastChild() : 0;
470545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        blockCurr->moveChildrenTo(cloneBlock, currChild->nextSibling(), 0, afterContent);
471545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
472545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // Keep walking up the chain.
473545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        currChild = curr;
474545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        curr = toRenderBoxModelObject(curr->parent());
475545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
476545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
477545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Now we are at the columns block level. We need to put the clone into the toBlock.
478545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    toBlock->children()->appendChildNode(toBlock, cloneBlock);
479545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
480545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Now take all the children after currChild and remove them from the fromBlock
481545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // and put them in the toBlock.
482545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    fromBlock->moveChildrenTo(toBlock, currChild->nextSibling(), 0);
483545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
484545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
485545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid RenderBlock::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
486545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                            RenderObject* newChild, RenderBoxModelObject* oldCont)
487545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
488545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBlock* pre = 0;
489545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBlock* block = containingColumnsBlock();
490545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
491545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Delete our line boxes before we do the inline split into continuations.
492545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    block->deleteLineBoxTree();
493545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
494545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    bool madeNewBeforeBlock = false;
495545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (block->isAnonymousColumnsBlock()) {
496545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // We can reuse this block and make it the preBlock of the next continuation.
497545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        pre = block;
498545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        pre->removePositionedObjects(0);
499545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        block = toRenderBlock(block->parent());
500545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    } else {
501545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // No anonymous block available for use.  Make one.
502545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        pre = block->createAnonymousColumnsBlock();
503545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        pre->setChildrenInline(false);
504545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        madeNewBeforeBlock = true;
505545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
506545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
507545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBlock* post = block->createAnonymousColumnsBlock();
508545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    post->setChildrenInline(false);
509545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
510545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
511545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (madeNewBeforeBlock)
512545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        block->children()->insertChildNode(block, pre, boxFirst);
513545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    block->children()->insertChildNode(block, newBlockBox, boxFirst);
514545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    block->children()->insertChildNode(block, post, boxFirst);
515545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    block->setChildrenInline(false);
516545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
517545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (madeNewBeforeBlock)
518545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        block->moveChildrenTo(pre, boxFirst, 0);
519545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
520545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    splitBlocks(pre, post, newBlockBox, beforeChild, oldCont);
521545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
522545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
523545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // time in makeChildrenNonInline by just setting this explicitly up front.
524545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    newBlockBox->setChildrenInline(false);
525545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
526545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // We delayed adding the newChild until now so that the |newBlockBox| would be fully
527545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // connected, thus allowing newChild access to a renderArena should it need
528545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // to wrap itself in additional boxes (e.g., table construction).
529545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    newBlockBox->addChild(newChild);
530545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
531545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
532545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // get deleted properly.  Because objects moves from the pre block into the post block, we want to
533545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // make new line boxes instead of leaving the old line boxes around.
534545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    pre->setNeedsLayoutAndPrefWidthsRecalc();
535545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    block->setNeedsLayoutAndPrefWidthsRecalc();
536545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    post->setNeedsLayoutAndPrefWidthsRecalc();
537545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
538545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
5395af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeRenderObject* RenderBlock::splitAnonymousBlocksAroundChild(RenderObject* beforeChild)
5405af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
5415af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    while (beforeChild->parent() != this) {
5425af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        RenderBlock* blockToSplit = toRenderBlock(beforeChild->parent());
5435af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (blockToSplit->firstChild() != beforeChild) {
5445af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // We have to split the parentBlock into two blocks.
5455af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            RenderBlock* post = createAnonymousBlockWithSameTypeAs(blockToSplit);
5465af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            post->setChildrenInline(blockToSplit->childrenInline());
5475af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            RenderBlock* parentBlock = toRenderBlock(blockToSplit->parent());
5485af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            parentBlock->children()->insertChildNode(parentBlock, post, blockToSplit->nextSibling());
5495af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            blockToSplit->moveChildrenTo(post, beforeChild, 0, blockToSplit->hasLayer());
5505af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            post->setNeedsLayoutAndPrefWidthsRecalc();
5515af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            blockToSplit->setNeedsLayoutAndPrefWidthsRecalc();
5525af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            beforeChild = post;
5535af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        } else
5545af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            beforeChild = blockToSplit;
5555af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    }
5565af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return beforeChild;
5575af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
5585af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
5595af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild)
5605af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
5615af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderBlock* pre = 0;
5625af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderBlock* post = 0;
5635af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderBlock* block = this; // Eventually block will not just be |this|, but will also be a block nested inside |this|.  Assign to a variable
5645af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                               // so that we don't have to patch all of the rest of the code later on.
5655af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
5665af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // Delete the block's line boxes before we do the split.
5675af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    block->deleteLineBoxTree();
568545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
5695af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (beforeChild && beforeChild->parent() != this)
5705af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        beforeChild = splitAnonymousBlocksAroundChild(beforeChild);
571545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
5725af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (beforeChild != firstChild()) {
5735af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        pre = block->createAnonymousColumnsBlock();
5745af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        pre->setChildrenInline(block->childrenInline());
5755af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    }
5765af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
5775af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (beforeChild) {
5785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        post = block->createAnonymousColumnsBlock();
5795af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        post->setChildrenInline(block->childrenInline());
5805af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    }
5815af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
5825af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderObject* boxFirst = block->firstChild();
5835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (pre)
5845af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        block->children()->insertChildNode(block, pre, boxFirst);
5855af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    block->children()->insertChildNode(block, newBlockBox, boxFirst);
5865af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (post)
5875af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        block->children()->insertChildNode(block, post, boxFirst);
5885af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    block->setChildrenInline(false);
5895af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
5905af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // The pre/post blocks always have layers, so we know to always do a full insert/remove (so we pass true as the last argument).
5915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    block->moveChildrenTo(pre, boxFirst, beforeChild, true);
5925af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    block->moveChildrenTo(post, beforeChild, 0, true);
5935af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
5945af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
5955af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // time in makeChildrenNonInline by just setting this explicitly up front.
5965af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newBlockBox->setChildrenInline(false);
5975af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
5985af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // We delayed adding the newChild until now so that the |newBlockBox| would be fully
5995af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // connected, thus allowing newChild access to a renderArena should it need
6005af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // to wrap itself in additional boxes (e.g., table construction).
6015af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newBlockBox->addChild(newChild);
6025af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
6035af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
6045af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // get deleted properly.  Because objects moved from the pre block into the post block, we want to
6055af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // make new line boxes instead of leaving the old line boxes around.
6065af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (pre)
6075af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        pre->setNeedsLayoutAndPrefWidthsRecalc();
6085af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    block->setNeedsLayoutAndPrefWidthsRecalc();
6095af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (post)
6105af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        post->setNeedsLayoutAndPrefWidthsRecalc();
6115af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
6125af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
613545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRenderBlock* RenderBlock::columnsBlockForSpanningElement(RenderObject* newChild)
6145af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
615545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // FIXME: This function is the gateway for the addition of column-span support.  It will
616545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // be added to in three stages:
6175af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // (1) Immediate children of a multi-column block can span.
6185af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // (2) Nested block-level children with only block-level ancestors between them and the multi-column block can span.
6195af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // (3) Nested children with block or inline ancestors between them and the multi-column block can span (this is when we
6205af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // cross the streams and have to cope with both types of continuations mixed together).
621545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // This function currently supports (1) and (2).
622545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBlock* columnsBlockAncestor = 0;
623545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isFloatingOrPositioned()
624545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        && !newChild->isInline() && !isAnonymousColumnSpanBlock()) {
625545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (style()->specifiesColumns())
626545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            columnsBlockAncestor = this;
627bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        else if (parent() && parent()->isRenderBlock())
628545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            columnsBlockAncestor = toRenderBlock(parent())->containingColumnsBlock(false);
629545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
630545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return columnsBlockAncestor;
6315af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
6325af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
6335af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
6348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Make sure we don't append things after :after-generated content if we have it.
636dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!beforeChild) {
637dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        RenderObject* lastRenderer = lastChild();
638dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (isAfterContent(lastRenderer))
639dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            beforeChild = lastRenderer;
640dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        else if (lastRenderer && lastRenderer->isAnonymousBlock() && isAfterContent(lastRenderer->lastChild()))
641dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            beforeChild = lastRenderer->lastChild();
642dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
6438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the requested beforeChild is not one of our children, then this is because
6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // there is an anonymous container within this object that contains the beforeChild.
6468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (beforeChild && beforeChild->parent() != this) {
6478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderObject* anonymousChild = beforeChild->parent();
6488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(anonymousChild);
6498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (anonymousChild->parent() != this)
6518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            anonymousChild = anonymousChild->parent();
6528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(anonymousChild->isAnonymous());
6548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (anonymousChild->isAnonymousBlock()) {
6568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Insert the child into the anonymous block box instead of here.
6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                beforeChild->parent()->addChild(newChild, beforeChild);
6598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
6608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                addChild(newChild, beforeChild->parent());
6618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
6628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(anonymousChild->isTable());
6658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if ((newChild->isTableCol() && newChild->style()->display() == TABLE_COLUMN_GROUP)
6668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                || (newChild->isRenderBlock() && newChild->style()->display() == TABLE_CAPTION)
6678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                || newChild->isTableSection()
6688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                || newChild->isTableRow()
6698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                || newChild->isTableCell()) {
6708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Insert into the anonymous table.
6718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            anonymousChild->addChild(newChild, beforeChild);
6728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Go on to insert before the anonymous table.
6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        beforeChild = anonymousChild;
6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6794a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    // Check for a spanning element in columns.
6804a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    RenderBlock* columnsBlockAncestor = columnsBlockForSpanningElement(newChild);
6814a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    if (columnsBlockAncestor) {
6824a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        // We are placing a column-span element inside a block.
6834a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        RenderBlock* newBox = createAnonymousColumnSpanBlock();
6844a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
6854a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        if (columnsBlockAncestor != this) {
6864a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            // We are nested inside a multi-column element and are being split by the span.  We have to break up
6874a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            // our block into continuations.
6884a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            RenderBoxModelObject* oldContinuation = continuation();
6894a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            setContinuation(newBox);
6904a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
6914a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            // Someone may have put a <p> inside a <q>, causing a split.  When this happens, the :after content
6924a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            // has to move into the inline continuation.  Call updateBeforeAfterContent to ensure that our :after
6934a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            // content gets properly destroyed.
6944a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            bool isLastChild = (beforeChild == lastChild());
6954a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            if (document()->usesBeforeAfterRules())
6964a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch                children()->updateBeforeAfterContent(this, AFTER);
6974a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            if (isLastChild && beforeChild != lastChild())
6984a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch                beforeChild = 0; // We destroyed the last child, so now we need to update our insertion
6994a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch                                 // point to be 0.  It's just a straight append now.
7004a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
7014a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            splitFlow(beforeChild, newBox, newChild, oldContinuation);
7024a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            return;
7034a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        }
7044a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
7054a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        // We have to perform a split of this block's children.  This involves creating an anonymous block box to hold
7064a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        // the column-spanning |newChild|.  We take all of the children from before |newChild| and put them into
7074a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        // one anonymous columns block, and all of the children after |newChild| go into another anonymous block.
7084a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        makeChildrenAnonymousColumnBlocks(beforeChild, newBox, newChild);
7094a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        return;
7104a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    }
7114a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
7124a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    bool madeBoxesNonInline = false;
7134a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
7148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // A block has to either have all of its children inline, or all of its children as blocks.
7158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // So, if our children are currently inline and a block child has to be inserted, we move all our
7168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // inline children into anonymous block boxes.
7178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrPositioned()) {
7188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // This is a block with inline content. Wrap the inline content in anonymous blocks.
7198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        makeChildrenNonInline(beforeChild);
7208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        madeBoxesNonInline = true;
7218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (beforeChild && beforeChild->parent() != this) {
7238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            beforeChild = beforeChild->parent();
7248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(beforeChild->isAnonymousBlock());
7258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(beforeChild->parent() == this);
7268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    } else if (!childrenInline() && (newChild->isFloatingOrPositioned() || newChild->isInline())) {
7288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // If we're inserting an inline child but all of our children are blocks, then we have to make sure
7298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
7308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // a new one is created and inserted into our list of children in the appropriate position.
7318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
7328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (afterChild && afterChild->isAnonymousBlock()) {
7348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            afterChild->addChild(newChild);
7358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
7368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (newChild->isInline()) {
7398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // No suitable existing anonymous box - create a new one.
7408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderBlock* newBox = createAnonymousBlock();
7418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            RenderBox::addChild(newBox, beforeChild);
7428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            newBox->addChild(newChild);
7438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
7448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBox::addChild(newChild, beforeChild);
7488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRenderBlock())
7508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
7518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // this object may be dead here
7528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7545af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
7555af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
756545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (continuation() && !isAnonymousBlock())
757545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return addChildToContinuation(newChild, beforeChild);
758545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return addChildIgnoringContinuation(newChild, beforeChild);
759545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
760545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
761545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild)
762545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
763545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (!isAnonymousBlock() && firstChild() && (firstChild()->isAnonymousColumnsBlock() || firstChild()->isAnonymousColumnSpanBlock()))
7645af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return addChildToAnonymousColumnBlocks(newChild, beforeChild);
7655af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
7665af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
7675af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
7688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void getInlineRun(RenderObject* start, RenderObject* boundary,
7698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                         RenderObject*& inlineRunStart,
7708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                         RenderObject*& inlineRunEnd)
7718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Beginning at |start| we find the largest contiguous run of inlines that
7738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // we can.  We denote the run with start and end points, |inlineRunStart|
7748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // and |inlineRunEnd|.  Note that these two values may be the same if
7758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // we encounter only one inline.
7768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    //
7778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We skip any non-inlines we encounter as long as we haven't found any
7788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // inlines yet.
7798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    //
7808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // |boundary| indicates a non-inclusive boundary point.  Regardless of whether |boundary|
7818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // is inline or not, we will not include it in a run with inlines before it.  It's as though we encountered
7828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // a non-inline.
7838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Start by skipping as many non-inlines as we can.
7858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject * curr = start;
7868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool sawInline;
7878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    do {
7888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (curr && !(curr->isInline() || curr->isFloatingOrPositioned()))
7898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            curr = curr->nextSibling();
7908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        inlineRunStart = inlineRunEnd = curr;
7928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!curr)
7948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return; // No more inline children to be found.
7958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        sawInline = curr->isInline();
7978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        curr = curr->nextSibling();
7998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (curr && (curr->isInline() || curr->isFloatingOrPositioned()) && (curr != boundary)) {
8008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            inlineRunEnd = curr;
8018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (curr->isInline())
8028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                sawInline = true;
8038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            curr = curr->nextSibling();
8048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
8058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } while (!sawInline);
8068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::deleteLineBoxTree()
8098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_lineBoxes.deleteLineBoxTree(renderArena());
8118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
8128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochRootInlineBox* RenderBlock::createRootInlineBox()
8148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
8158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return new (renderArena()) RootInlineBox(this);
8168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
8178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochRootInlineBox* RenderBlock::createAndAppendRootInlineBox()
8198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
8200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    RootInlineBox* rootBox = createRootInlineBox();
8218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_lineBoxes.appendLineBox(rootBox);
8228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return rootBox;
8238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
824643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
8255af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::moveChildTo(RenderBlock* to, RenderObject* child, RenderObject* beforeChild, bool fullRemoveInsert)
826643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
827643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ASSERT(this == child->parent());
828643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ASSERT(!beforeChild || to == beforeChild->parent());
8295af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    to->children()->insertChildNode(to, children()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert);
830d0825bca7fe65beaee391d30da42e937db621564Steve Block}
831d0825bca7fe65beaee391d30da42e937db621564Steve Block
8325af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::moveChildrenTo(RenderBlock* to, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert)
833d0825bca7fe65beaee391d30da42e937db621564Steve Block{
834d0825bca7fe65beaee391d30da42e937db621564Steve Block    ASSERT(!beforeChild || to == beforeChild->parent());
8355af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderObject* nextChild = startChild;
8365af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    while (nextChild && nextChild != endChild) {
837d0825bca7fe65beaee391d30da42e937db621564Steve Block        RenderObject* child = nextChild;
838d0825bca7fe65beaee391d30da42e937db621564Steve Block        nextChild = child->nextSibling();
8395af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        to->children()->insertChildNode(to, children()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert);
8405af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (child == endChild)
8415af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            return;
842d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
843d0825bca7fe65beaee391d30da42e937db621564Steve Block}
844d0825bca7fe65beaee391d30da42e937db621564Steve Block
8458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
8468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // makeChildrenNonInline takes a block whose children are *all* inline and it
8488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // makes sure that inline children are coalesced under anonymous
8498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // blocks.  If |insertionPoint| is defined, then it represents the insertion point for
8508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the new block child that is causing us to have to wrap all the inlines.  This
8518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // means that we cannot coalesce inlines before |insertionPoint| with inlines following
8528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // |insertionPoint|, because the new child is going to be inserted in between the inlines,
8538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // splitting them.
8548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(isInlineBlockOrInlineTable() || !isInline());
8558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!insertionPoint || insertionPoint->parent() == this);
8568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    setChildrenInline(false);
8588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject *child = firstChild();
8608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!child)
8618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
8628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    deleteLineBoxTree();
8648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (child) {
8668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderObject *inlineRunStart, *inlineRunEnd;
8678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
8688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!inlineRunStart)
8708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
8718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child = inlineRunEnd->nextSibling();
8738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderBlock* block = createAnonymousBlock();
8758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        children()->insertChildNode(this, block, inlineRunStart);
8765af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        moveChildrenTo(block, inlineRunStart, child);
8778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG
8808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (RenderObject *c = firstChild(); c; c = c->nextSibling())
8818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(!c->isInline());
8828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
8838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    repaint();
8858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
8888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
8898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(child->isAnonymousBlock());
8908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(!child->childrenInline());
8918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8925af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (child->continuation() || (child->firstChild() && (child->isAnonymousColumnSpanBlock() || child->isAnonymousColumnsBlock())))
8938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
8948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* firstAnChild = child->m_children.firstChild();
8968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* lastAnChild = child->m_children.lastChild();
8978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (firstAnChild) {
8988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderObject* o = firstAnChild;
8998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        while (o) {
9008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            o->setParent(this);
9018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            o = o->nextSibling();
9028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
9038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        firstAnChild->setPreviousSibling(child->previousSibling());
9048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        lastAnChild->setNextSibling(child->nextSibling());
9058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (child->previousSibling())
9068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            child->previousSibling()->setNextSibling(firstAnChild);
9078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (child->nextSibling())
9088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            child->nextSibling()->setPreviousSibling(lastAnChild);
9095af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
9105af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (child == m_children.firstChild())
9115af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            m_children.setFirstChild(firstAnChild);
9125af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (child == m_children.lastChild())
9135af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            m_children.setLastChild(lastAnChild);
9148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    } else {
9155af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (child == m_children.firstChild())
9165af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            m_children.setFirstChild(child->nextSibling());
9175af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (child == m_children.lastChild())
9185af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            m_children.setLastChild(child->previousSibling());
9195af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
9208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (child->previousSibling())
9218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            child->previousSibling()->setNextSibling(child->nextSibling());
9228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (child->nextSibling())
9238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            child->nextSibling()->setPreviousSibling(child->previousSibling());
9248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
9258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->setParent(0);
9268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->setPreviousSibling(0);
9278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->setNextSibling(0);
9288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->children()->setFirstChild(0);
9308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->m_next = 0;
9318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->destroy();
9338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
9348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9355af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkestatic bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObject* prev, RenderObject* next)
9365af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
9375af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (oldChild->documentBeingDestroyed() || oldChild->isInline() || oldChild->virtualContinuation())
9385af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return false;
9395af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
9402bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (oldChild->parent() && oldChild->parent()->isDetails())
9412bde8e466a4451c7319e3a072d118917957d6554Steve Block        return false;
9422bde8e466a4451c7319e3a072d118917957d6554Steve Block
94365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if ((prev && (!prev->isAnonymousBlock() || toRenderBlock(prev)->continuation() || toRenderBlock(prev)->beingDestroyed()))
94465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        || (next && (!next->isAnonymousBlock() || toRenderBlock(next)->continuation() || toRenderBlock(next)->beingDestroyed())))
9455af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return false;
9465af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
947967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // FIXME: This check isn't required when inline run-ins can't be split into continuations.
948967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    if (prev && prev->firstChild() && prev->firstChild()->isInline() && prev->firstChild()->isRunIn())
949967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        return false;
950967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
9515af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if ((prev && (prev->isRubyRun() || prev->isRubyBase()))
9525af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        || (next && (next->isRubyRun() || next->isRubyBase())))
9535af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return false;
9545af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
9555af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (!prev || !next)
9565af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return true;
9575af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
9585af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // Make sure the types of the anonymous blocks match up.
9595af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return prev->isAnonymousColumnsBlock() == next->isAnonymousColumnsBlock()
960cad810f21b803229eb11403f9209855525a25d57Steve Block           && prev->isAnonymousColumnSpanBlock() == next->isAnonymousColumnSpanBlock();
9615af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
9625af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
9638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::removeChild(RenderObject* oldChild)
9648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If this child is a block, and if our previous and next siblings are
9668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // both anonymous blocks with inline content, then we can go ahead and
9678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // fold the inline content back together.
9688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* prev = oldChild->previousSibling();
9698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* next = oldChild->nextSibling();
9705af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, prev, next);
9715af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (canMergeAnonymousBlocks && prev && next) {
9728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        prev->setNeedsLayoutAndPrefWidthsRecalc();
9738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderBlock* nextBlock = toRenderBlock(next);
9748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderBlock* prevBlock = toRenderBlock(prev);
9755af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
9765af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (prev->childrenInline() != next->childrenInline()) {
9775af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            RenderBlock* inlineChildrenBlock = prev->childrenInline() ? prevBlock : nextBlock;
9785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            RenderBlock* blockChildrenBlock = prev->childrenInline() ? nextBlock : prevBlock;
9795af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
9805af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // Place the inline children block inside of the block children block instead of deleting it.
9815af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // In order to reuse it, we have to reset it to just be a generic anonymous block.  Make sure
9825af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // to clear out inherited column properties by just making a new style, and to also clear the
9835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // column span flag if it is set.
9845af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            ASSERT(!inlineChildrenBlock->continuation());
9852bde8e466a4451c7319e3a072d118917957d6554Steve Block            RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
9865af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            children()->removeChildNode(this, inlineChildrenBlock, inlineChildrenBlock->hasLayer());
9875af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            inlineChildrenBlock->setStyle(newStyle);
9885af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
9895af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // Now just put the inlineChildrenBlock inside the blockChildrenBlock.
9905af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            blockChildrenBlock->children()->insertChildNode(blockChildrenBlock, inlineChildrenBlock, prev == inlineChildrenBlock ? blockChildrenBlock->firstChild() : 0,
9915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                                                            inlineChildrenBlock->hasLayer() || blockChildrenBlock->hasLayer());
9925af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            next->setNeedsLayoutAndPrefWidthsRecalc();
993cad810f21b803229eb11403f9209855525a25d57Steve Block
994cad810f21b803229eb11403f9209855525a25d57Steve Block            // inlineChildrenBlock got reparented to blockChildrenBlock, so it is no longer a child
995cad810f21b803229eb11403f9209855525a25d57Steve Block            // of "this". we null out prev or next so that is not used later in the function.
996cad810f21b803229eb11403f9209855525a25d57Steve Block            if (inlineChildrenBlock == prevBlock)
997cad810f21b803229eb11403f9209855525a25d57Steve Block                prev = 0;
998cad810f21b803229eb11403f9209855525a25d57Steve Block            else
999cad810f21b803229eb11403f9209855525a25d57Steve Block                next = 0;
10005af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        } else {
10015af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // Take all the children out of the |next| block and put them in
10025af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // the |prev| block.
100365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            nextBlock->moveAllChildrenTo(prevBlock, nextBlock->hasLayer() || prevBlock->hasLayer());
1004cad810f21b803229eb11403f9209855525a25d57Steve Block
10055af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // Delete the now-empty block's lines and nuke it.
10065af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            nextBlock->deleteLineBoxTree();
10075af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            nextBlock->destroy();
1008cad810f21b803229eb11403f9209855525a25d57Steve Block            next = 0;
10095af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        }
10108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBox::removeChild(oldChild);
10138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* child = prev ? prev : next;
10155af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && !isFlexibleBox()) {
10168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // The removal has knocked us down to containing only a single anonymous
10178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // box.  We can go ahead and pull the content right back up into our
10188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // box.
10198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setNeedsLayoutAndPrefWidthsRecalc();
10205af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        setChildrenInline(child->childrenInline());
10215af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        RenderBlock* anonBlock = toRenderBlock(children()->removeChildNode(this, child, child->hasLayer()));
10225af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        anonBlock->moveAllChildrenTo(this, child->hasLayer());
10238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Delete the now-empty block's lines and nuke it.
10248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        anonBlock->deleteLineBoxTree();
10258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        anonBlock->destroy();
10268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1027d0825bca7fe65beaee391d30da42e937db621564Steve Block
10285af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (!firstChild() && !documentBeingDestroyed()) {
10295af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        // If this was our last child be sure to clear out our line boxes.
10305af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (childrenInline())
10315af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            lineBoxes()->deleteLineBoxes(renderArena());
10325af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    }
10338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::isSelfCollapsingBlock() const
10368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We are not self-collapsing if we
10388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (a) have a non-zero height according to layout (an optimization to avoid wasting time)
10398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (b) are a table,
10408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (c) have border/padding,
10418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (d) have a min-height
10428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (e) have specified that one of our margins can't collapse using a CSS extension
1043a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (logicalHeight() > 0
1044a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        || isTable() || borderAndPaddingLogicalHeight()
1045a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        || style()->logicalMinHeight().isPositive()
1046bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        || style()->marginBeforeCollapse() == MSEPARATE || style()->marginAfterCollapse() == MSEPARATE)
10478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
10488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1049a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    Length logicalHeightLength = style()->logicalHeight();
1050a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool hasAutoHeight = logicalHeightLength.isAuto();
1051a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (logicalHeightLength.isPercent() && !document()->inQuirksMode()) {
10528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        hasAutoHeight = true;
10538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (RenderBlock* cb = containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) {
1054a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (cb->style()->logicalHeight().isFixed() || cb->isTableCell())
10558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                hasAutoHeight = false;
10568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
10578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the height is 0 or auto, then whether or not we are a self-collapsing block depends
10608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // on whether we have content that is all self-collapsing or not.
1061a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (hasAutoHeight || ((logicalHeightLength.isFixed() || logicalHeightLength.isPercent()) && logicalHeightLength.isZero())) {
10628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // If the block has inline children, see if we generated any line boxes.  If we have any
10638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // line boxes, then we can't be self-collapsing, since we have content.
10648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (childrenInline())
10658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return !firstLineBox();
10668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Whether or not we collapse is dependent on whether all our normal flow children
10688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // are also self-collapsing.
1069635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
10708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (child->isFloatingOrPositioned())
10718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
10728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!child->isSelfCollapsingBlock())
10738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return false;
10748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
10758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
10768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
10788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid RenderBlock::startDelayUpdateScrollInfo()
10810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
10820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (gDelayUpdateScrollInfo == 0) {
10830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ASSERT(!gDelayedUpdateScrollInfoSet);
10840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet;
10850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
10860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(gDelayedUpdateScrollInfoSet);
10870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ++gDelayUpdateScrollInfo;
10880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
10890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
10900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid RenderBlock::finishDelayUpdateScrollInfo()
10910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
10920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    --gDelayUpdateScrollInfo;
10930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(gDelayUpdateScrollInfo >= 0);
10940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (gDelayUpdateScrollInfo == 0) {
10950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ASSERT(gDelayedUpdateScrollInfoSet);
10960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1097643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        OwnPtr<DelayedUpdateScrollInfoSet> infoSet(gDelayedUpdateScrollInfoSet);
1098643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        gDelayedUpdateScrollInfoSet = 0;
1099643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
1100643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        for (DelayedUpdateScrollInfoSet::iterator it = infoSet->begin(); it != infoSet->end(); ++it) {
11010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            RenderBlock* block = *it;
11020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (block->hasOverflowClip()) {
11030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                block->layer()->updateScrollInfoAfterLayout();
11040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
11050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
11060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
11070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
11080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
11090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid RenderBlock::updateScrollInfoAfterLayout()
11100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
11110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (hasOverflowClip()) {
11120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (gDelayUpdateScrollInfo)
11130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            gDelayedUpdateScrollInfoSet->add(this);
11140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        else
11150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            layer()->updateScrollInfoAfterLayout();
11160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
11170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
11180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
11198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::layout()
11208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Update our first letter info now.
11228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    updateFirstLetter();
11238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Table cells call layoutBlock directly, so don't add any logic here.  Put code into
11258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // layoutBlock().
11268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    layoutBlock(false);
11278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // It's safe to check for control clip here, since controls can never be table cells.
1129231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // If we have a lightweight clip, there can never be any overflow from children.
1130231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (hasControlClip() && m_overflow)
1131231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        clearLayoutOverflow();
11328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1134f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderBlock::layoutBlock(bool relayoutChildren, int pageLogicalHeight)
11358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(needsLayout());
11378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isInline() && !isInlineBlockOrInlineTable()) // Inline <form>s inside various table elements can
11398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;                                      // cause us to come in here.  Just bail.
11408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11412bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!relayoutChildren && simplifiedLayout())
11428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
11438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    LayoutRepainter repainter(*this, m_everHadLayout && checkForRepaintDuringLayout());
11458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1146a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int oldWidth = logicalWidth();
11478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int oldColumnWidth = desiredColumnWidth();
11488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1149bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    computeLogicalWidth();
11508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    calcColumnWidth();
11518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1152231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_overflow.clear();
11538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1154bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (oldWidth != logicalWidth() || oldColumnWidth != desiredColumnWidth())
11558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        relayoutChildren = true;
11568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_LAYOUT
115823e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang    checkAndSetRelayoutChildren(&relayoutChildren);
11598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
11608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    clearFloats();
11628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1163bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int previousHeight = logicalHeight();
1164bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    setLogicalHeight(0);
1165f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    bool hasSpecifiedPageLogicalHeight = false;
1166f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    bool pageLogicalHeightChanged = false;
116768513a70bcd92384395513322f1b801e7bf9c729Steve Block    ColumnInfo* colInfo = columnInfo();
116868513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (hasColumns()) {
1169f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (!pageLogicalHeight) {
117068513a70bcd92384395513322f1b801e7bf9c729Steve Block            // We need to go ahead and set our explicit page height if one exists, so that we can
117168513a70bcd92384395513322f1b801e7bf9c729Steve Block            // avoid doing two layout passes.
1172bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            computeLogicalHeight();
1173bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            int columnHeight = contentLogicalHeight();
117468513a70bcd92384395513322f1b801e7bf9c729Steve Block            if (columnHeight > 0) {
1175f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                pageLogicalHeight = columnHeight;
1176f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                hasSpecifiedPageLogicalHeight = true;
117768513a70bcd92384395513322f1b801e7bf9c729Steve Block            }
1178bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setLogicalHeight(0);
117968513a70bcd92384395513322f1b801e7bf9c729Steve Block        }
1180f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (colInfo->columnHeight() != pageLogicalHeight && m_everHadLayout) {
1181f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            colInfo->setColumnHeight(pageLogicalHeight);
1182f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            pageLogicalHeightChanged = true;
118368513a70bcd92384395513322f1b801e7bf9c729Steve Block        }
118468513a70bcd92384395513322f1b801e7bf9c729Steve Block
1185f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (!hasSpecifiedPageLogicalHeight && !pageLogicalHeight)
118668513a70bcd92384395513322f1b801e7bf9c729Steve Block            colInfo->clearForcedBreaks();
118768513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
118868513a70bcd92384395513322f1b801e7bf9c729Steve Block
1189f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode(), pageLogicalHeight, pageLogicalHeightChanged, colInfo);
1190635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
11915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track
11928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // our current maximal positive and negative margins.  These values are used when we
11938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // are collapsed with adjacent blocks, so for example, if you have block A and B
11948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // collapsing together, then you'd take the maximal positive margin from both A and B
11958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // and subtract it from the maximal negative margin from both A and B to get the
11968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // true collapsed margin.  This algorithm is recursive, so when we finish layout()
11978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // our block knows its current maximal positive/negative values.
11988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    //
11998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Start out by setting our margin values to our current margins.  Table cells have
12008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // no margins, so we don't fill in the values for table cells.
12018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool isCell = isTableCell();
12028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!isCell) {
12038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        initMaxMarginValues();
120468513a70bcd92384395513322f1b801e7bf9c729Steve Block
1205bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setMarginBeforeQuirk(style()->marginBefore().quirk());
1206bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setMarginAfterQuirk(style()->marginAfter().quirk());
12078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        Node* n = node();
12098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (n && n->hasTagName(formTag) && static_cast<HTMLFormElement*>(n)->isMalformed()) {
12108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // See if this form is malformed (i.e., unclosed). If so, don't give the form
12118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // a bottom margin.
1212bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setMaxMarginAfterValues(0, 0);
12138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
121468513a70bcd92384395513322f1b801e7bf9c729Steve Block
121568513a70bcd92384395513322f1b801e7bf9c729Steve Block        setPaginationStrut(0);
12168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // For overflow:scroll blocks, ensure we have both scrollbars in place always.
12198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (scrollsOverflow()) {
12208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (style()->overflowX() == OSCROLL)
12218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            layer()->setHasHorizontalScrollbar(true);
12228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (style()->overflowY() == OSCROLL)
12238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            layer()->setHasVerticalScrollbar(true);
12248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1226a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int repaintLogicalTop = 0;
1227a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int repaintLogicalBottom = 0;
1228a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int maxFloatLogicalBottom = 0;
1229e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (!firstChild() && !isAnonymousBlock())
12306c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        setChildrenInline(true);
12318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childrenInline())
1232a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        layoutInlineChildren(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
12338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
1234a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        layoutBlockChildren(relayoutChildren, maxFloatLogicalBottom);
12358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Expand our intrinsic height to encompass floats.
1237a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int toAdd = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
1238a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (lowestFloatLogicalBottom() > (logicalHeight() - toAdd) && expandsToEncloseOverhangingFloats())
1239a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalHeight(lowestFloatLogicalBottom() + toAdd);
12408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1241f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (layoutColumns(hasSpecifiedPageLogicalHeight, pageLogicalHeight, statePusher))
124268513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
124368513a70bcd92384395513322f1b801e7bf9c729Steve Block
12448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Calculate our new height.
1245bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int oldHeight = logicalHeight();
1246f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int oldClientAfterEdge = clientLogicalBottom();
1247bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    computeLogicalHeight();
1248bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int newHeight = logicalHeight();
1249bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (oldHeight != newHeight) {
1250a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (oldHeight > newHeight && maxFloatLogicalBottom > newHeight && !childrenInline()) {
12518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // One of our children's floats may have become an overhanging float for us. We need to look for it.
12528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
12538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (child->isBlockFlow() && !child->isFloatingOrPositioned()) {
12548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    RenderBlock* block = toRenderBlock(child);
1255a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    if (block->lowestFloatLogicalBottom() + block->logicalTop() > newHeight)
1256a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                        addOverhangingFloats(block, -block->logicalLeft(), -block->logicalTop(), false);
12578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
12588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
12598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
12608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1261231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1262bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (previousHeight != newHeight)
12638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        relayoutChildren = true;
12648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1265231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    layoutPositionedObjects(relayoutChildren || isRoot());
12668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1267f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway).
1268f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    computeOverflow(oldClientAfterEdge);
1269231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1270635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    statePusher.pop();
12718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1272f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (view()->layoutState()->m_pageLogicalHeight)
12732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(logicalTop()));
1274f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1275f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    updateLayerTransform();
127668513a70bcd92384395513322f1b801e7bf9c729Steve Block
12778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
12788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // we overflow or not.
12790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    updateScrollInfoAfterLayout();
12808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Repaint with our new bounds if they are different from our old bounds.
12828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool didFullRepaint = repainter.repaintAfterLayout();
1283a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!didFullRepaint && repaintLogicalTop != repaintLogicalBottom && (style()->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) {
1284f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // FIXME: We could tighten up the left and right invalidation points if we let layoutInlineChildren fill them in based off the particular lines
1285f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // it had to lay out.  We wouldn't need the hasOverflowClip() hack in that case either.
1286f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        int repaintLogicalLeft = logicalLeftVisualOverflow();
1287f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        int repaintLogicalRight = logicalRightVisualOverflow();
1288f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (hasOverflowClip()) {
1289f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // If we have clipped overflow, we should use layout overflow as well, since visual overflow from lines didn't propagate to our block's overflow.
1290f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // Note the old code did this as well but even for overflow:visible.  The addition of hasOverflowClip() at least tightens up the hack a bit.
1291f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // layoutInlineChildren should be patched to compute the entire repaint rect.
1292f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            repaintLogicalLeft = min(repaintLogicalLeft, logicalLeftLayoutOverflow());
1293f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            repaintLogicalRight = max(repaintLogicalRight, logicalRightLayoutOverflow());
1294f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        }
1295a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1296a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        IntRect repaintRect;
12972bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (isHorizontalWritingMode())
1298a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            repaintRect = IntRect(repaintLogicalLeft, repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop);
1299a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
1300a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            repaintRect = IntRect(repaintLogicalTop, repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft);
13018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1302e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        // The repaint rect may be split across columns, in which case adjustRectForColumns() will return the union.
1303e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        adjustRectForColumns(repaintRect);
13048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        repaintRect.inflate(maximalOutlineSize(PaintPhaseOutline));
13068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (hasOverflowClip()) {
13088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Adjust repaint rect for scroll offset
1309dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            repaintRect.move(-layer()->scrolledContentOffset());
13108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Don't allow this rect to spill out of our overflow box.
1312635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            repaintRect.intersect(IntRect(0, 0, width(), height()));
13138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
13148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Make sure the rect is still non-empty after intersecting for overflow above
13168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!repaintRect.isEmpty()) {
13178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            repaintRectangle(repaintRect); // We need to do a partial repaint of our content.
13188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (hasReflection())
13195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                repaintRectangle(reflectedRect(repaintRect));
13208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
13218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
13228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setNeedsLayout(false);
13238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1325f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderBlock::addOverflowFromChildren()
1326f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
1327f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!hasColumns()) {
1328f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (childrenInline())
1329f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            addOverflowFromInlineChildren();
1330f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        else
1331f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            addOverflowFromBlockChildren();
1332f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    } else {
1333f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        ColumnInfo* colInfo = columnInfo();
1334f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (columnCount(colInfo)) {
1335f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            IntRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
13362bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (isHorizontalWritingMode()) {
13372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int overflowLeft = !style()->isLeftToRightDirection() ? min(0, lastRect.x()) : 0;
13382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int overflowRight = style()->isLeftToRightDirection() ? max(width(), lastRect.maxX()) : 0;
13392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int overflowHeight = borderBefore() + paddingBefore() + colInfo->columnHeight();
13402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                addLayoutOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight));
13412bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (!hasOverflowClip())
13422bde8e466a4451c7319e3a072d118917957d6554Steve Block                    addVisualOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight));
13432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            } else {
13442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                IntRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
13452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int overflowTop = !style()->isLeftToRightDirection() ? min(0, lastRect.y()) : 0;
13462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int overflowBottom = style()->isLeftToRightDirection() ? max(height(), lastRect.maxY()) : 0;
13472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int overflowWidth = borderBefore() + paddingBefore() + colInfo->columnHeight();
13482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                addLayoutOverflow(IntRect(0, overflowTop, overflowWidth, overflowBottom - overflowTop));
13492bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (!hasOverflowClip())
13502bde8e466a4451c7319e3a072d118917957d6554Steve Block                    addVisualOverflow(IntRect(0, overflowTop, overflowWidth, overflowBottom - overflowTop));
13512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            }
1352f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        }
1353f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
1354f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
1355f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1356f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderBlock::computeOverflow(int oldClientAfterEdge, bool recomputeFloats)
1357f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
1358f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Add overflow from children.
1359f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    addOverflowFromChildren();
1360f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1361f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!hasColumns() && (recomputeFloats || isRoot() || expandsToEncloseOverhangingFloats() || hasSelfPaintingLayer()))
1362f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        addOverflowFromFloats();
1363f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1364f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Add in the overflow from positioned objects.
1365f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    addOverflowFromPositionedObjects();
1366f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1367f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (hasOverflowClip()) {
1368f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // When we have overflow clip, propagate the original spillout since it will include collapsed bottom margins
1369f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // and bottom padding.  Set the axis we don't care about to be 1, since we want this overflow to always
1370f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // be considered reachable.
1371f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        IntRect clientRect(clientBoxRect());
1372f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        IntRect rectToApply;
13732bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (isHorizontalWritingMode())
1374f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            rectToApply = IntRect(clientRect.x(), clientRect.y(), 1, max(0, oldClientAfterEdge - clientRect.y()));
1375f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        else
1376f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            rectToApply = IntRect(clientRect.x(), clientRect.y(), max(0, oldClientAfterEdge - clientRect.x()), 1);
1377f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        addLayoutOverflow(rectToApply);
1378f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
1379f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1380f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Add visual overflow from box-shadow and reflections.
1381f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    addShadowOverflow();
1382f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
1383f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1384231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid RenderBlock::addOverflowFromBlockChildren()
1385231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
1386231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
1387231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (!child->isFloatingOrPositioned())
1388231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            addOverflowFromChild(child);
1389231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
1390231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
1391231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1392231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid RenderBlock::addOverflowFromFloats()
1393231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
1394231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!m_floatingObjects)
1395231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
139681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
139781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
139881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator end = floatingObjectSet.end();
139981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
140081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObject* r = *it;
1401f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (r->m_isDescendant)
14022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            addOverflowFromChild(r->m_renderer, IntSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r)));
1403231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
1404231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return;
1405231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
1406231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1407f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderBlock::addOverflowFromPositionedObjects()
1408f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
1409f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!m_positionedObjects)
1410f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return;
1411f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1412f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    RenderBox* positionedObject;
1413f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    Iterator end = m_positionedObjects->end();
1414f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
1415f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        positionedObject = *it;
1416f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1417f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // Fixed positioned elements don't contribute to layout overflow, since they don't scroll with the content.
1418f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (positionedObject->style()->position() != FixedPosition)
1419f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            addOverflowFromChild(positionedObject);
1420f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
1421f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
1422f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1423635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool RenderBlock::expandsToEncloseOverhangingFloats() const
1424635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
1425bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return isInlineBlockOrInlineTable() || isFloatingOrPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBox())
1426a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch           || hasColumns() || isTableCell() || isFieldset() || isWritingModeRoot();
1427635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
1428635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1429635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marginInfo)
14308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
14312bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool isHorizontal = isHorizontalWritingMode();
143281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    bool hasStaticBlockPosition = child->style()->hasStaticBlockPosition(isHorizontal);
143381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    RenderLayer* childLayer = child->layer();
143481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
14352bde8e466a4451c7319e3a072d118917957d6554Steve Block    childLayer->setStaticInlinePosition(borderAndPaddingStart());
14362bde8e466a4451c7319e3a072d118917957d6554Steve Block
14372bde8e466a4451c7319e3a072d118917957d6554Steve Block    int logicalTop = logicalHeight();
14382bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!marginInfo.canCollapseWithMarginBefore()) {
14392bde8e466a4451c7319e3a072d118917957d6554Steve Block        child->computeBlockDirectionMargins(this);
14402bde8e466a4451c7319e3a072d118917957d6554Steve Block        int marginBefore = marginBeforeForChild(child);
14412bde8e466a4451c7319e3a072d118917957d6554Steve Block        int collapsedBeforePos = marginInfo.positiveMargin();
14422bde8e466a4451c7319e3a072d118917957d6554Steve Block        int collapsedBeforeNeg = marginInfo.negativeMargin();
14432bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (marginBefore > 0) {
14442bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (marginBefore > collapsedBeforePos)
14452bde8e466a4451c7319e3a072d118917957d6554Steve Block                collapsedBeforePos = marginBefore;
14462bde8e466a4451c7319e3a072d118917957d6554Steve Block        } else {
14472bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (-marginBefore > collapsedBeforeNeg)
14482bde8e466a4451c7319e3a072d118917957d6554Steve Block                collapsedBeforeNeg = -marginBefore;
14498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
14502bde8e466a4451c7319e3a072d118917957d6554Steve Block        logicalTop += (collapsedBeforePos - collapsedBeforeNeg) - marginBefore;
14512bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
14522bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (childLayer->staticBlockPosition() != logicalTop) {
14532bde8e466a4451c7319e3a072d118917957d6554Steve Block        childLayer->setStaticBlockPosition(logicalTop);
14542bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (hasStaticBlockPosition)
1455643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            child->setChildNeedsLayout(true, false);
14568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
14588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::adjustFloatingBlock(const MarginInfo& marginInfo)
14608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
14618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The float should be positioned taking into account the bottom margin
14628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // of the previous flow.  We add that margin into the height, get the
14638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // float positioned properly, and then subtract the margin out of the
14648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // height again.  In the case of self-collapsing blocks, we always just
14658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // use the top margins, since the self-collapsing block collapsed its
14668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // own bottom margin into its top margin.
14678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    //
14688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Note also that the previous flow may collapse its margin into the top of
14698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // our block.  If this is the case, then we do not add the margin in to our
14708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // height when computing the position of the float.   This condition can be tested
1471bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // for by simply calling canCollapseWithMarginBefore.  See
14728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for
14738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // an example of this scenario.
1474bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int marginOffset = marginInfo.canCollapseWithMarginBefore() ? 0 : marginInfo.margin();
1475a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalHeight(logicalHeight() + marginOffset);
14768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    positionNewFloats();
1477a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalHeight(logicalHeight() - marginOffset);
14788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
14798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool RenderBlock::handleSpecialChild(RenderBox* child, const MarginInfo& marginInfo)
14818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
14825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Handle in the given order
14835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return handlePositionedChild(child, marginInfo)
14845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        || handleFloatingChild(child, marginInfo)
14855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        || handleRunInChild(child);
14868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
14878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool RenderBlock::handlePositionedChild(RenderBox* child, const MarginInfo& marginInfo)
14908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
14918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (child->isPositioned()) {
14928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child->containingBlock()->insertPositionedObject(child);
14938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        adjustPositionedBlock(child, marginInfo);
14945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return true;
14958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return false;
14978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
14988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool RenderBlock::handleFloatingChild(RenderBox* child, const MarginInfo& marginInfo)
15008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (child->isFloating()) {
15028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        insertFloatingObject(child);
15038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        adjustFloatingBlock(marginInfo);
15045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return true;
15058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return false;
15078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool RenderBlock::handleRunInChild(RenderBox* child)
15108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // See if we have a run-in element with inline children.  If the
15128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // children aren't inline, then just treat the run-in as a normal
15138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // block.
1514231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!child->isRunIn() || !child->childrenInline())
1515231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return false;
1516231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // FIXME: We don't handle non-block elements with run-in for now.
1517231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!child->isRenderBlock())
15185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return false;
1519635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
15205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Get the next non-positioned/non-floating RenderBlock.
15210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    RenderBlock* blockRunIn = toRenderBlock(child);
15225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RenderObject* curr = blockRunIn->nextSibling();
15235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    while (curr && curr->isFloatingOrPositioned())
15245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        curr = curr->nextSibling();
15255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
15260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!curr || !curr->isRenderBlock() || !curr->childrenInline() || curr->isRunIn() || curr->isAnonymous())
15275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return false;
15285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
15295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RenderBlock* currBlock = toRenderBlock(curr);
15305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
15315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Remove the old child.
15325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    children()->removeChildNode(this, blockRunIn);
1533635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
15345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Create an inline.
15355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Node* runInNode = blockRunIn->node();
15365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RenderInline* inlineRunIn = new (renderArena()) RenderInline(runInNode ? runInNode : document());
15375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    inlineRunIn->setStyle(blockRunIn->style());
15385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
15395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    bool runInIsGenerated = child->style()->styleType() == BEFORE || child->style()->styleType() == AFTER;
15405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
15415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Move the nodes from the old child to the new child, but skip any :before/:after content.  It has already
15425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // been regenerated by the new inline.
15436c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    for (RenderObject* runInChild = blockRunIn->firstChild(); runInChild;) {
15446c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        RenderObject* nextSibling = runInChild->nextSibling();
1545643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (runInIsGenerated || (runInChild->style()->styleType() != BEFORE && runInChild->style()->styleType() != AFTER)) {
15465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            blockRunIn->children()->removeChildNode(blockRunIn, runInChild, false);
15475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            inlineRunIn->addChild(runInChild); // Use addChild instead of appendChildNode since it handles correct placement of the children relative to :after-generated content.
15488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
15496c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        runInChild = nextSibling;
15508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
15522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // Now insert the new child under |currBlock|. Use addChild instead of insertChildNode since it handles correct placement of the children, esp where we cannot insert
15532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // anything before the first child. e.g. details tag. See https://bugs.webkit.org/show_bug.cgi?id=58228.
15542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    currBlock->addChild(inlineRunIn, currBlock->firstChild());
15555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
15565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // If the run-in had an element, we need to set the new renderer.
15575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (runInNode)
15585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        runInNode->setRenderer(inlineRunIn);
15595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1560bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // Destroy the block run-in, which includes deleting its line box tree.
1561bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    blockRunIn->deleteLineBoxTree();
15625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    blockRunIn->destroy();
15635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
15645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // The block acts like an inline, so just null out its
15655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // position.
15665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
15675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return true;
15688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianint RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo)
15718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1572a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Get the four margin values for the child and cache them.
1573a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    const MarginValues childMargins = marginValuesForChild(child);
1574a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
15758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Get our max pos and neg top margins.
1576a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int posTop = childMargins.positiveMarginBefore();
1577a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int negTop = childMargins.negativeMarginBefore();
15788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // For self-collapsing blocks, collapse our bottom margins into our
15808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // top to get new posTop and negTop values.
15818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (child->isSelfCollapsingBlock()) {
1582a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        posTop = max(posTop, childMargins.positiveMarginAfter());
1583a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        negTop = max(negTop, childMargins.negativeMarginAfter());
15848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // See if the top margin is quirky. We only care if this child has
15878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // margins that will collapse with us.
1588bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    bool topQuirk = child->isMarginBeforeQuirk() || style()->marginBeforeCollapse() == MDISCARD;
15898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1590bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (marginInfo.canCollapseWithMarginBefore()) {
15918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // This child is collapsing with the top of the
15928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // block.  If it has larger margin values, then we need to update
15938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // our own maximal values.
15945ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        if (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !topQuirk)
1595a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            setMaxMarginBeforeValues(max(posTop, maxPositiveMarginBefore()), max(negTop, maxNegativeMarginBefore()));
15968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // The minute any of the margins involved isn't a quirk, don't
15988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // collapse it away, even if the margin is smaller (www.webreference.com
15998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // has an example of this, a <dt> with 0.8em author-specified inside
16008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // a <dl> inside a <td>.
1601a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!marginInfo.determinedMarginBeforeQuirk() && !topQuirk && (posTop - negTop)) {
1602bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setMarginBeforeQuirk(false);
1603bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            marginInfo.setDeterminedMarginBeforeQuirk(true);
16048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
16058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1606a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!marginInfo.determinedMarginBeforeQuirk() && topQuirk && !marginBefore())
16078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We have no top margin and our top child has a quirky margin.
16088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We will pick up this quirky margin and pass it through.
16098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // This deals with the <td><div><p> case.
16108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Don't do this for a block that split two inlines though.  You do
16118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // still apply margins in this case.
1612bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setMarginBeforeQuirk(true);
16138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1615bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (marginInfo.quirkContainer() && marginInfo.atBeforeSideOfBlock() && (posTop - negTop))
1616bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        marginInfo.setMarginBeforeQuirk(topQuirk);
16178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1618a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int beforeCollapseLogicalTop = logicalHeight();
1619a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalTop = beforeCollapseLogicalTop;
16208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (child->isSelfCollapsingBlock()) {
16218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // This child has no height.  We need to compute our
16228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // position before we collapse the child's margins together,
16238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // so that we can get an accurate position for the zero-height block.
1624a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int collapsedBeforePos = max(marginInfo.positiveMargin(), childMargins.positiveMarginBefore());
1625a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int collapsedBeforeNeg = max(marginInfo.negativeMargin(), childMargins.negativeMarginBefore());
1626a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        marginInfo.setMargin(collapsedBeforePos, collapsedBeforeNeg);
16278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Now collapse the child's margins together, which means examining our
16298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // bottom margin values as well.
1630a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        marginInfo.setPositiveMarginIfLarger(childMargins.positiveMarginAfter());
1631a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        marginInfo.setNegativeMarginIfLarger(childMargins.negativeMarginAfter());
16328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1633bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (!marginInfo.canCollapseWithMarginBefore())
16348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We need to make sure that the position of the self-collapsing block
16358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // is correct, since it could have overflowing content
16368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // that needs to be positioned correctly (e.g., a block that
16378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // had a specified height of 0 but that actually had subcontent).
1638a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            logicalTop = logicalHeight() + collapsedBeforePos - collapsedBeforeNeg;
16398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
1641bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (child->style()->marginBeforeCollapse() == MSEPARATE) {
1642a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            setLogicalHeight(logicalHeight() + marginInfo.margin() + marginBeforeForChild(child));
1643a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            logicalTop = logicalHeight();
16448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1645bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        else if (!marginInfo.atBeforeSideOfBlock() ||
1646bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            (!marginInfo.canCollapseMarginBeforeWithChildren()
1647bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen             && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.marginBeforeQuirk()))) {
16488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We're collapsing with a previous sibling's margins and not
16498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // with the top of the block.
1650a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            setLogicalHeight(logicalHeight() + max(marginInfo.positiveMargin(), posTop) - max(marginInfo.negativeMargin(), negTop));
1651a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            logicalTop = logicalHeight();
16528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
16538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1654a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        marginInfo.setPositiveMargin(childMargins.positiveMarginAfter());
1655a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        marginInfo.setNegativeMargin(childMargins.negativeMarginAfter());
16568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (marginInfo.margin())
1658bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            marginInfo.setMarginAfterQuirk(child->isMarginAfterQuirk() || style()->marginAfterCollapse() == MDISCARD);
16598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
166168513a70bcd92384395513322f1b801e7bf9c729Steve Block    // If margins would pull us past the top of the next page, then we need to pull back and pretend like the margins
166268513a70bcd92384395513322f1b801e7bf9c729Steve Block    // collapsed into the page edge.
166368513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool paginated = view()->layoutState()->isPaginated();
1664a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (paginated && logicalTop > beforeCollapseLogicalTop) {
1665a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int oldLogicalTop = logicalTop;
16662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        logicalTop = min(logicalTop, nextPageLogicalTop(beforeCollapseLogicalTop));
1667a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop));
166868513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
1669a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return logicalTop;
16708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
16718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianint RenderBlock::clearFloatsIfNeeded(RenderBox* child, MarginInfo& marginInfo, int oldTopPosMargin, int oldTopNegMargin, int yPos)
16738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
16748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int heightIncrease = getClearDelta(child, yPos);
16758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!heightIncrease)
16768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return yPos;
16778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (child->isSelfCollapsingBlock()) {
16798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // For self-collapsing blocks that clear, they can still collapse their
16808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // margins with following siblings.  Reset the current margins to represent
16818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // the self-collapsing block's margins only.
1682231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // CSS2.1 states:
1683231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // "An element that has had clearance applied to it never collapses its top margin with its parent block's bottom margin.
1684231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Therefore if we are at the bottom of the block, let's go ahead and reset margins to only include the
1685231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // self-collapsing block's bottom margin.
1686231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        bool atBottomOfBlock = true;
1687231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        for (RenderBox* curr = child->nextSiblingBox(); curr && atBottomOfBlock; curr = curr->nextSiblingBox()) {
1688231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if (!curr->isFloatingOrPositioned())
1689231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                atBottomOfBlock = false;
1690231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
1691a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1692a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        MarginValues childMargins = marginValuesForChild(child);
1693231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (atBottomOfBlock) {
1694a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            marginInfo.setPositiveMargin(childMargins.positiveMarginAfter());
1695a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            marginInfo.setNegativeMargin(childMargins.negativeMarginAfter());
1696231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        } else {
1697a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            marginInfo.setPositiveMargin(max(childMargins.positiveMarginBefore(), childMargins.positiveMarginAfter()));
1698a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            marginInfo.setNegativeMargin(max(childMargins.negativeMarginBefore(), childMargins.negativeMarginAfter()));
1699231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
17008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1701231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Adjust our height such that we are ready to be collapsed with subsequent siblings (or the bottom
1702231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // of the parent block).
1703bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setLogicalHeight(child->y() - max(0, marginInfo.margin()));
17048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else
17058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Increase our height by the amount we had to clear.
1706bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setLogicalHeight(height() + heightIncrease);
17078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1708bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (marginInfo.canCollapseWithMarginBefore()) {
17098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We can no longer collapse with the top of the block since a clear
17108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // occurred.  The empty blocks collapse into the cleared block.
17118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: This isn't quite correct.  Need clarification for what to do
17128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // if the height the cleared block is offset by is smaller than the
17138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // margins involved.
1714bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setMaxMarginBeforeValues(oldTopPosMargin, oldTopNegMargin);
1715bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        marginInfo.setAtBeforeSideOfBlock(false);
17168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
17178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
17188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return yPos + heightIncrease;
17198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1721a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::estimateLogicalTopPosition(RenderBox* child, const MarginInfo& marginInfo)
17228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
17238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: We need to eliminate the estimation of vertical position, because when it's wrong we sometimes trigger a pathological
17248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // relayout if there are intruding floats.
1725a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalTopEstimate = logicalHeight();
1726bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (!marginInfo.canCollapseWithMarginBefore()) {
1727a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int childMarginBefore = child->selfNeedsLayout() ? marginBeforeForChild(child) : collapsedMarginBeforeForChild(child);
1728a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        logicalTopEstimate += max(marginInfo.margin(), childMarginBefore);
17298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
173068513a70bcd92384395513322f1b801e7bf9c729Steve Block
173168513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool paginated = view()->layoutState()->isPaginated();
173268513a70bcd92384395513322f1b801e7bf9c729Steve Block
1733a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Adjust logicalTopEstimate down to the next page if the margins are so large that we don't fit on the current
173468513a70bcd92384395513322f1b801e7bf9c729Steve Block    // page.
1735a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (paginated && logicalTopEstimate > logicalHeight())
17362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        logicalTopEstimate = min(logicalTopEstimate, nextPageLogicalTop(logicalHeight()));
173768513a70bcd92384395513322f1b801e7bf9c729Steve Block
1738a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    logicalTopEstimate += getClearDelta(child, logicalTopEstimate);
173968513a70bcd92384395513322f1b801e7bf9c729Steve Block
174068513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (paginated) {
174168513a70bcd92384395513322f1b801e7bf9c729Steve Block        // If the object has a page or column break value of "before", then we should shift to the top of the next page.
1742a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        logicalTopEstimate = applyBeforeBreak(child, logicalTopEstimate);
174368513a70bcd92384395513322f1b801e7bf9c729Steve Block
174468513a70bcd92384395513322f1b801e7bf9c729Steve Block        // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one.
1745a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        logicalTopEstimate = adjustForUnsplittableChild(child, logicalTopEstimate);
174668513a70bcd92384395513322f1b801e7bf9c729Steve Block
174768513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (!child->selfNeedsLayout() && child->isRenderBlock())
1748a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            logicalTopEstimate += toRenderBlock(child)->paginationStrut();
174968513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
175068513a70bcd92384395513322f1b801e7bf9c729Steve Block
1751a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return logicalTopEstimate;
17528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1754a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::determineLogicalLeftPositionForChild(RenderBox* child)
17558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1756a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int startPosition = borderStart() + paddingStart();
1757a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + availableLogicalWidth();
1758a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1759a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Add in our start margin.
1760a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int childMarginStart = marginStartForChild(child);
1761a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int newPosition = startPosition + childMarginStart;
17628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1763a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats.  They need
1764a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // to shift over as necessary to dodge any floats that might get in the way.
1765a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (child->avoidsFloats()) {
1766a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int startOff = style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(logicalHeight(), false) : totalAvailableLogicalWidth - logicalRightOffsetForLine(logicalHeight(), false);
1767a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->textAlign() != WEBKIT_CENTER && !child->style()->marginStartUsing(style()).isAuto()) {
1768a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (childMarginStart < 0)
1769a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                startOff += childMarginStart;
1770a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            newPosition = max(newPosition, startOff); // Let the float sit in the child's margin if it can fit.
1771a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        } else if (startOff != startPosition) {
1772a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // The object is shifting to the "end" side of the block. The object might be centered, so we need to
1773a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // recalculate our inline direction margins. Note that the containing block content
1774a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // width computation will take into account the delta between |startOff| and |startPosition|
1775a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // so that we can just pass the content width in directly to the |computeMarginsInContainingBlockInlineDirection|
1776a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // function.
1777a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->computeInlineDirectionMargins(this, availableLogicalWidthForLine(logicalTopForChild(child), false), logicalWidthForChild(child));
1778a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            newPosition = startOff + marginStartForChild(child);
17798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
17808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1781a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1782a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalLeftForChild(child, style()->isLeftToRightDirection() ? newPosition : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child), ApplyLayoutDelta);
17838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::setCollapsedBottomMargin(const MarginInfo& marginInfo)
17868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1787bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()) {
17888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Update our max pos/neg bottom margins, since we collapsed our bottom margins
17898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // with our children.
1790a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setMaxMarginAfterValues(max(maxPositiveMarginAfter(), marginInfo.positiveMargin()), max(maxNegativeMarginAfter(), marginInfo.negativeMargin()));
17918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1792bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (!marginInfo.marginAfterQuirk())
1793bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setMarginAfterQuirk(false);
17948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1795a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (marginInfo.marginAfterQuirk() && marginAfter() == 0)
17968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We have no bottom margin and our last child has a quirky margin.
17978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We will pick up this quirky margin and pass it through.
17988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // This deals with the <td><div><p> case.
1799bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setMarginAfterQuirk(true);
18008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
18018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1803a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::handleAfterSideOfBlock(int beforeSide, int afterSide, MarginInfo& marginInfo)
18048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1805bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    marginInfo.setAtAfterSideOfBlock(true);
18068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If we can't collapse with children then go ahead and add in the bottom margin.
1808bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (!marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()
1809bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.marginAfterQuirk()))
1810a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalHeight(logicalHeight() + marginInfo.margin());
18118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Now add in our bottom border/padding.
1813a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalHeight(logicalHeight() + afterSide);
18148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Negative margins can cause our height to shrink below our minimal height (border/padding).
18168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If this happens, ensure that the computed height is increased to the minimal height.
1817a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalHeight(max(logicalHeight(), beforeSide + afterSide));
18188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Update our bottom collapsed margin info.
18208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setCollapsedBottomMargin(marginInfo);
18218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1823a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setLogicalLeftForChild(RenderBox* child, int logicalLeft, ApplyLayoutDeltaMode applyDelta)
1824a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
18252bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode()) {
1826a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (applyDelta == ApplyLayoutDelta)
1827a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            view()->addLayoutDelta(IntSize(child->x() - logicalLeft, 0));
1828a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setX(logicalLeft);
1829a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else {
1830a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (applyDelta == ApplyLayoutDelta)
1831a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            view()->addLayoutDelta(IntSize(0, child->y() - logicalLeft));
1832a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setY(logicalLeft);
1833a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
1834a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1835a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1836a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setLogicalTopForChild(RenderBox* child, int logicalTop, ApplyLayoutDeltaMode applyDelta)
1837a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
18382bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode()) {
1839a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (applyDelta == ApplyLayoutDelta)
1840a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            view()->addLayoutDelta(IntSize(0, child->y() - logicalTop));
1841a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setY(logicalTop);
1842a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else {
1843a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (applyDelta == ApplyLayoutDelta)
1844a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            view()->addLayoutDelta(IntSize(child->x() - logicalTop, 0));
1845a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setX(logicalTop);
1846a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
1847a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1848a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1849a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatLogicalBottom)
18508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
18518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (gPercentHeightDescendantsMap) {
18528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (HashSet<RenderBox*>* descendants = gPercentHeightDescendantsMap->get(this)) {
18538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            HashSet<RenderBox*>::iterator end = descendants->end();
18548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (HashSet<RenderBox*>::iterator it = descendants->begin(); it != end; ++it) {
18558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                RenderBox* box = *it;
18568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                while (box != this) {
18578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (box->normalChildNeedsLayout())
18588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
18598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    box->setChildNeedsLayout(true, false);
18608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    box = box->containingBlock();
18618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    ASSERT(box);
18628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (!box)
18638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
18648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
18658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
18668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
18678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
18688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1869a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int beforeEdge = borderBefore() + paddingBefore();
1870a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
18718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1872a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalHeight(beforeEdge);
18738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The margin struct caches all our current margin collapsing state.  The compact struct caches state when we encounter compacts,
1875a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    MarginInfo marginInfo(this, beforeEdge, afterEdge);
18768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Fieldsets need to find their legend and position it inside the border of the object.
18784576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    // The legend then gets skipped during normal layout.  The same is true for ruby text.
18794576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    // It doesn't get included in the normal layout process but is instead skipped.
18804576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    RenderObject* childToExclude = layoutSpecialExcludedChild(relayoutChildren);
18818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1882a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int previousFloatLogicalBottom = 0;
1883a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    maxFloatLogicalBottom = 0;
18848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RenderBox* next = firstChildBox();
18865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
18875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    while (next) {
18885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        RenderBox* child = next;
18895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        next = child->nextSiblingBox();
18905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
18914576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        if (childToExclude == child)
18924576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            continue; // Skip this child, since it will be positioned by the specialized subclass (fieldsets and ruby runs).
18938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Make sure we layout children if they need it.
18958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into
18968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // an auto value.  Add a method to determine this, so that we can avoid the relayout.
1897a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (relayoutChildren || ((child->style()->logicalHeight().isPercent() || child->style()->logicalMinHeight().isPercent() || child->style()->logicalMaxHeight().isPercent()) && !isRenderView()))
18988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            child->setChildNeedsLayout(true, false);
18998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1900a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // If relayoutChildren is set and the child has percentage padding, we also need to invalidate the child's pref widths.
1901a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (relayoutChildren && (child->style()->paddingStart().isPercent() || child->style()->paddingEnd().isPercent()))
1902bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            child->setPreferredLogicalWidthsDirty(true, false);
19038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Handle the four types of special elements first.  These include positioned content, floating content, compacts and
19058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // run-ins.  When we encounter these four types of objects, we don't actually lay them out as normal flow blocks.
19065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (handleSpecialChild(child, marginInfo))
19078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
19088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1909231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Lay out the child.
1910a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        layoutBlockChild(child, marginInfo, previousFloatLogicalBottom, maxFloatLogicalBottom);
1911231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
1912231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1913231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Now do the handling of the bottom of the block, adding in our bottom border/padding and
1914231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // determining the correct collapsed bottom margin information.
1915a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    handleAfterSideOfBlock(beforeEdge, afterEdge, marginInfo);
1916231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
19178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1918a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, int& previousFloatLogicalBottom, int& maxFloatLogicalBottom)
1919231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
1920a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int oldPosMarginBefore = maxPositiveMarginBefore();
1921a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int oldNegMarginBefore = maxNegativeMarginBefore();
19228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1923a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // The child is a normal flow object.  Compute the margins we will use for collapsing now.
1924bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    child->computeBlockDirectionMargins(this);
19258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1926a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Do not allow a collapse if the margin-before-collapse style is set to SEPARATE.
1927bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (child->style()->marginBeforeCollapse() == MSEPARATE) {
1928bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        marginInfo.setAtBeforeSideOfBlock(false);
1929231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        marginInfo.clearMargin();
1930231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
1931231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1932a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Try to guess our correct logical top position.  In most cases this guess will
1933a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // be correct.  Only if we're wrong (when we compute the real logical top position)
1934231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // will we have to potentially relayout.
1935a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalTopEstimate = estimateLogicalTopPosition(child, marginInfo);
1936231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1937231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Cache our old rect so that we can dirty the proper repaint rects if the child moves.
1938231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    IntRect oldRect(child->x(), child->y() , child->width(), child->height());
1939a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int oldLogicalTop = logicalTopForChild(child);
1940a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1941635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#ifndef NDEBUG
1942231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    IntSize oldLayoutDelta = view()->layoutDelta();
1943635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif
1944231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Go ahead and position the child as though it didn't collapse with the top.
1945a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalTopForChild(child, logicalTopEstimate, ApplyLayoutDelta);
1946231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
194768513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0;
1948231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    bool markDescendantsWithFloats = false;
1949a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (logicalTopEstimate != oldLogicalTop && !child->avoidsFloats() && childRenderBlock && childRenderBlock->containsFloats())
1950231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        markDescendantsWithFloats = true;
1951231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) {
1952231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // If an element might be affected by the presence of floats, then always mark it for
1953231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // layout.
1954a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int fb = max(previousFloatLogicalBottom, lowestFloatLogicalBottom());
1955a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (fb > logicalTopEstimate)
19568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            markDescendantsWithFloats = true;
1957231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
19588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
195968513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (childRenderBlock) {
1960231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (markDescendantsWithFloats)
196168513a70bcd92384395513322f1b801e7bf9c729Steve Block            childRenderBlock->markAllDescendantsWithFloatsForLayout();
1962a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!child->isWritingModeRoot())
1963a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            previousFloatLogicalBottom = max(previousFloatLogicalBottom, oldLogicalTop + childRenderBlock->lowestFloatLogicalBottom());
1964231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
19658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1966a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!child->needsLayout())
1967a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->markForPaginationRelayoutIfNeeded();
196868513a70bcd92384395513322f1b801e7bf9c729Steve Block
1969231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    bool childHadLayout = child->m_everHadLayout;
1970231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    bool childNeededLayout = child->needsLayout();
1971231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (childNeededLayout)
1972231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        child->layout();
19738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
197468513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Cache if we are at the top of the block right now.
1975bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock();
197668513a70bcd92384395513322f1b801e7bf9c729Steve Block
1977231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Now determine the correct ypos based off examination of collapsing margin
1978231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // values.
1979a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalTopBeforeClear = collapseMargins(child, marginInfo);
19808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1981231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Now check for clear.
1982a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalTopAfterClear = clearFloatsIfNeeded(child, marginInfo, oldPosMarginBefore, oldNegMarginBefore, logicalTopBeforeClear);
19838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1984a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool paginated = view()->layoutState()->isPaginated();
198568513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (paginated) {
1986a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int oldTop = logicalTopAfterClear;
198768513a70bcd92384395513322f1b801e7bf9c729Steve Block
198868513a70bcd92384395513322f1b801e7bf9c729Steve Block        // If the object has a page or column break value of "before", then we should shift to the top of the next page.
1989a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        logicalTopAfterClear = applyBeforeBreak(child, logicalTopAfterClear);
199068513a70bcd92384395513322f1b801e7bf9c729Steve Block
199168513a70bcd92384395513322f1b801e7bf9c729Steve Block        // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one.
1992a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int logicalTopBeforeUnsplittableAdjustment = logicalTopAfterClear;
1993a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChild(child, logicalTopAfterClear);
199468513a70bcd92384395513322f1b801e7bf9c729Steve Block
199568513a70bcd92384395513322f1b801e7bf9c729Steve Block        int paginationStrut = 0;
1996a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustment - logicalTopBeforeUnsplittableAdjustment;
199768513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (unsplittableAdjustmentDelta)
199868513a70bcd92384395513322f1b801e7bf9c729Steve Block            paginationStrut = unsplittableAdjustmentDelta;
199968513a70bcd92384395513322f1b801e7bf9c729Steve Block        else if (childRenderBlock && childRenderBlock->paginationStrut())
200068513a70bcd92384395513322f1b801e7bf9c729Steve Block            paginationStrut = childRenderBlock->paginationStrut();
200168513a70bcd92384395513322f1b801e7bf9c729Steve Block
200268513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (paginationStrut) {
200368513a70bcd92384395513322f1b801e7bf9c729Steve Block            // We are willing to propagate out to our parent block as long as we were at the top of the block prior
200468513a70bcd92384395513322f1b801e7bf9c729Steve Block            // to collapsing our margins, and as long as we didn't clear or move as a result of other pagination.
2005a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (atBeforeSideOfBlock && oldTop == logicalTopBeforeClear && !isPositioned() && !isTableCell()) {
200668513a70bcd92384395513322f1b801e7bf9c729Steve Block                // FIXME: Should really check if we're exceeding the page height before propagating the strut, but we don't
200768513a70bcd92384395513322f1b801e7bf9c729Steve Block                // have all the information to do so (the strut only has the remaining amount to push).  Gecko gets this wrong too
200868513a70bcd92384395513322f1b801e7bf9c729Steve Block                // and pushes to the next page anyway, so not too concerned about it.
2009a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                setPaginationStrut(logicalTopAfterClear + paginationStrut);
201068513a70bcd92384395513322f1b801e7bf9c729Steve Block                if (childRenderBlock)
201168513a70bcd92384395513322f1b801e7bf9c729Steve Block                    childRenderBlock->setPaginationStrut(0);
201268513a70bcd92384395513322f1b801e7bf9c729Steve Block            } else
2013a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                logicalTopAfterClear += paginationStrut;
201468513a70bcd92384395513322f1b801e7bf9c729Steve Block        }
201568513a70bcd92384395513322f1b801e7bf9c729Steve Block
201668513a70bcd92384395513322f1b801e7bf9c729Steve Block        // Similar to how we apply clearance.  Go ahead and boost height() to be the place where we're going to position the child.
2017a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalHeight(logicalHeight() + (logicalTopAfterClear - oldTop));
201868513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
201968513a70bcd92384395513322f1b801e7bf9c729Steve Block
2020a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalTopForChild(child, logicalTopAfterClear, ApplyLayoutDelta);
2021231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
2022a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Now we have a final top position.  See if it really does end up being different from our estimate.
2023a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (logicalTopAfterClear != logicalTopEstimate) {
2024231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (child->shrinkToAvoidFloats()) {
2025231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // The child's width depends on the line width.
2026231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // When the child shifts to clear an item, its width can
2027231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // change (because it has more available line width).
2028231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // So go ahead and mark the item as dirty.
2029231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            child->setChildNeedsLayout(true, false);
20308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
203168513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (childRenderBlock) {
203268513a70bcd92384395513322f1b801e7bf9c729Steve Block            if (!child->avoidsFloats() && childRenderBlock->containsFloats())
203368513a70bcd92384395513322f1b801e7bf9c729Steve Block                childRenderBlock->markAllDescendantsWithFloatsForLayout();
2034a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (!child->needsLayout())
2035a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                child->markForPaginationRelayoutIfNeeded();
203668513a70bcd92384395513322f1b801e7bf9c729Steve Block        }
203768513a70bcd92384395513322f1b801e7bf9c729Steve Block
2038231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Our guess was wrong. Make the child lay itself out again.
2039231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        child->layoutIfNeeded();
2040231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
20418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2042231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // We are no longer at the top of the block if we encounter a non-empty child.
2043231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // This has to be done after checking for clear, so that margins can be reset if a clear occurred.
2044bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (marginInfo.atBeforeSideOfBlock() && !child->isSelfCollapsingBlock())
2045bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        marginInfo.setAtBeforeSideOfBlock(false);
20468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2047a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Now place the child in the correct left position
2048a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    determineLogicalLeftPositionForChild(child);
20498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2050231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Update our height now that the child has been placed in the correct position.
2051a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalHeight(logicalHeight() + logicalHeightForChild(child));
2052bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (child->style()->marginAfterCollapse() == MSEPARATE) {
2053a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalHeight(logicalHeight() + marginAfterForChild(child));
2054231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        marginInfo.clearMargin();
2055231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
2056231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // If the child has overhanging floats that intrude into following siblings (or possibly out
2057231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // of this block), then the parent gets notified of the floats now.
205868513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (childRenderBlock && childRenderBlock->containsFloats())
2059a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        maxFloatLogicalBottom = max(maxFloatLogicalBottom, addOverhangingFloats(toRenderBlock(child), -child->logicalLeft(), -child->logicalTop(), !childNeededLayout));
20608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2061231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    IntSize childOffset(child->x() - oldRect.x(), child->y() - oldRect.y());
2062231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (childOffset.width() || childOffset.height()) {
2063231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        view()->addLayoutDelta(childOffset);
20648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2065231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // If the child moved, we have to repaint it as well as any floating/positioned
2066231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // descendants.  An exception is if we need a layout.  In this case, we know we're going to
2067231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // repaint ourselves (and the child) anyway.
2068231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (childHadLayout && !selfNeedsLayout() && child->checkForRepaintDuringLayout())
2069231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            child->repaintDuringLayoutIfMoved(oldRect);
2070231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
20718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2072231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!childHadLayout && child->checkForRepaintDuringLayout()) {
2073231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        child->repaint();
2074231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        child->repaintOverhangingFloats(true);
20758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
20768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
207768513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (paginated) {
207868513a70bcd92384395513322f1b801e7bf9c729Steve Block        // Check for an after page/column break.
20792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int newHeight = applyAfterBreak(child, logicalHeight(), marginInfo);
208068513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (newHeight != height())
2081bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setLogicalHeight(newHeight);
208268513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
208368513a70bcd92384395513322f1b801e7bf9c729Steve Block
2084231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    ASSERT(oldLayoutDelta == view()->layoutDelta());
20858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
20868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
20872bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid RenderBlock::simplifiedNormalFlowLayout()
20888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
20892bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (childrenInline()) {
20902bde8e466a4451c7319e3a072d118917957d6554Steve Block        ListHashSet<RootInlineBox*> lineBoxes;
20912bde8e466a4451c7319e3a072d118917957d6554Steve Block        bool endOfInline = false;
20922bde8e466a4451c7319e3a072d118917957d6554Steve Block        RenderObject* o = bidiFirst(this, 0, false);
20932bde8e466a4451c7319e3a072d118917957d6554Steve Block        while (o) {
20942bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (!o->isPositioned() && (o->isReplaced() || o->isFloating())) {
20952bde8e466a4451c7319e3a072d118917957d6554Steve Block                o->layoutIfNeeded();
20962bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (toRenderBox(o)->inlineBoxWrapper()) {
20972bde8e466a4451c7319e3a072d118917957d6554Steve Block                    RootInlineBox* box = toRenderBox(o)->inlineBoxWrapper()->root();
20982bde8e466a4451c7319e3a072d118917957d6554Steve Block                    lineBoxes.add(box);
20992bde8e466a4451c7319e3a072d118917957d6554Steve Block                }
21002bde8e466a4451c7319e3a072d118917957d6554Steve Block            } else if (o->isText() || (o->isRenderInline() && !endOfInline))
21012bde8e466a4451c7319e3a072d118917957d6554Steve Block                o->setNeedsLayout(false);
21022bde8e466a4451c7319e3a072d118917957d6554Steve Block            o = bidiNext(this, o, 0, false, &endOfInline);
21032bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
21042bde8e466a4451c7319e3a072d118917957d6554Steve Block
21052bde8e466a4451c7319e3a072d118917957d6554Steve Block        // FIXME: Glyph overflow will get lost in this case, but not really a big deal.
21062bde8e466a4451c7319e3a072d118917957d6554Steve Block        GlyphOverflowAndFallbackFontsMap textBoxDataMap;
21072bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it != lineBoxes.end(); ++it) {
21082bde8e466a4451c7319e3a072d118917957d6554Steve Block            RootInlineBox* box = *it;
21092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap);
21102bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
21112bde8e466a4451c7319e3a072d118917957d6554Steve Block    } else {
21122bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (RenderBox* box = firstChildBox(); box; box = box->nextSiblingBox()) {
21132bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (!box->isPositioned())
21142bde8e466a4451c7319e3a072d118917957d6554Steve Block                box->layoutIfNeeded();
21152bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
21162bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
21172bde8e466a4451c7319e3a072d118917957d6554Steve Block}
21182bde8e466a4451c7319e3a072d118917957d6554Steve Block
21192bde8e466a4451c7319e3a072d118917957d6554Steve Blockbool RenderBlock::simplifiedLayout()
21202bde8e466a4451c7319e3a072d118917957d6554Steve Block{
21212bde8e466a4451c7319e3a072d118917957d6554Steve Block    if ((!posChildNeedsLayout() && !needsSimplifiedNormalFlowLayout()) || normalChildNeedsLayout() || selfNeedsLayout())
21228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
21238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21246b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
21252bde8e466a4451c7319e3a072d118917957d6554Steve Block
21262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (needsPositionedMovementLayout() && !tryLayoutDoingPositionedMovementOnly())
21272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return false;
21288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21292bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Lay out positioned descendants or objects that just need to recompute overflow.
21302bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (needsSimplifiedNormalFlowLayout())
21312bde8e466a4451c7319e3a072d118917957d6554Steve Block        simplifiedNormalFlowLayout();
21322bde8e466a4451c7319e3a072d118917957d6554Steve Block
21332bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Lay out our positioned objects if our positioned child bit is set.
21342bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (posChildNeedsLayout())
21352bde8e466a4451c7319e3a072d118917957d6554Steve Block        layoutPositionedObjects(false);
21368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2137f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Recompute our overflow information.
2138f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // FIXME: We could do better here by computing a temporary overflow object from layoutPositionedObjects and only
2139f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // updating our overflow if we either used to have overflow or if the new temporary object has overflow.
2140f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // For now just always recompute overflow.  This is no worse performance-wise than the old code that called rightmostPosition and
2141f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // lowestPosition on every relayout so it's not a regression.
2142f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    m_overflow.clear();
2143f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    computeOverflow(clientLogicalBottom(), true);
2144f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
2145635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    statePusher.pop();
2146f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
2147f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    updateLayerTransform();
21488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    updateScrollInfoAfterLayout();
21508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2151c4e3b3281a821e60834e2bdb4e3358986dda5b91Grace Kloba#ifdef ANDROID_FIX
2152bc7b84de3fd863c500a8169fd00dca3811cadbb3Steve Block    // iframe flatten will call FrameView::layout() which calls performPostLayoutTasks,
2153c4e3b3281a821e60834e2bdb4e3358986dda5b91Grace Kloba    // which may make us need to layout again
2154c4e3b3281a821e60834e2bdb4e3358986dda5b91Grace Kloba    if (!posChildNeedsLayout() || normalChildNeedsLayout() || selfNeedsLayout())
2155c4e3b3281a821e60834e2bdb4e3358986dda5b91Grace Kloba        return false;
2156c4e3b3281a821e60834e2bdb4e3358986dda5b91Grace Kloba#endif
2157c4e3b3281a821e60834e2bdb4e3358986dda5b91Grace Kloba
21588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setNeedsLayout(false);
21598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
21608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
21618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::layoutPositionedObjects(bool relayoutChildren)
21638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2164f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!m_positionedObjects)
2165f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return;
2166f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
2167f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (hasColumns())
2168f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        view()->layoutState()->clearPaginationInformation(); // Positioned objects are not part of the column flow, so they don't paginate with the columns.
216968513a70bcd92384395513322f1b801e7bf9c729Steve Block
2170f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    RenderBox* r;
2171f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    Iterator end = m_positionedObjects->end();
2172f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
2173f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        r = *it;
2174f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the
2175f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // non-positioned block.  Rather than trying to detect all of these movement cases, we just always lay out positioned
2176f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // objects that are positioned implicitly like this.  Such objects are rare, and so in typical DHTML menu usage (where everything is
2177f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // positioned explicitly) this should not incur a performance penalty.
21782bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (relayoutChildren || (r->style()->hasStaticBlockPosition(isHorizontalWritingMode()) && r->parent() != this && r->parent()->isBlockFlow()))
2179f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            r->setChildNeedsLayout(true, false);
21808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2181f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.
2182f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (relayoutChildren && (r->style()->paddingStart().isPercent() || r->style()->paddingEnd().isPercent()))
2183f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            r->setPreferredLogicalWidthsDirty(true, false);
218468513a70bcd92384395513322f1b801e7bf9c729Steve Block
2185f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (!r->needsLayout())
2186f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            r->markForPaginationRelayoutIfNeeded();
2187f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
2188f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // We don't have to do a full layout.  We just have to update our position. Try that first. If we have shrink-to-fit width
2189f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // and we hit the available width constraint, the layoutIfNeeded() will catch it and do a full layout.
21902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (r->needsPositionedMovementLayoutOnly() && r->tryLayoutDoingPositionedMovementOnly())
21912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            r->setNeedsLayout(false);
2192f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        r->layoutIfNeeded();
21938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2194f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
2195f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (hasColumns())
2196f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        view()->layoutState()->m_columnInfo = columnInfo(); // FIXME: Kind of gross. We just put this back into the layout state so that pop() will work.
21978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
21988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::markPositionedObjectsForLayout()
22008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
22018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_positionedObjects) {
2202635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        RenderBox* r;
22038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Iterator end = m_positionedObjects->end();
22048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
22058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            r = *it;
22068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            r->setChildNeedsLayout(true);
22078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
22088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
22098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
22108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2211a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::markForPaginationRelayoutIfNeeded()
2212a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
2213a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ASSERT(!needsLayout());
2214a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (needsLayout())
2215a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
2216a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
22172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(logicalTop()) != pageLogicalOffset()))
2218a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setChildNeedsLayout(true, false);
2219a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
2220a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
22218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::repaintOverhangingFloats(bool paintAllDescendants)
22228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
22238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Repaint any overhanging floats (if we know we're the one to paint them).
22248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (hasOverhangingFloats()) {
22258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We think that we must be in a bad state if m_floatingObjects is nil at this point, so
22268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // we assert on Debug builds and nil-check Release builds.
22278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(m_floatingObjects);
22288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!m_floatingObjects)
22298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
22308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: Avoid disabling LayoutState. At the very least, don't disable it for floats originating
22328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // in this block. Better yet would be to push extra state for the containers of other floats.
22338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        view()->disableLayoutState();
223481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
223581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSetIterator end = floatingObjectSet.end();
223681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
223781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObject* r = *it;
22388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Only repaint the object if it is overhanging, is not in its own layer, and
22398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // is our responsibility to paint (m_shouldPaint is set). When paintAllDescendants is true, the latter
22408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // condition is replaced with being a descendant of us.
2241a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (logicalBottomForFloat(r) > logicalHeight() && ((paintAllDescendants && r->m_renderer->isDescendantOf(this)) || r->m_shouldPaint) && !r->m_renderer->hasSelfPaintingLayer()) {
22428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                r->m_renderer->repaint();
22438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                r->m_renderer->repaintOverhangingFloats();
22448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
22458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
22468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        view()->enableLayoutState();
22478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
22488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
22498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
22508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paint(PaintInfo& paintInfo, int tx, int ty)
22518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2252635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    tx += x();
2253635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ty += y();
22548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    PaintPhase phase = paintInfo.phase;
22568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Check if we need to do anything at all.
22588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
22598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // paints the root's background.
2260635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!isRoot()) {
2261f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        IntRect overflowBox = visualOverflowRect();
22622bde8e466a4451c7319e3a072d118917957d6554Steve Block        flipForWritingMode(overflowBox);
22638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        overflowBox.inflate(maximalOutlineSize(paintInfo.phase));
22648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        overflowBox.move(tx, ty);
22658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!overflowBox.intersects(paintInfo.rect))
22668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
22678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
22688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool pushedClip = pushContentsClip(paintInfo, tx, ty);
22708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    paintObject(paintInfo, tx, ty);
22718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (pushedClip)
22728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        popContentsClip(paintInfo, phase, tx, ty);
22738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
22758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // z-index.  We paint after we painted the background/border, so that the scrollbars will
22768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // sit above the background/border.
2277ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.shouldPaintWithinRoot(this))
22788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        layer()->paintOverflowControls(paintInfo.context, tx, ty, paintInfo.rect);
22798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
22808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::paintColumnRules(PaintInfo& paintInfo, int tx, int ty)
22828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
2283dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    const Color& ruleColor = style()->visitedDependentColor(CSSPropertyWebkitColumnRuleColor);
22848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool ruleTransparent = style()->columnRuleIsTransparent();
22858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    EBorderStyle ruleStyle = style()->columnRuleStyle();
22868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int ruleWidth = style()->columnRuleWidth();
22878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int colGap = columnGap();
22888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent && ruleWidth <= colGap;
22898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!renderRule)
22908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
22918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
22928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // We need to do multiple passes, breaking up our child painting into strips.
22935abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    ColumnInfo* colInfo = columnInfo();
229468513a70bcd92384395513322f1b801e7bf9c729Steve Block    unsigned colCount = columnCount(colInfo);
22952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int currLogicalLeftOffset = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth();
22962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int ruleAdd = logicalLeftOffsetForContent();
22972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int ruleLogicalLeft = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth();
22988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    for (unsigned i = 0; i < colCount; i++) {
229968513a70bcd92384395513322f1b801e7bf9c729Steve Block        IntRect colRect = columnRectAt(colInfo, i);
23008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
23012bde8e466a4451c7319e3a072d118917957d6554Steve Block        int inlineDirectionSize = isHorizontalWritingMode() ? colRect.width() : colRect.height();
23022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
23038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // Move to the next position.
2304a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->isLeftToRightDirection()) {
23052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            ruleLogicalLeft += inlineDirectionSize + colGap / 2;
23062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalLeftOffset += inlineDirectionSize + colGap;
23078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else {
23082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            ruleLogicalLeft -= (inlineDirectionSize + colGap / 2);
23092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalLeftOffset -= (inlineDirectionSize + colGap);
23108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
23118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
23128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // Now paint the column rule.
23138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (i < colCount - 1) {
23142bde8e466a4451c7319e3a072d118917957d6554Steve Block            int ruleLeft = isHorizontalWritingMode() ? tx + ruleLogicalLeft - ruleWidth / 2 + ruleAdd : tx + borderBefore() + paddingBefore();
23152bde8e466a4451c7319e3a072d118917957d6554Steve Block            int ruleRight = isHorizontalWritingMode() ? ruleLeft + ruleWidth : ruleLeft + contentWidth();
23162bde8e466a4451c7319e3a072d118917957d6554Steve Block            int ruleTop = isHorizontalWritingMode() ? ty + borderTop() + paddingTop() : ty + ruleLogicalLeft - ruleWidth / 2 + ruleAdd;
23172bde8e466a4451c7319e3a072d118917957d6554Steve Block            int ruleBottom = isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleWidth;
23182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            drawLineForBoxSide(paintInfo.context, ruleLeft, ruleTop, ruleRight, ruleBottom,
2319a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                               style()->isLeftToRightDirection() ? BSLeft : BSRight, ruleColor, ruleStyle, 0, 0);
23208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
23218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
23222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        ruleLogicalLeft = currLogicalLeftOffset;
23238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
23248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
23258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
23268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::paintColumnContents(PaintInfo& paintInfo, int tx, int ty, bool paintingFloats)
23278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
23288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We need to do multiple passes, breaking up our child painting into strips.
23298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GraphicsContext* context = paintInfo.context;
23305abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    ColumnInfo* colInfo = columnInfo();
233168513a70bcd92384395513322f1b801e7bf9c729Steve Block    unsigned colCount = columnCount(colInfo);
23326c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (!colCount)
23336c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        return;
23342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int currLogicalTopOffset = 0;
23358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < colCount; i++) {
23368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // For each rect, we clip to the rect, and then we adjust our coords.
233768513a70bcd92384395513322f1b801e7bf9c729Steve Block        IntRect colRect = columnRectAt(colInfo, i);
23382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        flipForWritingMode(colRect);
23392bde8e466a4451c7319e3a072d118917957d6554Steve Block        int logicalLeftOffset = (isHorizontalWritingMode() ? colRect.x() : colRect.y()) - logicalLeftOffsetForContent();
23402bde8e466a4451c7319e3a072d118917957d6554Steve Block        IntSize offset = isHorizontalWritingMode() ? IntSize(logicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, logicalLeftOffset);
23418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        colRect.move(tx, ty);
23428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PaintInfo info(paintInfo);
23438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        info.rect.intersect(colRect);
23448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2345e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        if (!info.rect.isEmpty()) {
2346e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            context->save();
2347e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block
2348e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            // Each strip pushes a clip, since column boxes are specified as being
2349e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            // like overflow:hidden.
2350e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            context->clip(colRect);
23512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2352e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            // Adjust our x and y when painting.
23532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int finalX = tx + offset.width();
23542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int finalY = ty + offset.height();
2355e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            if (paintingFloats)
2356e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block                paintFloats(info, finalX, finalY, paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip);
2357e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            else
2358e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block                paintContents(info, finalX, finalY);
23598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2360e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            context->restore();
2361e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        }
23622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
23632bde8e466a4451c7319e3a072d118917957d6554Steve Block        int blockDelta = (isHorizontalWritingMode() ? colRect.height() : colRect.width());
23642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (style()->isFlippedBlocksWritingMode())
23652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalTopOffset += blockDelta;
23668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        else
23672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalTopOffset -= blockDelta;
23688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
23698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
23708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
23718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintContents(PaintInfo& paintInfo, int tx, int ty)
23728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
23738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Avoid painting descendants of the root element when stylesheets haven't loaded.  This eliminates FOUC.
23748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
23758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // will do a full repaint().
23762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (document()->didLayoutWithPendingStylesheets() && !isRenderView())
23778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
23788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
23798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childrenInline())
23808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_lineBoxes.paint(this, paintInfo, tx, ty);
23818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
23828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        paintChildren(paintInfo, tx, ty);
23838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
23848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
23858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
23868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
23878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
23888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;
23898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
23908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We don't paint our own background, but we do let the kids paint their backgrounds.
23918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    PaintInfo info(paintInfo);
23928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    info.phase = newPhase;
2393ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    info.updatePaintingRootForChildren(this);
23945ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
239568513a70bcd92384395513322f1b801e7bf9c729Steve Block    // FIXME: Paint-time pagination is obsolete and is now only used by embedded WebViews inside AppKit
239668513a70bcd92384395513322f1b801e7bf9c729Steve Block    // NSViews.  Do not add any more code for this.
23975ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    RenderView* renderView = view();
239868513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool usePrintRect = !renderView->printRect().isEmpty();
23995ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
2400635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
24018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Check for page-break-before: always, and if it's set, break and bail.
240268513a70bcd92384395513322f1b801e7bf9c729Steve Block        bool checkBeforeAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakBefore() == PBALWAYS);
2403545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (checkBeforeAlways
2404dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            && (ty + child->y()) > paintInfo.rect.y()
24052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            && (ty + child->y()) < paintInfo.rect.maxY()) {
2406635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            view()->setBestTruncatedAt(ty + child->y(), this, true);
24078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
24088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
24098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24105ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        if (!child->isFloating() && child->isReplaced() && usePrintRect && child->height() <= renderView->printRect().height()) {
24115ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            // Paginate block-level replaced elements.
24122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (ty + child->y() + child->height() > renderView->printRect().maxY()) {
24135ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                if (ty + child->y() < renderView->truncatedAt())
24145ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                    renderView->setBestTruncatedAt(ty + child->y(), child);
24155ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                // If we were able to truncate, don't paint.
24165ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                if (ty + child->y() >= renderView->truncatedAt())
24175ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                    break;
24185ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            }
24195ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        }
24205ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
242128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        IntPoint childPoint = flipForWritingMode(child, IntPoint(tx, ty), ParentToChildFlippingAdjustment);
24228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (!child->hasSelfPaintingLayer() && !child->isFloating())
2423e14391e94c850b8bd03680c23b38978db68687a8John Reck            child->paint(info, childPoint.x(), childPoint.y());
24248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Check for page-break-after: always, and if it's set, break and bail.
242668513a70bcd92384395513322f1b801e7bf9c729Steve Block        bool checkAfterAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakAfter() == PBALWAYS);
2427545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (checkAfterAlways
2428dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            && (ty + child->y() + child->height()) > paintInfo.rect.y()
24292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            && (ty + child->y() + child->height()) < paintInfo.rect.maxY()) {
2430bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            view()->setBestTruncatedAt(ty + child->y() + child->height() + max(0, child->collapsedMarginAfter()), this, true);
24318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
24328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
24338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
24348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
24358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2436635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::paintCaret(PaintInfo& paintInfo, int tx, int ty, CaretType type)
24378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
243868513a70bcd92384395513322f1b801e7bf9c729Steve Block    SelectionController* selection = type == CursorCaret ? frame()->selection() : frame()->page()->dragCaretController();
2439635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
24405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Paint the caret if the SelectionController says so or if caret browsing is enabled
2441545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    bool caretBrowsing = frame()->settings() && frame()->settings()->caretBrowsingEnabled();
2442635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderObject* caretPainter = selection->caretRenderer();
24435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (caretPainter == this && (selection->isContentEditable() || caretBrowsing)) {
2444635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // Convert the painting offset into the local coordinate system of this renderer,
2445635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // to match the localCaretRect computed by the SelectionController
2446635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        offsetForContents(tx, ty);
2447635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
24488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (type == CursorCaret)
2449545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            frame()->selection()->paintCaret(paintInfo.context, tx, ty, paintInfo.rect);
24508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
245168513a70bcd92384395513322f1b801e7bf9c729Steve Block            frame()->selection()->paintDragCaret(paintInfo.context, tx, ty, paintInfo.rect);
24528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
24538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
24548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintObject(PaintInfo& paintInfo, int tx, int ty)
24568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
24578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    PaintPhase paintPhase = paintInfo.phase;
24588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 1. paint background, borders etc
24608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && style()->visibility() == VISIBLE) {
24618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (hasBoxDecorations())
24628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            paintBoxDecorations(paintInfo, tx, ty);
24638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (hasColumns())
24648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            paintColumnRules(paintInfo, tx, ty);
24658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
24668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintPhase == PaintPhaseMask && style()->visibility() == VISIBLE) {
24688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        paintMask(paintInfo, tx, ty);
24698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
24708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
24718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We're done.  We don't bother painting any children.
24738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintPhase == PaintPhaseBlockBackground)
24748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
24758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2476dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).
24778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int scrolledX = tx;
24788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int scrolledY = ty;
2479dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (hasOverflowClip()) {
2480dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        IntSize offset = layer()->scrolledContentOffset();
2481dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        scrolledX -= offset.width();
2482dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        scrolledY -= offset.height();
2483dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
24848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 2. paint contents
24868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintPhase != PaintPhaseSelfOutline) {
24878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (hasColumns())
24888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            paintColumnContents(paintInfo, scrolledX, scrolledY);
24898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
24908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            paintContents(paintInfo, scrolledX, scrolledY);
24918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
24928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 3. paint selection
24948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Make this work with multi column layouts.  For now don't fill gaps.
24958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool isPrinting = document()->printing();
24968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!isPrinting && !hasColumns())
24978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        paintSelection(paintInfo, scrolledX, scrolledY); // Fill in gaps in selection on lines and between blocks.
24988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 4. paint floats.
2500635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip) {
25018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (hasColumns())
25028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            paintColumnContents(paintInfo, scrolledX, scrolledY, true);
25038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
25048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            paintFloats(paintInfo, scrolledX, scrolledY, paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip);
25058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
25068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 5. paint outline.
2508635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
2509dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        paintOutline(paintInfo.context, tx, ty, width(), height());
25108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 6. paint continuation outlines.
2512635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
2513e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        RenderInline* inlineCont = inlineElementContinuation();
2514e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        if (inlineCont && inlineCont->hasOutline() && inlineCont->style()->visibility() == VISIBLE) {
2515e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            RenderInline* inlineRenderer = toRenderInline(inlineCont->node()->renderer());
2516e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            RenderBlock* cb = containingBlock();
2517e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
2518e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            bool inlineEnclosedInSelfPaintingLayer = false;
2519e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            for (RenderBoxModelObject* box = inlineRenderer; box != cb; box = box->parent()->enclosingBoxModelObject()) {
2520e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                if (box->hasSelfPaintingLayer()) {
2521e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                    inlineEnclosedInSelfPaintingLayer = true;
2522e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                    break;
2523e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                }
2524e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            }
2525e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
2526e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            if (!inlineEnclosedInSelfPaintingLayer)
2527e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                cb->addContinuationWithOutline(inlineRenderer);
25288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            else if (!inlineRenderer->firstLineBox())
25298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                inlineRenderer->paintOutline(paintInfo.context, tx - x() + inlineRenderer->containingBlock()->x(),
25308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                                             ty - y() + inlineRenderer->containingBlock()->y());
25318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
25328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        paintContinuationOutlines(paintInfo, tx, ty);
25338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
25348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 7. paint caret.
25368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
25378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // then paint the caret.
2538635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (paintPhase == PaintPhaseForeground) {
2539635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        paintCaret(paintInfo, scrolledX, scrolledY, CursorCaret);
2540635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        paintCaret(paintInfo, scrolledX, scrolledY, DragCaret);
25418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
25428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
25438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25442fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockIntPoint RenderBlock::flipFloatForWritingMode(const FloatingObject* child, const IntPoint& point) const
25452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
25462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!style()->isFlippedBlocksWritingMode())
25472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return point;
25482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
25492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // This is similar to the ParentToChildFlippingAdjustment in RenderBox::flipForWritingMode.  We have to subtract out our left/top offsets twice, since
25502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // it's going to get added back in.  We hide this complication here so that the calling code looks normal for the unflipped
25512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // case.
25522bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
25532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return IntPoint(point.x(), point.y() + height() - child->renderer()->height() - 2 * yPositionForFloatIncludingMargin(child));
25542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return IntPoint(point.x() + width() - child->width() - 2 * xPositionForFloatIncludingMargin(child), point.y());
25552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
25562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
25578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintFloats(PaintInfo& paintInfo, int tx, int ty, bool preservePhase)
25588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
25598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_floatingObjects)
25608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
25618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
256281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
256381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator end = floatingObjectSet.end();
256481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
256581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObject* r = *it;
25668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Only paint the object if our m_shouldPaint flag is set.
25678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
25688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            PaintInfo currentPaintInfo(paintInfo);
25698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
25702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            IntPoint childPoint = flipFloatForWritingMode(r, IntPoint(tx + xPositionForFloatIncludingMargin(r) - r->m_renderer->x(), ty + yPositionForFloatIncludingMargin(r) - r->m_renderer->y()));
2571e14391e94c850b8bd03680c23b38978db68687a8John Reck            r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
25728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!preservePhase) {
25738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                currentPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
2574e14391e94c850b8bd03680c23b38978db68687a8John Reck                r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
25758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                currentPaintInfo.phase = PaintPhaseFloat;
2576e14391e94c850b8bd03680c23b38978db68687a8John Reck                r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
25778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                currentPaintInfo.phase = PaintPhaseForeground;
2578e14391e94c850b8bd03680c23b38978db68687a8John Reck                r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
25798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                currentPaintInfo.phase = PaintPhaseOutline;
2580e14391e94c850b8bd03680c23b38978db68687a8John Reck                r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
25818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
25828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
25838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
25848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
25858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintEllipsisBoxes(PaintInfo& paintInfo, int tx, int ty)
25878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2588ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (!paintInfo.shouldPaintWithinRoot(this) || !firstLineBox())
25898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
25908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->visibility() == VISIBLE && paintInfo.phase == PaintPhaseForeground) {
25928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We can check the first box and last box and avoid painting if we don't
25938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // intersect.
25948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        int yPos = ty + firstLineBox()->y();
2595bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        int h = lastLineBox()->y() + lastLineBox()->logicalHeight() - firstLineBox()->y();
25962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (yPos >= paintInfo.rect.maxY() || yPos + h <= paintInfo.rect.y())
25978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
25988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // See if our boxes intersect with the dirty rect.  If so, then we paint
26008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // them.  Note that boxes can easily overlap, so we can't make any assumptions
26018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // based off positions of our first line box or our last line box.
26028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
26038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            yPos = ty + curr->y();
2604bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            h = curr->logicalHeight();
26052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (curr->ellipsisBox() && yPos < paintInfo.rect.maxY() && yPos + h > paintInfo.rect.y())
26062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                curr->paintEllipsisBox(paintInfo, tx, ty, curr->lineTop(), curr->lineBottom());
26078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
26088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
26098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
26108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2611e78cbe89e6f337f2f1fe40315be88f742b547151Steve BlockRenderInline* RenderBlock::inlineElementContinuation() const
2612e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block{
2613cad810f21b803229eb11403f9209855525a25d57Steve Block    RenderBoxModelObject* continuation = this->continuation();
2614cad810f21b803229eb11403f9209855525a25d57Steve Block    return continuation && continuation->isInline() ? toRenderInline(continuation) : 0;
2615e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block}
2616e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block
2617e78cbe89e6f337f2f1fe40315be88f742b547151Steve BlockRenderBlock* RenderBlock::blockElementContinuation() const
2618e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block{
2619cad810f21b803229eb11403f9209855525a25d57Steve Block    RenderBoxModelObject* currentContinuation = continuation();
2620cad810f21b803229eb11403f9209855525a25d57Steve Block    if (!currentContinuation || currentContinuation->isInline())
2621e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        return 0;
2622cad810f21b803229eb11403f9209855525a25d57Steve Block    RenderBlock* nextContinuation = toRenderBlock(currentContinuation);
2623e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (nextContinuation->isAnonymousBlock())
2624e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        return nextContinuation->blockElementContinuation();
2625545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return nextContinuation;
2626e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block}
2627e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block
2628635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic ContinuationOutlineTableMap* continuationOutlineTable()
26298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2630635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ());
26318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return &table;
26328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
26338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::addContinuationWithOutline(RenderInline* flow)
26358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
26368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We can't make this work if the inline is in a layer.  We'll just rely on the broken
26378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // way of painting.
2638e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    ASSERT(!flow->layer() && !flow->isInlineElementContinuation());
26398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2640635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ContinuationOutlineTableMap* table = continuationOutlineTable();
26418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ListHashSet<RenderInline*>* continuations = table->get(this);
26428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!continuations) {
26438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        continuations = new ListHashSet<RenderInline*>;
26448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        table->set(this, continuations);
26458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
26468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    continuations->add(flow);
26488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
26498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
265081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochbool RenderBlock::paintsContinuationOutline(RenderInline* flow)
265181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
265281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ContinuationOutlineTableMap* table = continuationOutlineTable();
265381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (table->isEmpty())
265481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return false;
265581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
265681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ListHashSet<RenderInline*>* continuations = table->get(this);
265781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!continuations)
265881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return false;
265981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
266081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return continuations->contains(flow);
266181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
266281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
26638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintContinuationOutlines(PaintInfo& info, int tx, int ty)
26648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2665635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ContinuationOutlineTableMap* table = continuationOutlineTable();
26668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (table->isEmpty())
26678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
26688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ListHashSet<RenderInline*>* continuations = table->get(this);
26708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!continuations)
26718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
26728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Paint each continuation outline.
26748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ListHashSet<RenderInline*>::iterator end = continuations->end();
26758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    for (ListHashSet<RenderInline*>::iterator it = continuations->begin(); it != end; ++it) {
26768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Need to add in the coordinates of the intervening blocks.
26778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderInline* flow = *it;
26788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderBlock* block = flow->containingBlock();
26798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for ( ; block && block != this; block = block->containingBlock()) {
2680635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            tx += block->x();
2681635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            ty += block->y();
26828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
26838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(block);
26848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        flow->paintOutline(info.context, tx, ty);
26858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
26868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Delete
26888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    delete continuations;
26898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    table->remove(this);
26908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
26918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::shouldPaintSelectionGaps() const
26938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
26948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot();
26958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
26968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::isSelectionRoot() const
26988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
26998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!node())
27008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
27018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Eventually tables should have to learn how to fill gaps between cells, at least in simple non-spanning cases.
27038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isTable())
27048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
27058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isBody() || isRoot() || hasOverflowClip() || isRelPositioned() ||
27078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        isFloatingOrPositioned() || isTableCell() || isInlineBlockOrInlineTable() || hasTransform() ||
270828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        hasReflection() || hasMask() || isWritingModeRoot())
27098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
27108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (view() && view()->selectionStart()) {
27128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        Node* startElement = view()->selectionStart()->node();
27138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (startElement && startElement->rootEditableElement() == node())
27148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
27158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
27168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
27188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
27198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2720643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockGapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer)
27218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
27228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!needsLayout());
27238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!shouldPaintSelectionGaps())
27258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return GapRects();
27268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2727643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // FIXME: this is broken with transforms
2728643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
2729643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    mapLocalToContainer(repaintContainer, false, false, transformState);
2730dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    IntPoint offsetFromRepaintContainer = roundedIntPoint(transformState.mappedPoint());
2731643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
27328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (hasOverflowClip())
2733dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        offsetFromRepaintContainer -= layer()->scrolledContentOffset();
27348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2735635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int lastTop = 0;
273628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int lastLeft = logicalLeftSelectionOffset(this, lastTop);
273728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int lastRight = logicalRightSelectionOffset(this, lastTop);
27388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
273928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return selectionGaps(this, offsetFromRepaintContainer, IntSize(), lastTop, lastLeft, lastRight);
27408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
27418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
27438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
27448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (shouldPaintSelectionGaps() && paintInfo.phase == PaintPhaseForeground) {
2745635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        int lastTop = 0;
274628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        int lastLeft = logicalLeftSelectionOffset(this, lastTop);
274728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        int lastRight = logicalRightSelectionOffset(this, lastTop);
27488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        paintInfo.context->save();
274928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        IntRect gapRectsBounds = selectionGaps(this, IntPoint(tx, ty), IntSize(), lastTop, lastLeft, lastRight, &paintInfo);
2750643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (!gapRectsBounds.isEmpty()) {
2751643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (RenderLayer* layer = enclosingLayer()) {
2752d0825bca7fe65beaee391d30da42e937db621564Steve Block                gapRectsBounds.move(IntSize(-tx, -ty));
2753d0825bca7fe65beaee391d30da42e937db621564Steve Block                if (!hasLayer()) {
27546b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                    IntRect localBounds(gapRectsBounds);
27556b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                    flipForWritingMode(localBounds);
27566b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                    gapRectsBounds = localToContainerQuad(FloatRect(localBounds), layer->renderer()).enclosingBoundingBox();
2757692e5dbf12901edacf14812a6fae25462920af42Steve Block                    gapRectsBounds.move(layer->scrolledContentOffset());
2758d0825bca7fe65beaee391d30da42e937db621564Steve Block                }
2759643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                layer->addBlockSelectionGapsBounds(gapRectsBounds);
2760643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            }
2761643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
27628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        paintInfo.context->restore();
27638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
27648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
27658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
276628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic void clipOutPositionedObjects(const PaintInfo* paintInfo, const IntPoint& offset, RenderBlock::PositionedObjectsListHashSet* positionedObjects)
27678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
27688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!positionedObjects)
27698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
27708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2771e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    RenderBlock::PositionedObjectsListHashSet::const_iterator end = positionedObjects->end();
2772e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
2773635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        RenderBox* r = *it;
277428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r->y(), r->width(), r->height()));
27758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
27768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
27778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
277828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic int blockDirectionOffset(RenderBlock* rootBlock, const IntSize& offsetFromRootBlock)
277928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{
27802bde8e466a4451c7319e3a072d118917957d6554Steve Block    return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.height() : offsetFromRootBlock.width();
278128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu}
278228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
278328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic int inlineDirectionOffset(RenderBlock* rootBlock, const IntSize& offsetFromRootBlock)
278428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{
27852bde8e466a4451c7319e3a072d118917957d6554Steve Block    return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.width() : offsetFromRootBlock.height();
278628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu}
278728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
278828040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuIntRect RenderBlock::logicalRectToPhysicalRect(const IntPoint& rootBlockPhysicalPosition, const IntRect& logicalRect)
278928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{
279028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    IntRect result;
27912bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
279228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        result = logicalRect;
279328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    else
279428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        result = IntRect(logicalRect.y(), logicalRect.x(), logicalRect.height(), logicalRect.width());
279528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    flipForWritingMode(result);
279628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    result.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
279728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return result;
279828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu}
279928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
280028040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuGapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
280128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                    int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo)
28028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
28038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore.
28048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Clip out floating and positioned objects when painting selection gaps.
28058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintInfo) {
28068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Note that we don't clip out overflow for positioned objects.  We just stick to the border box.
280728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        IntRect flippedBlockRect = IntRect(offsetFromRootBlock.width(), offsetFromRootBlock.height(), width(), height());
280828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        rootBlock->flipForWritingMode(flippedBlockRect);
280928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        flippedBlockRect.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
281081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), m_positionedObjects.get());
28118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (isBody() || isRoot()) // The <body> must make sure to examine its containingBlock's positioned objects.
28128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock())
281381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                clipOutPositionedObjects(paintInfo, IntPoint(cb->x(), cb->y()), cb->m_positionedObjects.get()); // FIXME: Not right for flipped writing modes.
28148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_floatingObjects) {
281581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
281681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObjectSetIterator end = floatingObjectSet.end();
281781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
281881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                FloatingObject* r = *it;
28192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                IntRect floatBox = IntRect(offsetFromRootBlock.width() + xPositionForFloatIncludingMargin(r),
28202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                                           offsetFromRootBlock.height() + yPositionForFloatIncludingMargin(r),
282128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                           r->m_renderer->width(), r->m_renderer->height());
282228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                rootBlock->flipForWritingMode(floatBox);
282328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                floatBox.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
282428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                paintInfo->context->clipOut(floatBox);
28258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
28268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
28278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
28288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: overflow: auto/scroll regions need more math here, since painting in the border box is different from painting in the padding box (one is scrolled, the other is
28308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // fixed).
28318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GapRects result;
28328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!isBlockFlow()) // FIXME: Make multi-column selection gap filling work someday.
28338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return result;
28348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28355af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (hasColumns() || hasTransform() || style()->columnSpan()) {
28368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: We should learn how to gap fill multiple columns and transforms eventually.
283728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
283828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight());
283928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight());
28408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return result;
28418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
28428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childrenInline())
284428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        result = inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
28458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
284628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
28478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Go ahead and fill the vertical gap all the way to the bottom of our block if the selection extends past our block.
28498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd))
285028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
285128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                             logicalHeight(), paintInfo));
28528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
28538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
28548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
285528040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuGapRects RenderBlock::inlineSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
285628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                          int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo)
28578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
28588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GapRects result;
28598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool containsStart = selectionState() == SelectionStart || selectionState() == SelectionBoth;
28618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!firstLineBox()) {
28638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (containsStart) {
286428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            // Go ahead and update our lastLogicalTop to be the bottom of the block.  <hr>s or empty blocks with height can trip this
28658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // case.
286628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
286728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight());
286828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight());
28698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
28708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return result;
28718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
28728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RootInlineBox* lastSelectedLine = 0;
28748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RootInlineBox* curr;
28758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (curr = firstRootBox(); curr && !curr->hasSelectedChildren(); curr = curr->nextRootBox()) { }
28768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Now paint the gaps for the lines.
28788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (; curr && curr->hasSelectedChildren(); curr = curr->nextRootBox()) {
28798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int selTop =  curr->selectionTop();
28808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int selHeight = curr->selectionHeight();
28818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!containsStart && !lastSelectedLine &&
28838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            selectionState() != SelectionStart && selectionState() != SelectionBoth)
288428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
288528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                                 selTop, paintInfo));
288628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
288728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        IntRect logicalRect(curr->logicalLeft(), selTop, curr->logicalWidth(), selTop + selHeight);
28882bde8e466a4451c7319e3a072d118917957d6554Steve Block        logicalRect.move(isHorizontalWritingMode() ? offsetFromRootBlock : IntSize(offsetFromRootBlock.height(), offsetFromRootBlock.width()));
288928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        IntRect physicalRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect);
28902bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!paintInfo || (isHorizontalWritingMode() && physicalRect.y() < paintInfo->rect.maxY() && physicalRect.maxY() > paintInfo->rect.y())
28912bde8e466a4451c7319e3a072d118917957d6554Steve Block            || (!isHorizontalWritingMode() && physicalRect.x() < paintInfo->rect.maxX() && physicalRect.maxX() > paintInfo->rect.x()))
289228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            result.unite(curr->lineSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, selTop, selHeight, paintInfo));
28938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        lastSelectedLine = curr;
28958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
28968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (containsStart && !lastSelectedLine)
28988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // VisibleSelection must start just after our last line.
28998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        lastSelectedLine = lastRootBox();
29008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (lastSelectedLine && selectionState() != SelectionEnd && selectionState() != SelectionBoth) {
29028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Go ahead and update our lastY to be the bottom of the last selected line.
290328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + lastSelectedLine->selectionBottom();
290428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
290528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        lastLogicalRight = logicalRightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
29068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
29078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
29088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
29098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
291028040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuGapRects RenderBlock::blockSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
291128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                         int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo)
29128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
29138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GapRects result;
29148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Go ahead and jump right to the first block child that contains some selected objects.
2916635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderBox* curr;
2917635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    for (curr = firstChildBox(); curr && curr->selectionState() == SelectionNone; curr = curr->nextSiblingBox()) { }
29188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2919635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    for (bool sawSelectionEnd = false; curr && !sawSelectionEnd; curr = curr->nextSiblingBox()) {
29208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        SelectionState childState = curr->selectionState();
29218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (childState == SelectionBoth || childState == SelectionEnd)
29228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            sawSelectionEnd = true;
29238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (curr->isFloatingOrPositioned())
29258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue; // We must be a normal flow object in order to even be considered.
29268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (curr->isRelPositioned() && curr->hasLayer()) {
29288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // If the relposition offset is anything other than 0, then treat this just like an absolute positioned element.
29298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Just disregard it completely.
2930635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            IntSize relOffset = curr->layer()->relativePositionOffset();
2931635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (relOffset.width() || relOffset.height())
29328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
29338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
29348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTable(); // FIXME: Eventually we won't special-case table like this.
29368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool fillBlockGaps = paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone);
29378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (fillBlockGaps) {
29388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We need to fill the vertical gap above this object.
29398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (childState == SelectionEnd || childState == SelectionInside)
29408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Fill the gap above the object.
294128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
294228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                                     curr->logicalTop(), paintInfo));
29438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Only fill side gaps for objects that paint their own selection if we know for sure the selection is going to extend all the way *past*
29458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // our object.  We know this if the selection did not end inside our object.
29468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (paintsOwnSelection && (childState == SelectionStart || sawSelectionEnd))
29478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                childState = SelectionNone;
29488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Fill side gaps on this object based off its state.
29508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            bool leftGap, rightGap;
295128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            getSelectionGapInfo(childState, leftGap, rightGap);
29528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (leftGap)
295428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                result.uniteLeft(logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalLeft(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
29558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (rightGap)
295628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalRight(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
29578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
295828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            // Update lastLogicalTop to be just underneath the object.  lastLogicalLeft and lastLogicalRight extend as far as
29598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // they can without bumping into floating or positioned objects.  Ideally they will go right up
29608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // to the border of the root selection block.
296128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + curr->logicalBottom();
296228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logicalBottom());
296328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logicalBottom());
29648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (childState != SelectionNone)
29658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We must be a block that has some selected object inside it.  Go ahead and recur.
296628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            result.unite(toRenderBlock(curr)->selectionGaps(rootBlock, rootBlockPhysicalPosition, IntSize(offsetFromRootBlock.width() + curr->x(), offsetFromRootBlock.height() + curr->y()),
296728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                                            lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo));
29688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
29698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
29708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
29718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
297228040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuIntRect RenderBlock::blockSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
297328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                       int lastLogicalTop, int lastLogicalLeft, int lastLogicalRight, int logicalBottom, const PaintInfo* paintInfo)
29748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
297528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int logicalTop = lastLogicalTop;
297628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int logicalHeight = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalBottom - logicalTop;
297728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (logicalHeight <= 0)
29788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return IntRect();
29798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Get the selection offsets for the bottom of the gap
298128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int logicalLeft = max(lastLogicalLeft, logicalLeftSelectionOffset(rootBlock, logicalBottom));
298228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int logicalRight = min(lastLogicalRight, logicalRightSelectionOffset(rootBlock, logicalBottom));
298328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int logicalWidth = logicalRight - logicalLeft;
298428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (logicalWidth <= 0)
29858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return IntRect();
29868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
298728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(logicalLeft, logicalTop, logicalWidth, logicalHeight));
29888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintInfo)
2989643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        paintInfo->context->fillRect(gapRect, selectionBackgroundColor(), style()->colorSpace());
29908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return gapRect;
29918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
29928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
299328040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuIntRect RenderBlock::logicalLeftSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
299428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                             RenderObject* selObj, int logicalLeft, int logicalTop, int logicalHeight, const PaintInfo* paintInfo)
29958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
299628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
299728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalLeft = max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight));
299828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalRight = min(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalLeft, min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight)));
299928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
300028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (rootBlockLogicalWidth <= 0)
30018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return IntRect();
30028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
300328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
30048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintInfo)
3005643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
30068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return gapRect;
30078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
30088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
300928040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuIntRect RenderBlock::logicalRightSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
301028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                              RenderObject* selObj, int logicalRight, int logicalTop, int logicalHeight, const PaintInfo* paintInfo)
30118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
301228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
301328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalLeft = max(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalRight, max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight)));
301428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalRight = min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight));
301528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
301628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (rootBlockLogicalWidth <= 0)
30178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return IntRect();
30188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
301928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
30208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintInfo)
3021643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
30228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return gapRect;
30238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
30248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
302528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuvoid RenderBlock::getSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap)
30268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3027a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool ltr = style()->isLeftToRightDirection();
30288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    leftGap = (state == RenderObject::SelectionInside) ||
30298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project              (state == RenderObject::SelectionEnd && ltr) ||
30308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project              (state == RenderObject::SelectionStart && !ltr);
30318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    rightGap = (state == RenderObject::SelectionInside) ||
30328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project               (state == RenderObject::SelectionStart && ltr) ||
30338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project               (state == RenderObject::SelectionEnd && !ltr);
30348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
30358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
303628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuint RenderBlock::logicalLeftSelectionOffset(RenderBlock* rootBlock, int position)
30378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
303828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int logicalLeft = logicalLeftOffsetForLine(position, false);
303928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (logicalLeft == logicalLeftOffsetForContent()) {
30408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (rootBlock != this)
30418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // The border can potentially be further extended by our containingBlock().
304228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            return containingBlock()->logicalLeftSelectionOffset(rootBlock, position + logicalTop());
304328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        return logicalLeft;
304428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    } else {
30458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderBlock* cb = this;
30468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (cb != rootBlock) {
304728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            logicalLeft += cb->logicalLeft();
30488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            cb = cb->containingBlock();
30498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
30508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
305128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return logicalLeft;
30528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
30538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
305428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuint RenderBlock::logicalRightSelectionOffset(RenderBlock* rootBlock, int position)
30558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
305628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int logicalRight = logicalRightOffsetForLine(position, false);
305728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (logicalRight == logicalRightOffsetForContent()) {
30588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (rootBlock != this)
30598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // The border can potentially be further extended by our containingBlock().
306028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            return containingBlock()->logicalRightSelectionOffset(rootBlock, position + logicalTop());
306128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        return logicalRight;
306228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    } else {
30638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderBlock* cb = this;
30648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (cb != rootBlock) {
306528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            logicalRight += cb->logicalLeft();
30668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            cb = cb->containingBlock();
30678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
30688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
306928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return logicalRight;
30708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
30718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3072635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::insertPositionedObject(RenderBox* o)
30738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
30748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Create the list of special objects if we don't aleady have one
30758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_positionedObjects)
307681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_positionedObjects = adoptPtr(new PositionedObjectsListHashSet);
30778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
30788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_positionedObjects->add(o);
30798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
30808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3081635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::removePositionedObject(RenderBox* o)
30828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
30838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_positionedObjects)
30848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_positionedObjects->remove(o);
30858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
30868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
30878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::removePositionedObjects(RenderBlock* o)
30888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
30898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_positionedObjects)
30908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
30918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3092635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderBox* r;
30938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
30948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Iterator end = m_positionedObjects->end();
30958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3096635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    Vector<RenderBox*, 16> deadObjects;
30978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
30988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
30998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        r = *it;
31008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!o || r->isDescendantOf(o)) {
31018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (o)
31028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                r->setChildNeedsLayout(true, false);
31038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // It is parent blocks job to add positioned child to positioned objects list of its containing block
31058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Parent layout needs to be invalidated to ensure this happens.
31068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderObject* p = r->parent();
31078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            while (p && !p->isRenderBlock())
31088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                p = p->parent();
31098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (p)
31108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                p->setChildNeedsLayout(true);
31118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            deadObjects.append(r);
31138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
31148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
31158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < deadObjects.size(); i++)
31178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_positionedObjects->remove(deadObjects.at(i));
31188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
31198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
312068513a70bcd92384395513322f1b801e7bf9c729Steve BlockRenderBlock::FloatingObject* RenderBlock::insertFloatingObject(RenderBox* o)
31218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
31228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(o->isFloating());
31238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Create the list of special objects if we don't aleady have one
312581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!m_floatingObjects)
312681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_floatingObjects = adoptPtr(new FloatingObjects);
312781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    else {
31288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Don't insert the object again if it's already in the list
312981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
313081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSetIterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(o);
313181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (it != floatingObjectSet.end())
313281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return *it;
31338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
31348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Create the special object entry & append it to the list
31368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FloatingObject* newObj = new FloatingObject(o->style()->floating() == FLEFT ? FloatingObject::FloatLeft : FloatingObject::FloatRight);
313868513a70bcd92384395513322f1b801e7bf9c729Steve Block
313968513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Our location is irrelevant if we're unsplittable or no pagination is in effect.
314068513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Just go ahead and lay out the float.
3141a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool isChildRenderBlock = o->isRenderBlock();
3142f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (isChildRenderBlock && !o->needsLayout() && view()->layoutState()->pageLogicalHeightChanged())
3143a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        o->setChildNeedsLayout(true, false);
3144a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
3145f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    bool affectedByPagination = isChildRenderBlock && view()->layoutState()->m_pageLogicalHeight;
3146a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!affectedByPagination || isWritingModeRoot()) // We are unsplittable if we're a block flow root.
314768513a70bcd92384395513322f1b801e7bf9c729Steve Block        o->layoutIfNeeded();
314868513a70bcd92384395513322f1b801e7bf9c729Steve Block    else {
3149bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        o->computeLogicalWidth();
3150bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        o->computeBlockDirectionMargins(this);
315168513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
3152a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalWidthForFloat(newObj, logicalWidthForChild(o) + marginStartForChild(o) + marginEndForChild(o));
315368513a70bcd92384395513322f1b801e7bf9c729Steve Block
31548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    newObj->m_shouldPaint = !o->hasSelfPaintingLayer(); // If a layer exists, the float will paint itself.  Otherwise someone else will.
31558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    newObj->m_isDescendant = true;
31568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    newObj->m_renderer = o;
31578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
315881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_floatingObjects->increaseObjectsCount(newObj->type());
315981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_floatingObjects->set().add(newObj);
316068513a70bcd92384395513322f1b801e7bf9c729Steve Block
316168513a70bcd92384395513322f1b801e7bf9c729Steve Block    return newObj;
31628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
31638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3164635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::removeFloatingObject(RenderBox* o)
31658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
31668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_floatingObjects) {
316781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
316881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSet::iterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(o);
316981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (it != floatingObjectSet.end()) {
317081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObject* r = *it;
317181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (childrenInline()) {
317281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                int logicalTop = logicalTopForFloat(r);
317381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                int logicalBottom = logicalBottomForFloat(r);
317481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
317581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                // Fix for https://bugs.webkit.org/show_bug.cgi?id=54995.
317681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (logicalBottom < 0 || logicalBottom < logicalTop || logicalTop == numeric_limits<int>::max())
317781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    logicalBottom = numeric_limits<int>::max();
317881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                else {
3179dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                    // Special-case zero- and less-than-zero-height floats: those don't touch
3180dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                    // the line that they're on, but it still needs to be dirtied. This is
3181dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                    // accomplished by pretending they have a height of 1.
318281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    logicalBottom = max(logicalBottom, logicalTop + 1);
3183dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                }
318481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                markLinesDirtyInBlockRange(0, logicalBottom);
31858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
318681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            m_floatingObjects->decreaseObjectsCount(r->type());
318781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            floatingObjectSet.remove(it);
318881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            delete r;
31898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
31908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
31918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
31928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31932fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid RenderBlock::removeFloatingObjectsBelow(FloatingObject* lastFloat, int logicalOffset)
319468513a70bcd92384395513322f1b801e7bf9c729Steve Block{
319568513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!m_floatingObjects)
319668513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
319768513a70bcd92384395513322f1b801e7bf9c729Steve Block
319881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
319981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObject* curr = floatingObjectSet.last();
32002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    while (curr != lastFloat && (!curr->isPlaced() || logicalTopForFloat(curr) >= logicalOffset)) {
320181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_floatingObjects->decreaseObjectsCount(curr->type());
320281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        floatingObjectSet.removeLast();
320381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        delete curr;
320481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        curr = floatingObjectSet.last();
320568513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
320668513a70bcd92384395513322f1b801e7bf9c729Steve Block}
320768513a70bcd92384395513322f1b801e7bf9c729Steve Block
32088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::positionNewFloats()
32098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
32108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_floatingObjects)
32118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
321281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
321381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
321481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (floatingObjectSet.isEmpty())
321581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return false;
32168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
32178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If all floats have already been positioned, then we have no work to do.
321881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (floatingObjectSet.last()->isPlaced())
32198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
32208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
32218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Move backwards through our floating object list until we find a float that has
32228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // already been positioned.  Then we'll be able to move forward, positioning all of
32238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the new floats that need it.
322481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator it = floatingObjectSet.end();
322581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    --it; // Go to last item.
322681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator begin = floatingObjectSet.begin();
322781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObject* lastPlacedFloatingObject = 0;
322881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    while (it != begin) {
322981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        --it;
323081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if ((*it)->isPlaced()) {
323181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            lastPlacedFloatingObject = *it;
323281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            ++it;
323381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            break;
323481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
32358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
32368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3237a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalTop = logicalHeight();
32388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3239a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // The float cannot start above the top position of the last positioned float.
324081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (lastPlacedFloatingObject)
324181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalTop = max(logicalTopForFloat(lastPlacedFloatingObject), logicalTop);
32428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
324381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator end = floatingObjectSet.end();
32448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Now walk through the set of unpositioned floats and place them.
324581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (; it != end; ++it) {
324681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch         FloatingObject* floatingObject = *it;
32478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // The containing block is responsible for positioning floats, so if we have floats in our
32488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // list that come from somewhere else, do not attempt to position them.
324981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (floatingObject->renderer()->containingBlock() != this)
32508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
32518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3252a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        RenderBox* childBox = floatingObject->renderer();
3253a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int childLogicalLeftMargin = style()->isLeftToRightDirection() ? marginStartForChild(childBox) : marginEndForChild(childBox);
32548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3255a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int rightOffset = logicalRightOffsetForContent(); // Constant part of right offset.
3256a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int leftOffset = logicalLeftOffsetForContent(); // Constant part of left offset.
3257a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int floatLogicalWidth = logicalWidthForFloat(floatingObject); // The width we look for.
3258a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (rightOffset - leftOffset < floatLogicalWidth)
3259a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            floatLogicalWidth = rightOffset - leftOffset; // Never look for more than what will be available.
32608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3261a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        IntRect oldRect(childBox->x(), childBox->y() , childBox->width(), childBox->height());
326268513a70bcd92384395513322f1b801e7bf9c729Steve Block
3263a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (childBox->style()->clear() & CLEFT)
3264a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            logicalTop = max(lowestFloatLogicalBottom(FloatingObject::FloatLeft), logicalTop);
3265a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (childBox->style()->clear() & CRIGHT)
3266a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            logicalTop = max(lowestFloatLogicalBottom(FloatingObject::FloatRight), logicalTop);
32678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3268a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int floatLogicalLeft;
3269a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (childBox->style()->floating() == FLEFT) {
32708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int heightRemainingLeft = 1;
32718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int heightRemainingRight = 1;
3272a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            floatLogicalLeft = logicalLeftOffsetForLine(logicalTop, leftOffset, false, &heightRemainingLeft);
3273a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            while (logicalRightOffsetForLine(logicalTop, rightOffset, false, &heightRemainingRight) - floatLogicalLeft < floatLogicalWidth) {
3274a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                logicalTop += min(heightRemainingLeft, heightRemainingRight);
3275a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                floatLogicalLeft = logicalLeftOffsetForLine(logicalTop, leftOffset, false, &heightRemainingLeft);
32768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
3277a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            floatLogicalLeft = max(0, floatLogicalLeft);
32788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
32798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int heightRemainingLeft = 1;
32808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int heightRemainingRight = 1;
3281a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            floatLogicalLeft = logicalRightOffsetForLine(logicalTop, rightOffset, false, &heightRemainingRight);
3282a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            while (floatLogicalLeft - logicalLeftOffsetForLine(logicalTop, leftOffset, false, &heightRemainingLeft) < floatLogicalWidth) {
3283a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                logicalTop += min(heightRemainingLeft, heightRemainingRight);
3284a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                floatLogicalLeft = logicalRightOffsetForLine(logicalTop, rightOffset, false, &heightRemainingRight);
32858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
3286a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            floatLogicalLeft -= logicalWidthForFloat(floatingObject); // Use the original width of the float here, since the local variable
3287a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                                                                      // |floatLogicalWidth| was capped to the available line width.
3288a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                                                                      // See fast/block/float/clamped-right-float.html.
32898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3290a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
3291a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalLeftForFloat(floatingObject, floatLogicalLeft);
3292a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalLeftForChild(childBox, floatLogicalLeft + childLogicalLeftMargin);
3293a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalTopForChild(childBox, logicalTop + marginBeforeForChild(childBox));
32948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
329568513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (view()->layoutState()->isPaginated()) {
3296a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            RenderBlock* childBlock = childBox->isRenderBlock() ? toRenderBlock(childBox) : 0;
32978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3298a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (!childBox->needsLayout())
3299a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                childBox->markForPaginationRelayoutIfNeeded();;
3300a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBox->layoutIfNeeded();
330168513a70bcd92384395513322f1b801e7bf9c729Steve Block
330268513a70bcd92384395513322f1b801e7bf9c729Steve Block            // If we are unsplittable and don't fit, then we need to move down.
330368513a70bcd92384395513322f1b801e7bf9c729Steve Block            // We include our margins as part of the unsplittable area.
3304a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            int newLogicalTop = adjustForUnsplittableChild(childBox, logicalTop, true);
330568513a70bcd92384395513322f1b801e7bf9c729Steve Block
330668513a70bcd92384395513322f1b801e7bf9c729Steve Block            // See if we have a pagination strut that is making us move down further.
330768513a70bcd92384395513322f1b801e7bf9c729Steve Block            // Note that an unsplittable child can't also have a pagination strut, so this is
330868513a70bcd92384395513322f1b801e7bf9c729Steve Block            // exclusive with the case above.
330968513a70bcd92384395513322f1b801e7bf9c729Steve Block            if (childBlock && childBlock->paginationStrut()) {
3310a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                newLogicalTop += childBlock->paginationStrut();
331168513a70bcd92384395513322f1b801e7bf9c729Steve Block                childBlock->setPaginationStrut(0);
331268513a70bcd92384395513322f1b801e7bf9c729Steve Block            }
331368513a70bcd92384395513322f1b801e7bf9c729Steve Block
3314a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (newLogicalTop != logicalTop) {
3315a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                floatingObject->m_paginationStrut = newLogicalTop - logicalTop;
3316a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                logicalTop = newLogicalTop;
3317a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                setLogicalTopForChild(childBox, logicalTop + marginBeforeForChild(childBox));
331868513a70bcd92384395513322f1b801e7bf9c729Steve Block                if (childBlock)
331968513a70bcd92384395513322f1b801e7bf9c729Steve Block                    childBlock->setChildNeedsLayout(true, false);
3320a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                childBox->layoutIfNeeded();
332168513a70bcd92384395513322f1b801e7bf9c729Steve Block            }
332268513a70bcd92384395513322f1b801e7bf9c729Steve Block        }
332368513a70bcd92384395513322f1b801e7bf9c729Steve Block
3324a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalTopForFloat(floatingObject, logicalTop);
3325a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalHeightForFloat(floatingObject, logicalHeightForChild(childBox) + marginBeforeForChild(childBox) + marginAfterForChild(childBox));
3326a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
3327a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        floatingObject->setIsPlaced();
3328a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
33298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // If the child moved, we have to repaint it.
3330a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (childBox->checkForRepaintDuringLayout())
3331a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBox->repaintDuringLayoutIfMoved(oldRect);
33328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
33338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
33348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
33358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
33368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::newLine(EClear clear)
33378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
33388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    positionNewFloats();
33398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // set y position
33408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int newY = 0;
33410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    switch (clear)
33428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
33438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CLEFT:
3344a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            newY = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
33458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
33468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CRIGHT:
3347a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            newY = lowestFloatLogicalBottom(FloatingObject::FloatRight);
33488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
33498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CBOTH:
3350a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            newY = lowestFloatLogicalBottom();
33518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        default:
33528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
33538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3354635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (height() < newY)
3355bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setLogicalHeight(newY);
33568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
33578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
33588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::addPercentHeightDescendant(RenderBox* descendant)
33598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
33608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!gPercentHeightDescendantsMap) {
33618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gPercentHeightDescendantsMap = new PercentHeightDescendantsMap;
33628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gPercentHeightContainerMap = new PercentHeightContainerMap;
33638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
33648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
33658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(this);
33668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!descendantSet) {
33678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        descendantSet = new HashSet<RenderBox*>;
33688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gPercentHeightDescendantsMap->set(this, descendantSet);
33698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
33708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool added = descendantSet->add(descendant).second;
33718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!added) {
33728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(gPercentHeightContainerMap->get(descendant));
33738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(gPercentHeightContainerMap->get(descendant)->contains(this));
33748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
33758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
33768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
33778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(descendant);
33788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!containerSet) {
33798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        containerSet = new HashSet<RenderBlock*>;
33808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gPercentHeightContainerMap->set(descendant, containerSet);
33818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
33828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!containerSet->contains(this));
33838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    containerSet->add(this);
33848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
33858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
33868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::removePercentHeightDescendant(RenderBox* descendant)
33878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
33888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!gPercentHeightContainerMap)
33898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
33908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
33918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->take(descendant);
33928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!containerSet)
33938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
33948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
33958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HashSet<RenderBlock*>::iterator end = containerSet->end();
33968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (HashSet<RenderBlock*>::iterator it = containerSet->begin(); it != end; ++it) {
33978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderBlock* container = *it;
33988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(container);
33998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(descendantSet);
34008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!descendantSet)
34018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
34028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(descendantSet->contains(descendant));
34038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        descendantSet->remove(descendant);
34048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (descendantSet->isEmpty()) {
34058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            gPercentHeightDescendantsMap->remove(container);
34068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            delete descendantSet;
34078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
34088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
34098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    delete containerSet;
34118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
34128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianHashSet<RenderBox*>* RenderBlock::percentHeightDescendants() const
34148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
34158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0;
34168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
34178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34182bde8e466a4451c7319e3a072d118917957d6554Steve Block// FIXME: The logicalLeftOffsetForLine/logicalRightOffsetForLine functions are very slow if there are many floats
34192bde8e466a4451c7319e3a072d118917957d6554Steve Block// present. We need to add a structure to floating objects to represent "lines" of floats.  Then instead of checking
34202bde8e466a4451c7319e3a072d118917957d6554Steve Block// each float individually, we'd just walk backwards through the "lines" and stop when we hit a line that is fully above
34212bde8e466a4451c7319e3a072d118917957d6554Steve Block// the vertical offset that we'd like to check.  Computing the "lines" would be rather complicated, but could replace the left
34222bde8e466a4451c7319e3a072d118917957d6554Steve Block// objects and right objects count hack that is currently used here.
3423a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::logicalLeftOffsetForLine(int logicalTop, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
34248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
34258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int left = fixedOffset;
342681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_floatingObjects && m_floatingObjects->hasLeftObjects()) {
3427a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (heightRemaining)
3428a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            *heightRemaining = 1;
342981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
34302bde8e466a4451c7319e3a072d118917957d6554Steve Block        // We know the list is non-empty, since we have "left" objects to search for.
34312bde8e466a4451c7319e3a072d118917957d6554Steve Block        // Therefore we can assume that begin != end, and that we can do at least one
34322bde8e466a4451c7319e3a072d118917957d6554Steve Block        // decrement.
343381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
34342bde8e466a4451c7319e3a072d118917957d6554Steve Block        FloatingObjectSetIterator begin = floatingObjectSet.begin();
34352bde8e466a4451c7319e3a072d118917957d6554Steve Block        FloatingObjectSetIterator it = floatingObjectSet.end();
34362bde8e466a4451c7319e3a072d118917957d6554Steve Block        do {
34372bde8e466a4451c7319e3a072d118917957d6554Steve Block            --it;
343881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObject* r = *it;
3439a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (r->isPlaced() && logicalTopForFloat(r) <= logicalTop && logicalBottomForFloat(r) > logicalTop
3440a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                && r->type() == FloatingObject::FloatLeft
3441a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                && logicalRightForFloat(r) > left) {
34422bde8e466a4451c7319e3a072d118917957d6554Steve Block                left = max(left, logicalRightForFloat(r));
3443a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                if (heightRemaining)
3444a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    *heightRemaining = logicalBottomForFloat(r) - logicalTop;
34458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
34462bde8e466a4451c7319e3a072d118917957d6554Steve Block        } while (it != begin);
34478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
34488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3449a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (applyTextIndent && style()->isLeftToRightDirection()) {
3450635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        int cw = 0;
34518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (style()->textIndent().isPercent())
3452bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            cw = containingBlock()->availableLogicalWidth();
34538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        left += style()->textIndent().calcMinValue(cw);
34548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
34558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return left;
34578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
34588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3459a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::logicalRightOffsetForLine(int logicalTop, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
34608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
34618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int right = fixedOffset;
34628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
346381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_floatingObjects && m_floatingObjects->hasRightObjects()) {
3464a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (heightRemaining)
3465a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            *heightRemaining = 1;
34662bde8e466a4451c7319e3a072d118917957d6554Steve Block
34672bde8e466a4451c7319e3a072d118917957d6554Steve Block        // We know the list is non-empty, since we have "right" objects to search for.
34682bde8e466a4451c7319e3a072d118917957d6554Steve Block        // Therefore we can assume that begin != end, and that we can do at least one
34692bde8e466a4451c7319e3a072d118917957d6554Steve Block        // decrement.
347081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
34712bde8e466a4451c7319e3a072d118917957d6554Steve Block        FloatingObjectSetIterator begin = floatingObjectSet.begin();
34722bde8e466a4451c7319e3a072d118917957d6554Steve Block        FloatingObjectSetIterator it = floatingObjectSet.end();
34732bde8e466a4451c7319e3a072d118917957d6554Steve Block        do {
34742bde8e466a4451c7319e3a072d118917957d6554Steve Block            --it;
347581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObject* r = *it;
3476a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (r->isPlaced() && logicalTopForFloat(r) <= logicalTop && logicalBottomForFloat(r) > logicalTop
3477a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                && r->type() == FloatingObject::FloatRight
3478a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                && logicalLeftForFloat(r) < right) {
34792bde8e466a4451c7319e3a072d118917957d6554Steve Block                right = min(right, logicalLeftForFloat(r));
3480a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                if (heightRemaining)
3481a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    *heightRemaining = logicalBottomForFloat(r) - logicalTop;
34828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
34832bde8e466a4451c7319e3a072d118917957d6554Steve Block        } while (it != begin);
34848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
34858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3486a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (applyTextIndent && !style()->isLeftToRightDirection()) {
3487635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        int cw = 0;
34888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (style()->textIndent().isPercent())
3489bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            cw = containingBlock()->availableLogicalWidth();
34908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        right -= style()->textIndent().calcMinValue(cw);
34918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
34928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return right;
34948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
34958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
349681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochint RenderBlock::availableLogicalWidthForLine(int position, bool firstLine) const
34978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3498bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int result = logicalRightOffsetForLine(position, firstLine) - logicalLeftOffsetForLine(position, firstLine);
34998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return (result < 0) ? 0 : result;
35008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
35018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3502a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::nextFloatLogicalBottomBelow(int logicalHeight) const
35038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
35048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_floatingObjects)
35058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
35068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
35078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int bottom = INT_MAX;
350881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
350981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator end = floatingObjectSet.end();
351081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
351181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObject* r = *it;
3512a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int floatBottom = logicalBottomForFloat(r);
3513a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (floatBottom > logicalHeight)
3514a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            bottom = min(floatBottom, bottom);
35158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
35168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
35178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return bottom == INT_MAX ? 0 : bottom;
35188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
35198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3520a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::lowestFloatLogicalBottom(FloatingObject::Type floatType) const
35218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3522a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!m_floatingObjects)
3523a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return 0;
3524a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int lowestFloatBottom = 0;
352581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
352681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator end = floatingObjectSet.end();
352781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
352881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObject* r = *it;
3529a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (r->isPlaced() && r->type() & floatType)
3530a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            lowestFloatBottom = max(lowestFloatBottom, logicalBottomForFloat(r));
3531a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
3532a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return lowestFloatBottom;
35338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
35348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3535a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::markLinesDirtyInBlockRange(int logicalTop, int logicalBottom, RootInlineBox* highest)
35368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3537a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (logicalTop >= logicalBottom)
35388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
35398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
35408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RootInlineBox* lowestDirtyLine = lastRootBox();
35418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RootInlineBox* afterLowest = lowestDirtyLine;
35422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    while (lowestDirtyLine && lowestDirtyLine->blockLogicalHeight() >= logicalBottom && logicalBottom < numeric_limits<int>::max()) {
35438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        afterLowest = lowestDirtyLine;
35448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        lowestDirtyLine = lowestDirtyLine->prevRootBox();
35458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
35468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
354781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    while (afterLowest && afterLowest != highest && (afterLowest->blockLogicalHeight() >= logicalTop || afterLowest->blockLogicalHeight() < 0)) {
35488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        afterLowest->markDirty();
35498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        afterLowest = afterLowest->prevRootBox();
35508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
35518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
35528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
35538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::clearFloats()
35548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
35558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Inline blocks are covered by the isReplaced() check in the avoidFloats method.
35568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (avoidsFloats() || isRoot() || isRenderView() || isFloatingOrPositioned() || isTableCell()) {
355781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (m_floatingObjects) {
355881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            deleteAllValues(m_floatingObjects->set());
35598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_floatingObjects->clear();
356081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
35618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
35628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
35638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
35648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    typedef HashMap<RenderObject*, FloatingObject*> RendererToFloatInfoMap;
35658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RendererToFloatInfoMap floatMap;
35668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
35678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_floatingObjects) {
356881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
35698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (childrenInline()) {
357081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObjectSet::iterator end = floatingObjectSet.end();
357181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            for (FloatingObjectSet::iterator it = floatingObjectSet.begin(); it != end; ++it) {
357281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                FloatingObject* f = *it;
35738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatMap.add(f->m_renderer, f);
357481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
35758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else
357681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            deleteAllValues(floatingObjectSet);
357781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_floatingObjects->clear();
35788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
35798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3580545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // We should not process floats if the parent node is not a RenderBlock. Otherwise, we will add
3581545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // floats in an invalid context. This will cause a crash arising from a bad cast on the parent.
3582545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // See <rdar://problem/8049753>, where float property is applied on a text node in a SVG.
3583545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (!parent() || !parent()->isRenderBlock())
3584545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return;
3585545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
35868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Attempt to locate a previous sibling with overhanging floats.  We skip any elements that are
35878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // out of flow (like floating/positioned elements), and we also skip over any objects that may have shifted
35888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // to avoid floats.
35898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool parentHasFloats = false;
3590a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RenderBlock* parentBlock = toRenderBlock(parent());
3591635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderObject* prev = previousSibling();
35928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    while (prev && (prev->isFloatingOrPositioned() || !prev->isBox() || !prev->isRenderBlock() || toRenderBlock(prev)->avoidsFloats())) {
35938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (prev->isFloating())
35948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            parentHasFloats = true;
35958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         prev = prev->previousSibling();
35968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
35978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
35988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // First add in floats from the parent.
3599a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalTopOffset = logicalTop();
3600a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (parentHasFloats)
3601a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        addIntrudingFloats(parentBlock, parentBlock->logicalLeftOffsetForContent(), logicalTopOffset);
3602635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
3603a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalLeftOffset = 0;
36048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (prev)
3605a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        logicalTopOffset -= toRenderBox(prev)->logicalTop();
3606a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    else {
3607a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        prev = parentBlock;
3608a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        logicalLeftOffset += parentBlock->logicalLeftOffsetForContent();
36098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
36108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
36118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Add overhanging floats from the previous RenderBlock, but only if it has a float that intrudes into our space.
3612635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!prev || !prev->isRenderBlock())
3613635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
3614635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
36158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBlock* block = toRenderBlock(prev);
3616a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (block->m_floatingObjects && block->lowestFloatLogicalBottom() > logicalTopOffset)
3617a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        addIntrudingFloats(block, logicalLeftOffset, logicalTopOffset);
36188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
36198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childrenInline()) {
3620a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int changeLogicalTop = numeric_limits<int>::max();
3621a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int changeLogicalBottom = numeric_limits<int>::min();
36228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_floatingObjects) {
362381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
362481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObjectSetIterator end = floatingObjectSet.end();
362581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
362681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                FloatingObject* f = *it;
36278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                FloatingObject* oldFloatingObject = floatMap.get(f->m_renderer);
3628a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                int logicalBottom = logicalBottomForFloat(f);
36298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (oldFloatingObject) {
3630a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    int oldLogicalBottom = logicalBottomForFloat(oldFloatingObject);
3631a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    if (logicalWidthForFloat(f) != logicalWidthForFloat(oldFloatingObject) || logicalLeftForFloat(f) != logicalLeftForFloat(oldFloatingObject)) {
3632a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                        changeLogicalTop = 0;
3633a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                        changeLogicalBottom = max(changeLogicalBottom, max(logicalBottom, oldLogicalBottom));
3634a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    } else if (logicalBottom != oldLogicalBottom) {
3635a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                        changeLogicalTop = min(changeLogicalTop, min(logicalBottom, oldLogicalBottom));
3636a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                        changeLogicalBottom = max(changeLogicalBottom, max(logicalBottom, oldLogicalBottom));
36378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
36388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
36398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    floatMap.remove(f->m_renderer);
36408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    delete oldFloatingObject;
36418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else {
3642a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    changeLogicalTop = 0;
3643a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    changeLogicalBottom = max(changeLogicalBottom, logicalBottom);
36448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
36458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
36468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
36478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
36488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RendererToFloatInfoMap::iterator end = floatMap.end();
36498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (RendererToFloatInfoMap::iterator it = floatMap.begin(); it != end; ++it) {
36508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            FloatingObject* floatingObject = (*it).second;
36518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!floatingObject->m_isDescendant) {
3652a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                changeLogicalTop = 0;
3653a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                changeLogicalBottom = max(changeLogicalBottom, logicalBottomForFloat(floatingObject));
36548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
36558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
36568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        deleteAllValues(floatMap);
36578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3658a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        markLinesDirtyInBlockRange(changeLogicalTop, changeLogicalBottom);
36598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
36608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
36618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3662a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::addOverhangingFloats(RenderBlock* child, int logicalLeftOffset, int logicalTopOffset, bool makeChildPaintOtherFloats)
36638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
36648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Prevent floats from being added to the canvas by the root element, e.g., <html>.
3665a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (child->hasOverflowClip() || !child->containsFloats() || child->isRoot() || child->hasColumns() || child->isWritingModeRoot())
36668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
36678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
36682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    int childLogicalTop = child->logicalTop();
3669a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int lowestFloatLogicalBottom = 0;
36708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3671231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Floats that will remain the child's responsibility to paint should factor into its
3672231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // overflow.
367381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator childEnd = child->m_floatingObjects->set().end();
367481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (FloatingObjectSetIterator childIt = child->m_floatingObjects->set().begin(); childIt != childEnd; ++childIt) {
367581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObject* r = *childIt;
36762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        int logicalBottomForFloat = min(this->logicalBottomForFloat(r), numeric_limits<int>::max() - childLogicalTop);
36772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        int logicalBottom = childLogicalTop + logicalBottomForFloat;
3678a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        lowestFloatLogicalBottom = max(lowestFloatLogicalBottom, logicalBottom);
36798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3680a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (logicalBottom > logicalHeight()) {
36818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // If the object is not in the list, we add it now.
36828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!containsFloat(r->m_renderer)) {
36832bde8e466a4451c7319e3a072d118917957d6554Steve Block                int leftOffset = isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset;
36842bde8e466a4451c7319e3a072d118917957d6554Steve Block                int topOffset = isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset;
36852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->x() - leftOffset, r->y() - topOffset, r->width(), r->height()));
36868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatingObj->m_renderer = r->m_renderer;
36878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
36888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // The nearest enclosing layer always paints the float (so that zindex and stacking
36898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // behaves properly).  We always want to propagate the desire to paint the float as
36908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // far out as we can, to the outermost block that overlaps the float, stopping only
36918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                // if we hit a self-painting layer boundary.
3692f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                if (r->m_renderer->enclosingFloatPaintingLayer() == enclosingFloatPaintingLayer())
36938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    r->m_shouldPaint = false;
36948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                else
36958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    floatingObj->m_shouldPaint = false;
36968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3697f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                floatingObj->m_isDescendant = true;
3698f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
36998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // We create the floating object list lazily.
370081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (!m_floatingObjects)
370181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    m_floatingObjects = adoptPtr(new FloatingObjects);
370281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
370381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                m_floatingObjects->increaseObjectsCount(floatingObj->type());
370481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                m_floatingObjects->set().add(floatingObj);
37058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
3706f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        } else {
3707f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            if (makeChildPaintOtherFloats && !r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer() &&
3708f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                r->m_renderer->isDescendantOf(child) && r->m_renderer->enclosingFloatPaintingLayer() == child->enclosingFloatPaintingLayer()) {
3709f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                // The float is not overhanging from this block, so if it is a descendant of the child, the child should
3710f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                // paint it (the other case is that it is intruding into the child), unless it has its own layer or enclosing
3711f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                // layer.
3712f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                // If makeChildPaintOtherFloats is false, it means that the child must already know about all the floats
3713f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                // it should paint.
3714f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                r->m_shouldPaint = true;
3715f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            }
3716f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
3717f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // Since the float doesn't overhang, it didn't get put into our list.  We need to go ahead and add its overflow in to the
3718f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // child now.
3719f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            if (r->m_isDescendant)
37202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                child->addOverflowFromChild(r->m_renderer, IntSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r)));
3721f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        }
37228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3723a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return lowestFloatLogicalBottom;
37248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
37258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3726a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::addIntrudingFloats(RenderBlock* prev, int logicalLeftOffset, int logicalTopOffset)
37278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
37288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the parent or previous sibling doesn't have any floats to add, don't bother.
37298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!prev->m_floatingObjects)
37308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
37318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
37322bde8e466a4451c7319e3a072d118917957d6554Steve Block    logicalLeftOffset += (isHorizontalWritingMode() ? marginLeft() : marginTop());
373381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
373481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& prevSet = prev->m_floatingObjects->set();
373581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator prevEnd = prevSet.end();
373681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (FloatingObjectSetIterator prevIt = prevSet.begin(); prevIt != prevEnd; ++prevIt) {
373781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObject* r = *prevIt;
3738a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (logicalBottomForFloat(r) > logicalTopOffset) {
373981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (!m_floatingObjects || !m_floatingObjects->set().contains(r)) {
37402bde8e466a4451c7319e3a072d118917957d6554Steve Block                int leftOffset = isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset;
37412bde8e466a4451c7319e3a072d118917957d6554Steve Block                int topOffset = isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset;
3742a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
37432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->x() - leftOffset, r->y() - topOffset, r->width(), r->height()));
3744a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
37458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Applying the child's margin makes no sense in the case where the child was passed in.
3746a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                // since this margin was added already through the modification of the |logicalLeftOffset| variable
3747a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                // above.  |logicalLeftOffset| will equal the margin in this case, so it's already been taken
3748a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                // into account.  Only apply this code if prev is the parent, since otherwise the left margin
37498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // will get applied twice.
37506b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                if (prev != parent()) {
37512bde8e466a4451c7319e3a072d118917957d6554Steve Block                    if (isHorizontalWritingMode())
37522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                        floatingObj->setX(floatingObj->x() + prev->marginLeft());
37536b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                    else
37542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                        floatingObj->setY(floatingObj->y() + prev->marginTop());
37556b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                }
3756a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
37578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatingObj->m_shouldPaint = false;  // We are not in the direct inheritance chain for this float. We will never paint it.
37588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatingObj->m_renderer = r->m_renderer;
37598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
37608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // We create the floating object list lazily.
376181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (!m_floatingObjects)
376281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    m_floatingObjects = adoptPtr(new FloatingObjects);
376381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                m_floatingObjects->increaseObjectsCount(floatingObj->type());
376481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                m_floatingObjects->set().add(floatingObj);
37658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
37668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
37678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
37688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
37698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
37708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::avoidsFloats() const
37718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
37728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Floats can't intrude into our box if we have a non-auto column count or width.
37738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return RenderBox::avoidsFloats() || !style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth();
37748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
37758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
377681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochbool RenderBlock::containsFloat(RenderBox* renderer)
37778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
377881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return m_floatingObjects && m_floatingObjects->set().contains<RenderBox*, FloatingObjectHashTranslator>(renderer);
37798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
37808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3781635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove, bool inLayout)
37828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
378368513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!m_everHadLayout)
378468513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
378568513a70bcd92384395513322f1b801e7bf9c729Steve Block
3786635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    setChildNeedsLayout(true, !inLayout);
37878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
37888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (floatToRemove)
37898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        removeFloatingObject(floatToRemove);
37908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
37918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Iterate over our children and mark them as needed.
37928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!childrenInline()) {
37938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
37948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if ((!floatToRemove && child->isFloatingOrPositioned()) || !child->isRenderBlock())
37958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                continue;
37968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            RenderBlock* childBlock = toRenderBlock(child);
37978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if ((floatToRemove ? childBlock->containsFloat(floatToRemove) : childBlock->containsFloats()) || childBlock->shrinkToAvoidFloats())
37988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                childBlock->markAllDescendantsWithFloatsForLayout(floatToRemove, inLayout);
37998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
38008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
38018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
38028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
38038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianint RenderBlock::getClearDelta(RenderBox* child, int yPos)
38048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
38058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // There is no need to compute clearance if we have no floats.
38068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!containsFloats())
38078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
38088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
38098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // At least one float is present.  We need to perform the clearance computation.
38108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool clearSet = child->style()->clear() != CNONE;
38118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int bottom = 0;
38128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch (child->style()->clear()) {
38138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CNONE:
38148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
38158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CLEFT:
3816a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            bottom = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
38178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
38188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CRIGHT:
3819a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            bottom = lowestFloatLogicalBottom(FloatingObject::FloatRight);
38208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
38218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CBOTH:
3822a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            bottom = lowestFloatLogicalBottom();
38238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
38248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
38258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
38268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We also clear floats if we are too big to sit on the same line as a float (and wish to avoid floats by default).
38278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int result = clearSet ? max(0, bottom - yPos) : 0;
3828231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!result && child->avoidsFloats()) {
3829d0825bca7fe65beaee391d30da42e937db621564Steve Block        int y = yPos;
3830d0825bca7fe65beaee391d30da42e937db621564Steve Block        while (true) {
3831bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            int widthAtY = availableLogicalWidthForLine(y, false);
3832e14391e94c850b8bd03680c23b38978db68687a8John Reck            if (widthAtY == availableLogicalWidth())
3833d0825bca7fe65beaee391d30da42e937db621564Steve Block                return y - yPos;
3834d0825bca7fe65beaee391d30da42e937db621564Steve Block
3835d0825bca7fe65beaee391d30da42e937db621564Steve Block            int oldChildY = child->y();
3836d0825bca7fe65beaee391d30da42e937db621564Steve Block            int oldChildWidth = child->width();
3837d0825bca7fe65beaee391d30da42e937db621564Steve Block            child->setY(y);
3838bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            child->computeLogicalWidth();
3839d0825bca7fe65beaee391d30da42e937db621564Steve Block            int childWidthAtY = child->width();
3840d0825bca7fe65beaee391d30da42e937db621564Steve Block            child->setY(oldChildY);
3841d0825bca7fe65beaee391d30da42e937db621564Steve Block            child->setWidth(oldChildWidth);
3842d0825bca7fe65beaee391d30da42e937db621564Steve Block
3843d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (childWidthAtY <= widthAtY)
3844d0825bca7fe65beaee391d30da42e937db621564Steve Block                return y - yPos;
3845d0825bca7fe65beaee391d30da42e937db621564Steve Block
3846a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            y = nextFloatLogicalBottomBelow(y);
3847d0825bca7fe65beaee391d30da42e937db621564Steve Block            ASSERT(y >= yPos);
3848d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (y < yPos)
3849d0825bca7fe65beaee391d30da42e937db621564Steve Block                break;
3850d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
3851d0825bca7fe65beaee391d30da42e937db621564Steve Block        ASSERT_NOT_REACHED();
3852231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
38538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
38548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
38558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
38560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool RenderBlock::isPointInOverflowControl(HitTestResult& result, int _x, int _y, int _tx, int _ty)
38578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
38588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!scrollsOverflow())
38598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
38608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
38610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return layer()->hitTestOverflowControls(result, IntPoint(_x - _tx, _y - _ty));
38628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
38638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
38648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction)
38658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3866635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int tx = _tx + x();
3867635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int ty = _ty + y();
38688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3869635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!isRenderView()) {
38708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Check if we need to do anything at all.
3871f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        IntRect overflowBox = visualOverflowRect();
38728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        overflowBox.move(tx, ty);
3873a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!overflowBox.intersects(result.rectForPoint(_x, _y)))
38748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
38758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
38768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
38778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) && isPointInOverflowControl(result, _x, _y, tx, ty)) {
38788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
3879ad3386af2204fbbc9033a6dcced2f9b0adcd6f10Steve Block        // FIXME: isPointInOverflowControl() doesn't handle rect-based tests yet.
3880db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block        if (!result.addNodeToRectBasedTestResult(node(), _x, _y))
3881db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block           return true;
38828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
38838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
38848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If we have clipping, then we can't have any spillout.
38858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer();
38868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool useClip = (hasControlClip() || useOverflowClip);
3887a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    IntRect hitTestArea(result.rectForPoint(_x, _y));
38882bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool checkChildren = !useClip || (hasControlClip() ? controlClipRect(tx, ty).intersects(hitTestArea) : overflowClipRect(tx, ty, IncludeOverlayScrollbarSize).intersects(hitTestArea));
38898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (checkChildren) {
38908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Hit test descendants first.
38918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int scrolledX = tx;
38928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int scrolledY = ty;
3893dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (hasOverflowClip()) {
3894dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            IntSize offset = layer()->scrolledContentOffset();
3895dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            scrolledX -= offset.width();
3896dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            scrolledY -= offset.height();
3897dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
38988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
38998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Hit test contents if we don't have columns.
39005abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        if (!hasColumns()) {
39015abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            if (hitTestContents(request, result, _x, _y, scrolledX, scrolledY, hitTestAction)) {
39025abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick                updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
39035abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick                return true;
39045abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            }
39055abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            if (hitTestAction == HitTestFloat && hitTestFloats(request, result, _x, _y, scrolledX, scrolledY))
39065abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick                return true;
39075abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        } else if (hitTestColumns(request, result, _x, _y, scrolledX, scrolledY, hitTestAction)) {
39086c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
39098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
39106c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        }
39118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
39128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3913635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Now hit test our background
3914635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) {
3915635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        IntRect boundsRect(tx, ty, width(), height());
3916a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (visibleToHitTesting() && boundsRect.intersects(result.rectForPoint(_x, _y))) {
39176b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            updateHitTestResult(result, flipForWritingMode(IntPoint(_x - tx, _y - ty)));
3918db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block            if (!result.addNodeToRectBasedTestResult(node(), _x, _y, boundsRect))
3919db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block                return true;
39208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
39218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
39228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
39238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
39248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
39258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
39265abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickbool RenderBlock::hitTestFloats(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty)
39275abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{
39285abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    if (!m_floatingObjects)
39295abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        return false;
39305abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
39315abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    if (isRenderView()) {
39325abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        tx += toRenderView(this)->frameView()->scrollX();
39335abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        ty += toRenderView(this)->frameView()->scrollY();
39345abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    }
39355abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
393681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
393781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator begin = floatingObjectSet.begin();
393881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (FloatingObjectSetIterator it = floatingObjectSet.end(); it != begin;) {
393981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        --it;
394081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObject* floatingObject = *it;
39415abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        if (floatingObject->m_shouldPaint && !floatingObject->m_renderer->hasSelfPaintingLayer()) {
39422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int xOffset = xPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->x();
39432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int yOffset = yPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->y();
39442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            IntPoint childPoint = flipFloatForWritingMode(floatingObject, IntPoint(tx + xOffset, ty + yOffset));
394528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            if (floatingObject->m_renderer->hitTest(request, result, IntPoint(x, y), childPoint.x(), childPoint.y())) {
394628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                updateHitTestResult(result, IntPoint(x - childPoint.x(), y - childPoint.y()));
39475abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick                return true;
39485abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            }
39495abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        }
39505abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    }
39515abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
39525abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    return false;
39535abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick}
39545abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
39558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
39568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
39578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We need to do multiple passes, breaking up our hit testing into strips.
39585abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    ColumnInfo* colInfo = columnInfo();
395968513a70bcd92384395513322f1b801e7bf9c729Steve Block    int colCount = columnCount(colInfo);
39606c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (!colCount)
39616c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        return false;
39622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int logicalLeft = logicalLeftOffsetForContent();
39632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int currLogicalTopOffset = 0;
3964e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    int i;
39652bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool isHorizontal = isHorizontalWritingMode();
39662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    for (i = 0; i < colCount; i++) {
39672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        IntRect colRect = columnRectAt(colInfo, i);
39682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int blockDelta =  (isHorizontal ? colRect.height() : colRect.width());
39692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (style()->isFlippedBlocksWritingMode())
39702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalTopOffset += blockDelta;
39712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        else
39722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalTopOffset -= blockDelta;
39732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
3974e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    for (i = colCount - 1; i >= 0; i--) {
397568513a70bcd92384395513322f1b801e7bf9c729Steve Block        IntRect colRect = columnRectAt(colInfo, i);
39762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        flipForWritingMode(colRect);
39772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft;
39782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int blockDelta =  (isHorizontal ? colRect.height() : colRect.width());
39792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (style()->isFlippedBlocksWritingMode())
39802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalTopOffset -= blockDelta;
39812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        else
39822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalTopOffset += blockDelta;
39838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        colRect.move(tx, ty);
39848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3985a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (colRect.intersects(result.rectForPoint(x, y))) {
39868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // The point is inside this column.
39878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Adjust tx and ty to change where we hit test.
39888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
39892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            IntSize offset = isHorizontal ? IntSize(currLogicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, currLogicalLeftOffset);
39902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int finalX = tx + offset.width();
39912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int finalY = ty + offset.height();
3992a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (result.isRectBasedTest() && !colRect.contains(result.rectForPoint(x, y)))
3993db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block                hitTestContents(request, result, x, y, finalX, finalY, hitTestAction);
3994db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block            else
39955abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick                return hitTestContents(request, result, x, y, finalX, finalY, hitTestAction) || (hitTestAction == HitTestFloat && hitTestFloats(request, result, x, y, finalX, finalY));
39968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
39978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
39988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
39998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
40008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
40018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::hitTestContents(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
40038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
40048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childrenInline() && !isTable()) {
40058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We have to hit-test our line boxes.
40066c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (m_lineBoxes.hitTest(this, request, result, x, y, tx, ty, hitTestAction))
40078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
40088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
40098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Hit test our children.
40108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HitTestAction childHitTest = hitTestAction;
40118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (hitTestAction == HitTestChildBlockBackgrounds)
40128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            childHitTest = HitTestChildBlockBackground;
40138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        for (RenderBox* child = lastChildBox(); child; child = child->previousSiblingBox()) {
401428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            IntPoint childPoint = flipForWritingMode(child, IntPoint(tx, ty), ParentToChildFlippingAdjustment);
401528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            if (!child->hasSelfPaintingLayer() && !child->isFloating() && child->nodeAtPoint(request, result, x, y, childPoint.x(), childPoint.y(), childHitTest))
40168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
40178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
40188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
40198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
40218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
40228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPosition RenderBlock::positionForBox(InlineBox *box, bool start) const
40248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
40258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!box)
40268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return Position();
40278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!box->renderer()->node())
40298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return Position(node(), start ? caretMinOffset() : caretMaxOffset());
40308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!box->isInlineTextBox())
40328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return Position(box->renderer()->node(), start ? box->renderer()->caretMinOffset() : box->renderer()->caretMaxOffset());
40338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    InlineTextBox *textBox = static_cast<InlineTextBox *>(box);
40358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return Position(box->renderer()->node(), start ? textBox->start() : textBox->start() + textBox->len());
40368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
40378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// FIXME: This function should go on RenderObject as an instance method. Then
40395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian// all cases in which positionForPoint recurs could call this instead to
40408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// prevent crossing editable boundaries. This would require many tests.
40416b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerstatic VisiblePosition positionForPointRespectingEditingBoundaries(RenderBlock* parent, RenderBox* child, const IntPoint& pointInParentCoordinates)
40428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
40436b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // FIXME: This is wrong if the child's writing-mode is different from the parent's.
40445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    IntPoint pointInChildCoordinates(pointInParentCoordinates - child->location());
40458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If this is an anonymous renderer, we just recur normally
40478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Node* childNode = child->node();
40488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!childNode)
40495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return child->positionForPoint(pointInChildCoordinates);
40508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Otherwise, first make sure that the editability of the parent and child agree.
40528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If they don't agree, then we return a visible position just before or after the child
40538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* ancestor = parent;
40548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    while (ancestor && !ancestor->node())
40558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ancestor = ancestor->parent();
40568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If we can't find an ancestor to check editability on, or editability is unchanged, we recur like normal
40582bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!ancestor || ancestor->node()->rendererIsEditable() == childNode->rendererIsEditable())
40595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return child->positionForPoint(pointInChildCoordinates);
40608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40616b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // Otherwise return before or after the child, depending on if the click was to the logical left or logical right of the child
40626b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    int childMiddle = parent->logicalWidthForChild(child) / 2;
40632bde8e466a4451c7319e3a072d118917957d6554Steve Block    int logicalLeft = parent->isHorizontalWritingMode() ? pointInChildCoordinates.x() : pointInChildCoordinates.y();
40646b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (logicalLeft < childMiddle)
40658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return ancestor->createVisiblePosition(childNode->nodeIndex(), DOWNSTREAM);
40668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return ancestor->createVisiblePosition(childNode->nodeIndex() + 1, UPSTREAM);
40678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
40688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40696b70adc33054f8aee8c54d0f460458a9df11b8a5Russell BrennerVisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint& pointInLogicalContents)
40708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
40715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(childrenInline());
40728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (!firstRootBox())
40745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return createVisiblePosition(0, DOWNSTREAM);
40758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
40768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // look for the closest line box in the root box which is at the passed-in y coordinate
40775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    InlineBox* closestBox = 0;
40785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RootInlineBox* firstRootBoxWithChildren = 0;
40795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RootInlineBox* lastRootBoxWithChildren = 0;
40805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
4081643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (!root->firstLeafChild())
40825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            continue;
40835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (!firstRootBoxWithChildren)
40845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            firstRootBoxWithChildren = root;
40855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        lastRootBoxWithChildren = root;
40865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
40878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // check if this root line box is located at this y coordinate
40886b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (pointInLogicalContents.y() < root->selectionBottom()) {
40896b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            closestBox = root->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
40908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (closestBox)
40918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                break;
40928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
40938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
40948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4095545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    bool moveCaretToBoundary = document()->frame()->editor()->behavior().shouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom();
40965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
4097545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (!moveCaretToBoundary && !closestBox && lastRootBoxWithChildren) {
40985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // y coordinate is below last root line box, pretend we hit it
40996b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        closestBox = lastRootBoxWithChildren->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
41005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
41018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (closestBox) {
41036b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (moveCaretToBoundary && pointInLogicalContents.y() < firstRootBoxWithChildren->selectionTop()) {
41045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            // y coordinate is above first root line box, so return the start of the first
41055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            return VisiblePosition(positionForBox(firstRootBoxWithChildren->firstLeafChild(), true), DOWNSTREAM);
41065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
41075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
41086b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        // pass the box a top position that is inside it
41096b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        IntPoint point(pointInLogicalContents.x(), closestBox->logicalTop());
41102bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!isHorizontalWritingMode())
41116b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            point = point.transposedPoint();
41126b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (closestBox->renderer()->isReplaced())
41136b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            return positionForPointRespectingEditingBoundaries(this, toRenderBox(closestBox->renderer()), point);
41146b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        return closestBox->renderer()->positionForPoint(point);
41155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
41165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
41175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (lastRootBoxWithChildren) {
41185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // We hit this case for Mac behavior when the Y coordinate is below the last box.
4119545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        ASSERT(moveCaretToBoundary);
41202bde8e466a4451c7319e3a072d118917957d6554Steve Block        InlineBox* logicallyLastBox;
41212bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (lastRootBoxWithChildren->getLogicalEndBoxWithNode(logicallyLastBox))
41222bde8e466a4451c7319e3a072d118917957d6554Steve Block            return VisiblePosition(positionForBox(logicallyLastBox, false), DOWNSTREAM);
41238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
41248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
41255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Can't reach this. We have a root line box, but it has no kids.
41268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // FIXME: This should ASSERT_NOT_REACHED(), but clicking on placeholder text
41275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // seems to hit this code path.
41285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return createVisiblePosition(0, DOWNSTREAM);
41295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
41305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
41315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianstatic inline bool isChildHitTestCandidate(RenderBox* box)
41325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
41335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return box->height() && box->style()->visibility() == VISIBLE && !box->isFloatingOrPositioned();
41348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
41358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
41368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianVisiblePosition RenderBlock::positionForPoint(const IntPoint& point)
41378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
41388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (isTable())
41398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return RenderBox::positionForPoint(point);
41408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
41418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (isReplaced()) {
41426b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        // FIXME: This seems wrong when the object's writing-mode doesn't match the line's writing-mode.
41432bde8e466a4451c7319e3a072d118917957d6554Steve Block        int pointLogicalLeft = isHorizontalWritingMode() ? point.x() : point.y();
41442bde8e466a4451c7319e3a072d118917957d6554Steve Block        int pointLogicalTop = isHorizontalWritingMode() ? point.y() : point.x();
41456b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
41466b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (pointLogicalTop < 0 || (pointLogicalTop < logicalHeight() && pointLogicalLeft < 0))
41478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return createVisiblePosition(caretMinOffset(), DOWNSTREAM);
41486b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (pointLogicalTop >= logicalHeight() || (pointLogicalTop >= 0 && pointLogicalLeft >= logicalWidth()))
41498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return createVisiblePosition(caretMaxOffset(), DOWNSTREAM);
41508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
41518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    int contentsX = point.x();
41535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    int contentsY = point.y();
41545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    offsetForContents(contentsX, contentsY);
41555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    IntPoint pointInContents(contentsX, contentsY);
41566b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    IntPoint pointInLogicalContents(pointInContents);
41572bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!isHorizontalWritingMode())
41586b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        pointInLogicalContents = pointInLogicalContents.transposedPoint();
41598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
41605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (childrenInline())
41616b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        return positionForPointWithInlineChildren(pointInLogicalContents);
41628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
41636b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (lastChildBox() && pointInContents.y() > lastChildBox()->logicalTop()) {
41645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        for (RenderBox* childBox = lastChildBox(); childBox; childBox = childBox->previousSiblingBox()) {
41655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            if (isChildHitTestCandidate(childBox))
41665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents);
41675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
41685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    } else {
41695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
41705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            // We hit child if our click is above the bottom of its padding box (like IE6/7 and FF3).
41716b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            if (isChildHitTestCandidate(childBox) && pointInContents.y() < childBox->logicalBottom())
41725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents);
41735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
41748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
41758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
41765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // We only get here if there are no hit test candidate children below the click.
41778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return RenderBox::positionForPoint(point);
41788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
41798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4180635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::offsetForContents(int& tx, int& ty) const
4181635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
4182dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    IntPoint contentsPoint(tx, ty);
4183dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
4184635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (hasOverflowClip())
4185dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        contentsPoint += layer()->scrolledContentOffset();
4186635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
4187dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (hasColumns())
4188635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        adjustPointToColumnContents(contentsPoint);
4189dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
4190dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    tx = contentsPoint.x();
4191dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ty = contentsPoint.y();
4192635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
4193635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
419468513a70bcd92384395513322f1b801e7bf9c729Steve Blockint RenderBlock::availableLogicalWidth() const
419568513a70bcd92384395513322f1b801e7bf9c729Steve Block{
419668513a70bcd92384395513322f1b801e7bf9c729Steve Block    // If we have multiple columns, then the available logical width is reduced to our column width.
419768513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (hasColumns())
419868513a70bcd92384395513322f1b801e7bf9c729Steve Block        return desiredColumnWidth();
419968513a70bcd92384395513322f1b801e7bf9c729Steve Block    return RenderBox::availableLogicalWidth();
42008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
42018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
42028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderBlock::columnGap() const
42038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
42048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->hasNormalColumnGap())
42058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return style()->fontDescription().computedPixelSize(); // "1em" is recommended as the normal gap setting. Matches <p> margins.
42068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return static_cast<int>(style()->columnGap());
42078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
42088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
42098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::calcColumnWidth()
42108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
42118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Calculate our column width and column count.
42128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned desiredColumnCount = 1;
42132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int desiredColumnWidth = contentLogicalWidth();
42148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
42158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // For now, we don't support multi-column layouts when printing, since we have to do a lot of work for proper pagination.
4216f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    if (document()->paginated() || (style()->hasAutoColumnCount() && style()->hasAutoColumnWidth())) {
42178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
42188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
42198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
42208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
42218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int availWidth = desiredColumnWidth;
42228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int colGap = columnGap();
42238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int colWidth = max(1, static_cast<int>(style()->columnWidth()));
42248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int colCount = max(1, static_cast<int>(style()->columnCount()));
42258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
42262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (style()->hasAutoColumnWidth() && !style()->hasAutoColumnCount()) {
42272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        desiredColumnCount = colCount;
42282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        desiredColumnWidth = max<int>(0, (availWidth - ((desiredColumnCount - 1) * colGap)) / desiredColumnCount);
42292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    } else if (!style()->hasAutoColumnWidth() && style()->hasAutoColumnCount()) {
42302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        desiredColumnCount = max<int>(1, (float)(availWidth + colGap) / (colWidth + colGap));
42312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap;
42328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
42332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        desiredColumnCount = max(min<int>(colCount, (float)(availWidth + colGap) / (colWidth + colGap)), 1);
42342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap;
42358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
42368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
42378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
42388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
42398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::setDesiredColumnCountAndWidth(int count, int width)
42408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
42415af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    bool destroyColumns = !firstChild()
42425af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                          || (count == 1 && style()->hasAutoColumnWidth())
42435af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                          || firstChild()->isAnonymousColumnsBlock()
424468513a70bcd92384395513322f1b801e7bf9c729Steve Block                          || firstChild()->isAnonymousColumnSpanBlock();
42455af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (destroyColumns) {
42468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (hasColumns()) {
42478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            delete gColumnInfoMap->take(this);
42488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            setHasColumns(false);
42498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
42508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
42518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ColumnInfo* info;
42528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (hasColumns())
42538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            info = gColumnInfoMap->get(this);
42548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
42558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!gColumnInfoMap)
42568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                gColumnInfoMap = new ColumnInfoMap;
42578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            info = new ColumnInfo;
42588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            gColumnInfoMap->add(this, info);
42598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            setHasColumns(true);
42608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
42615abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        info->setDesiredColumnCount(count);
42625abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        info->setDesiredColumnWidth(width);
42638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
42648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
42658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
42668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderBlock::desiredColumnWidth() const
42678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
42688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!hasColumns())
42692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return contentLogicalWidth();
42705abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    return gColumnInfoMap->get(this)->desiredColumnWidth();
42718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
42728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
42738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectunsigned RenderBlock::desiredColumnCount() const
42748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
42758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!hasColumns())
42768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 1;
42775abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    return gColumnInfoMap->get(this)->desiredColumnCount();
42788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
42798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
42805abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain MerrickColumnInfo* RenderBlock::columnInfo() const
42818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
42828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!hasColumns())
42838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
42845abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    return gColumnInfoMap->get(this);
42858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
42868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
428768513a70bcd92384395513322f1b801e7bf9c729Steve Blockunsigned RenderBlock::columnCount(ColumnInfo* colInfo) const
42888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
428968513a70bcd92384395513322f1b801e7bf9c729Steve Block    ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo);
429068513a70bcd92384395513322f1b801e7bf9c729Steve Block    return colInfo->columnCount();
429168513a70bcd92384395513322f1b801e7bf9c729Steve Block}
42928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
429368513a70bcd92384395513322f1b801e7bf9c729Steve BlockIntRect RenderBlock::columnRectAt(ColumnInfo* colInfo, unsigned index) const
429468513a70bcd92384395513322f1b801e7bf9c729Steve Block{
429568513a70bcd92384395513322f1b801e7bf9c729Steve Block    ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo);
42968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
429768513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Compute the appropriate rect based off our information.
42982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int colLogicalWidth = colInfo->desiredColumnWidth();
42992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int colLogicalHeight = colInfo->columnHeight();
43002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int colLogicalTop = borderBefore() + paddingBefore();
43018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int colGap = columnGap();
43022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int colLogicalLeft = style()->isLeftToRightDirection() ?
43032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                          logicalLeftOffsetForContent() + (index * (colLogicalWidth + colGap))
43042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                        : logicalLeftOffsetForContent() + contentLogicalWidth() - colLogicalWidth - (index * (colLogicalWidth + colGap));
43052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    IntRect rect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
43062bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
43072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return IntRect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
43082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return IntRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogicalWidth);
430968513a70bcd92384395513322f1b801e7bf9c729Steve Block}
43108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4311f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochbool RenderBlock::layoutColumns(bool hasSpecifiedPageLogicalHeight, int pageLogicalHeight, LayoutStateMaintainer& statePusher)
431268513a70bcd92384395513322f1b801e7bf9c729Steve Block{
4313f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!hasColumns())
4314f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return false;
4315f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
4316f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // FIXME: We don't balance properly at all in the presence of forced page breaks.  We need to understand what
4317f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // the distance between forced page breaks is so that we can avoid making the minimum column height too tall.
4318f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    ColumnInfo* colInfo = columnInfo();
4319f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int desiredColumnCount = colInfo->desiredColumnCount();
4320f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!hasSpecifiedPageLogicalHeight) {
4321f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        int columnHeight = pageLogicalHeight;
4322f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        int minColumnCount = colInfo->forcedBreaks() + 1;
4323f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (minColumnCount >= desiredColumnCount) {
4324f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // The forced page breaks are in control of the balancing.  Just set the column height to the
4325f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // maximum page break distance.
4326f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            if (!pageLogicalHeight) {
4327f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                int distanceBetweenBreaks = max(colInfo->maximumDistanceBetweenForcedBreaks(),
43282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                                                view()->layoutState()->pageLogicalOffset(borderBefore() + paddingBefore() + contentLogicalHeight()) - colInfo->forcedBreakOffset());
4329f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                columnHeight = max(colInfo->minimumColumnHeight(), distanceBetweenBreaks);
433068513a70bcd92384395513322f1b801e7bf9c729Steve Block            }
43312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        } else if (contentLogicalHeight() > pageLogicalHeight * desiredColumnCount) {
4332f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // Now that we know the intrinsic height of the columns, we have to rebalance them.
43332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            columnHeight = max(colInfo->minimumColumnHeight(), (int)ceilf((float)contentLogicalHeight() / desiredColumnCount));
4334f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        }
43358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4336f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (columnHeight && columnHeight != pageLogicalHeight) {
4337f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            statePusher.pop();
4338f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            m_everHadLayout = true;
4339f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            layoutBlock(false, columnHeight);
4340f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            return true;
43418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4342f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
4343f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
4344f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (pageLogicalHeight)
43452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        colInfo->setColumnCountAndHeight(ceilf((float)contentLogicalHeight() / pageLogicalHeight), pageLogicalHeight);
4346f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
4347f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (columnCount(colInfo)) {
43482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        setLogicalHeight(borderBefore() + paddingBefore() + colInfo->columnHeight() + borderAfter() + paddingAfter() + scrollbarLogicalHeight());
4349f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        m_overflow.clear();
4350643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
43518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
435268513a70bcd92384395513322f1b801e7bf9c729Steve Block    return false;
43538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
43548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
43558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::adjustPointToColumnContents(IntPoint& point) const
43568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
43578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Just bail if we have no columns.
43588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!hasColumns())
43598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
43608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
43615abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    ColumnInfo* colInfo = columnInfo();
436268513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!columnCount(colInfo))
43635abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        return;
43648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
43658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Determine which columns we intersect.
43668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int colGap = columnGap();
43672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int halfColGap = colGap / 2;
436868513a70bcd92384395513322f1b801e7bf9c729Steve Block    IntPoint columnPoint(columnRectAt(colInfo, 0).location());
43692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int logicalOffset = 0;
43705abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    for (unsigned i = 0; i < colInfo->columnCount(); i++) {
43718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Add in half the column gap to the left and right of the rect.
437268513a70bcd92384395513322f1b801e7bf9c729Steve Block        IntRect colRect = columnRectAt(colInfo, i);
43732bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (isHorizontalWritingMode()) {
43742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            IntRect gapAndColumnRect(colRect.x() - halfColGap, colRect.y(), colRect.width() + colGap, colRect.height());
43752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRect.maxX()) {
43762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // FIXME: The clamping that follows is not completely right for right-to-left
43772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // content.
43782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // Clamp everything above the column to its top left.
43792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                if (point.y() < gapAndColumnRect.y())
43802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    point = gapAndColumnRect.location();
43812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // Clamp everything below the column to the next column's top left. If there is
43822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // no next column, this still maps to just after this column.
43832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                else if (point.y() >= gapAndColumnRect.maxY()) {
43842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    point = gapAndColumnRect.location();
43852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    point.move(0, gapAndColumnRect.height());
43862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                }
43872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
43882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // We're inside the column.  Translate the x and y into our column coordinate space.
43892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                point.move(columnPoint.x() - colRect.x(), logicalOffset);
43902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                return;
4391dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            }
43922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
43932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            // Move to the next position.
43942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            logicalOffset += colRect.height();
43952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        } else {
43962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            IntRect gapAndColumnRect(colRect.x(), colRect.y() - halfColGap, colRect.width(), colRect.height() + colGap);
43972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (point.y() >= gapAndColumnRect.y() && point.y() < gapAndColumnRect.maxY()) {
43982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // FIXME: The clamping that follows is not completely right for right-to-left
43992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // content.
44002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // Clamp everything above the column to its top left.
44012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                if (point.x() < gapAndColumnRect.x())
44022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    point = gapAndColumnRect.location();
44032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // Clamp everything below the column to the next column's top left. If there is
44042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // no next column, this still maps to just after this column.
44052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                else if (point.x() >= gapAndColumnRect.maxX()) {
44062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    point = gapAndColumnRect.location();
44072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    point.move(gapAndColumnRect.width(), 0);
44082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                }
4409dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
44102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // We're inside the column.  Translate the x and y into our column coordinate space.
44112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                point.move(logicalOffset, columnPoint.y() - colRect.y());
44122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                return;
44132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            }
44142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
44152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            // Move to the next position.
44162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            logicalOffset += colRect.width();
44178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
44188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
44198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
44208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
44218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::adjustRectForColumns(IntRect& r) const
44228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
44238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Just bail if we have no columns.
44248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!hasColumns())
44258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
44268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
44275abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    ColumnInfo* colInfo = columnInfo();
44288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
44298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Begin with a result rect that is empty.
44308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    IntRect result;
44318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
44328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Determine which columns we intersect.
443368513a70bcd92384395513322f1b801e7bf9c729Steve Block    unsigned colCount = columnCount(colInfo);
44346c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (!colCount)
44356c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        return;
4436e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block
44372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int logicalLeft = logicalLeftOffsetForContent();
44382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int currLogicalOffset = 0;
44392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
44406c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    for (unsigned i = 0; i < colCount; i++) {
444168513a70bcd92384395513322f1b801e7bf9c729Steve Block        IntRect colRect = columnRectAt(colInfo, i);
44428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        IntRect repaintRect = r;
44432bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (isHorizontalWritingMode()) {
44442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int currXOffset = colRect.x() - logicalLeft;
44452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            repaintRect.move(currXOffset, currLogicalOffset);
44462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalOffset -= colRect.height();
44472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        } else {
44482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int currYOffset = colRect.y() - logicalLeft;
44492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            repaintRect.move(currLogicalOffset, currYOffset);
44502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalOffset -= colRect.width();
44512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
44528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        repaintRect.intersect(colRect);
44538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result.unite(repaintRect);
44548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
44558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
44568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    r = result;
44578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
44588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
44592fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockIntPoint RenderBlock::flipForWritingModeIncludingColumns(const IntPoint& point) const
44602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
44612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ASSERT(hasColumns());
44622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
44632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return point;
44642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ColumnInfo* colInfo = columnInfo();
44652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int columnLogicalHeight = colInfo->columnHeight();
44662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
44672bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
44682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return IntPoint(point.x(), expandedLogicalHeight - point.y());
44692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return IntPoint(expandedLogicalHeight - point.x(), point.y());
44702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
44712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
44722fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid RenderBlock::flipForWritingModeIncludingColumns(IntRect& rect) const
44732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
44742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ASSERT(hasColumns());
44752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
44762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
44772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
44782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ColumnInfo* colInfo = columnInfo();
44792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int columnLogicalHeight = colInfo->columnHeight();
44802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
44812bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
44822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        rect.setY(expandedLogicalHeight - rect.maxY());
44832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    else
44842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        rect.setX(expandedLogicalHeight - rect.maxX());
44852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
44862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
4487692e5dbf12901edacf14812a6fae25462920af42Steve Blockvoid RenderBlock::adjustForColumns(IntSize& offset, const IntPoint& point) const
4488692e5dbf12901edacf14812a6fae25462920af42Steve Block{
4489692e5dbf12901edacf14812a6fae25462920af42Steve Block    if (!hasColumns())
4490692e5dbf12901edacf14812a6fae25462920af42Steve Block        return;
4491692e5dbf12901edacf14812a6fae25462920af42Steve Block
44925abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    ColumnInfo* colInfo = columnInfo();
44935abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
44942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int logicalLeft = logicalLeftOffsetForContent();
449568513a70bcd92384395513322f1b801e7bf9c729Steve Block    size_t colCount = columnCount(colInfo);
44962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int colLogicalWidth = colInfo->desiredColumnWidth();
44972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int colLogicalHeight = colInfo->columnHeight();
44982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
449968513a70bcd92384395513322f1b801e7bf9c729Steve Block    for (size_t i = 0; i < colCount; ++i) {
45002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        // Compute the edges for a given column in the block progression direction.
45012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        IntRect sliceRect = IntRect(logicalLeft, borderBefore() + paddingBefore() + i * colLogicalHeight, colLogicalWidth, colLogicalHeight);
45022bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!isHorizontalWritingMode())
45032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            sliceRect = sliceRect.transposedRect();
45042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
45052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        // If we have a flipped blocks writing mode, then convert the column so that it's coming from the after edge (either top or left edge).
45062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        flipForWritingModeIncludingColumns(sliceRect);
45072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
45082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int logicalOffset = style()->isFlippedBlocksWritingMode() ? (colCount - 1 - i) * colLogicalHeight : i * colLogicalHeight;
4509692e5dbf12901edacf14812a6fae25462920af42Steve Block
45102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        // Now we're in the same coordinate space as the point.  See if it is inside the rectangle.
45112bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (isHorizontalWritingMode()) {
45122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (point.y() >= sliceRect.y() && point.y() < sliceRect.maxY()) {
45132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                offset.expand(columnRectAt(colInfo, i).x() - logicalLeft, -logicalOffset);
45142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                return;
45152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            }
45162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        } else {
45172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (point.x() >= sliceRect.x() && point.x() < sliceRect.maxX()) {
45182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                offset.expand(-logicalOffset, columnRectAt(colInfo, i).y() - logicalLeft);
45192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                return;
45202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            }
45212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
4522692e5dbf12901edacf14812a6fae25462920af42Steve Block    }
4523692e5dbf12901edacf14812a6fae25462920af42Steve Block}
4524692e5dbf12901edacf14812a6fae25462920af42Steve Block
4525bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBlock::computePreferredLogicalWidths()
45268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4527bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    ASSERT(preferredLogicalWidthsDirty());
45288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
45298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    updateFirstLetter();
45308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4531a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!isTableCell() && style()->logicalWidth().isFixed() && style()->logicalWidth().value() > 0)
4532a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeContentBoxLogicalWidth(style()->logicalWidth().value());
45338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
4534bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_minPreferredLogicalWidth = 0;
4535bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_maxPreferredLogicalWidth = 0;
45368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
45378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (childrenInline())
4538bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            computeInlinePreferredLogicalWidths();
45398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
4540bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            computeBlockPreferredLogicalWidths();
45418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4542bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_maxPreferredLogicalWidth = max(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
45438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
45448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!style()->autoWrap() && childrenInline()) {
4545bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth;
45468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
45478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // A horizontal marquee with inline children has no minimum width.
45488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (layer() && layer()->marquee() && layer()->marquee()->isHorizontal())
4549bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                m_minPreferredLogicalWidth = 0;
45508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
45518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4552f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        int scrollbarWidth = 0;
4553f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (hasOverflowClip() && style()->overflowY() == OSCROLL) {
4554f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            layer()->setHasVerticalScrollbar(true);
4555f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            scrollbarWidth = verticalScrollbarWidth();
4556f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            m_maxPreferredLogicalWidth += scrollbarWidth;
4557f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        }
4558f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
45598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (isTableCell()) {
456028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            Length w = toRenderTableCell(this)->styleOrColLogicalWidth();
4561f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            if (w.isFixed() && w.value() > 0) {
4562bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                m_maxPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(w.value()));
4563f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                scrollbarWidth = 0;
4564f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            }
45658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4566f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
4567f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        m_minPreferredLogicalWidth += scrollbarWidth;
45688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
45698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4570a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (style()->logicalMinWidth().isFixed() && style()->logicalMinWidth().value() > 0) {
4571a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMinWidth().value()));
4572a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMinWidth().value()));
45738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
45748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4575a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (style()->logicalMaxWidth().isFixed() && style()->logicalMaxWidth().value() != undefinedLength) {
4576a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMaxWidth().value()));
4577a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMaxWidth().value()));
45788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
45798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4580f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int borderAndPadding = borderAndPaddingLogicalWidth();
4581f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    m_minPreferredLogicalWidth += borderAndPadding;
4582f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    m_maxPreferredLogicalWidth += borderAndPadding;
45838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4584bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    setPreferredLogicalWidthsDirty(false);
45858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
45868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
45870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstruct InlineMinMaxIterator {
45888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* InlineMinMaxIterator is a class that will iterate over all render objects that contribute to
45898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project   inline min/max width calculations.  Note the following about the way it walks:
45908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project   (1) Positioned content is skipped (since it does not contribute to min/max width of a block)
45918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project   (2) We do not drill into the children of floats or replaced elements, since you can't break
45928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project       in the middle of such an element.
45938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project   (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side can have
45948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project       distinct borders/margin/padding that contribute to the min/max width.
45958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project*/
45968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* parent;
45978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* current;
45988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool endOfInline;
45998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    InlineMinMaxIterator(RenderObject* p, bool end = false)
46018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        :parent(p), current(p), endOfInline(end) {}
46028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* next();
46048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
46058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderObject* InlineMinMaxIterator::next()
46078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
46088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* result = 0;
46098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool oldEndOfInline = endOfInline;
46108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    endOfInline = false;
46118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (current || current == parent) {
46128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!oldEndOfInline &&
46138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            (current == parent ||
46148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project             (!current->isFloating() && !current->isReplaced() && !current->isPositioned())))
46158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            result = current->firstChild();
46168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!result) {
46178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We hit the end of our inline. (It was empty, e.g., <span></span>.)
4618635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (!oldEndOfInline && current->isRenderInline()) {
46198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                result = current;
46208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                endOfInline = true;
46218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
46228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
46238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            while (current && current != parent) {
46258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                result = current->nextSibling();
46268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (result) break;
46278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                current = current->parent();
4628635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (current && current != parent && current->isRenderInline()) {
46298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    result = current;
46308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    endOfInline = true;
46318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
46328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
46338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
46348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
46358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!result)
46378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
46388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4639635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (!result->isPositioned() && (result->isText() || result->isFloating() || result->isReplaced() || result->isRenderInline()))
46408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project             break;
46418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        current = result;
46438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result = 0;
46448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
46458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Update our position.
46478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    current = result;
46488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return current;
46498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
46508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic int getBPMWidth(int childValue, Length cssUnit)
46528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
46538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (cssUnit.type() != Auto)
46548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return (cssUnit.isFixed() ? cssUnit.value() : childValue);
46558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
46568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
46578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic int getBorderPaddingMargin(const RenderBoxModelObject* child, bool endOfInline)
46598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
46608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderStyle* cstyle = child->style();
46612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (endOfInline)
46622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return getBPMWidth(child->marginEnd(), cstyle->marginEnd()) +
46632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block               getBPMWidth(child->paddingEnd(), cstyle->paddingEnd()) +
46642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block               child->borderEnd();
46652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return getBPMWidth(child->marginStart(), cstyle->marginStart()) +
46662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block               getBPMWidth(child->paddingStart(), cstyle->paddingStart()) +
46672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block               child->borderStart();
46688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
46698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
467081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic inline void stripTrailingSpace(float& inlineMax, float& inlineMin,
46718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                      RenderObject* trailingSpaceChild)
46728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
46738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (trailingSpaceChild && trailingSpaceChild->isText()) {
46748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Collapse away the trailing space at the end of a block.
4675635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        RenderText* t = toRenderText(trailingSpaceChild);
46768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const UChar space = ' ';
46778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const Font& font = t->style()->font(); // FIXME: This ignores first-line.
467881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        float spaceWidth = font.width(TextRun(&space, 1));
46798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        inlineMax -= spaceWidth + font.wordSpacing();
46808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (inlineMin > inlineMax)
46818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            inlineMin = inlineMax;
46828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
46838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
46848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
468581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic inline void updatePreferredWidth(int& preferredWidth, float& result)
468681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
468781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int snappedResult = ceilf(result);
468881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    preferredWidth = max(snappedResult, preferredWidth);
468981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
469081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
4691bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBlock::computeInlinePreferredLogicalWidths()
46928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
469381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    float inlineMax = 0;
469481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    float inlineMin = 0;
46958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int cw = containingBlock()->contentLogicalWidth();
46978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If we are at the start of a line, we want to ignore all white-space.
46998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Also strip spaces if we previously had text that ended in a trailing space.
47008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool stripFrontSpaces = true;
47018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* trailingSpaceChild = 0;
47028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Firefox and Opera will allow a table cell to grow to fit an image inside it under
47048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // very specific cirucumstances (in order to match common WinIE renderings).
47058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
47062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    bool allowImagesToBreak = !document()->inQuirksMode() || !isTableCell() || !style()->logicalWidth().isIntrinsicOrAuto();
47078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool autoWrap, oldAutoWrap;
47098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    autoWrap = oldAutoWrap = style()->autoWrap();
47108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    InlineMinMaxIterator childIterator(this);
47128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool addedTextIndent = false; // Only gets added in once.
47138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* prevFloat = 0;
47148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (RenderObject* child = childIterator.next()) {
47158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        autoWrap = child->isReplaced() ? child->parent()->style()->autoWrap() :
47168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            child->style()->autoWrap();
47178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!child->isBR()) {
47198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Step One: determine whether or not we need to go ahead and
47208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // terminate our current line.  Each discrete chunk can become
47218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // the new min-width, if it is the widest chunk seen so far, and
47228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // it can also become the max-width.
47238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Children fall into three categories:
47258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (1) An inline flow object.  These objects always have a min/max of 0,
47268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // and are included in the iteration solely so that their margins can
47278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // be added in.
47288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            //
47298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (2) An inline non-text non-flow object, e.g., an inline replaced element.
47308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // These objects can always be on a line by themselves, so in this situation
47318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // we need to go ahead and break the current line, and then add in our own
47328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // margins and min/max width on its own line, and then terminate the line.
47338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            //
47348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (3) A text object.  Text runs can have breakable characters at the start,
47358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // the middle or the end.  They may also lose whitespace off the front if
47368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // we're already ignoring whitespace.  In order to compute accurate min-width
47378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // information, we need three pieces of information.
47388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (a) the min-width of the first non-breakable run.  Should be 0 if the text string
47398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // starts with whitespace.
47408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (b) the min-width of the last non-breakable run. Should be 0 if the text string
47418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // ends with whitespace.
47428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (c) the min/max width of the string (trimmed for whitespace).
47438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            //
47448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // If the text string starts with whitespace, then we need to go ahead and
47458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // terminate our current line (unless we're already in a whitespace stripping
47468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // mode.
47478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            //
47488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // If the text string has a breakable character in the middle, but didn't start
47498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // with whitespace, then we add the width of the first non-breakable run and
47508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // then end the current line.  We then need to use the intermediate min/max width
47518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // values (if any of them are larger than our current min/max).  We then look at
47528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // the width of the last non-breakable run and use that to start a new line
47538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (unless we end in whitespace).
47548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderStyle* cstyle = child->style();
475581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            float childMin = 0;
475681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            float childMax = 0;
47578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!child->isText()) {
47598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Case (1) and (2).  Inline replaced and inline flow elements.
4760635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (child->isRenderInline()) {
47618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // Add in padding/border/margin from the appropriate side of
47628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // the element.
476381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    float bpm = getBorderPaddingMargin(toRenderInline(child), childIterator.endOfInline);
47648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    childMin += bpm;
47658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    childMax += bpm;
47668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMin += childMin;
47688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMax += childMax;
47698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4770bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                    child->setPreferredLogicalWidthsDirty(false);
47718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else {
47728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // Inline replaced elts add in their margins to their min/max values.
477381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    float margins = 0;
47742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    Length startMargin = cstyle->marginStart();
47752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    Length endMargin = cstyle->marginEnd();
47762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    if (startMargin.isFixed())
47772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                        margins += startMargin.value();
47782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    if (endMargin.isFixed())
47792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                        margins += endMargin.value();
47808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    childMin += margins;
47818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    childMax += margins;
47828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
47838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
47848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!child->isRenderInline() && !child->isText()) {
47868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Case (2). Inline replaced elements and floats.
47878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Go ahead and terminate the current line as far as
47888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // minwidth is concerned.
4789bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                childMin += child->minPreferredLogicalWidth();
4790bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                childMax += child->maxPreferredLogicalWidth();
47918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                bool clearPreviousFloat;
47938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (child->isFloating()) {
47948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    clearPreviousFloat = (prevFloat
47958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        && ((prevFloat->style()->floating() == FLEFT && (child->style()->clear() & CLEFT))
47968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                            || (prevFloat->style()->floating() == FRIGHT && (child->style()->clear() & CRIGHT))));
47978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    prevFloat = child;
47988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else
47998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    clearPreviousFloat = false;
48008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak;
48028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if ((canBreakReplacedElement && (autoWrap || oldAutoWrap)) || clearPreviousFloat) {
480381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
48048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMin = 0;
48058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
48068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // If we're supposed to clear the previous float, then terminate maxwidth as well.
48088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (clearPreviousFloat) {
480981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
48108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMax = 0;
48118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
48128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Add in text-indent.  This is added in only once.
48148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                int ti = 0;
48158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!addedTextIndent) {
48168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    addedTextIndent = true;
48178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    ti = style()->textIndent().calcMinValue(cw);
48182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    childMin += ti;
48192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    childMax += ti;
48208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
48218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Add our width to the max.
48238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                inlineMax += childMax;
48248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!autoWrap || !canBreakReplacedElement) {
48268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (child->isFloating())
482781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        updatePreferredWidth(m_minPreferredLogicalWidth, childMin);
48288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    else
48298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        inlineMin += childMin;
48308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else {
48318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // Now check our line.
483281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    updatePreferredWidth(m_minPreferredLogicalWidth, childMin);
48338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // Now start a new line.
48358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMin = 0;
48368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
48378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // We are no longer stripping whitespace at the start of
48398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // a line.
48408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!child->isFloating()) {
48418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    stripFrontSpaces = false;
48428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    trailingSpaceChild = 0;
48438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
48448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else if (child->isText()) {
48458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Case (3). Text.
4846635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                RenderText* t = toRenderText(child);
48478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (t->isWordBreak()) {
484981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
48508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMin = 0;
48518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
48528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
48538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48542bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (t->style()->hasTextCombine() && t->isCombineText())
48552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    toRenderCombineText(t)->combineText();
48562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
48578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Determine if we have a breakable character.  Pass in
48588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // whether or not we should ignore any spaces at the front
48598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // of the string.  If those are going to be stripped out,
48608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // then they shouldn't be considered in the breakable char
48618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // check.
48628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                bool hasBreakableChar, hasBreak;
486381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                float beginMin, endMin;
48648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                bool beginWS, endWS;
486581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                float beginMax, endMax;
48668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                t->trimmedPrefWidths(inlineMax, beginMin, beginWS, endMin, endWS,
48678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                     hasBreakableChar, hasBreak, beginMax, endMax,
48688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                     childMin, childMax, stripFrontSpaces);
48698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // This text object will not be rendered, but it may still provide a breaking opportunity.
48718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!hasBreak && childMax == 0) {
48728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (autoWrap && (beginWS || endWS)) {
487381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
48748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        inlineMin = 0;
48758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
48768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
48778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
48788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (stripFrontSpaces)
48808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    trailingSpaceChild = child;
48818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                else
48828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    trailingSpaceChild = 0;
48838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Add in text-indent.  This is added in only once.
48858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                int ti = 0;
48868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!addedTextIndent) {
48878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    addedTextIndent = true;
48888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    ti = style()->textIndent().calcMinValue(cw);
48898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    childMin+=ti; beginMin += ti;
48908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    childMax+=ti; beginMax += ti;
48918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
48928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // If we have no breakable characters at all,
48948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // then this is the easy case. We add ourselves to the current
48958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // min and max and continue.
48968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!hasBreakableChar) {
48978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMin += childMin;
48988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else {
48998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // We have a breakable character.  Now we need to know if
49008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // we start and end with whitespace.
49018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (beginWS)
49028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // Go ahead and end the current line.
490381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
49048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    else {
49058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        inlineMin += beginMin;
490681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
49078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        childMin -= ti;
49088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
49098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMin = childMin;
49118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (endWS) {
49138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // We end in whitespace, which means we can go ahead
49148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // and end our current line.
491581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
49168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        inlineMin = 0;
49178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    } else {
491881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
49198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        inlineMin = endMin;
49208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
49218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
49228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (hasBreak) {
49248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMax += beginMax;
492581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
492681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    updatePreferredWidth(m_maxPreferredLogicalWidth, childMax);
49278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMax = endMax;
49288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else
49298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMax += childMax;
49308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4931643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
4932643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            // Ignore spaces after a list marker.
4933643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (child->isListMarker())
4934643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                stripFrontSpaces = true;
49358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
493681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
493781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
49388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            inlineMin = inlineMax = 0;
49398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            stripFrontSpaces = true;
49408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            trailingSpaceChild = 0;
49418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
49428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        oldAutoWrap = autoWrap;
49448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
49458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->collapseWhiteSpace())
49478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        stripTrailingSpace(inlineMax, inlineMin, trailingSpaceChild);
49488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
494981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
495081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
49518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
49528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Use a very large value (in effect infinite).
49548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define BLOCK_MAX_WIDTH 15000
49558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4956bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBlock::computeBlockPreferredLogicalWidths()
49578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
49588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool nowrap = style()->whiteSpace() == NOWRAP;
49598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject *child = firstChild();
49618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int floatLeftWidth = 0, floatRightWidth = 0;
49628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (child) {
49638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Positioned children don't affect the min/max width
49648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (child->isPositioned()) {
49658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            child = child->nextSibling();
49668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
49678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
49688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (child->isFloating() || (child->isBox() && toRenderBox(child)->avoidsFloats())) {
49708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int floatTotalWidth = floatLeftWidth + floatRightWidth;
49718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (child->style()->clear() & CLEFT) {
4972bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                m_maxPreferredLogicalWidth = max(floatTotalWidth, m_maxPreferredLogicalWidth);
49738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatLeftWidth = 0;
49748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
49758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (child->style()->clear() & CRIGHT) {
4976bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                m_maxPreferredLogicalWidth = max(floatTotalWidth, m_maxPreferredLogicalWidth);
49778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatRightWidth = 0;
49788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
49798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
49808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // A margin basically has three types: fixed, percentage, and auto (variable).
49828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Auto and percentage margins simply become 0 when computing min/max width.
49838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Fixed margins can be added in as is.
49842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        Length startMarginLength = child->style()->marginStart();
49852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        Length endMarginLength = child->style()->marginEnd();
49862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int margin = 0;
49872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int marginStart = 0;
49882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int marginEnd = 0;
49892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (startMarginLength.isFixed())
49902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            marginStart += startMarginLength.value();
49912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (endMarginLength.isFixed())
49922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            marginEnd += endMarginLength.value();
49932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        margin = marginStart + marginEnd;
49948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4995bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        int w = child->minPreferredLogicalWidth() + margin;
4996bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_minPreferredLogicalWidth = max(w, m_minPreferredLogicalWidth);
49978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // IE ignores tables for calculation of nowrap. Makes some sense.
49998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (nowrap && !child->isTable())
5000bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            m_maxPreferredLogicalWidth = max(w, m_maxPreferredLogicalWidth);
50018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5002bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        w = child->maxPreferredLogicalWidth() + margin;
50038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!child->isFloating()) {
50058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (child->isBox() && toRenderBox(child)->avoidsFloats()) {
50068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Determine a left and right max value based off whether or not the floats can fit in the
50078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // margins of the object.  For negative margins, we will attempt to overlap the float if the negative margin
50088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // is smaller than the float width.
50092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                bool ltr = containingBlock()->style()->isLeftToRightDirection();
50102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int marginLogicalLeft = ltr ? marginStart : marginEnd;
50112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int marginLogicalRight = ltr ? marginEnd : marginStart;
50122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int maxLeft = marginLogicalLeft > 0 ? max(floatLeftWidth, marginLogicalLeft) : floatLeftWidth + marginLogicalLeft;
50132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int maxRight = marginLogicalRight > 0 ? max(floatRightWidth, marginLogicalRight) : floatRightWidth + marginLogicalRight;
5014bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                w = child->maxPreferredLogicalWidth() + maxLeft + maxRight;
50158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                w = max(w, floatLeftWidth + floatRightWidth);
50168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
50178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
5018bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                m_maxPreferredLogicalWidth = max(floatLeftWidth + floatRightWidth, m_maxPreferredLogicalWidth);
50198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            floatLeftWidth = floatRightWidth = 0;
50208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
50218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (child->isFloating()) {
50238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (style()->floating() == FLEFT)
50248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatLeftWidth += w;
50258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
50268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatRightWidth += w;
50278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else
5028bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            m_maxPreferredLogicalWidth = max(w, m_maxPreferredLogicalWidth);
50298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // A very specific WinIE quirk.
50318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Example:
50328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        /*
50338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project           <div style="position:absolute; width:100px; top:50px;">
50348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project              <div style="position:absolute;left:0px;top:50px;height:50px;background-color:green">
50358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                <table style="width:100%"><tr><td></table>
50368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project              </div>
50378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project           </div>
50388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        */
50398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // In the above example, the inner absolute positioned block should have a computed width
50408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // of 100px because of the table.
50418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We can achieve this effect by making the maxwidth of blocks that contain tables
50428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // with percentage widths be infinite (as long as they are not inside a table cell).
50432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (document()->inQuirksMode() && child->style()->logicalWidth().isPercent() &&
5044bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            !isTableCell() && child->isTable() && m_maxPreferredLogicalWidth < BLOCK_MAX_WIDTH) {
50458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderBlock* cb = containingBlock();
50468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            while (!cb->isRenderView() && !cb->isTableCell())
50478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                cb = cb->containingBlock();
50488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!cb->isTableCell())
5049bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                m_maxPreferredLogicalWidth = BLOCK_MAX_WIDTH;
50508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
50518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child = child->nextSibling();
50538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
50548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Always make sure these values are non-negative.
5056bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_minPreferredLogicalWidth = max(0, m_minPreferredLogicalWidth);
5057bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_maxPreferredLogicalWidth = max(0, m_maxPreferredLogicalWidth);
50588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5059bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_maxPreferredLogicalWidth = max(floatLeftWidth + floatRightWidth, m_maxPreferredLogicalWidth);
50608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
50618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::hasLineIfEmpty() const
50638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
50640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!node())
50650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return false;
50660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
50672bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (node()->rendererIsEditable() && node()->rootEditableElement() == node())
50680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return true;
50690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5070cad810f21b803229eb11403f9209855525a25d57Steve Block    if (node()->isShadowRoot() && (node()->shadowHost()->hasTagName(inputTag)))
50710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return true;
50720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
50730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return false;
50748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
50758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5076a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::lineHeight(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
50778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
50788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Inline blocks are replaced elements. Otherwise, just pass off to
50798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the base class.  If we're being queried as though we're the root line
50808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // box, then the fact that we're an inline-block is irrelevant, and we behave
50818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // just like a block.
5082a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (isReplaced() && linePositionMode == PositionOnContainingLine)
5083a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return RenderBox::lineHeight(firstLine, direction, linePositionMode);
5084a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
50858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (firstLine && document()->usesFirstLineRules()) {
50868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderStyle* s = style(firstLine);
50878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (s != style())
50888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return s->computedLineHeight();
50898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
50908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
50918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_lineHeight == -1)
50928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_lineHeight = style()->computedLineHeight();
50938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
50948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return m_lineHeight;
50958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
50968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50976b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerint RenderBlock::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
50988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
50998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Inline blocks are replaced elements. Otherwise, just pass off to
51008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the base class.  If we're being queried as though we're the root line
51018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // box, then the fact that we're an inline-block is irrelevant, and we behave
51028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // just like a block.
5103a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (isReplaced() && linePositionMode == PositionOnContainingLine) {
51048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // For "leaf" theme objects, let the theme decide what the baseline position is.
51058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: Might be better to have a custom CSS property instead, so that if the theme
51068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // is turned off, checkboxes/radios will still have decent baselines.
5107a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // FIXME: Need to patch form controls to deal with vertical lines.
51088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (style()->hasAppearance() && !theme()->isControlContainer(style()->appearance()))
51098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return theme()->baselinePosition(this);
51108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
51118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // CSS2.1 states that the baseline of an inline block is the baseline of the last line box in
51128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // the normal flow.  We make an exception for marquees, since their baselines are meaningless
51138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // (the content inside them moves).  This matches WinIE as well, which just bottom-aligns them.
51148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We also give up on finding a baseline if we have a vertical scrollbar, or if we are scrolled
51158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // vertically (e.g., an overflow:hidden block that has had scrollTop moved) or if the baseline is outside
51168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // of our content box.
5117a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        bool ignoreBaseline = (layer() && (layer()->marquee() || (direction == HorizontalLine ? (layer()->verticalScrollbar() || layer()->scrollYOffset() != 0)
51186b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            : (layer()->horizontalScrollbar() || layer()->scrollXOffset() != 0)))) || (isWritingModeRoot() && !isRubyRun());
51196b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
5120a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int baselinePos = ignoreBaseline ? -1 : lastLineBoxBaseline();
5121a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
5122a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int bottomOfContent = direction == HorizontalLine ? borderTop() + paddingTop() + contentHeight() : borderRight() + paddingRight() + contentWidth();
5123a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (baselinePos != -1 && baselinePos <= bottomOfContent)
5124a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            return direction == HorizontalLine ? marginTop() + baselinePos : marginRight() + baselinePos;
5125a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
51266b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
51278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5128a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
51292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    const FontMetrics& fontMetrics = style(firstLine)->fontMetrics();
51302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2;
51318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
51328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
51338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianint RenderBlock::firstLineBoxBaseline() const
51348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
51356b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (!isBlockFlow() || (isWritingModeRoot() && !isRubyRun()))
51368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return -1;
51378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
51388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childrenInline()) {
51398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (firstLineBox())
51402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return firstLineBox()->logicalTop() + style(true)->fontMetrics().ascent(firstRootBox()->baselineType());
51418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
51428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return -1;
51438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
51448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
5145635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        for (RenderBox* curr = firstChildBox(); curr; curr = curr->nextSiblingBox()) {
51468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!curr->isFloatingOrPositioned()) {
51478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                int result = curr->firstLineBoxBaseline();
51488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (result != -1)
5149a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    return curr->logicalTop() + result; // Translate to our coordinate space.
51508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
51518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
51528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
51538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
51548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return -1;
51558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
51568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
51578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianint RenderBlock::lastLineBoxBaseline() const
51588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
51596b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (!isBlockFlow() || (isWritingModeRoot() && !isRubyRun()))
51608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return -1;
51618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
51622bde8e466a4451c7319e3a072d118917957d6554Steve Block    LineDirectionMode lineDirection = isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
5163a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
51648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childrenInline()) {
5165a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!firstLineBox() && hasLineIfEmpty()) {
51662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
51672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return fontMetrics.ascent()
51682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                 + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
51692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
5170a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
51718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (lastLineBox())
51722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->fontMetrics().ascent(lastRootBox()->baselineType());
51738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return -1;
5174a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else {
51758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool haveNormalFlowChild = false;
5176635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        for (RenderBox* curr = lastChildBox(); curr; curr = curr->previousSiblingBox()) {
51778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!curr->isFloatingOrPositioned()) {
51788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                haveNormalFlowChild = true;
51798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                int result = curr->lastLineBoxBaseline();
51808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (result != -1)
5181a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    return curr->logicalTop() + result; // Translate to our coordinate space.
51828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
51838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5184a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!haveNormalFlowChild && hasLineIfEmpty()) {
51852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
51862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return fontMetrics.ascent()
51872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                 + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
51882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
5189a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
51908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
51918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
51928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return -1;
51938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
51948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5195635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool RenderBlock::containsNonZeroBidiLevel() const
5196635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
5197635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
5198635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        for (InlineBox* box = root->firstLeafChild(); box; box = box->nextLeafChild()) {
5199635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (box->bidiLevel())
5200635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                return true;
5201635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
5202635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
5203635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return false;
5204635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
5205635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
52068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderBlock* RenderBlock::firstLineBlock() const
52078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5208635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderBlock* firstLineBlock = const_cast<RenderBlock*>(this);
52098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool hasPseudo = false;
52108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (true) {
52118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        hasPseudo = firstLineBlock->style()->hasPseudoStyle(FIRST_LINE);
52128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (hasPseudo)
52138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
52148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderObject* parentBlock = firstLineBlock->parent();
52158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (firstLineBlock->isReplaced() || firstLineBlock->isFloating() ||
52168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            !parentBlock || parentBlock->firstChild() != firstLineBlock || !parentBlock->isBlockFlow())
52178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
5218635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        ASSERT(parentBlock->isRenderBlock());
52198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        firstLineBlock = toRenderBlock(parentBlock);
52208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
52218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
52228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!hasPseudo)
52238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
52248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5225635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return firstLineBlock;
52268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
52278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
522868513a70bcd92384395513322f1b801e7bf9c729Steve Blockstatic RenderStyle* styleForFirstLetter(RenderObject* firstLetterBlock, RenderObject* firstLetterContainer)
522968513a70bcd92384395513322f1b801e7bf9c729Steve Block{
523068513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderStyle* pseudoStyle = firstLetterBlock->getCachedPseudoStyle(FIRST_LETTER, firstLetterContainer->firstLineStyle());
523168513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Force inline display (except for floating first-letters).
523268513a70bcd92384395513322f1b801e7bf9c729Steve Block    pseudoStyle->setDisplay(pseudoStyle->isFloating() ? BLOCK : INLINE);
523368513a70bcd92384395513322f1b801e7bf9c729Steve Block    // CSS2 says first-letter can't be positioned.
523468513a70bcd92384395513322f1b801e7bf9c729Steve Block    pseudoStyle->setPosition(StaticPosition);
523568513a70bcd92384395513322f1b801e7bf9c729Steve Block    return pseudoStyle;
523668513a70bcd92384395513322f1b801e7bf9c729Steve Block}
523768513a70bcd92384395513322f1b801e7bf9c729Steve Block
5238a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch// CSS 2.1 http://www.w3.org/TR/CSS21/selector.html#first-letter
5239a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch// "Punctuation (i.e, characters defined in Unicode [UNICODE] in the "open" (Ps), "close" (Pe),
5240a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch// "initial" (Pi). "final" (Pf) and "other" (Po) punctuation classes), that precedes or follows the first letter should be included"
5241a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic inline bool isPunctuationForFirstLetter(UChar c)
5242a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
5243a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    CharCategory charCategory = category(c);
5244a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return charCategory == Punctuation_Open
5245a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        || charCategory == Punctuation_Close
5246a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        || charCategory == Punctuation_InitialQuote
5247a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        || charCategory == Punctuation_FinalQuote
5248a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        || charCategory == Punctuation_Other;
5249a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
5250a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
5251a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic inline bool shouldSkipForFirstLetter(UChar c)
5252a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
5253a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return isSpaceOrNewline(c) || c == noBreakSpace || isPunctuationForFirstLetter(c);
5254a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
5255a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
52568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::updateFirstLetter()
52578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
52588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!document()->usesFirstLetterRules())
52598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
52608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Don't recur
52618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (style()->styleType() == FIRST_LETTER)
52628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
52638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
52648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: We need to destroy the first-letter object if it is no longer the first child.  Need to find
52658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // an efficient way to check for that situation though before implementing anything.
52668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* firstLetterBlock = this;
52678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool hasPseudoStyle = false;
52688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (true) {
52698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We only honor first-letter if the firstLetterBlock can have children in the DOM. This correctly
52708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // prevents form controls from honoring first-letter.
52718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        hasPseudoStyle = firstLetterBlock->style()->hasPseudoStyle(FIRST_LETTER)
52728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            && firstLetterBlock->canHaveChildren();
52738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (hasPseudoStyle)
52748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
52758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderObject* parentBlock = firstLetterBlock->parent();
52768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (firstLetterBlock->isReplaced() || !parentBlock || parentBlock->firstChild() != firstLetterBlock ||
52778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            !parentBlock->isBlockFlow())
52788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
52798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        firstLetterBlock = parentBlock;
52808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
52818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
52828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!hasPseudoStyle)
52838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
52848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
52858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Drill into inlines looking for our first text child.
52868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* currChild = firstLetterBlock->firstChild();
52876c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    while (currChild && ((!currChild->isReplaced() && !currChild->isRenderButton() && !currChild->isMenuList()) || currChild->isFloatingOrPositioned()) && !currChild->isText()) {
52888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (currChild->isFloatingOrPositioned()) {
52896c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            if (currChild->style()->styleType() == FIRST_LETTER) {
52906c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen                currChild = currChild->firstChild();
52918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
52926c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            }
52938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            currChild = currChild->nextSibling();
52948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else
52958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            currChild = currChild->firstChild();
52968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
52978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
52988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Get list markers out of the way.
52998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (currChild && currChild->isListMarker())
53008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        currChild = currChild->nextSibling();
53018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
53028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!currChild)
53038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
53048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
53058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the child already has style, then it has already been created, so we just want
53068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // to update it.
530768513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (currChild->parent()->style()->styleType() == FIRST_LETTER) {
530868513a70bcd92384395513322f1b801e7bf9c729Steve Block        RenderObject* firstLetter = currChild->parent();
530968513a70bcd92384395513322f1b801e7bf9c729Steve Block        RenderObject* firstLetterContainer = firstLetter->parent();
531068513a70bcd92384395513322f1b801e7bf9c729Steve Block        RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
531168513a70bcd92384395513322f1b801e7bf9c729Steve Block
531268513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (Node::diff(firstLetter->style(), pseudoStyle) == Node::Detach) {
531368513a70bcd92384395513322f1b801e7bf9c729Steve Block            // The first-letter renderer needs to be replaced. Create a new renderer of the right type.
531468513a70bcd92384395513322f1b801e7bf9c729Steve Block            RenderObject* newFirstLetter;
531568513a70bcd92384395513322f1b801e7bf9c729Steve Block            if (pseudoStyle->display() == INLINE)
531668513a70bcd92384395513322f1b801e7bf9c729Steve Block                newFirstLetter = new (renderArena()) RenderInline(document());
531768513a70bcd92384395513322f1b801e7bf9c729Steve Block            else
531868513a70bcd92384395513322f1b801e7bf9c729Steve Block                newFirstLetter = new (renderArena()) RenderBlock(document());
531968513a70bcd92384395513322f1b801e7bf9c729Steve Block            newFirstLetter->setStyle(pseudoStyle);
532068513a70bcd92384395513322f1b801e7bf9c729Steve Block
532168513a70bcd92384395513322f1b801e7bf9c729Steve Block            // Move the first letter into the new renderer.
532268513a70bcd92384395513322f1b801e7bf9c729Steve Block            view()->disableLayoutState();
532368513a70bcd92384395513322f1b801e7bf9c729Steve Block            while (RenderObject* child = firstLetter->firstChild()) {
532468513a70bcd92384395513322f1b801e7bf9c729Steve Block                if (child->isText())
53252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    toRenderText(child)->removeAndDestroyTextBoxes();
532668513a70bcd92384395513322f1b801e7bf9c729Steve Block                firstLetter->removeChild(child);
532768513a70bcd92384395513322f1b801e7bf9c729Steve Block                newFirstLetter->addChild(child, 0);
532868513a70bcd92384395513322f1b801e7bf9c729Steve Block            }
532981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
533081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            RenderTextFragment* remainingText = 0;
533181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            RenderObject* nextSibling = firstLetter->nextSibling();
533281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            RenderObject* next = nextSibling;
533381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            while (next) {
533481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (next->isText() && toRenderText(next)->isTextFragment()) {
533581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    remainingText = toRenderTextFragment(next);
533681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    break;
533781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                }
533881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                next = next->nextSibling();
533981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
534081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (remainingText) {
534181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                ASSERT(remainingText->node()->renderer() == remainingText);
534281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                // Replace the old renderer with the new one.
534381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                remainingText->setFirstLetter(newFirstLetter);
534481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
534568513a70bcd92384395513322f1b801e7bf9c729Steve Block            firstLetter->destroy();
534668513a70bcd92384395513322f1b801e7bf9c729Steve Block            firstLetter = newFirstLetter;
534781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            firstLetterContainer->addChild(firstLetter, nextSibling);
534868513a70bcd92384395513322f1b801e7bf9c729Steve Block            view()->enableLayoutState();
534968513a70bcd92384395513322f1b801e7bf9c729Steve Block        } else
535068513a70bcd92384395513322f1b801e7bf9c729Steve Block            firstLetter->setStyle(pseudoStyle);
535168513a70bcd92384395513322f1b801e7bf9c729Steve Block
535268513a70bcd92384395513322f1b801e7bf9c729Steve Block        for (RenderObject* genChild = firstLetter->firstChild(); genChild; genChild = genChild->nextSibling()) {
53538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (genChild->isText())
535468513a70bcd92384395513322f1b801e7bf9c729Steve Block                genChild->setStyle(pseudoStyle);
53558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
535668513a70bcd92384395513322f1b801e7bf9c729Steve Block
53578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
53588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
53598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
536068513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!currChild->isText() || currChild->isBR())
536168513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
536268513a70bcd92384395513322f1b801e7bf9c729Steve Block
53638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the child does not already have style, we create it here.
536468513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderObject* firstLetterContainer = currChild->parent();
53658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
536668513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Our layout state is not valid for the repaints we are going to trigger by
536768513a70bcd92384395513322f1b801e7bf9c729Steve Block    // adding and removing children of firstLetterContainer.
536868513a70bcd92384395513322f1b801e7bf9c729Steve Block    view()->disableLayoutState();
536968513a70bcd92384395513322f1b801e7bf9c729Steve Block
537068513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderText* textObj = toRenderText(currChild);
537168513a70bcd92384395513322f1b801e7bf9c729Steve Block
537268513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Create our pseudo style now that we have our firstLetterContainer determined.
537368513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
537468513a70bcd92384395513322f1b801e7bf9c729Steve Block
537568513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderObject* firstLetter = 0;
537668513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (pseudoStyle->display() == INLINE)
537768513a70bcd92384395513322f1b801e7bf9c729Steve Block        firstLetter = new (renderArena()) RenderInline(document());
537868513a70bcd92384395513322f1b801e7bf9c729Steve Block    else
537968513a70bcd92384395513322f1b801e7bf9c729Steve Block        firstLetter = new (renderArena()) RenderBlock(document());
538068513a70bcd92384395513322f1b801e7bf9c729Steve Block    firstLetter->setStyle(pseudoStyle);
538168513a70bcd92384395513322f1b801e7bf9c729Steve Block    firstLetterContainer->addChild(firstLetter, currChild);
538268513a70bcd92384395513322f1b801e7bf9c729Steve Block
538368513a70bcd92384395513322f1b801e7bf9c729Steve Block    // The original string is going to be either a generated content string or a DOM node's
538468513a70bcd92384395513322f1b801e7bf9c729Steve Block    // string.  We want the original string before it got transformed in case first-letter has
538568513a70bcd92384395513322f1b801e7bf9c729Steve Block    // no text-transform or a different text-transform applied to it.
538668513a70bcd92384395513322f1b801e7bf9c729Steve Block    RefPtr<StringImpl> oldText = textObj->originalText();
538768513a70bcd92384395513322f1b801e7bf9c729Steve Block    ASSERT(oldText);
538868513a70bcd92384395513322f1b801e7bf9c729Steve Block
538968513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (oldText && oldText->length() > 0) {
539068513a70bcd92384395513322f1b801e7bf9c729Steve Block        unsigned length = 0;
539168513a70bcd92384395513322f1b801e7bf9c729Steve Block
5392a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // Account for leading spaces and punctuation.
5393a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        while (length < oldText->length() && shouldSkipForFirstLetter((*oldText)[length]))
53948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            length++;
53958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5396a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // Account for first letter.
539768513a70bcd92384395513322f1b801e7bf9c729Steve Block        length++;
5398a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
5399a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // Keep looking for whitespace and allowed punctuation, but avoid
5400a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // accumulating just whitespace into the :first-letter.
5401a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        for (unsigned scanLength = length; scanLength < oldText->length(); ++scanLength) {
5402a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            UChar c = (*oldText)[scanLength];
5403a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
5404a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (!shouldSkipForFirstLetter(c))
5405a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                break;
540668513a70bcd92384395513322f1b801e7bf9c729Steve Block
5407a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (isPunctuationForFirstLetter(c))
5408a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                length = scanLength + 1;
5409a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch         }
5410a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
5411a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // Construct a text fragment for the text after the first letter.
5412a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // This text fragment might be empty.
541368513a70bcd92384395513322f1b801e7bf9c729Steve Block        RenderTextFragment* remainingText =
541468513a70bcd92384395513322f1b801e7bf9c729Steve Block            new (renderArena()) RenderTextFragment(textObj->node() ? textObj->node() : textObj->document(), oldText.get(), length, oldText->length() - length);
541568513a70bcd92384395513322f1b801e7bf9c729Steve Block        remainingText->setStyle(textObj->style());
541668513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (remainingText->node())
541768513a70bcd92384395513322f1b801e7bf9c729Steve Block            remainingText->node()->setRenderer(remainingText);
541868513a70bcd92384395513322f1b801e7bf9c729Steve Block
5419ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        firstLetterContainer->addChild(remainingText, textObj);
542068513a70bcd92384395513322f1b801e7bf9c729Steve Block        firstLetterContainer->removeChild(textObj);
542168513a70bcd92384395513322f1b801e7bf9c729Steve Block        remainingText->setFirstLetter(firstLetter);
542268513a70bcd92384395513322f1b801e7bf9c729Steve Block
542368513a70bcd92384395513322f1b801e7bf9c729Steve Block        // construct text fragment for the first letter
542468513a70bcd92384395513322f1b801e7bf9c729Steve Block        RenderTextFragment* letter =
542568513a70bcd92384395513322f1b801e7bf9c729Steve Block            new (renderArena()) RenderTextFragment(remainingText->node() ? remainingText->node() : remainingText->document(), oldText.get(), 0, length);
542668513a70bcd92384395513322f1b801e7bf9c729Steve Block        letter->setStyle(pseudoStyle);
542768513a70bcd92384395513322f1b801e7bf9c729Steve Block        firstLetter->addChild(letter);
542868513a70bcd92384395513322f1b801e7bf9c729Steve Block
542968513a70bcd92384395513322f1b801e7bf9c729Steve Block        textObj->destroy();
54308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
543168513a70bcd92384395513322f1b801e7bf9c729Steve Block    view()->enableLayoutState();
54328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
54338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
54348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Helper methods for obtaining the last line, computing line counts and heights for line counts
54358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// (crawling into blocks).
54368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool shouldCheckLines(RenderObject* obj)
54378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5438635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return !obj->isFloatingOrPositioned() && !obj->isRunIn() &&
54398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            obj->isBlockFlow() && obj->style()->height().isAuto() &&
54408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            (!obj->isFlexibleBox() || obj->style()->boxOrient() == VERTICAL);
54418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
54428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
54438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic RootInlineBox* getLineAtIndex(RenderBlock* block, int i, int& count)
54448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
54458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (block->style()->visibility() == VISIBLE) {
54468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (block->childrenInline()) {
54478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) {
54488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (count++ == i)
54498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    return box;
54508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
54518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
54528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
54538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RenderObject* obj = block->firstChild(); obj; obj = obj->nextSibling()) {
54548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (shouldCheckLines(obj)) {
54558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    RootInlineBox *box = getLineAtIndex(toRenderBlock(obj), i, count);
54568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (box)
54578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        return box;
54588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
54598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
54608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
54618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
54628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
54638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
54648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5465635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic int getHeightForLineCount(RenderBlock* block, int l, bool includeBottom, int& count)
54668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
54678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (block->style()->visibility() == VISIBLE) {
54688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (block->childrenInline()) {
54698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) {
54708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (++count == l)
5471231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    return box->lineBottom() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : 0);
54728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
54738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
54748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
5475635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            RenderBox* normalFlowChildWithoutLines = 0;
5476635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            for (RenderBox* obj = block->firstChildBox(); obj; obj = obj->nextSiblingBox()) {
54778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (shouldCheckLines(obj)) {
54788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    int result = getHeightForLineCount(toRenderBlock(obj), l, false, count);
54798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (result != -1)
5480635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                        return result + obj->y() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : 0);
54818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
5482635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                else if (!obj->isFloatingOrPositioned() && !obj->isRunIn())
54838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    normalFlowChildWithoutLines = obj;
54848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
54858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (normalFlowChildWithoutLines && l == 0)
5486635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                return normalFlowChildWithoutLines->y() + normalFlowChildWithoutLines->height();
54878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
54888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
54898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
54908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return -1;
54918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
54928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
54938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRootInlineBox* RenderBlock::lineAtIndex(int i)
54948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
54958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int count = 0;
54968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return getLineAtIndex(this, i, count);
54978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
54988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
54998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderBlock::lineCount()
55008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
55018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int count = 0;
55028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->visibility() == VISIBLE) {
55038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (childrenInline())
55048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
55058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                count++;
55068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
55078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling())
55088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (shouldCheckLines(obj))
55098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    count += toRenderBlock(obj)->lineCount();
55108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
55118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return count;
55128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
55138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
55148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderBlock::heightForLineCount(int l)
55158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
55168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int count = 0;
55178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return getHeightForLineCount(this, l, true, count);
55188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
55198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
55208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::adjustForBorderFit(int x, int& left, int& right) const
55218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
55228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We don't deal with relative positioning.  Our assumption is that you shrink to fit the lines without accounting
55238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // for either overflow or translations via relative positioning.
55248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->visibility() == VISIBLE) {
55258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (childrenInline()) {
55268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) {
55278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (box->firstChild())
552881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    left = min(left, x + static_cast<int>(box->firstChild()->x()));
55298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (box->lastChild())
553081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    right = max(right, x + static_cast<int>(ceilf(box->lastChild()->logicalRight())));
55318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
55328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
55338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
5534635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            for (RenderBox* obj = firstChildBox(); obj; obj = obj->nextSiblingBox()) {
55358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!obj->isFloatingOrPositioned()) {
55368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (obj->isBlockFlow() && !obj->hasOverflowClip())
55378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        toRenderBlock(obj)->adjustForBorderFit(x + obj->x(), left, right);
55388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    else if (obj->style()->visibility() == VISIBLE) {
55398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // We are a replaced element or some kind of non-block-flow object.
5540635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                        left = min(left, x + obj->x());
5541635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                        right = max(right, x + obj->x() + obj->width());
55428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
55438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
55448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
55458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
55468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
55478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_floatingObjects) {
554881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
554981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObjectSetIterator end = floatingObjectSet.end();
555081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
555181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                FloatingObject* r = *it;
55528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Only examine the object if our m_shouldPaint flag is set.
55538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (r->m_shouldPaint) {
55542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    int floatLeft = xPositionForFloatIncludingMargin(r) - r->m_renderer->x();
55558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    int floatRight = floatLeft + r->m_renderer->width();
55568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    left = min(left, floatLeft);
55578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    right = max(right, floatRight);
55588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
55598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
55608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
55618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
55628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
55638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
55648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::borderFitAdjust(int& x, int& w) const
55658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
55668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->borderFit() == BorderFitBorder)
55678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
55688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
55698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Walk any normal flow lines to snugly fit.
55708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int left = INT_MAX;
55718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int right = INT_MIN;
55728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int oldWidth = w;
55738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    adjustForBorderFit(0, left, right);
55748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (left != INT_MAX) {
55758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        left -= (borderLeft() + paddingLeft());
55768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (left > 0) {
55778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            x += left;
55788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            w -= left;
55798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
55808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
55818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (right != INT_MIN) {
55828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        right += (borderRight() + paddingRight());
55838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (right < oldWidth)
55848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            w -= (oldWidth - right);
55858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
55868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
55878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
55888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::clearTruncation()
55898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
55908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->visibility() == VISIBLE) {
55918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (childrenInline() && hasMarkupTruncation()) {
55928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            setHasMarkupTruncation(false);
55938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
55948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                box->clearTruncation();
55958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
55968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
55978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling())
55988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (shouldCheckLines(obj))
55998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    toRenderBlock(obj)->clearTruncation();
56008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
56018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
56028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5603bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBlock::setMaxMarginBeforeValues(int pos, int neg)
56048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
560568513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!m_rareData) {
5606a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (pos == RenderBlockRareData::positiveMarginBeforeDefault(this) && neg == RenderBlockRareData::negativeMarginBeforeDefault(this))
56078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
560868513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_rareData = new RenderBlockRareData(this);
56098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5610a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_rareData->m_margins.setPositiveMarginBefore(pos);
5611a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_rareData->m_margins.setNegativeMarginBefore(neg);
56128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
56138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5614bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBlock::setMaxMarginAfterValues(int pos, int neg)
56158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
561668513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!m_rareData) {
5617a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (pos == RenderBlockRareData::positiveMarginAfterDefault(this) && neg == RenderBlockRareData::negativeMarginAfterDefault(this))
561868513a70bcd92384395513322f1b801e7bf9c729Steve Block            return;
561968513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_rareData = new RenderBlockRareData(this);
562068513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
5621a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_rareData->m_margins.setPositiveMarginAfter(pos);
5622a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_rareData->m_margins.setNegativeMarginAfter(neg);
562368513a70bcd92384395513322f1b801e7bf9c729Steve Block}
562468513a70bcd92384395513322f1b801e7bf9c729Steve Block
562568513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid RenderBlock::setPaginationStrut(int strut)
562668513a70bcd92384395513322f1b801e7bf9c729Steve Block{
562768513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!m_rareData) {
562868513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (!strut)
56298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
563068513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_rareData = new RenderBlockRareData(this);
56318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
563268513a70bcd92384395513322f1b801e7bf9c729Steve Block    m_rareData->m_paginationStrut = strut;
563368513a70bcd92384395513322f1b801e7bf9c729Steve Block}
563468513a70bcd92384395513322f1b801e7bf9c729Steve Block
5635f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderBlock::setPageLogicalOffset(int logicalOffset)
563668513a70bcd92384395513322f1b801e7bf9c729Steve Block{
563768513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!m_rareData) {
5638f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (!logicalOffset)
563968513a70bcd92384395513322f1b801e7bf9c729Steve Block            return;
564068513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_rareData = new RenderBlockRareData(this);
564168513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
5642f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    m_rareData->m_pageLogicalOffset = logicalOffset;
56438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
56448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
56455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid RenderBlock::absoluteRects(Vector<IntRect>& rects, int tx, int ty)
56468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
56478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // For blocks inside inlines, we go ahead and include margins so that we run right up to the
56488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // inline boxes above and below us (thus getting merged with them to form a single irregular
56498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // shape).
5650e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (isAnonymousBlockContinuation()) {
5651bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // FIXME: This is wrong for block-flows that are horizontal.
5652bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // https://bugs.webkit.org/show_bug.cgi?id=46781
5653bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        rects.append(IntRect(tx, ty - collapsedMarginBefore(),
5654bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                             width(), height() + collapsedMarginBefore() + collapsedMarginAfter()));
5655e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        continuation()->absoluteRects(rects,
5656e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block                                      tx - x() + inlineElementContinuation()->containingBlock()->x(),
5657e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block                                      ty - y() + inlineElementContinuation()->containingBlock()->y());
56588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    } else
56598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        rects.append(IntRect(tx, ty, width(), height()));
56608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
56618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
56625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid RenderBlock::absoluteQuads(Vector<FloatQuad>& quads)
56638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
56648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // For blocks inside inlines, we go ahead and include margins so that we run right up to the
56658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // inline boxes above and below us (thus getting merged with them to form a single irregular
56668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // shape).
5667e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (isAnonymousBlockContinuation()) {
5668bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // FIXME: This is wrong for block-flows that are horizontal.
5669bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // https://bugs.webkit.org/show_bug.cgi?id=46781
5670bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        FloatRect localRect(0, -collapsedMarginBefore(),
5671bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                            width(), height() + collapsedMarginBefore() + collapsedMarginAfter());
56728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        quads.append(localToAbsoluteQuad(localRect));
5673e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        continuation()->absoluteQuads(quads);
56748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    } else
56758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width(), height())));
56768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
56778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
56788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianIntRect RenderBlock::rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth)
56798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
56808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    IntRect r(RenderBox::rectWithOutlineForRepaint(repaintContainer, outlineWidth));
5681e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (isAnonymousBlockContinuation())
5682bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        r.inflateY(collapsedMarginBefore()); // FIXME: This is wrong for block-flows that are horizontal.
56838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return r;
56848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
56858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
56868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianRenderObject* RenderBlock::hoverAncestor() const
56878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
5688e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    return isAnonymousBlockContinuation() ? continuation() : RenderBox::hoverAncestor();
56898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
56908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
56918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::updateDragState(bool dragOn)
56928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
56938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBox::updateDragState(dragOn);
5694e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (continuation())
5695e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        continuation()->updateDragState(dragOn);
56968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
56978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
56988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianRenderStyle* RenderBlock::outlineStyleForRepaint() const
56998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
5700e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    return isAnonymousBlockContinuation() ? continuation()->style() : style();
57018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
57028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::childBecameNonInline(RenderObject*)
57048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
57058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    makeChildrenNonInline();
57068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (isAnonymousBlock() && parent() && parent()->isRenderBlock())
57078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
57088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // |this| may be dead here
57098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
57108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::updateHitTestResult(HitTestResult& result, const IntPoint& point)
57128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
57138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (result.innerNode())
57148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
57158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Node* n = node();
5717e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (isAnonymousBlockContinuation())
57188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // We are in the margins of block elements that are part of a continuation.  In
5719e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        // this case we're actually still inside the enclosing element that was
57208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // split.  Go ahead and set our inner node accordingly.
5721e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        n = continuation()->node();
57228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (n) {
57248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        result.setInnerNode(n);
57258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (!result.innerNonSharedNode())
57268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            result.setInnerNonSharedNode(n);
57278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        result.setLocalPoint(point);
57288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
57298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
57308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianIntRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, int* extraWidthToEndOfLine)
57328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
57338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Do the normal calculation in most cases.
57348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (firstChild())
57358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return RenderBox::localCaretRect(inlineBox, caretOffset, extraWidthToEndOfLine);
57368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // This is a special case:
57388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // The element is not an inline element, and it's empty. So we have to
57398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // calculate a fake position to indicate where objects are to be inserted.
57408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // FIXME: This does not take into account either :first-line or :first-letter
57428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // However, as soon as some content is entered, the line boxes will be
57438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // constructed and this kludge is not called any more. So only the caret size
57448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // of an empty :first-line'd block is wrong. I think we can live with that.
57458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderStyle* currentStyle = firstLineStyle();
5746a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int height = lineHeight(true, currentStyle->isHorizontalWritingMode() ? HorizontalLine : VerticalLine);
57478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    enum CaretAlignment { alignLeft, alignRight, alignCenter };
57498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    CaretAlignment alignment = alignLeft;
57518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    switch (currentStyle->textAlign()) {
57538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case TAAUTO:
57548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case JUSTIFY:
5755a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (!currentStyle->isLeftToRightDirection())
57568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                alignment = alignRight;
57578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
57588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case LEFT:
57598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case WEBKIT_LEFT:
57608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
57618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case CENTER:
57628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case WEBKIT_CENTER:
57638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            alignment = alignCenter;
57648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
57658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case RIGHT:
57668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case WEBKIT_RIGHT:
57678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            alignment = alignRight;
57688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
57692bde8e466a4451c7319e3a072d118917957d6554Steve Block        case TASTART:
57702bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (!currentStyle->isLeftToRightDirection())
57712bde8e466a4451c7319e3a072d118917957d6554Steve Block                alignment = alignRight;
57722bde8e466a4451c7319e3a072d118917957d6554Steve Block            break;
57732bde8e466a4451c7319e3a072d118917957d6554Steve Block        case TAEND:
57742bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (currentStyle->isLeftToRightDirection())
57752bde8e466a4451c7319e3a072d118917957d6554Steve Block                alignment = alignRight;
57762bde8e466a4451c7319e3a072d118917957d6554Steve Block            break;
57778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
57788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int x = borderLeft() + paddingLeft();
57808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int w = width();
57818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    switch (alignment) {
57838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case alignLeft:
57848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
57858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case alignCenter:
57868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            x = (x + w - (borderRight() + paddingRight())) / 2;
57878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
57888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case alignRight:
57895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            x = w - (borderRight() + paddingRight()) - caretWidth;
57908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
57918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
57928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (extraWidthToEndOfLine) {
57948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (isRenderBlock()) {
57958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            *extraWidthToEndOfLine = w - (x + caretWidth);
57968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else {
57978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // FIXME: This code looks wrong.
57988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // myRight and containerRight are set up, but then clobbered.
57998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // So *extraWidthToEndOfLine will always be 0 here.
58008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            int myRight = x + caretWidth;
58028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // FIXME: why call localToAbsoluteForContent() twice here, too?
58038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            FloatPoint absRightPoint = localToAbsolute(FloatPoint(myRight, 0));
58048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
5805bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            int containerRight = containingBlock()->x() + containingBlockLogicalWidthForContent();
58068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            FloatPoint absContainerPoint = localToAbsolute(FloatPoint(containerRight, 0));
58078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            *extraWidthToEndOfLine = absContainerPoint.x() - absRightPoint.x();
58098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
58108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
58118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int y = paddingTop() + borderTop();
58138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return IntRect(x, y, caretWidth, height);
58158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
58168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
5817d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid RenderBlock::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
58188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
58198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // For blocks inside inlines, we go ahead and include margins so that we run right up to the
58208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // inline boxes above and below us (thus getting merged with them to form a single irregular
58218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // shape).
5822e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (inlineElementContinuation()) {
58238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // FIXME: This check really isn't accurate.
5824e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        bool nextInlineHasLineBox = inlineElementContinuation()->firstLineBox();
58258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // FIXME: This is wrong. The principal renderer may not be the continuation preceding this block.
5826bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // FIXME: This is wrong for block-flows that are horizontal.
5827bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // https://bugs.webkit.org/show_bug.cgi?id=46781
5828e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        bool prevInlineHasLineBox = toRenderInline(inlineElementContinuation()->node()->renderer())->firstLineBox();
5829bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        int topMargin = prevInlineHasLineBox ? collapsedMarginBefore() : 0;
5830bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        int bottomMargin = nextInlineHasLineBox ? collapsedMarginAfter() : 0;
5831d0825bca7fe65beaee391d30da42e937db621564Steve Block        IntRect rect(tx, ty - topMargin, width(), height() + topMargin + bottomMargin);
5832d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (!rect.isEmpty())
5833d0825bca7fe65beaee391d30da42e937db621564Steve Block            rects.append(rect);
5834d0825bca7fe65beaee391d30da42e937db621564Steve Block    } else if (width() && height())
5835d0825bca7fe65beaee391d30da42e937db621564Steve Block        rects.append(IntRect(tx, ty, width(), height()));
58368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!hasOverflowClip() && !hasControlClip()) {
5838231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
583981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            int top = max(curr->lineTop(), curr->logicalTop());
584081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            int bottom = min(curr->lineBottom(), curr->logicalTop() + curr->logicalHeight());
5841bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            IntRect rect(tx + curr->x(), ty + top, curr->logicalWidth(), bottom - top);
5842d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (!rect.isEmpty())
5843d0825bca7fe65beaee391d30da42e937db621564Steve Block                rects.append(rect);
5844231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
58458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
58478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (!curr->isText() && !curr->isListMarker() && curr->isBox()) {
58488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                RenderBox* box = toRenderBox(curr);
58498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                FloatPoint pos;
58508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                // FIXME: This doesn't work correctly with transforms.
58518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if (box->layer())
58528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    pos = curr->localToAbsolute();
58538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                else
58548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    pos = FloatPoint(tx + box->x(), ty + box->y());
5855d0825bca7fe65beaee391d30da42e937db621564Steve Block                box->addFocusRingRects(rects, pos.x(), pos.y());
58568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
58578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
58588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
58598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
5860e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (inlineElementContinuation())
5861e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        inlineElementContinuation()->addFocusRingRects(rects,
5862e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block                                                       tx - x() + inlineElementContinuation()->containingBlock()->x(),
5863e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block                                                       ty - y() + inlineElementContinuation()->containingBlock()->y());
58648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
58658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
5866231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockRenderBlock* RenderBlock::createAnonymousBlock(bool isFlexibleBox) const
58678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
58682bde8e466a4451c7319e3a072d118917957d6554Steve Block    RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
58698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
5870231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    RenderBlock* newBox = 0;
5871231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (isFlexibleBox) {
5872231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        newStyle->setDisplay(BOX);
5873231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        newBox = new (renderArena()) RenderFlexibleBox(document() /* anonymous box */);
5874231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    } else {
5875231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        newStyle->setDisplay(BLOCK);
5876231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
5877231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
5878231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
58798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    newBox->setStyle(newStyle.release());
58808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return newBox;
58818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
58828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58835af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeRenderBlock* RenderBlock::createAnonymousBlockWithSameTypeAs(RenderBlock* otherAnonymousBlock) const
58845af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
58855af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (otherAnonymousBlock->isAnonymousColumnsBlock())
58865af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return createAnonymousColumnsBlock();
58875af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (otherAnonymousBlock->isAnonymousColumnSpanBlock())
58885af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return createAnonymousColumnSpanBlock();
58895af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return createAnonymousBlock(otherAnonymousBlock->style()->display() == BOX);
58905af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
58915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
58925af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeRenderBlock* RenderBlock::createAnonymousColumnsBlock() const
58935af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
58942bde8e466a4451c7319e3a072d118917957d6554Steve Block    RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
58955af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newStyle->inheritColumnPropertiesFrom(style());
58965af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newStyle->setDisplay(BLOCK);
58975af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
58985af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
58995af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newBox->setStyle(newStyle.release());
59005af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return newBox;
59015af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
59025af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
59035af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeRenderBlock* RenderBlock::createAnonymousColumnSpanBlock() const
59045af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
59052bde8e466a4451c7319e3a072d118917957d6554Steve Block    RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
59065af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newStyle->setColumnSpan(true);
59075af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newStyle->setDisplay(BLOCK);
59085af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
59095af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
59105af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newBox->setStyle(newStyle.release());
59115af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return newBox;
59125af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
59135af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
59142fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockint RenderBlock::nextPageLogicalTop(int logicalOffset) const
591568513a70bcd92384395513322f1b801e7bf9c729Steve Block{
591668513a70bcd92384395513322f1b801e7bf9c729Steve Block    LayoutState* layoutState = view()->layoutState();
5917f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!layoutState->m_pageLogicalHeight)
59182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return logicalOffset;
591968513a70bcd92384395513322f1b801e7bf9c729Steve Block
59202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // The logicalOffset is in our coordinate space.  We can add in our pushed offset.
5921f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int pageLogicalHeight = layoutState->m_pageLogicalHeight;
59222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
59232bde8e466a4451c7319e3a072d118917957d6554Steve Block    int offset = isHorizontalWritingMode() ? delta.height() : delta.width();
59242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight;
59252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return logicalOffset + remainingLogicalHeight;
592668513a70bcd92384395513322f1b801e7bf9c729Steve Block}
592768513a70bcd92384395513322f1b801e7bf9c729Steve Block
592868513a70bcd92384395513322f1b801e7bf9c729Steve Blockstatic bool inNormalFlow(RenderBox* child)
592968513a70bcd92384395513322f1b801e7bf9c729Steve Block{
593068513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderBlock* curr = child->containingBlock();
593168513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderBlock* initialBlock = child->view();
593268513a70bcd92384395513322f1b801e7bf9c729Steve Block    while (curr && curr != initialBlock) {
593368513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (curr->hasColumns())
593468513a70bcd92384395513322f1b801e7bf9c729Steve Block            return true;
593568513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (curr->isFloatingOrPositioned())
593668513a70bcd92384395513322f1b801e7bf9c729Steve Block            return false;
593768513a70bcd92384395513322f1b801e7bf9c729Steve Block        curr = curr->containingBlock();
593868513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
593968513a70bcd92384395513322f1b801e7bf9c729Steve Block    return true;
594068513a70bcd92384395513322f1b801e7bf9c729Steve Block}
594168513a70bcd92384395513322f1b801e7bf9c729Steve Block
59422fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockint RenderBlock::applyBeforeBreak(RenderBox* child, int logicalOffset)
594368513a70bcd92384395513322f1b801e7bf9c729Steve Block{
594468513a70bcd92384395513322f1b801e7bf9c729Steve Block    // FIXME: Add page break checking here when we support printing.
594568513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
5946f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
594768513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool checkBeforeAlways = (checkColumnBreaks && child->style()->columnBreakBefore() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakBefore() == PBALWAYS);
594868513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (checkBeforeAlways && inNormalFlow(child)) {
594968513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (checkColumnBreaks)
59502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            view()->layoutState()->addForcedColumnBreak(logicalOffset);
59512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return nextPageLogicalTop(logicalOffset);
595268513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
59532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return logicalOffset;
595468513a70bcd92384395513322f1b801e7bf9c729Steve Block}
595568513a70bcd92384395513322f1b801e7bf9c729Steve Block
59562fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockint RenderBlock::applyAfterBreak(RenderBox* child, int logicalOffset, MarginInfo& marginInfo)
595768513a70bcd92384395513322f1b801e7bf9c729Steve Block{
595868513a70bcd92384395513322f1b801e7bf9c729Steve Block    // FIXME: Add page break checking here when we support printing.
595968513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
5960f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
596168513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool checkAfterAlways = (checkColumnBreaks && child->style()->columnBreakAfter() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakAfter() == PBALWAYS);
596268513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (checkAfterAlways && inNormalFlow(child)) {
5963bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        marginInfo.setMarginAfterQuirk(true); // Cause margins to be discarded for any following content.
596468513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (checkColumnBreaks)
59652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            view()->layoutState()->addForcedColumnBreak(logicalOffset);
59662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return nextPageLogicalTop(logicalOffset);
596768513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
59682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return logicalOffset;
596968513a70bcd92384395513322f1b801e7bf9c729Steve Block}
597068513a70bcd92384395513322f1b801e7bf9c729Steve Block
59712fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockint RenderBlock::adjustForUnsplittableChild(RenderBox* child, int logicalOffset, bool includeMargins)
597268513a70bcd92384395513322f1b801e7bf9c729Steve Block{
597368513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool isUnsplittable = child->isReplaced() || child->scrollsOverflow();
597468513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!isUnsplittable)
59752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return logicalOffset;
59762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int childLogicalHeight = logicalHeightForChild(child) + (includeMargins ? marginBeforeForChild(child) + marginAfterForChild(child) : 0);
597768513a70bcd92384395513322f1b801e7bf9c729Steve Block    LayoutState* layoutState = view()->layoutState();
597868513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (layoutState->m_columnInfo)
59792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        layoutState->m_columnInfo->updateMinimumColumnHeight(childLogicalHeight);
5980f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int pageLogicalHeight = layoutState->m_pageLogicalHeight;
59812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!pageLogicalHeight || childLogicalHeight > pageLogicalHeight)
59822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return logicalOffset;
59832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
59842bde8e466a4451c7319e3a072d118917957d6554Steve Block    int offset = isHorizontalWritingMode() ? delta.height() : delta.width();
59852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight;
59862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (remainingLogicalHeight < childLogicalHeight)
59872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return logicalOffset + remainingLogicalHeight;
59882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return logicalOffset;
598968513a70bcd92384395513322f1b801e7bf9c729Steve Block}
599068513a70bcd92384395513322f1b801e7bf9c729Steve Block
599168513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, int& delta)
599268513a70bcd92384395513322f1b801e7bf9c729Steve Block{
599368513a70bcd92384395513322f1b801e7bf9c729Steve Block    // FIXME: For now we paginate using line overflow.  This ensures that lines don't overlap at all when we
599468513a70bcd92384395513322f1b801e7bf9c729Steve Block    // put a strut between them for pagination purposes.  However, this really isn't the desired rendering, since
599568513a70bcd92384395513322f1b801e7bf9c729Steve Block    // the line on the top of the next page will appear too far down relative to the same kind of line at the top
599668513a70bcd92384395513322f1b801e7bf9c729Steve Block    // of the first column.
599768513a70bcd92384395513322f1b801e7bf9c729Steve Block    //
599868513a70bcd92384395513322f1b801e7bf9c729Steve Block    // The rendering we would like to see is one where the lineTop is at the top of the column, and any line overflow
599968513a70bcd92384395513322f1b801e7bf9c729Steve Block    // simply spills out above the top of the column.  This effect would match what happens at the top of the first column.
600068513a70bcd92384395513322f1b801e7bf9c729Steve Block    // We can't achieve this rendering, however, until we stop columns from clipping to the column bounds (thus allowing
600168513a70bcd92384395513322f1b801e7bf9c729Steve Block    // for overflow to occur), and then cache visible overflow for each column rect.
600268513a70bcd92384395513322f1b801e7bf9c729Steve Block    //
600368513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Furthermore, the paint we have to do when a column has overflow has to be special.  We need to exclude
600468513a70bcd92384395513322f1b801e7bf9c729Steve Block    // content that paints in a previous column (and content that paints in the following column).
600568513a70bcd92384395513322f1b801e7bf9c729Steve Block    //
600668513a70bcd92384395513322f1b801e7bf9c729Steve Block    // FIXME: Another problem with simply moving lines is that the available line width may change (because of floats).
600768513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Technically if the location we move the line to has a different line width than our old position, then we need to dirty the
600868513a70bcd92384395513322f1b801e7bf9c729Steve Block    // line and all following lines.
600968513a70bcd92384395513322f1b801e7bf9c729Steve Block    LayoutState* layoutState = view()->layoutState();
6010f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int pageLogicalHeight = layoutState->m_pageLogicalHeight;
60112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    IntRect logicalVisualOverflow = lineBox->logicalVisualOverflowRect(lineBox->lineTop(), lineBox->lineBottom());
60122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    int logicalOffset = logicalVisualOverflow.y();
60132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    int lineHeight = logicalVisualOverflow.maxY() - logicalOffset;
601468513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (layoutState->m_columnInfo)
601568513a70bcd92384395513322f1b801e7bf9c729Steve Block        layoutState->m_columnInfo->updateMinimumColumnHeight(lineHeight);
60162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    logicalOffset += delta;
601768513a70bcd92384395513322f1b801e7bf9c729Steve Block    lineBox->setPaginationStrut(0);
6018f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!pageLogicalHeight || lineHeight > pageLogicalHeight)
601968513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
60202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    IntSize offsetDelta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
60212bde8e466a4451c7319e3a072d118917957d6554Steve Block    int offset = isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width();
60222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int remainingLogicalHeight = pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight;
60232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (remainingLogicalHeight < lineHeight) {
60242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int totalLogicalHeight = lineHeight + max(0, logicalOffset);
60252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (lineBox == firstRootBox() && totalLogicalHeight < pageLogicalHeight && !isPositioned() && !isTableCell())
60262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            setPaginationStrut(remainingLogicalHeight + max(0, logicalOffset));
602768513a70bcd92384395513322f1b801e7bf9c729Steve Block        else {
60282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            delta += remainingLogicalHeight;
60292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            lineBox->setPaginationStrut(remainingLogicalHeight);
603068513a70bcd92384395513322f1b801e7bf9c729Steve Block        }
603168513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
603268513a70bcd92384395513322f1b801e7bf9c729Steve Block}
6033a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6034a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::collapsedMarginBeforeForChild(RenderBox* child) const
6035a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
6036a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // If the child has the same directionality as we do, then we can just return its
6037a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // collapsed margin.
6038a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!child->isWritingModeRoot())
6039a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->collapsedMarginBefore();
6040a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6041a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // The child has a different directionality.  If the child is parallel, then it's just
6042a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // flipped relative to us.  We can use the collapsed margin for the opposite edge.
60432bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
6044a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->collapsedMarginAfter();
6045a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6046a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // The child is perpendicular to us, which means its margins don't collapse but are on the
6047a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // "logical left/right" sides of the child box.  We can just return the raw margin in this case.
6048a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return marginBeforeForChild(child);
6049a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6050a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6051a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::collapsedMarginAfterForChild(RenderBox* child) const
6052a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
6053a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // If the child has the same directionality as we do, then we can just return its
6054a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // collapsed margin.
6055a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!child->isWritingModeRoot())
6056a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->collapsedMarginAfter();
6057a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6058a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // The child has a different directionality.  If the child is parallel, then it's just
6059a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // flipped relative to us.  We can use the collapsed margin for the opposite edge.
60602bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
6061a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->collapsedMarginBefore();
6062a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6063a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // The child is perpendicular to us, which means its margins don't collapse but are on the
6064a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // "logical left/right" side of the child box.  We can just return the raw margin in this case.
6065a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return marginAfterForChild(child);
6066a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6067a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6068a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::marginBeforeForChild(RenderBoxModelObject* child) const
6069a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
6070a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    switch (style()->writingMode()) {
6071a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case TopToBottomWritingMode:
6072a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginTop();
6073a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case BottomToTopWritingMode:
6074a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginBottom();
6075a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case LeftToRightWritingMode:
6076a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginLeft();
6077a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case RightToLeftWritingMode:
6078a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginRight();
6079a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6080a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ASSERT_NOT_REACHED();
6081a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return child->marginTop();
6082a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6083a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6084a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::marginAfterForChild(RenderBoxModelObject* child) const
6085a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
6086a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    switch (style()->writingMode()) {
6087a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case TopToBottomWritingMode:
6088a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginBottom();
6089a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case BottomToTopWritingMode:
6090a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginTop();
6091a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case LeftToRightWritingMode:
6092a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginRight();
6093a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case RightToLeftWritingMode:
6094a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginLeft();
6095a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6096a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ASSERT_NOT_REACHED();
6097a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return child->marginBottom();
6098a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6099a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6100a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::marginStartForChild(RenderBoxModelObject* child) const
6101a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
61022bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
6103a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return style()->isLeftToRightDirection() ? child->marginLeft() : child->marginRight();
6104a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return style()->isLeftToRightDirection() ? child->marginTop() : child->marginBottom();
6105a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6106a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6107a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::marginEndForChild(RenderBoxModelObject* child) const
6108a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
61092bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
6110a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return style()->isLeftToRightDirection() ? child->marginRight() : child->marginLeft();
6111a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return style()->isLeftToRightDirection() ? child->marginBottom() : child->marginTop();
6112a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6113a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6114a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setMarginStartForChild(RenderBox* child, int margin)
6115a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
61162bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode()) {
6117a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->isLeftToRightDirection())
6118a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginLeft(margin);
6119a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
6120a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginRight(margin);
6121a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else {
6122a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->isLeftToRightDirection())
6123a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginTop(margin);
6124a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
6125a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginBottom(margin);
6126a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6127a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6128a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6129a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setMarginEndForChild(RenderBox* child, int margin)
6130a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
61312bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode()) {
6132a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->isLeftToRightDirection())
6133a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginRight(margin);
6134a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
6135a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginLeft(margin);
6136a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else {
6137a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->isLeftToRightDirection())
6138a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginBottom(margin);
6139a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
6140a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginTop(margin);
6141a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6142a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6143a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6144a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setMarginBeforeForChild(RenderBox* child, int margin)
6145a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
6146a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    switch (style()->writingMode()) {
6147a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case TopToBottomWritingMode:
6148a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginTop(margin);
6149a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6150a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case BottomToTopWritingMode:
6151a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginBottom(margin);
6152a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6153a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case LeftToRightWritingMode:
6154a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginLeft(margin);
6155a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6156a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case RightToLeftWritingMode:
6157a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginRight(margin);
6158a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6159a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6160a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6161a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6162a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setMarginAfterForChild(RenderBox* child, int margin)
6163a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
6164a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    switch (style()->writingMode()) {
6165a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case TopToBottomWritingMode:
6166a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginBottom(margin);
6167a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6168a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case BottomToTopWritingMode:
6169a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginTop(margin);
6170a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6171a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case LeftToRightWritingMode:
6172a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginRight(margin);
6173a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6174a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case RightToLeftWritingMode:
6175a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginLeft(margin);
6176a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6177a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6178a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6179a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6180a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochRenderBlock::MarginValues RenderBlock::marginValuesForChild(RenderBox* child)
6181a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
6182a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int childBeforePositive = 0;
6183a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int childBeforeNegative = 0;
6184a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int childAfterPositive = 0;
6185a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int childAfterNegative = 0;
6186a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6187a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int beforeMargin = 0;
6188a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int afterMargin = 0;
6189a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6190a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0;
6191a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6192a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // If the child has the same directionality as we do, then we can just return its
6193a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // margins in the same direction.
6194a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!child->isWritingModeRoot()) {
6195a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (childRenderBlock) {
6196a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBeforePositive = childRenderBlock->maxPositiveMarginBefore();
6197a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBeforeNegative = childRenderBlock->maxNegativeMarginBefore();
6198a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childAfterPositive = childRenderBlock->maxPositiveMarginAfter();
6199a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childAfterNegative = childRenderBlock->maxNegativeMarginAfter();
6200a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        } else {
6201a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            beforeMargin = child->marginBefore();
6202a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            afterMargin = child->marginAfter();
6203a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
62042bde8e466a4451c7319e3a072d118917957d6554Steve Block    } else if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) {
6205a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // The child has a different directionality.  If the child is parallel, then it's just
6206a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // flipped relative to us.  We can use the margins for the opposite edges.
6207a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (childRenderBlock) {
6208a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBeforePositive = childRenderBlock->maxPositiveMarginAfter();
6209a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBeforeNegative = childRenderBlock->maxNegativeMarginAfter();
6210a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childAfterPositive = childRenderBlock->maxPositiveMarginBefore();
6211a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childAfterNegative = childRenderBlock->maxNegativeMarginBefore();
6212a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        } else {
6213a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            beforeMargin = child->marginAfter();
6214a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            afterMargin = child->marginBefore();
6215a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
6216a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else {
6217a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // The child is perpendicular to us, which means its margins don't collapse but are on the
6218a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // "logical left/right" sides of the child box.  We can just return the raw margin in this case.
6219a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        beforeMargin = marginBeforeForChild(child);
6220a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        afterMargin = marginAfterForChild(child);
6221a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6222a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6223a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Resolve uncollapsing margins into their positive/negative buckets.
6224a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (beforeMargin) {
6225a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (beforeMargin > 0)
6226a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBeforePositive = beforeMargin;
6227a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
6228a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBeforeNegative = -beforeMargin;
6229a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6230a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (afterMargin) {
6231a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (afterMargin > 0)
6232a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childAfterPositive = afterMargin;
6233a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
6234a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childAfterNegative = -afterMargin;
6235a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6236a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6237a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return MarginValues(childBeforePositive, childBeforeNegative, childAfterPositive, childAfterNegative);
6238a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6239a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
62408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst char* RenderBlock::renderName() const
62418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
62428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isBody())
62438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "RenderBody"; // FIXME: Temporary hack until we know that the regression tests pass.
62448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
62458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isFloating())
62468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "RenderBlock (floating)";
62478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isPositioned())
62488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "RenderBlock (positioned)";
62495af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (isAnonymousColumnsBlock())
62505af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return "RenderBlock (anonymous multi-column)";
62515af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (isAnonymousColumnSpanBlock())
62525af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return "RenderBlock (anonymous multi-column span)";
62538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isAnonymousBlock())
62548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "RenderBlock (anonymous)";
62558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (isAnonymous())
62568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "RenderBlock (generated)";
62578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isRelPositioned())
62588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "RenderBlock (relative positioned)";
62598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isRunIn())
62608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "RenderBlock (run-in)";
62618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return "RenderBlock";
62628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
62638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
626481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline void RenderBlock::FloatingObjects::clear()
626581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
626681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_set.clear();
626781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_leftObjectsCount = 0;
626881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_rightObjectsCount = 0;
626981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
627081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
627181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline void RenderBlock::FloatingObjects::increaseObjectsCount(FloatingObject::Type type)
627281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
627381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (type == FloatingObject::FloatLeft)
627481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_leftObjectsCount++;
627581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    else
627681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_rightObjectsCount++;
627781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
627881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
627981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline void RenderBlock::FloatingObjects::decreaseObjectsCount(FloatingObject::Type type)
628081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
628181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (type == FloatingObject::FloatLeft)
628281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_leftObjectsCount--;
628381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    else
628481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_rightObjectsCount--;
628581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
628681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
62878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
6288