RenderBlock.cpp revision b52229f8ad5e8b3632305005e437104c11eba942
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
8454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Blockbool RenderBlock::s_canPropagateFloatIntoSibling = false;
8554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Our MarginInfo state used when laying out block children.
87bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenRenderBlock::MarginInfo::MarginInfo(RenderBlock* block, int beforeBorderPadding, int afterBorderPadding)
88bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    : m_atBeforeSideOfBlock(true)
89bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    , m_atAfterSideOfBlock(false)
90bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    , m_marginBeforeQuirk(false)
91bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    , m_marginAfterQuirk(false)
92bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    , m_determinedMarginBeforeQuirk(false)
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Whether or not we can collapse our own margins with our children.  We don't do this
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // if we had any border/padding (obviously), if we're the root or HTML elements, or if
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // we're positioned, floating, a table cell.
97bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_canCollapseWithChildren = !block->isRenderView() && !block->isRoot() && !block->isPositioned()
98bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        && !block->isFloating() && !block->isTableCell() && !block->hasOverflowClip() && !block->isInlineBlockOrInlineTable()
99a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        && !block->isWritingModeRoot();
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
101bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_canCollapseMarginBeforeWithChildren = m_canCollapseWithChildren && (beforeBorderPadding == 0) && block->style()->marginBeforeCollapse() != MSEPARATE;
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If any height other than auto is specified in CSS, then we don't collapse our bottom
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // margins with our children's margins.  To do otherwise would be to risk odd visual
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // effects when the children overflow out of the parent block and yet still collapse
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // with it.  We also don't collapse if we have any bottom border/padding.
107bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_canCollapseMarginAfterWithChildren = m_canCollapseWithChildren && (afterBorderPadding == 0) &&
108bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        (block->style()->logicalHeight().isAuto() && block->style()->logicalHeight().value() == 0) && block->style()->marginAfterCollapse() != MSEPARATE;
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
110bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_quirkContainer = block->isTableCell() || block->isBody() || block->style()->marginBeforeCollapse() == MDISCARD ||
111bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        block->style()->marginAfterCollapse() == MDISCARD;
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
113a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_positiveMargin = m_canCollapseMarginBeforeWithChildren ? block->maxPositiveMarginBefore() : 0;
114a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_negativeMargin = m_canCollapseMarginBeforeWithChildren ? block->maxNegativeMarginBefore() : 0;
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// -------------------------------------------------------------------------------------------------------
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderBlock::RenderBlock(Node* node)
1208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian      : RenderBox(node)
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project      , m_floatingObjects(0)
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project      , m_positionedObjects(0)
12368513a70bcd92384395513322f1b801e7bf9c729Steve Block      , m_rareData(0)
1248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian      , m_lineHeight(-1)
12565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch      , m_beingDestroyed(false)
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    setChildrenInline(true);
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderBlock::~RenderBlock()
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_floatingObjects)
13381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        deleteAllValues(m_floatingObjects->set());
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (hasColumns())
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        delete gColumnInfoMap->take(this);
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (gPercentHeightDescendantsMap) {
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->take(this)) {
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            HashSet<RenderBox*>::iterator end = descendantSet->end();
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (HashSet<RenderBox*>::iterator descendant = descendantSet->begin(); descendant != end; ++descendant) {
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(*descendant);
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                ASSERT(containerSet);
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!containerSet)
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                ASSERT(containerSet->contains(this));
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                containerSet->remove(this);
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (containerSet->isEmpty()) {
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    gPercentHeightContainerMap->remove(*descendant);
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    delete containerSet;
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            delete descendantSet;
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::destroy()
1598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
16065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // Mark as being destroyed to avoid trouble with merges in removeChild().
16165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_beingDestroyed = true;
16265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
163643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
164643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
165643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    children()->destroyLeftoverChildren();
1668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
167643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // Destroy our continuation before anything other than anonymous children.
168643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // The reason we don't destroy it before anonymous children is that they may
169643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // have continuations of their own that are anonymous children of our continuation.
170cad810f21b803229eb11403f9209855525a25d57Steve Block    RenderBoxModelObject* continuation = this->continuation();
171cad810f21b803229eb11403f9209855525a25d57Steve Block    if (continuation) {
172cad810f21b803229eb11403f9209855525a25d57Steve Block        continuation->destroy();
173cad810f21b803229eb11403f9209855525a25d57Steve Block        setContinuation(0);
174643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
175643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
1768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!documentBeingDestroyed()) {
1778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (firstLineBox()) {
1788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // We can't wait for RenderBox::destroy to clear the selection,
1798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // because by then we will have nuked the line boxes.
1808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // FIXME: The SelectionController should be responsible for this when it
1818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // is notified of DOM mutations.
1828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (isSelectionBorder())
1838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                view()->clearSelection();
1848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // If we are an anonymous block, then our line boxes might have children
1868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // that will outlast this block. In the non-anonymous block case those
1878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // children will be destroyed by the time we return from this function.
1888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (isAnonymousBlock()) {
189dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox()) {
1908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    while (InlineBox* childBox = box->firstChild())
1918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        childBox->remove();
1928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                }
1938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
194c9773ed4ca308bb2b8e70f49ba7fbaa35b1f46a2Steve Block        } else if (parent())
1958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            parent()->dirtyLinesFromChangedChild(this);
1968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_lineBoxes.deleteLineBoxes(renderArena());
1998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBox::destroy();
2018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
2028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
20554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    s_canPropagateFloatIntoSibling = style() ? !isFloatingOrPositioned() && !avoidsFloats() : false;
20654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
20765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    setReplaced(newStyle->isDisplayInlineType());
208635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
2098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (style() && parent() && diff == StyleDifferenceLayout && style()->position() != newStyle->position()) {
210635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (newStyle->position() == StaticPosition)
211635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // Clear our positioned objects list. Our absolutely positioned descendants will be
212635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // inserted into our containing block's positioned objects list during layout.
213635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            removePositionedObjects(0);
214635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        else if (style()->position() == StaticPosition) {
215635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // Remove our absolutely positioned descendants from their current containing block.
216635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // They will be inserted into our positioned objects list during layout.
217635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            RenderObject* cb = parent();
218635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            while (cb && (cb->style()->position() == StaticPosition || (cb->isInline() && !cb->isReplaced())) && !cb->isRenderView()) {
219635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (cb->style()->position() == RelativePosition && cb->isInline() && !cb->isReplaced()) {
220635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    cb = cb->containingBlock();
221635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    break;
222635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                }
223635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                cb = cb->parent();
224635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
225635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
226635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (cb->isRenderBlock())
2278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                toRenderBlock(cb)->removePositionedObjects(this);
228635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
229383cc12851b723ebdaf6dddc7cb16d62cf7c7c7eSteve Block
230383cc12851b723ebdaf6dddc7cb16d62cf7c7c7eSteve Block        if (containsFloats() && !isFloating() && !isPositioned() && (newStyle->position() == AbsolutePosition || newStyle->position() == FixedPosition))
231383cc12851b723ebdaf6dddc7cb16d62cf7c7c7eSteve Block            markAllDescendantsWithFloatsForLayout();
232635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
233635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
2348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBox::styleWillChange(diff, newStyle);
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBox::styleDidChange(diff, oldStyle);
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
241545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (!isAnonymousBlock()) {
242545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // Ensure that all of our continuation blocks pick up the new style.
243545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        for (RenderBlock* currCont = blockElementContinuation(); currCont; currCont = currCont->blockElementContinuation()) {
244545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            RenderBoxModelObject* nextCont = currCont->continuation();
245545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            currCont->setContinuation(0);
246545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            currCont->setStyle(style());
247545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            currCont->setContinuation(nextCont);
248545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        }
249545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
250545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: We could save this call when the change only affected non-inherited properties
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (child->isAnonymousBlock()) {
2542bde8e466a4451c7319e3a072d118917957d6554Steve Block            RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
2555af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            if (style()->specifiesColumns()) {
2565af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                if (child->style()->specifiesColumns())
2575af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                    newStyle->inheritColumnPropertiesFrom(style());
2585af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                if (child->style()->columnSpan())
2595af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                    newStyle->setColumnSpan(true);
2605af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            }
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            newStyle->setDisplay(BLOCK);
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            child->setStyle(newStyle.release());
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_lineHeight = -1;
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Update pseudos for :before and :after now.
269635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!isAnonymous() && document()->usesBeforeAfterRules() && canHaveChildren()) {
2708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        updateBeforeAfterContent(BEFORE);
2718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        updateBeforeAfterContent(AFTER);
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
27354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
27454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    // After our style changed, if we lose our ability to propagate floats into next sibling
2754fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block    // blocks, then we need to find the top most parent containing that overhanging float and
2764fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block    // then mark its descendants with floats for layout and clear all floats from its next
2774fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block    // sibling blocks that exist in our floating objects list. See bug 56299 and 62875.
27854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    bool canPropagateFloatIntoSibling = !isFloatingOrPositioned() && !avoidsFloats();
27954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    if (diff == StyleDifferenceLayout && s_canPropagateFloatIntoSibling && !canPropagateFloatIntoSibling && hasOverhangingFloats()) {
2804fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block        RenderBlock* parentBlock = this;
2814fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2824fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block        FloatingObjectSetIterator end = floatingObjectSet.end();
2834fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block
2844fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block        for (RenderObject* curr = parent(); curr && !curr->isRenderView(); curr = curr->parent()) {
2854fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block            if (curr->isRenderBlock()) {
2864fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block                RenderBlock* currBlock = toRenderBlock(curr);
2874fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block
2884fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block                if (currBlock->hasOverhangingFloats()) {
2894fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block                    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
2904fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block                        RenderBox* renderer = (*it)->renderer();
2914fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block                        if (currBlock->hasOverhangingFloat(renderer)) {
2924fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block                            parentBlock = currBlock;
2934fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block                            break;
2944fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block                        }
2954fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block                    }
2964fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block                }
2974fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block            }
2984fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block        }
2994fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block
3004fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block        parentBlock->markAllDescendantsWithFloatsForLayout();
3014fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block        parentBlock->markSiblingsWithFloatsForLayout();
30254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    }
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::updateBeforeAfterContent(PseudoId pseudoId)
3068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
3078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If this is an anonymous wrapper, then the parent applies its own pseudo-element style to it.
3088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (parent() && parent()->createsAnonymousWrapper())
3098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
3108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return children()->updateBeforeAfterContent(this, pseudoId);
3118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
3125af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
313545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRenderBlock* RenderBlock::continuationBefore(RenderObject* beforeChild)
314545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
315545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (beforeChild && beforeChild->parent() == this)
316545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return this;
317545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
318545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBlock* curr = toRenderBlock(continuation());
319545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBlock* nextToLast = this;
320545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBlock* last = this;
321545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    while (curr) {
322545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (beforeChild && beforeChild->parent() == curr) {
323545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            if (curr->firstChild() == beforeChild)
324545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                return last;
325545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            return curr;
326545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        }
327545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
328545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        nextToLast = last;
329545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        last = curr;
330545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        curr = toRenderBlock(curr->continuation());
331545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
332545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
333545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (!beforeChild && !last->firstChild())
334545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return nextToLast;
335545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return last;
336545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
337545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
338545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid RenderBlock::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild)
339545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
340545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBlock* flow = continuationBefore(beforeChild);
341545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    ASSERT(!beforeChild || beforeChild->parent()->isAnonymousColumnSpanBlock() || beforeChild->parent()->isRenderBlock());
342545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBoxModelObject* beforeChildParent = 0;
343545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (beforeChild)
344545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        beforeChildParent = toRenderBoxModelObject(beforeChild->parent());
345545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    else {
346545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        RenderBoxModelObject* cont = flow->continuation();
347545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (cont)
348545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            beforeChildParent = cont;
349545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        else
350545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            beforeChildParent = flow;
351545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
352545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
353545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (newChild->isFloatingOrPositioned())
354545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
355545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
356545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // A continuation always consists of two potential candidates: a block or an anonymous
357545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // column span box holding column span children.
358545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    bool childIsNormal = newChild->isInline() || !newChild->style()->columnSpan();
359545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    bool bcpIsNormal = beforeChildParent->isInline() || !beforeChildParent->style()->columnSpan();
360545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    bool flowIsNormal = flow->isInline() || !flow->style()->columnSpan();
361545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
362545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (flow == beforeChildParent)
363545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return flow->addChildIgnoringContinuation(newChild, beforeChild);
364545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
365545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // The goal here is to match up if we can, so that we can coalesce and create the
366545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // minimal # of continuations needed for the inline.
367545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (childIsNormal == bcpIsNormal)
368545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
369545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (flowIsNormal == childIsNormal)
370545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return flow->addChildIgnoringContinuation(newChild, 0); // Just treat like an append.
371545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
372545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
373545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
374545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
3755af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
3765af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
3775af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    ASSERT(!continuation()); // We don't yet support column spans that aren't immediate children of the multi-column block.
3785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
3795af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // The goal is to locate a suitable box in which to place our child.
380bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    RenderBlock* beforeChildParent = toRenderBlock(beforeChild && beforeChild->parent()->isRenderBlock() ? beforeChild->parent() : lastChild());
3818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3825af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // If the new child is floating or positioned it can just go in that block.
3835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (newChild->isFloatingOrPositioned())
3845af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
3855af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
3865af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // See if the child can be placed in the box.
3875af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    bool newChildHasColumnSpan = newChild->style()->columnSpan() && !newChild->isInline();
3885af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    bool beforeChildParentHoldsColumnSpans = beforeChildParent->isAnonymousColumnSpanBlock();
3895af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
3905af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (newChildHasColumnSpan == beforeChildParentHoldsColumnSpans)
3915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
3925af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
3935af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (!beforeChild) {
3945af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        // Create a new block of the correct type.
3955af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
3965af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        children()->appendChildNode(this, newBox);
3975af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
3985af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return;
3995af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    }
4005af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
4015af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderObject* immediateChild = beforeChild;
4025af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    bool isPreviousBlockViable = true;
4035af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    while (immediateChild->parent() != this) {
4045af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (isPreviousBlockViable)
4055af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            isPreviousBlockViable = !immediateChild->previousSibling();
4065af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        immediateChild = immediateChild->parent();
4075af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    }
4085af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (isPreviousBlockViable && immediateChild->previousSibling())
4095af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return toRenderBlock(immediateChild->previousSibling())->addChildIgnoringAnonymousColumnBlocks(newChild, 0); // Treat like an append.
4105af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
4115af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // Split our anonymous blocks.
4125af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderObject* newBeforeChild = splitAnonymousBlocksAroundChild(beforeChild);
4135af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
4145af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // Create a new anonymous box of the appropriate type.
4155af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
4165af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    children()->insertChildNode(this, newBox, newBeforeChild);
4175af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
4185af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return;
4195af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
4205af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
421545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRenderBlock* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBlock)
422545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
423545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    for (RenderObject* curr = this; curr; curr = curr->parent()) {
424545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (!curr->isRenderBlock() || curr->isFloatingOrPositioned() || curr->isTableCell() || curr->isRoot() || curr->isRenderView() || curr->hasOverflowClip()
425545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            || curr->isInlineBlockOrInlineTable())
426545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            return 0;
427545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
428545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        RenderBlock* currBlock = toRenderBlock(curr);
429545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (currBlock->style()->specifiesColumns() && (allowAnonymousColumnBlock || !currBlock->isAnonymousColumnsBlock()))
430545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            return currBlock;
431545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
432545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (currBlock->isAnonymousColumnSpanBlock())
433545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            return 0;
434545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
435545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return 0;
436545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
437545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
438545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRenderBlock* RenderBlock::clone() const
439545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
440cad810f21b803229eb11403f9209855525a25d57Steve Block    RenderBlock* cloneBlock;
441cad810f21b803229eb11403f9209855525a25d57Steve Block    if (isAnonymousBlock())
442cad810f21b803229eb11403f9209855525a25d57Steve Block        cloneBlock = createAnonymousBlock();
443cad810f21b803229eb11403f9209855525a25d57Steve Block    else {
444cad810f21b803229eb11403f9209855525a25d57Steve Block        cloneBlock = new (renderArena()) RenderBlock(node());
445cad810f21b803229eb11403f9209855525a25d57Steve Block        cloneBlock->setStyle(style());
446b52229f8ad5e8b3632305005e437104c11eba942Steve Block        if (!childrenInline() && cloneBlock->firstChild() && cloneBlock->firstChild()->isInline())
447b52229f8ad5e8b3632305005e437104c11eba942Steve Block            cloneBlock->makeChildrenNonInline();
448cad810f21b803229eb11403f9209855525a25d57Steve Block    }
449cad810f21b803229eb11403f9209855525a25d57Steve Block    cloneBlock->setChildrenInline(childrenInline());
450cad810f21b803229eb11403f9209855525a25d57Steve Block    return cloneBlock;
451545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
452545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
453545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
454545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                              RenderBlock* middleBlock,
455545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                              RenderObject* beforeChild, RenderBoxModelObject* oldCont)
456545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
457545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Create a clone of this inline.
458cad810f21b803229eb11403f9209855525a25d57Steve Block    RenderBlock* cloneBlock = clone();
459cad810f21b803229eb11403f9209855525a25d57Steve Block    if (!isAnonymousBlock())
4604a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        cloneBlock->setContinuation(oldCont);
461545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
462545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Now take all of the children from beforeChild to the end and remove
463545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // them from |this| and place them in the clone.
464545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (!beforeChild && isAfterContent(lastChild()))
465545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        beforeChild = lastChild();
466545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    moveChildrenTo(cloneBlock, beforeChild, 0);
467545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
468545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Hook |clone| up as the continuation of the middle block.
4694a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    if (!cloneBlock->isAnonymousBlock())
4704a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        middleBlock->setContinuation(cloneBlock);
471545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
472545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // We have been reparented and are now under the fromBlock.  We need
473545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // to walk up our block parent chain until we hit the containing anonymous columns block.
474545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Once we hit the anonymous columns block we're done.
475545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBoxModelObject* curr = toRenderBoxModelObject(parent());
476545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBoxModelObject* currChild = this;
477545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
478545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    while (curr && curr != fromBlock) {
4794a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        ASSERT(curr->isRenderBlock());
480545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
481545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        RenderBlock* blockCurr = toRenderBlock(curr);
482545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
483545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // Create a new clone.
484545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        RenderBlock* cloneChild = cloneBlock;
485cad810f21b803229eb11403f9209855525a25d57Steve Block        cloneBlock = blockCurr->clone();
486545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
487545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // Insert our child clone as the first child.
488545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        cloneBlock->children()->appendChildNode(cloneBlock, cloneChild);
489545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
490545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // Hook the clone up as a continuation of |curr|.  Note we do encounter
491545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // anonymous blocks possibly as we walk up the block chain.  When we split an
492545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // anonymous block, there's no need to do any continuation hookup, since we haven't
493545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // actually split a real element.
494545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (!blockCurr->isAnonymousBlock()) {
495545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            oldCont = blockCurr->continuation();
496545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            blockCurr->setContinuation(cloneBlock);
497545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            cloneBlock->setContinuation(oldCont);
498545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        }
499545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
500545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // Someone may have indirectly caused a <q> to split.  When this happens, the :after content
501545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // has to move into the inline continuation.  Call updateBeforeAfterContent to ensure that the inline's :after
502545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // content gets properly destroyed.
503545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (document()->usesBeforeAfterRules())
504545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            blockCurr->children()->updateBeforeAfterContent(blockCurr, AFTER);
505545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
506545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // Now we need to take all of the children starting from the first child
507545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // *after* currChild and append them all to the clone.
508545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        RenderObject* afterContent = isAfterContent(cloneBlock->lastChild()) ? cloneBlock->lastChild() : 0;
509545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        blockCurr->moveChildrenTo(cloneBlock, currChild->nextSibling(), 0, afterContent);
510545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
511545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // Keep walking up the chain.
512545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        currChild = curr;
513545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        curr = toRenderBoxModelObject(curr->parent());
514545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
515545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
516545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Now we are at the columns block level. We need to put the clone into the toBlock.
517545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    toBlock->children()->appendChildNode(toBlock, cloneBlock);
518545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
519545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Now take all the children after currChild and remove them from the fromBlock
520545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // and put them in the toBlock.
521545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    fromBlock->moveChildrenTo(toBlock, currChild->nextSibling(), 0);
522545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
523545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
524545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid RenderBlock::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
525545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                            RenderObject* newChild, RenderBoxModelObject* oldCont)
526545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
527545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBlock* pre = 0;
528545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBlock* block = containingColumnsBlock();
529545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
530545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Delete our line boxes before we do the inline split into continuations.
531545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    block->deleteLineBoxTree();
532545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
533545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    bool madeNewBeforeBlock = false;
534545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (block->isAnonymousColumnsBlock()) {
535545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // We can reuse this block and make it the preBlock of the next continuation.
536545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        pre = block;
537545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        pre->removePositionedObjects(0);
538545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        block = toRenderBlock(block->parent());
539545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    } else {
540545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // No anonymous block available for use.  Make one.
541545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        pre = block->createAnonymousColumnsBlock();
542545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        pre->setChildrenInline(false);
543545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        madeNewBeforeBlock = true;
544545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
545545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
546545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBlock* post = block->createAnonymousColumnsBlock();
547545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    post->setChildrenInline(false);
548545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
549545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
550545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (madeNewBeforeBlock)
551545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        block->children()->insertChildNode(block, pre, boxFirst);
552545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    block->children()->insertChildNode(block, newBlockBox, boxFirst);
553545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    block->children()->insertChildNode(block, post, boxFirst);
554545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    block->setChildrenInline(false);
555545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
556545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (madeNewBeforeBlock)
557545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        block->moveChildrenTo(pre, boxFirst, 0);
558545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
559545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    splitBlocks(pre, post, newBlockBox, beforeChild, oldCont);
560545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
561545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
562545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // time in makeChildrenNonInline by just setting this explicitly up front.
563545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    newBlockBox->setChildrenInline(false);
564545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
565545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // We delayed adding the newChild until now so that the |newBlockBox| would be fully
566545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // connected, thus allowing newChild access to a renderArena should it need
567545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // to wrap itself in additional boxes (e.g., table construction).
568545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    newBlockBox->addChild(newChild);
569545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
570545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
571545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // get deleted properly.  Because objects moves from the pre block into the post block, we want to
572545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // make new line boxes instead of leaving the old line boxes around.
573545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    pre->setNeedsLayoutAndPrefWidthsRecalc();
574545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    block->setNeedsLayoutAndPrefWidthsRecalc();
575545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    post->setNeedsLayoutAndPrefWidthsRecalc();
576545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
577545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
5785af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeRenderObject* RenderBlock::splitAnonymousBlocksAroundChild(RenderObject* beforeChild)
5795af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
5805af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    while (beforeChild->parent() != this) {
5815af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        RenderBlock* blockToSplit = toRenderBlock(beforeChild->parent());
5825af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (blockToSplit->firstChild() != beforeChild) {
5835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // We have to split the parentBlock into two blocks.
5845af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            RenderBlock* post = createAnonymousBlockWithSameTypeAs(blockToSplit);
5855af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            post->setChildrenInline(blockToSplit->childrenInline());
5865af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            RenderBlock* parentBlock = toRenderBlock(blockToSplit->parent());
5875af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            parentBlock->children()->insertChildNode(parentBlock, post, blockToSplit->nextSibling());
5885af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            blockToSplit->moveChildrenTo(post, beforeChild, 0, blockToSplit->hasLayer());
5895af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            post->setNeedsLayoutAndPrefWidthsRecalc();
5905af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            blockToSplit->setNeedsLayoutAndPrefWidthsRecalc();
5915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            beforeChild = post;
5925af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        } else
5935af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            beforeChild = blockToSplit;
5945af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    }
5955af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return beforeChild;
5965af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
5975af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
5985af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild)
5995af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
6005af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderBlock* pre = 0;
6015af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderBlock* post = 0;
6025af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderBlock* block = this; // Eventually block will not just be |this|, but will also be a block nested inside |this|.  Assign to a variable
6035af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                               // so that we don't have to patch all of the rest of the code later on.
6045af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
6055af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // Delete the block's line boxes before we do the split.
6065af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    block->deleteLineBoxTree();
607545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
6085af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (beforeChild && beforeChild->parent() != this)
6095af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        beforeChild = splitAnonymousBlocksAroundChild(beforeChild);
610545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
6115af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (beforeChild != firstChild()) {
6125af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        pre = block->createAnonymousColumnsBlock();
6135af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        pre->setChildrenInline(block->childrenInline());
6145af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    }
6155af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
6165af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (beforeChild) {
6175af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        post = block->createAnonymousColumnsBlock();
6185af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        post->setChildrenInline(block->childrenInline());
6195af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    }
6205af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
6215af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderObject* boxFirst = block->firstChild();
6225af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (pre)
6235af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        block->children()->insertChildNode(block, pre, boxFirst);
6245af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    block->children()->insertChildNode(block, newBlockBox, boxFirst);
6255af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (post)
6265af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        block->children()->insertChildNode(block, post, boxFirst);
6275af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    block->setChildrenInline(false);
6285af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
6295af96e2c7b73ebc627c6894727826a7576d31758Leon 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).
6305af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    block->moveChildrenTo(pre, boxFirst, beforeChild, true);
6315af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    block->moveChildrenTo(post, beforeChild, 0, true);
6325af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
6335af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
6345af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // time in makeChildrenNonInline by just setting this explicitly up front.
6355af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newBlockBox->setChildrenInline(false);
6365af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
6375af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // We delayed adding the newChild until now so that the |newBlockBox| would be fully
6385af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // connected, thus allowing newChild access to a renderArena should it need
6395af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // to wrap itself in additional boxes (e.g., table construction).
6405af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newBlockBox->addChild(newChild);
6415af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
6425af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
6435af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // get deleted properly.  Because objects moved from the pre block into the post block, we want to
6445af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // make new line boxes instead of leaving the old line boxes around.
6455af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (pre)
6465af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        pre->setNeedsLayoutAndPrefWidthsRecalc();
6475af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    block->setNeedsLayoutAndPrefWidthsRecalc();
6485af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (post)
6495af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        post->setNeedsLayoutAndPrefWidthsRecalc();
6505af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
6515af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
652545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRenderBlock* RenderBlock::columnsBlockForSpanningElement(RenderObject* newChild)
6535af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
654545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // FIXME: This function is the gateway for the addition of column-span support.  It will
655545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // be added to in three stages:
6565af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // (1) Immediate children of a multi-column block can span.
6575af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // (2) Nested block-level children with only block-level ancestors between them and the multi-column block can span.
6585af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // (3) Nested children with block or inline ancestors between them and the multi-column block can span (this is when we
6595af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // cross the streams and have to cope with both types of continuations mixed together).
660545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // This function currently supports (1) and (2).
661545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBlock* columnsBlockAncestor = 0;
662b52229f8ad5e8b3632305005e437104c11eba942Steve Block    if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isBeforeOrAfterContent()
663b52229f8ad5e8b3632305005e437104c11eba942Steve Block        && !newChild->isFloatingOrPositioned() && !newChild->isInline() && !isAnonymousColumnSpanBlock()) {
664545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (style()->specifiesColumns())
665545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            columnsBlockAncestor = this;
666bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        else if (parent() && parent()->isRenderBlock())
667545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            columnsBlockAncestor = toRenderBlock(parent())->containingColumnsBlock(false);
668545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
669545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return columnsBlockAncestor;
6705af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
6715af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
6725af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Make sure we don't append things after :after-generated content if we have it.
675dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!beforeChild) {
676dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        RenderObject* lastRenderer = lastChild();
677dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (isAfterContent(lastRenderer))
678dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            beforeChild = lastRenderer;
679dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        else if (lastRenderer && lastRenderer->isAnonymousBlock() && isAfterContent(lastRenderer->lastChild()))
680dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            beforeChild = lastRenderer->lastChild();
681dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
6828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the requested beforeChild is not one of our children, then this is because
6848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // there is an anonymous container within this object that contains the beforeChild.
6858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (beforeChild && beforeChild->parent() != this) {
6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderObject* anonymousChild = beforeChild->parent();
6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(anonymousChild);
6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (anonymousChild->parent() != this)
6908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            anonymousChild = anonymousChild->parent();
6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(anonymousChild->isAnonymous());
6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (anonymousChild->isAnonymousBlock()) {
6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Insert the child into the anonymous block box instead of here.
6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
6978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                beforeChild->parent()->addChild(newChild, beforeChild);
6988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
6998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                addChild(newChild, beforeChild->parent());
7008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(anonymousChild->isTable());
7048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if ((newChild->isTableCol() && newChild->style()->display() == TABLE_COLUMN_GROUP)
7058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                || (newChild->isRenderBlock() && newChild->style()->display() == TABLE_CAPTION)
7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                || newChild->isTableSection()
7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                || newChild->isTableRow()
7088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                || newChild->isTableCell()) {
7098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Insert into the anonymous table.
7108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            anonymousChild->addChild(newChild, beforeChild);
7118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
7128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Go on to insert before the anonymous table.
7158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        beforeChild = anonymousChild;
7168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7184a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    // Check for a spanning element in columns.
7194a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    RenderBlock* columnsBlockAncestor = columnsBlockForSpanningElement(newChild);
7204a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    if (columnsBlockAncestor) {
7214a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        // We are placing a column-span element inside a block.
7224a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        RenderBlock* newBox = createAnonymousColumnSpanBlock();
7234a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
7244a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        if (columnsBlockAncestor != this) {
7254a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            // We are nested inside a multi-column element and are being split by the span.  We have to break up
7264a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            // our block into continuations.
7274a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            RenderBoxModelObject* oldContinuation = continuation();
7284a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            setContinuation(newBox);
7294a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
7304a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            // Someone may have put a <p> inside a <q>, causing a split.  When this happens, the :after content
7314a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            // has to move into the inline continuation.  Call updateBeforeAfterContent to ensure that our :after
7324a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            // content gets properly destroyed.
7334a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            bool isLastChild = (beforeChild == lastChild());
7344a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            if (document()->usesBeforeAfterRules())
7354a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch                children()->updateBeforeAfterContent(this, AFTER);
7364a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            if (isLastChild && beforeChild != lastChild())
7374a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch                beforeChild = 0; // We destroyed the last child, so now we need to update our insertion
7384a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch                                 // point to be 0.  It's just a straight append now.
7394a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
7404a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            splitFlow(beforeChild, newBox, newChild, oldContinuation);
7414a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            return;
7424a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        }
7434a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
7444a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        // We have to perform a split of this block's children.  This involves creating an anonymous block box to hold
7454a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        // the column-spanning |newChild|.  We take all of the children from before |newChild| and put them into
7464a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        // one anonymous columns block, and all of the children after |newChild| go into another anonymous block.
7474a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        makeChildrenAnonymousColumnBlocks(beforeChild, newBox, newChild);
7484a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        return;
7494a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    }
7504a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
7514a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    bool madeBoxesNonInline = false;
7524a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // A block has to either have all of its children inline, or all of its children as blocks.
7548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // So, if our children are currently inline and a block child has to be inserted, we move all our
7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // inline children into anonymous block boxes.
7568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrPositioned()) {
7578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // This is a block with inline content. Wrap the inline content in anonymous blocks.
7588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        makeChildrenNonInline(beforeChild);
7598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        madeBoxesNonInline = true;
7608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (beforeChild && beforeChild->parent() != this) {
7628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            beforeChild = beforeChild->parent();
7638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(beforeChild->isAnonymousBlock());
7648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(beforeChild->parent() == this);
7658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    } else if (!childrenInline() && (newChild->isFloatingOrPositioned() || newChild->isInline())) {
7678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // If we're inserting an inline child but all of our children are blocks, then we have to make sure
7688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
7698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // a new one is created and inserted into our list of children in the appropriate position.
7708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
7718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (afterChild && afterChild->isAnonymousBlock()) {
7738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            afterChild->addChild(newChild);
7748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
7758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (newChild->isInline()) {
7788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // No suitable existing anonymous box - create a new one.
7798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderBlock* newBox = createAnonymousBlock();
7808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            RenderBox::addChild(newBox, beforeChild);
7818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            newBox->addChild(newChild);
7828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
7838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBox::addChild(newChild, beforeChild);
7878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRenderBlock())
7898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
7908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // this object may be dead here
7918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7935af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
7945af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
795545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (continuation() && !isAnonymousBlock())
796545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return addChildToContinuation(newChild, beforeChild);
797545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return addChildIgnoringContinuation(newChild, beforeChild);
798545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
799545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
800545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild)
801545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
802545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (!isAnonymousBlock() && firstChild() && (firstChild()->isAnonymousColumnsBlock() || firstChild()->isAnonymousColumnSpanBlock()))
8035af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return addChildToAnonymousColumnBlocks(newChild, beforeChild);
8045af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
8055af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
8065af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
8078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void getInlineRun(RenderObject* start, RenderObject* boundary,
8088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                         RenderObject*& inlineRunStart,
8098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                         RenderObject*& inlineRunEnd)
8108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Beginning at |start| we find the largest contiguous run of inlines that
8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // we can.  We denote the run with start and end points, |inlineRunStart|
8138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // and |inlineRunEnd|.  Note that these two values may be the same if
8148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // we encounter only one inline.
8158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    //
8168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We skip any non-inlines we encounter as long as we haven't found any
8178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // inlines yet.
8188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    //
8198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // |boundary| indicates a non-inclusive boundary point.  Regardless of whether |boundary|
8208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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
8218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // a non-inline.
8228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Start by skipping as many non-inlines as we can.
8248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject * curr = start;
8258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool sawInline;
8268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    do {
8278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (curr && !(curr->isInline() || curr->isFloatingOrPositioned()))
8288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            curr = curr->nextSibling();
8298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        inlineRunStart = inlineRunEnd = curr;
8318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!curr)
8338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return; // No more inline children to be found.
8348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        sawInline = curr->isInline();
8368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        curr = curr->nextSibling();
8388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (curr && (curr->isInline() || curr->isFloatingOrPositioned()) && (curr != boundary)) {
8398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            inlineRunEnd = curr;
8408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (curr->isInline())
8418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                sawInline = true;
8428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            curr = curr->nextSibling();
8438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
8448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } while (!sawInline);
8458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::deleteLineBoxTree()
8488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_lineBoxes.deleteLineBoxTree(renderArena());
8508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
8518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochRootInlineBox* RenderBlock::createRootInlineBox()
8538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
8548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return new (renderArena()) RootInlineBox(this);
8558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
8568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochRootInlineBox* RenderBlock::createAndAppendRootInlineBox()
8588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
8590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    RootInlineBox* rootBox = createRootInlineBox();
8608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_lineBoxes.appendLineBox(rootBox);
8618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return rootBox;
8628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
863643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
8645af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::moveChildTo(RenderBlock* to, RenderObject* child, RenderObject* beforeChild, bool fullRemoveInsert)
865643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
866643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ASSERT(this == child->parent());
867643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ASSERT(!beforeChild || to == beforeChild->parent());
8685af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    to->children()->insertChildNode(to, children()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert);
869d0825bca7fe65beaee391d30da42e937db621564Steve Block}
870d0825bca7fe65beaee391d30da42e937db621564Steve Block
8715af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::moveChildrenTo(RenderBlock* to, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert)
872d0825bca7fe65beaee391d30da42e937db621564Steve Block{
873d0825bca7fe65beaee391d30da42e937db621564Steve Block    ASSERT(!beforeChild || to == beforeChild->parent());
8745af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderObject* nextChild = startChild;
8755af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    while (nextChild && nextChild != endChild) {
876d0825bca7fe65beaee391d30da42e937db621564Steve Block        RenderObject* child = nextChild;
877d0825bca7fe65beaee391d30da42e937db621564Steve Block        nextChild = child->nextSibling();
8785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        to->children()->insertChildNode(to, children()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert);
8795af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (child == endChild)
8805af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            return;
881d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
882d0825bca7fe65beaee391d30da42e937db621564Steve Block}
883d0825bca7fe65beaee391d30da42e937db621564Steve Block
8848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
8858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // makeChildrenNonInline takes a block whose children are *all* inline and it
8878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // makes sure that inline children are coalesced under anonymous
8888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // blocks.  If |insertionPoint| is defined, then it represents the insertion point for
8898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the new block child that is causing us to have to wrap all the inlines.  This
8908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // means that we cannot coalesce inlines before |insertionPoint| with inlines following
8918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // |insertionPoint|, because the new child is going to be inserted in between the inlines,
8928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // splitting them.
8938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(isInlineBlockOrInlineTable() || !isInline());
8948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!insertionPoint || insertionPoint->parent() == this);
8958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    setChildrenInline(false);
8978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject *child = firstChild();
8998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!child)
9008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    deleteLineBoxTree();
9038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (child) {
9058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderObject *inlineRunStart, *inlineRunEnd;
9068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
9078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!inlineRunStart)
9098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
9108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child = inlineRunEnd->nextSibling();
9128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderBlock* block = createAnonymousBlock();
9148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        children()->insertChildNode(this, block, inlineRunStart);
9155af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        moveChildrenTo(block, inlineRunStart, child);
9168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG
9198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (RenderObject *c = firstChild(); c; c = c->nextSibling())
9208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(!c->isInline());
9218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
9228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    repaint();
9248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
9278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
9288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(child->isAnonymousBlock());
9298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(!child->childrenInline());
9308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9315af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (child->continuation() || (child->firstChild() && (child->isAnonymousColumnSpanBlock() || child->isAnonymousColumnsBlock())))
9328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
9338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* firstAnChild = child->m_children.firstChild();
9358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* lastAnChild = child->m_children.lastChild();
9368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (firstAnChild) {
9378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderObject* o = firstAnChild;
9388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        while (o) {
9398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            o->setParent(this);
9408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            o = o->nextSibling();
9418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
9428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        firstAnChild->setPreviousSibling(child->previousSibling());
9438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        lastAnChild->setNextSibling(child->nextSibling());
9448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (child->previousSibling())
9458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            child->previousSibling()->setNextSibling(firstAnChild);
9468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (child->nextSibling())
9478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            child->nextSibling()->setPreviousSibling(lastAnChild);
9485af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
9495af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (child == m_children.firstChild())
9505af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            m_children.setFirstChild(firstAnChild);
9515af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (child == m_children.lastChild())
9525af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            m_children.setLastChild(lastAnChild);
9538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    } else {
9545af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (child == m_children.firstChild())
9555af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            m_children.setFirstChild(child->nextSibling());
9565af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (child == m_children.lastChild())
9575af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            m_children.setLastChild(child->previousSibling());
9585af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
9598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (child->previousSibling())
9608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            child->previousSibling()->setNextSibling(child->nextSibling());
9618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (child->nextSibling())
9628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            child->nextSibling()->setPreviousSibling(child->previousSibling());
9638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
9648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->setParent(0);
9658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->setPreviousSibling(0);
9668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->setNextSibling(0);
9678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->children()->setFirstChild(0);
9698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->m_next = 0;
9708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->destroy();
9728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
9738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9745af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkestatic bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObject* prev, RenderObject* next)
9755af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
9765af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (oldChild->documentBeingDestroyed() || oldChild->isInline() || oldChild->virtualContinuation())
9775af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return false;
9785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
9792bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (oldChild->parent() && oldChild->parent()->isDetails())
9802bde8e466a4451c7319e3a072d118917957d6554Steve Block        return false;
9812bde8e466a4451c7319e3a072d118917957d6554Steve Block
98265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if ((prev && (!prev->isAnonymousBlock() || toRenderBlock(prev)->continuation() || toRenderBlock(prev)->beingDestroyed()))
98365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        || (next && (!next->isAnonymousBlock() || toRenderBlock(next)->continuation() || toRenderBlock(next)->beingDestroyed())))
9845af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return false;
9855af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
986967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // FIXME: This check isn't required when inline run-ins can't be split into continuations.
987967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    if (prev && prev->firstChild() && prev->firstChild()->isInline() && prev->firstChild()->isRunIn())
988967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        return false;
989967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
9905af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if ((prev && (prev->isRubyRun() || prev->isRubyBase()))
9915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        || (next && (next->isRubyRun() || next->isRubyBase())))
9925af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return false;
9935af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
9945af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (!prev || !next)
9955af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return true;
9965af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
9975af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // Make sure the types of the anonymous blocks match up.
9985af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return prev->isAnonymousColumnsBlock() == next->isAnonymousColumnsBlock()
999cad810f21b803229eb11403f9209855525a25d57Steve Block           && prev->isAnonymousColumnSpanBlock() == next->isAnonymousColumnSpanBlock();
10005af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
10015af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
10028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::removeChild(RenderObject* oldChild)
10038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If this child is a block, and if our previous and next siblings are
10058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // both anonymous blocks with inline content, then we can go ahead and
10068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // fold the inline content back together.
10078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* prev = oldChild->previousSibling();
10088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* next = oldChild->nextSibling();
10095af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, prev, next);
10105af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (canMergeAnonymousBlocks && prev && next) {
10118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        prev->setNeedsLayoutAndPrefWidthsRecalc();
10128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderBlock* nextBlock = toRenderBlock(next);
10138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderBlock* prevBlock = toRenderBlock(prev);
10145af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
10155af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (prev->childrenInline() != next->childrenInline()) {
10165af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            RenderBlock* inlineChildrenBlock = prev->childrenInline() ? prevBlock : nextBlock;
10175af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            RenderBlock* blockChildrenBlock = prev->childrenInline() ? nextBlock : prevBlock;
10185af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
10195af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // Place the inline children block inside of the block children block instead of deleting it.
10205af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // In order to reuse it, we have to reset it to just be a generic anonymous block.  Make sure
10215af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // to clear out inherited column properties by just making a new style, and to also clear the
10225af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // column span flag if it is set.
10235af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            ASSERT(!inlineChildrenBlock->continuation());
10242bde8e466a4451c7319e3a072d118917957d6554Steve Block            RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
10255af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            children()->removeChildNode(this, inlineChildrenBlock, inlineChildrenBlock->hasLayer());
10265af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            inlineChildrenBlock->setStyle(newStyle);
10275af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
10285af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // Now just put the inlineChildrenBlock inside the blockChildrenBlock.
10295af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            blockChildrenBlock->children()->insertChildNode(blockChildrenBlock, inlineChildrenBlock, prev == inlineChildrenBlock ? blockChildrenBlock->firstChild() : 0,
10305af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                                                            inlineChildrenBlock->hasLayer() || blockChildrenBlock->hasLayer());
10315af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            next->setNeedsLayoutAndPrefWidthsRecalc();
1032cad810f21b803229eb11403f9209855525a25d57Steve Block
1033cad810f21b803229eb11403f9209855525a25d57Steve Block            // inlineChildrenBlock got reparented to blockChildrenBlock, so it is no longer a child
1034cad810f21b803229eb11403f9209855525a25d57Steve Block            // of "this". we null out prev or next so that is not used later in the function.
1035cad810f21b803229eb11403f9209855525a25d57Steve Block            if (inlineChildrenBlock == prevBlock)
1036cad810f21b803229eb11403f9209855525a25d57Steve Block                prev = 0;
1037cad810f21b803229eb11403f9209855525a25d57Steve Block            else
1038cad810f21b803229eb11403f9209855525a25d57Steve Block                next = 0;
10395af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        } else {
10405af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // Take all the children out of the |next| block and put them in
10415af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // the |prev| block.
104265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            nextBlock->moveAllChildrenTo(prevBlock, nextBlock->hasLayer() || prevBlock->hasLayer());
1043cad810f21b803229eb11403f9209855525a25d57Steve Block
10445af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // Delete the now-empty block's lines and nuke it.
10455af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            nextBlock->deleteLineBoxTree();
10465af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            nextBlock->destroy();
1047cad810f21b803229eb11403f9209855525a25d57Steve Block            next = 0;
10485af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        }
10498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBox::removeChild(oldChild);
10528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* child = prev ? prev : next;
10545af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && !isFlexibleBox()) {
10558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // The removal has knocked us down to containing only a single anonymous
10568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // box.  We can go ahead and pull the content right back up into our
10578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // box.
10588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setNeedsLayoutAndPrefWidthsRecalc();
10595af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        setChildrenInline(child->childrenInline());
10605af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        RenderBlock* anonBlock = toRenderBlock(children()->removeChildNode(this, child, child->hasLayer()));
10615af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        anonBlock->moveAllChildrenTo(this, child->hasLayer());
10628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Delete the now-empty block's lines and nuke it.
10638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        anonBlock->deleteLineBoxTree();
10648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        anonBlock->destroy();
10658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1066d0825bca7fe65beaee391d30da42e937db621564Steve Block
10675af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (!firstChild() && !documentBeingDestroyed()) {
10685af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        // If this was our last child be sure to clear out our line boxes.
10695af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (childrenInline())
10705af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            lineBoxes()->deleteLineBoxes(renderArena());
10715af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    }
10728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::isSelfCollapsingBlock() const
10758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We are not self-collapsing if we
10778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (a) have a non-zero height according to layout (an optimization to avoid wasting time)
10788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (b) are a table,
10798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (c) have border/padding,
10808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (d) have a min-height
10818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (e) have specified that one of our margins can't collapse using a CSS extension
1082a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (logicalHeight() > 0
1083a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        || isTable() || borderAndPaddingLogicalHeight()
1084a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        || style()->logicalMinHeight().isPositive()
1085bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        || style()->marginBeforeCollapse() == MSEPARATE || style()->marginAfterCollapse() == MSEPARATE)
10868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
10878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1088a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    Length logicalHeightLength = style()->logicalHeight();
1089a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool hasAutoHeight = logicalHeightLength.isAuto();
1090a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (logicalHeightLength.isPercent() && !document()->inQuirksMode()) {
10918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        hasAutoHeight = true;
10928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (RenderBlock* cb = containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) {
1093a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (cb->style()->logicalHeight().isFixed() || cb->isTableCell())
10948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                hasAutoHeight = false;
10958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
10968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the height is 0 or auto, then whether or not we are a self-collapsing block depends
10998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // on whether we have content that is all self-collapsing or not.
1100a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (hasAutoHeight || ((logicalHeightLength.isFixed() || logicalHeightLength.isPercent()) && logicalHeightLength.isZero())) {
11018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // If the block has inline children, see if we generated any line boxes.  If we have any
11028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // line boxes, then we can't be self-collapsing, since we have content.
11038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (childrenInline())
11048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return !firstLineBox();
11058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Whether or not we collapse is dependent on whether all our normal flow children
11078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // are also self-collapsing.
1108635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
11098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (child->isFloatingOrPositioned())
11108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
11118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!child->isSelfCollapsingBlock())
11128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return false;
11138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
11148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
11158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
11168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
11178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid RenderBlock::startDelayUpdateScrollInfo()
11200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
11210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (gDelayUpdateScrollInfo == 0) {
11220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ASSERT(!gDelayedUpdateScrollInfoSet);
11230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet;
11240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
11250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(gDelayedUpdateScrollInfoSet);
11260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ++gDelayUpdateScrollInfo;
11270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
11280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
11290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid RenderBlock::finishDelayUpdateScrollInfo()
11300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
11310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    --gDelayUpdateScrollInfo;
11320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(gDelayUpdateScrollInfo >= 0);
11330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (gDelayUpdateScrollInfo == 0) {
11340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ASSERT(gDelayedUpdateScrollInfoSet);
11350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1136643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        OwnPtr<DelayedUpdateScrollInfoSet> infoSet(gDelayedUpdateScrollInfoSet);
1137643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        gDelayedUpdateScrollInfoSet = 0;
1138643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
1139643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        for (DelayedUpdateScrollInfoSet::iterator it = infoSet->begin(); it != infoSet->end(); ++it) {
11400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            RenderBlock* block = *it;
11410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (block->hasOverflowClip()) {
11420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                block->layer()->updateScrollInfoAfterLayout();
11430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
11440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
11450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
11460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
11470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
11480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid RenderBlock::updateScrollInfoAfterLayout()
11490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
11500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (hasOverflowClip()) {
11510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (gDelayUpdateScrollInfo)
11520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            gDelayedUpdateScrollInfoSet->add(this);
11530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        else
11540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            layer()->updateScrollInfoAfterLayout();
11550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
11560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
11570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
11588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::layout()
11598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Update our first letter info now.
11618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    updateFirstLetter();
11628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Table cells call layoutBlock directly, so don't add any logic here.  Put code into
11648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // layoutBlock().
11658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    layoutBlock(false);
11668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // It's safe to check for control clip here, since controls can never be table cells.
1168231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // If we have a lightweight clip, there can never be any overflow from children.
1169231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (hasControlClip() && m_overflow)
1170231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        clearLayoutOverflow();
11718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1173f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderBlock::layoutBlock(bool relayoutChildren, int pageLogicalHeight)
11748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(needsLayout());
11768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isInline() && !isInlineBlockOrInlineTable()) // Inline <form>s inside various table elements can
11788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;                                      // cause us to come in here.  Just bail.
11798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11802bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!relayoutChildren && simplifiedLayout())
11818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
11828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    LayoutRepainter repainter(*this, m_everHadLayout && checkForRepaintDuringLayout());
11848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1185a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int oldWidth = logicalWidth();
11868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int oldColumnWidth = desiredColumnWidth();
11878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1188bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    computeLogicalWidth();
11898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    calcColumnWidth();
11908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1191231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_overflow.clear();
11928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1193bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (oldWidth != logicalWidth() || oldColumnWidth != desiredColumnWidth())
11948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        relayoutChildren = true;
11958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_LAYOUT
119723e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang    checkAndSetRelayoutChildren(&relayoutChildren);
11988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
11998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    clearFloats();
12018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1202bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int previousHeight = logicalHeight();
1203bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    setLogicalHeight(0);
1204f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    bool hasSpecifiedPageLogicalHeight = false;
1205f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    bool pageLogicalHeightChanged = false;
120668513a70bcd92384395513322f1b801e7bf9c729Steve Block    ColumnInfo* colInfo = columnInfo();
120768513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (hasColumns()) {
1208f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (!pageLogicalHeight) {
120968513a70bcd92384395513322f1b801e7bf9c729Steve Block            // We need to go ahead and set our explicit page height if one exists, so that we can
121068513a70bcd92384395513322f1b801e7bf9c729Steve Block            // avoid doing two layout passes.
1211bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            computeLogicalHeight();
1212bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            int columnHeight = contentLogicalHeight();
121368513a70bcd92384395513322f1b801e7bf9c729Steve Block            if (columnHeight > 0) {
1214f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                pageLogicalHeight = columnHeight;
1215f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                hasSpecifiedPageLogicalHeight = true;
121668513a70bcd92384395513322f1b801e7bf9c729Steve Block            }
1217bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setLogicalHeight(0);
121868513a70bcd92384395513322f1b801e7bf9c729Steve Block        }
1219f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (colInfo->columnHeight() != pageLogicalHeight && m_everHadLayout) {
1220f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            colInfo->setColumnHeight(pageLogicalHeight);
1221f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            pageLogicalHeightChanged = true;
122268513a70bcd92384395513322f1b801e7bf9c729Steve Block        }
122368513a70bcd92384395513322f1b801e7bf9c729Steve Block
1224f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (!hasSpecifiedPageLogicalHeight && !pageLogicalHeight)
122568513a70bcd92384395513322f1b801e7bf9c729Steve Block            colInfo->clearForcedBreaks();
122668513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
122768513a70bcd92384395513322f1b801e7bf9c729Steve Block
1228f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode(), pageLogicalHeight, pageLogicalHeightChanged, colInfo);
1229635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
12305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track
12318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // our current maximal positive and negative margins.  These values are used when we
12328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // are collapsed with adjacent blocks, so for example, if you have block A and B
12338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // collapsing together, then you'd take the maximal positive margin from both A and B
12348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // and subtract it from the maximal negative margin from both A and B to get the
12358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // true collapsed margin.  This algorithm is recursive, so when we finish layout()
12368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // our block knows its current maximal positive/negative values.
12378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    //
12388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Start out by setting our margin values to our current margins.  Table cells have
12398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // no margins, so we don't fill in the values for table cells.
12408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool isCell = isTableCell();
12418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!isCell) {
12428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        initMaxMarginValues();
124368513a70bcd92384395513322f1b801e7bf9c729Steve Block
1244bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setMarginBeforeQuirk(style()->marginBefore().quirk());
1245bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setMarginAfterQuirk(style()->marginAfter().quirk());
12468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        Node* n = node();
12488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (n && n->hasTagName(formTag) && static_cast<HTMLFormElement*>(n)->isMalformed()) {
12498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // See if this form is malformed (i.e., unclosed). If so, don't give the form
12508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // a bottom margin.
1251bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setMaxMarginAfterValues(0, 0);
12528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
125368513a70bcd92384395513322f1b801e7bf9c729Steve Block
125468513a70bcd92384395513322f1b801e7bf9c729Steve Block        setPaginationStrut(0);
12558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // For overflow:scroll blocks, ensure we have both scrollbars in place always.
12588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (scrollsOverflow()) {
12598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (style()->overflowX() == OSCROLL)
12608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            layer()->setHasHorizontalScrollbar(true);
12618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (style()->overflowY() == OSCROLL)
12628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            layer()->setHasVerticalScrollbar(true);
12638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1265a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int repaintLogicalTop = 0;
1266a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int repaintLogicalBottom = 0;
1267a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int maxFloatLogicalBottom = 0;
1268e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (!firstChild() && !isAnonymousBlock())
12696c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        setChildrenInline(true);
12708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childrenInline())
1271a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        layoutInlineChildren(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
12728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
1273a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        layoutBlockChildren(relayoutChildren, maxFloatLogicalBottom);
12748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Expand our intrinsic height to encompass floats.
1276a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int toAdd = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
1277a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (lowestFloatLogicalBottom() > (logicalHeight() - toAdd) && expandsToEncloseOverhangingFloats())
1278a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalHeight(lowestFloatLogicalBottom() + toAdd);
12798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1280f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (layoutColumns(hasSpecifiedPageLogicalHeight, pageLogicalHeight, statePusher))
128168513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
128268513a70bcd92384395513322f1b801e7bf9c729Steve Block
12838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Calculate our new height.
1284bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int oldHeight = logicalHeight();
1285f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int oldClientAfterEdge = clientLogicalBottom();
1286bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    computeLogicalHeight();
1287bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int newHeight = logicalHeight();
1288bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (oldHeight != newHeight) {
1289a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (oldHeight > newHeight && maxFloatLogicalBottom > newHeight && !childrenInline()) {
12908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // One of our children's floats may have become an overhanging float for us. We need to look for it.
12918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
12928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (child->isBlockFlow() && !child->isFloatingOrPositioned()) {
12938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    RenderBlock* block = toRenderBlock(child);
1294a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    if (block->lowestFloatLogicalBottom() + block->logicalTop() > newHeight)
1295a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                        addOverhangingFloats(block, -block->logicalLeft(), -block->logicalTop(), false);
12968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
12978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
12988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
12998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1300231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1301bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (previousHeight != newHeight)
13028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        relayoutChildren = true;
13038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1304231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    layoutPositionedObjects(relayoutChildren || isRoot());
13058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1306f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway).
1307f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    computeOverflow(oldClientAfterEdge);
1308231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1309635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    statePusher.pop();
13108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1311f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (view()->layoutState()->m_pageLogicalHeight)
13122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(logicalTop()));
1313f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1314f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    updateLayerTransform();
131568513a70bcd92384395513322f1b801e7bf9c729Steve Block
13168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
13178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // we overflow or not.
13180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    updateScrollInfoAfterLayout();
13198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Repaint with our new bounds if they are different from our old bounds.
13218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool didFullRepaint = repainter.repaintAfterLayout();
1322a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!didFullRepaint && repaintLogicalTop != repaintLogicalBottom && (style()->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) {
1323f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // FIXME: We could tighten up the left and right invalidation points if we let layoutInlineChildren fill them in based off the particular lines
1324f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // it had to lay out.  We wouldn't need the hasOverflowClip() hack in that case either.
1325f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        int repaintLogicalLeft = logicalLeftVisualOverflow();
1326f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        int repaintLogicalRight = logicalRightVisualOverflow();
1327f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (hasOverflowClip()) {
1328f05b935882198ccf7d81675736e3aeb089c5113aBen 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.
1329f05b935882198ccf7d81675736e3aeb089c5113aBen 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.
1330f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // layoutInlineChildren should be patched to compute the entire repaint rect.
1331f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            repaintLogicalLeft = min(repaintLogicalLeft, logicalLeftLayoutOverflow());
1332f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            repaintLogicalRight = max(repaintLogicalRight, logicalRightLayoutOverflow());
1333f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        }
1334a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1335a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        IntRect repaintRect;
13362bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (isHorizontalWritingMode())
1337a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            repaintRect = IntRect(repaintLogicalLeft, repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop);
1338a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
1339a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            repaintRect = IntRect(repaintLogicalTop, repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft);
13408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1341e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        // The repaint rect may be split across columns, in which case adjustRectForColumns() will return the union.
1342e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        adjustRectForColumns(repaintRect);
13438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        repaintRect.inflate(maximalOutlineSize(PaintPhaseOutline));
13458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (hasOverflowClip()) {
13478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Adjust repaint rect for scroll offset
1348dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            repaintRect.move(-layer()->scrolledContentOffset());
13498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Don't allow this rect to spill out of our overflow box.
1351635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            repaintRect.intersect(IntRect(0, 0, width(), height()));
13528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
13538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Make sure the rect is still non-empty after intersecting for overflow above
13558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!repaintRect.isEmpty()) {
13568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            repaintRectangle(repaintRect); // We need to do a partial repaint of our content.
13578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (hasReflection())
13585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                repaintRectangle(reflectedRect(repaintRect));
13598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
13608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
13618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setNeedsLayout(false);
13628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1364f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderBlock::addOverflowFromChildren()
1365f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
1366f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!hasColumns()) {
1367f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (childrenInline())
1368f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            addOverflowFromInlineChildren();
1369f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        else
1370f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            addOverflowFromBlockChildren();
1371f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    } else {
1372f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        ColumnInfo* colInfo = columnInfo();
1373f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (columnCount(colInfo)) {
1374f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            IntRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
13752bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (isHorizontalWritingMode()) {
13762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int overflowLeft = !style()->isLeftToRightDirection() ? min(0, lastRect.x()) : 0;
13772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int overflowRight = style()->isLeftToRightDirection() ? max(width(), lastRect.maxX()) : 0;
13782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int overflowHeight = borderBefore() + paddingBefore() + colInfo->columnHeight();
13792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                addLayoutOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight));
13802bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (!hasOverflowClip())
13812bde8e466a4451c7319e3a072d118917957d6554Steve Block                    addVisualOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight));
13822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            } else {
13832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                IntRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
13842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int overflowTop = !style()->isLeftToRightDirection() ? min(0, lastRect.y()) : 0;
13852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int overflowBottom = style()->isLeftToRightDirection() ? max(height(), lastRect.maxY()) : 0;
13862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int overflowWidth = borderBefore() + paddingBefore() + colInfo->columnHeight();
13872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                addLayoutOverflow(IntRect(0, overflowTop, overflowWidth, overflowBottom - overflowTop));
13882bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (!hasOverflowClip())
13892bde8e466a4451c7319e3a072d118917957d6554Steve Block                    addVisualOverflow(IntRect(0, overflowTop, overflowWidth, overflowBottom - overflowTop));
13902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            }
1391f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        }
1392f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
1393f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
1394f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1395f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderBlock::computeOverflow(int oldClientAfterEdge, bool recomputeFloats)
1396f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
1397f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Add overflow from children.
1398f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    addOverflowFromChildren();
1399f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1400f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!hasColumns() && (recomputeFloats || isRoot() || expandsToEncloseOverhangingFloats() || hasSelfPaintingLayer()))
1401f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        addOverflowFromFloats();
1402f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1403f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Add in the overflow from positioned objects.
1404f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    addOverflowFromPositionedObjects();
1405f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1406f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (hasOverflowClip()) {
1407f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // When we have overflow clip, propagate the original spillout since it will include collapsed bottom margins
1408f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // and bottom padding.  Set the axis we don't care about to be 1, since we want this overflow to always
1409f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // be considered reachable.
1410f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        IntRect clientRect(clientBoxRect());
1411f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        IntRect rectToApply;
14122bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (isHorizontalWritingMode())
1413f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            rectToApply = IntRect(clientRect.x(), clientRect.y(), 1, max(0, oldClientAfterEdge - clientRect.y()));
1414f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        else
1415f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            rectToApply = IntRect(clientRect.x(), clientRect.y(), max(0, oldClientAfterEdge - clientRect.x()), 1);
1416f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        addLayoutOverflow(rectToApply);
1417f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
1418f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1419f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Add visual overflow from box-shadow and reflections.
1420f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    addShadowOverflow();
1421f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
1422f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1423231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid RenderBlock::addOverflowFromBlockChildren()
1424231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
1425231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
1426231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (!child->isFloatingOrPositioned())
1427231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            addOverflowFromChild(child);
1428231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
1429231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
1430231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1431231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid RenderBlock::addOverflowFromFloats()
1432231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
1433231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!m_floatingObjects)
1434231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
143581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
143681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
143781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator end = floatingObjectSet.end();
143881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
143981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObject* r = *it;
1440f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (r->m_isDescendant)
14412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            addOverflowFromChild(r->m_renderer, IntSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r)));
1442231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
1443231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return;
1444231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
1445231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1446f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderBlock::addOverflowFromPositionedObjects()
1447f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
1448f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!m_positionedObjects)
1449f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return;
1450f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1451f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    RenderBox* positionedObject;
1452f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    Iterator end = m_positionedObjects->end();
1453f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
1454f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        positionedObject = *it;
1455f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1456f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // Fixed positioned elements don't contribute to layout overflow, since they don't scroll with the content.
1457f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (positionedObject->style()->position() != FixedPosition)
1458f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            addOverflowFromChild(positionedObject);
1459f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
1460f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
1461f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1462635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool RenderBlock::expandsToEncloseOverhangingFloats() const
1463635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
1464bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return isInlineBlockOrInlineTable() || isFloatingOrPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBox())
1465a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch           || hasColumns() || isTableCell() || isFieldset() || isWritingModeRoot();
1466635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
1467635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1468635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marginInfo)
14698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
14702bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool isHorizontal = isHorizontalWritingMode();
147181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    bool hasStaticBlockPosition = child->style()->hasStaticBlockPosition(isHorizontal);
147281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    RenderLayer* childLayer = child->layer();
147381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
14742bde8e466a4451c7319e3a072d118917957d6554Steve Block    childLayer->setStaticInlinePosition(borderAndPaddingStart());
14752bde8e466a4451c7319e3a072d118917957d6554Steve Block
14762bde8e466a4451c7319e3a072d118917957d6554Steve Block    int logicalTop = logicalHeight();
14772bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!marginInfo.canCollapseWithMarginBefore()) {
14782bde8e466a4451c7319e3a072d118917957d6554Steve Block        child->computeBlockDirectionMargins(this);
14792bde8e466a4451c7319e3a072d118917957d6554Steve Block        int marginBefore = marginBeforeForChild(child);
14802bde8e466a4451c7319e3a072d118917957d6554Steve Block        int collapsedBeforePos = marginInfo.positiveMargin();
14812bde8e466a4451c7319e3a072d118917957d6554Steve Block        int collapsedBeforeNeg = marginInfo.negativeMargin();
14822bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (marginBefore > 0) {
14832bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (marginBefore > collapsedBeforePos)
14842bde8e466a4451c7319e3a072d118917957d6554Steve Block                collapsedBeforePos = marginBefore;
14852bde8e466a4451c7319e3a072d118917957d6554Steve Block        } else {
14862bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (-marginBefore > collapsedBeforeNeg)
14872bde8e466a4451c7319e3a072d118917957d6554Steve Block                collapsedBeforeNeg = -marginBefore;
14888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
14892bde8e466a4451c7319e3a072d118917957d6554Steve Block        logicalTop += (collapsedBeforePos - collapsedBeforeNeg) - marginBefore;
14902bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
14912bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (childLayer->staticBlockPosition() != logicalTop) {
14922bde8e466a4451c7319e3a072d118917957d6554Steve Block        childLayer->setStaticBlockPosition(logicalTop);
14932bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (hasStaticBlockPosition)
1494643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            child->setChildNeedsLayout(true, false);
14958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
14978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::adjustFloatingBlock(const MarginInfo& marginInfo)
14998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The float should be positioned taking into account the bottom margin
15018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // of the previous flow.  We add that margin into the height, get the
15028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // float positioned properly, and then subtract the margin out of the
15038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // height again.  In the case of self-collapsing blocks, we always just
15048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // use the top margins, since the self-collapsing block collapsed its
15058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // own bottom margin into its top margin.
15068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    //
15078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Note also that the previous flow may collapse its margin into the top of
15088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // our block.  If this is the case, then we do not add the margin in to our
15098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // height when computing the position of the float.   This condition can be tested
1510bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // for by simply calling canCollapseWithMarginBefore.  See
15118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for
15128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // an example of this scenario.
1513bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int marginOffset = marginInfo.canCollapseWithMarginBefore() ? 0 : marginInfo.margin();
1514a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalHeight(logicalHeight() + marginOffset);
15158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    positionNewFloats();
1516a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalHeight(logicalHeight() - marginOffset);
15178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool RenderBlock::handleSpecialChild(RenderBox* child, const MarginInfo& marginInfo)
15208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Handle in the given order
15225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return handlePositionedChild(child, marginInfo)
15235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        || handleFloatingChild(child, marginInfo)
15245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        || handleRunInChild(child);
15258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool RenderBlock::handlePositionedChild(RenderBox* child, const MarginInfo& marginInfo)
15298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (child->isPositioned()) {
15318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child->containingBlock()->insertPositionedObject(child);
15328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        adjustPositionedBlock(child, marginInfo);
15335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return true;
15348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return false;
15368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool RenderBlock::handleFloatingChild(RenderBox* child, const MarginInfo& marginInfo)
15398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (child->isFloating()) {
15418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        insertFloatingObject(child);
15428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        adjustFloatingBlock(marginInfo);
15435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return true;
15448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return false;
15468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool RenderBlock::handleRunInChild(RenderBox* child)
15498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // See if we have a run-in element with inline children.  If the
15518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // children aren't inline, then just treat the run-in as a normal
15528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // block.
1553231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!child->isRunIn() || !child->childrenInline())
1554231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return false;
1555231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // FIXME: We don't handle non-block elements with run-in for now.
1556231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!child->isRenderBlock())
15575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return false;
1558635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
15590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    RenderBlock* blockRunIn = toRenderBlock(child);
15605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RenderObject* curr = blockRunIn->nextSibling();
15619a26d18f4c7e98b479be700575d003f873214550John Reck    if (!curr || !curr->isRenderBlock() || !curr->childrenInline() || curr->isRunIn() || curr->isAnonymous() || curr->isFloatingOrPositioned())
15625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return false;
15635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
15645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RenderBlock* currBlock = toRenderBlock(curr);
15655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1566538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block    // First we destroy any :before/:after content. It will be regenerated by the new inline.
1567538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block    // Exception is if the run-in itself is generated.
1568538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block    if (child->style()->styleType() != BEFORE && child->style()->styleType() != AFTER) {
1569538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block        RenderObject* generatedContent;
1570538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block        if (child->getCachedPseudoStyle(BEFORE) && (generatedContent = child->beforePseudoElementRenderer()))
1571538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block            generatedContent->destroy();
1572538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block        if (child->getCachedPseudoStyle(AFTER) && (generatedContent = child->afterPseudoElementRenderer()))
1573538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block            generatedContent->destroy();
1574538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block    }
1575538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block
15765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Remove the old child.
15775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    children()->removeChildNode(this, blockRunIn);
1578635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
15795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Create an inline.
15805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Node* runInNode = blockRunIn->node();
15815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RenderInline* inlineRunIn = new (renderArena()) RenderInline(runInNode ? runInNode : document());
15825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    inlineRunIn->setStyle(blockRunIn->style());
15835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1584538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block    // Move the nodes from the old child to the new child
15856c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    for (RenderObject* runInChild = blockRunIn->firstChild(); runInChild;) {
15866c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        RenderObject* nextSibling = runInChild->nextSibling();
1587538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block        blockRunIn->children()->removeChildNode(blockRunIn, runInChild, false);
1588538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block        inlineRunIn->addChild(runInChild); // Use addChild instead of appendChildNode since it handles correct placement of the children relative to :after-generated content.
15896c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        runInChild = nextSibling;
15908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
15922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben 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
15932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // anything before the first child. e.g. details tag. See https://bugs.webkit.org/show_bug.cgi?id=58228.
15942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    currBlock->addChild(inlineRunIn, currBlock->firstChild());
15955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
15965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // If the run-in had an element, we need to set the new renderer.
15975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (runInNode)
15985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        runInNode->setRenderer(inlineRunIn);
15995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1600bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // Destroy the block run-in, which includes deleting its line box tree.
1601bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    blockRunIn->deleteLineBoxTree();
16025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    blockRunIn->destroy();
16035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
16045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // The block acts like an inline, so just null out its
16055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // position.
16065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
16075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return true;
16088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
16098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianint RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo)
16118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1612a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Get the four margin values for the child and cache them.
1613a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    const MarginValues childMargins = marginValuesForChild(child);
1614a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
16158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Get our max pos and neg top margins.
1616a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int posTop = childMargins.positiveMarginBefore();
1617a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int negTop = childMargins.negativeMarginBefore();
16188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // For self-collapsing blocks, collapse our bottom margins into our
16208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // top to get new posTop and negTop values.
16218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (child->isSelfCollapsingBlock()) {
1622a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        posTop = max(posTop, childMargins.positiveMarginAfter());
1623a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        negTop = max(negTop, childMargins.negativeMarginAfter());
16248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // See if the top margin is quirky. We only care if this child has
16278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // margins that will collapse with us.
1628bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    bool topQuirk = child->isMarginBeforeQuirk() || style()->marginBeforeCollapse() == MDISCARD;
16298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1630bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (marginInfo.canCollapseWithMarginBefore()) {
16318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // This child is collapsing with the top of the
16328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // block.  If it has larger margin values, then we need to update
16338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // our own maximal values.
16345ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        if (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !topQuirk)
1635a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            setMaxMarginBeforeValues(max(posTop, maxPositiveMarginBefore()), max(negTop, maxNegativeMarginBefore()));
16368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // The minute any of the margins involved isn't a quirk, don't
16388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // collapse it away, even if the margin is smaller (www.webreference.com
16398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // has an example of this, a <dt> with 0.8em author-specified inside
16408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // a <dl> inside a <td>.
1641a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!marginInfo.determinedMarginBeforeQuirk() && !topQuirk && (posTop - negTop)) {
1642bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setMarginBeforeQuirk(false);
1643bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            marginInfo.setDeterminedMarginBeforeQuirk(true);
16448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
16458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1646a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!marginInfo.determinedMarginBeforeQuirk() && topQuirk && !marginBefore())
16478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We have no top margin and our top child has a quirky margin.
16488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We will pick up this quirky margin and pass it through.
16498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // This deals with the <td><div><p> case.
16508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Don't do this for a block that split two inlines though.  You do
16518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // still apply margins in this case.
1652bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setMarginBeforeQuirk(true);
16538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1655bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (marginInfo.quirkContainer() && marginInfo.atBeforeSideOfBlock() && (posTop - negTop))
1656bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        marginInfo.setMarginBeforeQuirk(topQuirk);
16578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1658a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int beforeCollapseLogicalTop = logicalHeight();
1659a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalTop = beforeCollapseLogicalTop;
16608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (child->isSelfCollapsingBlock()) {
16618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // This child has no height.  We need to compute our
16628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // position before we collapse the child's margins together,
16638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // so that we can get an accurate position for the zero-height block.
1664a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int collapsedBeforePos = max(marginInfo.positiveMargin(), childMargins.positiveMarginBefore());
1665a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int collapsedBeforeNeg = max(marginInfo.negativeMargin(), childMargins.negativeMarginBefore());
1666a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        marginInfo.setMargin(collapsedBeforePos, collapsedBeforeNeg);
16678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Now collapse the child's margins together, which means examining our
16698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // bottom margin values as well.
1670a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        marginInfo.setPositiveMarginIfLarger(childMargins.positiveMarginAfter());
1671a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        marginInfo.setNegativeMarginIfLarger(childMargins.negativeMarginAfter());
16728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1673bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (!marginInfo.canCollapseWithMarginBefore())
16748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We need to make sure that the position of the self-collapsing block
16758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // is correct, since it could have overflowing content
16768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // that needs to be positioned correctly (e.g., a block that
16778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // had a specified height of 0 but that actually had subcontent).
1678a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            logicalTop = logicalHeight() + collapsedBeforePos - collapsedBeforeNeg;
16798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
1681bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (child->style()->marginBeforeCollapse() == MSEPARATE) {
1682a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            setLogicalHeight(logicalHeight() + marginInfo.margin() + marginBeforeForChild(child));
1683a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            logicalTop = logicalHeight();
16848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1685bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        else if (!marginInfo.atBeforeSideOfBlock() ||
1686bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            (!marginInfo.canCollapseMarginBeforeWithChildren()
1687bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen             && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.marginBeforeQuirk()))) {
16888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We're collapsing with a previous sibling's margins and not
16898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // with the top of the block.
1690a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            setLogicalHeight(logicalHeight() + max(marginInfo.positiveMargin(), posTop) - max(marginInfo.negativeMargin(), negTop));
1691a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            logicalTop = logicalHeight();
16928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
16938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1694a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        marginInfo.setPositiveMargin(childMargins.positiveMarginAfter());
1695a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        marginInfo.setNegativeMargin(childMargins.negativeMarginAfter());
16968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (marginInfo.margin())
1698bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            marginInfo.setMarginAfterQuirk(child->isMarginAfterQuirk() || style()->marginAfterCollapse() == MDISCARD);
16998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
17008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
170168513a70bcd92384395513322f1b801e7bf9c729Steve Block    // If margins would pull us past the top of the next page, then we need to pull back and pretend like the margins
170268513a70bcd92384395513322f1b801e7bf9c729Steve Block    // collapsed into the page edge.
170368513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool paginated = view()->layoutState()->isPaginated();
1704a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (paginated && logicalTop > beforeCollapseLogicalTop) {
1705a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int oldLogicalTop = logicalTop;
17062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        logicalTop = min(logicalTop, nextPageLogicalTop(beforeCollapseLogicalTop));
1707a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop));
170868513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
1709a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return logicalTop;
17108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianint RenderBlock::clearFloatsIfNeeded(RenderBox* child, MarginInfo& marginInfo, int oldTopPosMargin, int oldTopNegMargin, int yPos)
17138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
17148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int heightIncrease = getClearDelta(child, yPos);
17158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!heightIncrease)
17168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return yPos;
17178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (child->isSelfCollapsingBlock()) {
17198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // For self-collapsing blocks that clear, they can still collapse their
17208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // margins with following siblings.  Reset the current margins to represent
17218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // the self-collapsing block's margins only.
1722231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // CSS2.1 states:
1723231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // "An element that has had clearance applied to it never collapses its top margin with its parent block's bottom margin.
1724231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Therefore if we are at the bottom of the block, let's go ahead and reset margins to only include the
1725231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // self-collapsing block's bottom margin.
1726231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        bool atBottomOfBlock = true;
1727231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        for (RenderBox* curr = child->nextSiblingBox(); curr && atBottomOfBlock; curr = curr->nextSiblingBox()) {
1728231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if (!curr->isFloatingOrPositioned())
1729231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                atBottomOfBlock = false;
1730231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
1731a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1732a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        MarginValues childMargins = marginValuesForChild(child);
1733231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (atBottomOfBlock) {
1734a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            marginInfo.setPositiveMargin(childMargins.positiveMarginAfter());
1735a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            marginInfo.setNegativeMargin(childMargins.negativeMarginAfter());
1736231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        } else {
1737a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            marginInfo.setPositiveMargin(max(childMargins.positiveMarginBefore(), childMargins.positiveMarginAfter()));
1738a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            marginInfo.setNegativeMargin(max(childMargins.negativeMarginBefore(), childMargins.negativeMarginAfter()));
1739231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
17408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1741231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Adjust our height such that we are ready to be collapsed with subsequent siblings (or the bottom
1742231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // of the parent block).
1743bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setLogicalHeight(child->y() - max(0, marginInfo.margin()));
17448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else
17458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Increase our height by the amount we had to clear.
1746bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setLogicalHeight(height() + heightIncrease);
17478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1748bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (marginInfo.canCollapseWithMarginBefore()) {
17498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We can no longer collapse with the top of the block since a clear
17508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // occurred.  The empty blocks collapse into the cleared block.
17518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: This isn't quite correct.  Need clarification for what to do
17528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // if the height the cleared block is offset by is smaller than the
17538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // margins involved.
1754bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setMaxMarginBeforeValues(oldTopPosMargin, oldTopNegMargin);
1755bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        marginInfo.setAtBeforeSideOfBlock(false);
17568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
17578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
17588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return yPos + heightIncrease;
17598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1761a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::estimateLogicalTopPosition(RenderBox* child, const MarginInfo& marginInfo)
17628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
17638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: We need to eliminate the estimation of vertical position, because when it's wrong we sometimes trigger a pathological
17648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // relayout if there are intruding floats.
1765a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalTopEstimate = logicalHeight();
1766bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (!marginInfo.canCollapseWithMarginBefore()) {
1767a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int childMarginBefore = child->selfNeedsLayout() ? marginBeforeForChild(child) : collapsedMarginBeforeForChild(child);
1768a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        logicalTopEstimate += max(marginInfo.margin(), childMarginBefore);
17698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
177068513a70bcd92384395513322f1b801e7bf9c729Steve Block
177168513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool paginated = view()->layoutState()->isPaginated();
177268513a70bcd92384395513322f1b801e7bf9c729Steve Block
1773a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Adjust logicalTopEstimate down to the next page if the margins are so large that we don't fit on the current
177468513a70bcd92384395513322f1b801e7bf9c729Steve Block    // page.
1775a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (paginated && logicalTopEstimate > logicalHeight())
17762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        logicalTopEstimate = min(logicalTopEstimate, nextPageLogicalTop(logicalHeight()));
177768513a70bcd92384395513322f1b801e7bf9c729Steve Block
1778a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    logicalTopEstimate += getClearDelta(child, logicalTopEstimate);
177968513a70bcd92384395513322f1b801e7bf9c729Steve Block
178068513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (paginated) {
178168513a70bcd92384395513322f1b801e7bf9c729Steve Block        // If the object has a page or column break value of "before", then we should shift to the top of the next page.
1782a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        logicalTopEstimate = applyBeforeBreak(child, logicalTopEstimate);
178368513a70bcd92384395513322f1b801e7bf9c729Steve Block
178468513a70bcd92384395513322f1b801e7bf9c729Steve 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.
1785a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        logicalTopEstimate = adjustForUnsplittableChild(child, logicalTopEstimate);
178668513a70bcd92384395513322f1b801e7bf9c729Steve Block
178768513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (!child->selfNeedsLayout() && child->isRenderBlock())
1788a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            logicalTopEstimate += toRenderBlock(child)->paginationStrut();
178968513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
179068513a70bcd92384395513322f1b801e7bf9c729Steve Block
1791a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return logicalTopEstimate;
17928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1794a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::determineLogicalLeftPositionForChild(RenderBox* child)
17958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1796a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int startPosition = borderStart() + paddingStart();
1797a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + availableLogicalWidth();
1798a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1799a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Add in our start margin.
1800a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int childMarginStart = marginStartForChild(child);
1801a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int newPosition = startPosition + childMarginStart;
18028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1803a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats.  They need
1804a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // to shift over as necessary to dodge any floats that might get in the way.
1805a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (child->avoidsFloats()) {
1806a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int startOff = style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(logicalHeight(), false) : totalAvailableLogicalWidth - logicalRightOffsetForLine(logicalHeight(), false);
1807a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->textAlign() != WEBKIT_CENTER && !child->style()->marginStartUsing(style()).isAuto()) {
1808a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (childMarginStart < 0)
1809a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                startOff += childMarginStart;
1810a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            newPosition = max(newPosition, startOff); // Let the float sit in the child's margin if it can fit.
1811a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        } else if (startOff != startPosition) {
1812a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // The object is shifting to the "end" side of the block. The object might be centered, so we need to
1813a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // recalculate our inline direction margins. Note that the containing block content
1814a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // width computation will take into account the delta between |startOff| and |startPosition|
1815a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // so that we can just pass the content width in directly to the |computeMarginsInContainingBlockInlineDirection|
1816a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // function.
1817a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->computeInlineDirectionMargins(this, availableLogicalWidthForLine(logicalTopForChild(child), false), logicalWidthForChild(child));
1818a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            newPosition = startOff + marginStartForChild(child);
18198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
18208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1821a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1822a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalLeftForChild(child, style()->isLeftToRightDirection() ? newPosition : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child), ApplyLayoutDelta);
18238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::setCollapsedBottomMargin(const MarginInfo& marginInfo)
18268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1827bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()) {
18288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Update our max pos/neg bottom margins, since we collapsed our bottom margins
18298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // with our children.
1830a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setMaxMarginAfterValues(max(maxPositiveMarginAfter(), marginInfo.positiveMargin()), max(maxNegativeMarginAfter(), marginInfo.negativeMargin()));
18318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1832bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (!marginInfo.marginAfterQuirk())
1833bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setMarginAfterQuirk(false);
18348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1835a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (marginInfo.marginAfterQuirk() && marginAfter() == 0)
18368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We have no bottom margin and our last child has a quirky margin.
18378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We will pick up this quirky margin and pass it through.
18388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // This deals with the <td><div><p> case.
1839bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setMarginAfterQuirk(true);
18408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
18418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1843a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::handleAfterSideOfBlock(int beforeSide, int afterSide, MarginInfo& marginInfo)
18448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1845bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    marginInfo.setAtAfterSideOfBlock(true);
18468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If we can't collapse with children then go ahead and add in the bottom margin.
1848bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (!marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()
1849bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.marginAfterQuirk()))
1850a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalHeight(logicalHeight() + marginInfo.margin());
18518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Now add in our bottom border/padding.
1853a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalHeight(logicalHeight() + afterSide);
18548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Negative margins can cause our height to shrink below our minimal height (border/padding).
18568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If this happens, ensure that the computed height is increased to the minimal height.
1857a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalHeight(max(logicalHeight(), beforeSide + afterSide));
18588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Update our bottom collapsed margin info.
18608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setCollapsedBottomMargin(marginInfo);
18618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1863a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setLogicalLeftForChild(RenderBox* child, int logicalLeft, ApplyLayoutDeltaMode applyDelta)
1864a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
18652bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode()) {
1866a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (applyDelta == ApplyLayoutDelta)
1867a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            view()->addLayoutDelta(IntSize(child->x() - logicalLeft, 0));
1868a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setX(logicalLeft);
1869a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else {
1870a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (applyDelta == ApplyLayoutDelta)
1871a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            view()->addLayoutDelta(IntSize(0, child->y() - logicalLeft));
1872a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setY(logicalLeft);
1873a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
1874a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1875a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1876a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setLogicalTopForChild(RenderBox* child, int logicalTop, ApplyLayoutDeltaMode applyDelta)
1877a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
18782bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode()) {
1879a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (applyDelta == ApplyLayoutDelta)
1880a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            view()->addLayoutDelta(IntSize(0, child->y() - logicalTop));
1881a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setY(logicalTop);
1882a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else {
1883a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (applyDelta == ApplyLayoutDelta)
1884a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            view()->addLayoutDelta(IntSize(child->x() - logicalTop, 0));
1885a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setX(logicalTop);
1886a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
1887a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1888a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1889a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatLogicalBottom)
18908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
18918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (gPercentHeightDescendantsMap) {
18928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (HashSet<RenderBox*>* descendants = gPercentHeightDescendantsMap->get(this)) {
18938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            HashSet<RenderBox*>::iterator end = descendants->end();
18948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (HashSet<RenderBox*>::iterator it = descendants->begin(); it != end; ++it) {
18958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                RenderBox* box = *it;
18968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                while (box != this) {
18978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (box->normalChildNeedsLayout())
18988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
18998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    box->setChildNeedsLayout(true, false);
19008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    box = box->containingBlock();
19018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    ASSERT(box);
19028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (!box)
19038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
19048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
19058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
19068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
19078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
19088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1909a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int beforeEdge = borderBefore() + paddingBefore();
1910a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
19118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1912a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalHeight(beforeEdge);
19138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The margin struct caches all our current margin collapsing state.  The compact struct caches state when we encounter compacts,
1915a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    MarginInfo marginInfo(this, beforeEdge, afterEdge);
19168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Fieldsets need to find their legend and position it inside the border of the object.
19184576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    // The legend then gets skipped during normal layout.  The same is true for ruby text.
19194576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    // It doesn't get included in the normal layout process but is instead skipped.
19204576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    RenderObject* childToExclude = layoutSpecialExcludedChild(relayoutChildren);
19218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1922a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int previousFloatLogicalBottom = 0;
1923a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    maxFloatLogicalBottom = 0;
19248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RenderBox* next = firstChildBox();
19265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
19275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    while (next) {
19285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        RenderBox* child = next;
19295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        next = child->nextSiblingBox();
19305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
19314576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        if (childToExclude == child)
19324576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            continue; // Skip this child, since it will be positioned by the specialized subclass (fieldsets and ruby runs).
19338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Make sure we layout children if they need it.
19358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into
19368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // an auto value.  Add a method to determine this, so that we can avoid the relayout.
1937a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (relayoutChildren || ((child->style()->logicalHeight().isPercent() || child->style()->logicalMinHeight().isPercent() || child->style()->logicalMaxHeight().isPercent()) && !isRenderView()))
19388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            child->setChildNeedsLayout(true, false);
19398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1940a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // If relayoutChildren is set and the child has percentage padding, we also need to invalidate the child's pref widths.
1941a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (relayoutChildren && (child->style()->paddingStart().isPercent() || child->style()->paddingEnd().isPercent()))
1942bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            child->setPreferredLogicalWidthsDirty(true, false);
19438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Handle the four types of special elements first.  These include positioned content, floating content, compacts and
19458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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.
19465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (handleSpecialChild(child, marginInfo))
19478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
19488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1949231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Lay out the child.
1950a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        layoutBlockChild(child, marginInfo, previousFloatLogicalBottom, maxFloatLogicalBottom);
1951231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
1952231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1953231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Now do the handling of the bottom of the block, adding in our bottom border/padding and
1954231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // determining the correct collapsed bottom margin information.
1955a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    handleAfterSideOfBlock(beforeEdge, afterEdge, marginInfo);
1956231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
19578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1958a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, int& previousFloatLogicalBottom, int& maxFloatLogicalBottom)
1959231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
1960a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int oldPosMarginBefore = maxPositiveMarginBefore();
1961a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int oldNegMarginBefore = maxNegativeMarginBefore();
19628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1963a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // The child is a normal flow object.  Compute the margins we will use for collapsing now.
1964bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    child->computeBlockDirectionMargins(this);
19658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1966a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Do not allow a collapse if the margin-before-collapse style is set to SEPARATE.
1967bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (child->style()->marginBeforeCollapse() == MSEPARATE) {
1968bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        marginInfo.setAtBeforeSideOfBlock(false);
1969231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        marginInfo.clearMargin();
1970231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
1971231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1972a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Try to guess our correct logical top position.  In most cases this guess will
1973a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // be correct.  Only if we're wrong (when we compute the real logical top position)
1974231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // will we have to potentially relayout.
1975a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalTopEstimate = estimateLogicalTopPosition(child, marginInfo);
1976231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1977231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Cache our old rect so that we can dirty the proper repaint rects if the child moves.
1978231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    IntRect oldRect(child->x(), child->y() , child->width(), child->height());
1979a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int oldLogicalTop = logicalTopForChild(child);
1980a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1981635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#ifndef NDEBUG
1982231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    IntSize oldLayoutDelta = view()->layoutDelta();
1983635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif
1984231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Go ahead and position the child as though it didn't collapse with the top.
1985a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalTopForChild(child, logicalTopEstimate, ApplyLayoutDelta);
1986231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
198768513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0;
1988231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    bool markDescendantsWithFloats = false;
1989a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (logicalTopEstimate != oldLogicalTop && !child->avoidsFloats() && childRenderBlock && childRenderBlock->containsFloats())
1990231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        markDescendantsWithFloats = true;
1991231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) {
1992231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // If an element might be affected by the presence of floats, then always mark it for
1993231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // layout.
1994a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int fb = max(previousFloatLogicalBottom, lowestFloatLogicalBottom());
1995a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (fb > logicalTopEstimate)
19968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            markDescendantsWithFloats = true;
1997231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
19988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
199968513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (childRenderBlock) {
2000231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (markDescendantsWithFloats)
200168513a70bcd92384395513322f1b801e7bf9c729Steve Block            childRenderBlock->markAllDescendantsWithFloatsForLayout();
2002a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!child->isWritingModeRoot())
2003a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            previousFloatLogicalBottom = max(previousFloatLogicalBottom, oldLogicalTop + childRenderBlock->lowestFloatLogicalBottom());
2004231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
20058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2006a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!child->needsLayout())
2007a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->markForPaginationRelayoutIfNeeded();
200868513a70bcd92384395513322f1b801e7bf9c729Steve Block
2009231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    bool childHadLayout = child->m_everHadLayout;
2010231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    bool childNeededLayout = child->needsLayout();
2011231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (childNeededLayout)
2012231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        child->layout();
20138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
201468513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Cache if we are at the top of the block right now.
2015bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock();
201668513a70bcd92384395513322f1b801e7bf9c729Steve Block
2017231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Now determine the correct ypos based off examination of collapsing margin
2018231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // values.
2019a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalTopBeforeClear = collapseMargins(child, marginInfo);
20208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2021231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Now check for clear.
2022a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalTopAfterClear = clearFloatsIfNeeded(child, marginInfo, oldPosMarginBefore, oldNegMarginBefore, logicalTopBeforeClear);
20238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2024a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool paginated = view()->layoutState()->isPaginated();
202568513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (paginated) {
2026a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int oldTop = logicalTopAfterClear;
202768513a70bcd92384395513322f1b801e7bf9c729Steve Block
202868513a70bcd92384395513322f1b801e7bf9c729Steve Block        // If the object has a page or column break value of "before", then we should shift to the top of the next page.
2029a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        logicalTopAfterClear = applyBeforeBreak(child, logicalTopAfterClear);
203068513a70bcd92384395513322f1b801e7bf9c729Steve Block
203168513a70bcd92384395513322f1b801e7bf9c729Steve 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.
2032a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int logicalTopBeforeUnsplittableAdjustment = logicalTopAfterClear;
2033a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChild(child, logicalTopAfterClear);
203468513a70bcd92384395513322f1b801e7bf9c729Steve Block
203568513a70bcd92384395513322f1b801e7bf9c729Steve Block        int paginationStrut = 0;
2036a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustment - logicalTopBeforeUnsplittableAdjustment;
203768513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (unsplittableAdjustmentDelta)
203868513a70bcd92384395513322f1b801e7bf9c729Steve Block            paginationStrut = unsplittableAdjustmentDelta;
203968513a70bcd92384395513322f1b801e7bf9c729Steve Block        else if (childRenderBlock && childRenderBlock->paginationStrut())
204068513a70bcd92384395513322f1b801e7bf9c729Steve Block            paginationStrut = childRenderBlock->paginationStrut();
204168513a70bcd92384395513322f1b801e7bf9c729Steve Block
204268513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (paginationStrut) {
204368513a70bcd92384395513322f1b801e7bf9c729Steve Block            // We are willing to propagate out to our parent block as long as we were at the top of the block prior
204468513a70bcd92384395513322f1b801e7bf9c729Steve Block            // to collapsing our margins, and as long as we didn't clear or move as a result of other pagination.
2045a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (atBeforeSideOfBlock && oldTop == logicalTopBeforeClear && !isPositioned() && !isTableCell()) {
204668513a70bcd92384395513322f1b801e7bf9c729Steve Block                // FIXME: Should really check if we're exceeding the page height before propagating the strut, but we don't
204768513a70bcd92384395513322f1b801e7bf9c729Steve Block                // have all the information to do so (the strut only has the remaining amount to push).  Gecko gets this wrong too
204868513a70bcd92384395513322f1b801e7bf9c729Steve Block                // and pushes to the next page anyway, so not too concerned about it.
2049a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                setPaginationStrut(logicalTopAfterClear + paginationStrut);
205068513a70bcd92384395513322f1b801e7bf9c729Steve Block                if (childRenderBlock)
205168513a70bcd92384395513322f1b801e7bf9c729Steve Block                    childRenderBlock->setPaginationStrut(0);
205268513a70bcd92384395513322f1b801e7bf9c729Steve Block            } else
2053a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                logicalTopAfterClear += paginationStrut;
205468513a70bcd92384395513322f1b801e7bf9c729Steve Block        }
205568513a70bcd92384395513322f1b801e7bf9c729Steve Block
205668513a70bcd92384395513322f1b801e7bf9c729Steve Block        // Similar to how we apply clearance.  Go ahead and boost height() to be the place where we're going to position the child.
2057a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalHeight(logicalHeight() + (logicalTopAfterClear - oldTop));
205868513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
205968513a70bcd92384395513322f1b801e7bf9c729Steve Block
2060a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalTopForChild(child, logicalTopAfterClear, ApplyLayoutDelta);
2061231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
2062a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Now we have a final top position.  See if it really does end up being different from our estimate.
2063a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (logicalTopAfterClear != logicalTopEstimate) {
2064231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (child->shrinkToAvoidFloats()) {
2065231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // The child's width depends on the line width.
2066231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // When the child shifts to clear an item, its width can
2067231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // change (because it has more available line width).
2068231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // So go ahead and mark the item as dirty.
2069231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            child->setChildNeedsLayout(true, false);
20708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
207168513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (childRenderBlock) {
207268513a70bcd92384395513322f1b801e7bf9c729Steve Block            if (!child->avoidsFloats() && childRenderBlock->containsFloats())
207368513a70bcd92384395513322f1b801e7bf9c729Steve Block                childRenderBlock->markAllDescendantsWithFloatsForLayout();
2074a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (!child->needsLayout())
2075a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                child->markForPaginationRelayoutIfNeeded();
207668513a70bcd92384395513322f1b801e7bf9c729Steve Block        }
207768513a70bcd92384395513322f1b801e7bf9c729Steve Block
2078231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Our guess was wrong. Make the child lay itself out again.
2079231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        child->layoutIfNeeded();
2080231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
20818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2082231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // We are no longer at the top of the block if we encounter a non-empty child.
2083231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // This has to be done after checking for clear, so that margins can be reset if a clear occurred.
2084bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (marginInfo.atBeforeSideOfBlock() && !child->isSelfCollapsingBlock())
2085bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        marginInfo.setAtBeforeSideOfBlock(false);
20868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2087a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Now place the child in the correct left position
2088a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    determineLogicalLeftPositionForChild(child);
20898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2090231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Update our height now that the child has been placed in the correct position.
2091a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalHeight(logicalHeight() + logicalHeightForChild(child));
2092bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (child->style()->marginAfterCollapse() == MSEPARATE) {
2093a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalHeight(logicalHeight() + marginAfterForChild(child));
2094231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        marginInfo.clearMargin();
2095231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
2096231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // If the child has overhanging floats that intrude into following siblings (or possibly out
2097231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // of this block), then the parent gets notified of the floats now.
209868513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (childRenderBlock && childRenderBlock->containsFloats())
2099a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        maxFloatLogicalBottom = max(maxFloatLogicalBottom, addOverhangingFloats(toRenderBlock(child), -child->logicalLeft(), -child->logicalTop(), !childNeededLayout));
21008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2101231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    IntSize childOffset(child->x() - oldRect.x(), child->y() - oldRect.y());
2102231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (childOffset.width() || childOffset.height()) {
2103231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        view()->addLayoutDelta(childOffset);
21048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2105231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // If the child moved, we have to repaint it as well as any floating/positioned
2106231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // descendants.  An exception is if we need a layout.  In this case, we know we're going to
2107231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // repaint ourselves (and the child) anyway.
2108231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (childHadLayout && !selfNeedsLayout() && child->checkForRepaintDuringLayout())
2109231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            child->repaintDuringLayoutIfMoved(oldRect);
2110231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
21118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2112231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!childHadLayout && child->checkForRepaintDuringLayout()) {
2113231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        child->repaint();
2114231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        child->repaintOverhangingFloats(true);
21158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
21168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
211768513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (paginated) {
211868513a70bcd92384395513322f1b801e7bf9c729Steve Block        // Check for an after page/column break.
21192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int newHeight = applyAfterBreak(child, logicalHeight(), marginInfo);
212068513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (newHeight != height())
2121bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setLogicalHeight(newHeight);
212268513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
212368513a70bcd92384395513322f1b801e7bf9c729Steve Block
2124231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    ASSERT(oldLayoutDelta == view()->layoutDelta());
21258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
21268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21272bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid RenderBlock::simplifiedNormalFlowLayout()
21288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
21292bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (childrenInline()) {
21302bde8e466a4451c7319e3a072d118917957d6554Steve Block        ListHashSet<RootInlineBox*> lineBoxes;
21312bde8e466a4451c7319e3a072d118917957d6554Steve Block        bool endOfInline = false;
21322bde8e466a4451c7319e3a072d118917957d6554Steve Block        RenderObject* o = bidiFirst(this, 0, false);
21332bde8e466a4451c7319e3a072d118917957d6554Steve Block        while (o) {
21342bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (!o->isPositioned() && (o->isReplaced() || o->isFloating())) {
21352bde8e466a4451c7319e3a072d118917957d6554Steve Block                o->layoutIfNeeded();
21362bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (toRenderBox(o)->inlineBoxWrapper()) {
21372bde8e466a4451c7319e3a072d118917957d6554Steve Block                    RootInlineBox* box = toRenderBox(o)->inlineBoxWrapper()->root();
21382bde8e466a4451c7319e3a072d118917957d6554Steve Block                    lineBoxes.add(box);
21392bde8e466a4451c7319e3a072d118917957d6554Steve Block                }
21402bde8e466a4451c7319e3a072d118917957d6554Steve Block            } else if (o->isText() || (o->isRenderInline() && !endOfInline))
21412bde8e466a4451c7319e3a072d118917957d6554Steve Block                o->setNeedsLayout(false);
21422bde8e466a4451c7319e3a072d118917957d6554Steve Block            o = bidiNext(this, o, 0, false, &endOfInline);
21432bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
21442bde8e466a4451c7319e3a072d118917957d6554Steve Block
21452bde8e466a4451c7319e3a072d118917957d6554Steve Block        // FIXME: Glyph overflow will get lost in this case, but not really a big deal.
21462bde8e466a4451c7319e3a072d118917957d6554Steve Block        GlyphOverflowAndFallbackFontsMap textBoxDataMap;
21472bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it != lineBoxes.end(); ++it) {
21482bde8e466a4451c7319e3a072d118917957d6554Steve Block            RootInlineBox* box = *it;
21492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap);
21502bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
21512bde8e466a4451c7319e3a072d118917957d6554Steve Block    } else {
21522bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (RenderBox* box = firstChildBox(); box; box = box->nextSiblingBox()) {
21532bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (!box->isPositioned())
21542bde8e466a4451c7319e3a072d118917957d6554Steve Block                box->layoutIfNeeded();
21552bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
21562bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
21572bde8e466a4451c7319e3a072d118917957d6554Steve Block}
21582bde8e466a4451c7319e3a072d118917957d6554Steve Block
21592bde8e466a4451c7319e3a072d118917957d6554Steve Blockbool RenderBlock::simplifiedLayout()
21602bde8e466a4451c7319e3a072d118917957d6554Steve Block{
21612bde8e466a4451c7319e3a072d118917957d6554Steve Block    if ((!posChildNeedsLayout() && !needsSimplifiedNormalFlowLayout()) || normalChildNeedsLayout() || selfNeedsLayout())
21628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
21638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21646b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
21652bde8e466a4451c7319e3a072d118917957d6554Steve Block
21662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (needsPositionedMovementLayout() && !tryLayoutDoingPositionedMovementOnly())
21672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return false;
21688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21692bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Lay out positioned descendants or objects that just need to recompute overflow.
21702bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (needsSimplifiedNormalFlowLayout())
21712bde8e466a4451c7319e3a072d118917957d6554Steve Block        simplifiedNormalFlowLayout();
21722bde8e466a4451c7319e3a072d118917957d6554Steve Block
21732bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Lay out our positioned objects if our positioned child bit is set.
21742bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (posChildNeedsLayout())
21752bde8e466a4451c7319e3a072d118917957d6554Steve Block        layoutPositionedObjects(false);
21768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2177f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Recompute our overflow information.
2178f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // FIXME: We could do better here by computing a temporary overflow object from layoutPositionedObjects and only
2179f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // updating our overflow if we either used to have overflow or if the new temporary object has overflow.
2180f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // For now just always recompute overflow.  This is no worse performance-wise than the old code that called rightmostPosition and
2181f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // lowestPosition on every relayout so it's not a regression.
2182f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    m_overflow.clear();
2183f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    computeOverflow(clientLogicalBottom(), true);
2184f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
2185635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    statePusher.pop();
2186f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
2187f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    updateLayerTransform();
21888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    updateScrollInfoAfterLayout();
21908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setNeedsLayout(false);
21928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
21938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
21948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::layoutPositionedObjects(bool relayoutChildren)
21968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2197f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!m_positionedObjects)
2198f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return;
2199f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
2200f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (hasColumns())
2201f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        view()->layoutState()->clearPaginationInformation(); // Positioned objects are not part of the column flow, so they don't paginate with the columns.
220268513a70bcd92384395513322f1b801e7bf9c729Steve Block
2203f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    RenderBox* r;
2204f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    Iterator end = m_positionedObjects->end();
2205f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
2206f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        r = *it;
2207f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the
2208f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // non-positioned block.  Rather than trying to detect all of these movement cases, we just always lay out positioned
2209f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // objects that are positioned implicitly like this.  Such objects are rare, and so in typical DHTML menu usage (where everything is
2210f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // positioned explicitly) this should not incur a performance penalty.
22112bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (relayoutChildren || (r->style()->hasStaticBlockPosition(isHorizontalWritingMode()) && r->parent() != this && r->parent()->isBlockFlow()))
2212f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            r->setChildNeedsLayout(true, false);
22138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2214f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.
2215f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (relayoutChildren && (r->style()->paddingStart().isPercent() || r->style()->paddingEnd().isPercent()))
2216f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            r->setPreferredLogicalWidthsDirty(true, false);
221768513a70bcd92384395513322f1b801e7bf9c729Steve Block
2218f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (!r->needsLayout())
2219f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            r->markForPaginationRelayoutIfNeeded();
2220f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
2221f05b935882198ccf7d81675736e3aeb089c5113aBen 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
2222f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // and we hit the available width constraint, the layoutIfNeeded() will catch it and do a full layout.
22232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (r->needsPositionedMovementLayoutOnly() && r->tryLayoutDoingPositionedMovementOnly())
22242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            r->setNeedsLayout(false);
2225f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        r->layoutIfNeeded();
22268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2227f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
2228f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (hasColumns())
2229f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        view()->layoutState()->m_columnInfo = columnInfo(); // FIXME: Kind of gross. We just put this back into the layout state so that pop() will work.
22308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
22318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::markPositionedObjectsForLayout()
22338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
22348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_positionedObjects) {
2235635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        RenderBox* r;
22368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Iterator end = m_positionedObjects->end();
22378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
22388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            r = *it;
22398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            r->setChildNeedsLayout(true);
22408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
22418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
22428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
22438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2244a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::markForPaginationRelayoutIfNeeded()
2245a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
2246a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ASSERT(!needsLayout());
2247a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (needsLayout())
2248a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
2249a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
22502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(logicalTop()) != pageLogicalOffset()))
2251a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setChildNeedsLayout(true, false);
2252a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
2253a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
22548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::repaintOverhangingFloats(bool paintAllDescendants)
22558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
22568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Repaint any overhanging floats (if we know we're the one to paint them).
225754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    // Otherwise, bail out.
225854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    if (!hasOverhangingFloats())
225954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        return;
22608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
226154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    // FIXME: Avoid disabling LayoutState. At the very least, don't disable it for floats originating
226254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    // in this block. Better yet would be to push extra state for the containers of other floats.
226354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    view()->disableLayoutState();
226454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
226554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    FloatingObjectSetIterator end = floatingObjectSet.end();
226654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
226754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        FloatingObject* r = *it;
226854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        // Only repaint the object if it is overhanging, is not in its own layer, and
226954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        // is our responsibility to paint (m_shouldPaint is set). When paintAllDescendants is true, the latter
227054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        // condition is replaced with being a descendant of us.
227154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        if (logicalBottomForFloat(r) > logicalHeight() && ((paintAllDescendants && r->m_renderer->isDescendantOf(this)) || r->m_shouldPaint) && !r->m_renderer->hasSelfPaintingLayer()) {
227254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block            r->m_renderer->repaint();
227354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block            r->m_renderer->repaintOverhangingFloats();
22748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
22758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
227654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    view()->enableLayoutState();
22778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
22788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
22798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paint(PaintInfo& paintInfo, int tx, int ty)
22808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2281635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    tx += x();
2282635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ty += y();
22838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    PaintPhase phase = paintInfo.phase;
22858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Check if we need to do anything at all.
22878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
22888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // paints the root's background.
2289635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!isRoot()) {
2290f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        IntRect overflowBox = visualOverflowRect();
22912bde8e466a4451c7319e3a072d118917957d6554Steve Block        flipForWritingMode(overflowBox);
22928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        overflowBox.inflate(maximalOutlineSize(paintInfo.phase));
22938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        overflowBox.move(tx, ty);
22948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!overflowBox.intersects(paintInfo.rect))
22958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
22968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
22978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool pushedClip = pushContentsClip(paintInfo, tx, ty);
22998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    paintObject(paintInfo, tx, ty);
23008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (pushedClip)
23018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        popContentsClip(paintInfo, phase, tx, ty);
23028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
23038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
23048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // z-index.  We paint after we painted the background/border, so that the scrollbars will
23058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // sit above the background/border.
2306ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.shouldPaintWithinRoot(this))
23078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        layer()->paintOverflowControls(paintInfo.context, tx, ty, paintInfo.rect);
23088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
23098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
23108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::paintColumnRules(PaintInfo& paintInfo, int tx, int ty)
23118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
2312dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    const Color& ruleColor = style()->visitedDependentColor(CSSPropertyWebkitColumnRuleColor);
23138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool ruleTransparent = style()->columnRuleIsTransparent();
23148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    EBorderStyle ruleStyle = style()->columnRuleStyle();
23158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int ruleWidth = style()->columnRuleWidth();
23168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int colGap = columnGap();
23178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent && ruleWidth <= colGap;
23188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!renderRule)
23198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
23208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
23218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // We need to do multiple passes, breaking up our child painting into strips.
23225abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    ColumnInfo* colInfo = columnInfo();
232368513a70bcd92384395513322f1b801e7bf9c729Steve Block    unsigned colCount = columnCount(colInfo);
23242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int currLogicalLeftOffset = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth();
23252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int ruleAdd = logicalLeftOffsetForContent();
23262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int ruleLogicalLeft = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth();
23278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    for (unsigned i = 0; i < colCount; i++) {
232868513a70bcd92384395513322f1b801e7bf9c729Steve Block        IntRect colRect = columnRectAt(colInfo, i);
23298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
23302bde8e466a4451c7319e3a072d118917957d6554Steve Block        int inlineDirectionSize = isHorizontalWritingMode() ? colRect.width() : colRect.height();
23312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
23328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // Move to the next position.
2333a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->isLeftToRightDirection()) {
23342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            ruleLogicalLeft += inlineDirectionSize + colGap / 2;
23352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalLeftOffset += inlineDirectionSize + colGap;
23368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else {
23372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            ruleLogicalLeft -= (inlineDirectionSize + colGap / 2);
23382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalLeftOffset -= (inlineDirectionSize + colGap);
23398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
23408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
23418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // Now paint the column rule.
23428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (i < colCount - 1) {
23432bde8e466a4451c7319e3a072d118917957d6554Steve Block            int ruleLeft = isHorizontalWritingMode() ? tx + ruleLogicalLeft - ruleWidth / 2 + ruleAdd : tx + borderBefore() + paddingBefore();
23442bde8e466a4451c7319e3a072d118917957d6554Steve Block            int ruleRight = isHorizontalWritingMode() ? ruleLeft + ruleWidth : ruleLeft + contentWidth();
23452bde8e466a4451c7319e3a072d118917957d6554Steve Block            int ruleTop = isHorizontalWritingMode() ? ty + borderTop() + paddingTop() : ty + ruleLogicalLeft - ruleWidth / 2 + ruleAdd;
23462bde8e466a4451c7319e3a072d118917957d6554Steve Block            int ruleBottom = isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleWidth;
23472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            drawLineForBoxSide(paintInfo.context, ruleLeft, ruleTop, ruleRight, ruleBottom,
2348a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                               style()->isLeftToRightDirection() ? BSLeft : BSRight, ruleColor, ruleStyle, 0, 0);
23498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
23508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
23512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        ruleLogicalLeft = currLogicalLeftOffset;
23528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
23538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
23548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
23558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::paintColumnContents(PaintInfo& paintInfo, int tx, int ty, bool paintingFloats)
23568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
23578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We need to do multiple passes, breaking up our child painting into strips.
23588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GraphicsContext* context = paintInfo.context;
23595abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    ColumnInfo* colInfo = columnInfo();
236068513a70bcd92384395513322f1b801e7bf9c729Steve Block    unsigned colCount = columnCount(colInfo);
23616c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (!colCount)
23626c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        return;
23632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int currLogicalTopOffset = 0;
23648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < colCount; i++) {
23658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // For each rect, we clip to the rect, and then we adjust our coords.
236668513a70bcd92384395513322f1b801e7bf9c729Steve Block        IntRect colRect = columnRectAt(colInfo, i);
23672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        flipForWritingMode(colRect);
23682bde8e466a4451c7319e3a072d118917957d6554Steve Block        int logicalLeftOffset = (isHorizontalWritingMode() ? colRect.x() : colRect.y()) - logicalLeftOffsetForContent();
23692bde8e466a4451c7319e3a072d118917957d6554Steve Block        IntSize offset = isHorizontalWritingMode() ? IntSize(logicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, logicalLeftOffset);
23708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        colRect.move(tx, ty);
23718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PaintInfo info(paintInfo);
23728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        info.rect.intersect(colRect);
23738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2374e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        if (!info.rect.isEmpty()) {
2375e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            context->save();
2376e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block
2377e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            // Each strip pushes a clip, since column boxes are specified as being
2378e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            // like overflow:hidden.
2379e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            context->clip(colRect);
23802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2381e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            // Adjust our x and y when painting.
23822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int finalX = tx + offset.width();
23832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int finalY = ty + offset.height();
2384e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            if (paintingFloats)
2385e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block                paintFloats(info, finalX, finalY, paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip);
2386e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            else
2387e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block                paintContents(info, finalX, finalY);
23888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2389e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            context->restore();
2390e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        }
23912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
23922bde8e466a4451c7319e3a072d118917957d6554Steve Block        int blockDelta = (isHorizontalWritingMode() ? colRect.height() : colRect.width());
23932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (style()->isFlippedBlocksWritingMode())
23942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalTopOffset += blockDelta;
23958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        else
23962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalTopOffset -= blockDelta;
23978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
23988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
23998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintContents(PaintInfo& paintInfo, int tx, int ty)
24018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
24028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Avoid painting descendants of the root element when stylesheets haven't loaded.  This eliminates FOUC.
24038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
24048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // will do a full repaint().
24052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (document()->didLayoutWithPendingStylesheets() && !isRenderView())
24068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
24078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childrenInline())
24098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_lineBoxes.paint(this, paintInfo, tx, ty);
24108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
24118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        paintChildren(paintInfo, tx, ty);
24128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
24138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
24158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
24168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
24178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;
24188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We don't paint our own background, but we do let the kids paint their backgrounds.
24208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    PaintInfo info(paintInfo);
24218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    info.phase = newPhase;
2422ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    info.updatePaintingRootForChildren(this);
24235ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
242468513a70bcd92384395513322f1b801e7bf9c729Steve Block    // FIXME: Paint-time pagination is obsolete and is now only used by embedded WebViews inside AppKit
242568513a70bcd92384395513322f1b801e7bf9c729Steve Block    // NSViews.  Do not add any more code for this.
24265ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    RenderView* renderView = view();
242768513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool usePrintRect = !renderView->printRect().isEmpty();
24285ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
2429635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
24308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Check for page-break-before: always, and if it's set, break and bail.
243168513a70bcd92384395513322f1b801e7bf9c729Steve Block        bool checkBeforeAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakBefore() == PBALWAYS);
2432545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (checkBeforeAlways
2433dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            && (ty + child->y()) > paintInfo.rect.y()
24342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            && (ty + child->y()) < paintInfo.rect.maxY()) {
2435635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            view()->setBestTruncatedAt(ty + child->y(), this, true);
24368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
24378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
24388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24395ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        if (!child->isFloating() && child->isReplaced() && usePrintRect && child->height() <= renderView->printRect().height()) {
24405ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            // Paginate block-level replaced elements.
24412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (ty + child->y() + child->height() > renderView->printRect().maxY()) {
24425ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                if (ty + child->y() < renderView->truncatedAt())
24435ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                    renderView->setBestTruncatedAt(ty + child->y(), child);
24445ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                // If we were able to truncate, don't paint.
24455ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                if (ty + child->y() >= renderView->truncatedAt())
24465ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                    break;
24475ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            }
24485ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        }
24495ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
245028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        IntPoint childPoint = flipForWritingMode(child, IntPoint(tx, ty), ParentToChildFlippingAdjustment);
24518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (!child->hasSelfPaintingLayer() && !child->isFloating())
2452e14391e94c850b8bd03680c23b38978db68687a8John Reck            child->paint(info, childPoint.x(), childPoint.y());
24538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Check for page-break-after: always, and if it's set, break and bail.
245568513a70bcd92384395513322f1b801e7bf9c729Steve Block        bool checkAfterAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakAfter() == PBALWAYS);
2456545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (checkAfterAlways
2457dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            && (ty + child->y() + child->height()) > paintInfo.rect.y()
24582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            && (ty + child->y() + child->height()) < paintInfo.rect.maxY()) {
2459bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            view()->setBestTruncatedAt(ty + child->y() + child->height() + max(0, child->collapsedMarginAfter()), this, true);
24608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
24618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
24628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
24638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
24648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2465635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::paintCaret(PaintInfo& paintInfo, int tx, int ty, CaretType type)
24668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
246768513a70bcd92384395513322f1b801e7bf9c729Steve Block    SelectionController* selection = type == CursorCaret ? frame()->selection() : frame()->page()->dragCaretController();
2468635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
24695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Paint the caret if the SelectionController says so or if caret browsing is enabled
2470545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    bool caretBrowsing = frame()->settings() && frame()->settings()->caretBrowsingEnabled();
2471635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderObject* caretPainter = selection->caretRenderer();
24725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (caretPainter == this && (selection->isContentEditable() || caretBrowsing)) {
2473635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // Convert the painting offset into the local coordinate system of this renderer,
2474635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // to match the localCaretRect computed by the SelectionController
2475635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        offsetForContents(tx, ty);
2476635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
24778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (type == CursorCaret)
2478545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            frame()->selection()->paintCaret(paintInfo.context, tx, ty, paintInfo.rect);
24798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
248068513a70bcd92384395513322f1b801e7bf9c729Steve Block            frame()->selection()->paintDragCaret(paintInfo.context, tx, ty, paintInfo.rect);
24818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
24828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
24838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintObject(PaintInfo& paintInfo, int tx, int ty)
24858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
24868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    PaintPhase paintPhase = paintInfo.phase;
24878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 1. paint background, borders etc
24898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && style()->visibility() == VISIBLE) {
24908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (hasBoxDecorations())
24918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            paintBoxDecorations(paintInfo, tx, ty);
24928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (hasColumns())
24938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            paintColumnRules(paintInfo, tx, ty);
24948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
24958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintPhase == PaintPhaseMask && style()->visibility() == VISIBLE) {
24978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        paintMask(paintInfo, tx, ty);
24988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
24998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
25008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We're done.  We don't bother painting any children.
25028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintPhase == PaintPhaseBlockBackground)
25038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
25048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2505dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).
25068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int scrolledX = tx;
25078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int scrolledY = ty;
2508dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (hasOverflowClip()) {
2509dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        IntSize offset = layer()->scrolledContentOffset();
2510dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        scrolledX -= offset.width();
2511dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        scrolledY -= offset.height();
2512dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
25138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 2. paint contents
25158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintPhase != PaintPhaseSelfOutline) {
25168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (hasColumns())
25178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            paintColumnContents(paintInfo, scrolledX, scrolledY);
25188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
25198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            paintContents(paintInfo, scrolledX, scrolledY);
25208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
25218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 3. paint selection
25238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Make this work with multi column layouts.  For now don't fill gaps.
25248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool isPrinting = document()->printing();
25258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!isPrinting && !hasColumns())
25268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        paintSelection(paintInfo, scrolledX, scrolledY); // Fill in gaps in selection on lines and between blocks.
25278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 4. paint floats.
2529635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip) {
25308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (hasColumns())
25318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            paintColumnContents(paintInfo, scrolledX, scrolledY, true);
25328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
25338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            paintFloats(paintInfo, scrolledX, scrolledY, paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip);
25348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
25358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 5. paint outline.
2537635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
2538dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        paintOutline(paintInfo.context, tx, ty, width(), height());
25398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 6. paint continuation outlines.
2541635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
2542e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        RenderInline* inlineCont = inlineElementContinuation();
2543e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        if (inlineCont && inlineCont->hasOutline() && inlineCont->style()->visibility() == VISIBLE) {
2544e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            RenderInline* inlineRenderer = toRenderInline(inlineCont->node()->renderer());
2545e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            RenderBlock* cb = containingBlock();
2546e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
2547e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            bool inlineEnclosedInSelfPaintingLayer = false;
2548e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            for (RenderBoxModelObject* box = inlineRenderer; box != cb; box = box->parent()->enclosingBoxModelObject()) {
2549e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                if (box->hasSelfPaintingLayer()) {
2550e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                    inlineEnclosedInSelfPaintingLayer = true;
2551e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                    break;
2552e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                }
2553e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            }
2554e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
2555e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            if (!inlineEnclosedInSelfPaintingLayer)
2556e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                cb->addContinuationWithOutline(inlineRenderer);
25578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            else if (!inlineRenderer->firstLineBox())
25588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                inlineRenderer->paintOutline(paintInfo.context, tx - x() + inlineRenderer->containingBlock()->x(),
25598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                                             ty - y() + inlineRenderer->containingBlock()->y());
25608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
25618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        paintContinuationOutlines(paintInfo, tx, ty);
25628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
25638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 7. paint caret.
25658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
25668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // then paint the caret.
2567635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (paintPhase == PaintPhaseForeground) {
2568635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        paintCaret(paintInfo, scrolledX, scrolledY, CursorCaret);
2569635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        paintCaret(paintInfo, scrolledX, scrolledY, DragCaret);
25708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
25718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
25728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25732fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockIntPoint RenderBlock::flipFloatForWritingMode(const FloatingObject* child, const IntPoint& point) const
25742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
25752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!style()->isFlippedBlocksWritingMode())
25762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return point;
25772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
25782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // This is similar to the ParentToChildFlippingAdjustment in RenderBox::flipForWritingMode.  We have to subtract out our left/top offsets twice, since
25792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // it's going to get added back in.  We hide this complication here so that the calling code looks normal for the unflipped
25802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // case.
25812bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
25822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return IntPoint(point.x(), point.y() + height() - child->renderer()->height() - 2 * yPositionForFloatIncludingMargin(child));
25832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return IntPoint(point.x() + width() - child->width() - 2 * xPositionForFloatIncludingMargin(child), point.y());
25842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
25852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
25868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintFloats(PaintInfo& paintInfo, int tx, int ty, bool preservePhase)
25878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
25888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_floatingObjects)
25898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
25908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
259181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
259281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator end = floatingObjectSet.end();
259381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
259481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObject* r = *it;
25958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Only paint the object if our m_shouldPaint flag is set.
25968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
25978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            PaintInfo currentPaintInfo(paintInfo);
25988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
25992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            IntPoint childPoint = flipFloatForWritingMode(r, IntPoint(tx + xPositionForFloatIncludingMargin(r) - r->m_renderer->x(), ty + yPositionForFloatIncludingMargin(r) - r->m_renderer->y()));
2600e14391e94c850b8bd03680c23b38978db68687a8John Reck            r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
26018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!preservePhase) {
26028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                currentPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
2603e14391e94c850b8bd03680c23b38978db68687a8John Reck                r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
26048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                currentPaintInfo.phase = PaintPhaseFloat;
2605e14391e94c850b8bd03680c23b38978db68687a8John Reck                r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
26068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                currentPaintInfo.phase = PaintPhaseForeground;
2607e14391e94c850b8bd03680c23b38978db68687a8John Reck                r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
26088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                currentPaintInfo.phase = PaintPhaseOutline;
2609e14391e94c850b8bd03680c23b38978db68687a8John Reck                r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
26108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
26118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
26128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
26138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
26148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintEllipsisBoxes(PaintInfo& paintInfo, int tx, int ty)
26168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2617ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (!paintInfo.shouldPaintWithinRoot(this) || !firstLineBox())
26188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
26198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->visibility() == VISIBLE && paintInfo.phase == PaintPhaseForeground) {
26218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We can check the first box and last box and avoid painting if we don't
26228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // intersect.
26238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        int yPos = ty + firstLineBox()->y();
2624bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        int h = lastLineBox()->y() + lastLineBox()->logicalHeight() - firstLineBox()->y();
26252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (yPos >= paintInfo.rect.maxY() || yPos + h <= paintInfo.rect.y())
26268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
26278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // See if our boxes intersect with the dirty rect.  If so, then we paint
26298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // them.  Note that boxes can easily overlap, so we can't make any assumptions
26308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // based off positions of our first line box or our last line box.
26318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
26328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            yPos = ty + curr->y();
2633bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            h = curr->logicalHeight();
26342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (curr->ellipsisBox() && yPos < paintInfo.rect.maxY() && yPos + h > paintInfo.rect.y())
26352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                curr->paintEllipsisBox(paintInfo, tx, ty, curr->lineTop(), curr->lineBottom());
26368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
26378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
26388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
26398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2640e78cbe89e6f337f2f1fe40315be88f742b547151Steve BlockRenderInline* RenderBlock::inlineElementContinuation() const
2641e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block{
2642cad810f21b803229eb11403f9209855525a25d57Steve Block    RenderBoxModelObject* continuation = this->continuation();
2643cad810f21b803229eb11403f9209855525a25d57Steve Block    return continuation && continuation->isInline() ? toRenderInline(continuation) : 0;
2644e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block}
2645e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block
2646e78cbe89e6f337f2f1fe40315be88f742b547151Steve BlockRenderBlock* RenderBlock::blockElementContinuation() const
2647e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block{
2648cad810f21b803229eb11403f9209855525a25d57Steve Block    RenderBoxModelObject* currentContinuation = continuation();
2649cad810f21b803229eb11403f9209855525a25d57Steve Block    if (!currentContinuation || currentContinuation->isInline())
2650e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        return 0;
2651cad810f21b803229eb11403f9209855525a25d57Steve Block    RenderBlock* nextContinuation = toRenderBlock(currentContinuation);
2652e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (nextContinuation->isAnonymousBlock())
2653e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        return nextContinuation->blockElementContinuation();
2654545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return nextContinuation;
2655e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block}
2656e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block
2657635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic ContinuationOutlineTableMap* continuationOutlineTable()
26588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2659635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ());
26608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return &table;
26618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
26628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::addContinuationWithOutline(RenderInline* flow)
26648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
26658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We can't make this work if the inline is in a layer.  We'll just rely on the broken
26668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // way of painting.
2667e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    ASSERT(!flow->layer() && !flow->isInlineElementContinuation());
26688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2669635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ContinuationOutlineTableMap* table = continuationOutlineTable();
26708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ListHashSet<RenderInline*>* continuations = table->get(this);
26718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!continuations) {
26728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        continuations = new ListHashSet<RenderInline*>;
26738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        table->set(this, continuations);
26748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
26758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    continuations->add(flow);
26778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
26788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
267981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochbool RenderBlock::paintsContinuationOutline(RenderInline* flow)
268081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
268181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ContinuationOutlineTableMap* table = continuationOutlineTable();
268281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (table->isEmpty())
268381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return false;
268481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
268581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ListHashSet<RenderInline*>* continuations = table->get(this);
268681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!continuations)
268781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return false;
268881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
268981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return continuations->contains(flow);
269081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
269181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
26928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintContinuationOutlines(PaintInfo& info, int tx, int ty)
26938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2694635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ContinuationOutlineTableMap* table = continuationOutlineTable();
26958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (table->isEmpty())
26968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
26978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ListHashSet<RenderInline*>* continuations = table->get(this);
26998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!continuations)
27008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
27018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Paint each continuation outline.
27038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ListHashSet<RenderInline*>::iterator end = continuations->end();
27048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    for (ListHashSet<RenderInline*>::iterator it = continuations->begin(); it != end; ++it) {
27058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Need to add in the coordinates of the intervening blocks.
27068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderInline* flow = *it;
27078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderBlock* block = flow->containingBlock();
27088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for ( ; block && block != this; block = block->containingBlock()) {
2709635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            tx += block->x();
2710635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            ty += block->y();
27118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
27128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(block);
27138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        flow->paintOutline(info.context, tx, ty);
27148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
27158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Delete
27178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    delete continuations;
27188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    table->remove(this);
27198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
27208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::shouldPaintSelectionGaps() const
27228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
27238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot();
27248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
27258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::isSelectionRoot() const
27278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
27288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!node())
27298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
27308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Eventually tables should have to learn how to fill gaps between cells, at least in simple non-spanning cases.
27328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isTable())
27338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
27348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isBody() || isRoot() || hasOverflowClip() || isRelPositioned() ||
27368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        isFloatingOrPositioned() || isTableCell() || isInlineBlockOrInlineTable() || hasTransform() ||
273728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        hasReflection() || hasMask() || isWritingModeRoot())
27388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
27398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (view() && view()->selectionStart()) {
27418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        Node* startElement = view()->selectionStart()->node();
27428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (startElement && startElement->rootEditableElement() == node())
27438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
27448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
27458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
27478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
27488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2749643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockGapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer)
27508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
27518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!needsLayout());
27528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!shouldPaintSelectionGaps())
27548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return GapRects();
27558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2756643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // FIXME: this is broken with transforms
2757643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
2758643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    mapLocalToContainer(repaintContainer, false, false, transformState);
2759dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    IntPoint offsetFromRepaintContainer = roundedIntPoint(transformState.mappedPoint());
2760643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
27618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (hasOverflowClip())
2762dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        offsetFromRepaintContainer -= layer()->scrolledContentOffset();
27638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2764635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int lastTop = 0;
276528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int lastLeft = logicalLeftSelectionOffset(this, lastTop);
276628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int lastRight = logicalRightSelectionOffset(this, lastTop);
27678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
276828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return selectionGaps(this, offsetFromRepaintContainer, IntSize(), lastTop, lastLeft, lastRight);
27698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
27708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
27728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
27738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (shouldPaintSelectionGaps() && paintInfo.phase == PaintPhaseForeground) {
2774635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        int lastTop = 0;
277528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        int lastLeft = logicalLeftSelectionOffset(this, lastTop);
277628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        int lastRight = logicalRightSelectionOffset(this, lastTop);
27778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        paintInfo.context->save();
277828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        IntRect gapRectsBounds = selectionGaps(this, IntPoint(tx, ty), IntSize(), lastTop, lastLeft, lastRight, &paintInfo);
2779643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (!gapRectsBounds.isEmpty()) {
2780643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (RenderLayer* layer = enclosingLayer()) {
2781d0825bca7fe65beaee391d30da42e937db621564Steve Block                gapRectsBounds.move(IntSize(-tx, -ty));
2782d0825bca7fe65beaee391d30da42e937db621564Steve Block                if (!hasLayer()) {
27836b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                    IntRect localBounds(gapRectsBounds);
27846b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                    flipForWritingMode(localBounds);
27856b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                    gapRectsBounds = localToContainerQuad(FloatRect(localBounds), layer->renderer()).enclosingBoundingBox();
2786692e5dbf12901edacf14812a6fae25462920af42Steve Block                    gapRectsBounds.move(layer->scrolledContentOffset());
2787d0825bca7fe65beaee391d30da42e937db621564Steve Block                }
2788643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                layer->addBlockSelectionGapsBounds(gapRectsBounds);
2789643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            }
2790643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
27918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        paintInfo.context->restore();
27928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
27938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
27948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
279528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic void clipOutPositionedObjects(const PaintInfo* paintInfo, const IntPoint& offset, RenderBlock::PositionedObjectsListHashSet* positionedObjects)
27968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
27978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!positionedObjects)
27988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
27998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2800e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    RenderBlock::PositionedObjectsListHashSet::const_iterator end = positionedObjects->end();
2801e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
2802635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        RenderBox* r = *it;
280328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r->y(), r->width(), r->height()));
28048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
28058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
28068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
280728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic int blockDirectionOffset(RenderBlock* rootBlock, const IntSize& offsetFromRootBlock)
280828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{
28092bde8e466a4451c7319e3a072d118917957d6554Steve Block    return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.height() : offsetFromRootBlock.width();
281028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu}
281128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
281228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic int inlineDirectionOffset(RenderBlock* rootBlock, const IntSize& offsetFromRootBlock)
281328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{
28142bde8e466a4451c7319e3a072d118917957d6554Steve Block    return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.width() : offsetFromRootBlock.height();
281528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu}
281628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
281728040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuIntRect RenderBlock::logicalRectToPhysicalRect(const IntPoint& rootBlockPhysicalPosition, const IntRect& logicalRect)
281828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{
281928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    IntRect result;
28202bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
282128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        result = logicalRect;
282228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    else
282328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        result = IntRect(logicalRect.y(), logicalRect.x(), logicalRect.height(), logicalRect.width());
282428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    flipForWritingMode(result);
282528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    result.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
282628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return result;
282728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu}
282828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
282928040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuGapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
283028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                    int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo)
28318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
28328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore.
28338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Clip out floating and positioned objects when painting selection gaps.
28348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintInfo) {
28358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Note that we don't clip out overflow for positioned objects.  We just stick to the border box.
283628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        IntRect flippedBlockRect = IntRect(offsetFromRootBlock.width(), offsetFromRootBlock.height(), width(), height());
283728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        rootBlock->flipForWritingMode(flippedBlockRect);
283828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        flippedBlockRect.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
283981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), m_positionedObjects.get());
28408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (isBody() || isRoot()) // The <body> must make sure to examine its containingBlock's positioned objects.
28418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock())
284281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                clipOutPositionedObjects(paintInfo, IntPoint(cb->x(), cb->y()), cb->m_positionedObjects.get()); // FIXME: Not right for flipped writing modes.
28438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_floatingObjects) {
284481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
284581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObjectSetIterator end = floatingObjectSet.end();
284681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
284781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                FloatingObject* r = *it;
28482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                IntRect floatBox = IntRect(offsetFromRootBlock.width() + xPositionForFloatIncludingMargin(r),
28492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                                           offsetFromRootBlock.height() + yPositionForFloatIncludingMargin(r),
285028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                           r->m_renderer->width(), r->m_renderer->height());
285128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                rootBlock->flipForWritingMode(floatBox);
285228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                floatBox.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
285328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                paintInfo->context->clipOut(floatBox);
28548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
28558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
28568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
28578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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
28598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // fixed).
28608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GapRects result;
28618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!isBlockFlow()) // FIXME: Make multi-column selection gap filling work someday.
28628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return result;
28638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28645af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (hasColumns() || hasTransform() || style()->columnSpan()) {
28658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: We should learn how to gap fill multiple columns and transforms eventually.
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        return result;
28708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
28718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childrenInline())
287328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        result = inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
28748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
287528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
28768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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.
28788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd))
287928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
288028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                             logicalHeight(), paintInfo));
28818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
28828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
28838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
288428040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuGapRects RenderBlock::inlineSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
288528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                          int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo)
28868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
28878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GapRects result;
28888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool containsStart = selectionState() == SelectionStart || selectionState() == SelectionBoth;
28908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!firstLineBox()) {
28928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (containsStart) {
289328040489d744e0c5d475a88663056c9040ed5320Teng-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
28948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // case.
289528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
289628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight());
289728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight());
28988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
28998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return result;
29008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
29018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RootInlineBox* lastSelectedLine = 0;
29038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RootInlineBox* curr;
29048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (curr = firstRootBox(); curr && !curr->hasSelectedChildren(); curr = curr->nextRootBox()) { }
29058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Now paint the gaps for the lines.
29078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (; curr && curr->hasSelectedChildren(); curr = curr->nextRootBox()) {
29088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int selTop =  curr->selectionTop();
29098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int selHeight = curr->selectionHeight();
29108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!containsStart && !lastSelectedLine &&
29128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            selectionState() != SelectionStart && selectionState() != SelectionBoth)
291328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
291428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                                 selTop, paintInfo));
291528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
291628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        IntRect logicalRect(curr->logicalLeft(), selTop, curr->logicalWidth(), selTop + selHeight);
29172bde8e466a4451c7319e3a072d118917957d6554Steve Block        logicalRect.move(isHorizontalWritingMode() ? offsetFromRootBlock : IntSize(offsetFromRootBlock.height(), offsetFromRootBlock.width()));
291828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        IntRect physicalRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect);
29192bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!paintInfo || (isHorizontalWritingMode() && physicalRect.y() < paintInfo->rect.maxY() && physicalRect.maxY() > paintInfo->rect.y())
29202bde8e466a4451c7319e3a072d118917957d6554Steve Block            || (!isHorizontalWritingMode() && physicalRect.x() < paintInfo->rect.maxX() && physicalRect.maxX() > paintInfo->rect.x()))
292128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            result.unite(curr->lineSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, selTop, selHeight, paintInfo));
29228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        lastSelectedLine = curr;
29248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
29258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (containsStart && !lastSelectedLine)
29278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // VisibleSelection must start just after our last line.
29288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        lastSelectedLine = lastRootBox();
29298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (lastSelectedLine && selectionState() != SelectionEnd && selectionState() != SelectionBoth) {
29318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Go ahead and update our lastY to be the bottom of the last selected line.
293228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + lastSelectedLine->selectionBottom();
293328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
293428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        lastLogicalRight = logicalRightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
29358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
29368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
29378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
29388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
293928040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuGapRects RenderBlock::blockSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
294028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                         int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo)
29418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
29428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GapRects result;
29438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Go ahead and jump right to the first block child that contains some selected objects.
2945635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderBox* curr;
2946635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    for (curr = firstChildBox(); curr && curr->selectionState() == SelectionNone; curr = curr->nextSiblingBox()) { }
29478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2948635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    for (bool sawSelectionEnd = false; curr && !sawSelectionEnd; curr = curr->nextSiblingBox()) {
29498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        SelectionState childState = curr->selectionState();
29508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (childState == SelectionBoth || childState == SelectionEnd)
29518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            sawSelectionEnd = true;
29528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (curr->isFloatingOrPositioned())
29548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue; // We must be a normal flow object in order to even be considered.
29558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (curr->isRelPositioned() && curr->hasLayer()) {
29578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // If the relposition offset is anything other than 0, then treat this just like an absolute positioned element.
29588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Just disregard it completely.
2959635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            IntSize relOffset = curr->layer()->relativePositionOffset();
2960635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (relOffset.width() || relOffset.height())
29618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
29628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
29638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTable(); // FIXME: Eventually we won't special-case table like this.
29658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool fillBlockGaps = paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone);
29668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (fillBlockGaps) {
29678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We need to fill the vertical gap above this object.
29688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (childState == SelectionEnd || childState == SelectionInside)
29698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Fill the gap above the object.
297028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
297128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                                     curr->logicalTop(), paintInfo));
29728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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*
29748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // our object.  We know this if the selection did not end inside our object.
29758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (paintsOwnSelection && (childState == SelectionStart || sawSelectionEnd))
29768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                childState = SelectionNone;
29778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Fill side gaps on this object based off its state.
29798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            bool leftGap, rightGap;
298028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            getSelectionGapInfo(childState, leftGap, rightGap);
29818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (leftGap)
298328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                result.uniteLeft(logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalLeft(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
29848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (rightGap)
298528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalRight(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
29868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
298728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            // Update lastLogicalTop to be just underneath the object.  lastLogicalLeft and lastLogicalRight extend as far as
29888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // they can without bumping into floating or positioned objects.  Ideally they will go right up
29898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // to the border of the root selection block.
299028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + curr->logicalBottom();
299128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logicalBottom());
299228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logicalBottom());
29938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (childState != SelectionNone)
29948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We must be a block that has some selected object inside it.  Go ahead and recur.
299528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            result.unite(toRenderBlock(curr)->selectionGaps(rootBlock, rootBlockPhysicalPosition, IntSize(offsetFromRootBlock.width() + curr->x(), offsetFromRootBlock.height() + curr->y()),
299628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                                            lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo));
29978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
29988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
29998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
30008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
300128040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuIntRect RenderBlock::blockSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
300228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                       int lastLogicalTop, int lastLogicalLeft, int lastLogicalRight, int logicalBottom, const PaintInfo* paintInfo)
30038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
300428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int logicalTop = lastLogicalTop;
300528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int logicalHeight = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalBottom - logicalTop;
300628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (logicalHeight <= 0)
30078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return IntRect();
30088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
30098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Get the selection offsets for the bottom of the gap
301028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int logicalLeft = max(lastLogicalLeft, logicalLeftSelectionOffset(rootBlock, logicalBottom));
301128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int logicalRight = min(lastLogicalRight, logicalRightSelectionOffset(rootBlock, logicalBottom));
301228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int logicalWidth = logicalRight - logicalLeft;
301328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (logicalWidth <= 0)
30148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return IntRect();
30158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
301628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(logicalLeft, logicalTop, logicalWidth, logicalHeight));
30178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintInfo)
3018643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        paintInfo->context->fillRect(gapRect, selectionBackgroundColor(), style()->colorSpace());
30198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return gapRect;
30208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
30218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
302228040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuIntRect RenderBlock::logicalLeftSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
302328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                             RenderObject* selObj, int logicalLeft, int logicalTop, int logicalHeight, const PaintInfo* paintInfo)
30248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
302528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
302628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalLeft = max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight));
302728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalRight = min(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalLeft, min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight)));
302828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
302928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (rootBlockLogicalWidth <= 0)
30308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return IntRect();
30318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
303228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
30338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintInfo)
3034643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
30358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return gapRect;
30368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
30378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
303828040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuIntRect RenderBlock::logicalRightSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
303928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                              RenderObject* selObj, int logicalRight, int logicalTop, int logicalHeight, const PaintInfo* paintInfo)
30408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
304128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
304228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalLeft = max(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalRight, max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight)));
304328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalRight = min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight));
304428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
304528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (rootBlockLogicalWidth <= 0)
30468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return IntRect();
30478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
304828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
30498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintInfo)
3050643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
30518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return gapRect;
30528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
30538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
305428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuvoid RenderBlock::getSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap)
30558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3056a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool ltr = style()->isLeftToRightDirection();
30578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    leftGap = (state == RenderObject::SelectionInside) ||
30588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project              (state == RenderObject::SelectionEnd && ltr) ||
30598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project              (state == RenderObject::SelectionStart && !ltr);
30608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    rightGap = (state == RenderObject::SelectionInside) ||
30618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project               (state == RenderObject::SelectionStart && ltr) ||
30628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project               (state == RenderObject::SelectionEnd && !ltr);
30638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
30648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
306528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuint RenderBlock::logicalLeftSelectionOffset(RenderBlock* rootBlock, int position)
30668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
306728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int logicalLeft = logicalLeftOffsetForLine(position, false);
306828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (logicalLeft == logicalLeftOffsetForContent()) {
30698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (rootBlock != this)
30708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // The border can potentially be further extended by our containingBlock().
307128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            return containingBlock()->logicalLeftSelectionOffset(rootBlock, position + logicalTop());
307228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        return logicalLeft;
307328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    } else {
30748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderBlock* cb = this;
30758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (cb != rootBlock) {
307628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            logicalLeft += cb->logicalLeft();
30778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            cb = cb->containingBlock();
30788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
30798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
308028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return logicalLeft;
30818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
30828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
308328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuint RenderBlock::logicalRightSelectionOffset(RenderBlock* rootBlock, int position)
30848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
308528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int logicalRight = logicalRightOffsetForLine(position, false);
308628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (logicalRight == logicalRightOffsetForContent()) {
30878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (rootBlock != this)
30888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // The border can potentially be further extended by our containingBlock().
308928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            return containingBlock()->logicalRightSelectionOffset(rootBlock, position + logicalTop());
309028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        return logicalRight;
309128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    } else {
30928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderBlock* cb = this;
30938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (cb != rootBlock) {
309428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            logicalRight += cb->logicalLeft();
30958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            cb = cb->containingBlock();
30968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
30978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
309828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return logicalRight;
30998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
31008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3101635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::insertPositionedObject(RenderBox* o)
31028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
31038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Create the list of special objects if we don't aleady have one
31048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_positionedObjects)
310581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_positionedObjects = adoptPtr(new PositionedObjectsListHashSet);
31068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_positionedObjects->add(o);
31088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
31098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3110635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::removePositionedObject(RenderBox* o)
31118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
31128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_positionedObjects)
31138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_positionedObjects->remove(o);
31148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
31158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::removePositionedObjects(RenderBlock* o)
31178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
31188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_positionedObjects)
31198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
31208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3121635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderBox* r;
31228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Iterator end = m_positionedObjects->end();
31248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3125635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    Vector<RenderBox*, 16> deadObjects;
31268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
31288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        r = *it;
31298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!o || r->isDescendantOf(o)) {
31308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (o)
31318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                r->setChildNeedsLayout(true, false);
31328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // It is parent blocks job to add positioned child to positioned objects list of its containing block
31348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Parent layout needs to be invalidated to ensure this happens.
31358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderObject* p = r->parent();
31368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            while (p && !p->isRenderBlock())
31378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                p = p->parent();
31388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (p)
31398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                p->setChildNeedsLayout(true);
31408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            deadObjects.append(r);
31428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
31438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
31448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < deadObjects.size(); i++)
31468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_positionedObjects->remove(deadObjects.at(i));
31478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
31488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
314968513a70bcd92384395513322f1b801e7bf9c729Steve BlockRenderBlock::FloatingObject* RenderBlock::insertFloatingObject(RenderBox* o)
31508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
31518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(o->isFloating());
31528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Create the list of special objects if we don't aleady have one
315481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!m_floatingObjects)
315581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_floatingObjects = adoptPtr(new FloatingObjects);
315681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    else {
31578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Don't insert the object again if it's already in the list
315881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
315981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSetIterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(o);
316081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (it != floatingObjectSet.end())
316181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return *it;
31628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
31638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Create the special object entry & append it to the list
31658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FloatingObject* newObj = new FloatingObject(o->style()->floating() == FLEFT ? FloatingObject::FloatLeft : FloatingObject::FloatRight);
316768513a70bcd92384395513322f1b801e7bf9c729Steve Block
316868513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Our location is irrelevant if we're unsplittable or no pagination is in effect.
316968513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Just go ahead and lay out the float.
3170a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool isChildRenderBlock = o->isRenderBlock();
3171f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (isChildRenderBlock && !o->needsLayout() && view()->layoutState()->pageLogicalHeightChanged())
3172a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        o->setChildNeedsLayout(true, false);
3173a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
3174f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    bool affectedByPagination = isChildRenderBlock && view()->layoutState()->m_pageLogicalHeight;
3175a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!affectedByPagination || isWritingModeRoot()) // We are unsplittable if we're a block flow root.
317668513a70bcd92384395513322f1b801e7bf9c729Steve Block        o->layoutIfNeeded();
317768513a70bcd92384395513322f1b801e7bf9c729Steve Block    else {
3178bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        o->computeLogicalWidth();
3179bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        o->computeBlockDirectionMargins(this);
318068513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
3181a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalWidthForFloat(newObj, logicalWidthForChild(o) + marginStartForChild(o) + marginEndForChild(o));
318268513a70bcd92384395513322f1b801e7bf9c729Steve Block
31838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    newObj->m_shouldPaint = !o->hasSelfPaintingLayer(); // If a layer exists, the float will paint itself.  Otherwise someone else will.
31848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    newObj->m_isDescendant = true;
31858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    newObj->m_renderer = o;
31868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
318781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_floatingObjects->increaseObjectsCount(newObj->type());
318881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_floatingObjects->set().add(newObj);
318968513a70bcd92384395513322f1b801e7bf9c729Steve Block
319068513a70bcd92384395513322f1b801e7bf9c729Steve Block    return newObj;
31918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
31928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3193635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::removeFloatingObject(RenderBox* o)
31948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
31958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_floatingObjects) {
319681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
319781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSet::iterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(o);
319881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (it != floatingObjectSet.end()) {
319981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObject* r = *it;
320081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (childrenInline()) {
320181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                int logicalTop = logicalTopForFloat(r);
320281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                int logicalBottom = logicalBottomForFloat(r);
320381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
320481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                // Fix for https://bugs.webkit.org/show_bug.cgi?id=54995.
320581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (logicalBottom < 0 || logicalBottom < logicalTop || logicalTop == numeric_limits<int>::max())
320681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    logicalBottom = numeric_limits<int>::max();
320781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                else {
3208dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                    // Special-case zero- and less-than-zero-height floats: those don't touch
3209dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                    // the line that they're on, but it still needs to be dirtied. This is
3210dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                    // accomplished by pretending they have a height of 1.
321181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    logicalBottom = max(logicalBottom, logicalTop + 1);
3212dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                }
321354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                if (r->m_originatingLine) {
321454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                    ASSERT(r->m_originatingLine->renderer() == this);
321554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                    r->m_originatingLine->markDirty();
321654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block#if !ASSERT_DISABLED
321754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                    r->m_originatingLine = 0;
321854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block#endif
321954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                }
322081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                markLinesDirtyInBlockRange(0, logicalBottom);
32218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
322281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            m_floatingObjects->decreaseObjectsCount(r->type());
322381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            floatingObjectSet.remove(it);
322454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block            ASSERT(!r->m_originatingLine);
322581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            delete r;
32268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
32278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
32288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
32298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
32302fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid RenderBlock::removeFloatingObjectsBelow(FloatingObject* lastFloat, int logicalOffset)
323168513a70bcd92384395513322f1b801e7bf9c729Steve Block{
323268513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!m_floatingObjects)
323368513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
323468513a70bcd92384395513322f1b801e7bf9c729Steve Block
323581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
323681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObject* curr = floatingObjectSet.last();
32372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    while (curr != lastFloat && (!curr->isPlaced() || logicalTopForFloat(curr) >= logicalOffset)) {
323881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_floatingObjects->decreaseObjectsCount(curr->type());
323981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        floatingObjectSet.removeLast();
324054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        ASSERT(!curr->m_originatingLine);
324181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        delete curr;
324281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        curr = floatingObjectSet.last();
324368513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
324468513a70bcd92384395513322f1b801e7bf9c729Steve Block}
324568513a70bcd92384395513322f1b801e7bf9c729Steve Block
32468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::positionNewFloats()
32478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
32488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_floatingObjects)
32498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
325081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
325181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
325281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (floatingObjectSet.isEmpty())
325381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return false;
32548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
32558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If all floats have already been positioned, then we have no work to do.
325681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (floatingObjectSet.last()->isPlaced())
32578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
32588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
32598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Move backwards through our floating object list until we find a float that has
32608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // already been positioned.  Then we'll be able to move forward, positioning all of
32618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the new floats that need it.
326281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator it = floatingObjectSet.end();
326381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    --it; // Go to last item.
326481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator begin = floatingObjectSet.begin();
326581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObject* lastPlacedFloatingObject = 0;
326681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    while (it != begin) {
326781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        --it;
326881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if ((*it)->isPlaced()) {
326981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            lastPlacedFloatingObject = *it;
327081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            ++it;
327181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            break;
327281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
32738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
32748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3275a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalTop = logicalHeight();
32768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3277a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // The float cannot start above the top position of the last positioned float.
327881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (lastPlacedFloatingObject)
327981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalTop = max(logicalTopForFloat(lastPlacedFloatingObject), logicalTop);
32808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
328181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator end = floatingObjectSet.end();
32828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Now walk through the set of unpositioned floats and place them.
328381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (; it != end; ++it) {
328481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch         FloatingObject* floatingObject = *it;
32858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // The containing block is responsible for positioning floats, so if we have floats in our
32868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // list that come from somewhere else, do not attempt to position them.
328781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (floatingObject->renderer()->containingBlock() != this)
32888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
32898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3290a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        RenderBox* childBox = floatingObject->renderer();
3291a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int childLogicalLeftMargin = style()->isLeftToRightDirection() ? marginStartForChild(childBox) : marginEndForChild(childBox);
32928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3293a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int rightOffset = logicalRightOffsetForContent(); // Constant part of right offset.
3294a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int leftOffset = logicalLeftOffsetForContent(); // Constant part of left offset.
3295a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int floatLogicalWidth = logicalWidthForFloat(floatingObject); // The width we look for.
3296a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (rightOffset - leftOffset < floatLogicalWidth)
3297a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            floatLogicalWidth = rightOffset - leftOffset; // Never look for more than what will be available.
32988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3299a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        IntRect oldRect(childBox->x(), childBox->y() , childBox->width(), childBox->height());
330068513a70bcd92384395513322f1b801e7bf9c729Steve Block
3301a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (childBox->style()->clear() & CLEFT)
3302a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            logicalTop = max(lowestFloatLogicalBottom(FloatingObject::FloatLeft), logicalTop);
3303a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (childBox->style()->clear() & CRIGHT)
3304a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            logicalTop = max(lowestFloatLogicalBottom(FloatingObject::FloatRight), logicalTop);
33058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3306a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int floatLogicalLeft;
3307a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (childBox->style()->floating() == FLEFT) {
33088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int heightRemainingLeft = 1;
33098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int heightRemainingRight = 1;
3310a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            floatLogicalLeft = logicalLeftOffsetForLine(logicalTop, leftOffset, false, &heightRemainingLeft);
3311a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            while (logicalRightOffsetForLine(logicalTop, rightOffset, false, &heightRemainingRight) - floatLogicalLeft < floatLogicalWidth) {
3312a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                logicalTop += min(heightRemainingLeft, heightRemainingRight);
3313a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                floatLogicalLeft = logicalLeftOffsetForLine(logicalTop, leftOffset, false, &heightRemainingLeft);
33148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
3315a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            floatLogicalLeft = max(0, floatLogicalLeft);
33168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
33178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int heightRemainingLeft = 1;
33188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int heightRemainingRight = 1;
3319a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            floatLogicalLeft = logicalRightOffsetForLine(logicalTop, rightOffset, false, &heightRemainingRight);
3320a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            while (floatLogicalLeft - logicalLeftOffsetForLine(logicalTop, leftOffset, false, &heightRemainingLeft) < floatLogicalWidth) {
3321a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                logicalTop += min(heightRemainingLeft, heightRemainingRight);
3322a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                floatLogicalLeft = logicalRightOffsetForLine(logicalTop, rightOffset, false, &heightRemainingRight);
33238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
3324a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            floatLogicalLeft -= logicalWidthForFloat(floatingObject); // Use the original width of the float here, since the local variable
3325a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                                                                      // |floatLogicalWidth| was capped to the available line width.
3326a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                                                                      // See fast/block/float/clamped-right-float.html.
33278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3328a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
3329a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalLeftForFloat(floatingObject, floatLogicalLeft);
3330a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalLeftForChild(childBox, floatLogicalLeft + childLogicalLeftMargin);
3331a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalTopForChild(childBox, logicalTop + marginBeforeForChild(childBox));
33328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
333368513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (view()->layoutState()->isPaginated()) {
3334a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            RenderBlock* childBlock = childBox->isRenderBlock() ? toRenderBlock(childBox) : 0;
33358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3336a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (!childBox->needsLayout())
3337a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                childBox->markForPaginationRelayoutIfNeeded();;
3338a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBox->layoutIfNeeded();
333968513a70bcd92384395513322f1b801e7bf9c729Steve Block
334068513a70bcd92384395513322f1b801e7bf9c729Steve Block            // If we are unsplittable and don't fit, then we need to move down.
334168513a70bcd92384395513322f1b801e7bf9c729Steve Block            // We include our margins as part of the unsplittable area.
3342a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            int newLogicalTop = adjustForUnsplittableChild(childBox, logicalTop, true);
334368513a70bcd92384395513322f1b801e7bf9c729Steve Block
334468513a70bcd92384395513322f1b801e7bf9c729Steve Block            // See if we have a pagination strut that is making us move down further.
334568513a70bcd92384395513322f1b801e7bf9c729Steve Block            // Note that an unsplittable child can't also have a pagination strut, so this is
334668513a70bcd92384395513322f1b801e7bf9c729Steve Block            // exclusive with the case above.
334768513a70bcd92384395513322f1b801e7bf9c729Steve Block            if (childBlock && childBlock->paginationStrut()) {
3348a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                newLogicalTop += childBlock->paginationStrut();
334968513a70bcd92384395513322f1b801e7bf9c729Steve Block                childBlock->setPaginationStrut(0);
335068513a70bcd92384395513322f1b801e7bf9c729Steve Block            }
335168513a70bcd92384395513322f1b801e7bf9c729Steve Block
3352a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (newLogicalTop != logicalTop) {
3353a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                floatingObject->m_paginationStrut = newLogicalTop - logicalTop;
3354a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                logicalTop = newLogicalTop;
3355a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                setLogicalTopForChild(childBox, logicalTop + marginBeforeForChild(childBox));
335668513a70bcd92384395513322f1b801e7bf9c729Steve Block                if (childBlock)
335768513a70bcd92384395513322f1b801e7bf9c729Steve Block                    childBlock->setChildNeedsLayout(true, false);
3358a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                childBox->layoutIfNeeded();
335968513a70bcd92384395513322f1b801e7bf9c729Steve Block            }
336068513a70bcd92384395513322f1b801e7bf9c729Steve Block        }
336168513a70bcd92384395513322f1b801e7bf9c729Steve Block
3362a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalTopForFloat(floatingObject, logicalTop);
3363a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalHeightForFloat(floatingObject, logicalHeightForChild(childBox) + marginBeforeForChild(childBox) + marginAfterForChild(childBox));
3364a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
3365a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        floatingObject->setIsPlaced();
3366a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
33678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // If the child moved, we have to repaint it.
3368a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (childBox->checkForRepaintDuringLayout())
3369a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBox->repaintDuringLayoutIfMoved(oldRect);
33708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
33718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
33728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
33738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
33748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::newLine(EClear clear)
33758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
33768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    positionNewFloats();
33778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // set y position
33788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int newY = 0;
33790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    switch (clear)
33808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
33818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CLEFT:
3382a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            newY = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
33838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
33848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CRIGHT:
3385a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            newY = lowestFloatLogicalBottom(FloatingObject::FloatRight);
33868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
33878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CBOTH:
3388a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            newY = lowestFloatLogicalBottom();
33898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        default:
33908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
33918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3392635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (height() < newY)
3393bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setLogicalHeight(newY);
33948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
33958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
33968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::addPercentHeightDescendant(RenderBox* descendant)
33978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
33988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!gPercentHeightDescendantsMap) {
33998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gPercentHeightDescendantsMap = new PercentHeightDescendantsMap;
34008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gPercentHeightContainerMap = new PercentHeightContainerMap;
34018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
34028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(this);
34048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!descendantSet) {
34058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        descendantSet = new HashSet<RenderBox*>;
34068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gPercentHeightDescendantsMap->set(this, descendantSet);
34078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
34088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool added = descendantSet->add(descendant).second;
34098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!added) {
34108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(gPercentHeightContainerMap->get(descendant));
34118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(gPercentHeightContainerMap->get(descendant)->contains(this));
34128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
34138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
34148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(descendant);
34168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!containerSet) {
34178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        containerSet = new HashSet<RenderBlock*>;
34188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gPercentHeightContainerMap->set(descendant, containerSet);
34198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
34208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!containerSet->contains(this));
34218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    containerSet->add(this);
34228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
34238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::removePercentHeightDescendant(RenderBox* descendant)
34258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
34268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!gPercentHeightContainerMap)
34278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
34288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->take(descendant);
34308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!containerSet)
34318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
34328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HashSet<RenderBlock*>::iterator end = containerSet->end();
34348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (HashSet<RenderBlock*>::iterator it = containerSet->begin(); it != end; ++it) {
34358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderBlock* container = *it;
34368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(container);
34378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(descendantSet);
34388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!descendantSet)
34398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
34408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(descendantSet->contains(descendant));
34418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        descendantSet->remove(descendant);
34428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (descendantSet->isEmpty()) {
34438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            gPercentHeightDescendantsMap->remove(container);
34448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            delete descendantSet;
34458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
34468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
34478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    delete containerSet;
34498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
34508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianHashSet<RenderBox*>* RenderBlock::percentHeightDescendants() const
34528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
34538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0;
34548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
34558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34562bde8e466a4451c7319e3a072d118917957d6554Steve Block// FIXME: The logicalLeftOffsetForLine/logicalRightOffsetForLine functions are very slow if there are many floats
34572bde8e466a4451c7319e3a072d118917957d6554Steve Block// present. We need to add a structure to floating objects to represent "lines" of floats.  Then instead of checking
34582bde8e466a4451c7319e3a072d118917957d6554Steve Block// each float individually, we'd just walk backwards through the "lines" and stop when we hit a line that is fully above
34592bde8e466a4451c7319e3a072d118917957d6554Steve Block// the vertical offset that we'd like to check.  Computing the "lines" would be rather complicated, but could replace the left
34602bde8e466a4451c7319e3a072d118917957d6554Steve Block// objects and right objects count hack that is currently used here.
3461a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::logicalLeftOffsetForLine(int logicalTop, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
34628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
34638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int left = fixedOffset;
346481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_floatingObjects && m_floatingObjects->hasLeftObjects()) {
3465a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (heightRemaining)
3466a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            *heightRemaining = 1;
346781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
34682bde8e466a4451c7319e3a072d118917957d6554Steve Block        // We know the list is non-empty, since we have "left" objects to search for.
34692bde8e466a4451c7319e3a072d118917957d6554Steve Block        // Therefore we can assume that begin != end, and that we can do at least one
34702bde8e466a4451c7319e3a072d118917957d6554Steve Block        // decrement.
347181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
34722bde8e466a4451c7319e3a072d118917957d6554Steve Block        FloatingObjectSetIterator begin = floatingObjectSet.begin();
34732bde8e466a4451c7319e3a072d118917957d6554Steve Block        FloatingObjectSetIterator it = floatingObjectSet.end();
34742bde8e466a4451c7319e3a072d118917957d6554Steve Block        do {
34752bde8e466a4451c7319e3a072d118917957d6554Steve Block            --it;
347681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObject* r = *it;
3477a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (r->isPlaced() && logicalTopForFloat(r) <= logicalTop && logicalBottomForFloat(r) > logicalTop
3478a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                && r->type() == FloatingObject::FloatLeft
3479a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                && logicalRightForFloat(r) > left) {
34802bde8e466a4451c7319e3a072d118917957d6554Steve Block                left = max(left, logicalRightForFloat(r));
3481a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                if (heightRemaining)
3482a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    *heightRemaining = logicalBottomForFloat(r) - logicalTop;
34838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
34842bde8e466a4451c7319e3a072d118917957d6554Steve Block        } while (it != begin);
34858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
34868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3487a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (applyTextIndent && style()->isLeftToRightDirection()) {
3488635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        int cw = 0;
34898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (style()->textIndent().isPercent())
3490bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            cw = containingBlock()->availableLogicalWidth();
34918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        left += style()->textIndent().calcMinValue(cw);
34928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
34938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return left;
34958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
34968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3497a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::logicalRightOffsetForLine(int logicalTop, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
34988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
34998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int right = fixedOffset;
35008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
350181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_floatingObjects && m_floatingObjects->hasRightObjects()) {
3502a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (heightRemaining)
3503a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            *heightRemaining = 1;
35042bde8e466a4451c7319e3a072d118917957d6554Steve Block
35052bde8e466a4451c7319e3a072d118917957d6554Steve Block        // We know the list is non-empty, since we have "right" objects to search for.
35062bde8e466a4451c7319e3a072d118917957d6554Steve Block        // Therefore we can assume that begin != end, and that we can do at least one
35072bde8e466a4451c7319e3a072d118917957d6554Steve Block        // decrement.
350881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
35092bde8e466a4451c7319e3a072d118917957d6554Steve Block        FloatingObjectSetIterator begin = floatingObjectSet.begin();
35102bde8e466a4451c7319e3a072d118917957d6554Steve Block        FloatingObjectSetIterator it = floatingObjectSet.end();
35112bde8e466a4451c7319e3a072d118917957d6554Steve Block        do {
35122bde8e466a4451c7319e3a072d118917957d6554Steve Block            --it;
351381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObject* r = *it;
3514a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (r->isPlaced() && logicalTopForFloat(r) <= logicalTop && logicalBottomForFloat(r) > logicalTop
3515a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                && r->type() == FloatingObject::FloatRight
3516a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                && logicalLeftForFloat(r) < right) {
35172bde8e466a4451c7319e3a072d118917957d6554Steve Block                right = min(right, logicalLeftForFloat(r));
3518a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                if (heightRemaining)
3519a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    *heightRemaining = logicalBottomForFloat(r) - logicalTop;
35208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
35212bde8e466a4451c7319e3a072d118917957d6554Steve Block        } while (it != begin);
35228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
35238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3524a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (applyTextIndent && !style()->isLeftToRightDirection()) {
3525635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        int cw = 0;
35268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (style()->textIndent().isPercent())
3527bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            cw = containingBlock()->availableLogicalWidth();
35288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        right -= style()->textIndent().calcMinValue(cw);
35298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
35308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
35318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return right;
35328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
35338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
353481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochint RenderBlock::availableLogicalWidthForLine(int position, bool firstLine) const
35358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3536bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int result = logicalRightOffsetForLine(position, firstLine) - logicalLeftOffsetForLine(position, firstLine);
35378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return (result < 0) ? 0 : result;
35388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
35398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3540a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::nextFloatLogicalBottomBelow(int logicalHeight) const
35418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
35428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_floatingObjects)
35438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
35448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
35458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int bottom = INT_MAX;
354681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
354781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator end = floatingObjectSet.end();
354881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
354981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObject* r = *it;
3550a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int floatBottom = logicalBottomForFloat(r);
3551a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (floatBottom > logicalHeight)
3552a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            bottom = min(floatBottom, bottom);
35538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
35548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
35558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return bottom == INT_MAX ? 0 : bottom;
35568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
35578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3558a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::lowestFloatLogicalBottom(FloatingObject::Type floatType) const
35598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3560a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!m_floatingObjects)
3561a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return 0;
3562a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int lowestFloatBottom = 0;
356381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
356481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator end = floatingObjectSet.end();
356581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
356681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObject* r = *it;
3567a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (r->isPlaced() && r->type() & floatType)
3568a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            lowestFloatBottom = max(lowestFloatBottom, logicalBottomForFloat(r));
3569a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
3570a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return lowestFloatBottom;
35718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
35728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3573a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::markLinesDirtyInBlockRange(int logicalTop, int logicalBottom, RootInlineBox* highest)
35748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3575a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (logicalTop >= logicalBottom)
35768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
35778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
35788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RootInlineBox* lowestDirtyLine = lastRootBox();
35798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RootInlineBox* afterLowest = lowestDirtyLine;
35802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    while (lowestDirtyLine && lowestDirtyLine->blockLogicalHeight() >= logicalBottom && logicalBottom < numeric_limits<int>::max()) {
35818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        afterLowest = lowestDirtyLine;
35828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        lowestDirtyLine = lowestDirtyLine->prevRootBox();
35838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
35848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
358581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    while (afterLowest && afterLowest != highest && (afterLowest->blockLogicalHeight() >= logicalTop || afterLowest->blockLogicalHeight() < 0)) {
35868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        afterLowest->markDirty();
35878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        afterLowest = afterLowest->prevRootBox();
35888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
35898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
35908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
35918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::clearFloats()
35928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
35938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Inline blocks are covered by the isReplaced() check in the avoidFloats method.
35948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (avoidsFloats() || isRoot() || isRenderView() || isFloatingOrPositioned() || isTableCell()) {
359581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (m_floatingObjects) {
359681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            deleteAllValues(m_floatingObjects->set());
35978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_floatingObjects->clear();
359881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
35998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
36008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
36018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
36028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    typedef HashMap<RenderObject*, FloatingObject*> RendererToFloatInfoMap;
36038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RendererToFloatInfoMap floatMap;
36048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
36058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_floatingObjects) {
360681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
36078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (childrenInline()) {
360881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObjectSet::iterator end = floatingObjectSet.end();
360981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            for (FloatingObjectSet::iterator it = floatingObjectSet.begin(); it != end; ++it) {
361081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                FloatingObject* f = *it;
36118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatMap.add(f->m_renderer, f);
361281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
36138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else
361481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            deleteAllValues(floatingObjectSet);
361581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_floatingObjects->clear();
36168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
36178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3618545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // We should not process floats if the parent node is not a RenderBlock. Otherwise, we will add
3619545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // floats in an invalid context. This will cause a crash arising from a bad cast on the parent.
3620545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // See <rdar://problem/8049753>, where float property is applied on a text node in a SVG.
3621545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (!parent() || !parent()->isRenderBlock())
3622545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return;
3623545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
36248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Attempt to locate a previous sibling with overhanging floats.  We skip any elements that are
36258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // out of flow (like floating/positioned elements), and we also skip over any objects that may have shifted
36268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // to avoid floats.
36278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool parentHasFloats = false;
3628a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RenderBlock* parentBlock = toRenderBlock(parent());
3629635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderObject* prev = previousSibling();
36308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    while (prev && (prev->isFloatingOrPositioned() || !prev->isBox() || !prev->isRenderBlock() || toRenderBlock(prev)->avoidsFloats())) {
36318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (prev->isFloating())
36328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            parentHasFloats = true;
36338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         prev = prev->previousSibling();
36348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
36358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
36368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // First add in floats from the parent.
3637a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalTopOffset = logicalTop();
3638a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (parentHasFloats)
3639a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        addIntrudingFloats(parentBlock, parentBlock->logicalLeftOffsetForContent(), logicalTopOffset);
3640635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
3641a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalLeftOffset = 0;
36428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (prev)
3643a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        logicalTopOffset -= toRenderBox(prev)->logicalTop();
3644a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    else {
3645a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        prev = parentBlock;
3646a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        logicalLeftOffset += parentBlock->logicalLeftOffsetForContent();
36478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
36488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
36498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Add overhanging floats from the previous RenderBlock, but only if it has a float that intrudes into our space.
3650635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!prev || !prev->isRenderBlock())
3651635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
3652635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
36538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBlock* block = toRenderBlock(prev);
3654a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (block->m_floatingObjects && block->lowestFloatLogicalBottom() > logicalTopOffset)
3655a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        addIntrudingFloats(block, logicalLeftOffset, logicalTopOffset);
36568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
36578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childrenInline()) {
3658a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int changeLogicalTop = numeric_limits<int>::max();
3659a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int changeLogicalBottom = numeric_limits<int>::min();
36608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_floatingObjects) {
366181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
366281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObjectSetIterator end = floatingObjectSet.end();
366381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
366481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                FloatingObject* f = *it;
36658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                FloatingObject* oldFloatingObject = floatMap.get(f->m_renderer);
3666a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                int logicalBottom = logicalBottomForFloat(f);
36678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (oldFloatingObject) {
3668a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    int oldLogicalBottom = logicalBottomForFloat(oldFloatingObject);
3669a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    if (logicalWidthForFloat(f) != logicalWidthForFloat(oldFloatingObject) || logicalLeftForFloat(f) != logicalLeftForFloat(oldFloatingObject)) {
3670a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                        changeLogicalTop = 0;
3671a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                        changeLogicalBottom = max(changeLogicalBottom, max(logicalBottom, oldLogicalBottom));
3672a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    } else if (logicalBottom != oldLogicalBottom) {
3673a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                        changeLogicalTop = min(changeLogicalTop, min(logicalBottom, oldLogicalBottom));
3674a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                        changeLogicalBottom = max(changeLogicalBottom, max(logicalBottom, oldLogicalBottom));
36758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
36768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
36778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    floatMap.remove(f->m_renderer);
367854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                    if (oldFloatingObject->m_originatingLine) {
367954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                        ASSERT(oldFloatingObject->m_originatingLine->renderer() == this);
368054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                        oldFloatingObject->m_originatingLine->markDirty();
368154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                    }
36828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    delete oldFloatingObject;
36838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else {
3684a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    changeLogicalTop = 0;
3685a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    changeLogicalBottom = max(changeLogicalBottom, logicalBottom);
36868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
36878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
36888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
36898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
36908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RendererToFloatInfoMap::iterator end = floatMap.end();
36918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (RendererToFloatInfoMap::iterator it = floatMap.begin(); it != end; ++it) {
36928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            FloatingObject* floatingObject = (*it).second;
36938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!floatingObject->m_isDescendant) {
3694a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                changeLogicalTop = 0;
3695a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                changeLogicalBottom = max(changeLogicalBottom, logicalBottomForFloat(floatingObject));
36968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
36978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
36988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        deleteAllValues(floatMap);
36998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3700a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        markLinesDirtyInBlockRange(changeLogicalTop, changeLogicalBottom);
37018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
37028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
37038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3704a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::addOverhangingFloats(RenderBlock* child, int logicalLeftOffset, int logicalTopOffset, bool makeChildPaintOtherFloats)
37058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
37068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Prevent floats from being added to the canvas by the root element, e.g., <html>.
3707a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (child->hasOverflowClip() || !child->containsFloats() || child->isRoot() || child->hasColumns() || child->isWritingModeRoot())
37088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
37098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
37102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    int childLogicalTop = child->logicalTop();
3711a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int lowestFloatLogicalBottom = 0;
37128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3713231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Floats that will remain the child's responsibility to paint should factor into its
3714231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // overflow.
371581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator childEnd = child->m_floatingObjects->set().end();
371681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (FloatingObjectSetIterator childIt = child->m_floatingObjects->set().begin(); childIt != childEnd; ++childIt) {
371781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObject* r = *childIt;
37182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        int logicalBottomForFloat = min(this->logicalBottomForFloat(r), numeric_limits<int>::max() - childLogicalTop);
37192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        int logicalBottom = childLogicalTop + logicalBottomForFloat;
3720a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        lowestFloatLogicalBottom = max(lowestFloatLogicalBottom, logicalBottom);
37218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3722a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (logicalBottom > logicalHeight()) {
37238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // If the object is not in the list, we add it now.
37248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!containsFloat(r->m_renderer)) {
37252bde8e466a4451c7319e3a072d118917957d6554Steve Block                int leftOffset = isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset;
37262bde8e466a4451c7319e3a072d118917957d6554Steve Block                int topOffset = isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset;
37272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->x() - leftOffset, r->y() - topOffset, r->width(), r->height()));
37288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatingObj->m_renderer = r->m_renderer;
37298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
37308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // The nearest enclosing layer always paints the float (so that zindex and stacking
37318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // behaves properly).  We always want to propagate the desire to paint the float as
37328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // far out as we can, to the outermost block that overlaps the float, stopping only
37338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                // if we hit a self-painting layer boundary.
3734f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                if (r->m_renderer->enclosingFloatPaintingLayer() == enclosingFloatPaintingLayer())
37358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    r->m_shouldPaint = false;
37368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                else
37378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    floatingObj->m_shouldPaint = false;
37388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3739f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                floatingObj->m_isDescendant = true;
3740f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
37418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // We create the floating object list lazily.
374281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (!m_floatingObjects)
374381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    m_floatingObjects = adoptPtr(new FloatingObjects);
374481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
374581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                m_floatingObjects->increaseObjectsCount(floatingObj->type());
374681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                m_floatingObjects->set().add(floatingObj);
37478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
3748f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        } else {
3749f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            if (makeChildPaintOtherFloats && !r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer() &&
3750f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                r->m_renderer->isDescendantOf(child) && r->m_renderer->enclosingFloatPaintingLayer() == child->enclosingFloatPaintingLayer()) {
3751f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                // The float is not overhanging from this block, so if it is a descendant of the child, the child should
3752f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                // paint it (the other case is that it is intruding into the child), unless it has its own layer or enclosing
3753f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                // layer.
3754f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                // If makeChildPaintOtherFloats is false, it means that the child must already know about all the floats
3755f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                // it should paint.
3756f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                r->m_shouldPaint = true;
3757f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            }
3758f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
3759f05b935882198ccf7d81675736e3aeb089c5113aBen 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
3760f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // child now.
3761f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            if (r->m_isDescendant)
37622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                child->addOverflowFromChild(r->m_renderer, IntSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r)));
3763f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        }
37648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3765a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return lowestFloatLogicalBottom;
37668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
37678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
37684fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Blockbool RenderBlock::hasOverhangingFloat(RenderBox* renderer)
37694fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block{
37704fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block    if (!m_floatingObjects || hasColumns() || !parent())
37714fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block        return false;
37724fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block
37734fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
37744fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block    FloatingObjectSetIterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(renderer);
37754fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block    if (it == floatingObjectSet.end())
37764fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block        return false;
37774fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block
37784fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block    return logicalBottomForFloat(*it) > logicalHeight();
37794fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block}
37804fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block
3781a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::addIntrudingFloats(RenderBlock* prev, int logicalLeftOffset, int logicalTopOffset)
37828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
37838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the parent or previous sibling doesn't have any floats to add, don't bother.
37848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!prev->m_floatingObjects)
37858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
37868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
37872bde8e466a4451c7319e3a072d118917957d6554Steve Block    logicalLeftOffset += (isHorizontalWritingMode() ? marginLeft() : marginTop());
378881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
378981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& prevSet = prev->m_floatingObjects->set();
379081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator prevEnd = prevSet.end();
379181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (FloatingObjectSetIterator prevIt = prevSet.begin(); prevIt != prevEnd; ++prevIt) {
379281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObject* r = *prevIt;
3793a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (logicalBottomForFloat(r) > logicalTopOffset) {
379481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (!m_floatingObjects || !m_floatingObjects->set().contains(r)) {
37952bde8e466a4451c7319e3a072d118917957d6554Steve Block                int leftOffset = isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset;
37962bde8e466a4451c7319e3a072d118917957d6554Steve Block                int topOffset = isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset;
3797a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
37982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->x() - leftOffset, r->y() - topOffset, r->width(), r->height()));
3799a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
38008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Applying the child's margin makes no sense in the case where the child was passed in.
3801a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                // since this margin was added already through the modification of the |logicalLeftOffset| variable
3802a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                // above.  |logicalLeftOffset| will equal the margin in this case, so it's already been taken
3803a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                // into account.  Only apply this code if prev is the parent, since otherwise the left margin
38048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // will get applied twice.
38056b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                if (prev != parent()) {
38062bde8e466a4451c7319e3a072d118917957d6554Steve Block                    if (isHorizontalWritingMode())
38072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                        floatingObj->setX(floatingObj->x() + prev->marginLeft());
38086b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                    else
38092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                        floatingObj->setY(floatingObj->y() + prev->marginTop());
38106b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                }
3811a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
38128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatingObj->m_shouldPaint = false;  // We are not in the direct inheritance chain for this float. We will never paint it.
38138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatingObj->m_renderer = r->m_renderer;
38148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
38158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // We create the floating object list lazily.
381681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (!m_floatingObjects)
381781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    m_floatingObjects = adoptPtr(new FloatingObjects);
381881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                m_floatingObjects->increaseObjectsCount(floatingObj->type());
381981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                m_floatingObjects->set().add(floatingObj);
38208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
38218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
38228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
38238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
38248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
38258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::avoidsFloats() const
38268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
38278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Floats can't intrude into our box if we have a non-auto column count or width.
38288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return RenderBox::avoidsFloats() || !style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth();
38298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
38308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
383181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochbool RenderBlock::containsFloat(RenderBox* renderer)
38328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
383381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return m_floatingObjects && m_floatingObjects->set().contains<RenderBox*, FloatingObjectHashTranslator>(renderer);
38348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
38358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3836635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove, bool inLayout)
38378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
383868513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!m_everHadLayout)
383968513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
384068513a70bcd92384395513322f1b801e7bf9c729Steve Block
3841635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    setChildNeedsLayout(true, !inLayout);
38428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
38438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (floatToRemove)
38448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        removeFloatingObject(floatToRemove);
38458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
38468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Iterate over our children and mark them as needed.
38478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!childrenInline()) {
38488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
38498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if ((!floatToRemove && child->isFloatingOrPositioned()) || !child->isRenderBlock())
38508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                continue;
38518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            RenderBlock* childBlock = toRenderBlock(child);
38528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if ((floatToRemove ? childBlock->containsFloat(floatToRemove) : childBlock->containsFloats()) || childBlock->shrinkToAvoidFloats())
38538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                childBlock->markAllDescendantsWithFloatsForLayout(floatToRemove, inLayout);
38548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
38558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
38568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
38578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
385854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Blockvoid RenderBlock::markSiblingsWithFloatsForLayout()
385954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block{
386054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
386154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    FloatingObjectSetIterator end = floatingObjectSet.end();
386254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
386354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        if (logicalBottomForFloat(*it) > logicalHeight()) {
386454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block            RenderBox* floatingBox = (*it)->renderer();
386554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
386654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block            RenderObject* next = nextSibling();
386754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block            while (next) {
386854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                if (next->isRenderBlock() && !next->isFloatingOrPositioned() && !toRenderBlock(next)->avoidsFloats()) {
386954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                    RenderBlock* nextBlock = toRenderBlock(next);
387054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                    if (nextBlock->containsFloat(floatingBox))
387154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                        nextBlock->markAllDescendantsWithFloatsForLayout(floatingBox);
387254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                    else
387354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                        break;
387454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                }
387554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
387654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                next = next->nextSibling();
387754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block            }
387854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        }
387954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    }
388054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block}
388154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
38828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianint RenderBlock::getClearDelta(RenderBox* child, int yPos)
38838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
38848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // There is no need to compute clearance if we have no floats.
38858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!containsFloats())
38868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
38878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
38888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // At least one float is present.  We need to perform the clearance computation.
38898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool clearSet = child->style()->clear() != CNONE;
38908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int bottom = 0;
38918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch (child->style()->clear()) {
38928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CNONE:
38938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
38948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CLEFT:
3895a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            bottom = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
38968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
38978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CRIGHT:
3898a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            bottom = lowestFloatLogicalBottom(FloatingObject::FloatRight);
38998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
39008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CBOTH:
3901a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            bottom = lowestFloatLogicalBottom();
39028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
39038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
39048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
39058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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).
39068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int result = clearSet ? max(0, bottom - yPos) : 0;
3907231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!result && child->avoidsFloats()) {
3908d0825bca7fe65beaee391d30da42e937db621564Steve Block        int y = yPos;
3909d0825bca7fe65beaee391d30da42e937db621564Steve Block        while (true) {
3910bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            int widthAtY = availableLogicalWidthForLine(y, false);
3911e14391e94c850b8bd03680c23b38978db68687a8John Reck            if (widthAtY == availableLogicalWidth())
3912d0825bca7fe65beaee391d30da42e937db621564Steve Block                return y - yPos;
3913d0825bca7fe65beaee391d30da42e937db621564Steve Block
3914d0825bca7fe65beaee391d30da42e937db621564Steve Block            int oldChildY = child->y();
3915d0825bca7fe65beaee391d30da42e937db621564Steve Block            int oldChildWidth = child->width();
3916d0825bca7fe65beaee391d30da42e937db621564Steve Block            child->setY(y);
3917bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            child->computeLogicalWidth();
3918d0825bca7fe65beaee391d30da42e937db621564Steve Block            int childWidthAtY = child->width();
3919d0825bca7fe65beaee391d30da42e937db621564Steve Block            child->setY(oldChildY);
3920d0825bca7fe65beaee391d30da42e937db621564Steve Block            child->setWidth(oldChildWidth);
3921d0825bca7fe65beaee391d30da42e937db621564Steve Block
3922d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (childWidthAtY <= widthAtY)
3923d0825bca7fe65beaee391d30da42e937db621564Steve Block                return y - yPos;
3924d0825bca7fe65beaee391d30da42e937db621564Steve Block
3925a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            y = nextFloatLogicalBottomBelow(y);
3926d0825bca7fe65beaee391d30da42e937db621564Steve Block            ASSERT(y >= yPos);
3927d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (y < yPos)
3928d0825bca7fe65beaee391d30da42e937db621564Steve Block                break;
3929d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
3930d0825bca7fe65beaee391d30da42e937db621564Steve Block        ASSERT_NOT_REACHED();
3931231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
39328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
39338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
39348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
39350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool RenderBlock::isPointInOverflowControl(HitTestResult& result, int _x, int _y, int _tx, int _ty)
39368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
39378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!scrollsOverflow())
39388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
39398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
39400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return layer()->hitTestOverflowControls(result, IntPoint(_x - _tx, _y - _ty));
39418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
39428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
39438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction)
39448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3945635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int tx = _tx + x();
3946635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int ty = _ty + y();
39478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3948635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!isRenderView()) {
39498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Check if we need to do anything at all.
3950f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        IntRect overflowBox = visualOverflowRect();
39518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        overflowBox.move(tx, ty);
3952a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!overflowBox.intersects(result.rectForPoint(_x, _y)))
39538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
39548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
39558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
39568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) && isPointInOverflowControl(result, _x, _y, tx, ty)) {
39578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
3958ad3386af2204fbbc9033a6dcced2f9b0adcd6f10Steve Block        // FIXME: isPointInOverflowControl() doesn't handle rect-based tests yet.
3959db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block        if (!result.addNodeToRectBasedTestResult(node(), _x, _y))
3960db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block           return true;
39618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
39628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
39638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If we have clipping, then we can't have any spillout.
39648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer();
39658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool useClip = (hasControlClip() || useOverflowClip);
3966a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    IntRect hitTestArea(result.rectForPoint(_x, _y));
39672bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool checkChildren = !useClip || (hasControlClip() ? controlClipRect(tx, ty).intersects(hitTestArea) : overflowClipRect(tx, ty, IncludeOverlayScrollbarSize).intersects(hitTestArea));
39688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (checkChildren) {
39698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Hit test descendants first.
39708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int scrolledX = tx;
39718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int scrolledY = ty;
3972dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (hasOverflowClip()) {
3973dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            IntSize offset = layer()->scrolledContentOffset();
3974dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            scrolledX -= offset.width();
3975dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            scrolledY -= offset.height();
3976dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
39778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
39788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Hit test contents if we don't have columns.
39795abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        if (!hasColumns()) {
39805abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            if (hitTestContents(request, result, _x, _y, scrolledX, scrolledY, hitTestAction)) {
39815abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick                updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
39825abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick                return true;
39835abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            }
39845abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            if (hitTestAction == HitTestFloat && hitTestFloats(request, result, _x, _y, scrolledX, scrolledY))
39855abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick                return true;
39865abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        } else if (hitTestColumns(request, result, _x, _y, scrolledX, scrolledY, hitTestAction)) {
39876c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
39888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
39896c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        }
39908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
39918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3992635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Now hit test our background
3993635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) {
3994635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        IntRect boundsRect(tx, ty, width(), height());
3995a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (visibleToHitTesting() && boundsRect.intersects(result.rectForPoint(_x, _y))) {
39966b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            updateHitTestResult(result, flipForWritingMode(IntPoint(_x - tx, _y - ty)));
3997db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block            if (!result.addNodeToRectBasedTestResult(node(), _x, _y, boundsRect))
3998db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block                return true;
39998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
40008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
40018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
40038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
40048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40055abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickbool RenderBlock::hitTestFloats(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty)
40065abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{
40075abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    if (!m_floatingObjects)
40085abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        return false;
40095abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
40105abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    if (isRenderView()) {
40115abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        tx += toRenderView(this)->frameView()->scrollX();
40125abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        ty += toRenderView(this)->frameView()->scrollY();
40135abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    }
40145abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
401581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
401681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator begin = floatingObjectSet.begin();
401781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (FloatingObjectSetIterator it = floatingObjectSet.end(); it != begin;) {
401881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        --it;
401981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObject* floatingObject = *it;
40205abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        if (floatingObject->m_shouldPaint && !floatingObject->m_renderer->hasSelfPaintingLayer()) {
40212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int xOffset = xPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->x();
40222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int yOffset = yPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->y();
40232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            IntPoint childPoint = flipFloatForWritingMode(floatingObject, IntPoint(tx + xOffset, ty + yOffset));
402428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            if (floatingObject->m_renderer->hitTest(request, result, IntPoint(x, y), childPoint.x(), childPoint.y())) {
402528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                updateHitTestResult(result, IntPoint(x - childPoint.x(), y - childPoint.y()));
40265abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick                return true;
40275abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            }
40285abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        }
40295abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    }
40305abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
40315abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    return false;
40325abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick}
40335abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
40348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
40358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
40368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We need to do multiple passes, breaking up our hit testing into strips.
40375abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    ColumnInfo* colInfo = columnInfo();
403868513a70bcd92384395513322f1b801e7bf9c729Steve Block    int colCount = columnCount(colInfo);
40396c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (!colCount)
40406c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        return false;
40412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int logicalLeft = logicalLeftOffsetForContent();
40422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int currLogicalTopOffset = 0;
4043e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    int i;
40442bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool isHorizontal = isHorizontalWritingMode();
40452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    for (i = 0; i < colCount; i++) {
40462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        IntRect colRect = columnRectAt(colInfo, i);
40472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int blockDelta =  (isHorizontal ? colRect.height() : colRect.width());
40482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (style()->isFlippedBlocksWritingMode())
40492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalTopOffset += blockDelta;
40502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        else
40512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalTopOffset -= blockDelta;
40522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
4053e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    for (i = colCount - 1; i >= 0; i--) {
405468513a70bcd92384395513322f1b801e7bf9c729Steve Block        IntRect colRect = columnRectAt(colInfo, i);
40552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        flipForWritingMode(colRect);
40562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft;
40572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int blockDelta =  (isHorizontal ? colRect.height() : colRect.width());
40582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (style()->isFlippedBlocksWritingMode())
40592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalTopOffset -= blockDelta;
40602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        else
40612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalTopOffset += blockDelta;
40628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        colRect.move(tx, ty);
40638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4064a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (colRect.intersects(result.rectForPoint(x, y))) {
40658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // The point is inside this column.
40668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Adjust tx and ty to change where we hit test.
40678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            IntSize offset = isHorizontal ? IntSize(currLogicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, currLogicalLeftOffset);
40692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int finalX = tx + offset.width();
40702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int finalY = ty + offset.height();
4071a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (result.isRectBasedTest() && !colRect.contains(result.rectForPoint(x, y)))
4072db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block                hitTestContents(request, result, x, y, finalX, finalY, hitTestAction);
4073db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block            else
40745abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick                return hitTestContents(request, result, x, y, finalX, finalY, hitTestAction) || (hitTestAction == HitTestFloat && hitTestFloats(request, result, x, y, finalX, finalY));
40758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
40768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
40778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
40798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
40808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::hitTestContents(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
40828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
40838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childrenInline() && !isTable()) {
40848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We have to hit-test our line boxes.
40856c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (m_lineBoxes.hitTest(this, request, result, x, y, tx, ty, hitTestAction))
40868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
40878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
40888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Hit test our children.
40898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HitTestAction childHitTest = hitTestAction;
40908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (hitTestAction == HitTestChildBlockBackgrounds)
40918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            childHitTest = HitTestChildBlockBackground;
40928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        for (RenderBox* child = lastChildBox(); child; child = child->previousSiblingBox()) {
409328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            IntPoint childPoint = flipForWritingMode(child, IntPoint(tx, ty), ParentToChildFlippingAdjustment);
409428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            if (!child->hasSelfPaintingLayer() && !child->isFloating() && child->nodeAtPoint(request, result, x, y, childPoint.x(), childPoint.y(), childHitTest))
40958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
40968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
40978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
40988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
41008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
41018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPosition RenderBlock::positionForBox(InlineBox *box, bool start) const
41038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
41048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!box)
41058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return Position();
41068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!box->renderer()->node())
41088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return Position(node(), start ? caretMinOffset() : caretMaxOffset());
41098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!box->isInlineTextBox())
41118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return Position(box->renderer()->node(), start ? box->renderer()->caretMinOffset() : box->renderer()->caretMaxOffset());
41128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    InlineTextBox *textBox = static_cast<InlineTextBox *>(box);
41148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return Position(box->renderer()->node(), start ? textBox->start() : textBox->start() + textBox->len());
41158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
41168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// FIXME: This function should go on RenderObject as an instance method. Then
41185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian// all cases in which positionForPoint recurs could call this instead to
41198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// prevent crossing editable boundaries. This would require many tests.
41206b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerstatic VisiblePosition positionForPointRespectingEditingBoundaries(RenderBlock* parent, RenderBox* child, const IntPoint& pointInParentCoordinates)
41218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
41226b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // FIXME: This is wrong if the child's writing-mode is different from the parent's.
41235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    IntPoint pointInChildCoordinates(pointInParentCoordinates - child->location());
41248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If this is an anonymous renderer, we just recur normally
41268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Node* childNode = child->node();
41278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!childNode)
41285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return child->positionForPoint(pointInChildCoordinates);
41298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Otherwise, first make sure that the editability of the parent and child agree.
41318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If they don't agree, then we return a visible position just before or after the child
41328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* ancestor = parent;
41338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    while (ancestor && !ancestor->node())
41348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ancestor = ancestor->parent();
41358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If we can't find an ancestor to check editability on, or editability is unchanged, we recur like normal
41372bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!ancestor || ancestor->node()->rendererIsEditable() == childNode->rendererIsEditable())
41385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return child->positionForPoint(pointInChildCoordinates);
41398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41406b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // Otherwise return before or after the child, depending on if the click was to the logical left or logical right of the child
41416b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    int childMiddle = parent->logicalWidthForChild(child) / 2;
41422bde8e466a4451c7319e3a072d118917957d6554Steve Block    int logicalLeft = parent->isHorizontalWritingMode() ? pointInChildCoordinates.x() : pointInChildCoordinates.y();
41436b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (logicalLeft < childMiddle)
41448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return ancestor->createVisiblePosition(childNode->nodeIndex(), DOWNSTREAM);
41458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return ancestor->createVisiblePosition(childNode->nodeIndex() + 1, UPSTREAM);
41468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
41478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41486b70adc33054f8aee8c54d0f460458a9df11b8a5Russell BrennerVisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint& pointInLogicalContents)
41498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
41505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(childrenInline());
41518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (!firstRootBox())
41535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return createVisiblePosition(0, DOWNSTREAM);
41548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
41558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // look for the closest line box in the root box which is at the passed-in y coordinate
41565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    InlineBox* closestBox = 0;
41575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RootInlineBox* firstRootBoxWithChildren = 0;
41585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RootInlineBox* lastRootBoxWithChildren = 0;
41595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
4160643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (!root->firstLeafChild())
41615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            continue;
41625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (!firstRootBoxWithChildren)
41635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            firstRootBoxWithChildren = root;
41645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        lastRootBoxWithChildren = root;
41655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
41668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // check if this root line box is located at this y coordinate
41676b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (pointInLogicalContents.y() < root->selectionBottom()) {
41686b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            closestBox = root->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
41698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (closestBox)
41708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                break;
41718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
41728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
41738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4174545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    bool moveCaretToBoundary = document()->frame()->editor()->behavior().shouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom();
41755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
4176545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (!moveCaretToBoundary && !closestBox && lastRootBoxWithChildren) {
41775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // y coordinate is below last root line box, pretend we hit it
41786b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        closestBox = lastRootBoxWithChildren->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
41795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
41808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (closestBox) {
41826b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (moveCaretToBoundary && pointInLogicalContents.y() < firstRootBoxWithChildren->selectionTop()) {
41835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            // y coordinate is above first root line box, so return the start of the first
41845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            return VisiblePosition(positionForBox(firstRootBoxWithChildren->firstLeafChild(), true), DOWNSTREAM);
41855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
41865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
41876b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        // pass the box a top position that is inside it
41886b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        IntPoint point(pointInLogicalContents.x(), closestBox->logicalTop());
41892bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!isHorizontalWritingMode())
41906b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            point = point.transposedPoint();
41916b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (closestBox->renderer()->isReplaced())
41926b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            return positionForPointRespectingEditingBoundaries(this, toRenderBox(closestBox->renderer()), point);
41936b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        return closestBox->renderer()->positionForPoint(point);
41945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
41955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
41965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (lastRootBoxWithChildren) {
41975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // We hit this case for Mac behavior when the Y coordinate is below the last box.
4198545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        ASSERT(moveCaretToBoundary);
41992bde8e466a4451c7319e3a072d118917957d6554Steve Block        InlineBox* logicallyLastBox;
42002bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (lastRootBoxWithChildren->getLogicalEndBoxWithNode(logicallyLastBox))
42012bde8e466a4451c7319e3a072d118917957d6554Steve Block            return VisiblePosition(positionForBox(logicallyLastBox, false), DOWNSTREAM);
42028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
42038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
42045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Can't reach this. We have a root line box, but it has no kids.
42058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // FIXME: This should ASSERT_NOT_REACHED(), but clicking on placeholder text
42065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // seems to hit this code path.
42075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return createVisiblePosition(0, DOWNSTREAM);
42085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
42095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
42105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianstatic inline bool isChildHitTestCandidate(RenderBox* box)
42115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
42125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return box->height() && box->style()->visibility() == VISIBLE && !box->isFloatingOrPositioned();
42138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
42148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
42158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianVisiblePosition RenderBlock::positionForPoint(const IntPoint& point)
42168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
42178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (isTable())
42188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return RenderBox::positionForPoint(point);
42198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
42208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (isReplaced()) {
42216b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        // FIXME: This seems wrong when the object's writing-mode doesn't match the line's writing-mode.
42222bde8e466a4451c7319e3a072d118917957d6554Steve Block        int pointLogicalLeft = isHorizontalWritingMode() ? point.x() : point.y();
42232bde8e466a4451c7319e3a072d118917957d6554Steve Block        int pointLogicalTop = isHorizontalWritingMode() ? point.y() : point.x();
42246b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
42256b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (pointLogicalTop < 0 || (pointLogicalTop < logicalHeight() && pointLogicalLeft < 0))
42268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return createVisiblePosition(caretMinOffset(), DOWNSTREAM);
42276b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (pointLogicalTop >= logicalHeight() || (pointLogicalTop >= 0 && pointLogicalLeft >= logicalWidth()))
42288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return createVisiblePosition(caretMaxOffset(), DOWNSTREAM);
42298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
42308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
42315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    int contentsX = point.x();
42325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    int contentsY = point.y();
42335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    offsetForContents(contentsX, contentsY);
42345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    IntPoint pointInContents(contentsX, contentsY);
42356b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    IntPoint pointInLogicalContents(pointInContents);
42362bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!isHorizontalWritingMode())
42376b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        pointInLogicalContents = pointInLogicalContents.transposedPoint();
42388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
42395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (childrenInline())
42406b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        return positionForPointWithInlineChildren(pointInLogicalContents);
42418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
42426b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (lastChildBox() && pointInContents.y() > lastChildBox()->logicalTop()) {
42435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        for (RenderBox* childBox = lastChildBox(); childBox; childBox = childBox->previousSiblingBox()) {
42445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            if (isChildHitTestCandidate(childBox))
42455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents);
42465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
42475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    } else {
42485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
42495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            // We hit child if our click is above the bottom of its padding box (like IE6/7 and FF3).
42506b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            if (isChildHitTestCandidate(childBox) && pointInContents.y() < childBox->logicalBottom())
42515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents);
42525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
42538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
42548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
42555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // We only get here if there are no hit test candidate children below the click.
42568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return RenderBox::positionForPoint(point);
42578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
42588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4259635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::offsetForContents(int& tx, int& ty) const
4260635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
4261dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    IntPoint contentsPoint(tx, ty);
4262dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
4263635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (hasOverflowClip())
4264dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        contentsPoint += layer()->scrolledContentOffset();
4265635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
4266dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (hasColumns())
4267635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        adjustPointToColumnContents(contentsPoint);
4268dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
4269dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    tx = contentsPoint.x();
4270dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ty = contentsPoint.y();
4271635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
4272635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
427368513a70bcd92384395513322f1b801e7bf9c729Steve Blockint RenderBlock::availableLogicalWidth() const
427468513a70bcd92384395513322f1b801e7bf9c729Steve Block{
427568513a70bcd92384395513322f1b801e7bf9c729Steve Block    // If we have multiple columns, then the available logical width is reduced to our column width.
427668513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (hasColumns())
427768513a70bcd92384395513322f1b801e7bf9c729Steve Block        return desiredColumnWidth();
427868513a70bcd92384395513322f1b801e7bf9c729Steve Block    return RenderBox::availableLogicalWidth();
42798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
42808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
42818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderBlock::columnGap() const
42828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
42838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->hasNormalColumnGap())
42848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return style()->fontDescription().computedPixelSize(); // "1em" is recommended as the normal gap setting. Matches <p> margins.
42858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return static_cast<int>(style()->columnGap());
42868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
42878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
42888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::calcColumnWidth()
42898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
42908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Calculate our column width and column count.
42918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned desiredColumnCount = 1;
42922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int desiredColumnWidth = contentLogicalWidth();
42938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
42948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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.
4295f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    if (document()->paginated() || (style()->hasAutoColumnCount() && style()->hasAutoColumnWidth())) {
42968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
42978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
42988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
42998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
43008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int availWidth = desiredColumnWidth;
43018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int colGap = columnGap();
43028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int colWidth = max(1, static_cast<int>(style()->columnWidth()));
43038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int colCount = max(1, static_cast<int>(style()->columnCount()));
43048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
43052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (style()->hasAutoColumnWidth() && !style()->hasAutoColumnCount()) {
43062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        desiredColumnCount = colCount;
43072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        desiredColumnWidth = max<int>(0, (availWidth - ((desiredColumnCount - 1) * colGap)) / desiredColumnCount);
43082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    } else if (!style()->hasAutoColumnWidth() && style()->hasAutoColumnCount()) {
43092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        desiredColumnCount = max<int>(1, (float)(availWidth + colGap) / (colWidth + colGap));
43102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap;
43118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
43122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        desiredColumnCount = max(min<int>(colCount, (float)(availWidth + colGap) / (colWidth + colGap)), 1);
43132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap;
43148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
43158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
43168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
43178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
43188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::setDesiredColumnCountAndWidth(int count, int width)
43198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
43205af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    bool destroyColumns = !firstChild()
43215af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                          || (count == 1 && style()->hasAutoColumnWidth())
43225af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                          || firstChild()->isAnonymousColumnsBlock()
432368513a70bcd92384395513322f1b801e7bf9c729Steve Block                          || firstChild()->isAnonymousColumnSpanBlock();
43245af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (destroyColumns) {
43258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (hasColumns()) {
43268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            delete gColumnInfoMap->take(this);
43278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            setHasColumns(false);
43288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
43298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
43308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ColumnInfo* info;
43318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (hasColumns())
43328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            info = gColumnInfoMap->get(this);
43338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
43348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!gColumnInfoMap)
43358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                gColumnInfoMap = new ColumnInfoMap;
43368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            info = new ColumnInfo;
43378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            gColumnInfoMap->add(this, info);
43388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            setHasColumns(true);
43398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
43405abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        info->setDesiredColumnCount(count);
43415abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        info->setDesiredColumnWidth(width);
43428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
43438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
43448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
43458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderBlock::desiredColumnWidth() const
43468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
43478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!hasColumns())
43482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return contentLogicalWidth();
43495abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    return gColumnInfoMap->get(this)->desiredColumnWidth();
43508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
43518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
43528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectunsigned RenderBlock::desiredColumnCount() const
43538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
43548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!hasColumns())
43558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 1;
43565abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    return gColumnInfoMap->get(this)->desiredColumnCount();
43578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
43588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
43595abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain MerrickColumnInfo* RenderBlock::columnInfo() const
43608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
43618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!hasColumns())
43628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
43635abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    return gColumnInfoMap->get(this);
43648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
43658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
436668513a70bcd92384395513322f1b801e7bf9c729Steve Blockunsigned RenderBlock::columnCount(ColumnInfo* colInfo) const
43678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
436868513a70bcd92384395513322f1b801e7bf9c729Steve Block    ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo);
436968513a70bcd92384395513322f1b801e7bf9c729Steve Block    return colInfo->columnCount();
437068513a70bcd92384395513322f1b801e7bf9c729Steve Block}
43718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
437268513a70bcd92384395513322f1b801e7bf9c729Steve BlockIntRect RenderBlock::columnRectAt(ColumnInfo* colInfo, unsigned index) const
437368513a70bcd92384395513322f1b801e7bf9c729Steve Block{
437468513a70bcd92384395513322f1b801e7bf9c729Steve Block    ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo);
43758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
437668513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Compute the appropriate rect based off our information.
43772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int colLogicalWidth = colInfo->desiredColumnWidth();
43782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int colLogicalHeight = colInfo->columnHeight();
43792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int colLogicalTop = borderBefore() + paddingBefore();
43808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int colGap = columnGap();
43812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int colLogicalLeft = style()->isLeftToRightDirection() ?
43822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                          logicalLeftOffsetForContent() + (index * (colLogicalWidth + colGap))
43832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                        : logicalLeftOffsetForContent() + contentLogicalWidth() - colLogicalWidth - (index * (colLogicalWidth + colGap));
43842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    IntRect rect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
43852bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
43862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return IntRect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
43872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return IntRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogicalWidth);
438868513a70bcd92384395513322f1b801e7bf9c729Steve Block}
43898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4390f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochbool RenderBlock::layoutColumns(bool hasSpecifiedPageLogicalHeight, int pageLogicalHeight, LayoutStateMaintainer& statePusher)
439168513a70bcd92384395513322f1b801e7bf9c729Steve Block{
4392f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!hasColumns())
4393f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return false;
4394f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
4395f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // FIXME: We don't balance properly at all in the presence of forced page breaks.  We need to understand what
4396f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // the distance between forced page breaks is so that we can avoid making the minimum column height too tall.
4397f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    ColumnInfo* colInfo = columnInfo();
4398f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int desiredColumnCount = colInfo->desiredColumnCount();
4399f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!hasSpecifiedPageLogicalHeight) {
4400f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        int columnHeight = pageLogicalHeight;
4401f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        int minColumnCount = colInfo->forcedBreaks() + 1;
4402f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (minColumnCount >= desiredColumnCount) {
4403f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // The forced page breaks are in control of the balancing.  Just set the column height to the
4404f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // maximum page break distance.
4405f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            if (!pageLogicalHeight) {
4406f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                int distanceBetweenBreaks = max(colInfo->maximumDistanceBetweenForcedBreaks(),
44072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                                                view()->layoutState()->pageLogicalOffset(borderBefore() + paddingBefore() + contentLogicalHeight()) - colInfo->forcedBreakOffset());
4408f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                columnHeight = max(colInfo->minimumColumnHeight(), distanceBetweenBreaks);
440968513a70bcd92384395513322f1b801e7bf9c729Steve Block            }
44102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        } else if (contentLogicalHeight() > pageLogicalHeight * desiredColumnCount) {
4411f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // Now that we know the intrinsic height of the columns, we have to rebalance them.
44122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            columnHeight = max(colInfo->minimumColumnHeight(), (int)ceilf((float)contentLogicalHeight() / desiredColumnCount));
4413f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        }
44148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4415f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (columnHeight && columnHeight != pageLogicalHeight) {
4416f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            statePusher.pop();
4417f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            m_everHadLayout = true;
4418f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            layoutBlock(false, columnHeight);
4419f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            return true;
44208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4421f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
4422f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
4423f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (pageLogicalHeight)
44242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        colInfo->setColumnCountAndHeight(ceilf((float)contentLogicalHeight() / pageLogicalHeight), pageLogicalHeight);
4425f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
4426f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (columnCount(colInfo)) {
44272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        setLogicalHeight(borderBefore() + paddingBefore() + colInfo->columnHeight() + borderAfter() + paddingAfter() + scrollbarLogicalHeight());
4428f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        m_overflow.clear();
4429643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
44308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
443168513a70bcd92384395513322f1b801e7bf9c729Steve Block    return false;
44328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
44338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
44348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::adjustPointToColumnContents(IntPoint& point) const
44358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
44368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Just bail if we have no columns.
44378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!hasColumns())
44388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
44398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
44405abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    ColumnInfo* colInfo = columnInfo();
444168513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!columnCount(colInfo))
44425abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        return;
44438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
44448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Determine which columns we intersect.
44458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int colGap = columnGap();
44462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int halfColGap = colGap / 2;
444768513a70bcd92384395513322f1b801e7bf9c729Steve Block    IntPoint columnPoint(columnRectAt(colInfo, 0).location());
44482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int logicalOffset = 0;
44495abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    for (unsigned i = 0; i < colInfo->columnCount(); i++) {
44508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Add in half the column gap to the left and right of the rect.
445168513a70bcd92384395513322f1b801e7bf9c729Steve Block        IntRect colRect = columnRectAt(colInfo, i);
44522bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (isHorizontalWritingMode()) {
44532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            IntRect gapAndColumnRect(colRect.x() - halfColGap, colRect.y(), colRect.width() + colGap, colRect.height());
44542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRect.maxX()) {
44552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // FIXME: The clamping that follows is not completely right for right-to-left
44562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // content.
44572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // Clamp everything above the column to its top left.
44582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                if (point.y() < gapAndColumnRect.y())
44592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    point = gapAndColumnRect.location();
44602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // Clamp everything below the column to the next column's top left. If there is
44612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // no next column, this still maps to just after this column.
44622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                else if (point.y() >= gapAndColumnRect.maxY()) {
44632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    point = gapAndColumnRect.location();
44642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    point.move(0, gapAndColumnRect.height());
44652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                }
44662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
44672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // We're inside the column.  Translate the x and y into our column coordinate space.
44682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                point.move(columnPoint.x() - colRect.x(), logicalOffset);
44692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                return;
4470dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            }
44712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
44722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            // Move to the next position.
44732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            logicalOffset += colRect.height();
44742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        } else {
44752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            IntRect gapAndColumnRect(colRect.x(), colRect.y() - halfColGap, colRect.width(), colRect.height() + colGap);
44762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (point.y() >= gapAndColumnRect.y() && point.y() < gapAndColumnRect.maxY()) {
44772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // FIXME: The clamping that follows is not completely right for right-to-left
44782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // content.
44792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // Clamp everything above the column to its top left.
44802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                if (point.x() < gapAndColumnRect.x())
44812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    point = gapAndColumnRect.location();
44822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // Clamp everything below the column to the next column's top left. If there is
44832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // no next column, this still maps to just after this column.
44842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                else if (point.x() >= gapAndColumnRect.maxX()) {
44852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    point = gapAndColumnRect.location();
44862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    point.move(gapAndColumnRect.width(), 0);
44872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                }
4488dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
44892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // We're inside the column.  Translate the x and y into our column coordinate space.
44902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                point.move(logicalOffset, columnPoint.y() - colRect.y());
44912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                return;
44922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            }
44932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
44942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            // Move to the next position.
44952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            logicalOffset += colRect.width();
44968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
44978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
44988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
44998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
45008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::adjustRectForColumns(IntRect& r) const
45018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
45028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Just bail if we have no columns.
45038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!hasColumns())
45048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
45058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
45065abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    ColumnInfo* colInfo = columnInfo();
45078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
45088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Begin with a result rect that is empty.
45098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    IntRect result;
45108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
45118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Determine which columns we intersect.
451268513a70bcd92384395513322f1b801e7bf9c729Steve Block    unsigned colCount = columnCount(colInfo);
45136c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (!colCount)
45146c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        return;
4515e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block
45162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int logicalLeft = logicalLeftOffsetForContent();
45172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int currLogicalOffset = 0;
45182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
45196c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    for (unsigned i = 0; i < colCount; i++) {
452068513a70bcd92384395513322f1b801e7bf9c729Steve Block        IntRect colRect = columnRectAt(colInfo, i);
45218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        IntRect repaintRect = r;
45222bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (isHorizontalWritingMode()) {
45232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int currXOffset = colRect.x() - logicalLeft;
45242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            repaintRect.move(currXOffset, currLogicalOffset);
45252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalOffset -= colRect.height();
45262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        } else {
45272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int currYOffset = colRect.y() - logicalLeft;
45282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            repaintRect.move(currLogicalOffset, currYOffset);
45292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalOffset -= colRect.width();
45302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
45318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        repaintRect.intersect(colRect);
45328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result.unite(repaintRect);
45338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
45348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
45358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    r = result;
45368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
45378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
45382fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockIntPoint RenderBlock::flipForWritingModeIncludingColumns(const IntPoint& point) const
45392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
45402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ASSERT(hasColumns());
45412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
45422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return point;
45432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ColumnInfo* colInfo = columnInfo();
45442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int columnLogicalHeight = colInfo->columnHeight();
45452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
45462bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
45472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return IntPoint(point.x(), expandedLogicalHeight - point.y());
45482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return IntPoint(expandedLogicalHeight - point.x(), point.y());
45492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
45502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
45512fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid RenderBlock::flipForWritingModeIncludingColumns(IntRect& rect) const
45522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
45532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ASSERT(hasColumns());
45542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
45552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
45562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
45572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ColumnInfo* colInfo = columnInfo();
45582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int columnLogicalHeight = colInfo->columnHeight();
45592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
45602bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
45612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        rect.setY(expandedLogicalHeight - rect.maxY());
45622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    else
45632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        rect.setX(expandedLogicalHeight - rect.maxX());
45642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
45652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
4566692e5dbf12901edacf14812a6fae25462920af42Steve Blockvoid RenderBlock::adjustForColumns(IntSize& offset, const IntPoint& point) const
4567692e5dbf12901edacf14812a6fae25462920af42Steve Block{
4568692e5dbf12901edacf14812a6fae25462920af42Steve Block    if (!hasColumns())
4569692e5dbf12901edacf14812a6fae25462920af42Steve Block        return;
4570692e5dbf12901edacf14812a6fae25462920af42Steve Block
45715abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    ColumnInfo* colInfo = columnInfo();
45725abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
45732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int logicalLeft = logicalLeftOffsetForContent();
457468513a70bcd92384395513322f1b801e7bf9c729Steve Block    size_t colCount = columnCount(colInfo);
45752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int colLogicalWidth = colInfo->desiredColumnWidth();
45762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int colLogicalHeight = colInfo->columnHeight();
45772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
457868513a70bcd92384395513322f1b801e7bf9c729Steve Block    for (size_t i = 0; i < colCount; ++i) {
45792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        // Compute the edges for a given column in the block progression direction.
45802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        IntRect sliceRect = IntRect(logicalLeft, borderBefore() + paddingBefore() + i * colLogicalHeight, colLogicalWidth, colLogicalHeight);
45812bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!isHorizontalWritingMode())
45822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            sliceRect = sliceRect.transposedRect();
45832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
45842fc2651226baac27029e38c9d6ef883fa32084dbSteve 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).
45852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        flipForWritingModeIncludingColumns(sliceRect);
45862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
45872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int logicalOffset = style()->isFlippedBlocksWritingMode() ? (colCount - 1 - i) * colLogicalHeight : i * colLogicalHeight;
4588692e5dbf12901edacf14812a6fae25462920af42Steve Block
45892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        // Now we're in the same coordinate space as the point.  See if it is inside the rectangle.
45902bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (isHorizontalWritingMode()) {
45912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (point.y() >= sliceRect.y() && point.y() < sliceRect.maxY()) {
45922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                offset.expand(columnRectAt(colInfo, i).x() - logicalLeft, -logicalOffset);
45932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                return;
45942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            }
45952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        } else {
45962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (point.x() >= sliceRect.x() && point.x() < sliceRect.maxX()) {
45972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                offset.expand(-logicalOffset, columnRectAt(colInfo, i).y() - logicalLeft);
45982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                return;
45992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            }
46002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
4601692e5dbf12901edacf14812a6fae25462920af42Steve Block    }
4602692e5dbf12901edacf14812a6fae25462920af42Steve Block}
4603692e5dbf12901edacf14812a6fae25462920af42Steve Block
4604bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBlock::computePreferredLogicalWidths()
46058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4606bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    ASSERT(preferredLogicalWidthsDirty());
46078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    updateFirstLetter();
46098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4610a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!isTableCell() && style()->logicalWidth().isFixed() && style()->logicalWidth().value() > 0)
4611a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeContentBoxLogicalWidth(style()->logicalWidth().value());
46128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
4613bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_minPreferredLogicalWidth = 0;
4614bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_maxPreferredLogicalWidth = 0;
46158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (childrenInline())
4617bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            computeInlinePreferredLogicalWidths();
46188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
4619bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            computeBlockPreferredLogicalWidths();
46208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4621bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_maxPreferredLogicalWidth = max(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
46228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!style()->autoWrap() && childrenInline()) {
4624bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth;
46258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // A horizontal marquee with inline children has no minimum width.
46278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (layer() && layer()->marquee() && layer()->marquee()->isHorizontal())
4628bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                m_minPreferredLogicalWidth = 0;
46298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
46308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4631f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        int scrollbarWidth = 0;
4632f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (hasOverflowClip() && style()->overflowY() == OSCROLL) {
4633f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            layer()->setHasVerticalScrollbar(true);
4634f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            scrollbarWidth = verticalScrollbarWidth();
4635f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            m_maxPreferredLogicalWidth += scrollbarWidth;
4636f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        }
4637f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
46388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (isTableCell()) {
463928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            Length w = toRenderTableCell(this)->styleOrColLogicalWidth();
4640f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            if (w.isFixed() && w.value() > 0) {
4641bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                m_maxPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(w.value()));
4642f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                scrollbarWidth = 0;
4643f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            }
46448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4645f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
4646f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        m_minPreferredLogicalWidth += scrollbarWidth;
46478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
46488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4649a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (style()->logicalMinWidth().isFixed() && style()->logicalMinWidth().value() > 0) {
4650a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMinWidth().value()));
4651a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMinWidth().value()));
46528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
46538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4654a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (style()->logicalMaxWidth().isFixed() && style()->logicalMaxWidth().value() != undefinedLength) {
4655a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMaxWidth().value()));
4656a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMaxWidth().value()));
46578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
46588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4659f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int borderAndPadding = borderAndPaddingLogicalWidth();
4660f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    m_minPreferredLogicalWidth += borderAndPadding;
4661f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    m_maxPreferredLogicalWidth += borderAndPadding;
46628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4663bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    setPreferredLogicalWidthsDirty(false);
46648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
46658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstruct InlineMinMaxIterator {
46678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* InlineMinMaxIterator is a class that will iterate over all render objects that contribute to
46688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project   inline min/max width calculations.  Note the following about the way it walks:
46698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project   (1) Positioned content is skipped (since it does not contribute to min/max width of a block)
46708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project   (2) We do not drill into the children of floats or replaced elements, since you can't break
46718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project       in the middle of such an element.
46728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project   (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side can have
46738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project       distinct borders/margin/padding that contribute to the min/max width.
46748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project*/
46758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* parent;
46768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* current;
46778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool endOfInline;
46788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    InlineMinMaxIterator(RenderObject* p, bool end = false)
46808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        :parent(p), current(p), endOfInline(end) {}
46818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* next();
46838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
46848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderObject* InlineMinMaxIterator::next()
46868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
46878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* result = 0;
46888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool oldEndOfInline = endOfInline;
46898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    endOfInline = false;
46908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (current || current == parent) {
46918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!oldEndOfInline &&
46928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            (current == parent ||
46938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project             (!current->isFloating() && !current->isReplaced() && !current->isPositioned())))
46948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            result = current->firstChild();
46958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!result) {
46968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We hit the end of our inline. (It was empty, e.g., <span></span>.)
4697635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (!oldEndOfInline && current->isRenderInline()) {
46988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                result = current;
46998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                endOfInline = true;
47008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
47018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
47028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            while (current && current != parent) {
47048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                result = current->nextSibling();
47058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (result) break;
47068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                current = current->parent();
4707635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (current && current != parent && current->isRenderInline()) {
47088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    result = current;
47098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    endOfInline = true;
47108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
47118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
47128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
47138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
47148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!result)
47168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
47178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4718635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (!result->isPositioned() && (result->isText() || result->isFloating() || result->isReplaced() || result->isRenderInline()))
47198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project             break;
47208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        current = result;
47228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result = 0;
47238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
47248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Update our position.
47268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    current = result;
47278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return current;
47288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
47298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic int getBPMWidth(int childValue, Length cssUnit)
47318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
47328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (cssUnit.type() != Auto)
47338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return (cssUnit.isFixed() ? cssUnit.value() : childValue);
47348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
47358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
47368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic int getBorderPaddingMargin(const RenderBoxModelObject* child, bool endOfInline)
47388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
47398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderStyle* cstyle = child->style();
47402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (endOfInline)
47412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return getBPMWidth(child->marginEnd(), cstyle->marginEnd()) +
47422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block               getBPMWidth(child->paddingEnd(), cstyle->paddingEnd()) +
47432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block               child->borderEnd();
47442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return getBPMWidth(child->marginStart(), cstyle->marginStart()) +
47452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block               getBPMWidth(child->paddingStart(), cstyle->paddingStart()) +
47462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block               child->borderStart();
47478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
47488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
474981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic inline void stripTrailingSpace(float& inlineMax, float& inlineMin,
47508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                      RenderObject* trailingSpaceChild)
47518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
47528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (trailingSpaceChild && trailingSpaceChild->isText()) {
47538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Collapse away the trailing space at the end of a block.
4754635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        RenderText* t = toRenderText(trailingSpaceChild);
47558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const UChar space = ' ';
47568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const Font& font = t->style()->font(); // FIXME: This ignores first-line.
475781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        float spaceWidth = font.width(TextRun(&space, 1));
47588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        inlineMax -= spaceWidth + font.wordSpacing();
47598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (inlineMin > inlineMax)
47608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            inlineMin = inlineMax;
47618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
47628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
47638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
476481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic inline void updatePreferredWidth(int& preferredWidth, float& result)
476581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
476681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int snappedResult = ceilf(result);
476781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    preferredWidth = max(snappedResult, preferredWidth);
476881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
476981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
4770bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBlock::computeInlinePreferredLogicalWidths()
47718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
477281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    float inlineMax = 0;
477381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    float inlineMin = 0;
47748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int cw = containingBlock()->contentLogicalWidth();
47768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If we are at the start of a line, we want to ignore all white-space.
47788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Also strip spaces if we previously had text that ended in a trailing space.
47798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool stripFrontSpaces = true;
47808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* trailingSpaceChild = 0;
47818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Firefox and Opera will allow a table cell to grow to fit an image inside it under
47838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // very specific cirucumstances (in order to match common WinIE renderings).
47848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
47852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    bool allowImagesToBreak = !document()->inQuirksMode() || !isTableCell() || !style()->logicalWidth().isIntrinsicOrAuto();
47868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool autoWrap, oldAutoWrap;
47888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    autoWrap = oldAutoWrap = style()->autoWrap();
47898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    InlineMinMaxIterator childIterator(this);
47918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool addedTextIndent = false; // Only gets added in once.
47928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* prevFloat = 0;
47938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (RenderObject* child = childIterator.next()) {
47948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        autoWrap = child->isReplaced() ? child->parent()->style()->autoWrap() :
47958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            child->style()->autoWrap();
47968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!child->isBR()) {
47988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Step One: determine whether or not we need to go ahead and
47998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // terminate our current line.  Each discrete chunk can become
48008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // the new min-width, if it is the widest chunk seen so far, and
48018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // it can also become the max-width.
48028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Children fall into three categories:
48048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (1) An inline flow object.  These objects always have a min/max of 0,
48058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // and are included in the iteration solely so that their margins can
48068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // be added in.
48078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            //
48088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (2) An inline non-text non-flow object, e.g., an inline replaced element.
48098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // These objects can always be on a line by themselves, so in this situation
48108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // we need to go ahead and break the current line, and then add in our own
48118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // margins and min/max width on its own line, and then terminate the line.
48128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            //
48138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (3) A text object.  Text runs can have breakable characters at the start,
48148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // the middle or the end.  They may also lose whitespace off the front if
48158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // we're already ignoring whitespace.  In order to compute accurate min-width
48168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // information, we need three pieces of information.
48178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (a) the min-width of the first non-breakable run.  Should be 0 if the text string
48188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // starts with whitespace.
48198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (b) the min-width of the last non-breakable run. Should be 0 if the text string
48208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // ends with whitespace.
48218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (c) the min/max width of the string (trimmed for whitespace).
48228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            //
48238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // If the text string starts with whitespace, then we need to go ahead and
48248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // terminate our current line (unless we're already in a whitespace stripping
48258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // mode.
48268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            //
48278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // If the text string has a breakable character in the middle, but didn't start
48288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // with whitespace, then we add the width of the first non-breakable run and
48298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // then end the current line.  We then need to use the intermediate min/max width
48308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // values (if any of them are larger than our current min/max).  We then look at
48318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // the width of the last non-breakable run and use that to start a new line
48328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (unless we end in whitespace).
48338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderStyle* cstyle = child->style();
483481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            float childMin = 0;
483581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            float childMax = 0;
48368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!child->isText()) {
48388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Case (1) and (2).  Inline replaced and inline flow elements.
4839635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (child->isRenderInline()) {
48408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // Add in padding/border/margin from the appropriate side of
48418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // the element.
484281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    float bpm = getBorderPaddingMargin(toRenderInline(child), childIterator.endOfInline);
48438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    childMin += bpm;
48448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    childMax += bpm;
48458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMin += childMin;
48478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMax += childMax;
48488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4849bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                    child->setPreferredLogicalWidthsDirty(false);
48508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else {
48518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // Inline replaced elts add in their margins to their min/max values.
485281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    float margins = 0;
48532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    Length startMargin = cstyle->marginStart();
48542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    Length endMargin = cstyle->marginEnd();
48552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    if (startMargin.isFixed())
48562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                        margins += startMargin.value();
48572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    if (endMargin.isFixed())
48582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                        margins += endMargin.value();
48598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    childMin += margins;
48608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    childMax += margins;
48618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
48628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
48638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!child->isRenderInline() && !child->isText()) {
48658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Case (2). Inline replaced elements and floats.
48668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Go ahead and terminate the current line as far as
48678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // minwidth is concerned.
4868bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                childMin += child->minPreferredLogicalWidth();
4869bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                childMax += child->maxPreferredLogicalWidth();
48708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                bool clearPreviousFloat;
48728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (child->isFloating()) {
48738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    clearPreviousFloat = (prevFloat
48748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        && ((prevFloat->style()->floating() == FLEFT && (child->style()->clear() & CLEFT))
48758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                            || (prevFloat->style()->floating() == FRIGHT && (child->style()->clear() & CRIGHT))));
48768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    prevFloat = child;
48778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else
48788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    clearPreviousFloat = false;
48798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak;
48818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if ((canBreakReplacedElement && (autoWrap || oldAutoWrap)) || clearPreviousFloat) {
488281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
48838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMin = 0;
48848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
48858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // If we're supposed to clear the previous float, then terminate maxwidth as well.
48878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (clearPreviousFloat) {
488881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
48898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMax = 0;
48908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
48918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Add in text-indent.  This is added in only once.
48938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                int ti = 0;
48948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!addedTextIndent) {
48958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    addedTextIndent = true;
48968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    ti = style()->textIndent().calcMinValue(cw);
48972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    childMin += ti;
48982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    childMax += ti;
48998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
49008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Add our width to the max.
49028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                inlineMax += childMax;
49038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!autoWrap || !canBreakReplacedElement) {
49058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (child->isFloating())
490681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        updatePreferredWidth(m_minPreferredLogicalWidth, childMin);
49078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    else
49088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        inlineMin += childMin;
49098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else {
49108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // Now check our line.
491181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    updatePreferredWidth(m_minPreferredLogicalWidth, childMin);
49128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // Now start a new line.
49148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMin = 0;
49158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
49168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // We are no longer stripping whitespace at the start of
49188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // a line.
49198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!child->isFloating()) {
49208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    stripFrontSpaces = false;
49218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    trailingSpaceChild = 0;
49228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
49238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else if (child->isText()) {
49248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Case (3). Text.
4925635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                RenderText* t = toRenderText(child);
49268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (t->isWordBreak()) {
492881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
49298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMin = 0;
49308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
49318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
49328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49332bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (t->style()->hasTextCombine() && t->isCombineText())
49342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    toRenderCombineText(t)->combineText();
49352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
49368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Determine if we have a breakable character.  Pass in
49378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // whether or not we should ignore any spaces at the front
49388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // of the string.  If those are going to be stripped out,
49398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // then they shouldn't be considered in the breakable char
49408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // check.
49418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                bool hasBreakableChar, hasBreak;
494281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                float beginMin, endMin;
49438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                bool beginWS, endWS;
494481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                float beginMax, endMax;
49458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                t->trimmedPrefWidths(inlineMax, beginMin, beginWS, endMin, endWS,
49468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                     hasBreakableChar, hasBreak, beginMax, endMax,
49478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                     childMin, childMax, stripFrontSpaces);
49488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // This text object will not be rendered, but it may still provide a breaking opportunity.
49508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!hasBreak && childMax == 0) {
49518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (autoWrap && (beginWS || endWS)) {
495281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
49538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        inlineMin = 0;
49548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
49558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
49568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
49578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (stripFrontSpaces)
49598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    trailingSpaceChild = child;
49608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                else
49618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    trailingSpaceChild = 0;
49628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Add in text-indent.  This is added in only once.
49648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                int ti = 0;
49658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!addedTextIndent) {
49668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    addedTextIndent = true;
49678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    ti = style()->textIndent().calcMinValue(cw);
49688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    childMin+=ti; beginMin += ti;
49698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    childMax+=ti; beginMax += ti;
49708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
49718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // If we have no breakable characters at all,
49738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // then this is the easy case. We add ourselves to the current
49748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // min and max and continue.
49758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!hasBreakableChar) {
49768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMin += childMin;
49778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else {
49788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // We have a breakable character.  Now we need to know if
49798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // we start and end with whitespace.
49808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (beginWS)
49818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // Go ahead and end the current line.
498281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
49838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    else {
49848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        inlineMin += beginMin;
498581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
49868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        childMin -= ti;
49878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
49888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMin = childMin;
49908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (endWS) {
49928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // We end in whitespace, which means we can go ahead
49938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // and end our current line.
499481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
49958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        inlineMin = 0;
49968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    } else {
499781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
49988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        inlineMin = endMin;
49998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
50008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
50018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (hasBreak) {
50038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMax += beginMax;
500481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
500581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    updatePreferredWidth(m_maxPreferredLogicalWidth, childMax);
50068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMax = endMax;
50078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else
50088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMax += childMax;
50098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
5010643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
5011643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            // Ignore spaces after a list marker.
5012643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (child->isListMarker())
5013643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                stripFrontSpaces = true;
50148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
501581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
501681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
50178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            inlineMin = inlineMax = 0;
50188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            stripFrontSpaces = true;
50198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            trailingSpaceChild = 0;
50208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
50218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        oldAutoWrap = autoWrap;
50238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
50248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->collapseWhiteSpace())
50268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        stripTrailingSpace(inlineMax, inlineMin, trailingSpaceChild);
50278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
502881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
502981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
50308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
50318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Use a very large value (in effect infinite).
50338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define BLOCK_MAX_WIDTH 15000
50348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5035bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBlock::computeBlockPreferredLogicalWidths()
50368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
50378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool nowrap = style()->whiteSpace() == NOWRAP;
50388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject *child = firstChild();
50408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int floatLeftWidth = 0, floatRightWidth = 0;
50418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (child) {
50428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Positioned children don't affect the min/max width
50438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (child->isPositioned()) {
50448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            child = child->nextSibling();
50458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
50468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
50478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (child->isFloating() || (child->isBox() && toRenderBox(child)->avoidsFloats())) {
50498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int floatTotalWidth = floatLeftWidth + floatRightWidth;
50508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (child->style()->clear() & CLEFT) {
5051bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                m_maxPreferredLogicalWidth = max(floatTotalWidth, m_maxPreferredLogicalWidth);
50528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatLeftWidth = 0;
50538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
50548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (child->style()->clear() & CRIGHT) {
5055bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                m_maxPreferredLogicalWidth = max(floatTotalWidth, m_maxPreferredLogicalWidth);
50568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatRightWidth = 0;
50578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
50588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
50598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // A margin basically has three types: fixed, percentage, and auto (variable).
50618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Auto and percentage margins simply become 0 when computing min/max width.
50628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Fixed margins can be added in as is.
50632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        Length startMarginLength = child->style()->marginStart();
50642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        Length endMarginLength = child->style()->marginEnd();
50652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int margin = 0;
50662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int marginStart = 0;
50672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int marginEnd = 0;
50682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (startMarginLength.isFixed())
50692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            marginStart += startMarginLength.value();
50702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (endMarginLength.isFixed())
50712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            marginEnd += endMarginLength.value();
50722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        margin = marginStart + marginEnd;
50738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5074bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        int w = child->minPreferredLogicalWidth() + margin;
5075bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_minPreferredLogicalWidth = max(w, m_minPreferredLogicalWidth);
50768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // IE ignores tables for calculation of nowrap. Makes some sense.
50788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (nowrap && !child->isTable())
5079bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            m_maxPreferredLogicalWidth = max(w, m_maxPreferredLogicalWidth);
50808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5081bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        w = child->maxPreferredLogicalWidth() + margin;
50828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!child->isFloating()) {
50848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (child->isBox() && toRenderBox(child)->avoidsFloats()) {
50858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Determine a left and right max value based off whether or not the floats can fit in the
50868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // margins of the object.  For negative margins, we will attempt to overlap the float if the negative margin
50878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // is smaller than the float width.
50882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                bool ltr = containingBlock()->style()->isLeftToRightDirection();
50892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int marginLogicalLeft = ltr ? marginStart : marginEnd;
50902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int marginLogicalRight = ltr ? marginEnd : marginStart;
50912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int maxLeft = marginLogicalLeft > 0 ? max(floatLeftWidth, marginLogicalLeft) : floatLeftWidth + marginLogicalLeft;
50922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int maxRight = marginLogicalRight > 0 ? max(floatRightWidth, marginLogicalRight) : floatRightWidth + marginLogicalRight;
5093bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                w = child->maxPreferredLogicalWidth() + maxLeft + maxRight;
50948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                w = max(w, floatLeftWidth + floatRightWidth);
50958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
50968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
5097bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                m_maxPreferredLogicalWidth = max(floatLeftWidth + floatRightWidth, m_maxPreferredLogicalWidth);
50988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            floatLeftWidth = floatRightWidth = 0;
50998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
51008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
51018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (child->isFloating()) {
51028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (style()->floating() == FLEFT)
51038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatLeftWidth += w;
51048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
51058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatRightWidth += w;
51068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else
5107bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            m_maxPreferredLogicalWidth = max(w, m_maxPreferredLogicalWidth);
51088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
51098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // A very specific WinIE quirk.
51108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Example:
51118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        /*
51128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project           <div style="position:absolute; width:100px; top:50px;">
51138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project              <div style="position:absolute;left:0px;top:50px;height:50px;background-color:green">
51148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                <table style="width:100%"><tr><td></table>
51158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project              </div>
51168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project           </div>
51178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        */
51188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // In the above example, the inner absolute positioned block should have a computed width
51198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // of 100px because of the table.
51208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We can achieve this effect by making the maxwidth of blocks that contain tables
51218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // with percentage widths be infinite (as long as they are not inside a table cell).
51222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (document()->inQuirksMode() && child->style()->logicalWidth().isPercent() &&
5123bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            !isTableCell() && child->isTable() && m_maxPreferredLogicalWidth < BLOCK_MAX_WIDTH) {
51248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderBlock* cb = containingBlock();
51258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            while (!cb->isRenderView() && !cb->isTableCell())
51268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                cb = cb->containingBlock();
51278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!cb->isTableCell())
5128bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                m_maxPreferredLogicalWidth = BLOCK_MAX_WIDTH;
51298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
51308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
51318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child = child->nextSibling();
51328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
51338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
51348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Always make sure these values are non-negative.
5135bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_minPreferredLogicalWidth = max(0, m_minPreferredLogicalWidth);
5136bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_maxPreferredLogicalWidth = max(0, m_maxPreferredLogicalWidth);
51378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5138bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_maxPreferredLogicalWidth = max(floatLeftWidth + floatRightWidth, m_maxPreferredLogicalWidth);
51398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
51408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
51418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::hasLineIfEmpty() const
51428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
51430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!node())
51440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return false;
51450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
51462bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (node()->rendererIsEditable() && node()->rootEditableElement() == node())
51470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return true;
51480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5149cad810f21b803229eb11403f9209855525a25d57Steve Block    if (node()->isShadowRoot() && (node()->shadowHost()->hasTagName(inputTag)))
51500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return true;
51510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
51520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return false;
51538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
51548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5155a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::lineHeight(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
51568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
51578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Inline blocks are replaced elements. Otherwise, just pass off to
51588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the base class.  If we're being queried as though we're the root line
51598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // box, then the fact that we're an inline-block is irrelevant, and we behave
51608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // just like a block.
5161a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (isReplaced() && linePositionMode == PositionOnContainingLine)
5162a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return RenderBox::lineHeight(firstLine, direction, linePositionMode);
5163a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
51648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (firstLine && document()->usesFirstLineRules()) {
51658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderStyle* s = style(firstLine);
51668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (s != style())
51678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return s->computedLineHeight();
51688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
51698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
51708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_lineHeight == -1)
51718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_lineHeight = style()->computedLineHeight();
51728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
51738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return m_lineHeight;
51748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
51758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
51766b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerint RenderBlock::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
51778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
51788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Inline blocks are replaced elements. Otherwise, just pass off to
51798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the base class.  If we're being queried as though we're the root line
51808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // box, then the fact that we're an inline-block is irrelevant, and we behave
51818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // just like a block.
5182a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (isReplaced() && linePositionMode == PositionOnContainingLine) {
51838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // For "leaf" theme objects, let the theme decide what the baseline position is.
51848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: Might be better to have a custom CSS property instead, so that if the theme
51858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // is turned off, checkboxes/radios will still have decent baselines.
5186a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // FIXME: Need to patch form controls to deal with vertical lines.
51878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (style()->hasAppearance() && !theme()->isControlContainer(style()->appearance()))
51888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return theme()->baselinePosition(this);
51898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
51908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // CSS2.1 states that the baseline of an inline block is the baseline of the last line box in
51918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // the normal flow.  We make an exception for marquees, since their baselines are meaningless
51928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // (the content inside them moves).  This matches WinIE as well, which just bottom-aligns them.
51938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We also give up on finding a baseline if we have a vertical scrollbar, or if we are scrolled
51948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // vertically (e.g., an overflow:hidden block that has had scrollTop moved) or if the baseline is outside
51958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // of our content box.
5196a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        bool ignoreBaseline = (layer() && (layer()->marquee() || (direction == HorizontalLine ? (layer()->verticalScrollbar() || layer()->scrollYOffset() != 0)
51976b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            : (layer()->horizontalScrollbar() || layer()->scrollXOffset() != 0)))) || (isWritingModeRoot() && !isRubyRun());
51986b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
5199a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int baselinePos = ignoreBaseline ? -1 : lastLineBoxBaseline();
5200a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
5201a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int bottomOfContent = direction == HorizontalLine ? borderTop() + paddingTop() + contentHeight() : borderRight() + paddingRight() + contentWidth();
5202a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (baselinePos != -1 && baselinePos <= bottomOfContent)
5203a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            return direction == HorizontalLine ? marginTop() + baselinePos : marginRight() + baselinePos;
5204a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
52056b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
52068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5207a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
52082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    const FontMetrics& fontMetrics = style(firstLine)->fontMetrics();
52092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2;
52108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
52118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
52128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianint RenderBlock::firstLineBoxBaseline() const
52138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
52146b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (!isBlockFlow() || (isWritingModeRoot() && !isRubyRun()))
52158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return -1;
52168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
52178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childrenInline()) {
52188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (firstLineBox())
52192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return firstLineBox()->logicalTop() + style(true)->fontMetrics().ascent(firstRootBox()->baselineType());
52208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
52218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return -1;
52228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
52238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
5224635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        for (RenderBox* curr = firstChildBox(); curr; curr = curr->nextSiblingBox()) {
52258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!curr->isFloatingOrPositioned()) {
52268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                int result = curr->firstLineBoxBaseline();
52278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (result != -1)
5228a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    return curr->logicalTop() + result; // Translate to our coordinate space.
52298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
52308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
52318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
52328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
52338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return -1;
52348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
52358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
52368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianint RenderBlock::lastLineBoxBaseline() const
52378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
52386b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (!isBlockFlow() || (isWritingModeRoot() && !isRubyRun()))
52398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return -1;
52408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
52412bde8e466a4451c7319e3a072d118917957d6554Steve Block    LineDirectionMode lineDirection = isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
5242a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
52438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childrenInline()) {
5244a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!firstLineBox() && hasLineIfEmpty()) {
52452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
52462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return fontMetrics.ascent()
52472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                 + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
52482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
5249a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
52508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (lastLineBox())
52512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->fontMetrics().ascent(lastRootBox()->baselineType());
52528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return -1;
5253a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else {
52548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool haveNormalFlowChild = false;
5255635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        for (RenderBox* curr = lastChildBox(); curr; curr = curr->previousSiblingBox()) {
52568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!curr->isFloatingOrPositioned()) {
52578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                haveNormalFlowChild = true;
52588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                int result = curr->lastLineBoxBaseline();
52598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (result != -1)
5260a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    return curr->logicalTop() + result; // Translate to our coordinate space.
52618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
52628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5263a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!haveNormalFlowChild && hasLineIfEmpty()) {
52642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
52652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return fontMetrics.ascent()
52662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                 + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
52672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
5268a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
52698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
52708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
52718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return -1;
52728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
52738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5274635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool RenderBlock::containsNonZeroBidiLevel() const
5275635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
5276635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
5277635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        for (InlineBox* box = root->firstLeafChild(); box; box = box->nextLeafChild()) {
5278635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (box->bidiLevel())
5279635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                return true;
5280635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
5281635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
5282635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return false;
5283635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
5284635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
52858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderBlock* RenderBlock::firstLineBlock() const
52868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5287635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderBlock* firstLineBlock = const_cast<RenderBlock*>(this);
52888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool hasPseudo = false;
52898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (true) {
52908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        hasPseudo = firstLineBlock->style()->hasPseudoStyle(FIRST_LINE);
52918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (hasPseudo)
52928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
52938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderObject* parentBlock = firstLineBlock->parent();
52948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (firstLineBlock->isReplaced() || firstLineBlock->isFloating() ||
52958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            !parentBlock || parentBlock->firstChild() != firstLineBlock || !parentBlock->isBlockFlow())
52968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
5297635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        ASSERT(parentBlock->isRenderBlock());
52988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        firstLineBlock = toRenderBlock(parentBlock);
52998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
53008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
53018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!hasPseudo)
53028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
53038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5304635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return firstLineBlock;
53058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
53068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
530768513a70bcd92384395513322f1b801e7bf9c729Steve Blockstatic RenderStyle* styleForFirstLetter(RenderObject* firstLetterBlock, RenderObject* firstLetterContainer)
530868513a70bcd92384395513322f1b801e7bf9c729Steve Block{
530968513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderStyle* pseudoStyle = firstLetterBlock->getCachedPseudoStyle(FIRST_LETTER, firstLetterContainer->firstLineStyle());
531068513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Force inline display (except for floating first-letters).
531168513a70bcd92384395513322f1b801e7bf9c729Steve Block    pseudoStyle->setDisplay(pseudoStyle->isFloating() ? BLOCK : INLINE);
531268513a70bcd92384395513322f1b801e7bf9c729Steve Block    // CSS2 says first-letter can't be positioned.
531368513a70bcd92384395513322f1b801e7bf9c729Steve Block    pseudoStyle->setPosition(StaticPosition);
531468513a70bcd92384395513322f1b801e7bf9c729Steve Block    return pseudoStyle;
531568513a70bcd92384395513322f1b801e7bf9c729Steve Block}
531668513a70bcd92384395513322f1b801e7bf9c729Steve Block
5317a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch// CSS 2.1 http://www.w3.org/TR/CSS21/selector.html#first-letter
5318a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch// "Punctuation (i.e, characters defined in Unicode [UNICODE] in the "open" (Ps), "close" (Pe),
5319a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch// "initial" (Pi). "final" (Pf) and "other" (Po) punctuation classes), that precedes or follows the first letter should be included"
5320a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic inline bool isPunctuationForFirstLetter(UChar c)
5321a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
5322a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    CharCategory charCategory = category(c);
5323a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return charCategory == Punctuation_Open
5324a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        || charCategory == Punctuation_Close
5325a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        || charCategory == Punctuation_InitialQuote
5326a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        || charCategory == Punctuation_FinalQuote
5327a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        || charCategory == Punctuation_Other;
5328a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
5329a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
5330a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic inline bool shouldSkipForFirstLetter(UChar c)
5331a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
5332a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return isSpaceOrNewline(c) || c == noBreakSpace || isPunctuationForFirstLetter(c);
5333a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
5334a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
53358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::updateFirstLetter()
53368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
53378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!document()->usesFirstLetterRules())
53388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
53398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Don't recur
53408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (style()->styleType() == FIRST_LETTER)
53418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
53428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
53438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: We need to destroy the first-letter object if it is no longer the first child.  Need to find
53448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // an efficient way to check for that situation though before implementing anything.
53458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* firstLetterBlock = this;
53468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool hasPseudoStyle = false;
53478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (true) {
53488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We only honor first-letter if the firstLetterBlock can have children in the DOM. This correctly
53498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // prevents form controls from honoring first-letter.
53508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        hasPseudoStyle = firstLetterBlock->style()->hasPseudoStyle(FIRST_LETTER)
53518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            && firstLetterBlock->canHaveChildren();
53528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (hasPseudoStyle)
53538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
53548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderObject* parentBlock = firstLetterBlock->parent();
53558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (firstLetterBlock->isReplaced() || !parentBlock || parentBlock->firstChild() != firstLetterBlock ||
53568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            !parentBlock->isBlockFlow())
53578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
53588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        firstLetterBlock = parentBlock;
53598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
53608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
53618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!hasPseudoStyle)
53628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
53638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
53648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Drill into inlines looking for our first text child.
53658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* currChild = firstLetterBlock->firstChild();
53666c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    while (currChild && ((!currChild->isReplaced() && !currChild->isRenderButton() && !currChild->isMenuList()) || currChild->isFloatingOrPositioned()) && !currChild->isText()) {
53678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (currChild->isFloatingOrPositioned()) {
53686c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            if (currChild->style()->styleType() == FIRST_LETTER) {
53696c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen                currChild = currChild->firstChild();
53708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
53716c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            }
53728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            currChild = currChild->nextSibling();
53738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else
53748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            currChild = currChild->firstChild();
53758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
53768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
53778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Get list markers out of the way.
53788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (currChild && currChild->isListMarker())
53798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        currChild = currChild->nextSibling();
53808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
53818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!currChild)
53828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
53838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
53848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the child already has style, then it has already been created, so we just want
53858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // to update it.
538668513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (currChild->parent()->style()->styleType() == FIRST_LETTER) {
538768513a70bcd92384395513322f1b801e7bf9c729Steve Block        RenderObject* firstLetter = currChild->parent();
538868513a70bcd92384395513322f1b801e7bf9c729Steve Block        RenderObject* firstLetterContainer = firstLetter->parent();
538968513a70bcd92384395513322f1b801e7bf9c729Steve Block        RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
539068513a70bcd92384395513322f1b801e7bf9c729Steve Block
539168513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (Node::diff(firstLetter->style(), pseudoStyle) == Node::Detach) {
539268513a70bcd92384395513322f1b801e7bf9c729Steve Block            // The first-letter renderer needs to be replaced. Create a new renderer of the right type.
539368513a70bcd92384395513322f1b801e7bf9c729Steve Block            RenderObject* newFirstLetter;
539468513a70bcd92384395513322f1b801e7bf9c729Steve Block            if (pseudoStyle->display() == INLINE)
539568513a70bcd92384395513322f1b801e7bf9c729Steve Block                newFirstLetter = new (renderArena()) RenderInline(document());
539668513a70bcd92384395513322f1b801e7bf9c729Steve Block            else
539768513a70bcd92384395513322f1b801e7bf9c729Steve Block                newFirstLetter = new (renderArena()) RenderBlock(document());
539868513a70bcd92384395513322f1b801e7bf9c729Steve Block            newFirstLetter->setStyle(pseudoStyle);
539968513a70bcd92384395513322f1b801e7bf9c729Steve Block
540068513a70bcd92384395513322f1b801e7bf9c729Steve Block            // Move the first letter into the new renderer.
540168513a70bcd92384395513322f1b801e7bf9c729Steve Block            view()->disableLayoutState();
540268513a70bcd92384395513322f1b801e7bf9c729Steve Block            while (RenderObject* child = firstLetter->firstChild()) {
540368513a70bcd92384395513322f1b801e7bf9c729Steve Block                if (child->isText())
54042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    toRenderText(child)->removeAndDestroyTextBoxes();
540568513a70bcd92384395513322f1b801e7bf9c729Steve Block                firstLetter->removeChild(child);
540668513a70bcd92384395513322f1b801e7bf9c729Steve Block                newFirstLetter->addChild(child, 0);
540768513a70bcd92384395513322f1b801e7bf9c729Steve Block            }
540881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
540981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            RenderTextFragment* remainingText = 0;
541081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            RenderObject* nextSibling = firstLetter->nextSibling();
541181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            RenderObject* next = nextSibling;
541281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            while (next) {
541381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (next->isText() && toRenderText(next)->isTextFragment()) {
541481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    remainingText = toRenderTextFragment(next);
541581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    break;
541681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                }
541781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                next = next->nextSibling();
541881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
541981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (remainingText) {
542081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                ASSERT(remainingText->node()->renderer() == remainingText);
542181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                // Replace the old renderer with the new one.
542281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                remainingText->setFirstLetter(newFirstLetter);
542381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
542468513a70bcd92384395513322f1b801e7bf9c729Steve Block            firstLetter->destroy();
542568513a70bcd92384395513322f1b801e7bf9c729Steve Block            firstLetter = newFirstLetter;
542681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            firstLetterContainer->addChild(firstLetter, nextSibling);
542768513a70bcd92384395513322f1b801e7bf9c729Steve Block            view()->enableLayoutState();
542868513a70bcd92384395513322f1b801e7bf9c729Steve Block        } else
542968513a70bcd92384395513322f1b801e7bf9c729Steve Block            firstLetter->setStyle(pseudoStyle);
543068513a70bcd92384395513322f1b801e7bf9c729Steve Block
543168513a70bcd92384395513322f1b801e7bf9c729Steve Block        for (RenderObject* genChild = firstLetter->firstChild(); genChild; genChild = genChild->nextSibling()) {
54328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (genChild->isText())
543368513a70bcd92384395513322f1b801e7bf9c729Steve Block                genChild->setStyle(pseudoStyle);
54348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
543568513a70bcd92384395513322f1b801e7bf9c729Steve Block
54368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
54378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
54388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
543968513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!currChild->isText() || currChild->isBR())
544068513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
544168513a70bcd92384395513322f1b801e7bf9c729Steve Block
54428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the child does not already have style, we create it here.
544368513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderObject* firstLetterContainer = currChild->parent();
54448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
544568513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Our layout state is not valid for the repaints we are going to trigger by
544668513a70bcd92384395513322f1b801e7bf9c729Steve Block    // adding and removing children of firstLetterContainer.
544768513a70bcd92384395513322f1b801e7bf9c729Steve Block    view()->disableLayoutState();
544868513a70bcd92384395513322f1b801e7bf9c729Steve Block
544968513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderText* textObj = toRenderText(currChild);
545068513a70bcd92384395513322f1b801e7bf9c729Steve Block
545168513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Create our pseudo style now that we have our firstLetterContainer determined.
545268513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
545368513a70bcd92384395513322f1b801e7bf9c729Steve Block
545468513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderObject* firstLetter = 0;
545568513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (pseudoStyle->display() == INLINE)
545668513a70bcd92384395513322f1b801e7bf9c729Steve Block        firstLetter = new (renderArena()) RenderInline(document());
545768513a70bcd92384395513322f1b801e7bf9c729Steve Block    else
545868513a70bcd92384395513322f1b801e7bf9c729Steve Block        firstLetter = new (renderArena()) RenderBlock(document());
545968513a70bcd92384395513322f1b801e7bf9c729Steve Block    firstLetter->setStyle(pseudoStyle);
546068513a70bcd92384395513322f1b801e7bf9c729Steve Block    firstLetterContainer->addChild(firstLetter, currChild);
546168513a70bcd92384395513322f1b801e7bf9c729Steve Block
546268513a70bcd92384395513322f1b801e7bf9c729Steve Block    // The original string is going to be either a generated content string or a DOM node's
546368513a70bcd92384395513322f1b801e7bf9c729Steve Block    // string.  We want the original string before it got transformed in case first-letter has
546468513a70bcd92384395513322f1b801e7bf9c729Steve Block    // no text-transform or a different text-transform applied to it.
546568513a70bcd92384395513322f1b801e7bf9c729Steve Block    RefPtr<StringImpl> oldText = textObj->originalText();
546668513a70bcd92384395513322f1b801e7bf9c729Steve Block    ASSERT(oldText);
546768513a70bcd92384395513322f1b801e7bf9c729Steve Block
546868513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (oldText && oldText->length() > 0) {
546968513a70bcd92384395513322f1b801e7bf9c729Steve Block        unsigned length = 0;
547068513a70bcd92384395513322f1b801e7bf9c729Steve Block
5471a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // Account for leading spaces and punctuation.
5472a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        while (length < oldText->length() && shouldSkipForFirstLetter((*oldText)[length]))
54738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            length++;
54748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5475a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // Account for first letter.
547668513a70bcd92384395513322f1b801e7bf9c729Steve Block        length++;
5477a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
5478a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // Keep looking for whitespace and allowed punctuation, but avoid
5479a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // accumulating just whitespace into the :first-letter.
5480a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        for (unsigned scanLength = length; scanLength < oldText->length(); ++scanLength) {
5481a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            UChar c = (*oldText)[scanLength];
5482a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
5483a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (!shouldSkipForFirstLetter(c))
5484a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                break;
548568513a70bcd92384395513322f1b801e7bf9c729Steve Block
5486a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (isPunctuationForFirstLetter(c))
5487a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                length = scanLength + 1;
5488a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch         }
5489a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
5490a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // Construct a text fragment for the text after the first letter.
5491a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // This text fragment might be empty.
549268513a70bcd92384395513322f1b801e7bf9c729Steve Block        RenderTextFragment* remainingText =
549368513a70bcd92384395513322f1b801e7bf9c729Steve Block            new (renderArena()) RenderTextFragment(textObj->node() ? textObj->node() : textObj->document(), oldText.get(), length, oldText->length() - length);
549468513a70bcd92384395513322f1b801e7bf9c729Steve Block        remainingText->setStyle(textObj->style());
549568513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (remainingText->node())
549668513a70bcd92384395513322f1b801e7bf9c729Steve Block            remainingText->node()->setRenderer(remainingText);
549768513a70bcd92384395513322f1b801e7bf9c729Steve Block
5498ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        firstLetterContainer->addChild(remainingText, textObj);
549968513a70bcd92384395513322f1b801e7bf9c729Steve Block        firstLetterContainer->removeChild(textObj);
550068513a70bcd92384395513322f1b801e7bf9c729Steve Block        remainingText->setFirstLetter(firstLetter);
550168513a70bcd92384395513322f1b801e7bf9c729Steve Block
550268513a70bcd92384395513322f1b801e7bf9c729Steve Block        // construct text fragment for the first letter
550368513a70bcd92384395513322f1b801e7bf9c729Steve Block        RenderTextFragment* letter =
550468513a70bcd92384395513322f1b801e7bf9c729Steve Block            new (renderArena()) RenderTextFragment(remainingText->node() ? remainingText->node() : remainingText->document(), oldText.get(), 0, length);
550568513a70bcd92384395513322f1b801e7bf9c729Steve Block        letter->setStyle(pseudoStyle);
550668513a70bcd92384395513322f1b801e7bf9c729Steve Block        firstLetter->addChild(letter);
550768513a70bcd92384395513322f1b801e7bf9c729Steve Block
550868513a70bcd92384395513322f1b801e7bf9c729Steve Block        textObj->destroy();
55098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
551068513a70bcd92384395513322f1b801e7bf9c729Steve Block    view()->enableLayoutState();
55118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
55128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
55138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Helper methods for obtaining the last line, computing line counts and heights for line counts
55148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// (crawling into blocks).
55158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool shouldCheckLines(RenderObject* obj)
55168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5517635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return !obj->isFloatingOrPositioned() && !obj->isRunIn() &&
55188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            obj->isBlockFlow() && obj->style()->height().isAuto() &&
55198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            (!obj->isFlexibleBox() || obj->style()->boxOrient() == VERTICAL);
55208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
55218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
55228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic RootInlineBox* getLineAtIndex(RenderBlock* block, int i, int& count)
55238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
55248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (block->style()->visibility() == VISIBLE) {
55258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (block->childrenInline()) {
55268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) {
55278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (count++ == i)
55288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    return box;
55298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
55308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
55318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
55328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RenderObject* obj = block->firstChild(); obj; obj = obj->nextSibling()) {
55338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (shouldCheckLines(obj)) {
55348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    RootInlineBox *box = getLineAtIndex(toRenderBlock(obj), i, count);
55358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (box)
55368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        return box;
55378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
55388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
55398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
55408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
55418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
55428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
55438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5544635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic int getHeightForLineCount(RenderBlock* block, int l, bool includeBottom, int& count)
55458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
55468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (block->style()->visibility() == VISIBLE) {
55478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (block->childrenInline()) {
55488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) {
55498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (++count == l)
5550231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    return box->lineBottom() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : 0);
55518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
55528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
55538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
5554635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            RenderBox* normalFlowChildWithoutLines = 0;
5555635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            for (RenderBox* obj = block->firstChildBox(); obj; obj = obj->nextSiblingBox()) {
55568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (shouldCheckLines(obj)) {
55578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    int result = getHeightForLineCount(toRenderBlock(obj), l, false, count);
55588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (result != -1)
5559635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                        return result + obj->y() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : 0);
55608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
5561635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                else if (!obj->isFloatingOrPositioned() && !obj->isRunIn())
55628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    normalFlowChildWithoutLines = obj;
55638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
55648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (normalFlowChildWithoutLines && l == 0)
5565635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                return normalFlowChildWithoutLines->y() + normalFlowChildWithoutLines->height();
55668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
55678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
55688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
55698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return -1;
55708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
55718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
55728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRootInlineBox* RenderBlock::lineAtIndex(int i)
55738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
55748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int count = 0;
55758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return getLineAtIndex(this, i, count);
55768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
55778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
55788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderBlock::lineCount()
55798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
55808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int count = 0;
55818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->visibility() == VISIBLE) {
55828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (childrenInline())
55838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
55848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                count++;
55858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
55868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling())
55878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (shouldCheckLines(obj))
55888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    count += toRenderBlock(obj)->lineCount();
55898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
55908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return count;
55918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
55928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
55938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderBlock::heightForLineCount(int l)
55948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
55958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int count = 0;
55968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return getHeightForLineCount(this, l, true, count);
55978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
55988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
55998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::adjustForBorderFit(int x, int& left, int& right) const
56008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
56018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We don't deal with relative positioning.  Our assumption is that you shrink to fit the lines without accounting
56028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // for either overflow or translations via relative positioning.
56038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->visibility() == VISIBLE) {
56048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (childrenInline()) {
56058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) {
56068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (box->firstChild())
560781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    left = min(left, x + static_cast<int>(box->firstChild()->x()));
56088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (box->lastChild())
560981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    right = max(right, x + static_cast<int>(ceilf(box->lastChild()->logicalRight())));
56108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
56118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
56128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
5613635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            for (RenderBox* obj = firstChildBox(); obj; obj = obj->nextSiblingBox()) {
56148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!obj->isFloatingOrPositioned()) {
56158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (obj->isBlockFlow() && !obj->hasOverflowClip())
56168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        toRenderBlock(obj)->adjustForBorderFit(x + obj->x(), left, right);
56178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    else if (obj->style()->visibility() == VISIBLE) {
56188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // We are a replaced element or some kind of non-block-flow object.
5619635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                        left = min(left, x + obj->x());
5620635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                        right = max(right, x + obj->x() + obj->width());
56218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
56228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
56238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
56248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
56258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
56268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_floatingObjects) {
562781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
562881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObjectSetIterator end = floatingObjectSet.end();
562981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
563081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                FloatingObject* r = *it;
56318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Only examine the object if our m_shouldPaint flag is set.
56328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (r->m_shouldPaint) {
56332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    int floatLeft = xPositionForFloatIncludingMargin(r) - r->m_renderer->x();
56348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    int floatRight = floatLeft + r->m_renderer->width();
56358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    left = min(left, floatLeft);
56368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    right = max(right, floatRight);
56378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
56388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
56398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
56408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
56418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
56428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
56438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::borderFitAdjust(int& x, int& w) const
56448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
56458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->borderFit() == BorderFitBorder)
56468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
56478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
56488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Walk any normal flow lines to snugly fit.
56498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int left = INT_MAX;
56508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int right = INT_MIN;
56518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int oldWidth = w;
56528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    adjustForBorderFit(0, left, right);
56538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (left != INT_MAX) {
56548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        left -= (borderLeft() + paddingLeft());
56558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (left > 0) {
56568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            x += left;
56578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            w -= left;
56588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
56598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
56608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (right != INT_MIN) {
56618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        right += (borderRight() + paddingRight());
56628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (right < oldWidth)
56638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            w -= (oldWidth - right);
56648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
56658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
56668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
56678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::clearTruncation()
56688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
56698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->visibility() == VISIBLE) {
56708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (childrenInline() && hasMarkupTruncation()) {
56718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            setHasMarkupTruncation(false);
56728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
56738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                box->clearTruncation();
56748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
56758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
56768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling())
56778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (shouldCheckLines(obj))
56788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    toRenderBlock(obj)->clearTruncation();
56798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
56808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
56818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5682bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBlock::setMaxMarginBeforeValues(int pos, int neg)
56838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
568468513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!m_rareData) {
5685a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (pos == RenderBlockRareData::positiveMarginBeforeDefault(this) && neg == RenderBlockRareData::negativeMarginBeforeDefault(this))
56868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
568768513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_rareData = new RenderBlockRareData(this);
56888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5689a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_rareData->m_margins.setPositiveMarginBefore(pos);
5690a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_rareData->m_margins.setNegativeMarginBefore(neg);
56918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
56928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5693bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBlock::setMaxMarginAfterValues(int pos, int neg)
56948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
569568513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!m_rareData) {
5696a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (pos == RenderBlockRareData::positiveMarginAfterDefault(this) && neg == RenderBlockRareData::negativeMarginAfterDefault(this))
569768513a70bcd92384395513322f1b801e7bf9c729Steve Block            return;
569868513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_rareData = new RenderBlockRareData(this);
569968513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
5700a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_rareData->m_margins.setPositiveMarginAfter(pos);
5701a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_rareData->m_margins.setNegativeMarginAfter(neg);
570268513a70bcd92384395513322f1b801e7bf9c729Steve Block}
570368513a70bcd92384395513322f1b801e7bf9c729Steve Block
570468513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid RenderBlock::setPaginationStrut(int strut)
570568513a70bcd92384395513322f1b801e7bf9c729Steve Block{
570668513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!m_rareData) {
570768513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (!strut)
57088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
570968513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_rareData = new RenderBlockRareData(this);
57108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
571168513a70bcd92384395513322f1b801e7bf9c729Steve Block    m_rareData->m_paginationStrut = strut;
571268513a70bcd92384395513322f1b801e7bf9c729Steve Block}
571368513a70bcd92384395513322f1b801e7bf9c729Steve Block
5714f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderBlock::setPageLogicalOffset(int logicalOffset)
571568513a70bcd92384395513322f1b801e7bf9c729Steve Block{
571668513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!m_rareData) {
5717f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (!logicalOffset)
571868513a70bcd92384395513322f1b801e7bf9c729Steve Block            return;
571968513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_rareData = new RenderBlockRareData(this);
572068513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
5721f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    m_rareData->m_pageLogicalOffset = logicalOffset;
57228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
57238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
57245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid RenderBlock::absoluteRects(Vector<IntRect>& rects, int tx, int ty)
57258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
57268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // For blocks inside inlines, we go ahead and include margins so that we run right up to the
57278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // inline boxes above and below us (thus getting merged with them to form a single irregular
57288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // shape).
5729e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (isAnonymousBlockContinuation()) {
5730bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // FIXME: This is wrong for block-flows that are horizontal.
5731bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // https://bugs.webkit.org/show_bug.cgi?id=46781
5732bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        rects.append(IntRect(tx, ty - collapsedMarginBefore(),
5733bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                             width(), height() + collapsedMarginBefore() + collapsedMarginAfter()));
5734e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        continuation()->absoluteRects(rects,
5735e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block                                      tx - x() + inlineElementContinuation()->containingBlock()->x(),
5736e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block                                      ty - y() + inlineElementContinuation()->containingBlock()->y());
57378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    } else
57388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        rects.append(IntRect(tx, ty, width(), height()));
57398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
57408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid RenderBlock::absoluteQuads(Vector<FloatQuad>& quads)
57428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
57438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // For blocks inside inlines, we go ahead and include margins so that we run right up to the
57448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // inline boxes above and below us (thus getting merged with them to form a single irregular
57458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // shape).
5746e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (isAnonymousBlockContinuation()) {
5747bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // FIXME: This is wrong for block-flows that are horizontal.
5748bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // https://bugs.webkit.org/show_bug.cgi?id=46781
5749bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        FloatRect localRect(0, -collapsedMarginBefore(),
5750bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                            width(), height() + collapsedMarginBefore() + collapsedMarginAfter());
57518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        quads.append(localToAbsoluteQuad(localRect));
5752e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        continuation()->absoluteQuads(quads);
57538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    } else
57548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width(), height())));
57558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
57568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianIntRect RenderBlock::rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth)
57588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
57598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    IntRect r(RenderBox::rectWithOutlineForRepaint(repaintContainer, outlineWidth));
5760e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (isAnonymousBlockContinuation())
5761bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        r.inflateY(collapsedMarginBefore()); // FIXME: This is wrong for block-flows that are horizontal.
57628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return r;
57638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
57648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianRenderObject* RenderBlock::hoverAncestor() const
57668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
5767e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    return isAnonymousBlockContinuation() ? continuation() : RenderBox::hoverAncestor();
57688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
57698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::updateDragState(bool dragOn)
57718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
57728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBox::updateDragState(dragOn);
5773e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (continuation())
5774e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        continuation()->updateDragState(dragOn);
57758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
57768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianRenderStyle* RenderBlock::outlineStyleForRepaint() const
57788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
5779e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    return isAnonymousBlockContinuation() ? continuation()->style() : style();
57808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
57818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::childBecameNonInline(RenderObject*)
57838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
57848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    makeChildrenNonInline();
57858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (isAnonymousBlock() && parent() && parent()->isRenderBlock())
57868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
57878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // |this| may be dead here
57888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
57898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::updateHitTestResult(HitTestResult& result, const IntPoint& point)
57918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
57928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (result.innerNode())
57938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
57948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Node* n = node();
5796e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (isAnonymousBlockContinuation())
57978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // We are in the margins of block elements that are part of a continuation.  In
5798e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        // this case we're actually still inside the enclosing element that was
57998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // split.  Go ahead and set our inner node accordingly.
5800e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        n = continuation()->node();
58018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (n) {
58038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        result.setInnerNode(n);
58048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (!result.innerNonSharedNode())
58058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            result.setInnerNonSharedNode(n);
58068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        result.setLocalPoint(point);
58078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
58088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
58098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianIntRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, int* extraWidthToEndOfLine)
58118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
58128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Do the normal calculation in most cases.
58138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (firstChild())
58148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return RenderBox::localCaretRect(inlineBox, caretOffset, extraWidthToEndOfLine);
58158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // This is a special case:
58178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // The element is not an inline element, and it's empty. So we have to
58188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // calculate a fake position to indicate where objects are to be inserted.
58198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // FIXME: This does not take into account either :first-line or :first-letter
58218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // However, as soon as some content is entered, the line boxes will be
58228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // constructed and this kludge is not called any more. So only the caret size
58238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // of an empty :first-line'd block is wrong. I think we can live with that.
58248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderStyle* currentStyle = firstLineStyle();
5825a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int height = lineHeight(true, currentStyle->isHorizontalWritingMode() ? HorizontalLine : VerticalLine);
58268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    enum CaretAlignment { alignLeft, alignRight, alignCenter };
58288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    CaretAlignment alignment = alignLeft;
58308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    switch (currentStyle->textAlign()) {
58328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case TAAUTO:
58338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case JUSTIFY:
5834a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (!currentStyle->isLeftToRightDirection())
58358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                alignment = alignRight;
58368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
58378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case LEFT:
58388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case WEBKIT_LEFT:
58398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
58408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case CENTER:
58418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case WEBKIT_CENTER:
58428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            alignment = alignCenter;
58438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
58448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case RIGHT:
58458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case WEBKIT_RIGHT:
58468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            alignment = alignRight;
58478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
58482bde8e466a4451c7319e3a072d118917957d6554Steve Block        case TASTART:
58492bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (!currentStyle->isLeftToRightDirection())
58502bde8e466a4451c7319e3a072d118917957d6554Steve Block                alignment = alignRight;
58512bde8e466a4451c7319e3a072d118917957d6554Steve Block            break;
58522bde8e466a4451c7319e3a072d118917957d6554Steve Block        case TAEND:
58532bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (currentStyle->isLeftToRightDirection())
58542bde8e466a4451c7319e3a072d118917957d6554Steve Block                alignment = alignRight;
58552bde8e466a4451c7319e3a072d118917957d6554Steve Block            break;
58568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
58578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int x = borderLeft() + paddingLeft();
58598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int w = width();
58608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    switch (alignment) {
58628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case alignLeft:
58638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
58648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case alignCenter:
58658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            x = (x + w - (borderRight() + paddingRight())) / 2;
58668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
58678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case alignRight:
58685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            x = w - (borderRight() + paddingRight()) - caretWidth;
58698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
58708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
58718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (extraWidthToEndOfLine) {
58738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (isRenderBlock()) {
58748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            *extraWidthToEndOfLine = w - (x + caretWidth);
58758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else {
58768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // FIXME: This code looks wrong.
58778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // myRight and containerRight are set up, but then clobbered.
58788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // So *extraWidthToEndOfLine will always be 0 here.
58798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            int myRight = x + caretWidth;
58818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // FIXME: why call localToAbsoluteForContent() twice here, too?
58828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            FloatPoint absRightPoint = localToAbsolute(FloatPoint(myRight, 0));
58838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
5884bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            int containerRight = containingBlock()->x() + containingBlockLogicalWidthForContent();
58858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            FloatPoint absContainerPoint = localToAbsolute(FloatPoint(containerRight, 0));
58868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            *extraWidthToEndOfLine = absContainerPoint.x() - absRightPoint.x();
58888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
58898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
58908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int y = paddingTop() + borderTop();
58928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return IntRect(x, y, caretWidth, height);
58948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
58958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
5896d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid RenderBlock::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
58978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
58988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // For blocks inside inlines, we go ahead and include margins so that we run right up to the
58998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // inline boxes above and below us (thus getting merged with them to form a single irregular
59008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // shape).
5901e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (inlineElementContinuation()) {
59028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // FIXME: This check really isn't accurate.
5903e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        bool nextInlineHasLineBox = inlineElementContinuation()->firstLineBox();
59048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // FIXME: This is wrong. The principal renderer may not be the continuation preceding this block.
5905bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // FIXME: This is wrong for block-flows that are horizontal.
5906bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // https://bugs.webkit.org/show_bug.cgi?id=46781
5907e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        bool prevInlineHasLineBox = toRenderInline(inlineElementContinuation()->node()->renderer())->firstLineBox();
5908bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        int topMargin = prevInlineHasLineBox ? collapsedMarginBefore() : 0;
5909bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        int bottomMargin = nextInlineHasLineBox ? collapsedMarginAfter() : 0;
5910d0825bca7fe65beaee391d30da42e937db621564Steve Block        IntRect rect(tx, ty - topMargin, width(), height() + topMargin + bottomMargin);
5911d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (!rect.isEmpty())
5912d0825bca7fe65beaee391d30da42e937db621564Steve Block            rects.append(rect);
5913d0825bca7fe65beaee391d30da42e937db621564Steve Block    } else if (width() && height())
5914d0825bca7fe65beaee391d30da42e937db621564Steve Block        rects.append(IntRect(tx, ty, width(), height()));
59158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
59168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!hasOverflowClip() && !hasControlClip()) {
5917231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
591881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            int top = max(curr->lineTop(), curr->logicalTop());
591981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            int bottom = min(curr->lineBottom(), curr->logicalTop() + curr->logicalHeight());
5920bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            IntRect rect(tx + curr->x(), ty + top, curr->logicalWidth(), bottom - top);
5921d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (!rect.isEmpty())
5922d0825bca7fe65beaee391d30da42e937db621564Steve Block                rects.append(rect);
5923231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
59248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
59258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
59268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (!curr->isText() && !curr->isListMarker() && curr->isBox()) {
59278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                RenderBox* box = toRenderBox(curr);
59288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                FloatPoint pos;
59298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                // FIXME: This doesn't work correctly with transforms.
59308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if (box->layer())
59318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    pos = curr->localToAbsolute();
59328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                else
59338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    pos = FloatPoint(tx + box->x(), ty + box->y());
5934d0825bca7fe65beaee391d30da42e937db621564Steve Block                box->addFocusRingRects(rects, pos.x(), pos.y());
59358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
59368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
59378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
59388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
5939e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (inlineElementContinuation())
5940e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        inlineElementContinuation()->addFocusRingRects(rects,
5941e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block                                                       tx - x() + inlineElementContinuation()->containingBlock()->x(),
5942e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block                                                       ty - y() + inlineElementContinuation()->containingBlock()->y());
59438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
59448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
5945231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockRenderBlock* RenderBlock::createAnonymousBlock(bool isFlexibleBox) const
59468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
59472bde8e466a4451c7319e3a072d118917957d6554Steve Block    RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
59488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
5949231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    RenderBlock* newBox = 0;
5950231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (isFlexibleBox) {
5951231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        newStyle->setDisplay(BOX);
5952231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        newBox = new (renderArena()) RenderFlexibleBox(document() /* anonymous box */);
5953231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    } else {
5954231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        newStyle->setDisplay(BLOCK);
5955231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
5956231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
5957231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
59588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    newBox->setStyle(newStyle.release());
59598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return newBox;
59608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
59618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
59625af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeRenderBlock* RenderBlock::createAnonymousBlockWithSameTypeAs(RenderBlock* otherAnonymousBlock) const
59635af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
59645af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (otherAnonymousBlock->isAnonymousColumnsBlock())
59655af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return createAnonymousColumnsBlock();
59665af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (otherAnonymousBlock->isAnonymousColumnSpanBlock())
59675af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return createAnonymousColumnSpanBlock();
59685af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return createAnonymousBlock(otherAnonymousBlock->style()->display() == BOX);
59695af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
59705af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
59715af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeRenderBlock* RenderBlock::createAnonymousColumnsBlock() const
59725af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
59732bde8e466a4451c7319e3a072d118917957d6554Steve Block    RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
59745af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newStyle->inheritColumnPropertiesFrom(style());
59755af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newStyle->setDisplay(BLOCK);
59765af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
59775af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
59785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newBox->setStyle(newStyle.release());
59795af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return newBox;
59805af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
59815af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
59825af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeRenderBlock* RenderBlock::createAnonymousColumnSpanBlock() const
59835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
59842bde8e466a4451c7319e3a072d118917957d6554Steve Block    RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
59855af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newStyle->setColumnSpan(true);
59865af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newStyle->setDisplay(BLOCK);
59875af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
59885af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
59895af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newBox->setStyle(newStyle.release());
59905af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return newBox;
59915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
59925af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
59932fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockint RenderBlock::nextPageLogicalTop(int logicalOffset) const
599468513a70bcd92384395513322f1b801e7bf9c729Steve Block{
599568513a70bcd92384395513322f1b801e7bf9c729Steve Block    LayoutState* layoutState = view()->layoutState();
5996f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!layoutState->m_pageLogicalHeight)
59972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return logicalOffset;
599868513a70bcd92384395513322f1b801e7bf9c729Steve Block
59992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // The logicalOffset is in our coordinate space.  We can add in our pushed offset.
6000f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int pageLogicalHeight = layoutState->m_pageLogicalHeight;
60012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
60022bde8e466a4451c7319e3a072d118917957d6554Steve Block    int offset = isHorizontalWritingMode() ? delta.height() : delta.width();
60032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight;
60042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return logicalOffset + remainingLogicalHeight;
600568513a70bcd92384395513322f1b801e7bf9c729Steve Block}
600668513a70bcd92384395513322f1b801e7bf9c729Steve Block
600768513a70bcd92384395513322f1b801e7bf9c729Steve Blockstatic bool inNormalFlow(RenderBox* child)
600868513a70bcd92384395513322f1b801e7bf9c729Steve Block{
600968513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderBlock* curr = child->containingBlock();
601068513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderBlock* initialBlock = child->view();
601168513a70bcd92384395513322f1b801e7bf9c729Steve Block    while (curr && curr != initialBlock) {
601268513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (curr->hasColumns())
601368513a70bcd92384395513322f1b801e7bf9c729Steve Block            return true;
601468513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (curr->isFloatingOrPositioned())
601568513a70bcd92384395513322f1b801e7bf9c729Steve Block            return false;
601668513a70bcd92384395513322f1b801e7bf9c729Steve Block        curr = curr->containingBlock();
601768513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
601868513a70bcd92384395513322f1b801e7bf9c729Steve Block    return true;
601968513a70bcd92384395513322f1b801e7bf9c729Steve Block}
602068513a70bcd92384395513322f1b801e7bf9c729Steve Block
60212fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockint RenderBlock::applyBeforeBreak(RenderBox* child, int logicalOffset)
602268513a70bcd92384395513322f1b801e7bf9c729Steve Block{
602368513a70bcd92384395513322f1b801e7bf9c729Steve Block    // FIXME: Add page break checking here when we support printing.
602468513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
6025f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
602668513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool checkBeforeAlways = (checkColumnBreaks && child->style()->columnBreakBefore() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakBefore() == PBALWAYS);
602768513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (checkBeforeAlways && inNormalFlow(child)) {
602868513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (checkColumnBreaks)
60292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            view()->layoutState()->addForcedColumnBreak(logicalOffset);
60302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return nextPageLogicalTop(logicalOffset);
603168513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
60322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return logicalOffset;
603368513a70bcd92384395513322f1b801e7bf9c729Steve Block}
603468513a70bcd92384395513322f1b801e7bf9c729Steve Block
60352fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockint RenderBlock::applyAfterBreak(RenderBox* child, int logicalOffset, MarginInfo& marginInfo)
603668513a70bcd92384395513322f1b801e7bf9c729Steve Block{
603768513a70bcd92384395513322f1b801e7bf9c729Steve Block    // FIXME: Add page break checking here when we support printing.
603868513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
6039f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
604068513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool checkAfterAlways = (checkColumnBreaks && child->style()->columnBreakAfter() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakAfter() == PBALWAYS);
604168513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (checkAfterAlways && inNormalFlow(child)) {
6042bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        marginInfo.setMarginAfterQuirk(true); // Cause margins to be discarded for any following content.
604368513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (checkColumnBreaks)
60442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            view()->layoutState()->addForcedColumnBreak(logicalOffset);
60452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return nextPageLogicalTop(logicalOffset);
604668513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
60472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return logicalOffset;
604868513a70bcd92384395513322f1b801e7bf9c729Steve Block}
604968513a70bcd92384395513322f1b801e7bf9c729Steve Block
60502fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockint RenderBlock::adjustForUnsplittableChild(RenderBox* child, int logicalOffset, bool includeMargins)
605168513a70bcd92384395513322f1b801e7bf9c729Steve Block{
605268513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool isUnsplittable = child->isReplaced() || child->scrollsOverflow();
605368513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!isUnsplittable)
60542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return logicalOffset;
60552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int childLogicalHeight = logicalHeightForChild(child) + (includeMargins ? marginBeforeForChild(child) + marginAfterForChild(child) : 0);
605668513a70bcd92384395513322f1b801e7bf9c729Steve Block    LayoutState* layoutState = view()->layoutState();
605768513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (layoutState->m_columnInfo)
60582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        layoutState->m_columnInfo->updateMinimumColumnHeight(childLogicalHeight);
6059f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int pageLogicalHeight = layoutState->m_pageLogicalHeight;
60602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!pageLogicalHeight || childLogicalHeight > pageLogicalHeight)
60612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return logicalOffset;
60622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
60632bde8e466a4451c7319e3a072d118917957d6554Steve Block    int offset = isHorizontalWritingMode() ? delta.height() : delta.width();
60642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight;
60652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (remainingLogicalHeight < childLogicalHeight)
60662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return logicalOffset + remainingLogicalHeight;
60672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return logicalOffset;
606868513a70bcd92384395513322f1b801e7bf9c729Steve Block}
606968513a70bcd92384395513322f1b801e7bf9c729Steve Block
607068513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, int& delta)
607168513a70bcd92384395513322f1b801e7bf9c729Steve Block{
607268513a70bcd92384395513322f1b801e7bf9c729Steve Block    // FIXME: For now we paginate using line overflow.  This ensures that lines don't overlap at all when we
607368513a70bcd92384395513322f1b801e7bf9c729Steve Block    // put a strut between them for pagination purposes.  However, this really isn't the desired rendering, since
607468513a70bcd92384395513322f1b801e7bf9c729Steve 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
607568513a70bcd92384395513322f1b801e7bf9c729Steve Block    // of the first column.
607668513a70bcd92384395513322f1b801e7bf9c729Steve Block    //
607768513a70bcd92384395513322f1b801e7bf9c729Steve Block    // The rendering we would like to see is one where the lineTop is at the top of the column, and any line overflow
607868513a70bcd92384395513322f1b801e7bf9c729Steve Block    // simply spills out above the top of the column.  This effect would match what happens at the top of the first column.
607968513a70bcd92384395513322f1b801e7bf9c729Steve Block    // We can't achieve this rendering, however, until we stop columns from clipping to the column bounds (thus allowing
608068513a70bcd92384395513322f1b801e7bf9c729Steve Block    // for overflow to occur), and then cache visible overflow for each column rect.
608168513a70bcd92384395513322f1b801e7bf9c729Steve Block    //
608268513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Furthermore, the paint we have to do when a column has overflow has to be special.  We need to exclude
608368513a70bcd92384395513322f1b801e7bf9c729Steve Block    // content that paints in a previous column (and content that paints in the following column).
608468513a70bcd92384395513322f1b801e7bf9c729Steve Block    //
608568513a70bcd92384395513322f1b801e7bf9c729Steve Block    // FIXME: Another problem with simply moving lines is that the available line width may change (because of floats).
608668513a70bcd92384395513322f1b801e7bf9c729Steve 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
608768513a70bcd92384395513322f1b801e7bf9c729Steve Block    // line and all following lines.
608868513a70bcd92384395513322f1b801e7bf9c729Steve Block    LayoutState* layoutState = view()->layoutState();
6089f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int pageLogicalHeight = layoutState->m_pageLogicalHeight;
60902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    IntRect logicalVisualOverflow = lineBox->logicalVisualOverflowRect(lineBox->lineTop(), lineBox->lineBottom());
60912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    int logicalOffset = logicalVisualOverflow.y();
60922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    int lineHeight = logicalVisualOverflow.maxY() - logicalOffset;
609368513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (layoutState->m_columnInfo)
609468513a70bcd92384395513322f1b801e7bf9c729Steve Block        layoutState->m_columnInfo->updateMinimumColumnHeight(lineHeight);
60952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    logicalOffset += delta;
609668513a70bcd92384395513322f1b801e7bf9c729Steve Block    lineBox->setPaginationStrut(0);
6097f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!pageLogicalHeight || lineHeight > pageLogicalHeight)
609868513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
60992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    IntSize offsetDelta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
61002bde8e466a4451c7319e3a072d118917957d6554Steve Block    int offset = isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width();
61012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int remainingLogicalHeight = pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight;
61022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (remainingLogicalHeight < lineHeight) {
61032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int totalLogicalHeight = lineHeight + max(0, logicalOffset);
61042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (lineBox == firstRootBox() && totalLogicalHeight < pageLogicalHeight && !isPositioned() && !isTableCell())
61052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            setPaginationStrut(remainingLogicalHeight + max(0, logicalOffset));
610668513a70bcd92384395513322f1b801e7bf9c729Steve Block        else {
61072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            delta += remainingLogicalHeight;
61082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            lineBox->setPaginationStrut(remainingLogicalHeight);
610968513a70bcd92384395513322f1b801e7bf9c729Steve Block        }
611068513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
611168513a70bcd92384395513322f1b801e7bf9c729Steve Block}
6112a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6113a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::collapsedMarginBeforeForChild(RenderBox* child) const
6114a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
6115a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // If the child has the same directionality as we do, then we can just return its
6116a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // collapsed margin.
6117a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!child->isWritingModeRoot())
6118a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->collapsedMarginBefore();
6119a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6120a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // The child has a different directionality.  If the child is parallel, then it's just
6121a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // flipped relative to us.  We can use the collapsed margin for the opposite edge.
61222bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
6123a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->collapsedMarginAfter();
6124a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6125a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // The child is perpendicular to us, which means its margins don't collapse but are on the
6126a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // "logical left/right" sides of the child box.  We can just return the raw margin in this case.
6127a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return marginBeforeForChild(child);
6128a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6129a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6130a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::collapsedMarginAfterForChild(RenderBox* child) const
6131a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
6132a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // If the child has the same directionality as we do, then we can just return its
6133a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // collapsed margin.
6134a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!child->isWritingModeRoot())
6135a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->collapsedMarginAfter();
6136a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6137a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // The child has a different directionality.  If the child is parallel, then it's just
6138a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // flipped relative to us.  We can use the collapsed margin for the opposite edge.
61392bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
6140a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->collapsedMarginBefore();
6141a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6142a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // The child is perpendicular to us, which means its margins don't collapse but are on the
6143a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // "logical left/right" side of the child box.  We can just return the raw margin in this case.
6144a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return marginAfterForChild(child);
6145a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6146a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6147a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::marginBeforeForChild(RenderBoxModelObject* child) const
6148a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
6149a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    switch (style()->writingMode()) {
6150a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case TopToBottomWritingMode:
6151a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginTop();
6152a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case BottomToTopWritingMode:
6153a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginBottom();
6154a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case LeftToRightWritingMode:
6155a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginLeft();
6156a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case RightToLeftWritingMode:
6157a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginRight();
6158a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6159a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ASSERT_NOT_REACHED();
6160a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return child->marginTop();
6161a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6162a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6163a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::marginAfterForChild(RenderBoxModelObject* child) const
6164a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
6165a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    switch (style()->writingMode()) {
6166a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case TopToBottomWritingMode:
6167a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginBottom();
6168a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case BottomToTopWritingMode:
6169a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginTop();
6170a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case LeftToRightWritingMode:
6171a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginRight();
6172a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case RightToLeftWritingMode:
6173a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginLeft();
6174a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6175a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ASSERT_NOT_REACHED();
6176a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return child->marginBottom();
6177a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6178a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6179a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::marginStartForChild(RenderBoxModelObject* child) const
6180a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
61812bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
6182a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return style()->isLeftToRightDirection() ? child->marginLeft() : child->marginRight();
6183a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return style()->isLeftToRightDirection() ? child->marginTop() : child->marginBottom();
6184a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6185a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6186a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::marginEndForChild(RenderBoxModelObject* child) const
6187a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
61882bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
6189a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return style()->isLeftToRightDirection() ? child->marginRight() : child->marginLeft();
6190a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return style()->isLeftToRightDirection() ? child->marginBottom() : child->marginTop();
6191a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6192a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6193a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setMarginStartForChild(RenderBox* child, int margin)
6194a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
61952bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode()) {
6196a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->isLeftToRightDirection())
6197a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginLeft(margin);
6198a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
6199a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginRight(margin);
6200a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else {
6201a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->isLeftToRightDirection())
6202a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginTop(margin);
6203a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
6204a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginBottom(margin);
6205a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6206a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6207a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6208a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setMarginEndForChild(RenderBox* child, int margin)
6209a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
62102bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode()) {
6211a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->isLeftToRightDirection())
6212a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginRight(margin);
6213a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
6214a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginLeft(margin);
6215a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else {
6216a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->isLeftToRightDirection())
6217a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginBottom(margin);
6218a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
6219a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginTop(margin);
6220a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6221a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6222a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6223a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setMarginBeforeForChild(RenderBox* child, int margin)
6224a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
6225a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    switch (style()->writingMode()) {
6226a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case TopToBottomWritingMode:
6227a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginTop(margin);
6228a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6229a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case BottomToTopWritingMode:
6230a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginBottom(margin);
6231a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6232a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case LeftToRightWritingMode:
6233a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginLeft(margin);
6234a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6235a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case RightToLeftWritingMode:
6236a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginRight(margin);
6237a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6238a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6239a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6240a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6241a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setMarginAfterForChild(RenderBox* child, int margin)
6242a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
6243a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    switch (style()->writingMode()) {
6244a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case TopToBottomWritingMode:
6245a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginBottom(margin);
6246a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6247a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case BottomToTopWritingMode:
6248a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginTop(margin);
6249a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6250a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case LeftToRightWritingMode:
6251a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginRight(margin);
6252a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6253a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case RightToLeftWritingMode:
6254a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginLeft(margin);
6255a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6256a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6257a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6258a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6259a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochRenderBlock::MarginValues RenderBlock::marginValuesForChild(RenderBox* child)
6260a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
6261a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int childBeforePositive = 0;
6262a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int childBeforeNegative = 0;
6263a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int childAfterPositive = 0;
6264a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int childAfterNegative = 0;
6265a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6266a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int beforeMargin = 0;
6267a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int afterMargin = 0;
6268a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6269a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0;
6270a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6271a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // If the child has the same directionality as we do, then we can just return its
6272a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // margins in the same direction.
6273a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!child->isWritingModeRoot()) {
6274a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (childRenderBlock) {
6275a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBeforePositive = childRenderBlock->maxPositiveMarginBefore();
6276a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBeforeNegative = childRenderBlock->maxNegativeMarginBefore();
6277a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childAfterPositive = childRenderBlock->maxPositiveMarginAfter();
6278a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childAfterNegative = childRenderBlock->maxNegativeMarginAfter();
6279a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        } else {
6280a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            beforeMargin = child->marginBefore();
6281a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            afterMargin = child->marginAfter();
6282a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
62832bde8e466a4451c7319e3a072d118917957d6554Steve Block    } else if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) {
6284a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // The child has a different directionality.  If the child is parallel, then it's just
6285a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // flipped relative to us.  We can use the margins for the opposite edges.
6286a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (childRenderBlock) {
6287a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBeforePositive = childRenderBlock->maxPositiveMarginAfter();
6288a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBeforeNegative = childRenderBlock->maxNegativeMarginAfter();
6289a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childAfterPositive = childRenderBlock->maxPositiveMarginBefore();
6290a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childAfterNegative = childRenderBlock->maxNegativeMarginBefore();
6291a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        } else {
6292a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            beforeMargin = child->marginAfter();
6293a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            afterMargin = child->marginBefore();
6294a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
6295a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else {
6296a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // The child is perpendicular to us, which means its margins don't collapse but are on the
6297a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // "logical left/right" sides of the child box.  We can just return the raw margin in this case.
6298a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        beforeMargin = marginBeforeForChild(child);
6299a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        afterMargin = marginAfterForChild(child);
6300a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6301a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6302a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Resolve uncollapsing margins into their positive/negative buckets.
6303a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (beforeMargin) {
6304a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (beforeMargin > 0)
6305a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBeforePositive = beforeMargin;
6306a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
6307a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBeforeNegative = -beforeMargin;
6308a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6309a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (afterMargin) {
6310a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (afterMargin > 0)
6311a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childAfterPositive = afterMargin;
6312a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
6313a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childAfterNegative = -afterMargin;
6314a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6315a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6316a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return MarginValues(childBeforePositive, childBeforeNegative, childAfterPositive, childAfterNegative);
6317a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6318a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
63198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst char* RenderBlock::renderName() const
63208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
63218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isBody())
63228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "RenderBody"; // FIXME: Temporary hack until we know that the regression tests pass.
63238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
63248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isFloating())
63258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "RenderBlock (floating)";
63268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isPositioned())
63278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "RenderBlock (positioned)";
63285af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (isAnonymousColumnsBlock())
63295af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return "RenderBlock (anonymous multi-column)";
63305af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (isAnonymousColumnSpanBlock())
63315af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return "RenderBlock (anonymous multi-column span)";
63328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isAnonymousBlock())
63338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "RenderBlock (anonymous)";
63348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (isAnonymous())
63358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "RenderBlock (generated)";
63368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isRelPositioned())
63378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "RenderBlock (relative positioned)";
63388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isRunIn())
63398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "RenderBlock (run-in)";
63408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return "RenderBlock";
63418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
63428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
634381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline void RenderBlock::FloatingObjects::clear()
634481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
634581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_set.clear();
634681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_leftObjectsCount = 0;
634781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_rightObjectsCount = 0;
634881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
634981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
635081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline void RenderBlock::FloatingObjects::increaseObjectsCount(FloatingObject::Type type)
635181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
635281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (type == FloatingObject::FloatLeft)
635381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_leftObjectsCount++;
635481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    else
635581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_rightObjectsCount++;
635681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
635781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
635881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline void RenderBlock::FloatingObjects::decreaseObjectsCount(FloatingObject::Type type)
635981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
636081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (type == FloatingObject::FloatLeft)
636181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_leftObjectsCount--;
636281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    else
636381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_rightObjectsCount--;
636481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
636581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
63668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
6367