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{
4235eb142cf16d1349544dc19cfb780917d36fbf3b6Steve Block    RenderBlock* firstChildIgnoringAnonymousWrappers = 0;
424545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    for (RenderObject* curr = this; curr; curr = curr->parent()) {
425545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (!curr->isRenderBlock() || curr->isFloatingOrPositioned() || curr->isTableCell() || curr->isRoot() || curr->isRenderView() || curr->hasOverflowClip()
426545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            || curr->isInlineBlockOrInlineTable())
427545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            return 0;
428545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
429545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        RenderBlock* currBlock = toRenderBlock(curr);
4305eb142cf16d1349544dc19cfb780917d36fbf3b6Steve Block        if (!currBlock->createsAnonymousWrapper())
4315eb142cf16d1349544dc19cfb780917d36fbf3b6Steve Block            firstChildIgnoringAnonymousWrappers = currBlock;
4325eb142cf16d1349544dc19cfb780917d36fbf3b6Steve Block
433545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (currBlock->style()->specifiesColumns() && (allowAnonymousColumnBlock || !currBlock->isAnonymousColumnsBlock()))
4345eb142cf16d1349544dc19cfb780917d36fbf3b6Steve Block            return firstChildIgnoringAnonymousWrappers;
435545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
436545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (currBlock->isAnonymousColumnSpanBlock())
437545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            return 0;
438545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
439545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return 0;
440545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
441545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
442545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRenderBlock* RenderBlock::clone() const
443545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
444cad810f21b803229eb11403f9209855525a25d57Steve Block    RenderBlock* cloneBlock;
445cad810f21b803229eb11403f9209855525a25d57Steve Block    if (isAnonymousBlock())
446cad810f21b803229eb11403f9209855525a25d57Steve Block        cloneBlock = createAnonymousBlock();
447cad810f21b803229eb11403f9209855525a25d57Steve Block    else {
448cad810f21b803229eb11403f9209855525a25d57Steve Block        cloneBlock = new (renderArena()) RenderBlock(node());
449cad810f21b803229eb11403f9209855525a25d57Steve Block        cloneBlock->setStyle(style());
450b52229f8ad5e8b3632305005e437104c11eba942Steve Block        if (!childrenInline() && cloneBlock->firstChild() && cloneBlock->firstChild()->isInline())
451b52229f8ad5e8b3632305005e437104c11eba942Steve Block            cloneBlock->makeChildrenNonInline();
452cad810f21b803229eb11403f9209855525a25d57Steve Block    }
453cad810f21b803229eb11403f9209855525a25d57Steve Block    cloneBlock->setChildrenInline(childrenInline());
454cad810f21b803229eb11403f9209855525a25d57Steve Block    return cloneBlock;
455545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
456545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
457545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
458545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                              RenderBlock* middleBlock,
459545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                              RenderObject* beforeChild, RenderBoxModelObject* oldCont)
460545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
461545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Create a clone of this inline.
462cad810f21b803229eb11403f9209855525a25d57Steve Block    RenderBlock* cloneBlock = clone();
463cad810f21b803229eb11403f9209855525a25d57Steve Block    if (!isAnonymousBlock())
4644a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        cloneBlock->setContinuation(oldCont);
465545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
466545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Now take all of the children from beforeChild to the end and remove
467545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // them from |this| and place them in the clone.
468545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (!beforeChild && isAfterContent(lastChild()))
469545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        beforeChild = lastChild();
470545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    moveChildrenTo(cloneBlock, beforeChild, 0);
471545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
472545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Hook |clone| up as the continuation of the middle block.
4734a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    if (!cloneBlock->isAnonymousBlock())
4744a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        middleBlock->setContinuation(cloneBlock);
475545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
476545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // We have been reparented and are now under the fromBlock.  We need
477545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // to walk up our block parent chain until we hit the containing anonymous columns block.
478545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Once we hit the anonymous columns block we're done.
479545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBoxModelObject* curr = toRenderBoxModelObject(parent());
480545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBoxModelObject* currChild = this;
481545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
482545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    while (curr && curr != fromBlock) {
4834a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        ASSERT(curr->isRenderBlock());
484545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
485545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        RenderBlock* blockCurr = toRenderBlock(curr);
486545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
487545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // Create a new clone.
488545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        RenderBlock* cloneChild = cloneBlock;
489cad810f21b803229eb11403f9209855525a25d57Steve Block        cloneBlock = blockCurr->clone();
490545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
491545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // Insert our child clone as the first child.
492545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        cloneBlock->children()->appendChildNode(cloneBlock, cloneChild);
493545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
494545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // Hook the clone up as a continuation of |curr|.  Note we do encounter
495545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // anonymous blocks possibly as we walk up the block chain.  When we split an
496545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // anonymous block, there's no need to do any continuation hookup, since we haven't
497545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // actually split a real element.
498545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (!blockCurr->isAnonymousBlock()) {
499545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            oldCont = blockCurr->continuation();
500545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            blockCurr->setContinuation(cloneBlock);
501545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            cloneBlock->setContinuation(oldCont);
502545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        }
503545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
504545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // Someone may have indirectly caused a <q> to split.  When this happens, the :after content
505545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // has to move into the inline continuation.  Call updateBeforeAfterContent to ensure that the inline's :after
506545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // content gets properly destroyed.
507545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (document()->usesBeforeAfterRules())
508545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            blockCurr->children()->updateBeforeAfterContent(blockCurr, AFTER);
509545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
510545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // Now we need to take all of the children starting from the first child
511545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // *after* currChild and append them all to the clone.
512545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        RenderObject* afterContent = isAfterContent(cloneBlock->lastChild()) ? cloneBlock->lastChild() : 0;
513545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        blockCurr->moveChildrenTo(cloneBlock, currChild->nextSibling(), 0, afterContent);
514545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
515545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // Keep walking up the chain.
516545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        currChild = curr;
517545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        curr = toRenderBoxModelObject(curr->parent());
518545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
519545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
520545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Now we are at the columns block level. We need to put the clone into the toBlock.
521545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    toBlock->children()->appendChildNode(toBlock, cloneBlock);
522545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
523545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Now take all the children after currChild and remove them from the fromBlock
524545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // and put them in the toBlock.
525545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    fromBlock->moveChildrenTo(toBlock, currChild->nextSibling(), 0);
526545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
527545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
528545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid RenderBlock::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
529545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                            RenderObject* newChild, RenderBoxModelObject* oldCont)
530545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
531545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBlock* pre = 0;
532545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBlock* block = containingColumnsBlock();
533545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
534545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Delete our line boxes before we do the inline split into continuations.
535545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    block->deleteLineBoxTree();
536545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
537545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    bool madeNewBeforeBlock = false;
538545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (block->isAnonymousColumnsBlock()) {
539545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // We can reuse this block and make it the preBlock of the next continuation.
540545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        pre = block;
541545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        pre->removePositionedObjects(0);
542545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        block = toRenderBlock(block->parent());
543545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    } else {
544545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        // No anonymous block available for use.  Make one.
545545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        pre = block->createAnonymousColumnsBlock();
546545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        pre->setChildrenInline(false);
547545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        madeNewBeforeBlock = true;
548545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
549545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
550545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBlock* post = block->createAnonymousColumnsBlock();
551545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    post->setChildrenInline(false);
552545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
553545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
554545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (madeNewBeforeBlock)
555545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        block->children()->insertChildNode(block, pre, boxFirst);
556545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    block->children()->insertChildNode(block, newBlockBox, boxFirst);
557545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    block->children()->insertChildNode(block, post, boxFirst);
558545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    block->setChildrenInline(false);
559545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
560545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (madeNewBeforeBlock)
561545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        block->moveChildrenTo(pre, boxFirst, 0);
562545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
563545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    splitBlocks(pre, post, newBlockBox, beforeChild, oldCont);
564545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
565545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
566545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // time in makeChildrenNonInline by just setting this explicitly up front.
567545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    newBlockBox->setChildrenInline(false);
568545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
569545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // We delayed adding the newChild until now so that the |newBlockBox| would be fully
570545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // connected, thus allowing newChild access to a renderArena should it need
571545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // to wrap itself in additional boxes (e.g., table construction).
572545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    newBlockBox->addChild(newChild);
573545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
574545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
575545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // get deleted properly.  Because objects moves from the pre block into the post block, we want to
576545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // make new line boxes instead of leaving the old line boxes around.
577545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    pre->setNeedsLayoutAndPrefWidthsRecalc();
578545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    block->setNeedsLayoutAndPrefWidthsRecalc();
579545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    post->setNeedsLayoutAndPrefWidthsRecalc();
580545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
581545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
5825af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeRenderObject* RenderBlock::splitAnonymousBlocksAroundChild(RenderObject* beforeChild)
5835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
5845af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    while (beforeChild->parent() != this) {
5855af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        RenderBlock* blockToSplit = toRenderBlock(beforeChild->parent());
5865af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (blockToSplit->firstChild() != beforeChild) {
5875af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // We have to split the parentBlock into two blocks.
5885af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            RenderBlock* post = createAnonymousBlockWithSameTypeAs(blockToSplit);
5895af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            post->setChildrenInline(blockToSplit->childrenInline());
5905af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            RenderBlock* parentBlock = toRenderBlock(blockToSplit->parent());
5915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            parentBlock->children()->insertChildNode(parentBlock, post, blockToSplit->nextSibling());
5925af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            blockToSplit->moveChildrenTo(post, beforeChild, 0, blockToSplit->hasLayer());
5935af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            post->setNeedsLayoutAndPrefWidthsRecalc();
5945af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            blockToSplit->setNeedsLayoutAndPrefWidthsRecalc();
5955af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            beforeChild = post;
5965af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        } else
5975af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            beforeChild = blockToSplit;
5985af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    }
5995af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return beforeChild;
6005af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
6015af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
6025af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild)
6035af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
6045af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderBlock* pre = 0;
6055af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderBlock* post = 0;
6065af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderBlock* block = this; // Eventually block will not just be |this|, but will also be a block nested inside |this|.  Assign to a variable
6075af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                               // so that we don't have to patch all of the rest of the code later on.
6085af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
6095af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // Delete the block's line boxes before we do the split.
6105af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    block->deleteLineBoxTree();
611545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
6125af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (beforeChild && beforeChild->parent() != this)
6135af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        beforeChild = splitAnonymousBlocksAroundChild(beforeChild);
614545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
6155af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (beforeChild != firstChild()) {
6165af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        pre = block->createAnonymousColumnsBlock();
6175af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        pre->setChildrenInline(block->childrenInline());
6185af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    }
6195af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
6205af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (beforeChild) {
6215af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        post = block->createAnonymousColumnsBlock();
6225af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        post->setChildrenInline(block->childrenInline());
6235af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    }
6245af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
6255af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderObject* boxFirst = block->firstChild();
6265af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (pre)
6275af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        block->children()->insertChildNode(block, pre, boxFirst);
6285af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    block->children()->insertChildNode(block, newBlockBox, boxFirst);
6295af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (post)
6305af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        block->children()->insertChildNode(block, post, boxFirst);
6315af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    block->setChildrenInline(false);
6325af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
6335af96e2c7b73ebc627c6894727826a7576d31758Leon 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).
6345af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    block->moveChildrenTo(pre, boxFirst, beforeChild, true);
6355af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    block->moveChildrenTo(post, beforeChild, 0, true);
6365af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
6375af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
6385af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // time in makeChildrenNonInline by just setting this explicitly up front.
6395af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newBlockBox->setChildrenInline(false);
6405af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
6415af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // We delayed adding the newChild until now so that the |newBlockBox| would be fully
6425af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // connected, thus allowing newChild access to a renderArena should it need
6435af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // to wrap itself in additional boxes (e.g., table construction).
6445af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newBlockBox->addChild(newChild);
6455af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
6465af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
6475af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // get deleted properly.  Because objects moved from the pre block into the post block, we want to
6485af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // make new line boxes instead of leaving the old line boxes around.
6495af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (pre)
6505af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        pre->setNeedsLayoutAndPrefWidthsRecalc();
6515af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    block->setNeedsLayoutAndPrefWidthsRecalc();
6525af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (post)
6535af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        post->setNeedsLayoutAndPrefWidthsRecalc();
6545af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
6555af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
656545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRenderBlock* RenderBlock::columnsBlockForSpanningElement(RenderObject* newChild)
6575af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
658545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // FIXME: This function is the gateway for the addition of column-span support.  It will
659545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // be added to in three stages:
6605af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // (1) Immediate children of a multi-column block can span.
6615af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // (2) Nested block-level children with only block-level ancestors between them and the multi-column block can span.
6625af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // (3) Nested children with block or inline ancestors between them and the multi-column block can span (this is when we
6635af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // cross the streams and have to cope with both types of continuations mixed together).
664545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // This function currently supports (1) and (2).
665545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RenderBlock* columnsBlockAncestor = 0;
666b52229f8ad5e8b3632305005e437104c11eba942Steve Block    if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isBeforeOrAfterContent()
667b52229f8ad5e8b3632305005e437104c11eba942Steve Block        && !newChild->isFloatingOrPositioned() && !newChild->isInline() && !isAnonymousColumnSpanBlock()) {
6685eb142cf16d1349544dc19cfb780917d36fbf3b6Steve Block        columnsBlockAncestor = containingColumnsBlock(false);
6695eb142cf16d1349544dc19cfb780917d36fbf3b6Steve Block        if (columnsBlockAncestor) {
6705eb142cf16d1349544dc19cfb780917d36fbf3b6Steve Block            // Make sure that none of the parent ancestors have a continuation.
6715eb142cf16d1349544dc19cfb780917d36fbf3b6Steve Block            // If yes, we do not want split the block into continuations.
6725eb142cf16d1349544dc19cfb780917d36fbf3b6Steve Block            RenderObject* curr = this;
6735eb142cf16d1349544dc19cfb780917d36fbf3b6Steve Block            while (curr && curr != columnsBlockAncestor) {
6745eb142cf16d1349544dc19cfb780917d36fbf3b6Steve Block                if (curr->isRenderBlock() && toRenderBlock(curr)->continuation()) {
6755eb142cf16d1349544dc19cfb780917d36fbf3b6Steve Block                    columnsBlockAncestor = 0;
6765eb142cf16d1349544dc19cfb780917d36fbf3b6Steve Block                    break;
67718b8d441a9374dd8d867c63f12c330b20ae9b5d0Steve Block                }
6785eb142cf16d1349544dc19cfb780917d36fbf3b6Steve Block                curr = curr->parent();
67918b8d441a9374dd8d867c63f12c330b20ae9b5d0Steve Block            }
68018b8d441a9374dd8d867c63f12c330b20ae9b5d0Steve Block        }
681545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
682545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return columnsBlockAncestor;
6835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
6845af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
6855af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Make sure we don't append things after :after-generated content if we have it.
688dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!beforeChild) {
689dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        RenderObject* lastRenderer = lastChild();
690dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (isAfterContent(lastRenderer))
691dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            beforeChild = lastRenderer;
692dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        else if (lastRenderer && lastRenderer->isAnonymousBlock() && isAfterContent(lastRenderer->lastChild()))
693dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            beforeChild = lastRenderer->lastChild();
694dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the requested beforeChild is not one of our children, then this is because
6978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // there is an anonymous container within this object that contains the beforeChild.
6988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (beforeChild && beforeChild->parent() != this) {
6998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderObject* anonymousChild = beforeChild->parent();
7008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(anonymousChild);
7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (anonymousChild->parent() != this)
7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            anonymousChild = anonymousChild->parent();
7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(anonymousChild->isAnonymous());
7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (anonymousChild->isAnonymousBlock()) {
7088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Insert the child into the anonymous block box instead of here.
7098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
7108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                beforeChild->parent()->addChild(newChild, beforeChild);
7118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
7128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                addChild(newChild, beforeChild->parent());
7138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
7148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(anonymousChild->isTable());
7178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if ((newChild->isTableCol() && newChild->style()->display() == TABLE_COLUMN_GROUP)
7188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                || (newChild->isRenderBlock() && newChild->style()->display() == TABLE_CAPTION)
7198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                || newChild->isTableSection()
7208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                || newChild->isTableRow()
7218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                || newChild->isTableCell()) {
7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Insert into the anonymous table.
7238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            anonymousChild->addChild(newChild, beforeChild);
7248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
7258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Go on to insert before the anonymous table.
7288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        beforeChild = anonymousChild;
7298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7314a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    // Check for a spanning element in columns.
7324a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    RenderBlock* columnsBlockAncestor = columnsBlockForSpanningElement(newChild);
7334a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    if (columnsBlockAncestor) {
7344a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        // We are placing a column-span element inside a block.
7354a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        RenderBlock* newBox = createAnonymousColumnSpanBlock();
7364a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
7374a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        if (columnsBlockAncestor != this) {
7384a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            // We are nested inside a multi-column element and are being split by the span.  We have to break up
7394a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            // our block into continuations.
7404a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            RenderBoxModelObject* oldContinuation = continuation();
7414a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            setContinuation(newBox);
7424a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
7434a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            // Someone may have put a <p> inside a <q>, causing a split.  When this happens, the :after content
7444a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            // has to move into the inline continuation.  Call updateBeforeAfterContent to ensure that our :after
7454a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            // content gets properly destroyed.
7464a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            bool isLastChild = (beforeChild == lastChild());
7474a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            if (document()->usesBeforeAfterRules())
7484a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch                children()->updateBeforeAfterContent(this, AFTER);
7494a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            if (isLastChild && beforeChild != lastChild())
7504a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch                beforeChild = 0; // We destroyed the last child, so now we need to update our insertion
7514a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch                                 // point to be 0.  It's just a straight append now.
7524a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
7534a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            splitFlow(beforeChild, newBox, newChild, oldContinuation);
7544a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            return;
7554a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        }
7564a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
7574a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        // We have to perform a split of this block's children.  This involves creating an anonymous block box to hold
7584a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        // the column-spanning |newChild|.  We take all of the children from before |newChild| and put them into
7594a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        // one anonymous columns block, and all of the children after |newChild| go into another anonymous block.
7604a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        makeChildrenAnonymousColumnBlocks(beforeChild, newBox, newChild);
7614a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        return;
7624a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    }
7634a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
7644a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    bool madeBoxesNonInline = false;
7654a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
7668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // A block has to either have all of its children inline, or all of its children as blocks.
7678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // So, if our children are currently inline and a block child has to be inserted, we move all our
7688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // inline children into anonymous block boxes.
7698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrPositioned()) {
7708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // This is a block with inline content. Wrap the inline content in anonymous blocks.
7718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        makeChildrenNonInline(beforeChild);
7728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        madeBoxesNonInline = true;
7738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (beforeChild && beforeChild->parent() != this) {
7758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            beforeChild = beforeChild->parent();
7768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(beforeChild->isAnonymousBlock());
7778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(beforeChild->parent() == this);
7788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    } else if (!childrenInline() && (newChild->isFloatingOrPositioned() || newChild->isInline())) {
7808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // If we're inserting an inline child but all of our children are blocks, then we have to make sure
7818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
7828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // a new one is created and inserted into our list of children in the appropriate position.
7838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
7848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (afterChild && afterChild->isAnonymousBlock()) {
7868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            afterChild->addChild(newChild);
7878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
7888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (newChild->isInline()) {
7918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // No suitable existing anonymous box - create a new one.
7928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderBlock* newBox = createAnonymousBlock();
7938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            RenderBox::addChild(newBox, beforeChild);
7948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            newBox->addChild(newChild);
7958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
7968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBox::addChild(newChild, beforeChild);
8008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRenderBlock())
8028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
8038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // this object may be dead here
8048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8065af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
8075af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
808545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (continuation() && !isAnonymousBlock())
809545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return addChildToContinuation(newChild, beforeChild);
810545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return addChildIgnoringContinuation(newChild, beforeChild);
811545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
812545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
813545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild)
814545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
815545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (!isAnonymousBlock() && firstChild() && (firstChild()->isAnonymousColumnsBlock() || firstChild()->isAnonymousColumnSpanBlock()))
8165af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return addChildToAnonymousColumnBlocks(newChild, beforeChild);
8175af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
8185af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
8195af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
8208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void getInlineRun(RenderObject* start, RenderObject* boundary,
8218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                         RenderObject*& inlineRunStart,
8228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                         RenderObject*& inlineRunEnd)
8238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Beginning at |start| we find the largest contiguous run of inlines that
8258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // we can.  We denote the run with start and end points, |inlineRunStart|
8268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // and |inlineRunEnd|.  Note that these two values may be the same if
8278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // we encounter only one inline.
8288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    //
8298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We skip any non-inlines we encounter as long as we haven't found any
8308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // inlines yet.
8318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    //
8328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // |boundary| indicates a non-inclusive boundary point.  Regardless of whether |boundary|
8338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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
8348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // a non-inline.
8358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Start by skipping as many non-inlines as we can.
8378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject * curr = start;
8388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool sawInline;
8398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    do {
8408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (curr && !(curr->isInline() || curr->isFloatingOrPositioned()))
8418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            curr = curr->nextSibling();
8428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        inlineRunStart = inlineRunEnd = curr;
8448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!curr)
8468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return; // No more inline children to be found.
8478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        sawInline = curr->isInline();
8498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        curr = curr->nextSibling();
8518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (curr && (curr->isInline() || curr->isFloatingOrPositioned()) && (curr != boundary)) {
8528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            inlineRunEnd = curr;
8538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (curr->isInline())
8548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                sawInline = true;
8558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            curr = curr->nextSibling();
8568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
8578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } while (!sawInline);
8588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::deleteLineBoxTree()
8618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_lineBoxes.deleteLineBoxTree(renderArena());
8638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
8648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochRootInlineBox* RenderBlock::createRootInlineBox()
8668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
8678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return new (renderArena()) RootInlineBox(this);
8688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
8698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochRootInlineBox* RenderBlock::createAndAppendRootInlineBox()
8718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
8720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    RootInlineBox* rootBox = createRootInlineBox();
8738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_lineBoxes.appendLineBox(rootBox);
8748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return rootBox;
8758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
876643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
8775af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::moveChildTo(RenderBlock* to, RenderObject* child, RenderObject* beforeChild, bool fullRemoveInsert)
878643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
879643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ASSERT(this == child->parent());
880643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ASSERT(!beforeChild || to == beforeChild->parent());
8815af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    to->children()->insertChildNode(to, children()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert);
882d0825bca7fe65beaee391d30da42e937db621564Steve Block}
883d0825bca7fe65beaee391d30da42e937db621564Steve Block
8845af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::moveChildrenTo(RenderBlock* to, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert)
885d0825bca7fe65beaee391d30da42e937db621564Steve Block{
886d0825bca7fe65beaee391d30da42e937db621564Steve Block    ASSERT(!beforeChild || to == beforeChild->parent());
8875af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderObject* nextChild = startChild;
8885af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    while (nextChild && nextChild != endChild) {
889d0825bca7fe65beaee391d30da42e937db621564Steve Block        RenderObject* child = nextChild;
890d0825bca7fe65beaee391d30da42e937db621564Steve Block        nextChild = child->nextSibling();
8915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        to->children()->insertChildNode(to, children()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert);
8925af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (child == endChild)
8935af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            return;
894d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
895d0825bca7fe65beaee391d30da42e937db621564Steve Block}
896d0825bca7fe65beaee391d30da42e937db621564Steve Block
8978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
8988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // makeChildrenNonInline takes a block whose children are *all* inline and it
9008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // makes sure that inline children are coalesced under anonymous
9018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // blocks.  If |insertionPoint| is defined, then it represents the insertion point for
9028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the new block child that is causing us to have to wrap all the inlines.  This
9038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // means that we cannot coalesce inlines before |insertionPoint| with inlines following
9048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // |insertionPoint|, because the new child is going to be inserted in between the inlines,
9058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // splitting them.
9068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(isInlineBlockOrInlineTable() || !isInline());
9078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!insertionPoint || insertionPoint->parent() == this);
9088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    setChildrenInline(false);
9108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject *child = firstChild();
9128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!child)
9138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    deleteLineBoxTree();
9168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (child) {
9188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderObject *inlineRunStart, *inlineRunEnd;
9198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
9208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!inlineRunStart)
9228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
9238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child = inlineRunEnd->nextSibling();
9258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderBlock* block = createAnonymousBlock();
9278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        children()->insertChildNode(this, block, inlineRunStart);
9285af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        moveChildrenTo(block, inlineRunStart, child);
9298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG
9328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (RenderObject *c = firstChild(); c; c = c->nextSibling())
9338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(!c->isInline());
9348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
9358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    repaint();
9378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
9408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
9418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(child->isAnonymousBlock());
9428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(!child->childrenInline());
9438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9445af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (child->continuation() || (child->firstChild() && (child->isAnonymousColumnSpanBlock() || child->isAnonymousColumnsBlock())))
9458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
9468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* firstAnChild = child->m_children.firstChild();
9488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* lastAnChild = child->m_children.lastChild();
9498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (firstAnChild) {
9508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderObject* o = firstAnChild;
9518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        while (o) {
9528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            o->setParent(this);
9538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            o = o->nextSibling();
9548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
9558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        firstAnChild->setPreviousSibling(child->previousSibling());
9568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        lastAnChild->setNextSibling(child->nextSibling());
9578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (child->previousSibling())
9588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            child->previousSibling()->setNextSibling(firstAnChild);
9598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (child->nextSibling())
9608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            child->nextSibling()->setPreviousSibling(lastAnChild);
9615af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
9625af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (child == m_children.firstChild())
9635af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            m_children.setFirstChild(firstAnChild);
9645af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (child == m_children.lastChild())
9655af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            m_children.setLastChild(lastAnChild);
9668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    } else {
9675af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (child == m_children.firstChild())
9685af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            m_children.setFirstChild(child->nextSibling());
9695af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (child == m_children.lastChild())
9705af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            m_children.setLastChild(child->previousSibling());
9715af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
9728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (child->previousSibling())
9738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            child->previousSibling()->setNextSibling(child->nextSibling());
9748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (child->nextSibling())
9758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            child->nextSibling()->setPreviousSibling(child->previousSibling());
9768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
9778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->setParent(0);
9788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->setPreviousSibling(0);
9798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->setNextSibling(0);
9808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->children()->setFirstChild(0);
9828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->m_next = 0;
9838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->destroy();
9858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
9868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9875af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkestatic bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObject* prev, RenderObject* next)
9885af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
9895af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (oldChild->documentBeingDestroyed() || oldChild->isInline() || oldChild->virtualContinuation())
9905af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return false;
9915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
9922bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (oldChild->parent() && oldChild->parent()->isDetails())
9932bde8e466a4451c7319e3a072d118917957d6554Steve Block        return false;
9942bde8e466a4451c7319e3a072d118917957d6554Steve Block
99565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if ((prev && (!prev->isAnonymousBlock() || toRenderBlock(prev)->continuation() || toRenderBlock(prev)->beingDestroyed()))
99665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        || (next && (!next->isAnonymousBlock() || toRenderBlock(next)->continuation() || toRenderBlock(next)->beingDestroyed())))
9975af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return false;
9985af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
999967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // FIXME: This check isn't required when inline run-ins can't be split into continuations.
1000967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    if (prev && prev->firstChild() && prev->firstChild()->isInline() && prev->firstChild()->isRunIn())
1001967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        return false;
1002967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
10035af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if ((prev && (prev->isRubyRun() || prev->isRubyBase()))
10045af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        || (next && (next->isRubyRun() || next->isRubyBase())))
10055af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return false;
10065af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
10075af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (!prev || !next)
10085af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return true;
10095af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
10105af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // Make sure the types of the anonymous blocks match up.
10115af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return prev->isAnonymousColumnsBlock() == next->isAnonymousColumnsBlock()
1012cad810f21b803229eb11403f9209855525a25d57Steve Block           && prev->isAnonymousColumnSpanBlock() == next->isAnonymousColumnSpanBlock();
10135af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
10145af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
10158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::removeChild(RenderObject* oldChild)
10168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If this child is a block, and if our previous and next siblings are
10188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // both anonymous blocks with inline content, then we can go ahead and
10198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // fold the inline content back together.
10208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* prev = oldChild->previousSibling();
10218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* next = oldChild->nextSibling();
10225af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, prev, next);
10235af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (canMergeAnonymousBlocks && prev && next) {
10248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        prev->setNeedsLayoutAndPrefWidthsRecalc();
10258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderBlock* nextBlock = toRenderBlock(next);
10268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderBlock* prevBlock = toRenderBlock(prev);
10275af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
10285af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (prev->childrenInline() != next->childrenInline()) {
10295af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            RenderBlock* inlineChildrenBlock = prev->childrenInline() ? prevBlock : nextBlock;
10305af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            RenderBlock* blockChildrenBlock = prev->childrenInline() ? nextBlock : prevBlock;
10315af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
10325af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // Place the inline children block inside of the block children block instead of deleting it.
10335af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // In order to reuse it, we have to reset it to just be a generic anonymous block.  Make sure
10345af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // to clear out inherited column properties by just making a new style, and to also clear the
10355af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // column span flag if it is set.
10365af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            ASSERT(!inlineChildrenBlock->continuation());
10372bde8e466a4451c7319e3a072d118917957d6554Steve Block            RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
10385af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            children()->removeChildNode(this, inlineChildrenBlock, inlineChildrenBlock->hasLayer());
10395af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            inlineChildrenBlock->setStyle(newStyle);
10405af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
10415af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // Now just put the inlineChildrenBlock inside the blockChildrenBlock.
10425af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            blockChildrenBlock->children()->insertChildNode(blockChildrenBlock, inlineChildrenBlock, prev == inlineChildrenBlock ? blockChildrenBlock->firstChild() : 0,
10435af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                                                            inlineChildrenBlock->hasLayer() || blockChildrenBlock->hasLayer());
10445af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            next->setNeedsLayoutAndPrefWidthsRecalc();
1045cad810f21b803229eb11403f9209855525a25d57Steve Block
1046cad810f21b803229eb11403f9209855525a25d57Steve Block            // inlineChildrenBlock got reparented to blockChildrenBlock, so it is no longer a child
1047cad810f21b803229eb11403f9209855525a25d57Steve Block            // of "this". we null out prev or next so that is not used later in the function.
1048cad810f21b803229eb11403f9209855525a25d57Steve Block            if (inlineChildrenBlock == prevBlock)
1049cad810f21b803229eb11403f9209855525a25d57Steve Block                prev = 0;
1050cad810f21b803229eb11403f9209855525a25d57Steve Block            else
1051cad810f21b803229eb11403f9209855525a25d57Steve Block                next = 0;
10525af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        } else {
10535af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // Take all the children out of the |next| block and put them in
10545af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // the |prev| block.
105565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            nextBlock->moveAllChildrenTo(prevBlock, nextBlock->hasLayer() || prevBlock->hasLayer());
1056cad810f21b803229eb11403f9209855525a25d57Steve Block
10575af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            // Delete the now-empty block's lines and nuke it.
10585af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            nextBlock->deleteLineBoxTree();
10595af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            nextBlock->destroy();
1060cad810f21b803229eb11403f9209855525a25d57Steve Block            next = 0;
10615af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        }
10628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBox::removeChild(oldChild);
10658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* child = prev ? prev : next;
10675af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && !isFlexibleBox()) {
10688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // The removal has knocked us down to containing only a single anonymous
10698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // box.  We can go ahead and pull the content right back up into our
10708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // box.
10718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setNeedsLayoutAndPrefWidthsRecalc();
10725af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        setChildrenInline(child->childrenInline());
10735af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        RenderBlock* anonBlock = toRenderBlock(children()->removeChildNode(this, child, child->hasLayer()));
10745af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        anonBlock->moveAllChildrenTo(this, child->hasLayer());
10758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Delete the now-empty block's lines and nuke it.
10768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        anonBlock->deleteLineBoxTree();
10778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        anonBlock->destroy();
10788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1079d0825bca7fe65beaee391d30da42e937db621564Steve Block
10805af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (!firstChild() && !documentBeingDestroyed()) {
10815af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        // If this was our last child be sure to clear out our line boxes.
10825af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (childrenInline())
10835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            lineBoxes()->deleteLineBoxes(renderArena());
10845af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    }
10858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::isSelfCollapsingBlock() const
10888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We are not self-collapsing if we
10908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (a) have a non-zero height according to layout (an optimization to avoid wasting time)
10918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (b) are a table,
10928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (c) have border/padding,
10938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (d) have a min-height
10948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (e) have specified that one of our margins can't collapse using a CSS extension
1095a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (logicalHeight() > 0
1096a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        || isTable() || borderAndPaddingLogicalHeight()
1097a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        || style()->logicalMinHeight().isPositive()
1098bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        || style()->marginBeforeCollapse() == MSEPARATE || style()->marginAfterCollapse() == MSEPARATE)
10998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
11008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1101a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    Length logicalHeightLength = style()->logicalHeight();
1102a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool hasAutoHeight = logicalHeightLength.isAuto();
1103a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (logicalHeightLength.isPercent() && !document()->inQuirksMode()) {
11048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        hasAutoHeight = true;
11058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (RenderBlock* cb = containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) {
1106a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (cb->style()->logicalHeight().isFixed() || cb->isTableCell())
11078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                hasAutoHeight = false;
11088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
11098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
11108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the height is 0 or auto, then whether or not we are a self-collapsing block depends
11128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // on whether we have content that is all self-collapsing or not.
1113a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (hasAutoHeight || ((logicalHeightLength.isFixed() || logicalHeightLength.isPercent()) && logicalHeightLength.isZero())) {
11148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // If the block has inline children, see if we generated any line boxes.  If we have any
11158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // line boxes, then we can't be self-collapsing, since we have content.
11168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (childrenInline())
11178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return !firstLineBox();
11188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Whether or not we collapse is dependent on whether all our normal flow children
11208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // are also self-collapsing.
1121635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
11228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (child->isFloatingOrPositioned())
11238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
11248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!child->isSelfCollapsingBlock())
11258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return false;
11268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
11278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
11288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
11298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
11308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid RenderBlock::startDelayUpdateScrollInfo()
11330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
11340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (gDelayUpdateScrollInfo == 0) {
11350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ASSERT(!gDelayedUpdateScrollInfoSet);
11360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet;
11370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
11380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(gDelayedUpdateScrollInfoSet);
11390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ++gDelayUpdateScrollInfo;
11400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
11410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
11420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid RenderBlock::finishDelayUpdateScrollInfo()
11430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
11440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    --gDelayUpdateScrollInfo;
11450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(gDelayUpdateScrollInfo >= 0);
11460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (gDelayUpdateScrollInfo == 0) {
11470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ASSERT(gDelayedUpdateScrollInfoSet);
11480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1149643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        OwnPtr<DelayedUpdateScrollInfoSet> infoSet(gDelayedUpdateScrollInfoSet);
1150643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        gDelayedUpdateScrollInfoSet = 0;
1151643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
1152643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        for (DelayedUpdateScrollInfoSet::iterator it = infoSet->begin(); it != infoSet->end(); ++it) {
11530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            RenderBlock* block = *it;
11540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (block->hasOverflowClip()) {
11550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                block->layer()->updateScrollInfoAfterLayout();
11560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
11570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
11580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
11590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
11600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
11610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid RenderBlock::updateScrollInfoAfterLayout()
11620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
11630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (hasOverflowClip()) {
11640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (gDelayUpdateScrollInfo)
11650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            gDelayedUpdateScrollInfoSet->add(this);
11660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        else
11670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            layer()->updateScrollInfoAfterLayout();
11680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
11690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
11700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
11718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::layout()
11728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Update our first letter info now.
11748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    updateFirstLetter();
11758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Table cells call layoutBlock directly, so don't add any logic here.  Put code into
11778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // layoutBlock().
11788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    layoutBlock(false);
11798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // It's safe to check for control clip here, since controls can never be table cells.
1181231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // If we have a lightweight clip, there can never be any overflow from children.
1182231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (hasControlClip() && m_overflow)
1183231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        clearLayoutOverflow();
11848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1186f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderBlock::layoutBlock(bool relayoutChildren, int pageLogicalHeight)
11878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(needsLayout());
11898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isInline() && !isInlineBlockOrInlineTable()) // Inline <form>s inside various table elements can
11918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;                                      // cause us to come in here.  Just bail.
11928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11932bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!relayoutChildren && simplifiedLayout())
11948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
11958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    LayoutRepainter repainter(*this, m_everHadLayout && checkForRepaintDuringLayout());
11978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1198a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int oldWidth = logicalWidth();
11998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int oldColumnWidth = desiredColumnWidth();
12008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1201bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    computeLogicalWidth();
12028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    calcColumnWidth();
12038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1204231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_overflow.clear();
12058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1206bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (oldWidth != logicalWidth() || oldColumnWidth != desiredColumnWidth())
12078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        relayoutChildren = true;
12088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_LAYOUT
121023e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang    checkAndSetRelayoutChildren(&relayoutChildren);
12118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
12128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    clearFloats();
12148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1215bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int previousHeight = logicalHeight();
1216bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    setLogicalHeight(0);
1217f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    bool hasSpecifiedPageLogicalHeight = false;
1218f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    bool pageLogicalHeightChanged = false;
121968513a70bcd92384395513322f1b801e7bf9c729Steve Block    ColumnInfo* colInfo = columnInfo();
122068513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (hasColumns()) {
1221f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (!pageLogicalHeight) {
122268513a70bcd92384395513322f1b801e7bf9c729Steve Block            // We need to go ahead and set our explicit page height if one exists, so that we can
122368513a70bcd92384395513322f1b801e7bf9c729Steve Block            // avoid doing two layout passes.
1224bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            computeLogicalHeight();
1225bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            int columnHeight = contentLogicalHeight();
122668513a70bcd92384395513322f1b801e7bf9c729Steve Block            if (columnHeight > 0) {
1227f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                pageLogicalHeight = columnHeight;
1228f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                hasSpecifiedPageLogicalHeight = true;
122968513a70bcd92384395513322f1b801e7bf9c729Steve Block            }
1230bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setLogicalHeight(0);
123168513a70bcd92384395513322f1b801e7bf9c729Steve Block        }
1232f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (colInfo->columnHeight() != pageLogicalHeight && m_everHadLayout) {
1233f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            colInfo->setColumnHeight(pageLogicalHeight);
1234f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            pageLogicalHeightChanged = true;
123568513a70bcd92384395513322f1b801e7bf9c729Steve Block        }
123668513a70bcd92384395513322f1b801e7bf9c729Steve Block
1237f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (!hasSpecifiedPageLogicalHeight && !pageLogicalHeight)
123868513a70bcd92384395513322f1b801e7bf9c729Steve Block            colInfo->clearForcedBreaks();
123968513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
124068513a70bcd92384395513322f1b801e7bf9c729Steve Block
1241f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode(), pageLogicalHeight, pageLogicalHeightChanged, colInfo);
1242635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
12435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track
12448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // our current maximal positive and negative margins.  These values are used when we
12458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // are collapsed with adjacent blocks, so for example, if you have block A and B
12468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // collapsing together, then you'd take the maximal positive margin from both A and B
12478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // and subtract it from the maximal negative margin from both A and B to get the
12488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // true collapsed margin.  This algorithm is recursive, so when we finish layout()
12498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // our block knows its current maximal positive/negative values.
12508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    //
12518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Start out by setting our margin values to our current margins.  Table cells have
12528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // no margins, so we don't fill in the values for table cells.
12538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool isCell = isTableCell();
12548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!isCell) {
12558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        initMaxMarginValues();
125668513a70bcd92384395513322f1b801e7bf9c729Steve Block
1257bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setMarginBeforeQuirk(style()->marginBefore().quirk());
1258bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setMarginAfterQuirk(style()->marginAfter().quirk());
12598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        Node* n = node();
12618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (n && n->hasTagName(formTag) && static_cast<HTMLFormElement*>(n)->isMalformed()) {
12628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // See if this form is malformed (i.e., unclosed). If so, don't give the form
12638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // a bottom margin.
1264bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setMaxMarginAfterValues(0, 0);
12658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
126668513a70bcd92384395513322f1b801e7bf9c729Steve Block
126768513a70bcd92384395513322f1b801e7bf9c729Steve Block        setPaginationStrut(0);
12688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // For overflow:scroll blocks, ensure we have both scrollbars in place always.
12718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (scrollsOverflow()) {
12728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (style()->overflowX() == OSCROLL)
12738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            layer()->setHasHorizontalScrollbar(true);
12748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (style()->overflowY() == OSCROLL)
12758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            layer()->setHasVerticalScrollbar(true);
12768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1278a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int repaintLogicalTop = 0;
1279a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int repaintLogicalBottom = 0;
1280a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int maxFloatLogicalBottom = 0;
1281e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (!firstChild() && !isAnonymousBlock())
12826c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        setChildrenInline(true);
12838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childrenInline())
1284a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        layoutInlineChildren(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
12858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
1286a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        layoutBlockChildren(relayoutChildren, maxFloatLogicalBottom);
12878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Expand our intrinsic height to encompass floats.
1289a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int toAdd = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
1290a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (lowestFloatLogicalBottom() > (logicalHeight() - toAdd) && expandsToEncloseOverhangingFloats())
1291a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalHeight(lowestFloatLogicalBottom() + toAdd);
12928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1293f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (layoutColumns(hasSpecifiedPageLogicalHeight, pageLogicalHeight, statePusher))
129468513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
129568513a70bcd92384395513322f1b801e7bf9c729Steve Block
12968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Calculate our new height.
1297bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int oldHeight = logicalHeight();
1298f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int oldClientAfterEdge = clientLogicalBottom();
1299bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    computeLogicalHeight();
1300bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int newHeight = logicalHeight();
1301bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (oldHeight != newHeight) {
1302a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (oldHeight > newHeight && maxFloatLogicalBottom > newHeight && !childrenInline()) {
13038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // One of our children's floats may have become an overhanging float for us. We need to look for it.
13048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
13058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (child->isBlockFlow() && !child->isFloatingOrPositioned()) {
13068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    RenderBlock* block = toRenderBlock(child);
1307a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    if (block->lowestFloatLogicalBottom() + block->logicalTop() > newHeight)
1308a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                        addOverhangingFloats(block, -block->logicalLeft(), -block->logicalTop(), false);
13098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
13108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
13118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
13128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1313231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1314bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (previousHeight != newHeight)
13158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        relayoutChildren = true;
13168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1317231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    layoutPositionedObjects(relayoutChildren || isRoot());
13188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1319f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway).
1320f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    computeOverflow(oldClientAfterEdge);
1321231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1322635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    statePusher.pop();
13238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1324f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (view()->layoutState()->m_pageLogicalHeight)
13252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(logicalTop()));
1326f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1327f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    updateLayerTransform();
132868513a70bcd92384395513322f1b801e7bf9c729Steve Block
13298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
13308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // we overflow or not.
13310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    updateScrollInfoAfterLayout();
13328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Repaint with our new bounds if they are different from our old bounds.
13348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool didFullRepaint = repainter.repaintAfterLayout();
1335a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!didFullRepaint && repaintLogicalTop != repaintLogicalBottom && (style()->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) {
1336f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // FIXME: We could tighten up the left and right invalidation points if we let layoutInlineChildren fill them in based off the particular lines
1337f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // it had to lay out.  We wouldn't need the hasOverflowClip() hack in that case either.
1338f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        int repaintLogicalLeft = logicalLeftVisualOverflow();
1339f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        int repaintLogicalRight = logicalRightVisualOverflow();
1340f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (hasOverflowClip()) {
1341f05b935882198ccf7d81675736e3aeb089c5113aBen 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.
1342f05b935882198ccf7d81675736e3aeb089c5113aBen 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.
1343f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // layoutInlineChildren should be patched to compute the entire repaint rect.
1344f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            repaintLogicalLeft = min(repaintLogicalLeft, logicalLeftLayoutOverflow());
1345f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            repaintLogicalRight = max(repaintLogicalRight, logicalRightLayoutOverflow());
1346f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        }
1347a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1348a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        IntRect repaintRect;
13492bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (isHorizontalWritingMode())
1350a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            repaintRect = IntRect(repaintLogicalLeft, repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop);
1351a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
1352a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            repaintRect = IntRect(repaintLogicalTop, repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft);
13538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1354e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        // The repaint rect may be split across columns, in which case adjustRectForColumns() will return the union.
1355e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        adjustRectForColumns(repaintRect);
13568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        repaintRect.inflate(maximalOutlineSize(PaintPhaseOutline));
13588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (hasOverflowClip()) {
13608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Adjust repaint rect for scroll offset
1361dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            repaintRect.move(-layer()->scrolledContentOffset());
13628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Don't allow this rect to spill out of our overflow box.
1364635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            repaintRect.intersect(IntRect(0, 0, width(), height()));
13658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
13668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Make sure the rect is still non-empty after intersecting for overflow above
13688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!repaintRect.isEmpty()) {
13698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            repaintRectangle(repaintRect); // We need to do a partial repaint of our content.
13708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (hasReflection())
13715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                repaintRectangle(reflectedRect(repaintRect));
13728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
13738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
13748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setNeedsLayout(false);
13758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1377f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderBlock::addOverflowFromChildren()
1378f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
1379f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!hasColumns()) {
1380f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (childrenInline())
1381f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            addOverflowFromInlineChildren();
1382f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        else
1383f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            addOverflowFromBlockChildren();
1384f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    } else {
1385f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        ColumnInfo* colInfo = columnInfo();
1386f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (columnCount(colInfo)) {
1387f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            IntRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
13882bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (isHorizontalWritingMode()) {
13892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int overflowLeft = !style()->isLeftToRightDirection() ? min(0, lastRect.x()) : 0;
13902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int overflowRight = style()->isLeftToRightDirection() ? max(width(), lastRect.maxX()) : 0;
13912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int overflowHeight = borderBefore() + paddingBefore() + colInfo->columnHeight();
13922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                addLayoutOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight));
13932bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (!hasOverflowClip())
13942bde8e466a4451c7319e3a072d118917957d6554Steve Block                    addVisualOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight));
13952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            } else {
13962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                IntRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
13972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int overflowTop = !style()->isLeftToRightDirection() ? min(0, lastRect.y()) : 0;
13982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int overflowBottom = style()->isLeftToRightDirection() ? max(height(), lastRect.maxY()) : 0;
13992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int overflowWidth = borderBefore() + paddingBefore() + colInfo->columnHeight();
14002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                addLayoutOverflow(IntRect(0, overflowTop, overflowWidth, overflowBottom - overflowTop));
14012bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (!hasOverflowClip())
14022bde8e466a4451c7319e3a072d118917957d6554Steve Block                    addVisualOverflow(IntRect(0, overflowTop, overflowWidth, overflowBottom - overflowTop));
14032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            }
1404f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        }
1405f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
1406f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
1407f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1408f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderBlock::computeOverflow(int oldClientAfterEdge, bool recomputeFloats)
1409f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
1410f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Add overflow from children.
1411f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    addOverflowFromChildren();
1412f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1413f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!hasColumns() && (recomputeFloats || isRoot() || expandsToEncloseOverhangingFloats() || hasSelfPaintingLayer()))
1414f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        addOverflowFromFloats();
1415f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1416f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Add in the overflow from positioned objects.
1417f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    addOverflowFromPositionedObjects();
1418f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1419f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (hasOverflowClip()) {
1420f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // When we have overflow clip, propagate the original spillout since it will include collapsed bottom margins
1421f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // and bottom padding.  Set the axis we don't care about to be 1, since we want this overflow to always
1422f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // be considered reachable.
1423f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        IntRect clientRect(clientBoxRect());
1424f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        IntRect rectToApply;
14252bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (isHorizontalWritingMode())
1426f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            rectToApply = IntRect(clientRect.x(), clientRect.y(), 1, max(0, oldClientAfterEdge - clientRect.y()));
1427f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        else
1428f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            rectToApply = IntRect(clientRect.x(), clientRect.y(), max(0, oldClientAfterEdge - clientRect.x()), 1);
1429f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        addLayoutOverflow(rectToApply);
1430f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
1431f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1432f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Add visual overflow from box-shadow and reflections.
1433f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    addShadowOverflow();
1434f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
1435f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1436231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid RenderBlock::addOverflowFromBlockChildren()
1437231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
1438231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
1439231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (!child->isFloatingOrPositioned())
1440231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            addOverflowFromChild(child);
1441231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
1442231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
1443231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1444231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid RenderBlock::addOverflowFromFloats()
1445231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
1446231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!m_floatingObjects)
1447231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
144881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
144981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
145081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator end = floatingObjectSet.end();
145181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
145281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObject* r = *it;
1453f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (r->m_isDescendant)
14542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            addOverflowFromChild(r->m_renderer, IntSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r)));
1455231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
1456231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return;
1457231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
1458231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1459f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderBlock::addOverflowFromPositionedObjects()
1460f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
1461f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!m_positionedObjects)
1462f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return;
1463f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1464f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    RenderBox* positionedObject;
1465f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    Iterator end = m_positionedObjects->end();
1466f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
1467f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        positionedObject = *it;
1468f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1469f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // Fixed positioned elements don't contribute to layout overflow, since they don't scroll with the content.
1470f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (positionedObject->style()->position() != FixedPosition)
1471f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            addOverflowFromChild(positionedObject);
1472f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
1473f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
1474f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1475635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool RenderBlock::expandsToEncloseOverhangingFloats() const
1476635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
1477bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return isInlineBlockOrInlineTable() || isFloatingOrPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBox())
1478a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch           || hasColumns() || isTableCell() || isFieldset() || isWritingModeRoot();
1479635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
1480635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1481635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marginInfo)
14828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
14832bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool isHorizontal = isHorizontalWritingMode();
148481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    bool hasStaticBlockPosition = child->style()->hasStaticBlockPosition(isHorizontal);
148581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    RenderLayer* childLayer = child->layer();
148681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
14872bde8e466a4451c7319e3a072d118917957d6554Steve Block    childLayer->setStaticInlinePosition(borderAndPaddingStart());
14882bde8e466a4451c7319e3a072d118917957d6554Steve Block
14892bde8e466a4451c7319e3a072d118917957d6554Steve Block    int logicalTop = logicalHeight();
14902bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!marginInfo.canCollapseWithMarginBefore()) {
14912bde8e466a4451c7319e3a072d118917957d6554Steve Block        child->computeBlockDirectionMargins(this);
14922bde8e466a4451c7319e3a072d118917957d6554Steve Block        int marginBefore = marginBeforeForChild(child);
14932bde8e466a4451c7319e3a072d118917957d6554Steve Block        int collapsedBeforePos = marginInfo.positiveMargin();
14942bde8e466a4451c7319e3a072d118917957d6554Steve Block        int collapsedBeforeNeg = marginInfo.negativeMargin();
14952bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (marginBefore > 0) {
14962bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (marginBefore > collapsedBeforePos)
14972bde8e466a4451c7319e3a072d118917957d6554Steve Block                collapsedBeforePos = marginBefore;
14982bde8e466a4451c7319e3a072d118917957d6554Steve Block        } else {
14992bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (-marginBefore > collapsedBeforeNeg)
15002bde8e466a4451c7319e3a072d118917957d6554Steve Block                collapsedBeforeNeg = -marginBefore;
15018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
15022bde8e466a4451c7319e3a072d118917957d6554Steve Block        logicalTop += (collapsedBeforePos - collapsedBeforeNeg) - marginBefore;
15032bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
15042bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (childLayer->staticBlockPosition() != logicalTop) {
15052bde8e466a4451c7319e3a072d118917957d6554Steve Block        childLayer->setStaticBlockPosition(logicalTop);
15062bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (hasStaticBlockPosition)
1507643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            child->setChildNeedsLayout(true, false);
15088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::adjustFloatingBlock(const MarginInfo& marginInfo)
15128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The float should be positioned taking into account the bottom margin
15148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // of the previous flow.  We add that margin into the height, get the
15158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // float positioned properly, and then subtract the margin out of the
15168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // height again.  In the case of self-collapsing blocks, we always just
15178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // use the top margins, since the self-collapsing block collapsed its
15188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // own bottom margin into its top margin.
15198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    //
15208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Note also that the previous flow may collapse its margin into the top of
15218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // our block.  If this is the case, then we do not add the margin in to our
15228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // height when computing the position of the float.   This condition can be tested
1523bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // for by simply calling canCollapseWithMarginBefore.  See
15248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for
15258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // an example of this scenario.
1526bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int marginOffset = marginInfo.canCollapseWithMarginBefore() ? 0 : marginInfo.margin();
1527a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalHeight(logicalHeight() + marginOffset);
15288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    positionNewFloats();
1529a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalHeight(logicalHeight() - marginOffset);
15308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool RenderBlock::handleSpecialChild(RenderBox* child, const MarginInfo& marginInfo)
15338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Handle in the given order
15355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return handlePositionedChild(child, marginInfo)
15365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        || handleFloatingChild(child, marginInfo)
15375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        || handleRunInChild(child);
15388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool RenderBlock::handlePositionedChild(RenderBox* child, const MarginInfo& marginInfo)
15428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (child->isPositioned()) {
15448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child->containingBlock()->insertPositionedObject(child);
15458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        adjustPositionedBlock(child, marginInfo);
15465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return true;
15478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return false;
15498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool RenderBlock::handleFloatingChild(RenderBox* child, const MarginInfo& marginInfo)
15528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (child->isFloating()) {
15548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        insertFloatingObject(child);
15558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        adjustFloatingBlock(marginInfo);
15565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return true;
15578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return false;
15598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool RenderBlock::handleRunInChild(RenderBox* child)
15628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // See if we have a run-in element with inline children.  If the
15648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // children aren't inline, then just treat the run-in as a normal
15658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // block.
1566231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!child->isRunIn() || !child->childrenInline())
1567231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return false;
1568231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // FIXME: We don't handle non-block elements with run-in for now.
1569231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!child->isRenderBlock())
15705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return false;
1571635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
15720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    RenderBlock* blockRunIn = toRenderBlock(child);
15735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RenderObject* curr = blockRunIn->nextSibling();
15749a26d18f4c7e98b479be700575d003f873214550John Reck    if (!curr || !curr->isRenderBlock() || !curr->childrenInline() || curr->isRunIn() || curr->isAnonymous() || curr->isFloatingOrPositioned())
15755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return false;
15765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
15775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RenderBlock* currBlock = toRenderBlock(curr);
15785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1579538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block    // First we destroy any :before/:after content. It will be regenerated by the new inline.
1580538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block    // Exception is if the run-in itself is generated.
1581538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block    if (child->style()->styleType() != BEFORE && child->style()->styleType() != AFTER) {
1582538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block        RenderObject* generatedContent;
1583538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block        if (child->getCachedPseudoStyle(BEFORE) && (generatedContent = child->beforePseudoElementRenderer()))
1584538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block            generatedContent->destroy();
1585538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block        if (child->getCachedPseudoStyle(AFTER) && (generatedContent = child->afterPseudoElementRenderer()))
1586538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block            generatedContent->destroy();
1587538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block    }
1588538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block
15895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Remove the old child.
15905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    children()->removeChildNode(this, blockRunIn);
1591635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
15925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Create an inline.
15935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Node* runInNode = blockRunIn->node();
15945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RenderInline* inlineRunIn = new (renderArena()) RenderInline(runInNode ? runInNode : document());
15955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    inlineRunIn->setStyle(blockRunIn->style());
15965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1597538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block    // Move the nodes from the old child to the new child
15986c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    for (RenderObject* runInChild = blockRunIn->firstChild(); runInChild;) {
15996c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        RenderObject* nextSibling = runInChild->nextSibling();
1600538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block        blockRunIn->children()->removeChildNode(blockRunIn, runInChild, false);
1601538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block        inlineRunIn->addChild(runInChild); // Use addChild instead of appendChildNode since it handles correct placement of the children relative to :after-generated content.
16026c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        runInChild = nextSibling;
16038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
16052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben 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
16062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // anything before the first child. e.g. details tag. See https://bugs.webkit.org/show_bug.cgi?id=58228.
16072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    currBlock->addChild(inlineRunIn, currBlock->firstChild());
16085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
16095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // If the run-in had an element, we need to set the new renderer.
16105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (runInNode)
16115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        runInNode->setRenderer(inlineRunIn);
16125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1613bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // Destroy the block run-in, which includes deleting its line box tree.
1614bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    blockRunIn->deleteLineBoxTree();
16155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    blockRunIn->destroy();
16165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
16175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // The block acts like an inline, so just null out its
16185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // position.
16195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
16205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return true;
16218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
16228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianint RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo)
16248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1625a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Get the four margin values for the child and cache them.
1626a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    const MarginValues childMargins = marginValuesForChild(child);
1627a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
16288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Get our max pos and neg top margins.
1629a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int posTop = childMargins.positiveMarginBefore();
1630a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int negTop = childMargins.negativeMarginBefore();
16318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // For self-collapsing blocks, collapse our bottom margins into our
16338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // top to get new posTop and negTop values.
16348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (child->isSelfCollapsingBlock()) {
1635a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        posTop = max(posTop, childMargins.positiveMarginAfter());
1636a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        negTop = max(negTop, childMargins.negativeMarginAfter());
16378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // See if the top margin is quirky. We only care if this child has
16408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // margins that will collapse with us.
1641bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    bool topQuirk = child->isMarginBeforeQuirk() || style()->marginBeforeCollapse() == MDISCARD;
16428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1643bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (marginInfo.canCollapseWithMarginBefore()) {
16448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // This child is collapsing with the top of the
16458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // block.  If it has larger margin values, then we need to update
16468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // our own maximal values.
16475ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        if (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !topQuirk)
1648a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            setMaxMarginBeforeValues(max(posTop, maxPositiveMarginBefore()), max(negTop, maxNegativeMarginBefore()));
16498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // The minute any of the margins involved isn't a quirk, don't
16518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // collapse it away, even if the margin is smaller (www.webreference.com
16528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // has an example of this, a <dt> with 0.8em author-specified inside
16538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // a <dl> inside a <td>.
1654a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!marginInfo.determinedMarginBeforeQuirk() && !topQuirk && (posTop - negTop)) {
1655bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setMarginBeforeQuirk(false);
1656bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            marginInfo.setDeterminedMarginBeforeQuirk(true);
16578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
16588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1659a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!marginInfo.determinedMarginBeforeQuirk() && topQuirk && !marginBefore())
16608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We have no top margin and our top child has a quirky margin.
16618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We will pick up this quirky margin and pass it through.
16628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // This deals with the <td><div><p> case.
16638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Don't do this for a block that split two inlines though.  You do
16648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // still apply margins in this case.
1665bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setMarginBeforeQuirk(true);
16668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1668bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (marginInfo.quirkContainer() && marginInfo.atBeforeSideOfBlock() && (posTop - negTop))
1669bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        marginInfo.setMarginBeforeQuirk(topQuirk);
16708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1671a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int beforeCollapseLogicalTop = logicalHeight();
1672a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalTop = beforeCollapseLogicalTop;
16738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (child->isSelfCollapsingBlock()) {
16748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // This child has no height.  We need to compute our
16758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // position before we collapse the child's margins together,
16768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // so that we can get an accurate position for the zero-height block.
1677a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int collapsedBeforePos = max(marginInfo.positiveMargin(), childMargins.positiveMarginBefore());
1678a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int collapsedBeforeNeg = max(marginInfo.negativeMargin(), childMargins.negativeMarginBefore());
1679a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        marginInfo.setMargin(collapsedBeforePos, collapsedBeforeNeg);
16808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Now collapse the child's margins together, which means examining our
16828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // bottom margin values as well.
1683a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        marginInfo.setPositiveMarginIfLarger(childMargins.positiveMarginAfter());
1684a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        marginInfo.setNegativeMarginIfLarger(childMargins.negativeMarginAfter());
16858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1686bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (!marginInfo.canCollapseWithMarginBefore())
16878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We need to make sure that the position of the self-collapsing block
16888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // is correct, since it could have overflowing content
16898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // that needs to be positioned correctly (e.g., a block that
16908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // had a specified height of 0 but that actually had subcontent).
1691a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            logicalTop = logicalHeight() + collapsedBeforePos - collapsedBeforeNeg;
16928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
1694bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (child->style()->marginBeforeCollapse() == MSEPARATE) {
1695a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            setLogicalHeight(logicalHeight() + marginInfo.margin() + marginBeforeForChild(child));
1696a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            logicalTop = logicalHeight();
16978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1698bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        else if (!marginInfo.atBeforeSideOfBlock() ||
1699bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            (!marginInfo.canCollapseMarginBeforeWithChildren()
1700bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen             && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.marginBeforeQuirk()))) {
17018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We're collapsing with a previous sibling's margins and not
17028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // with the top of the block.
1703a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            setLogicalHeight(logicalHeight() + max(marginInfo.positiveMargin(), posTop) - max(marginInfo.negativeMargin(), negTop));
1704a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            logicalTop = logicalHeight();
17058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
17068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1707a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        marginInfo.setPositiveMargin(childMargins.positiveMarginAfter());
1708a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        marginInfo.setNegativeMargin(childMargins.negativeMarginAfter());
17098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (marginInfo.margin())
1711bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            marginInfo.setMarginAfterQuirk(child->isMarginAfterQuirk() || style()->marginAfterCollapse() == MDISCARD);
17128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
17138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
171468513a70bcd92384395513322f1b801e7bf9c729Steve Block    // If margins would pull us past the top of the next page, then we need to pull back and pretend like the margins
171568513a70bcd92384395513322f1b801e7bf9c729Steve Block    // collapsed into the page edge.
171668513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool paginated = view()->layoutState()->isPaginated();
1717a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (paginated && logicalTop > beforeCollapseLogicalTop) {
1718a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int oldLogicalTop = logicalTop;
17192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        logicalTop = min(logicalTop, nextPageLogicalTop(beforeCollapseLogicalTop));
1720a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop));
172168513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
1722a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return logicalTop;
17238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianint RenderBlock::clearFloatsIfNeeded(RenderBox* child, MarginInfo& marginInfo, int oldTopPosMargin, int oldTopNegMargin, int yPos)
17268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
17278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int heightIncrease = getClearDelta(child, yPos);
17288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!heightIncrease)
17298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return yPos;
17308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (child->isSelfCollapsingBlock()) {
17328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // For self-collapsing blocks that clear, they can still collapse their
17338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // margins with following siblings.  Reset the current margins to represent
17348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // the self-collapsing block's margins only.
1735231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // CSS2.1 states:
1736231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // "An element that has had clearance applied to it never collapses its top margin with its parent block's bottom margin.
1737231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Therefore if we are at the bottom of the block, let's go ahead and reset margins to only include the
1738231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // self-collapsing block's bottom margin.
1739231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        bool atBottomOfBlock = true;
1740231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        for (RenderBox* curr = child->nextSiblingBox(); curr && atBottomOfBlock; curr = curr->nextSiblingBox()) {
1741231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if (!curr->isFloatingOrPositioned())
1742231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                atBottomOfBlock = false;
1743231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
1744a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1745a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        MarginValues childMargins = marginValuesForChild(child);
1746231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (atBottomOfBlock) {
1747a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            marginInfo.setPositiveMargin(childMargins.positiveMarginAfter());
1748a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            marginInfo.setNegativeMargin(childMargins.negativeMarginAfter());
1749231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        } else {
1750a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            marginInfo.setPositiveMargin(max(childMargins.positiveMarginBefore(), childMargins.positiveMarginAfter()));
1751a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            marginInfo.setNegativeMargin(max(childMargins.negativeMarginBefore(), childMargins.negativeMarginAfter()));
1752231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
17538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1754231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Adjust our height such that we are ready to be collapsed with subsequent siblings (or the bottom
1755231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // of the parent block).
1756bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setLogicalHeight(child->y() - max(0, marginInfo.margin()));
17578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else
17588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Increase our height by the amount we had to clear.
1759bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setLogicalHeight(height() + heightIncrease);
17608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1761bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (marginInfo.canCollapseWithMarginBefore()) {
17628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We can no longer collapse with the top of the block since a clear
17638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // occurred.  The empty blocks collapse into the cleared block.
17648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: This isn't quite correct.  Need clarification for what to do
17658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // if the height the cleared block is offset by is smaller than the
17668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // margins involved.
1767bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setMaxMarginBeforeValues(oldTopPosMargin, oldTopNegMargin);
1768bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        marginInfo.setAtBeforeSideOfBlock(false);
17698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
17708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
17718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return yPos + heightIncrease;
17728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1774a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::estimateLogicalTopPosition(RenderBox* child, const MarginInfo& marginInfo)
17758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
17768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: We need to eliminate the estimation of vertical position, because when it's wrong we sometimes trigger a pathological
17778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // relayout if there are intruding floats.
1778a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalTopEstimate = logicalHeight();
1779bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (!marginInfo.canCollapseWithMarginBefore()) {
1780a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int childMarginBefore = child->selfNeedsLayout() ? marginBeforeForChild(child) : collapsedMarginBeforeForChild(child);
1781a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        logicalTopEstimate += max(marginInfo.margin(), childMarginBefore);
17828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
178368513a70bcd92384395513322f1b801e7bf9c729Steve Block
178468513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool paginated = view()->layoutState()->isPaginated();
178568513a70bcd92384395513322f1b801e7bf9c729Steve Block
1786a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Adjust logicalTopEstimate down to the next page if the margins are so large that we don't fit on the current
178768513a70bcd92384395513322f1b801e7bf9c729Steve Block    // page.
1788a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (paginated && logicalTopEstimate > logicalHeight())
17892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        logicalTopEstimate = min(logicalTopEstimate, nextPageLogicalTop(logicalHeight()));
179068513a70bcd92384395513322f1b801e7bf9c729Steve Block
1791a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    logicalTopEstimate += getClearDelta(child, logicalTopEstimate);
179268513a70bcd92384395513322f1b801e7bf9c729Steve Block
179368513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (paginated) {
179468513a70bcd92384395513322f1b801e7bf9c729Steve Block        // If the object has a page or column break value of "before", then we should shift to the top of the next page.
1795a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        logicalTopEstimate = applyBeforeBreak(child, logicalTopEstimate);
179668513a70bcd92384395513322f1b801e7bf9c729Steve Block
179768513a70bcd92384395513322f1b801e7bf9c729Steve 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.
1798a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        logicalTopEstimate = adjustForUnsplittableChild(child, logicalTopEstimate);
179968513a70bcd92384395513322f1b801e7bf9c729Steve Block
180068513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (!child->selfNeedsLayout() && child->isRenderBlock())
1801a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            logicalTopEstimate += toRenderBlock(child)->paginationStrut();
180268513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
180368513a70bcd92384395513322f1b801e7bf9c729Steve Block
1804a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return logicalTopEstimate;
18058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1807a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::determineLogicalLeftPositionForChild(RenderBox* child)
18088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1809a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int startPosition = borderStart() + paddingStart();
1810a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + availableLogicalWidth();
1811a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1812a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Add in our start margin.
1813a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int childMarginStart = marginStartForChild(child);
1814a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int newPosition = startPosition + childMarginStart;
18158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1816a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats.  They need
1817a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // to shift over as necessary to dodge any floats that might get in the way.
1818a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (child->avoidsFloats()) {
1819a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int startOff = style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(logicalHeight(), false) : totalAvailableLogicalWidth - logicalRightOffsetForLine(logicalHeight(), false);
1820a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->textAlign() != WEBKIT_CENTER && !child->style()->marginStartUsing(style()).isAuto()) {
1821a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (childMarginStart < 0)
1822a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                startOff += childMarginStart;
1823a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            newPosition = max(newPosition, startOff); // Let the float sit in the child's margin if it can fit.
1824a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        } else if (startOff != startPosition) {
1825a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // The object is shifting to the "end" side of the block. The object might be centered, so we need to
1826a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // recalculate our inline direction margins. Note that the containing block content
1827a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // width computation will take into account the delta between |startOff| and |startPosition|
1828a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // so that we can just pass the content width in directly to the |computeMarginsInContainingBlockInlineDirection|
1829a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // function.
1830a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->computeInlineDirectionMargins(this, availableLogicalWidthForLine(logicalTopForChild(child), false), logicalWidthForChild(child));
1831a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            newPosition = startOff + marginStartForChild(child);
18328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
18338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1834a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1835a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalLeftForChild(child, style()->isLeftToRightDirection() ? newPosition : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child), ApplyLayoutDelta);
18368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::setCollapsedBottomMargin(const MarginInfo& marginInfo)
18398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1840bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()) {
18418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Update our max pos/neg bottom margins, since we collapsed our bottom margins
18428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // with our children.
1843a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setMaxMarginAfterValues(max(maxPositiveMarginAfter(), marginInfo.positiveMargin()), max(maxNegativeMarginAfter(), marginInfo.negativeMargin()));
18448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1845bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (!marginInfo.marginAfterQuirk())
1846bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setMarginAfterQuirk(false);
18478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1848a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (marginInfo.marginAfterQuirk() && marginAfter() == 0)
18498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We have no bottom margin and our last child has a quirky margin.
18508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We will pick up this quirky margin and pass it through.
18518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // This deals with the <td><div><p> case.
1852bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setMarginAfterQuirk(true);
18538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
18548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1856a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::handleAfterSideOfBlock(int beforeSide, int afterSide, MarginInfo& marginInfo)
18578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1858bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    marginInfo.setAtAfterSideOfBlock(true);
18598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If we can't collapse with children then go ahead and add in the bottom margin.
1861bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (!marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()
1862bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.marginAfterQuirk()))
1863a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalHeight(logicalHeight() + marginInfo.margin());
18648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Now add in our bottom border/padding.
1866a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalHeight(logicalHeight() + afterSide);
18678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Negative margins can cause our height to shrink below our minimal height (border/padding).
18698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If this happens, ensure that the computed height is increased to the minimal height.
1870a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalHeight(max(logicalHeight(), beforeSide + afterSide));
18718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Update our bottom collapsed margin info.
18738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setCollapsedBottomMargin(marginInfo);
18748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1876a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setLogicalLeftForChild(RenderBox* child, int logicalLeft, ApplyLayoutDeltaMode applyDelta)
1877a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
18782bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode()) {
1879a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (applyDelta == ApplyLayoutDelta)
1880a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            view()->addLayoutDelta(IntSize(child->x() - logicalLeft, 0));
1881a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setX(logicalLeft);
1882a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else {
1883a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (applyDelta == ApplyLayoutDelta)
1884a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            view()->addLayoutDelta(IntSize(0, child->y() - logicalLeft));
1885a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setY(logicalLeft);
1886a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
1887a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1888a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1889a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setLogicalTopForChild(RenderBox* child, int logicalTop, ApplyLayoutDeltaMode applyDelta)
1890a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
18912bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode()) {
1892a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (applyDelta == ApplyLayoutDelta)
1893a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            view()->addLayoutDelta(IntSize(0, child->y() - logicalTop));
1894a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setY(logicalTop);
1895a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else {
1896a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (applyDelta == ApplyLayoutDelta)
1897a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            view()->addLayoutDelta(IntSize(child->x() - logicalTop, 0));
1898a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setX(logicalTop);
1899a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
1900a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1901a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1902a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatLogicalBottom)
19038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
19048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (gPercentHeightDescendantsMap) {
19058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (HashSet<RenderBox*>* descendants = gPercentHeightDescendantsMap->get(this)) {
19068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            HashSet<RenderBox*>::iterator end = descendants->end();
19078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (HashSet<RenderBox*>::iterator it = descendants->begin(); it != end; ++it) {
19088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                RenderBox* box = *it;
19098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                while (box != this) {
19108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (box->normalChildNeedsLayout())
19118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
19128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    box->setChildNeedsLayout(true, false);
19138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    box = box->containingBlock();
19148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    ASSERT(box);
19158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (!box)
19168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
19178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
19188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
19198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
19208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
19218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1922a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int beforeEdge = borderBefore() + paddingBefore();
1923a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
19248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1925a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalHeight(beforeEdge);
19268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The margin struct caches all our current margin collapsing state.  The compact struct caches state when we encounter compacts,
1928a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    MarginInfo marginInfo(this, beforeEdge, afterEdge);
19298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Fieldsets need to find their legend and position it inside the border of the object.
19314576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    // The legend then gets skipped during normal layout.  The same is true for ruby text.
19324576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    // It doesn't get included in the normal layout process but is instead skipped.
19334576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    RenderObject* childToExclude = layoutSpecialExcludedChild(relayoutChildren);
19348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1935a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int previousFloatLogicalBottom = 0;
1936a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    maxFloatLogicalBottom = 0;
19378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RenderBox* next = firstChildBox();
19395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
19405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    while (next) {
19415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        RenderBox* child = next;
19425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        next = child->nextSiblingBox();
19435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
19444576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        if (childToExclude == child)
19454576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            continue; // Skip this child, since it will be positioned by the specialized subclass (fieldsets and ruby runs).
19468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Make sure we layout children if they need it.
19488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into
19498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // an auto value.  Add a method to determine this, so that we can avoid the relayout.
1950a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (relayoutChildren || ((child->style()->logicalHeight().isPercent() || child->style()->logicalMinHeight().isPercent() || child->style()->logicalMaxHeight().isPercent()) && !isRenderView()))
19518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            child->setChildNeedsLayout(true, false);
19528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1953a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // If relayoutChildren is set and the child has percentage padding, we also need to invalidate the child's pref widths.
1954a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (relayoutChildren && (child->style()->paddingStart().isPercent() || child->style()->paddingEnd().isPercent()))
1955bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            child->setPreferredLogicalWidthsDirty(true, false);
19568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Handle the four types of special elements first.  These include positioned content, floating content, compacts and
19588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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.
19595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (handleSpecialChild(child, marginInfo))
19608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
19618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1962231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Lay out the child.
1963a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        layoutBlockChild(child, marginInfo, previousFloatLogicalBottom, maxFloatLogicalBottom);
1964231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
1965231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1966231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Now do the handling of the bottom of the block, adding in our bottom border/padding and
1967231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // determining the correct collapsed bottom margin information.
1968a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    handleAfterSideOfBlock(beforeEdge, afterEdge, marginInfo);
1969231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
19708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1971a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, int& previousFloatLogicalBottom, int& maxFloatLogicalBottom)
1972231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
1973a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int oldPosMarginBefore = maxPositiveMarginBefore();
1974a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int oldNegMarginBefore = maxNegativeMarginBefore();
19758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1976a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // The child is a normal flow object.  Compute the margins we will use for collapsing now.
1977bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    child->computeBlockDirectionMargins(this);
19788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1979a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Do not allow a collapse if the margin-before-collapse style is set to SEPARATE.
1980bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (child->style()->marginBeforeCollapse() == MSEPARATE) {
1981bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        marginInfo.setAtBeforeSideOfBlock(false);
1982231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        marginInfo.clearMargin();
1983231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
1984231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1985a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Try to guess our correct logical top position.  In most cases this guess will
1986a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // be correct.  Only if we're wrong (when we compute the real logical top position)
1987231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // will we have to potentially relayout.
1988a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalTopEstimate = estimateLogicalTopPosition(child, marginInfo);
1989231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1990231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Cache our old rect so that we can dirty the proper repaint rects if the child moves.
1991231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    IntRect oldRect(child->x(), child->y() , child->width(), child->height());
1992a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int oldLogicalTop = logicalTopForChild(child);
1993a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1994635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#ifndef NDEBUG
1995231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    IntSize oldLayoutDelta = view()->layoutDelta();
1996635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif
1997231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Go ahead and position the child as though it didn't collapse with the top.
1998a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalTopForChild(child, logicalTopEstimate, ApplyLayoutDelta);
1999231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
200068513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0;
2001231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    bool markDescendantsWithFloats = false;
2002a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (logicalTopEstimate != oldLogicalTop && !child->avoidsFloats() && childRenderBlock && childRenderBlock->containsFloats())
2003231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        markDescendantsWithFloats = true;
2004231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) {
2005231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // If an element might be affected by the presence of floats, then always mark it for
2006231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // layout.
2007a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int fb = max(previousFloatLogicalBottom, lowestFloatLogicalBottom());
2008a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (fb > logicalTopEstimate)
20098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            markDescendantsWithFloats = true;
2010231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
20118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
201268513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (childRenderBlock) {
2013231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (markDescendantsWithFloats)
201468513a70bcd92384395513322f1b801e7bf9c729Steve Block            childRenderBlock->markAllDescendantsWithFloatsForLayout();
2015a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!child->isWritingModeRoot())
2016a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            previousFloatLogicalBottom = max(previousFloatLogicalBottom, oldLogicalTop + childRenderBlock->lowestFloatLogicalBottom());
2017231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
20188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2019a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!child->needsLayout())
2020a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->markForPaginationRelayoutIfNeeded();
202168513a70bcd92384395513322f1b801e7bf9c729Steve Block
2022231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    bool childHadLayout = child->m_everHadLayout;
2023231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    bool childNeededLayout = child->needsLayout();
2024231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (childNeededLayout)
2025231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        child->layout();
20268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
202768513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Cache if we are at the top of the block right now.
2028bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock();
202968513a70bcd92384395513322f1b801e7bf9c729Steve Block
2030231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Now determine the correct ypos based off examination of collapsing margin
2031231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // values.
2032a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalTopBeforeClear = collapseMargins(child, marginInfo);
20338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2034231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Now check for clear.
2035a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalTopAfterClear = clearFloatsIfNeeded(child, marginInfo, oldPosMarginBefore, oldNegMarginBefore, logicalTopBeforeClear);
20368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2037a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool paginated = view()->layoutState()->isPaginated();
203868513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (paginated) {
2039a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int oldTop = logicalTopAfterClear;
204068513a70bcd92384395513322f1b801e7bf9c729Steve Block
204168513a70bcd92384395513322f1b801e7bf9c729Steve Block        // If the object has a page or column break value of "before", then we should shift to the top of the next page.
2042a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        logicalTopAfterClear = applyBeforeBreak(child, logicalTopAfterClear);
204368513a70bcd92384395513322f1b801e7bf9c729Steve Block
204468513a70bcd92384395513322f1b801e7bf9c729Steve 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.
2045a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int logicalTopBeforeUnsplittableAdjustment = logicalTopAfterClear;
2046a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChild(child, logicalTopAfterClear);
204768513a70bcd92384395513322f1b801e7bf9c729Steve Block
204868513a70bcd92384395513322f1b801e7bf9c729Steve Block        int paginationStrut = 0;
2049a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustment - logicalTopBeforeUnsplittableAdjustment;
205068513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (unsplittableAdjustmentDelta)
205168513a70bcd92384395513322f1b801e7bf9c729Steve Block            paginationStrut = unsplittableAdjustmentDelta;
205268513a70bcd92384395513322f1b801e7bf9c729Steve Block        else if (childRenderBlock && childRenderBlock->paginationStrut())
205368513a70bcd92384395513322f1b801e7bf9c729Steve Block            paginationStrut = childRenderBlock->paginationStrut();
205468513a70bcd92384395513322f1b801e7bf9c729Steve Block
205568513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (paginationStrut) {
205668513a70bcd92384395513322f1b801e7bf9c729Steve Block            // We are willing to propagate out to our parent block as long as we were at the top of the block prior
205768513a70bcd92384395513322f1b801e7bf9c729Steve Block            // to collapsing our margins, and as long as we didn't clear or move as a result of other pagination.
2058a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (atBeforeSideOfBlock && oldTop == logicalTopBeforeClear && !isPositioned() && !isTableCell()) {
205968513a70bcd92384395513322f1b801e7bf9c729Steve Block                // FIXME: Should really check if we're exceeding the page height before propagating the strut, but we don't
206068513a70bcd92384395513322f1b801e7bf9c729Steve Block                // have all the information to do so (the strut only has the remaining amount to push).  Gecko gets this wrong too
206168513a70bcd92384395513322f1b801e7bf9c729Steve Block                // and pushes to the next page anyway, so not too concerned about it.
2062a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                setPaginationStrut(logicalTopAfterClear + paginationStrut);
206368513a70bcd92384395513322f1b801e7bf9c729Steve Block                if (childRenderBlock)
206468513a70bcd92384395513322f1b801e7bf9c729Steve Block                    childRenderBlock->setPaginationStrut(0);
206568513a70bcd92384395513322f1b801e7bf9c729Steve Block            } else
2066a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                logicalTopAfterClear += paginationStrut;
206768513a70bcd92384395513322f1b801e7bf9c729Steve Block        }
206868513a70bcd92384395513322f1b801e7bf9c729Steve Block
206968513a70bcd92384395513322f1b801e7bf9c729Steve Block        // Similar to how we apply clearance.  Go ahead and boost height() to be the place where we're going to position the child.
2070a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalHeight(logicalHeight() + (logicalTopAfterClear - oldTop));
207168513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
207268513a70bcd92384395513322f1b801e7bf9c729Steve Block
2073a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalTopForChild(child, logicalTopAfterClear, ApplyLayoutDelta);
2074231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
2075a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Now we have a final top position.  See if it really does end up being different from our estimate.
2076a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (logicalTopAfterClear != logicalTopEstimate) {
2077231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (child->shrinkToAvoidFloats()) {
2078231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // The child's width depends on the line width.
2079231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // When the child shifts to clear an item, its width can
2080231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // change (because it has more available line width).
2081231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // So go ahead and mark the item as dirty.
2082231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            child->setChildNeedsLayout(true, false);
20838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
208468513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (childRenderBlock) {
208568513a70bcd92384395513322f1b801e7bf9c729Steve Block            if (!child->avoidsFloats() && childRenderBlock->containsFloats())
208668513a70bcd92384395513322f1b801e7bf9c729Steve Block                childRenderBlock->markAllDescendantsWithFloatsForLayout();
2087a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (!child->needsLayout())
2088a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                child->markForPaginationRelayoutIfNeeded();
208968513a70bcd92384395513322f1b801e7bf9c729Steve Block        }
209068513a70bcd92384395513322f1b801e7bf9c729Steve Block
2091231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Our guess was wrong. Make the child lay itself out again.
2092231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        child->layoutIfNeeded();
2093231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
20948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2095231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // We are no longer at the top of the block if we encounter a non-empty child.
2096231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // This has to be done after checking for clear, so that margins can be reset if a clear occurred.
2097bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (marginInfo.atBeforeSideOfBlock() && !child->isSelfCollapsingBlock())
2098bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        marginInfo.setAtBeforeSideOfBlock(false);
20998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2100a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Now place the child in the correct left position
2101a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    determineLogicalLeftPositionForChild(child);
21028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2103231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Update our height now that the child has been placed in the correct position.
2104a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalHeight(logicalHeight() + logicalHeightForChild(child));
2105bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (child->style()->marginAfterCollapse() == MSEPARATE) {
2106a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalHeight(logicalHeight() + marginAfterForChild(child));
2107231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        marginInfo.clearMargin();
2108231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
2109231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // If the child has overhanging floats that intrude into following siblings (or possibly out
2110231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // of this block), then the parent gets notified of the floats now.
211168513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (childRenderBlock && childRenderBlock->containsFloats())
2112a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        maxFloatLogicalBottom = max(maxFloatLogicalBottom, addOverhangingFloats(toRenderBlock(child), -child->logicalLeft(), -child->logicalTop(), !childNeededLayout));
21138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2114231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    IntSize childOffset(child->x() - oldRect.x(), child->y() - oldRect.y());
2115231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (childOffset.width() || childOffset.height()) {
2116231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        view()->addLayoutDelta(childOffset);
21178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2118231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // If the child moved, we have to repaint it as well as any floating/positioned
2119231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // descendants.  An exception is if we need a layout.  In this case, we know we're going to
2120231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // repaint ourselves (and the child) anyway.
2121231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (childHadLayout && !selfNeedsLayout() && child->checkForRepaintDuringLayout())
2122231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            child->repaintDuringLayoutIfMoved(oldRect);
2123231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
21248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2125231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!childHadLayout && child->checkForRepaintDuringLayout()) {
2126231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        child->repaint();
2127231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        child->repaintOverhangingFloats(true);
21288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
21298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
213068513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (paginated) {
213168513a70bcd92384395513322f1b801e7bf9c729Steve Block        // Check for an after page/column break.
21322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int newHeight = applyAfterBreak(child, logicalHeight(), marginInfo);
213368513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (newHeight != height())
2134bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setLogicalHeight(newHeight);
213568513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
213668513a70bcd92384395513322f1b801e7bf9c729Steve Block
2137231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    ASSERT(oldLayoutDelta == view()->layoutDelta());
21388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
21398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21402bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid RenderBlock::simplifiedNormalFlowLayout()
21418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
21422bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (childrenInline()) {
21432bde8e466a4451c7319e3a072d118917957d6554Steve Block        ListHashSet<RootInlineBox*> lineBoxes;
21442bde8e466a4451c7319e3a072d118917957d6554Steve Block        bool endOfInline = false;
21452bde8e466a4451c7319e3a072d118917957d6554Steve Block        RenderObject* o = bidiFirst(this, 0, false);
21462bde8e466a4451c7319e3a072d118917957d6554Steve Block        while (o) {
21472bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (!o->isPositioned() && (o->isReplaced() || o->isFloating())) {
21482bde8e466a4451c7319e3a072d118917957d6554Steve Block                o->layoutIfNeeded();
21492bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (toRenderBox(o)->inlineBoxWrapper()) {
21502bde8e466a4451c7319e3a072d118917957d6554Steve Block                    RootInlineBox* box = toRenderBox(o)->inlineBoxWrapper()->root();
21512bde8e466a4451c7319e3a072d118917957d6554Steve Block                    lineBoxes.add(box);
21522bde8e466a4451c7319e3a072d118917957d6554Steve Block                }
21532bde8e466a4451c7319e3a072d118917957d6554Steve Block            } else if (o->isText() || (o->isRenderInline() && !endOfInline))
21542bde8e466a4451c7319e3a072d118917957d6554Steve Block                o->setNeedsLayout(false);
21552bde8e466a4451c7319e3a072d118917957d6554Steve Block            o = bidiNext(this, o, 0, false, &endOfInline);
21562bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
21572bde8e466a4451c7319e3a072d118917957d6554Steve Block
21582bde8e466a4451c7319e3a072d118917957d6554Steve Block        // FIXME: Glyph overflow will get lost in this case, but not really a big deal.
21592bde8e466a4451c7319e3a072d118917957d6554Steve Block        GlyphOverflowAndFallbackFontsMap textBoxDataMap;
21602bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it != lineBoxes.end(); ++it) {
21612bde8e466a4451c7319e3a072d118917957d6554Steve Block            RootInlineBox* box = *it;
21622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap);
21632bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
21642bde8e466a4451c7319e3a072d118917957d6554Steve Block    } else {
21652bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (RenderBox* box = firstChildBox(); box; box = box->nextSiblingBox()) {
21662bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (!box->isPositioned())
21672bde8e466a4451c7319e3a072d118917957d6554Steve Block                box->layoutIfNeeded();
21682bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
21692bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
21702bde8e466a4451c7319e3a072d118917957d6554Steve Block}
21712bde8e466a4451c7319e3a072d118917957d6554Steve Block
21722bde8e466a4451c7319e3a072d118917957d6554Steve Blockbool RenderBlock::simplifiedLayout()
21732bde8e466a4451c7319e3a072d118917957d6554Steve Block{
21742bde8e466a4451c7319e3a072d118917957d6554Steve Block    if ((!posChildNeedsLayout() && !needsSimplifiedNormalFlowLayout()) || normalChildNeedsLayout() || selfNeedsLayout())
21758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
21768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21776b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
21782bde8e466a4451c7319e3a072d118917957d6554Steve Block
21792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (needsPositionedMovementLayout() && !tryLayoutDoingPositionedMovementOnly())
21802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return false;
21818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21822bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Lay out positioned descendants or objects that just need to recompute overflow.
21832bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (needsSimplifiedNormalFlowLayout())
21842bde8e466a4451c7319e3a072d118917957d6554Steve Block        simplifiedNormalFlowLayout();
21852bde8e466a4451c7319e3a072d118917957d6554Steve Block
21862bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Lay out our positioned objects if our positioned child bit is set.
21872bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (posChildNeedsLayout())
21882bde8e466a4451c7319e3a072d118917957d6554Steve Block        layoutPositionedObjects(false);
21898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2190f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Recompute our overflow information.
2191f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // FIXME: We could do better here by computing a temporary overflow object from layoutPositionedObjects and only
2192f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // updating our overflow if we either used to have overflow or if the new temporary object has overflow.
2193f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // For now just always recompute overflow.  This is no worse performance-wise than the old code that called rightmostPosition and
2194f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // lowestPosition on every relayout so it's not a regression.
2195f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    m_overflow.clear();
2196f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    computeOverflow(clientLogicalBottom(), true);
2197f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
2198635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    statePusher.pop();
2199f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
2200f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    updateLayerTransform();
22018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    updateScrollInfoAfterLayout();
22038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setNeedsLayout(false);
22058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
22068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
22078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::layoutPositionedObjects(bool relayoutChildren)
22098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2210f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!m_positionedObjects)
2211f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return;
2212f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
2213f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (hasColumns())
2214f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        view()->layoutState()->clearPaginationInformation(); // Positioned objects are not part of the column flow, so they don't paginate with the columns.
221568513a70bcd92384395513322f1b801e7bf9c729Steve Block
2216f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    RenderBox* r;
2217f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    Iterator end = m_positionedObjects->end();
2218f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
2219f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        r = *it;
2220f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the
2221f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // non-positioned block.  Rather than trying to detect all of these movement cases, we just always lay out positioned
2222f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // objects that are positioned implicitly like this.  Such objects are rare, and so in typical DHTML menu usage (where everything is
2223f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // positioned explicitly) this should not incur a performance penalty.
22242bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (relayoutChildren || (r->style()->hasStaticBlockPosition(isHorizontalWritingMode()) && r->parent() != this && r->parent()->isBlockFlow()))
2225f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            r->setChildNeedsLayout(true, false);
22268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2227f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.
2228f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (relayoutChildren && (r->style()->paddingStart().isPercent() || r->style()->paddingEnd().isPercent()))
2229f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            r->setPreferredLogicalWidthsDirty(true, false);
223068513a70bcd92384395513322f1b801e7bf9c729Steve Block
2231f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (!r->needsLayout())
2232f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            r->markForPaginationRelayoutIfNeeded();
2233f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
2234f05b935882198ccf7d81675736e3aeb089c5113aBen 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
2235f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // and we hit the available width constraint, the layoutIfNeeded() will catch it and do a full layout.
22362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (r->needsPositionedMovementLayoutOnly() && r->tryLayoutDoingPositionedMovementOnly())
22372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            r->setNeedsLayout(false);
2238f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        r->layoutIfNeeded();
22398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2240f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
2241f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (hasColumns())
2242f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        view()->layoutState()->m_columnInfo = columnInfo(); // FIXME: Kind of gross. We just put this back into the layout state so that pop() will work.
22438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
22448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::markPositionedObjectsForLayout()
22468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
22478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_positionedObjects) {
2248635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        RenderBox* r;
22498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Iterator end = m_positionedObjects->end();
22508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
22518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            r = *it;
22528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            r->setChildNeedsLayout(true);
22538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
22548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
22558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
22568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2257a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::markForPaginationRelayoutIfNeeded()
2258a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
2259a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ASSERT(!needsLayout());
2260a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (needsLayout())
2261a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
2262a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
22632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(logicalTop()) != pageLogicalOffset()))
2264a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setChildNeedsLayout(true, false);
2265a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
2266a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
22678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::repaintOverhangingFloats(bool paintAllDescendants)
22688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
22698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Repaint any overhanging floats (if we know we're the one to paint them).
227054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    // Otherwise, bail out.
227154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    if (!hasOverhangingFloats())
227254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        return;
22738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
227454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    // FIXME: Avoid disabling LayoutState. At the very least, don't disable it for floats originating
227554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    // in this block. Better yet would be to push extra state for the containers of other floats.
227654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    view()->disableLayoutState();
227754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
227854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    FloatingObjectSetIterator end = floatingObjectSet.end();
227954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
228054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        FloatingObject* r = *it;
228154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        // Only repaint the object if it is overhanging, is not in its own layer, and
228254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        // is our responsibility to paint (m_shouldPaint is set). When paintAllDescendants is true, the latter
228354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        // condition is replaced with being a descendant of us.
228454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        if (logicalBottomForFloat(r) > logicalHeight() && ((paintAllDescendants && r->m_renderer->isDescendantOf(this)) || r->m_shouldPaint) && !r->m_renderer->hasSelfPaintingLayer()) {
228554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block            r->m_renderer->repaint();
228654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block            r->m_renderer->repaintOverhangingFloats();
22878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
22888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
228954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    view()->enableLayoutState();
22908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
22918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
22928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paint(PaintInfo& paintInfo, int tx, int ty)
22938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2294635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    tx += x();
2295635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ty += y();
22968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    PaintPhase phase = paintInfo.phase;
22988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Check if we need to do anything at all.
23008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
23018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // paints the root's background.
2302635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!isRoot()) {
2303f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        IntRect overflowBox = visualOverflowRect();
23042bde8e466a4451c7319e3a072d118917957d6554Steve Block        flipForWritingMode(overflowBox);
23058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        overflowBox.inflate(maximalOutlineSize(paintInfo.phase));
23068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        overflowBox.move(tx, ty);
23078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!overflowBox.intersects(paintInfo.rect))
23088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
23098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
23108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
23118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool pushedClip = pushContentsClip(paintInfo, tx, ty);
23128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    paintObject(paintInfo, tx, ty);
23138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (pushedClip)
23148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        popContentsClip(paintInfo, phase, tx, ty);
23158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
23168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
23178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // z-index.  We paint after we painted the background/border, so that the scrollbars will
23188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // sit above the background/border.
2319ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.shouldPaintWithinRoot(this))
23208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        layer()->paintOverflowControls(paintInfo.context, tx, ty, paintInfo.rect);
23218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
23228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
23238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::paintColumnRules(PaintInfo& paintInfo, int tx, int ty)
23248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
2325dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    const Color& ruleColor = style()->visitedDependentColor(CSSPropertyWebkitColumnRuleColor);
23268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool ruleTransparent = style()->columnRuleIsTransparent();
23278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    EBorderStyle ruleStyle = style()->columnRuleStyle();
23288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int ruleWidth = style()->columnRuleWidth();
23298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int colGap = columnGap();
23308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent && ruleWidth <= colGap;
23318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!renderRule)
23328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
23338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
23348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // We need to do multiple passes, breaking up our child painting into strips.
23355abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    ColumnInfo* colInfo = columnInfo();
233668513a70bcd92384395513322f1b801e7bf9c729Steve Block    unsigned colCount = columnCount(colInfo);
23372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int currLogicalLeftOffset = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth();
23382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int ruleAdd = logicalLeftOffsetForContent();
23392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int ruleLogicalLeft = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth();
23408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    for (unsigned i = 0; i < colCount; i++) {
234168513a70bcd92384395513322f1b801e7bf9c729Steve Block        IntRect colRect = columnRectAt(colInfo, i);
23428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
23432bde8e466a4451c7319e3a072d118917957d6554Steve Block        int inlineDirectionSize = isHorizontalWritingMode() ? colRect.width() : colRect.height();
23442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
23458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // Move to the next position.
2346a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->isLeftToRightDirection()) {
23472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            ruleLogicalLeft += inlineDirectionSize + colGap / 2;
23482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalLeftOffset += inlineDirectionSize + colGap;
23498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else {
23502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            ruleLogicalLeft -= (inlineDirectionSize + colGap / 2);
23512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalLeftOffset -= (inlineDirectionSize + colGap);
23528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
23538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
23548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // Now paint the column rule.
23558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (i < colCount - 1) {
23562bde8e466a4451c7319e3a072d118917957d6554Steve Block            int ruleLeft = isHorizontalWritingMode() ? tx + ruleLogicalLeft - ruleWidth / 2 + ruleAdd : tx + borderBefore() + paddingBefore();
23572bde8e466a4451c7319e3a072d118917957d6554Steve Block            int ruleRight = isHorizontalWritingMode() ? ruleLeft + ruleWidth : ruleLeft + contentWidth();
23582bde8e466a4451c7319e3a072d118917957d6554Steve Block            int ruleTop = isHorizontalWritingMode() ? ty + borderTop() + paddingTop() : ty + ruleLogicalLeft - ruleWidth / 2 + ruleAdd;
23592bde8e466a4451c7319e3a072d118917957d6554Steve Block            int ruleBottom = isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleWidth;
23602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            drawLineForBoxSide(paintInfo.context, ruleLeft, ruleTop, ruleRight, ruleBottom,
2361a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                               style()->isLeftToRightDirection() ? BSLeft : BSRight, ruleColor, ruleStyle, 0, 0);
23628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
23638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
23642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        ruleLogicalLeft = currLogicalLeftOffset;
23658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
23668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
23678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
23688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::paintColumnContents(PaintInfo& paintInfo, int tx, int ty, bool paintingFloats)
23698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
23708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We need to do multiple passes, breaking up our child painting into strips.
23718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GraphicsContext* context = paintInfo.context;
23725abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    ColumnInfo* colInfo = columnInfo();
237368513a70bcd92384395513322f1b801e7bf9c729Steve Block    unsigned colCount = columnCount(colInfo);
23746c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (!colCount)
23756c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        return;
23762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int currLogicalTopOffset = 0;
23778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < colCount; i++) {
23788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // For each rect, we clip to the rect, and then we adjust our coords.
237968513a70bcd92384395513322f1b801e7bf9c729Steve Block        IntRect colRect = columnRectAt(colInfo, i);
23802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        flipForWritingMode(colRect);
23812bde8e466a4451c7319e3a072d118917957d6554Steve Block        int logicalLeftOffset = (isHorizontalWritingMode() ? colRect.x() : colRect.y()) - logicalLeftOffsetForContent();
23822bde8e466a4451c7319e3a072d118917957d6554Steve Block        IntSize offset = isHorizontalWritingMode() ? IntSize(logicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, logicalLeftOffset);
23838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        colRect.move(tx, ty);
23848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PaintInfo info(paintInfo);
23858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        info.rect.intersect(colRect);
23868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2387e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        if (!info.rect.isEmpty()) {
2388e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            context->save();
2389e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block
2390e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            // Each strip pushes a clip, since column boxes are specified as being
2391e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            // like overflow:hidden.
2392e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            context->clip(colRect);
23932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2394e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            // Adjust our x and y when painting.
23952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int finalX = tx + offset.width();
23962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int finalY = ty + offset.height();
2397e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            if (paintingFloats)
2398e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block                paintFloats(info, finalX, finalY, paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip);
2399e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            else
2400e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block                paintContents(info, finalX, finalY);
24018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2402e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            context->restore();
2403e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        }
24042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
24052bde8e466a4451c7319e3a072d118917957d6554Steve Block        int blockDelta = (isHorizontalWritingMode() ? colRect.height() : colRect.width());
24062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (style()->isFlippedBlocksWritingMode())
24072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalTopOffset += blockDelta;
24088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        else
24092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalTopOffset -= blockDelta;
24108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
24118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
24128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintContents(PaintInfo& paintInfo, int tx, int ty)
24148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
24158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Avoid painting descendants of the root element when stylesheets haven't loaded.  This eliminates FOUC.
24168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
24178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // will do a full repaint().
24182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (document()->didLayoutWithPendingStylesheets() && !isRenderView())
24198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
24208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childrenInline())
24228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_lineBoxes.paint(this, paintInfo, tx, ty);
24238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
24248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        paintChildren(paintInfo, tx, ty);
24258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
24268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
24288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
24298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
24308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;
24318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We don't paint our own background, but we do let the kids paint their backgrounds.
24338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    PaintInfo info(paintInfo);
24348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    info.phase = newPhase;
2435ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    info.updatePaintingRootForChildren(this);
24365ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
243768513a70bcd92384395513322f1b801e7bf9c729Steve Block    // FIXME: Paint-time pagination is obsolete and is now only used by embedded WebViews inside AppKit
243868513a70bcd92384395513322f1b801e7bf9c729Steve Block    // NSViews.  Do not add any more code for this.
24395ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    RenderView* renderView = view();
244068513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool usePrintRect = !renderView->printRect().isEmpty();
24415ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
2442635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
24438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Check for page-break-before: always, and if it's set, break and bail.
244468513a70bcd92384395513322f1b801e7bf9c729Steve Block        bool checkBeforeAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakBefore() == PBALWAYS);
2445545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (checkBeforeAlways
2446dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            && (ty + child->y()) > paintInfo.rect.y()
24472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            && (ty + child->y()) < paintInfo.rect.maxY()) {
2448635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            view()->setBestTruncatedAt(ty + child->y(), this, true);
24498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
24508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
24518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24525ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        if (!child->isFloating() && child->isReplaced() && usePrintRect && child->height() <= renderView->printRect().height()) {
24535ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            // Paginate block-level replaced elements.
24542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (ty + child->y() + child->height() > renderView->printRect().maxY()) {
24555ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                if (ty + child->y() < renderView->truncatedAt())
24565ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                    renderView->setBestTruncatedAt(ty + child->y(), child);
24575ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                // If we were able to truncate, don't paint.
24585ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                if (ty + child->y() >= renderView->truncatedAt())
24595ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                    break;
24605ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            }
24615ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        }
24625ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
246328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        IntPoint childPoint = flipForWritingMode(child, IntPoint(tx, ty), ParentToChildFlippingAdjustment);
24648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (!child->hasSelfPaintingLayer() && !child->isFloating())
2465e14391e94c850b8bd03680c23b38978db68687a8John Reck            child->paint(info, childPoint.x(), childPoint.y());
24668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Check for page-break-after: always, and if it's set, break and bail.
246868513a70bcd92384395513322f1b801e7bf9c729Steve Block        bool checkAfterAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakAfter() == PBALWAYS);
2469545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (checkAfterAlways
2470dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            && (ty + child->y() + child->height()) > paintInfo.rect.y()
24712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            && (ty + child->y() + child->height()) < paintInfo.rect.maxY()) {
2472bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            view()->setBestTruncatedAt(ty + child->y() + child->height() + max(0, child->collapsedMarginAfter()), this, true);
24738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
24748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
24758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
24768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
24778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2478635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::paintCaret(PaintInfo& paintInfo, int tx, int ty, CaretType type)
24798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
248068513a70bcd92384395513322f1b801e7bf9c729Steve Block    SelectionController* selection = type == CursorCaret ? frame()->selection() : frame()->page()->dragCaretController();
2481635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
24825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Paint the caret if the SelectionController says so or if caret browsing is enabled
2483545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    bool caretBrowsing = frame()->settings() && frame()->settings()->caretBrowsingEnabled();
2484635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderObject* caretPainter = selection->caretRenderer();
24855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (caretPainter == this && (selection->isContentEditable() || caretBrowsing)) {
2486635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // Convert the painting offset into the local coordinate system of this renderer,
2487635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // to match the localCaretRect computed by the SelectionController
2488635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        offsetForContents(tx, ty);
2489635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
24908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (type == CursorCaret)
2491545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            frame()->selection()->paintCaret(paintInfo.context, tx, ty, paintInfo.rect);
24928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
249368513a70bcd92384395513322f1b801e7bf9c729Steve Block            frame()->selection()->paintDragCaret(paintInfo.context, tx, ty, paintInfo.rect);
24948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
24958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
24968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintObject(PaintInfo& paintInfo, int tx, int ty)
24988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
24998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    PaintPhase paintPhase = paintInfo.phase;
25008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 1. paint background, borders etc
2502a15d30f54c6edc68da7e82c198b5916dd023ac4dNicolas Roard    if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground
2503a15d30f54c6edc68da7e82c198b5916dd023ac4dNicolas Roard#if PLATFORM(ANDROID)
2504a15d30f54c6edc68da7e82c198b5916dd023ac4dNicolas Roard         || paintPhase == PaintPhaseBlockBackgroundDecorations
2505a15d30f54c6edc68da7e82c198b5916dd023ac4dNicolas Roard#endif
2506a15d30f54c6edc68da7e82c198b5916dd023ac4dNicolas Roard        ) && style()->visibility() == VISIBLE) {
25078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (hasBoxDecorations())
25088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            paintBoxDecorations(paintInfo, tx, ty);
25098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (hasColumns())
25108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            paintColumnRules(paintInfo, tx, ty);
25118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
25128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintPhase == PaintPhaseMask && style()->visibility() == VISIBLE) {
25148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        paintMask(paintInfo, tx, ty);
25158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
25168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
25178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We're done.  We don't bother painting any children.
25198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintPhase == PaintPhaseBlockBackground)
25208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
25218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2522dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).
25238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int scrolledX = tx;
25248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int scrolledY = ty;
2525dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (hasOverflowClip()) {
2526dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        IntSize offset = layer()->scrolledContentOffset();
2527dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        scrolledX -= offset.width();
2528dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        scrolledY -= offset.height();
2529dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
25308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 2. paint contents
25328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintPhase != PaintPhaseSelfOutline) {
25338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (hasColumns())
25348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            paintColumnContents(paintInfo, scrolledX, scrolledY);
25358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
25368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            paintContents(paintInfo, scrolledX, scrolledY);
25378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
25388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 3. paint selection
25408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Make this work with multi column layouts.  For now don't fill gaps.
25418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool isPrinting = document()->printing();
25428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!isPrinting && !hasColumns())
25438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        paintSelection(paintInfo, scrolledX, scrolledY); // Fill in gaps in selection on lines and between blocks.
25448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 4. paint floats.
2546635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip) {
25478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (hasColumns())
25488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            paintColumnContents(paintInfo, scrolledX, scrolledY, true);
25498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
25508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            paintFloats(paintInfo, scrolledX, scrolledY, paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip);
25518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
25528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 5. paint outline.
2554635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
2555dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        paintOutline(paintInfo.context, tx, ty, width(), height());
25568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 6. paint continuation outlines.
2558635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
2559e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        RenderInline* inlineCont = inlineElementContinuation();
2560e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        if (inlineCont && inlineCont->hasOutline() && inlineCont->style()->visibility() == VISIBLE) {
2561e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            RenderInline* inlineRenderer = toRenderInline(inlineCont->node()->renderer());
2562e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            RenderBlock* cb = containingBlock();
2563e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
2564e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            bool inlineEnclosedInSelfPaintingLayer = false;
2565e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            for (RenderBoxModelObject* box = inlineRenderer; box != cb; box = box->parent()->enclosingBoxModelObject()) {
2566e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                if (box->hasSelfPaintingLayer()) {
2567e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                    inlineEnclosedInSelfPaintingLayer = true;
2568e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                    break;
2569e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                }
2570e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            }
2571e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
2572e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            if (!inlineEnclosedInSelfPaintingLayer)
2573e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                cb->addContinuationWithOutline(inlineRenderer);
25748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            else if (!inlineRenderer->firstLineBox())
25758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                inlineRenderer->paintOutline(paintInfo.context, tx - x() + inlineRenderer->containingBlock()->x(),
25768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                                             ty - y() + inlineRenderer->containingBlock()->y());
25778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
25788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        paintContinuationOutlines(paintInfo, tx, ty);
25798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
25808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 7. paint caret.
25828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
25838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // then paint the caret.
2584635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (paintPhase == PaintPhaseForeground) {
2585635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        paintCaret(paintInfo, scrolledX, scrolledY, CursorCaret);
2586635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        paintCaret(paintInfo, scrolledX, scrolledY, DragCaret);
25878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
25888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
25898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25902fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockIntPoint RenderBlock::flipFloatForWritingMode(const FloatingObject* child, const IntPoint& point) const
25912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
25922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!style()->isFlippedBlocksWritingMode())
25932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return point;
25942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
25952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // This is similar to the ParentToChildFlippingAdjustment in RenderBox::flipForWritingMode.  We have to subtract out our left/top offsets twice, since
25962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // it's going to get added back in.  We hide this complication here so that the calling code looks normal for the unflipped
25972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // case.
25982bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
25992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return IntPoint(point.x(), point.y() + height() - child->renderer()->height() - 2 * yPositionForFloatIncludingMargin(child));
26002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return IntPoint(point.x() + width() - child->width() - 2 * xPositionForFloatIncludingMargin(child), point.y());
26012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
26022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
26038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintFloats(PaintInfo& paintInfo, int tx, int ty, bool preservePhase)
26048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
26058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_floatingObjects)
26068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
26078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
260881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
260981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator end = floatingObjectSet.end();
261081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
261181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObject* r = *it;
26128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Only paint the object if our m_shouldPaint flag is set.
26138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
26148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            PaintInfo currentPaintInfo(paintInfo);
26158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
26162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            IntPoint childPoint = flipFloatForWritingMode(r, IntPoint(tx + xPositionForFloatIncludingMargin(r) - r->m_renderer->x(), ty + yPositionForFloatIncludingMargin(r) - r->m_renderer->y()));
2617e14391e94c850b8bd03680c23b38978db68687a8John Reck            r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
26188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!preservePhase) {
26198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                currentPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
2620e14391e94c850b8bd03680c23b38978db68687a8John Reck                r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
26218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                currentPaintInfo.phase = PaintPhaseFloat;
2622e14391e94c850b8bd03680c23b38978db68687a8John Reck                r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
26238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                currentPaintInfo.phase = PaintPhaseForeground;
2624e14391e94c850b8bd03680c23b38978db68687a8John Reck                r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
26258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                currentPaintInfo.phase = PaintPhaseOutline;
2626e14391e94c850b8bd03680c23b38978db68687a8John Reck                r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
26278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
26288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
26298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
26308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
26318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintEllipsisBoxes(PaintInfo& paintInfo, int tx, int ty)
26338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2634ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (!paintInfo.shouldPaintWithinRoot(this) || !firstLineBox())
26358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
26368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->visibility() == VISIBLE && paintInfo.phase == PaintPhaseForeground) {
26388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We can check the first box and last box and avoid painting if we don't
26398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // intersect.
26408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        int yPos = ty + firstLineBox()->y();
2641bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        int h = lastLineBox()->y() + lastLineBox()->logicalHeight() - firstLineBox()->y();
26422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (yPos >= paintInfo.rect.maxY() || yPos + h <= paintInfo.rect.y())
26438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
26448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // See if our boxes intersect with the dirty rect.  If so, then we paint
26468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // them.  Note that boxes can easily overlap, so we can't make any assumptions
26478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // based off positions of our first line box or our last line box.
26488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
26498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            yPos = ty + curr->y();
2650bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            h = curr->logicalHeight();
26512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (curr->ellipsisBox() && yPos < paintInfo.rect.maxY() && yPos + h > paintInfo.rect.y())
26522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                curr->paintEllipsisBox(paintInfo, tx, ty, curr->lineTop(), curr->lineBottom());
26538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
26548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
26558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
26568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2657e78cbe89e6f337f2f1fe40315be88f742b547151Steve BlockRenderInline* RenderBlock::inlineElementContinuation() const
2658e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block{
2659cad810f21b803229eb11403f9209855525a25d57Steve Block    RenderBoxModelObject* continuation = this->continuation();
2660cad810f21b803229eb11403f9209855525a25d57Steve Block    return continuation && continuation->isInline() ? toRenderInline(continuation) : 0;
2661e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block}
2662e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block
2663e78cbe89e6f337f2f1fe40315be88f742b547151Steve BlockRenderBlock* RenderBlock::blockElementContinuation() const
2664e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block{
2665cad810f21b803229eb11403f9209855525a25d57Steve Block    RenderBoxModelObject* currentContinuation = continuation();
2666cad810f21b803229eb11403f9209855525a25d57Steve Block    if (!currentContinuation || currentContinuation->isInline())
2667e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        return 0;
2668cad810f21b803229eb11403f9209855525a25d57Steve Block    RenderBlock* nextContinuation = toRenderBlock(currentContinuation);
2669e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (nextContinuation->isAnonymousBlock())
2670e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        return nextContinuation->blockElementContinuation();
2671545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return nextContinuation;
2672e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block}
2673e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block
2674635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic ContinuationOutlineTableMap* continuationOutlineTable()
26758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2676635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ());
26778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return &table;
26788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
26798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::addContinuationWithOutline(RenderInline* flow)
26818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
26828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We can't make this work if the inline is in a layer.  We'll just rely on the broken
26838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // way of painting.
2684e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    ASSERT(!flow->layer() && !flow->isInlineElementContinuation());
26858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2686635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ContinuationOutlineTableMap* table = continuationOutlineTable();
26878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ListHashSet<RenderInline*>* continuations = table->get(this);
26888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!continuations) {
26898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        continuations = new ListHashSet<RenderInline*>;
26908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        table->set(this, continuations);
26918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
26928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    continuations->add(flow);
26948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
26958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
269681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochbool RenderBlock::paintsContinuationOutline(RenderInline* flow)
269781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
269881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ContinuationOutlineTableMap* table = continuationOutlineTable();
269981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (table->isEmpty())
270081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return false;
270181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
270281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ListHashSet<RenderInline*>* continuations = table->get(this);
270381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!continuations)
270481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return false;
270581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
270681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return continuations->contains(flow);
270781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
270881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
27098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintContinuationOutlines(PaintInfo& info, int tx, int ty)
27108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2711635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ContinuationOutlineTableMap* table = continuationOutlineTable();
27128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (table->isEmpty())
27138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
27148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ListHashSet<RenderInline*>* continuations = table->get(this);
27168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!continuations)
27178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
27188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Paint each continuation outline.
27208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ListHashSet<RenderInline*>::iterator end = continuations->end();
27218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    for (ListHashSet<RenderInline*>::iterator it = continuations->begin(); it != end; ++it) {
27228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Need to add in the coordinates of the intervening blocks.
27238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderInline* flow = *it;
27248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderBlock* block = flow->containingBlock();
27258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for ( ; block && block != this; block = block->containingBlock()) {
2726635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            tx += block->x();
2727635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            ty += block->y();
27288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
27298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(block);
27308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        flow->paintOutline(info.context, tx, ty);
27318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
27328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Delete
27348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    delete continuations;
27358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    table->remove(this);
27368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
27378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::shouldPaintSelectionGaps() const
27398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
27408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot();
27418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
27428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::isSelectionRoot() const
27448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
27458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!node())
27468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
27478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Eventually tables should have to learn how to fill gaps between cells, at least in simple non-spanning cases.
27498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isTable())
27508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
27518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isBody() || isRoot() || hasOverflowClip() || isRelPositioned() ||
27538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        isFloatingOrPositioned() || isTableCell() || isInlineBlockOrInlineTable() || hasTransform() ||
275428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        hasReflection() || hasMask() || isWritingModeRoot())
27558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
27568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (view() && view()->selectionStart()) {
27588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        Node* startElement = view()->selectionStart()->node();
27598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (startElement && startElement->rootEditableElement() == node())
27608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
27618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
27628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
27648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
27658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2766643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockGapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer)
27678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
27688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!needsLayout());
27698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!shouldPaintSelectionGaps())
27718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return GapRects();
27728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2773643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // FIXME: this is broken with transforms
2774643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
2775643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    mapLocalToContainer(repaintContainer, false, false, transformState);
2776dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    IntPoint offsetFromRepaintContainer = roundedIntPoint(transformState.mappedPoint());
2777643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
27788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (hasOverflowClip())
2779dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        offsetFromRepaintContainer -= layer()->scrolledContentOffset();
27808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2781635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int lastTop = 0;
278228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int lastLeft = logicalLeftSelectionOffset(this, lastTop);
278328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int lastRight = logicalRightSelectionOffset(this, lastTop);
27848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
278528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return selectionGaps(this, offsetFromRepaintContainer, IntSize(), lastTop, lastLeft, lastRight);
27868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
27878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
27898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
27908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (shouldPaintSelectionGaps() && paintInfo.phase == PaintPhaseForeground) {
2791635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        int lastTop = 0;
279228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        int lastLeft = logicalLeftSelectionOffset(this, lastTop);
279328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        int lastRight = logicalRightSelectionOffset(this, lastTop);
27948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        paintInfo.context->save();
279528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        IntRect gapRectsBounds = selectionGaps(this, IntPoint(tx, ty), IntSize(), lastTop, lastLeft, lastRight, &paintInfo);
2796643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (!gapRectsBounds.isEmpty()) {
2797643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (RenderLayer* layer = enclosingLayer()) {
2798d0825bca7fe65beaee391d30da42e937db621564Steve Block                gapRectsBounds.move(IntSize(-tx, -ty));
2799d0825bca7fe65beaee391d30da42e937db621564Steve Block                if (!hasLayer()) {
28006b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                    IntRect localBounds(gapRectsBounds);
28016b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                    flipForWritingMode(localBounds);
28026b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                    gapRectsBounds = localToContainerQuad(FloatRect(localBounds), layer->renderer()).enclosingBoundingBox();
2803692e5dbf12901edacf14812a6fae25462920af42Steve Block                    gapRectsBounds.move(layer->scrolledContentOffset());
2804d0825bca7fe65beaee391d30da42e937db621564Steve Block                }
2805643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                layer->addBlockSelectionGapsBounds(gapRectsBounds);
2806643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            }
2807643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
28088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        paintInfo.context->restore();
28098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
28108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
28118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
281228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic void clipOutPositionedObjects(const PaintInfo* paintInfo, const IntPoint& offset, RenderBlock::PositionedObjectsListHashSet* positionedObjects)
28138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
28148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!positionedObjects)
28158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
28168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2817e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    RenderBlock::PositionedObjectsListHashSet::const_iterator end = positionedObjects->end();
2818e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
2819635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        RenderBox* r = *it;
282028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r->y(), r->width(), r->height()));
28218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
28228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
28238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
282428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic int blockDirectionOffset(RenderBlock* rootBlock, const IntSize& offsetFromRootBlock)
282528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{
28262bde8e466a4451c7319e3a072d118917957d6554Steve Block    return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.height() : offsetFromRootBlock.width();
282728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu}
282828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
282928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic int inlineDirectionOffset(RenderBlock* rootBlock, const IntSize& offsetFromRootBlock)
283028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{
28312bde8e466a4451c7319e3a072d118917957d6554Steve Block    return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.width() : offsetFromRootBlock.height();
283228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu}
283328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
283428040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuIntRect RenderBlock::logicalRectToPhysicalRect(const IntPoint& rootBlockPhysicalPosition, const IntRect& logicalRect)
283528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{
283628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    IntRect result;
28372bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
283828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        result = logicalRect;
283928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    else
284028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        result = IntRect(logicalRect.y(), logicalRect.x(), logicalRect.height(), logicalRect.width());
284128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    flipForWritingMode(result);
284228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    result.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
284328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return result;
284428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu}
284528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
284628040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuGapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
284728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                    int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo)
28488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
28498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore.
28508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Clip out floating and positioned objects when painting selection gaps.
28518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintInfo) {
28528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Note that we don't clip out overflow for positioned objects.  We just stick to the border box.
285328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        IntRect flippedBlockRect = IntRect(offsetFromRootBlock.width(), offsetFromRootBlock.height(), width(), height());
285428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        rootBlock->flipForWritingMode(flippedBlockRect);
285528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        flippedBlockRect.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
285681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), m_positionedObjects.get());
28578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (isBody() || isRoot()) // The <body> must make sure to examine its containingBlock's positioned objects.
28588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock())
285981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                clipOutPositionedObjects(paintInfo, IntPoint(cb->x(), cb->y()), cb->m_positionedObjects.get()); // FIXME: Not right for flipped writing modes.
28608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_floatingObjects) {
286181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
286281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObjectSetIterator end = floatingObjectSet.end();
286381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
286481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                FloatingObject* r = *it;
28652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                IntRect floatBox = IntRect(offsetFromRootBlock.width() + xPositionForFloatIncludingMargin(r),
28662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                                           offsetFromRootBlock.height() + yPositionForFloatIncludingMargin(r),
286728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                           r->m_renderer->width(), r->m_renderer->height());
286828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                rootBlock->flipForWritingMode(floatBox);
286928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                floatBox.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
287028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                paintInfo->context->clipOut(floatBox);
28718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
28728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
28738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
28748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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
28768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // fixed).
28778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GapRects result;
28788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!isBlockFlow()) // FIXME: Make multi-column selection gap filling work someday.
28798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return result;
28808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28815af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (hasColumns() || hasTransform() || style()->columnSpan()) {
28828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: We should learn how to gap fill multiple columns and transforms eventually.
288328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
288428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight());
288528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight());
28868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return result;
28878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
28888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childrenInline())
289028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        result = inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
28918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
289228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
28938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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.
28958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd))
289628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
289728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                             logicalHeight(), paintInfo));
28988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
28998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
29008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
290128040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuGapRects RenderBlock::inlineSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
290228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                          int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo)
29038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
29048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GapRects result;
29058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool containsStart = selectionState() == SelectionStart || selectionState() == SelectionBoth;
29078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!firstLineBox()) {
29098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (containsStart) {
291028040489d744e0c5d475a88663056c9040ed5320Teng-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
29118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // case.
291228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
291328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight());
291428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight());
29158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
29168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return result;
29178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
29188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RootInlineBox* lastSelectedLine = 0;
29208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RootInlineBox* curr;
29218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (curr = firstRootBox(); curr && !curr->hasSelectedChildren(); curr = curr->nextRootBox()) { }
29228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Now paint the gaps for the lines.
29248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (; curr && curr->hasSelectedChildren(); curr = curr->nextRootBox()) {
29258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int selTop =  curr->selectionTop();
29268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int selHeight = curr->selectionHeight();
29278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!containsStart && !lastSelectedLine &&
29298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            selectionState() != SelectionStart && selectionState() != SelectionBoth)
293028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
293128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                                 selTop, paintInfo));
293228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
293328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        IntRect logicalRect(curr->logicalLeft(), selTop, curr->logicalWidth(), selTop + selHeight);
29342bde8e466a4451c7319e3a072d118917957d6554Steve Block        logicalRect.move(isHorizontalWritingMode() ? offsetFromRootBlock : IntSize(offsetFromRootBlock.height(), offsetFromRootBlock.width()));
293528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        IntRect physicalRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect);
29362bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!paintInfo || (isHorizontalWritingMode() && physicalRect.y() < paintInfo->rect.maxY() && physicalRect.maxY() > paintInfo->rect.y())
29372bde8e466a4451c7319e3a072d118917957d6554Steve Block            || (!isHorizontalWritingMode() && physicalRect.x() < paintInfo->rect.maxX() && physicalRect.maxX() > paintInfo->rect.x()))
293828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            result.unite(curr->lineSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, selTop, selHeight, paintInfo));
29398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        lastSelectedLine = curr;
29418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
29428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (containsStart && !lastSelectedLine)
29448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // VisibleSelection must start just after our last line.
29458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        lastSelectedLine = lastRootBox();
29468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (lastSelectedLine && selectionState() != SelectionEnd && selectionState() != SelectionBoth) {
29488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Go ahead and update our lastY to be the bottom of the last selected line.
294928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + lastSelectedLine->selectionBottom();
295028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
295128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        lastLogicalRight = logicalRightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
29528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
29538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
29548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
29558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
295628040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuGapRects RenderBlock::blockSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
295728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                         int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo)
29588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
29598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GapRects result;
29608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Go ahead and jump right to the first block child that contains some selected objects.
2962635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderBox* curr;
2963635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    for (curr = firstChildBox(); curr && curr->selectionState() == SelectionNone; curr = curr->nextSiblingBox()) { }
29648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2965635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    for (bool sawSelectionEnd = false; curr && !sawSelectionEnd; curr = curr->nextSiblingBox()) {
29668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        SelectionState childState = curr->selectionState();
29678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (childState == SelectionBoth || childState == SelectionEnd)
29688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            sawSelectionEnd = true;
29698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (curr->isFloatingOrPositioned())
29718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue; // We must be a normal flow object in order to even be considered.
29728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (curr->isRelPositioned() && curr->hasLayer()) {
29748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // If the relposition offset is anything other than 0, then treat this just like an absolute positioned element.
29758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Just disregard it completely.
2976635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            IntSize relOffset = curr->layer()->relativePositionOffset();
2977635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (relOffset.width() || relOffset.height())
29788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
29798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
29808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTable(); // FIXME: Eventually we won't special-case table like this.
29828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool fillBlockGaps = paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone);
29838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (fillBlockGaps) {
29848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We need to fill the vertical gap above this object.
29858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (childState == SelectionEnd || childState == SelectionInside)
29868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Fill the gap above the object.
298728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
298828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                                     curr->logicalTop(), paintInfo));
29898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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*
29918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // our object.  We know this if the selection did not end inside our object.
29928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (paintsOwnSelection && (childState == SelectionStart || sawSelectionEnd))
29938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                childState = SelectionNone;
29948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Fill side gaps on this object based off its state.
29968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            bool leftGap, rightGap;
299728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            getSelectionGapInfo(childState, leftGap, rightGap);
29988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (leftGap)
300028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                result.uniteLeft(logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalLeft(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
30018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (rightGap)
300228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalRight(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
30038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
300428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            // Update lastLogicalTop to be just underneath the object.  lastLogicalLeft and lastLogicalRight extend as far as
30058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // they can without bumping into floating or positioned objects.  Ideally they will go right up
30068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // to the border of the root selection block.
300728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + curr->logicalBottom();
300828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logicalBottom());
300928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logicalBottom());
30108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (childState != SelectionNone)
30118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We must be a block that has some selected object inside it.  Go ahead and recur.
301228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            result.unite(toRenderBlock(curr)->selectionGaps(rootBlock, rootBlockPhysicalPosition, IntSize(offsetFromRootBlock.width() + curr->x(), offsetFromRootBlock.height() + curr->y()),
301328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                                            lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo));
30148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
30158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
30168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
30178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
301828040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuIntRect RenderBlock::blockSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
301928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                       int lastLogicalTop, int lastLogicalLeft, int lastLogicalRight, int logicalBottom, const PaintInfo* paintInfo)
30208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
302128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int logicalTop = lastLogicalTop;
302228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int logicalHeight = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalBottom - logicalTop;
302328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (logicalHeight <= 0)
30248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return IntRect();
30258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
30268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Get the selection offsets for the bottom of the gap
302728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int logicalLeft = max(lastLogicalLeft, logicalLeftSelectionOffset(rootBlock, logicalBottom));
302828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int logicalRight = min(lastLogicalRight, logicalRightSelectionOffset(rootBlock, logicalBottom));
302928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int logicalWidth = logicalRight - logicalLeft;
303028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (logicalWidth <= 0)
30318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return IntRect();
30328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
303328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(logicalLeft, logicalTop, logicalWidth, logicalHeight));
30348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintInfo)
3035643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        paintInfo->context->fillRect(gapRect, selectionBackgroundColor(), style()->colorSpace());
30368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return gapRect;
30378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
30388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
303928040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuIntRect RenderBlock::logicalLeftSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
304028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                             RenderObject* selObj, int logicalLeft, int logicalTop, int logicalHeight, const PaintInfo* paintInfo)
30418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
304228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
304328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalLeft = max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight));
304428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalRight = min(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalLeft, min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight)));
304528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
304628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (rootBlockLogicalWidth <= 0)
30478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return IntRect();
30488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
304928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
30508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintInfo)
3051643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
30528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return gapRect;
30538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
30548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
305528040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuIntRect RenderBlock::logicalRightSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
305628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                              RenderObject* selObj, int logicalRight, int logicalTop, int logicalHeight, const PaintInfo* paintInfo)
30578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
305828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
305928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalLeft = max(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalRight, max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight)));
306028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalRight = min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight));
306128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
306228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (rootBlockLogicalWidth <= 0)
30638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return IntRect();
30648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
306528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
30668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintInfo)
3067643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
30688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return gapRect;
30698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
30708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
307128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuvoid RenderBlock::getSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap)
30728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3073a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool ltr = style()->isLeftToRightDirection();
30748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    leftGap = (state == RenderObject::SelectionInside) ||
30758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project              (state == RenderObject::SelectionEnd && ltr) ||
30768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project              (state == RenderObject::SelectionStart && !ltr);
30778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    rightGap = (state == RenderObject::SelectionInside) ||
30788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project               (state == RenderObject::SelectionStart && ltr) ||
30798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project               (state == RenderObject::SelectionEnd && !ltr);
30808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
30818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
308228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuint RenderBlock::logicalLeftSelectionOffset(RenderBlock* rootBlock, int position)
30838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
308428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int logicalLeft = logicalLeftOffsetForLine(position, false);
308528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (logicalLeft == logicalLeftOffsetForContent()) {
30868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (rootBlock != this)
30878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // The border can potentially be further extended by our containingBlock().
308828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            return containingBlock()->logicalLeftSelectionOffset(rootBlock, position + logicalTop());
308928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        return logicalLeft;
309028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    } else {
30918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderBlock* cb = this;
30928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (cb != rootBlock) {
309328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            logicalLeft += cb->logicalLeft();
30948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            cb = cb->containingBlock();
30958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
30968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
309728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return logicalLeft;
30988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
30998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
310028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuint RenderBlock::logicalRightSelectionOffset(RenderBlock* rootBlock, int position)
31018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
310228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int logicalRight = logicalRightOffsetForLine(position, false);
310328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (logicalRight == logicalRightOffsetForContent()) {
31048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (rootBlock != this)
31058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // The border can potentially be further extended by our containingBlock().
310628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            return containingBlock()->logicalRightSelectionOffset(rootBlock, position + logicalTop());
310728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        return logicalRight;
310828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    } else {
31098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderBlock* cb = this;
31108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (cb != rootBlock) {
311128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            logicalRight += cb->logicalLeft();
31128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            cb = cb->containingBlock();
31138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
31148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
311528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return logicalRight;
31168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
31178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3118635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::insertPositionedObject(RenderBox* o)
31198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
31208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Create the list of special objects if we don't aleady have one
31218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_positionedObjects)
312281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_positionedObjects = adoptPtr(new PositionedObjectsListHashSet);
31238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_positionedObjects->add(o);
31258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
31268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3127635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::removePositionedObject(RenderBox* o)
31288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
31298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_positionedObjects)
31308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_positionedObjects->remove(o);
31318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
31328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::removePositionedObjects(RenderBlock* o)
31348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
31358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_positionedObjects)
31368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
31378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3138635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderBox* r;
31398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Iterator end = m_positionedObjects->end();
31418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3142635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    Vector<RenderBox*, 16> deadObjects;
31438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
31458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        r = *it;
31468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!o || r->isDescendantOf(o)) {
31478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (o)
31488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                r->setChildNeedsLayout(true, false);
31498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // It is parent blocks job to add positioned child to positioned objects list of its containing block
31518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Parent layout needs to be invalidated to ensure this happens.
31528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderObject* p = r->parent();
31538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            while (p && !p->isRenderBlock())
31548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                p = p->parent();
31558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (p)
31568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                p->setChildNeedsLayout(true);
31578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            deadObjects.append(r);
31598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
31608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
31618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < deadObjects.size(); i++)
31638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_positionedObjects->remove(deadObjects.at(i));
31648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
31658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
316668513a70bcd92384395513322f1b801e7bf9c729Steve BlockRenderBlock::FloatingObject* RenderBlock::insertFloatingObject(RenderBox* o)
31678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
31688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(o->isFloating());
31698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Create the list of special objects if we don't aleady have one
317181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!m_floatingObjects)
317281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_floatingObjects = adoptPtr(new FloatingObjects);
317381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    else {
31748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Don't insert the object again if it's already in the list
317581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
317681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSetIterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(o);
317781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (it != floatingObjectSet.end())
317881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return *it;
31798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
31808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Create the special object entry & append it to the list
31828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FloatingObject* newObj = new FloatingObject(o->style()->floating() == FLEFT ? FloatingObject::FloatLeft : FloatingObject::FloatRight);
318468513a70bcd92384395513322f1b801e7bf9c729Steve Block
318568513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Our location is irrelevant if we're unsplittable or no pagination is in effect.
318668513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Just go ahead and lay out the float.
3187a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool isChildRenderBlock = o->isRenderBlock();
3188f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (isChildRenderBlock && !o->needsLayout() && view()->layoutState()->pageLogicalHeightChanged())
3189a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        o->setChildNeedsLayout(true, false);
3190a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
3191f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    bool affectedByPagination = isChildRenderBlock && view()->layoutState()->m_pageLogicalHeight;
3192a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!affectedByPagination || isWritingModeRoot()) // We are unsplittable if we're a block flow root.
319368513a70bcd92384395513322f1b801e7bf9c729Steve Block        o->layoutIfNeeded();
319468513a70bcd92384395513322f1b801e7bf9c729Steve Block    else {
3195bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        o->computeLogicalWidth();
3196bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        o->computeBlockDirectionMargins(this);
319768513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
3198a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setLogicalWidthForFloat(newObj, logicalWidthForChild(o) + marginStartForChild(o) + marginEndForChild(o));
319968513a70bcd92384395513322f1b801e7bf9c729Steve Block
32008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    newObj->m_shouldPaint = !o->hasSelfPaintingLayer(); // If a layer exists, the float will paint itself.  Otherwise someone else will.
32018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    newObj->m_isDescendant = true;
32028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    newObj->m_renderer = o;
32038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
320481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_floatingObjects->increaseObjectsCount(newObj->type());
320581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_floatingObjects->set().add(newObj);
320668513a70bcd92384395513322f1b801e7bf9c729Steve Block
320768513a70bcd92384395513322f1b801e7bf9c729Steve Block    return newObj;
32088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
32098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3210635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::removeFloatingObject(RenderBox* o)
32118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
32128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_floatingObjects) {
321381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
321481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSet::iterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(o);
321581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (it != floatingObjectSet.end()) {
321681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObject* r = *it;
321781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (childrenInline()) {
321881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                int logicalTop = logicalTopForFloat(r);
321981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                int logicalBottom = logicalBottomForFloat(r);
322081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
322181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                // Fix for https://bugs.webkit.org/show_bug.cgi?id=54995.
322281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (logicalBottom < 0 || logicalBottom < logicalTop || logicalTop == numeric_limits<int>::max())
322381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    logicalBottom = numeric_limits<int>::max();
322481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                else {
3225dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                    // Special-case zero- and less-than-zero-height floats: those don't touch
3226dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                    // the line that they're on, but it still needs to be dirtied. This is
3227dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                    // accomplished by pretending they have a height of 1.
322881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    logicalBottom = max(logicalBottom, logicalTop + 1);
3229dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                }
323054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                if (r->m_originatingLine) {
323154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                    ASSERT(r->m_originatingLine->renderer() == this);
323254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                    r->m_originatingLine->markDirty();
323354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block#if !ASSERT_DISABLED
323454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                    r->m_originatingLine = 0;
323554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block#endif
323654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                }
323781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                markLinesDirtyInBlockRange(0, logicalBottom);
32388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
323981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            m_floatingObjects->decreaseObjectsCount(r->type());
324081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            floatingObjectSet.remove(it);
324154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block            ASSERT(!r->m_originatingLine);
324281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            delete r;
32438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
32448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
32458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
32468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
32472fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid RenderBlock::removeFloatingObjectsBelow(FloatingObject* lastFloat, int logicalOffset)
324868513a70bcd92384395513322f1b801e7bf9c729Steve Block{
324968513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!m_floatingObjects)
325068513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
325168513a70bcd92384395513322f1b801e7bf9c729Steve Block
325281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
325381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObject* curr = floatingObjectSet.last();
32542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    while (curr != lastFloat && (!curr->isPlaced() || logicalTopForFloat(curr) >= logicalOffset)) {
325581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_floatingObjects->decreaseObjectsCount(curr->type());
325681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        floatingObjectSet.removeLast();
325754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        ASSERT(!curr->m_originatingLine);
325881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        delete curr;
325981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        curr = floatingObjectSet.last();
326068513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
326168513a70bcd92384395513322f1b801e7bf9c729Steve Block}
326268513a70bcd92384395513322f1b801e7bf9c729Steve Block
32638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::positionNewFloats()
32648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
32658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_floatingObjects)
32668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
326781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
326881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
326981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (floatingObjectSet.isEmpty())
327081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return false;
32718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
32728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If all floats have already been positioned, then we have no work to do.
327381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (floatingObjectSet.last()->isPlaced())
32748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
32758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
32768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Move backwards through our floating object list until we find a float that has
32778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // already been positioned.  Then we'll be able to move forward, positioning all of
32788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the new floats that need it.
327981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator it = floatingObjectSet.end();
328081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    --it; // Go to last item.
328181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator begin = floatingObjectSet.begin();
328281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObject* lastPlacedFloatingObject = 0;
328381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    while (it != begin) {
328481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        --it;
328581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if ((*it)->isPlaced()) {
328681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            lastPlacedFloatingObject = *it;
328781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            ++it;
328881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            break;
328981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
32908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
32918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3292a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalTop = logicalHeight();
32938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3294a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // The float cannot start above the top position of the last positioned float.
329581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (lastPlacedFloatingObject)
329681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalTop = max(logicalTopForFloat(lastPlacedFloatingObject), logicalTop);
32978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
329881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator end = floatingObjectSet.end();
32998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Now walk through the set of unpositioned floats and place them.
330081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (; it != end; ++it) {
330181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch         FloatingObject* floatingObject = *it;
33028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // The containing block is responsible for positioning floats, so if we have floats in our
33038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // list that come from somewhere else, do not attempt to position them.
330481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (floatingObject->renderer()->containingBlock() != this)
33058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
33068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3307a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        RenderBox* childBox = floatingObject->renderer();
3308a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int childLogicalLeftMargin = style()->isLeftToRightDirection() ? marginStartForChild(childBox) : marginEndForChild(childBox);
33098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3310a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int rightOffset = logicalRightOffsetForContent(); // Constant part of right offset.
3311a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int leftOffset = logicalLeftOffsetForContent(); // Constant part of left offset.
3312a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int floatLogicalWidth = logicalWidthForFloat(floatingObject); // The width we look for.
3313a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (rightOffset - leftOffset < floatLogicalWidth)
3314a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            floatLogicalWidth = rightOffset - leftOffset; // Never look for more than what will be available.
33158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3316a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        IntRect oldRect(childBox->x(), childBox->y() , childBox->width(), childBox->height());
331768513a70bcd92384395513322f1b801e7bf9c729Steve Block
3318a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (childBox->style()->clear() & CLEFT)
3319a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            logicalTop = max(lowestFloatLogicalBottom(FloatingObject::FloatLeft), logicalTop);
3320a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (childBox->style()->clear() & CRIGHT)
3321a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            logicalTop = max(lowestFloatLogicalBottom(FloatingObject::FloatRight), logicalTop);
33228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3323a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int floatLogicalLeft;
3324a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (childBox->style()->floating() == FLEFT) {
33258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int heightRemainingLeft = 1;
33268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int heightRemainingRight = 1;
3327a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            floatLogicalLeft = logicalLeftOffsetForLine(logicalTop, leftOffset, false, &heightRemainingLeft);
3328a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            while (logicalRightOffsetForLine(logicalTop, rightOffset, false, &heightRemainingRight) - floatLogicalLeft < floatLogicalWidth) {
3329a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                logicalTop += min(heightRemainingLeft, heightRemainingRight);
3330a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                floatLogicalLeft = logicalLeftOffsetForLine(logicalTop, leftOffset, false, &heightRemainingLeft);
33318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
3332a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            floatLogicalLeft = max(0, floatLogicalLeft);
33338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
33348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int heightRemainingLeft = 1;
33358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int heightRemainingRight = 1;
3336a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            floatLogicalLeft = logicalRightOffsetForLine(logicalTop, rightOffset, false, &heightRemainingRight);
3337a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            while (floatLogicalLeft - logicalLeftOffsetForLine(logicalTop, leftOffset, false, &heightRemainingLeft) < floatLogicalWidth) {
3338a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                logicalTop += min(heightRemainingLeft, heightRemainingRight);
3339a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                floatLogicalLeft = logicalRightOffsetForLine(logicalTop, rightOffset, false, &heightRemainingRight);
33408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
3341a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            floatLogicalLeft -= logicalWidthForFloat(floatingObject); // Use the original width of the float here, since the local variable
3342a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                                                                      // |floatLogicalWidth| was capped to the available line width.
3343a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                                                                      // See fast/block/float/clamped-right-float.html.
33448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3345a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
3346a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalLeftForFloat(floatingObject, floatLogicalLeft);
3347a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalLeftForChild(childBox, floatLogicalLeft + childLogicalLeftMargin);
3348a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalTopForChild(childBox, logicalTop + marginBeforeForChild(childBox));
33498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
335068513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (view()->layoutState()->isPaginated()) {
3351a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            RenderBlock* childBlock = childBox->isRenderBlock() ? toRenderBlock(childBox) : 0;
33528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3353a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (!childBox->needsLayout())
3354a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                childBox->markForPaginationRelayoutIfNeeded();;
3355a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBox->layoutIfNeeded();
335668513a70bcd92384395513322f1b801e7bf9c729Steve Block
335768513a70bcd92384395513322f1b801e7bf9c729Steve Block            // If we are unsplittable and don't fit, then we need to move down.
335868513a70bcd92384395513322f1b801e7bf9c729Steve Block            // We include our margins as part of the unsplittable area.
3359a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            int newLogicalTop = adjustForUnsplittableChild(childBox, logicalTop, true);
336068513a70bcd92384395513322f1b801e7bf9c729Steve Block
336168513a70bcd92384395513322f1b801e7bf9c729Steve Block            // See if we have a pagination strut that is making us move down further.
336268513a70bcd92384395513322f1b801e7bf9c729Steve Block            // Note that an unsplittable child can't also have a pagination strut, so this is
336368513a70bcd92384395513322f1b801e7bf9c729Steve Block            // exclusive with the case above.
336468513a70bcd92384395513322f1b801e7bf9c729Steve Block            if (childBlock && childBlock->paginationStrut()) {
3365a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                newLogicalTop += childBlock->paginationStrut();
336668513a70bcd92384395513322f1b801e7bf9c729Steve Block                childBlock->setPaginationStrut(0);
336768513a70bcd92384395513322f1b801e7bf9c729Steve Block            }
336868513a70bcd92384395513322f1b801e7bf9c729Steve Block
3369a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (newLogicalTop != logicalTop) {
3370a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                floatingObject->m_paginationStrut = newLogicalTop - logicalTop;
3371a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                logicalTop = newLogicalTop;
3372a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                setLogicalTopForChild(childBox, logicalTop + marginBeforeForChild(childBox));
337368513a70bcd92384395513322f1b801e7bf9c729Steve Block                if (childBlock)
337468513a70bcd92384395513322f1b801e7bf9c729Steve Block                    childBlock->setChildNeedsLayout(true, false);
3375a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                childBox->layoutIfNeeded();
337668513a70bcd92384395513322f1b801e7bf9c729Steve Block            }
337768513a70bcd92384395513322f1b801e7bf9c729Steve Block        }
337868513a70bcd92384395513322f1b801e7bf9c729Steve Block
3379a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalTopForFloat(floatingObject, logicalTop);
3380a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        setLogicalHeightForFloat(floatingObject, logicalHeightForChild(childBox) + marginBeforeForChild(childBox) + marginAfterForChild(childBox));
3381a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
3382a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        floatingObject->setIsPlaced();
3383a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
33848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // If the child moved, we have to repaint it.
3385a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (childBox->checkForRepaintDuringLayout())
3386a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBox->repaintDuringLayoutIfMoved(oldRect);
33878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
33888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
33898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
33908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
33918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::newLine(EClear clear)
33928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
33938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    positionNewFloats();
33948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // set y position
33958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int newY = 0;
33960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    switch (clear)
33978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
33988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CLEFT:
3399a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            newY = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
34008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
34018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CRIGHT:
3402a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            newY = lowestFloatLogicalBottom(FloatingObject::FloatRight);
34038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
34048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CBOTH:
3405a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            newY = lowestFloatLogicalBottom();
34068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        default:
34078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
34088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3409635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (height() < newY)
3410bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setLogicalHeight(newY);
34118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
34128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::addPercentHeightDescendant(RenderBox* descendant)
34148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
34158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!gPercentHeightDescendantsMap) {
34168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gPercentHeightDescendantsMap = new PercentHeightDescendantsMap;
34178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gPercentHeightContainerMap = new PercentHeightContainerMap;
34188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
34198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(this);
34218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!descendantSet) {
34228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        descendantSet = new HashSet<RenderBox*>;
34238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gPercentHeightDescendantsMap->set(this, descendantSet);
34248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
34258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool added = descendantSet->add(descendant).second;
34268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!added) {
34278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(gPercentHeightContainerMap->get(descendant));
34288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(gPercentHeightContainerMap->get(descendant)->contains(this));
34298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
34308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
34318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(descendant);
34338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!containerSet) {
34348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        containerSet = new HashSet<RenderBlock*>;
34358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gPercentHeightContainerMap->set(descendant, containerSet);
34368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
34378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!containerSet->contains(this));
34388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    containerSet->add(this);
34398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
34408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::removePercentHeightDescendant(RenderBox* descendant)
34428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
34438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!gPercentHeightContainerMap)
34448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
34458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->take(descendant);
34478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!containerSet)
34488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
34498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HashSet<RenderBlock*>::iterator end = containerSet->end();
34518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (HashSet<RenderBlock*>::iterator it = containerSet->begin(); it != end; ++it) {
34528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderBlock* container = *it;
34538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(container);
34548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(descendantSet);
34558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!descendantSet)
34568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
34578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(descendantSet->contains(descendant));
34588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        descendantSet->remove(descendant);
34598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (descendantSet->isEmpty()) {
34608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            gPercentHeightDescendantsMap->remove(container);
34618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            delete descendantSet;
34628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
34638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
34648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    delete containerSet;
34668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
34678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianHashSet<RenderBox*>* RenderBlock::percentHeightDescendants() const
34698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
34708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0;
34718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
34728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34732bde8e466a4451c7319e3a072d118917957d6554Steve Block// FIXME: The logicalLeftOffsetForLine/logicalRightOffsetForLine functions are very slow if there are many floats
34742bde8e466a4451c7319e3a072d118917957d6554Steve Block// present. We need to add a structure to floating objects to represent "lines" of floats.  Then instead of checking
34752bde8e466a4451c7319e3a072d118917957d6554Steve Block// each float individually, we'd just walk backwards through the "lines" and stop when we hit a line that is fully above
34762bde8e466a4451c7319e3a072d118917957d6554Steve Block// the vertical offset that we'd like to check.  Computing the "lines" would be rather complicated, but could replace the left
34772bde8e466a4451c7319e3a072d118917957d6554Steve Block// objects and right objects count hack that is currently used here.
3478a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::logicalLeftOffsetForLine(int logicalTop, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
34798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
34808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int left = fixedOffset;
348181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_floatingObjects && m_floatingObjects->hasLeftObjects()) {
3482a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (heightRemaining)
3483a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            *heightRemaining = 1;
348481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
34852bde8e466a4451c7319e3a072d118917957d6554Steve Block        // We know the list is non-empty, since we have "left" objects to search for.
34862bde8e466a4451c7319e3a072d118917957d6554Steve Block        // Therefore we can assume that begin != end, and that we can do at least one
34872bde8e466a4451c7319e3a072d118917957d6554Steve Block        // decrement.
348881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
34892bde8e466a4451c7319e3a072d118917957d6554Steve Block        FloatingObjectSetIterator begin = floatingObjectSet.begin();
34902bde8e466a4451c7319e3a072d118917957d6554Steve Block        FloatingObjectSetIterator it = floatingObjectSet.end();
34912bde8e466a4451c7319e3a072d118917957d6554Steve Block        do {
34922bde8e466a4451c7319e3a072d118917957d6554Steve Block            --it;
349381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObject* r = *it;
3494a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (r->isPlaced() && logicalTopForFloat(r) <= logicalTop && logicalBottomForFloat(r) > logicalTop
3495a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                && r->type() == FloatingObject::FloatLeft
3496a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                && logicalRightForFloat(r) > left) {
34972bde8e466a4451c7319e3a072d118917957d6554Steve Block                left = max(left, logicalRightForFloat(r));
3498a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                if (heightRemaining)
3499a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    *heightRemaining = logicalBottomForFloat(r) - logicalTop;
35008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
35012bde8e466a4451c7319e3a072d118917957d6554Steve Block        } while (it != begin);
35028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
35038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3504a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (applyTextIndent && style()->isLeftToRightDirection()) {
3505635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        int cw = 0;
35068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (style()->textIndent().isPercent())
3507bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            cw = containingBlock()->availableLogicalWidth();
35088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        left += style()->textIndent().calcMinValue(cw);
35098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
35108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
35118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return left;
35128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
35138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3514a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::logicalRightOffsetForLine(int logicalTop, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
35158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
35168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int right = fixedOffset;
35178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
351881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_floatingObjects && m_floatingObjects->hasRightObjects()) {
3519a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (heightRemaining)
3520a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            *heightRemaining = 1;
35212bde8e466a4451c7319e3a072d118917957d6554Steve Block
35222bde8e466a4451c7319e3a072d118917957d6554Steve Block        // We know the list is non-empty, since we have "right" objects to search for.
35232bde8e466a4451c7319e3a072d118917957d6554Steve Block        // Therefore we can assume that begin != end, and that we can do at least one
35242bde8e466a4451c7319e3a072d118917957d6554Steve Block        // decrement.
352581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
35262bde8e466a4451c7319e3a072d118917957d6554Steve Block        FloatingObjectSetIterator begin = floatingObjectSet.begin();
35272bde8e466a4451c7319e3a072d118917957d6554Steve Block        FloatingObjectSetIterator it = floatingObjectSet.end();
35282bde8e466a4451c7319e3a072d118917957d6554Steve Block        do {
35292bde8e466a4451c7319e3a072d118917957d6554Steve Block            --it;
353081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObject* r = *it;
3531a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (r->isPlaced() && logicalTopForFloat(r) <= logicalTop && logicalBottomForFloat(r) > logicalTop
3532a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                && r->type() == FloatingObject::FloatRight
3533a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                && logicalLeftForFloat(r) < right) {
35342bde8e466a4451c7319e3a072d118917957d6554Steve Block                right = min(right, logicalLeftForFloat(r));
3535a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                if (heightRemaining)
3536a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    *heightRemaining = logicalBottomForFloat(r) - logicalTop;
35378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
35382bde8e466a4451c7319e3a072d118917957d6554Steve Block        } while (it != begin);
35398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
35408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3541a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (applyTextIndent && !style()->isLeftToRightDirection()) {
3542635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        int cw = 0;
35438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (style()->textIndent().isPercent())
3544bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            cw = containingBlock()->availableLogicalWidth();
35458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        right -= style()->textIndent().calcMinValue(cw);
35468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
35478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
35488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return right;
35498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
35508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
355181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochint RenderBlock::availableLogicalWidthForLine(int position, bool firstLine) const
35528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3553bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int result = logicalRightOffsetForLine(position, firstLine) - logicalLeftOffsetForLine(position, firstLine);
35548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return (result < 0) ? 0 : result;
35558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
35568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3557a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::nextFloatLogicalBottomBelow(int logicalHeight) const
35588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
35598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_floatingObjects)
35608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
35618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
35628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int bottom = INT_MAX;
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        int floatBottom = logicalBottomForFloat(r);
3568a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (floatBottom > logicalHeight)
3569a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            bottom = min(floatBottom, bottom);
35708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
35718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
35728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return bottom == INT_MAX ? 0 : bottom;
35738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
35748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3575a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::lowestFloatLogicalBottom(FloatingObject::Type floatType) const
35768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3577a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!m_floatingObjects)
3578a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return 0;
3579a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int lowestFloatBottom = 0;
358081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
358181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator end = floatingObjectSet.end();
358281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
358381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObject* r = *it;
3584a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (r->isPlaced() && r->type() & floatType)
3585a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            lowestFloatBottom = max(lowestFloatBottom, logicalBottomForFloat(r));
3586a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
3587a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return lowestFloatBottom;
35888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
35898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3590a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::markLinesDirtyInBlockRange(int logicalTop, int logicalBottom, RootInlineBox* highest)
35918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3592a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (logicalTop >= logicalBottom)
35938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
35948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
35958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RootInlineBox* lowestDirtyLine = lastRootBox();
35968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RootInlineBox* afterLowest = lowestDirtyLine;
35972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    while (lowestDirtyLine && lowestDirtyLine->blockLogicalHeight() >= logicalBottom && logicalBottom < numeric_limits<int>::max()) {
35988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        afterLowest = lowestDirtyLine;
35998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        lowestDirtyLine = lowestDirtyLine->prevRootBox();
36008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
36018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
360281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    while (afterLowest && afterLowest != highest && (afterLowest->blockLogicalHeight() >= logicalTop || afterLowest->blockLogicalHeight() < 0)) {
36038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        afterLowest->markDirty();
36048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        afterLowest = afterLowest->prevRootBox();
36058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
36068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
36078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
36088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::clearFloats()
36098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
36108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Inline blocks are covered by the isReplaced() check in the avoidFloats method.
36118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (avoidsFloats() || isRoot() || isRenderView() || isFloatingOrPositioned() || isTableCell()) {
361281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (m_floatingObjects) {
361381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            deleteAllValues(m_floatingObjects->set());
36148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_floatingObjects->clear();
361581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
36168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
36178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
36188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
36198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    typedef HashMap<RenderObject*, FloatingObject*> RendererToFloatInfoMap;
36208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RendererToFloatInfoMap floatMap;
36218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
36228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_floatingObjects) {
362381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
36248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (childrenInline()) {
362581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObjectSet::iterator end = floatingObjectSet.end();
362681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            for (FloatingObjectSet::iterator it = floatingObjectSet.begin(); it != end; ++it) {
362781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                FloatingObject* f = *it;
36288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatMap.add(f->m_renderer, f);
362981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
36308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else
363181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            deleteAllValues(floatingObjectSet);
363281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_floatingObjects->clear();
36338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
36348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3635545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // We should not process floats if the parent node is not a RenderBlock. Otherwise, we will add
3636545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // floats in an invalid context. This will cause a crash arising from a bad cast on the parent.
3637545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // See <rdar://problem/8049753>, where float property is applied on a text node in a SVG.
3638545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (!parent() || !parent()->isRenderBlock())
3639545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return;
3640545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
36418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Attempt to locate a previous sibling with overhanging floats.  We skip any elements that are
36428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // out of flow (like floating/positioned elements), and we also skip over any objects that may have shifted
36438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // to avoid floats.
36448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool parentHasFloats = false;
3645a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RenderBlock* parentBlock = toRenderBlock(parent());
3646635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderObject* prev = previousSibling();
36478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    while (prev && (prev->isFloatingOrPositioned() || !prev->isBox() || !prev->isRenderBlock() || toRenderBlock(prev)->avoidsFloats())) {
36488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (prev->isFloating())
36498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            parentHasFloats = true;
36508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         prev = prev->previousSibling();
36518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
36528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
36538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // First add in floats from the parent.
3654a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalTopOffset = logicalTop();
3655a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (parentHasFloats)
3656a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        addIntrudingFloats(parentBlock, parentBlock->logicalLeftOffsetForContent(), logicalTopOffset);
3657635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
3658a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalLeftOffset = 0;
36598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (prev)
3660a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        logicalTopOffset -= toRenderBox(prev)->logicalTop();
3661a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    else {
3662a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        prev = parentBlock;
3663a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        logicalLeftOffset += parentBlock->logicalLeftOffsetForContent();
36648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
36658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
36668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Add overhanging floats from the previous RenderBlock, but only if it has a float that intrudes into our space.
3667635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!prev || !prev->isRenderBlock())
3668635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
3669635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
36708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBlock* block = toRenderBlock(prev);
3671a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (block->m_floatingObjects && block->lowestFloatLogicalBottom() > logicalTopOffset)
3672a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        addIntrudingFloats(block, logicalLeftOffset, logicalTopOffset);
36738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
36748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childrenInline()) {
3675a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int changeLogicalTop = numeric_limits<int>::max();
3676a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int changeLogicalBottom = numeric_limits<int>::min();
36778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_floatingObjects) {
367881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
367981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObjectSetIterator end = floatingObjectSet.end();
368081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
368181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                FloatingObject* f = *it;
36828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                FloatingObject* oldFloatingObject = floatMap.get(f->m_renderer);
3683a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                int logicalBottom = logicalBottomForFloat(f);
36848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (oldFloatingObject) {
3685a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    int oldLogicalBottom = logicalBottomForFloat(oldFloatingObject);
3686a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    if (logicalWidthForFloat(f) != logicalWidthForFloat(oldFloatingObject) || logicalLeftForFloat(f) != logicalLeftForFloat(oldFloatingObject)) {
3687a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                        changeLogicalTop = 0;
3688a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                        changeLogicalBottom = max(changeLogicalBottom, max(logicalBottom, oldLogicalBottom));
3689a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    } else if (logicalBottom != oldLogicalBottom) {
3690a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                        changeLogicalTop = min(changeLogicalTop, min(logicalBottom, oldLogicalBottom));
3691a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                        changeLogicalBottom = max(changeLogicalBottom, max(logicalBottom, oldLogicalBottom));
36928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
36938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
36948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    floatMap.remove(f->m_renderer);
369554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                    if (oldFloatingObject->m_originatingLine) {
369654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                        ASSERT(oldFloatingObject->m_originatingLine->renderer() == this);
369754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                        oldFloatingObject->m_originatingLine->markDirty();
369854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                    }
36998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    delete oldFloatingObject;
37008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else {
3701a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    changeLogicalTop = 0;
3702a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    changeLogicalBottom = max(changeLogicalBottom, logicalBottom);
37038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
37048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
37058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
37068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
37078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RendererToFloatInfoMap::iterator end = floatMap.end();
37088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (RendererToFloatInfoMap::iterator it = floatMap.begin(); it != end; ++it) {
37098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            FloatingObject* floatingObject = (*it).second;
37108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!floatingObject->m_isDescendant) {
3711a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                changeLogicalTop = 0;
3712a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                changeLogicalBottom = max(changeLogicalBottom, logicalBottomForFloat(floatingObject));
37138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
37148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
37158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        deleteAllValues(floatMap);
37168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3717a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        markLinesDirtyInBlockRange(changeLogicalTop, changeLogicalBottom);
37188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
37198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
37208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3721a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::addOverhangingFloats(RenderBlock* child, int logicalLeftOffset, int logicalTopOffset, bool makeChildPaintOtherFloats)
37228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
37238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Prevent floats from being added to the canvas by the root element, e.g., <html>.
3724a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (child->hasOverflowClip() || !child->containsFloats() || child->isRoot() || child->hasColumns() || child->isWritingModeRoot())
37258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
37268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
37272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    int childLogicalTop = child->logicalTop();
3728a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int lowestFloatLogicalBottom = 0;
37298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3730231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Floats that will remain the child's responsibility to paint should factor into its
3731231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // overflow.
373281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator childEnd = child->m_floatingObjects->set().end();
373381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (FloatingObjectSetIterator childIt = child->m_floatingObjects->set().begin(); childIt != childEnd; ++childIt) {
373481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObject* r = *childIt;
37352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        int logicalBottomForFloat = min(this->logicalBottomForFloat(r), numeric_limits<int>::max() - childLogicalTop);
37362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        int logicalBottom = childLogicalTop + logicalBottomForFloat;
3737a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        lowestFloatLogicalBottom = max(lowestFloatLogicalBottom, logicalBottom);
37388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3739a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (logicalBottom > logicalHeight()) {
37408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // If the object is not in the list, we add it now.
37418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!containsFloat(r->m_renderer)) {
37422bde8e466a4451c7319e3a072d118917957d6554Steve Block                int leftOffset = isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset;
37432bde8e466a4451c7319e3a072d118917957d6554Steve Block                int topOffset = isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset;
37442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->x() - leftOffset, r->y() - topOffset, r->width(), r->height()));
37458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatingObj->m_renderer = r->m_renderer;
37468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
37478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // The nearest enclosing layer always paints the float (so that zindex and stacking
37488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // behaves properly).  We always want to propagate the desire to paint the float as
37498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // far out as we can, to the outermost block that overlaps the float, stopping only
37508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                // if we hit a self-painting layer boundary.
3751f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                if (r->m_renderer->enclosingFloatPaintingLayer() == enclosingFloatPaintingLayer())
37528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    r->m_shouldPaint = false;
37538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                else
37548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    floatingObj->m_shouldPaint = false;
37558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3756f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                floatingObj->m_isDescendant = true;
3757f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
37588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // We create the floating object list lazily.
375981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (!m_floatingObjects)
376081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    m_floatingObjects = adoptPtr(new FloatingObjects);
376181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
376281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                m_floatingObjects->increaseObjectsCount(floatingObj->type());
376381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                m_floatingObjects->set().add(floatingObj);
37648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
3765f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        } else {
3766f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            if (makeChildPaintOtherFloats && !r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer() &&
3767f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                r->m_renderer->isDescendantOf(child) && r->m_renderer->enclosingFloatPaintingLayer() == child->enclosingFloatPaintingLayer()) {
3768f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                // The float is not overhanging from this block, so if it is a descendant of the child, the child should
3769f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                // paint it (the other case is that it is intruding into the child), unless it has its own layer or enclosing
3770f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                // layer.
3771f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                // If makeChildPaintOtherFloats is false, it means that the child must already know about all the floats
3772f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                // it should paint.
3773f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                r->m_shouldPaint = true;
3774f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            }
3775f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
3776f05b935882198ccf7d81675736e3aeb089c5113aBen 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
3777f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // child now.
3778f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            if (r->m_isDescendant)
37792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                child->addOverflowFromChild(r->m_renderer, IntSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r)));
3780f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        }
37818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3782a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return lowestFloatLogicalBottom;
37838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
37848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
37854fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Blockbool RenderBlock::hasOverhangingFloat(RenderBox* renderer)
37864fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block{
37874fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block    if (!m_floatingObjects || hasColumns() || !parent())
37884fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block        return false;
37894fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block
37904fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
37914fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block    FloatingObjectSetIterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(renderer);
37924fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block    if (it == floatingObjectSet.end())
37934fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block        return false;
37944fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block
37954fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block    return logicalBottomForFloat(*it) > logicalHeight();
37964fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block}
37974fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block
3798a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::addIntrudingFloats(RenderBlock* prev, int logicalLeftOffset, int logicalTopOffset)
37998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
38008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the parent or previous sibling doesn't have any floats to add, don't bother.
38018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!prev->m_floatingObjects)
38028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
38038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
38042bde8e466a4451c7319e3a072d118917957d6554Steve Block    logicalLeftOffset += (isHorizontalWritingMode() ? marginLeft() : marginTop());
380581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
380681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& prevSet = prev->m_floatingObjects->set();
380781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator prevEnd = prevSet.end();
380881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (FloatingObjectSetIterator prevIt = prevSet.begin(); prevIt != prevEnd; ++prevIt) {
380981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObject* r = *prevIt;
3810a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (logicalBottomForFloat(r) > logicalTopOffset) {
381181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (!m_floatingObjects || !m_floatingObjects->set().contains(r)) {
38122bde8e466a4451c7319e3a072d118917957d6554Steve Block                int leftOffset = isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset;
38132bde8e466a4451c7319e3a072d118917957d6554Steve Block                int topOffset = isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset;
3814a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
38152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->x() - leftOffset, r->y() - topOffset, r->width(), r->height()));
3816a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
38178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Applying the child's margin makes no sense in the case where the child was passed in.
3818a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                // since this margin was added already through the modification of the |logicalLeftOffset| variable
3819a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                // above.  |logicalLeftOffset| will equal the margin in this case, so it's already been taken
3820a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                // into account.  Only apply this code if prev is the parent, since otherwise the left margin
38218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // will get applied twice.
38226b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                if (prev != parent()) {
38232bde8e466a4451c7319e3a072d118917957d6554Steve Block                    if (isHorizontalWritingMode())
38242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                        floatingObj->setX(floatingObj->x() + prev->marginLeft());
38256b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                    else
38262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                        floatingObj->setY(floatingObj->y() + prev->marginTop());
38276b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                }
3828a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
38298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatingObj->m_shouldPaint = false;  // We are not in the direct inheritance chain for this float. We will never paint it.
38308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatingObj->m_renderer = r->m_renderer;
38318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
38328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // We create the floating object list lazily.
383381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (!m_floatingObjects)
383481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    m_floatingObjects = adoptPtr(new FloatingObjects);
383581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                m_floatingObjects->increaseObjectsCount(floatingObj->type());
383681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                m_floatingObjects->set().add(floatingObj);
38378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
38388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
38398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
38408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
38418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
38428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::avoidsFloats() const
38438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
38448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Floats can't intrude into our box if we have a non-auto column count or width.
38458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return RenderBox::avoidsFloats() || !style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth();
38468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
38478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
384881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochbool RenderBlock::containsFloat(RenderBox* renderer)
38498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
385081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return m_floatingObjects && m_floatingObjects->set().contains<RenderBox*, FloatingObjectHashTranslator>(renderer);
38518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
38528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3853635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove, bool inLayout)
38548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
385568513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!m_everHadLayout)
385668513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
385768513a70bcd92384395513322f1b801e7bf9c729Steve Block
3858635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    setChildNeedsLayout(true, !inLayout);
38598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
38608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (floatToRemove)
38618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        removeFloatingObject(floatToRemove);
38628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
38638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Iterate over our children and mark them as needed.
38648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!childrenInline()) {
38658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
38668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if ((!floatToRemove && child->isFloatingOrPositioned()) || !child->isRenderBlock())
38678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                continue;
38688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            RenderBlock* childBlock = toRenderBlock(child);
38698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if ((floatToRemove ? childBlock->containsFloat(floatToRemove) : childBlock->containsFloats()) || childBlock->shrinkToAvoidFloats())
38708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                childBlock->markAllDescendantsWithFloatsForLayout(floatToRemove, inLayout);
38718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
38728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
38738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
38748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
387554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Blockvoid RenderBlock::markSiblingsWithFloatsForLayout()
387654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block{
387754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
387854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    FloatingObjectSetIterator end = floatingObjectSet.end();
387954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
388054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        if (logicalBottomForFloat(*it) > logicalHeight()) {
388154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block            RenderBox* floatingBox = (*it)->renderer();
388254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
388354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block            RenderObject* next = nextSibling();
388454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block            while (next) {
388554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                if (next->isRenderBlock() && !next->isFloatingOrPositioned() && !toRenderBlock(next)->avoidsFloats()) {
388654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                    RenderBlock* nextBlock = toRenderBlock(next);
388754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                    if (nextBlock->containsFloat(floatingBox))
388854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                        nextBlock->markAllDescendantsWithFloatsForLayout(floatingBox);
388954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                    else
389054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                        break;
389154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                }
389254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
389354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                next = next->nextSibling();
389454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block            }
389554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        }
389654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    }
389754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block}
389854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
38998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianint RenderBlock::getClearDelta(RenderBox* child, int yPos)
39008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
39018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // There is no need to compute clearance if we have no floats.
39028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!containsFloats())
39038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
39048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
39058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // At least one float is present.  We need to perform the clearance computation.
39068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool clearSet = child->style()->clear() != CNONE;
39078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int bottom = 0;
39088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch (child->style()->clear()) {
39098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CNONE:
39108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
39118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CLEFT:
3912a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            bottom = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
39138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
39148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CRIGHT:
3915a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            bottom = lowestFloatLogicalBottom(FloatingObject::FloatRight);
39168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
39178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CBOTH:
3918a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            bottom = lowestFloatLogicalBottom();
39198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
39208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
39218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
39228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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).
39238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int result = clearSet ? max(0, bottom - yPos) : 0;
3924231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!result && child->avoidsFloats()) {
3925d0825bca7fe65beaee391d30da42e937db621564Steve Block        int y = yPos;
3926d0825bca7fe65beaee391d30da42e937db621564Steve Block        while (true) {
3927bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            int widthAtY = availableLogicalWidthForLine(y, false);
3928e14391e94c850b8bd03680c23b38978db68687a8John Reck            if (widthAtY == availableLogicalWidth())
3929d0825bca7fe65beaee391d30da42e937db621564Steve Block                return y - yPos;
3930d0825bca7fe65beaee391d30da42e937db621564Steve Block
3931d0825bca7fe65beaee391d30da42e937db621564Steve Block            int oldChildY = child->y();
3932d0825bca7fe65beaee391d30da42e937db621564Steve Block            int oldChildWidth = child->width();
3933d0825bca7fe65beaee391d30da42e937db621564Steve Block            child->setY(y);
3934bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            child->computeLogicalWidth();
3935d0825bca7fe65beaee391d30da42e937db621564Steve Block            int childWidthAtY = child->width();
3936d0825bca7fe65beaee391d30da42e937db621564Steve Block            child->setY(oldChildY);
3937d0825bca7fe65beaee391d30da42e937db621564Steve Block            child->setWidth(oldChildWidth);
3938d0825bca7fe65beaee391d30da42e937db621564Steve Block
3939d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (childWidthAtY <= widthAtY)
3940d0825bca7fe65beaee391d30da42e937db621564Steve Block                return y - yPos;
3941d0825bca7fe65beaee391d30da42e937db621564Steve Block
3942a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            y = nextFloatLogicalBottomBelow(y);
3943d0825bca7fe65beaee391d30da42e937db621564Steve Block            ASSERT(y >= yPos);
3944d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (y < yPos)
3945d0825bca7fe65beaee391d30da42e937db621564Steve Block                break;
3946d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
3947d0825bca7fe65beaee391d30da42e937db621564Steve Block        ASSERT_NOT_REACHED();
3948231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
39498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
39508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
39518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
39520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool RenderBlock::isPointInOverflowControl(HitTestResult& result, int _x, int _y, int _tx, int _ty)
39538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
39548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!scrollsOverflow())
39558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
39568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
39570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return layer()->hitTestOverflowControls(result, IntPoint(_x - _tx, _y - _ty));
39588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
39598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
39608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction)
39618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3962635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int tx = _tx + x();
3963635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int ty = _ty + y();
39648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3965635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!isRenderView()) {
39668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Check if we need to do anything at all.
3967f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        IntRect overflowBox = visualOverflowRect();
39688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        overflowBox.move(tx, ty);
3969a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!overflowBox.intersects(result.rectForPoint(_x, _y)))
39708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
39718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
39728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
39738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) && isPointInOverflowControl(result, _x, _y, tx, ty)) {
39748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
3975ad3386af2204fbbc9033a6dcced2f9b0adcd6f10Steve Block        // FIXME: isPointInOverflowControl() doesn't handle rect-based tests yet.
3976db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block        if (!result.addNodeToRectBasedTestResult(node(), _x, _y))
3977db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block           return true;
39788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
39798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
39808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If we have clipping, then we can't have any spillout.
39818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer();
39828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool useClip = (hasControlClip() || useOverflowClip);
3983a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    IntRect hitTestArea(result.rectForPoint(_x, _y));
39842bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool checkChildren = !useClip || (hasControlClip() ? controlClipRect(tx, ty).intersects(hitTestArea) : overflowClipRect(tx, ty, IncludeOverlayScrollbarSize).intersects(hitTestArea));
39858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (checkChildren) {
39868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Hit test descendants first.
39878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int scrolledX = tx;
39888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int scrolledY = ty;
3989dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (hasOverflowClip()) {
3990dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            IntSize offset = layer()->scrolledContentOffset();
3991dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            scrolledX -= offset.width();
3992dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            scrolledY -= offset.height();
3993dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
39948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
39958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Hit test contents if we don't have columns.
39965abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        if (!hasColumns()) {
39975abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            if (hitTestContents(request, result, _x, _y, scrolledX, scrolledY, hitTestAction)) {
39985abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick                updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
39995abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick                return true;
40005abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            }
40015abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            if (hitTestAction == HitTestFloat && hitTestFloats(request, result, _x, _y, scrolledX, scrolledY))
40025abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick                return true;
40035abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        } else if (hitTestColumns(request, result, _x, _y, scrolledX, scrolledY, hitTestAction)) {
40046c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
40058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
40066c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        }
40078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
40088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4009635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Now hit test our background
4010635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) {
4011635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        IntRect boundsRect(tx, ty, width(), height());
4012a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (visibleToHitTesting() && boundsRect.intersects(result.rectForPoint(_x, _y))) {
40136b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            updateHitTestResult(result, flipForWritingMode(IntPoint(_x - tx, _y - ty)));
4014db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block            if (!result.addNodeToRectBasedTestResult(node(), _x, _y, boundsRect))
4015db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block                return true;
40168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
40178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
40188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
40208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
40218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40225abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickbool RenderBlock::hitTestFloats(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty)
40235abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{
40245abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    if (!m_floatingObjects)
40255abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        return false;
40265abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
40275abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    if (isRenderView()) {
40285abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        tx += toRenderView(this)->frameView()->scrollX();
40295abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        ty += toRenderView(this)->frameView()->scrollY();
40305abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    }
40315abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
403281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
403381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatingObjectSetIterator begin = floatingObjectSet.begin();
403481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (FloatingObjectSetIterator it = floatingObjectSet.end(); it != begin;) {
403581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        --it;
403681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        FloatingObject* floatingObject = *it;
40375abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        if (floatingObject->m_shouldPaint && !floatingObject->m_renderer->hasSelfPaintingLayer()) {
40382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int xOffset = xPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->x();
40392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int yOffset = yPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->y();
40402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            IntPoint childPoint = flipFloatForWritingMode(floatingObject, IntPoint(tx + xOffset, ty + yOffset));
404128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            if (floatingObject->m_renderer->hitTest(request, result, IntPoint(x, y), childPoint.x(), childPoint.y())) {
404228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                updateHitTestResult(result, IntPoint(x - childPoint.x(), y - childPoint.y()));
40435abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick                return true;
40445abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            }
40455abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        }
40465abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    }
40475abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
40485abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    return false;
40495abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick}
40505abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
40518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
40528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
40538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We need to do multiple passes, breaking up our hit testing into strips.
40545abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    ColumnInfo* colInfo = columnInfo();
405568513a70bcd92384395513322f1b801e7bf9c729Steve Block    int colCount = columnCount(colInfo);
40566c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (!colCount)
40576c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        return false;
40582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int logicalLeft = logicalLeftOffsetForContent();
40592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int currLogicalTopOffset = 0;
4060e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    int i;
40612bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool isHorizontal = isHorizontalWritingMode();
40622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    for (i = 0; i < colCount; i++) {
40632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        IntRect colRect = columnRectAt(colInfo, i);
40642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int blockDelta =  (isHorizontal ? colRect.height() : colRect.width());
40652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (style()->isFlippedBlocksWritingMode())
40662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalTopOffset += blockDelta;
40672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        else
40682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalTopOffset -= blockDelta;
40692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
4070e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    for (i = colCount - 1; i >= 0; i--) {
407168513a70bcd92384395513322f1b801e7bf9c729Steve Block        IntRect colRect = columnRectAt(colInfo, i);
40722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        flipForWritingMode(colRect);
40732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft;
40742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int blockDelta =  (isHorizontal ? colRect.height() : colRect.width());
40752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (style()->isFlippedBlocksWritingMode())
40762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalTopOffset -= blockDelta;
40772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        else
40782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalTopOffset += blockDelta;
40798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        colRect.move(tx, ty);
40808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4081a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (colRect.intersects(result.rectForPoint(x, y))) {
40828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // The point is inside this column.
40838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Adjust tx and ty to change where we hit test.
40848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            IntSize offset = isHorizontal ? IntSize(currLogicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, currLogicalLeftOffset);
40862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int finalX = tx + offset.width();
40872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int finalY = ty + offset.height();
4088a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (result.isRectBasedTest() && !colRect.contains(result.rectForPoint(x, y)))
4089db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block                hitTestContents(request, result, x, y, finalX, finalY, hitTestAction);
4090db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block            else
40915abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick                return hitTestContents(request, result, x, y, finalX, finalY, hitTestAction) || (hitTestAction == HitTestFloat && hitTestFloats(request, result, x, y, finalX, finalY));
40928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
40938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
40948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
40968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
40978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::hitTestContents(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
40998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
41008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childrenInline() && !isTable()) {
41018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We have to hit-test our line boxes.
41026c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (m_lineBoxes.hitTest(this, request, result, x, y, tx, ty, hitTestAction))
41038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
41048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
41058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Hit test our children.
41068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HitTestAction childHitTest = hitTestAction;
41078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (hitTestAction == HitTestChildBlockBackgrounds)
41088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            childHitTest = HitTestChildBlockBackground;
41098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        for (RenderBox* child = lastChildBox(); child; child = child->previousSiblingBox()) {
411028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            IntPoint childPoint = flipForWritingMode(child, IntPoint(tx, ty), ParentToChildFlippingAdjustment);
411128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            if (!child->hasSelfPaintingLayer() && !child->isFloating() && child->nodeAtPoint(request, result, x, y, childPoint.x(), childPoint.y(), childHitTest))
41128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
41138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
41148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
41158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
41178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
41188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPosition RenderBlock::positionForBox(InlineBox *box, bool start) const
41208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
41218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!box)
41228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return Position();
41238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!box->renderer()->node())
41258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return Position(node(), start ? caretMinOffset() : caretMaxOffset());
41268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!box->isInlineTextBox())
41288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return Position(box->renderer()->node(), start ? box->renderer()->caretMinOffset() : box->renderer()->caretMaxOffset());
41298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    InlineTextBox *textBox = static_cast<InlineTextBox *>(box);
41318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return Position(box->renderer()->node(), start ? textBox->start() : textBox->start() + textBox->len());
41328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
41338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// FIXME: This function should go on RenderObject as an instance method. Then
41355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian// all cases in which positionForPoint recurs could call this instead to
41368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// prevent crossing editable boundaries. This would require many tests.
41376b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerstatic VisiblePosition positionForPointRespectingEditingBoundaries(RenderBlock* parent, RenderBox* child, const IntPoint& pointInParentCoordinates)
41388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
41396b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // FIXME: This is wrong if the child's writing-mode is different from the parent's.
41405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    IntPoint pointInChildCoordinates(pointInParentCoordinates - child->location());
41418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If this is an anonymous renderer, we just recur normally
41438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Node* childNode = child->node();
41448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!childNode)
41455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return child->positionForPoint(pointInChildCoordinates);
41468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Otherwise, first make sure that the editability of the parent and child agree.
41488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If they don't agree, then we return a visible position just before or after the child
41498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* ancestor = parent;
41508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    while (ancestor && !ancestor->node())
41518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ancestor = ancestor->parent();
41528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If we can't find an ancestor to check editability on, or editability is unchanged, we recur like normal
41542bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!ancestor || ancestor->node()->rendererIsEditable() == childNode->rendererIsEditable())
41555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return child->positionForPoint(pointInChildCoordinates);
41568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41576b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // Otherwise return before or after the child, depending on if the click was to the logical left or logical right of the child
41586b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    int childMiddle = parent->logicalWidthForChild(child) / 2;
41592bde8e466a4451c7319e3a072d118917957d6554Steve Block    int logicalLeft = parent->isHorizontalWritingMode() ? pointInChildCoordinates.x() : pointInChildCoordinates.y();
41606b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (logicalLeft < childMiddle)
41618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return ancestor->createVisiblePosition(childNode->nodeIndex(), DOWNSTREAM);
41628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return ancestor->createVisiblePosition(childNode->nodeIndex() + 1, UPSTREAM);
41638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
41648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41656b70adc33054f8aee8c54d0f460458a9df11b8a5Russell BrennerVisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint& pointInLogicalContents)
41668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
41675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(childrenInline());
41688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (!firstRootBox())
41705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return createVisiblePosition(0, DOWNSTREAM);
41718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
41728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // look for the closest line box in the root box which is at the passed-in y coordinate
41735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    InlineBox* closestBox = 0;
41745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RootInlineBox* firstRootBoxWithChildren = 0;
41755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RootInlineBox* lastRootBoxWithChildren = 0;
41765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
4177643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (!root->firstLeafChild())
41785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            continue;
41795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (!firstRootBoxWithChildren)
41805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            firstRootBoxWithChildren = root;
41815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        lastRootBoxWithChildren = root;
41825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
41838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // check if this root line box is located at this y coordinate
41846b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (pointInLogicalContents.y() < root->selectionBottom()) {
41856b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            closestBox = root->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
41868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (closestBox)
41878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                break;
41888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
41898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
41908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4191545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    bool moveCaretToBoundary = document()->frame()->editor()->behavior().shouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom();
41925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
4193545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (!moveCaretToBoundary && !closestBox && lastRootBoxWithChildren) {
41945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // y coordinate is below last root line box, pretend we hit it
41956b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        closestBox = lastRootBoxWithChildren->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
41965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
41978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (closestBox) {
41996b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (moveCaretToBoundary && pointInLogicalContents.y() < firstRootBoxWithChildren->selectionTop()) {
42005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            // y coordinate is above first root line box, so return the start of the first
42015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            return VisiblePosition(positionForBox(firstRootBoxWithChildren->firstLeafChild(), true), DOWNSTREAM);
42025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
42035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
42046b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        // pass the box a top position that is inside it
42056b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        IntPoint point(pointInLogicalContents.x(), closestBox->logicalTop());
42062bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!isHorizontalWritingMode())
42076b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            point = point.transposedPoint();
42086b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (closestBox->renderer()->isReplaced())
42096b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            return positionForPointRespectingEditingBoundaries(this, toRenderBox(closestBox->renderer()), point);
42106b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        return closestBox->renderer()->positionForPoint(point);
42115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
42125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
42135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (lastRootBoxWithChildren) {
42145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // We hit this case for Mac behavior when the Y coordinate is below the last box.
4215545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        ASSERT(moveCaretToBoundary);
42162bde8e466a4451c7319e3a072d118917957d6554Steve Block        InlineBox* logicallyLastBox;
42172bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (lastRootBoxWithChildren->getLogicalEndBoxWithNode(logicallyLastBox))
42182bde8e466a4451c7319e3a072d118917957d6554Steve Block            return VisiblePosition(positionForBox(logicallyLastBox, false), DOWNSTREAM);
42198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
42208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
42215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Can't reach this. We have a root line box, but it has no kids.
42228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // FIXME: This should ASSERT_NOT_REACHED(), but clicking on placeholder text
42235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // seems to hit this code path.
42245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return createVisiblePosition(0, DOWNSTREAM);
42255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
42265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
42275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianstatic inline bool isChildHitTestCandidate(RenderBox* box)
42285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
42295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return box->height() && box->style()->visibility() == VISIBLE && !box->isFloatingOrPositioned();
42308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
42318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
42328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianVisiblePosition RenderBlock::positionForPoint(const IntPoint& point)
42338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
42348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (isTable())
42358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return RenderBox::positionForPoint(point);
42368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
42378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (isReplaced()) {
42386b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        // FIXME: This seems wrong when the object's writing-mode doesn't match the line's writing-mode.
42392bde8e466a4451c7319e3a072d118917957d6554Steve Block        int pointLogicalLeft = isHorizontalWritingMode() ? point.x() : point.y();
42402bde8e466a4451c7319e3a072d118917957d6554Steve Block        int pointLogicalTop = isHorizontalWritingMode() ? point.y() : point.x();
42416b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
42426b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (pointLogicalTop < 0 || (pointLogicalTop < logicalHeight() && pointLogicalLeft < 0))
42438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return createVisiblePosition(caretMinOffset(), DOWNSTREAM);
42446b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (pointLogicalTop >= logicalHeight() || (pointLogicalTop >= 0 && pointLogicalLeft >= logicalWidth()))
42458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return createVisiblePosition(caretMaxOffset(), DOWNSTREAM);
42468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
42478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
42485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    int contentsX = point.x();
42495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    int contentsY = point.y();
42505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    offsetForContents(contentsX, contentsY);
42515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    IntPoint pointInContents(contentsX, contentsY);
42526b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    IntPoint pointInLogicalContents(pointInContents);
42532bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!isHorizontalWritingMode())
42546b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        pointInLogicalContents = pointInLogicalContents.transposedPoint();
42558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
42565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (childrenInline())
42576b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        return positionForPointWithInlineChildren(pointInLogicalContents);
42588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
42596b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (lastChildBox() && pointInContents.y() > lastChildBox()->logicalTop()) {
42605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        for (RenderBox* childBox = lastChildBox(); childBox; childBox = childBox->previousSiblingBox()) {
42615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            if (isChildHitTestCandidate(childBox))
42625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents);
42635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
42645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    } else {
42655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
42665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            // We hit child if our click is above the bottom of its padding box (like IE6/7 and FF3).
42676b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            if (isChildHitTestCandidate(childBox) && pointInContents.y() < childBox->logicalBottom())
42685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents);
42695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
42708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
42718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
42725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // We only get here if there are no hit test candidate children below the click.
42738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return RenderBox::positionForPoint(point);
42748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
42758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4276635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::offsetForContents(int& tx, int& ty) const
4277635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
4278dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    IntPoint contentsPoint(tx, ty);
4279dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
4280635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (hasOverflowClip())
4281dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        contentsPoint += layer()->scrolledContentOffset();
4282635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
4283dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (hasColumns())
4284635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        adjustPointToColumnContents(contentsPoint);
4285dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
4286dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    tx = contentsPoint.x();
4287dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ty = contentsPoint.y();
4288635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
4289635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
429068513a70bcd92384395513322f1b801e7bf9c729Steve Blockint RenderBlock::availableLogicalWidth() const
429168513a70bcd92384395513322f1b801e7bf9c729Steve Block{
429268513a70bcd92384395513322f1b801e7bf9c729Steve Block    // If we have multiple columns, then the available logical width is reduced to our column width.
429368513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (hasColumns())
429468513a70bcd92384395513322f1b801e7bf9c729Steve Block        return desiredColumnWidth();
429568513a70bcd92384395513322f1b801e7bf9c729Steve Block    return RenderBox::availableLogicalWidth();
42968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
42978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
42988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderBlock::columnGap() const
42998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
43008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->hasNormalColumnGap())
43018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return style()->fontDescription().computedPixelSize(); // "1em" is recommended as the normal gap setting. Matches <p> margins.
43028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return static_cast<int>(style()->columnGap());
43038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
43048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
43058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::calcColumnWidth()
43068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
43078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Calculate our column width and column count.
43088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned desiredColumnCount = 1;
43092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int desiredColumnWidth = contentLogicalWidth();
43108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
43118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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.
4312f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    if (document()->paginated() || (style()->hasAutoColumnCount() && style()->hasAutoColumnWidth())) {
43138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
43148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
43158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
43168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
43178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int availWidth = desiredColumnWidth;
43188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int colGap = columnGap();
43198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int colWidth = max(1, static_cast<int>(style()->columnWidth()));
43208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int colCount = max(1, static_cast<int>(style()->columnCount()));
43218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
43222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (style()->hasAutoColumnWidth() && !style()->hasAutoColumnCount()) {
43232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        desiredColumnCount = colCount;
43242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        desiredColumnWidth = max<int>(0, (availWidth - ((desiredColumnCount - 1) * colGap)) / desiredColumnCount);
43252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    } else if (!style()->hasAutoColumnWidth() && style()->hasAutoColumnCount()) {
43262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        desiredColumnCount = max<int>(1, (float)(availWidth + colGap) / (colWidth + colGap));
43272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap;
43288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
43292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        desiredColumnCount = max(min<int>(colCount, (float)(availWidth + colGap) / (colWidth + colGap)), 1);
43302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap;
43318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
43328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
43338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
43348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
43358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::setDesiredColumnCountAndWidth(int count, int width)
43368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
43375af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    bool destroyColumns = !firstChild()
43385af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                          || (count == 1 && style()->hasAutoColumnWidth())
43395af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                          || firstChild()->isAnonymousColumnsBlock()
434068513a70bcd92384395513322f1b801e7bf9c729Steve Block                          || firstChild()->isAnonymousColumnSpanBlock();
43415af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (destroyColumns) {
43428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (hasColumns()) {
43438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            delete gColumnInfoMap->take(this);
43448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            setHasColumns(false);
43458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
43468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
43478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ColumnInfo* info;
43488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (hasColumns())
43498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            info = gColumnInfoMap->get(this);
43508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
43518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!gColumnInfoMap)
43528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                gColumnInfoMap = new ColumnInfoMap;
43538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            info = new ColumnInfo;
43548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            gColumnInfoMap->add(this, info);
43558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            setHasColumns(true);
43568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
43575abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        info->setDesiredColumnCount(count);
43585abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        info->setDesiredColumnWidth(width);
43598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
43608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
43618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
43628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderBlock::desiredColumnWidth() const
43638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
43648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!hasColumns())
43652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return contentLogicalWidth();
43665abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    return gColumnInfoMap->get(this)->desiredColumnWidth();
43678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
43688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
43698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectunsigned RenderBlock::desiredColumnCount() const
43708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
43718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!hasColumns())
43728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 1;
43735abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    return gColumnInfoMap->get(this)->desiredColumnCount();
43748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
43758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
43765abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain MerrickColumnInfo* RenderBlock::columnInfo() const
43778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
43788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!hasColumns())
43798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
43805abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    return gColumnInfoMap->get(this);
43818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
43828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
438368513a70bcd92384395513322f1b801e7bf9c729Steve Blockunsigned RenderBlock::columnCount(ColumnInfo* colInfo) const
43848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
438568513a70bcd92384395513322f1b801e7bf9c729Steve Block    ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo);
438668513a70bcd92384395513322f1b801e7bf9c729Steve Block    return colInfo->columnCount();
438768513a70bcd92384395513322f1b801e7bf9c729Steve Block}
43888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
438968513a70bcd92384395513322f1b801e7bf9c729Steve BlockIntRect RenderBlock::columnRectAt(ColumnInfo* colInfo, unsigned index) const
439068513a70bcd92384395513322f1b801e7bf9c729Steve Block{
439168513a70bcd92384395513322f1b801e7bf9c729Steve Block    ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo);
43928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
439368513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Compute the appropriate rect based off our information.
43942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int colLogicalWidth = colInfo->desiredColumnWidth();
43952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int colLogicalHeight = colInfo->columnHeight();
43962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int colLogicalTop = borderBefore() + paddingBefore();
43978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int colGap = columnGap();
43982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int colLogicalLeft = style()->isLeftToRightDirection() ?
43992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                          logicalLeftOffsetForContent() + (index * (colLogicalWidth + colGap))
44002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                        : logicalLeftOffsetForContent() + contentLogicalWidth() - colLogicalWidth - (index * (colLogicalWidth + colGap));
44012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    IntRect rect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
44022bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
44032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return IntRect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
44042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return IntRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogicalWidth);
440568513a70bcd92384395513322f1b801e7bf9c729Steve Block}
44068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4407f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochbool RenderBlock::layoutColumns(bool hasSpecifiedPageLogicalHeight, int pageLogicalHeight, LayoutStateMaintainer& statePusher)
440868513a70bcd92384395513322f1b801e7bf9c729Steve Block{
4409f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!hasColumns())
4410f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return false;
4411f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
4412f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // FIXME: We don't balance properly at all in the presence of forced page breaks.  We need to understand what
4413f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // the distance between forced page breaks is so that we can avoid making the minimum column height too tall.
4414f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    ColumnInfo* colInfo = columnInfo();
4415f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int desiredColumnCount = colInfo->desiredColumnCount();
4416f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!hasSpecifiedPageLogicalHeight) {
4417f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        int columnHeight = pageLogicalHeight;
4418f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        int minColumnCount = colInfo->forcedBreaks() + 1;
4419f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (minColumnCount >= desiredColumnCount) {
4420f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // The forced page breaks are in control of the balancing.  Just set the column height to the
4421f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // maximum page break distance.
4422f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            if (!pageLogicalHeight) {
4423f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                int distanceBetweenBreaks = max(colInfo->maximumDistanceBetweenForcedBreaks(),
44242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                                                view()->layoutState()->pageLogicalOffset(borderBefore() + paddingBefore() + contentLogicalHeight()) - colInfo->forcedBreakOffset());
4425f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                columnHeight = max(colInfo->minimumColumnHeight(), distanceBetweenBreaks);
442668513a70bcd92384395513322f1b801e7bf9c729Steve Block            }
44272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        } else if (contentLogicalHeight() > pageLogicalHeight * desiredColumnCount) {
4428f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // Now that we know the intrinsic height of the columns, we have to rebalance them.
44292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            columnHeight = max(colInfo->minimumColumnHeight(), (int)ceilf((float)contentLogicalHeight() / desiredColumnCount));
4430f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        }
44318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4432f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (columnHeight && columnHeight != pageLogicalHeight) {
4433f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            statePusher.pop();
4434f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            m_everHadLayout = true;
4435f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            layoutBlock(false, columnHeight);
4436f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            return true;
44378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4438f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
4439f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
4440f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (pageLogicalHeight)
44412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        colInfo->setColumnCountAndHeight(ceilf((float)contentLogicalHeight() / pageLogicalHeight), pageLogicalHeight);
4442f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
4443f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (columnCount(colInfo)) {
44442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        setLogicalHeight(borderBefore() + paddingBefore() + colInfo->columnHeight() + borderAfter() + paddingAfter() + scrollbarLogicalHeight());
4445f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        m_overflow.clear();
4446643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
44478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
444868513a70bcd92384395513322f1b801e7bf9c729Steve Block    return false;
44498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
44508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
44518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::adjustPointToColumnContents(IntPoint& point) const
44528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
44538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Just bail if we have no columns.
44548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!hasColumns())
44558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
44568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
44575abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    ColumnInfo* colInfo = columnInfo();
445868513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!columnCount(colInfo))
44595abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        return;
44608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
44618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Determine which columns we intersect.
44628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int colGap = columnGap();
44632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int halfColGap = colGap / 2;
446468513a70bcd92384395513322f1b801e7bf9c729Steve Block    IntPoint columnPoint(columnRectAt(colInfo, 0).location());
44652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int logicalOffset = 0;
44665abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    for (unsigned i = 0; i < colInfo->columnCount(); i++) {
44678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Add in half the column gap to the left and right of the rect.
446868513a70bcd92384395513322f1b801e7bf9c729Steve Block        IntRect colRect = columnRectAt(colInfo, i);
44692bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (isHorizontalWritingMode()) {
44702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            IntRect gapAndColumnRect(colRect.x() - halfColGap, colRect.y(), colRect.width() + colGap, colRect.height());
44712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRect.maxX()) {
44722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // FIXME: The clamping that follows is not completely right for right-to-left
44732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // content.
44742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // Clamp everything above the column to its top left.
44752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                if (point.y() < gapAndColumnRect.y())
44762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    point = gapAndColumnRect.location();
44772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // Clamp everything below the column to the next column's top left. If there is
44782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // no next column, this still maps to just after this column.
44792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                else if (point.y() >= gapAndColumnRect.maxY()) {
44802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    point = gapAndColumnRect.location();
44812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    point.move(0, gapAndColumnRect.height());
44822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                }
44832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
44842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // We're inside the column.  Translate the x and y into our column coordinate space.
44852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                point.move(columnPoint.x() - colRect.x(), logicalOffset);
44862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                return;
4487dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            }
44882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
44892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            // Move to the next position.
44902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            logicalOffset += colRect.height();
44912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        } else {
44922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            IntRect gapAndColumnRect(colRect.x(), colRect.y() - halfColGap, colRect.width(), colRect.height() + colGap);
44932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (point.y() >= gapAndColumnRect.y() && point.y() < gapAndColumnRect.maxY()) {
44942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // FIXME: The clamping that follows is not completely right for right-to-left
44952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // content.
44962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // Clamp everything above the column to its top left.
44972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                if (point.x() < gapAndColumnRect.x())
44982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    point = gapAndColumnRect.location();
44992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // Clamp everything below the column to the next column's top left. If there is
45002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // no next column, this still maps to just after this column.
45012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                else if (point.x() >= gapAndColumnRect.maxX()) {
45022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    point = gapAndColumnRect.location();
45032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    point.move(gapAndColumnRect.width(), 0);
45042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                }
4505dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
45062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                // We're inside the column.  Translate the x and y into our column coordinate space.
45072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                point.move(logicalOffset, columnPoint.y() - colRect.y());
45082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                return;
45092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            }
45102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
45112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            // Move to the next position.
45122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            logicalOffset += colRect.width();
45138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
45148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
45158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
45168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
45178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::adjustRectForColumns(IntRect& r) const
45188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
45198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Just bail if we have no columns.
45208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!hasColumns())
45218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
45228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
45235abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    ColumnInfo* colInfo = columnInfo();
45248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
45258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Begin with a result rect that is empty.
45268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    IntRect result;
45278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
45288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Determine which columns we intersect.
452968513a70bcd92384395513322f1b801e7bf9c729Steve Block    unsigned colCount = columnCount(colInfo);
45306c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (!colCount)
45316c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        return;
4532e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block
45332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int logicalLeft = logicalLeftOffsetForContent();
45342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int currLogicalOffset = 0;
45352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
45366c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    for (unsigned i = 0; i < colCount; i++) {
453768513a70bcd92384395513322f1b801e7bf9c729Steve Block        IntRect colRect = columnRectAt(colInfo, i);
45388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        IntRect repaintRect = r;
45392bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (isHorizontalWritingMode()) {
45402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int currXOffset = colRect.x() - logicalLeft;
45412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            repaintRect.move(currXOffset, currLogicalOffset);
45422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalOffset -= colRect.height();
45432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        } else {
45442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int currYOffset = colRect.y() - logicalLeft;
45452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            repaintRect.move(currLogicalOffset, currYOffset);
45462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            currLogicalOffset -= colRect.width();
45472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
45488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        repaintRect.intersect(colRect);
45498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result.unite(repaintRect);
45508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
45518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
45528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    r = result;
45538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
45548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
45552fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockIntPoint RenderBlock::flipForWritingModeIncludingColumns(const IntPoint& point) const
45562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
45572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ASSERT(hasColumns());
45582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
45592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return point;
45602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ColumnInfo* colInfo = columnInfo();
45612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int columnLogicalHeight = colInfo->columnHeight();
45622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
45632bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
45642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return IntPoint(point.x(), expandedLogicalHeight - point.y());
45652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return IntPoint(expandedLogicalHeight - point.x(), point.y());
45662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
45672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
45682fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid RenderBlock::flipForWritingModeIncludingColumns(IntRect& rect) const
45692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
45702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ASSERT(hasColumns());
45712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
45722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
45732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
45742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ColumnInfo* colInfo = columnInfo();
45752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int columnLogicalHeight = colInfo->columnHeight();
45762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
45772bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
45782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        rect.setY(expandedLogicalHeight - rect.maxY());
45792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    else
45802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        rect.setX(expandedLogicalHeight - rect.maxX());
45812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
45822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
4583692e5dbf12901edacf14812a6fae25462920af42Steve Blockvoid RenderBlock::adjustForColumns(IntSize& offset, const IntPoint& point) const
4584692e5dbf12901edacf14812a6fae25462920af42Steve Block{
4585692e5dbf12901edacf14812a6fae25462920af42Steve Block    if (!hasColumns())
4586692e5dbf12901edacf14812a6fae25462920af42Steve Block        return;
4587692e5dbf12901edacf14812a6fae25462920af42Steve Block
45885abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    ColumnInfo* colInfo = columnInfo();
45895abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
45902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int logicalLeft = logicalLeftOffsetForContent();
459168513a70bcd92384395513322f1b801e7bf9c729Steve Block    size_t colCount = columnCount(colInfo);
45922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int colLogicalWidth = colInfo->desiredColumnWidth();
45932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int colLogicalHeight = colInfo->columnHeight();
45942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
459568513a70bcd92384395513322f1b801e7bf9c729Steve Block    for (size_t i = 0; i < colCount; ++i) {
45962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        // Compute the edges for a given column in the block progression direction.
45972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        IntRect sliceRect = IntRect(logicalLeft, borderBefore() + paddingBefore() + i * colLogicalHeight, colLogicalWidth, colLogicalHeight);
45982bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!isHorizontalWritingMode())
45992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            sliceRect = sliceRect.transposedRect();
46002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
46012fc2651226baac27029e38c9d6ef883fa32084dbSteve 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).
46022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        flipForWritingModeIncludingColumns(sliceRect);
46032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
46042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int logicalOffset = style()->isFlippedBlocksWritingMode() ? (colCount - 1 - i) * colLogicalHeight : i * colLogicalHeight;
4605692e5dbf12901edacf14812a6fae25462920af42Steve Block
46062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        // Now we're in the same coordinate space as the point.  See if it is inside the rectangle.
46072bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (isHorizontalWritingMode()) {
46082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (point.y() >= sliceRect.y() && point.y() < sliceRect.maxY()) {
46092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                offset.expand(columnRectAt(colInfo, i).x() - logicalLeft, -logicalOffset);
46102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                return;
46112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            }
46122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        } else {
46132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (point.x() >= sliceRect.x() && point.x() < sliceRect.maxX()) {
46142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                offset.expand(-logicalOffset, columnRectAt(colInfo, i).y() - logicalLeft);
46152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                return;
46162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            }
46172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
4618692e5dbf12901edacf14812a6fae25462920af42Steve Block    }
4619692e5dbf12901edacf14812a6fae25462920af42Steve Block}
4620692e5dbf12901edacf14812a6fae25462920af42Steve Block
4621bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBlock::computePreferredLogicalWidths()
46228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4623bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    ASSERT(preferredLogicalWidthsDirty());
46248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    updateFirstLetter();
46268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4627a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!isTableCell() && style()->logicalWidth().isFixed() && style()->logicalWidth().value() > 0)
4628a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeContentBoxLogicalWidth(style()->logicalWidth().value());
46298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
4630bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_minPreferredLogicalWidth = 0;
4631bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_maxPreferredLogicalWidth = 0;
46328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (childrenInline())
4634bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            computeInlinePreferredLogicalWidths();
46358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
4636bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            computeBlockPreferredLogicalWidths();
46378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4638bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_maxPreferredLogicalWidth = max(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
46398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!style()->autoWrap() && childrenInline()) {
4641bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth;
46428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // A horizontal marquee with inline children has no minimum width.
46448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (layer() && layer()->marquee() && layer()->marquee()->isHorizontal())
4645bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                m_minPreferredLogicalWidth = 0;
46468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
46478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4648f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        int scrollbarWidth = 0;
4649f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (hasOverflowClip() && style()->overflowY() == OSCROLL) {
4650f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            layer()->setHasVerticalScrollbar(true);
4651f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            scrollbarWidth = verticalScrollbarWidth();
4652f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            m_maxPreferredLogicalWidth += scrollbarWidth;
4653f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        }
4654f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
46558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (isTableCell()) {
465628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            Length w = toRenderTableCell(this)->styleOrColLogicalWidth();
4657f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            if (w.isFixed() && w.value() > 0) {
4658bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                m_maxPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(w.value()));
4659f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                scrollbarWidth = 0;
4660f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            }
46618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4662f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
4663f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        m_minPreferredLogicalWidth += scrollbarWidth;
46648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
46658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4666a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (style()->logicalMinWidth().isFixed() && style()->logicalMinWidth().value() > 0) {
4667a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMinWidth().value()));
4668a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMinWidth().value()));
46698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
46708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4671a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (style()->logicalMaxWidth().isFixed() && style()->logicalMaxWidth().value() != undefinedLength) {
4672a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMaxWidth().value()));
4673a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMaxWidth().value()));
46748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
46758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4676f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int borderAndPadding = borderAndPaddingLogicalWidth();
4677f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    m_minPreferredLogicalWidth += borderAndPadding;
4678f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    m_maxPreferredLogicalWidth += borderAndPadding;
46798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4680bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    setPreferredLogicalWidthsDirty(false);
46818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
46828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstruct InlineMinMaxIterator {
46848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* InlineMinMaxIterator is a class that will iterate over all render objects that contribute to
46858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project   inline min/max width calculations.  Note the following about the way it walks:
46868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project   (1) Positioned content is skipped (since it does not contribute to min/max width of a block)
46878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project   (2) We do not drill into the children of floats or replaced elements, since you can't break
46888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project       in the middle of such an element.
46898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project   (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side can have
46908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project       distinct borders/margin/padding that contribute to the min/max width.
46918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project*/
46928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* parent;
46938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* current;
46948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool endOfInline;
46958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    InlineMinMaxIterator(RenderObject* p, bool end = false)
46978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        :parent(p), current(p), endOfInline(end) {}
46988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* next();
47008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
47018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderObject* InlineMinMaxIterator::next()
47038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
47048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* result = 0;
47058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool oldEndOfInline = endOfInline;
47068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    endOfInline = false;
47078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (current || current == parent) {
47088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!oldEndOfInline &&
47098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            (current == parent ||
47108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project             (!current->isFloating() && !current->isReplaced() && !current->isPositioned())))
47118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            result = current->firstChild();
47128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!result) {
47138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We hit the end of our inline. (It was empty, e.g., <span></span>.)
4714635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (!oldEndOfInline && current->isRenderInline()) {
47158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                result = current;
47168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                endOfInline = true;
47178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
47188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
47198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            while (current && current != parent) {
47218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                result = current->nextSibling();
47228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (result) break;
47238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                current = current->parent();
4724635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (current && current != parent && current->isRenderInline()) {
47258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    result = current;
47268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    endOfInline = true;
47278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
47288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
47298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
47308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
47318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!result)
47338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
47348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4735635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (!result->isPositioned() && (result->isText() || result->isFloating() || result->isReplaced() || result->isRenderInline()))
47368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project             break;
47378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        current = result;
47398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result = 0;
47408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
47418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Update our position.
47438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    current = result;
47448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return current;
47458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
47468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic int getBPMWidth(int childValue, Length cssUnit)
47488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
47498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (cssUnit.type() != Auto)
47508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return (cssUnit.isFixed() ? cssUnit.value() : childValue);
47518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
47528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
47538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic int getBorderPaddingMargin(const RenderBoxModelObject* child, bool endOfInline)
47558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
47568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderStyle* cstyle = child->style();
47572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (endOfInline)
47582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return getBPMWidth(child->marginEnd(), cstyle->marginEnd()) +
47592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block               getBPMWidth(child->paddingEnd(), cstyle->paddingEnd()) +
47602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block               child->borderEnd();
47612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return getBPMWidth(child->marginStart(), cstyle->marginStart()) +
47622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block               getBPMWidth(child->paddingStart(), cstyle->paddingStart()) +
47632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block               child->borderStart();
47648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
47658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
476681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic inline void stripTrailingSpace(float& inlineMax, float& inlineMin,
47678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                      RenderObject* trailingSpaceChild)
47688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
47698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (trailingSpaceChild && trailingSpaceChild->isText()) {
47708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Collapse away the trailing space at the end of a block.
4771635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        RenderText* t = toRenderText(trailingSpaceChild);
47728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const UChar space = ' ';
47738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const Font& font = t->style()->font(); // FIXME: This ignores first-line.
477481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        float spaceWidth = font.width(TextRun(&space, 1));
47758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        inlineMax -= spaceWidth + font.wordSpacing();
47768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (inlineMin > inlineMax)
47778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            inlineMin = inlineMax;
47788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
47798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
47808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
478181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic inline void updatePreferredWidth(int& preferredWidth, float& result)
478281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
478381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int snappedResult = ceilf(result);
478481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    preferredWidth = max(snappedResult, preferredWidth);
478581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
478681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
4787bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBlock::computeInlinePreferredLogicalWidths()
47888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
478981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    float inlineMax = 0;
479081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    float inlineMin = 0;
47918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int cw = containingBlock()->contentLogicalWidth();
47938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If we are at the start of a line, we want to ignore all white-space.
47958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Also strip spaces if we previously had text that ended in a trailing space.
47968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool stripFrontSpaces = true;
47978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* trailingSpaceChild = 0;
47988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
47998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Firefox and Opera will allow a table cell to grow to fit an image inside it under
48008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // very specific cirucumstances (in order to match common WinIE renderings).
48018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
48022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    bool allowImagesToBreak = !document()->inQuirksMode() || !isTableCell() || !style()->logicalWidth().isIntrinsicOrAuto();
48038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool autoWrap, oldAutoWrap;
48058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    autoWrap = oldAutoWrap = style()->autoWrap();
48068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    InlineMinMaxIterator childIterator(this);
48088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool addedTextIndent = false; // Only gets added in once.
48098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* prevFloat = 0;
48108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (RenderObject* child = childIterator.next()) {
48118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        autoWrap = child->isReplaced() ? child->parent()->style()->autoWrap() :
48128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            child->style()->autoWrap();
48138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!child->isBR()) {
48158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Step One: determine whether or not we need to go ahead and
48168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // terminate our current line.  Each discrete chunk can become
48178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // the new min-width, if it is the widest chunk seen so far, and
48188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // it can also become the max-width.
48198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Children fall into three categories:
48218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (1) An inline flow object.  These objects always have a min/max of 0,
48228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // and are included in the iteration solely so that their margins can
48238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // be added in.
48248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            //
48258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (2) An inline non-text non-flow object, e.g., an inline replaced element.
48268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // These objects can always be on a line by themselves, so in this situation
48278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // we need to go ahead and break the current line, and then add in our own
48288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // margins and min/max width on its own line, and then terminate the line.
48298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            //
48308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (3) A text object.  Text runs can have breakable characters at the start,
48318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // the middle or the end.  They may also lose whitespace off the front if
48328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // we're already ignoring whitespace.  In order to compute accurate min-width
48338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // information, we need three pieces of information.
48348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (a) the min-width of the first non-breakable run.  Should be 0 if the text string
48358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // starts with whitespace.
48368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (b) the min-width of the last non-breakable run. Should be 0 if the text string
48378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // ends with whitespace.
48388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (c) the min/max width of the string (trimmed for whitespace).
48398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            //
48408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // If the text string starts with whitespace, then we need to go ahead and
48418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // terminate our current line (unless we're already in a whitespace stripping
48428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // mode.
48438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            //
48448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // If the text string has a breakable character in the middle, but didn't start
48458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // with whitespace, then we add the width of the first non-breakable run and
48468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // then end the current line.  We then need to use the intermediate min/max width
48478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // values (if any of them are larger than our current min/max).  We then look at
48488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // the width of the last non-breakable run and use that to start a new line
48498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (unless we end in whitespace).
48508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderStyle* cstyle = child->style();
485181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            float childMin = 0;
485281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            float childMax = 0;
48538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!child->isText()) {
48558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Case (1) and (2).  Inline replaced and inline flow elements.
4856635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (child->isRenderInline()) {
48578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // Add in padding/border/margin from the appropriate side of
48588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // the element.
485981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    float bpm = getBorderPaddingMargin(toRenderInline(child), childIterator.endOfInline);
48608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    childMin += bpm;
48618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    childMax += bpm;
48628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMin += childMin;
48648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMax += childMax;
48658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4866bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                    child->setPreferredLogicalWidthsDirty(false);
48678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else {
48688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // Inline replaced elts add in their margins to their min/max values.
486981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    float margins = 0;
48702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    Length startMargin = cstyle->marginStart();
48712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    Length endMargin = cstyle->marginEnd();
48722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    if (startMargin.isFixed())
48732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                        margins += startMargin.value();
48742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    if (endMargin.isFixed())
48752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                        margins += endMargin.value();
48768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    childMin += margins;
48778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    childMax += margins;
48788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
48798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
48808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!child->isRenderInline() && !child->isText()) {
48828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Case (2). Inline replaced elements and floats.
48838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Go ahead and terminate the current line as far as
48848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // minwidth is concerned.
4885bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                childMin += child->minPreferredLogicalWidth();
4886bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                childMax += child->maxPreferredLogicalWidth();
48878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                bool clearPreviousFloat;
48898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (child->isFloating()) {
48908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    clearPreviousFloat = (prevFloat
48918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        && ((prevFloat->style()->floating() == FLEFT && (child->style()->clear() & CLEFT))
48928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                            || (prevFloat->style()->floating() == FRIGHT && (child->style()->clear() & CRIGHT))));
48938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    prevFloat = child;
48948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else
48958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    clearPreviousFloat = false;
48968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak;
48988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if ((canBreakReplacedElement && (autoWrap || oldAutoWrap)) || clearPreviousFloat) {
489981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
49008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMin = 0;
49018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
49028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // If we're supposed to clear the previous float, then terminate maxwidth as well.
49048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (clearPreviousFloat) {
490581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
49068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMax = 0;
49078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
49088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Add in text-indent.  This is added in only once.
49108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                int ti = 0;
49118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!addedTextIndent) {
49128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    addedTextIndent = true;
49138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    ti = style()->textIndent().calcMinValue(cw);
49142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    childMin += ti;
49152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    childMax += ti;
49168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
49178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Add our width to the max.
49198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                inlineMax += childMax;
49208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!autoWrap || !canBreakReplacedElement) {
49228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (child->isFloating())
492381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        updatePreferredWidth(m_minPreferredLogicalWidth, childMin);
49248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    else
49258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        inlineMin += childMin;
49268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else {
49278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // Now check our line.
492881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    updatePreferredWidth(m_minPreferredLogicalWidth, childMin);
49298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // Now start a new line.
49318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMin = 0;
49328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
49338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // We are no longer stripping whitespace at the start of
49358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // a line.
49368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!child->isFloating()) {
49378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    stripFrontSpaces = false;
49388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    trailingSpaceChild = 0;
49398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
49408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else if (child->isText()) {
49418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Case (3). Text.
4942635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                RenderText* t = toRenderText(child);
49438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (t->isWordBreak()) {
494581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
49468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMin = 0;
49478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
49488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
49498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49502bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (t->style()->hasTextCombine() && t->isCombineText())
49512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    toRenderCombineText(t)->combineText();
49522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
49538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Determine if we have a breakable character.  Pass in
49548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // whether or not we should ignore any spaces at the front
49558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // of the string.  If those are going to be stripped out,
49568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // then they shouldn't be considered in the breakable char
49578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // check.
49588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                bool hasBreakableChar, hasBreak;
495981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                float beginMin, endMin;
49608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                bool beginWS, endWS;
496181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                float beginMax, endMax;
49628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                t->trimmedPrefWidths(inlineMax, beginMin, beginWS, endMin, endWS,
49638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                     hasBreakableChar, hasBreak, beginMax, endMax,
49648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                     childMin, childMax, stripFrontSpaces);
49658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // This text object will not be rendered, but it may still provide a breaking opportunity.
49678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!hasBreak && childMax == 0) {
49688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (autoWrap && (beginWS || endWS)) {
496981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
49708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        inlineMin = 0;
49718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
49728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
49738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
49748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (stripFrontSpaces)
49768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    trailingSpaceChild = child;
49778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                else
49788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    trailingSpaceChild = 0;
49798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Add in text-indent.  This is added in only once.
49818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                int ti = 0;
49828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!addedTextIndent) {
49838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    addedTextIndent = true;
49848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    ti = style()->textIndent().calcMinValue(cw);
49858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    childMin+=ti; beginMin += ti;
49868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    childMax+=ti; beginMax += ti;
49878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
49888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // If we have no breakable characters at all,
49908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // then this is the easy case. We add ourselves to the current
49918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // min and max and continue.
49928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!hasBreakableChar) {
49938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMin += childMin;
49948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else {
49958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // We have a breakable character.  Now we need to know if
49968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // we start and end with whitespace.
49978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (beginWS)
49988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // Go ahead and end the current line.
499981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
50008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    else {
50018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        inlineMin += beginMin;
500281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
50038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        childMin -= ti;
50048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
50058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMin = childMin;
50078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (endWS) {
50098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // We end in whitespace, which means we can go ahead
50108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // and end our current line.
501181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
50128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        inlineMin = 0;
50138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    } else {
501481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
50158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        inlineMin = endMin;
50168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
50178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
50188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (hasBreak) {
50208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMax += beginMax;
502181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
502281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    updatePreferredWidth(m_maxPreferredLogicalWidth, childMax);
50238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMax = endMax;
50248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else
50258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineMax += childMax;
50268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
5027643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
5028643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            // Ignore spaces after a list marker.
5029643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (child->isListMarker())
5030643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                stripFrontSpaces = true;
50318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
503281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
503381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
50348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            inlineMin = inlineMax = 0;
50358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            stripFrontSpaces = true;
50368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            trailingSpaceChild = 0;
50378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
50388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        oldAutoWrap = autoWrap;
50408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
50418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->collapseWhiteSpace())
50438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        stripTrailingSpace(inlineMax, inlineMin, trailingSpaceChild);
50448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
504581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
504681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
50478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
50488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Use a very large value (in effect infinite).
50508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define BLOCK_MAX_WIDTH 15000
50518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5052bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBlock::computeBlockPreferredLogicalWidths()
50538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
50548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool nowrap = style()->whiteSpace() == NOWRAP;
50558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject *child = firstChild();
50578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int floatLeftWidth = 0, floatRightWidth = 0;
50588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (child) {
50598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Positioned children don't affect the min/max width
50608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (child->isPositioned()) {
50618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            child = child->nextSibling();
50628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
50638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
50648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (child->isFloating() || (child->isBox() && toRenderBox(child)->avoidsFloats())) {
50668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int floatTotalWidth = floatLeftWidth + floatRightWidth;
50678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (child->style()->clear() & CLEFT) {
5068bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                m_maxPreferredLogicalWidth = max(floatTotalWidth, m_maxPreferredLogicalWidth);
50698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatLeftWidth = 0;
50708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
50718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (child->style()->clear() & CRIGHT) {
5072bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                m_maxPreferredLogicalWidth = max(floatTotalWidth, m_maxPreferredLogicalWidth);
50738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatRightWidth = 0;
50748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
50758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
50768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // A margin basically has three types: fixed, percentage, and auto (variable).
50788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Auto and percentage margins simply become 0 when computing min/max width.
50798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Fixed margins can be added in as is.
50802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        Length startMarginLength = child->style()->marginStart();
50812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        Length endMarginLength = child->style()->marginEnd();
50822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int margin = 0;
50832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int marginStart = 0;
50842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int marginEnd = 0;
50852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (startMarginLength.isFixed())
50862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            marginStart += startMarginLength.value();
50872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (endMarginLength.isFixed())
50882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            marginEnd += endMarginLength.value();
50892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        margin = marginStart + marginEnd;
50908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5091bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        int w = child->minPreferredLogicalWidth() + margin;
5092bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_minPreferredLogicalWidth = max(w, m_minPreferredLogicalWidth);
50938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // IE ignores tables for calculation of nowrap. Makes some sense.
50958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (nowrap && !child->isTable())
5096bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            m_maxPreferredLogicalWidth = max(w, m_maxPreferredLogicalWidth);
50978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5098bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        w = child->maxPreferredLogicalWidth() + margin;
50998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
51008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!child->isFloating()) {
51018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (child->isBox() && toRenderBox(child)->avoidsFloats()) {
51028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Determine a left and right max value based off whether or not the floats can fit in the
51038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // margins of the object.  For negative margins, we will attempt to overlap the float if the negative margin
51048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // is smaller than the float width.
51052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                bool ltr = containingBlock()->style()->isLeftToRightDirection();
51062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int marginLogicalLeft = ltr ? marginStart : marginEnd;
51072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int marginLogicalRight = ltr ? marginEnd : marginStart;
51082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int maxLeft = marginLogicalLeft > 0 ? max(floatLeftWidth, marginLogicalLeft) : floatLeftWidth + marginLogicalLeft;
51092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                int maxRight = marginLogicalRight > 0 ? max(floatRightWidth, marginLogicalRight) : floatRightWidth + marginLogicalRight;
5110bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                w = child->maxPreferredLogicalWidth() + maxLeft + maxRight;
51118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                w = max(w, floatLeftWidth + floatRightWidth);
51128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
51138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
5114bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                m_maxPreferredLogicalWidth = max(floatLeftWidth + floatRightWidth, m_maxPreferredLogicalWidth);
51158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            floatLeftWidth = floatRightWidth = 0;
51168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
51178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
51188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (child->isFloating()) {
51198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (style()->floating() == FLEFT)
51208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatLeftWidth += w;
51218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
51228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                floatRightWidth += w;
51238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else
5124bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            m_maxPreferredLogicalWidth = max(w, m_maxPreferredLogicalWidth);
51258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
51268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // A very specific WinIE quirk.
51278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Example:
51288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        /*
51298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project           <div style="position:absolute; width:100px; top:50px;">
51308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project              <div style="position:absolute;left:0px;top:50px;height:50px;background-color:green">
51318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                <table style="width:100%"><tr><td></table>
51328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project              </div>
51338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project           </div>
51348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        */
51358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // In the above example, the inner absolute positioned block should have a computed width
51368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // of 100px because of the table.
51378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We can achieve this effect by making the maxwidth of blocks that contain tables
51388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // with percentage widths be infinite (as long as they are not inside a table cell).
51392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (document()->inQuirksMode() && child->style()->logicalWidth().isPercent() &&
5140bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            !isTableCell() && child->isTable() && m_maxPreferredLogicalWidth < BLOCK_MAX_WIDTH) {
51418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderBlock* cb = containingBlock();
51428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            while (!cb->isRenderView() && !cb->isTableCell())
51438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                cb = cb->containingBlock();
51448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!cb->isTableCell())
5145bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                m_maxPreferredLogicalWidth = BLOCK_MAX_WIDTH;
51468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
51478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
51488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child = child->nextSibling();
51498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
51508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
51518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Always make sure these values are non-negative.
5152bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_minPreferredLogicalWidth = max(0, m_minPreferredLogicalWidth);
5153bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_maxPreferredLogicalWidth = max(0, m_maxPreferredLogicalWidth);
51548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5155bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_maxPreferredLogicalWidth = max(floatLeftWidth + floatRightWidth, m_maxPreferredLogicalWidth);
51568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
51578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
51588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::hasLineIfEmpty() const
51598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
51600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!node())
51610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return false;
51620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
51632bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (node()->rendererIsEditable() && node()->rootEditableElement() == node())
51640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return true;
51650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5166cad810f21b803229eb11403f9209855525a25d57Steve Block    if (node()->isShadowRoot() && (node()->shadowHost()->hasTagName(inputTag)))
51670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return true;
51680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
51690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return false;
51708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
51718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5172a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::lineHeight(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
51738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
51748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Inline blocks are replaced elements. Otherwise, just pass off to
51758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the base class.  If we're being queried as though we're the root line
51768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // box, then the fact that we're an inline-block is irrelevant, and we behave
51778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // just like a block.
5178a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (isReplaced() && linePositionMode == PositionOnContainingLine)
5179a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return RenderBox::lineHeight(firstLine, direction, linePositionMode);
5180a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
51818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (firstLine && document()->usesFirstLineRules()) {
51828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderStyle* s = style(firstLine);
51838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (s != style())
51848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return s->computedLineHeight();
51858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
51868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
51878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_lineHeight == -1)
51888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_lineHeight = style()->computedLineHeight();
51898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
51908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return m_lineHeight;
51918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
51928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
51936b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerint RenderBlock::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
51948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
51958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Inline blocks are replaced elements. Otherwise, just pass off to
51968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the base class.  If we're being queried as though we're the root line
51978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // box, then the fact that we're an inline-block is irrelevant, and we behave
51988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // just like a block.
5199a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (isReplaced() && linePositionMode == PositionOnContainingLine) {
52008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // For "leaf" theme objects, let the theme decide what the baseline position is.
52018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: Might be better to have a custom CSS property instead, so that if the theme
52028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // is turned off, checkboxes/radios will still have decent baselines.
5203a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // FIXME: Need to patch form controls to deal with vertical lines.
52048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (style()->hasAppearance() && !theme()->isControlContainer(style()->appearance()))
52058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return theme()->baselinePosition(this);
52068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
52078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // CSS2.1 states that the baseline of an inline block is the baseline of the last line box in
52088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // the normal flow.  We make an exception for marquees, since their baselines are meaningless
52098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // (the content inside them moves).  This matches WinIE as well, which just bottom-aligns them.
52108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We also give up on finding a baseline if we have a vertical scrollbar, or if we are scrolled
52118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // vertically (e.g., an overflow:hidden block that has had scrollTop moved) or if the baseline is outside
52128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // of our content box.
5213a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        bool ignoreBaseline = (layer() && (layer()->marquee() || (direction == HorizontalLine ? (layer()->verticalScrollbar() || layer()->scrollYOffset() != 0)
52146b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            : (layer()->horizontalScrollbar() || layer()->scrollXOffset() != 0)))) || (isWritingModeRoot() && !isRubyRun());
52156b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
5216a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int baselinePos = ignoreBaseline ? -1 : lastLineBoxBaseline();
5217a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
5218a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        int bottomOfContent = direction == HorizontalLine ? borderTop() + paddingTop() + contentHeight() : borderRight() + paddingRight() + contentWidth();
5219a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (baselinePos != -1 && baselinePos <= bottomOfContent)
5220a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            return direction == HorizontalLine ? marginTop() + baselinePos : marginRight() + baselinePos;
5221a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
52226b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
52238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5224a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
52252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    const FontMetrics& fontMetrics = style(firstLine)->fontMetrics();
52262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2;
52278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
52288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
52298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianint RenderBlock::firstLineBoxBaseline() const
52308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
52316b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (!isBlockFlow() || (isWritingModeRoot() && !isRubyRun()))
52328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return -1;
52338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
52348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childrenInline()) {
52358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (firstLineBox())
52362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return firstLineBox()->logicalTop() + style(true)->fontMetrics().ascent(firstRootBox()->baselineType());
52378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
52388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return -1;
52398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
52408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
5241635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        for (RenderBox* curr = firstChildBox(); curr; curr = curr->nextSiblingBox()) {
52428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!curr->isFloatingOrPositioned()) {
52438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                int result = curr->firstLineBoxBaseline();
52448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (result != -1)
5245a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    return curr->logicalTop() + result; // Translate to our coordinate space.
52468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
52478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
52488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
52498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
52508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return -1;
52518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
52528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
52538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianint RenderBlock::lastLineBoxBaseline() const
52548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
52556b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (!isBlockFlow() || (isWritingModeRoot() && !isRubyRun()))
52568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return -1;
52578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
52582bde8e466a4451c7319e3a072d118917957d6554Steve Block    LineDirectionMode lineDirection = isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
5259a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
52608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childrenInline()) {
5261a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!firstLineBox() && hasLineIfEmpty()) {
52622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
52632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return fontMetrics.ascent()
52642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                 + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
52652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
5266a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
52678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (lastLineBox())
52682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->fontMetrics().ascent(lastRootBox()->baselineType());
52698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return -1;
5270a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else {
52718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool haveNormalFlowChild = false;
5272635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        for (RenderBox* curr = lastChildBox(); curr; curr = curr->previousSiblingBox()) {
52738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!curr->isFloatingOrPositioned()) {
52748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                haveNormalFlowChild = true;
52758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                int result = curr->lastLineBoxBaseline();
52768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (result != -1)
5277a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    return curr->logicalTop() + result; // Translate to our coordinate space.
52788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
52798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5280a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!haveNormalFlowChild && hasLineIfEmpty()) {
52812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
52822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return fontMetrics.ascent()
52832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                 + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
52842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
5285a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
52868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
52878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
52888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return -1;
52898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
52908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5291635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool RenderBlock::containsNonZeroBidiLevel() const
5292635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
5293635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
5294635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        for (InlineBox* box = root->firstLeafChild(); box; box = box->nextLeafChild()) {
5295635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (box->bidiLevel())
5296635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                return true;
5297635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
5298635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
5299635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return false;
5300635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
5301635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
53028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderBlock* RenderBlock::firstLineBlock() const
53038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5304635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderBlock* firstLineBlock = const_cast<RenderBlock*>(this);
53058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool hasPseudo = false;
53068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (true) {
53078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        hasPseudo = firstLineBlock->style()->hasPseudoStyle(FIRST_LINE);
53088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (hasPseudo)
53098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
53108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderObject* parentBlock = firstLineBlock->parent();
53118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (firstLineBlock->isReplaced() || firstLineBlock->isFloating() ||
53128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            !parentBlock || parentBlock->firstChild() != firstLineBlock || !parentBlock->isBlockFlow())
53138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
5314635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        ASSERT(parentBlock->isRenderBlock());
53158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        firstLineBlock = toRenderBlock(parentBlock);
53168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
53178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
53188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!hasPseudo)
53198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
53208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5321635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return firstLineBlock;
53228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
53238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
532468513a70bcd92384395513322f1b801e7bf9c729Steve Blockstatic RenderStyle* styleForFirstLetter(RenderObject* firstLetterBlock, RenderObject* firstLetterContainer)
532568513a70bcd92384395513322f1b801e7bf9c729Steve Block{
532668513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderStyle* pseudoStyle = firstLetterBlock->getCachedPseudoStyle(FIRST_LETTER, firstLetterContainer->firstLineStyle());
532768513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Force inline display (except for floating first-letters).
532868513a70bcd92384395513322f1b801e7bf9c729Steve Block    pseudoStyle->setDisplay(pseudoStyle->isFloating() ? BLOCK : INLINE);
532968513a70bcd92384395513322f1b801e7bf9c729Steve Block    // CSS2 says first-letter can't be positioned.
533068513a70bcd92384395513322f1b801e7bf9c729Steve Block    pseudoStyle->setPosition(StaticPosition);
533168513a70bcd92384395513322f1b801e7bf9c729Steve Block    return pseudoStyle;
533268513a70bcd92384395513322f1b801e7bf9c729Steve Block}
533368513a70bcd92384395513322f1b801e7bf9c729Steve Block
5334a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch// CSS 2.1 http://www.w3.org/TR/CSS21/selector.html#first-letter
5335a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch// "Punctuation (i.e, characters defined in Unicode [UNICODE] in the "open" (Ps), "close" (Pe),
5336a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch// "initial" (Pi). "final" (Pf) and "other" (Po) punctuation classes), that precedes or follows the first letter should be included"
5337a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic inline bool isPunctuationForFirstLetter(UChar c)
5338a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
5339a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    CharCategory charCategory = category(c);
5340a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return charCategory == Punctuation_Open
5341a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        || charCategory == Punctuation_Close
5342a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        || charCategory == Punctuation_InitialQuote
5343a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        || charCategory == Punctuation_FinalQuote
5344a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        || charCategory == Punctuation_Other;
5345a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
5346a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
5347a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic inline bool shouldSkipForFirstLetter(UChar c)
5348a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
5349a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return isSpaceOrNewline(c) || c == noBreakSpace || isPunctuationForFirstLetter(c);
5350a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
5351a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
53528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::updateFirstLetter()
53538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
53548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!document()->usesFirstLetterRules())
53558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
53568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Don't recur
53578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (style()->styleType() == FIRST_LETTER)
53588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
53598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
53608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: We need to destroy the first-letter object if it is no longer the first child.  Need to find
53618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // an efficient way to check for that situation though before implementing anything.
53628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* firstLetterBlock = this;
53638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool hasPseudoStyle = false;
53648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (true) {
53658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We only honor first-letter if the firstLetterBlock can have children in the DOM. This correctly
53668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // prevents form controls from honoring first-letter.
53678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        hasPseudoStyle = firstLetterBlock->style()->hasPseudoStyle(FIRST_LETTER)
53688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            && firstLetterBlock->canHaveChildren();
53698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (hasPseudoStyle)
53708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
53718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderObject* parentBlock = firstLetterBlock->parent();
53728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (firstLetterBlock->isReplaced() || !parentBlock || parentBlock->firstChild() != firstLetterBlock ||
53738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            !parentBlock->isBlockFlow())
53748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
53758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        firstLetterBlock = parentBlock;
53768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
53778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
53788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!hasPseudoStyle)
53798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
53808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
53818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Drill into inlines looking for our first text child.
53828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* currChild = firstLetterBlock->firstChild();
538335acba539f15b03afbe4071047898b72153fa1a8Steve Block    while (currChild) {
538435acba539f15b03afbe4071047898b72153fa1a8Steve Block        if (currChild->isText())
538535acba539f15b03afbe4071047898b72153fa1a8Steve Block            break;
538635acba539f15b03afbe4071047898b72153fa1a8Steve Block        if (currChild->isListMarker())
538735acba539f15b03afbe4071047898b72153fa1a8Steve Block            currChild = currChild->nextSibling();
538835acba539f15b03afbe4071047898b72153fa1a8Steve Block        else if (currChild->isFloatingOrPositioned()) {
53896c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            if (currChild->style()->styleType() == FIRST_LETTER) {
53906c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen                currChild = currChild->firstChild();
53918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
539235acba539f15b03afbe4071047898b72153fa1a8Steve Block            }
53938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            currChild = currChild->nextSibling();
539435acba539f15b03afbe4071047898b72153fa1a8Steve Block        } else if (currChild->isReplaced() || currChild->isRenderButton() || currChild->isMenuList())
539535acba539f15b03afbe4071047898b72153fa1a8Steve Block            break;
53960b6461e8a4be51c556f77873d5ec18767cb26f58Steve Block        else if (currChild->style()->hasPseudoStyle(FIRST_LETTER) && currChild->canHaveChildren())  {
53970b6461e8a4be51c556f77873d5ec18767cb26f58Steve Block            // We found a lower-level node with first-letter, which supersedes the higher-level style
53980b6461e8a4be51c556f77873d5ec18767cb26f58Steve Block            firstLetterBlock = currChild;
53990b6461e8a4be51c556f77873d5ec18767cb26f58Steve Block            currChild = currChild->firstChild();
54000b6461e8a4be51c556f77873d5ec18767cb26f58Steve Block        }
540135acba539f15b03afbe4071047898b72153fa1a8Steve Block        else
54028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            currChild = currChild->firstChild();
54038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
54048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
54058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!currChild)
54068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
54078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
54088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the child already has style, then it has already been created, so we just want
54098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // to update it.
541068513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (currChild->parent()->style()->styleType() == FIRST_LETTER) {
541168513a70bcd92384395513322f1b801e7bf9c729Steve Block        RenderObject* firstLetter = currChild->parent();
541268513a70bcd92384395513322f1b801e7bf9c729Steve Block        RenderObject* firstLetterContainer = firstLetter->parent();
541368513a70bcd92384395513322f1b801e7bf9c729Steve Block        RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
541468513a70bcd92384395513322f1b801e7bf9c729Steve Block
541568513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (Node::diff(firstLetter->style(), pseudoStyle) == Node::Detach) {
541668513a70bcd92384395513322f1b801e7bf9c729Steve Block            // The first-letter renderer needs to be replaced. Create a new renderer of the right type.
541768513a70bcd92384395513322f1b801e7bf9c729Steve Block            RenderObject* newFirstLetter;
541868513a70bcd92384395513322f1b801e7bf9c729Steve Block            if (pseudoStyle->display() == INLINE)
541968513a70bcd92384395513322f1b801e7bf9c729Steve Block                newFirstLetter = new (renderArena()) RenderInline(document());
542068513a70bcd92384395513322f1b801e7bf9c729Steve Block            else
542168513a70bcd92384395513322f1b801e7bf9c729Steve Block                newFirstLetter = new (renderArena()) RenderBlock(document());
542268513a70bcd92384395513322f1b801e7bf9c729Steve Block            newFirstLetter->setStyle(pseudoStyle);
542368513a70bcd92384395513322f1b801e7bf9c729Steve Block
542468513a70bcd92384395513322f1b801e7bf9c729Steve Block            // Move the first letter into the new renderer.
542568513a70bcd92384395513322f1b801e7bf9c729Steve Block            view()->disableLayoutState();
542668513a70bcd92384395513322f1b801e7bf9c729Steve Block            while (RenderObject* child = firstLetter->firstChild()) {
542768513a70bcd92384395513322f1b801e7bf9c729Steve Block                if (child->isText())
54282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    toRenderText(child)->removeAndDestroyTextBoxes();
542968513a70bcd92384395513322f1b801e7bf9c729Steve Block                firstLetter->removeChild(child);
543068513a70bcd92384395513322f1b801e7bf9c729Steve Block                newFirstLetter->addChild(child, 0);
543168513a70bcd92384395513322f1b801e7bf9c729Steve Block            }
543281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
543381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            RenderTextFragment* remainingText = 0;
543481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            RenderObject* nextSibling = firstLetter->nextSibling();
543581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            RenderObject* next = nextSibling;
543681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            while (next) {
543781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (next->isText() && toRenderText(next)->isTextFragment()) {
543881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    remainingText = toRenderTextFragment(next);
543981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    break;
544081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                }
544181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                next = next->nextSibling();
544281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
544381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (remainingText) {
544481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                ASSERT(remainingText->node()->renderer() == remainingText);
544581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                // Replace the old renderer with the new one.
544681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                remainingText->setFirstLetter(newFirstLetter);
544781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
544868513a70bcd92384395513322f1b801e7bf9c729Steve Block            firstLetter->destroy();
544968513a70bcd92384395513322f1b801e7bf9c729Steve Block            firstLetter = newFirstLetter;
545081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            firstLetterContainer->addChild(firstLetter, nextSibling);
545168513a70bcd92384395513322f1b801e7bf9c729Steve Block            view()->enableLayoutState();
545268513a70bcd92384395513322f1b801e7bf9c729Steve Block        } else
545368513a70bcd92384395513322f1b801e7bf9c729Steve Block            firstLetter->setStyle(pseudoStyle);
545468513a70bcd92384395513322f1b801e7bf9c729Steve Block
545568513a70bcd92384395513322f1b801e7bf9c729Steve Block        for (RenderObject* genChild = firstLetter->firstChild(); genChild; genChild = genChild->nextSibling()) {
54568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (genChild->isText())
545768513a70bcd92384395513322f1b801e7bf9c729Steve Block                genChild->setStyle(pseudoStyle);
54588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
545968513a70bcd92384395513322f1b801e7bf9c729Steve Block
54608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
54618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
54628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
546368513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!currChild->isText() || currChild->isBR())
546468513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
546568513a70bcd92384395513322f1b801e7bf9c729Steve Block
54668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the child does not already have style, we create it here.
546768513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderObject* firstLetterContainer = currChild->parent();
54688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
546968513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Our layout state is not valid for the repaints we are going to trigger by
547068513a70bcd92384395513322f1b801e7bf9c729Steve Block    // adding and removing children of firstLetterContainer.
547168513a70bcd92384395513322f1b801e7bf9c729Steve Block    view()->disableLayoutState();
547268513a70bcd92384395513322f1b801e7bf9c729Steve Block
547368513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderText* textObj = toRenderText(currChild);
547468513a70bcd92384395513322f1b801e7bf9c729Steve Block
547568513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Create our pseudo style now that we have our firstLetterContainer determined.
547668513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
547768513a70bcd92384395513322f1b801e7bf9c729Steve Block
547868513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderObject* firstLetter = 0;
547968513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (pseudoStyle->display() == INLINE)
548068513a70bcd92384395513322f1b801e7bf9c729Steve Block        firstLetter = new (renderArena()) RenderInline(document());
548168513a70bcd92384395513322f1b801e7bf9c729Steve Block    else
548268513a70bcd92384395513322f1b801e7bf9c729Steve Block        firstLetter = new (renderArena()) RenderBlock(document());
548368513a70bcd92384395513322f1b801e7bf9c729Steve Block    firstLetter->setStyle(pseudoStyle);
548468513a70bcd92384395513322f1b801e7bf9c729Steve Block    firstLetterContainer->addChild(firstLetter, currChild);
548568513a70bcd92384395513322f1b801e7bf9c729Steve Block
548668513a70bcd92384395513322f1b801e7bf9c729Steve Block    // The original string is going to be either a generated content string or a DOM node's
548768513a70bcd92384395513322f1b801e7bf9c729Steve Block    // string.  We want the original string before it got transformed in case first-letter has
548868513a70bcd92384395513322f1b801e7bf9c729Steve Block    // no text-transform or a different text-transform applied to it.
548968513a70bcd92384395513322f1b801e7bf9c729Steve Block    RefPtr<StringImpl> oldText = textObj->originalText();
549068513a70bcd92384395513322f1b801e7bf9c729Steve Block    ASSERT(oldText);
549168513a70bcd92384395513322f1b801e7bf9c729Steve Block
549268513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (oldText && oldText->length() > 0) {
549368513a70bcd92384395513322f1b801e7bf9c729Steve Block        unsigned length = 0;
549468513a70bcd92384395513322f1b801e7bf9c729Steve Block
5495a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // Account for leading spaces and punctuation.
5496a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        while (length < oldText->length() && shouldSkipForFirstLetter((*oldText)[length]))
54978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            length++;
54988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5499a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // Account for first letter.
550068513a70bcd92384395513322f1b801e7bf9c729Steve Block        length++;
5501a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
5502a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // Keep looking for whitespace and allowed punctuation, but avoid
5503a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // accumulating just whitespace into the :first-letter.
5504a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        for (unsigned scanLength = length; scanLength < oldText->length(); ++scanLength) {
5505a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            UChar c = (*oldText)[scanLength];
5506a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
5507a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (!shouldSkipForFirstLetter(c))
5508a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                break;
550968513a70bcd92384395513322f1b801e7bf9c729Steve Block
5510a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (isPunctuationForFirstLetter(c))
5511a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                length = scanLength + 1;
5512a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch         }
5513a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
5514a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // Construct a text fragment for the text after the first letter.
5515a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // This text fragment might be empty.
551668513a70bcd92384395513322f1b801e7bf9c729Steve Block        RenderTextFragment* remainingText =
551768513a70bcd92384395513322f1b801e7bf9c729Steve Block            new (renderArena()) RenderTextFragment(textObj->node() ? textObj->node() : textObj->document(), oldText.get(), length, oldText->length() - length);
551868513a70bcd92384395513322f1b801e7bf9c729Steve Block        remainingText->setStyle(textObj->style());
551968513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (remainingText->node())
552068513a70bcd92384395513322f1b801e7bf9c729Steve Block            remainingText->node()->setRenderer(remainingText);
552168513a70bcd92384395513322f1b801e7bf9c729Steve Block
5522ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        firstLetterContainer->addChild(remainingText, textObj);
552368513a70bcd92384395513322f1b801e7bf9c729Steve Block        firstLetterContainer->removeChild(textObj);
552468513a70bcd92384395513322f1b801e7bf9c729Steve Block        remainingText->setFirstLetter(firstLetter);
552568513a70bcd92384395513322f1b801e7bf9c729Steve Block
552668513a70bcd92384395513322f1b801e7bf9c729Steve Block        // construct text fragment for the first letter
552768513a70bcd92384395513322f1b801e7bf9c729Steve Block        RenderTextFragment* letter =
552868513a70bcd92384395513322f1b801e7bf9c729Steve Block            new (renderArena()) RenderTextFragment(remainingText->node() ? remainingText->node() : remainingText->document(), oldText.get(), 0, length);
552968513a70bcd92384395513322f1b801e7bf9c729Steve Block        letter->setStyle(pseudoStyle);
553068513a70bcd92384395513322f1b801e7bf9c729Steve Block        firstLetter->addChild(letter);
553168513a70bcd92384395513322f1b801e7bf9c729Steve Block
553268513a70bcd92384395513322f1b801e7bf9c729Steve Block        textObj->destroy();
55338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
553468513a70bcd92384395513322f1b801e7bf9c729Steve Block    view()->enableLayoutState();
55358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
55368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
55378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Helper methods for obtaining the last line, computing line counts and heights for line counts
55388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// (crawling into blocks).
55398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool shouldCheckLines(RenderObject* obj)
55408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5541635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return !obj->isFloatingOrPositioned() && !obj->isRunIn() &&
55428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            obj->isBlockFlow() && obj->style()->height().isAuto() &&
55438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            (!obj->isFlexibleBox() || obj->style()->boxOrient() == VERTICAL);
55448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
55458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
55468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic RootInlineBox* getLineAtIndex(RenderBlock* block, int i, int& count)
55478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
55488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (block->style()->visibility() == VISIBLE) {
55498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (block->childrenInline()) {
55508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) {
55518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (count++ == i)
55528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    return box;
55538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
55548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
55558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
55568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RenderObject* obj = block->firstChild(); obj; obj = obj->nextSibling()) {
55578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (shouldCheckLines(obj)) {
55588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    RootInlineBox *box = getLineAtIndex(toRenderBlock(obj), i, count);
55598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (box)
55608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        return box;
55618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
55628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
55638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
55648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
55658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
55668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
55678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5568635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic int getHeightForLineCount(RenderBlock* block, int l, bool includeBottom, int& count)
55698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
55708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (block->style()->visibility() == VISIBLE) {
55718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (block->childrenInline()) {
55728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) {
55738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (++count == l)
5574231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    return box->lineBottom() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : 0);
55758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
55768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
55778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
5578635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            RenderBox* normalFlowChildWithoutLines = 0;
5579635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            for (RenderBox* obj = block->firstChildBox(); obj; obj = obj->nextSiblingBox()) {
55808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (shouldCheckLines(obj)) {
55818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    int result = getHeightForLineCount(toRenderBlock(obj), l, false, count);
55828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (result != -1)
5583635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                        return result + obj->y() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : 0);
55848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
5585635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                else if (!obj->isFloatingOrPositioned() && !obj->isRunIn())
55868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    normalFlowChildWithoutLines = obj;
55878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
55888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (normalFlowChildWithoutLines && l == 0)
5589635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                return normalFlowChildWithoutLines->y() + normalFlowChildWithoutLines->height();
55908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
55918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
55928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
55938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return -1;
55948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
55958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
55968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRootInlineBox* RenderBlock::lineAtIndex(int i)
55978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
55988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int count = 0;
55998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return getLineAtIndex(this, i, count);
56008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
56018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
56028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderBlock::lineCount()
56038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
56048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int count = 0;
56058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->visibility() == VISIBLE) {
56068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (childrenInline())
56078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
56088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                count++;
56098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
56108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling())
56118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (shouldCheckLines(obj))
56128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    count += toRenderBlock(obj)->lineCount();
56138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
56148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return count;
56158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
56168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
56178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderBlock::heightForLineCount(int l)
56188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
56198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int count = 0;
56208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return getHeightForLineCount(this, l, true, count);
56218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
56228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
56238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::adjustForBorderFit(int x, int& left, int& right) const
56248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
56258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We don't deal with relative positioning.  Our assumption is that you shrink to fit the lines without accounting
56268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // for either overflow or translations via relative positioning.
56278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->visibility() == VISIBLE) {
56288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (childrenInline()) {
56298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) {
56308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (box->firstChild())
563181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    left = min(left, x + static_cast<int>(box->firstChild()->x()));
56328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (box->lastChild())
563381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    right = max(right, x + static_cast<int>(ceilf(box->lastChild()->logicalRight())));
56348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
56358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
56368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
5637635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            for (RenderBox* obj = firstChildBox(); obj; obj = obj->nextSiblingBox()) {
56388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!obj->isFloatingOrPositioned()) {
56398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (obj->isBlockFlow() && !obj->hasOverflowClip())
56408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        toRenderBlock(obj)->adjustForBorderFit(x + obj->x(), left, right);
56418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    else if (obj->style()->visibility() == VISIBLE) {
56428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // We are a replaced element or some kind of non-block-flow object.
5643635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                        left = min(left, x + obj->x());
5644635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                        right = max(right, x + obj->x() + obj->width());
56458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
56468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
56478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
56488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
56498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
56508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_floatingObjects) {
565181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
565281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            FloatingObjectSetIterator end = floatingObjectSet.end();
565381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
565481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                FloatingObject* r = *it;
56558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Only examine the object if our m_shouldPaint flag is set.
56568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (r->m_shouldPaint) {
56572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    int floatLeft = xPositionForFloatIncludingMargin(r) - r->m_renderer->x();
56588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    int floatRight = floatLeft + r->m_renderer->width();
56598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    left = min(left, floatLeft);
56608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    right = max(right, floatRight);
56618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
56628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
56638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
56648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
56658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
56668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
56678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::borderFitAdjust(int& x, int& w) const
56688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
56698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->borderFit() == BorderFitBorder)
56708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
56718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
56728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Walk any normal flow lines to snugly fit.
56738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int left = INT_MAX;
56748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int right = INT_MIN;
56758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int oldWidth = w;
56768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    adjustForBorderFit(0, left, right);
56778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (left != INT_MAX) {
56788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        left -= (borderLeft() + paddingLeft());
56798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (left > 0) {
56808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            x += left;
56818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            w -= left;
56828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
56838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
56848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (right != INT_MIN) {
56858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        right += (borderRight() + paddingRight());
56868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (right < oldWidth)
56878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            w -= (oldWidth - right);
56888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
56898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
56908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
56918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::clearTruncation()
56928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
56938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->visibility() == VISIBLE) {
56948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (childrenInline() && hasMarkupTruncation()) {
56958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            setHasMarkupTruncation(false);
56968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
56978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                box->clearTruncation();
56988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
56998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
57008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling())
57018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (shouldCheckLines(obj))
57028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    toRenderBlock(obj)->clearTruncation();
57038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
57048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
57058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5706bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBlock::setMaxMarginBeforeValues(int pos, int neg)
57078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
570868513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!m_rareData) {
5709a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (pos == RenderBlockRareData::positiveMarginBeforeDefault(this) && neg == RenderBlockRareData::negativeMarginBeforeDefault(this))
57108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
571168513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_rareData = new RenderBlockRareData(this);
57128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5713a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_rareData->m_margins.setPositiveMarginBefore(pos);
5714a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_rareData->m_margins.setNegativeMarginBefore(neg);
57158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
57168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5717bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBlock::setMaxMarginAfterValues(int pos, int neg)
57188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
571968513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!m_rareData) {
5720a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (pos == RenderBlockRareData::positiveMarginAfterDefault(this) && neg == RenderBlockRareData::negativeMarginAfterDefault(this))
572168513a70bcd92384395513322f1b801e7bf9c729Steve Block            return;
572268513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_rareData = new RenderBlockRareData(this);
572368513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
5724a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_rareData->m_margins.setPositiveMarginAfter(pos);
5725a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_rareData->m_margins.setNegativeMarginAfter(neg);
572668513a70bcd92384395513322f1b801e7bf9c729Steve Block}
572768513a70bcd92384395513322f1b801e7bf9c729Steve Block
572868513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid RenderBlock::setPaginationStrut(int strut)
572968513a70bcd92384395513322f1b801e7bf9c729Steve Block{
573068513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!m_rareData) {
573168513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (!strut)
57328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
573368513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_rareData = new RenderBlockRareData(this);
57348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
573568513a70bcd92384395513322f1b801e7bf9c729Steve Block    m_rareData->m_paginationStrut = strut;
573668513a70bcd92384395513322f1b801e7bf9c729Steve Block}
573768513a70bcd92384395513322f1b801e7bf9c729Steve Block
5738f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderBlock::setPageLogicalOffset(int logicalOffset)
573968513a70bcd92384395513322f1b801e7bf9c729Steve Block{
574068513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!m_rareData) {
5741f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (!logicalOffset)
574268513a70bcd92384395513322f1b801e7bf9c729Steve Block            return;
574368513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_rareData = new RenderBlockRareData(this);
574468513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
5745f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    m_rareData->m_pageLogicalOffset = logicalOffset;
57468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
57478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
57485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid RenderBlock::absoluteRects(Vector<IntRect>& rects, int tx, int ty)
57498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
57508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // For blocks inside inlines, we go ahead and include margins so that we run right up to the
57518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // inline boxes above and below us (thus getting merged with them to form a single irregular
57528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // shape).
5753e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (isAnonymousBlockContinuation()) {
5754bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // FIXME: This is wrong for block-flows that are horizontal.
5755bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // https://bugs.webkit.org/show_bug.cgi?id=46781
5756bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        rects.append(IntRect(tx, ty - collapsedMarginBefore(),
5757bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                             width(), height() + collapsedMarginBefore() + collapsedMarginAfter()));
5758e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        continuation()->absoluteRects(rects,
5759e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block                                      tx - x() + inlineElementContinuation()->containingBlock()->x(),
5760e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block                                      ty - y() + inlineElementContinuation()->containingBlock()->y());
57618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    } else
57628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        rects.append(IntRect(tx, ty, width(), height()));
57638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
57648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid RenderBlock::absoluteQuads(Vector<FloatQuad>& quads)
57668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
57678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // For blocks inside inlines, we go ahead and include margins so that we run right up to the
57688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // inline boxes above and below us (thus getting merged with them to form a single irregular
57698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // shape).
5770e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (isAnonymousBlockContinuation()) {
5771bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // FIXME: This is wrong for block-flows that are horizontal.
5772bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // https://bugs.webkit.org/show_bug.cgi?id=46781
5773bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        FloatRect localRect(0, -collapsedMarginBefore(),
5774bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                            width(), height() + collapsedMarginBefore() + collapsedMarginAfter());
57758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        quads.append(localToAbsoluteQuad(localRect));
5776e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        continuation()->absoluteQuads(quads);
57778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    } else
57788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width(), height())));
57798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
57808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianIntRect RenderBlock::rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth)
57828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
57838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    IntRect r(RenderBox::rectWithOutlineForRepaint(repaintContainer, outlineWidth));
5784e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (isAnonymousBlockContinuation())
5785bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        r.inflateY(collapsedMarginBefore()); // FIXME: This is wrong for block-flows that are horizontal.
57868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return r;
57878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
57888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianRenderObject* RenderBlock::hoverAncestor() const
57908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
5791e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    return isAnonymousBlockContinuation() ? continuation() : RenderBox::hoverAncestor();
57928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
57938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
57948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::updateDragState(bool dragOn)
57958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
57968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBox::updateDragState(dragOn);
5797e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (continuation())
5798e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        continuation()->updateDragState(dragOn);
57998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
58008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianRenderStyle* RenderBlock::outlineStyleForRepaint() const
58028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
5803e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    return isAnonymousBlockContinuation() ? continuation()->style() : style();
58048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
58058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::childBecameNonInline(RenderObject*)
58078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
58088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    makeChildrenNonInline();
58098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (isAnonymousBlock() && parent() && parent()->isRenderBlock())
58108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
58118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // |this| may be dead here
58128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
58138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::updateHitTestResult(HitTestResult& result, const IntPoint& point)
58158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
58168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (result.innerNode())
58178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
58188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Node* n = node();
5820e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (isAnonymousBlockContinuation())
58218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // We are in the margins of block elements that are part of a continuation.  In
5822e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        // this case we're actually still inside the enclosing element that was
58238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // split.  Go ahead and set our inner node accordingly.
5824e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        n = continuation()->node();
58258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (n) {
58278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        result.setInnerNode(n);
58288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (!result.innerNonSharedNode())
58298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            result.setInnerNonSharedNode(n);
58308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        result.setLocalPoint(point);
58318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
58328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
58338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianIntRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, int* extraWidthToEndOfLine)
58358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
58368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Do the normal calculation in most cases.
58378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (firstChild())
58388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return RenderBox::localCaretRect(inlineBox, caretOffset, extraWidthToEndOfLine);
58398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // This is a special case:
58418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // The element is not an inline element, and it's empty. So we have to
58428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // calculate a fake position to indicate where objects are to be inserted.
58438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // FIXME: This does not take into account either :first-line or :first-letter
58458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // However, as soon as some content is entered, the line boxes will be
58468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // constructed and this kludge is not called any more. So only the caret size
58478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // of an empty :first-line'd block is wrong. I think we can live with that.
58488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderStyle* currentStyle = firstLineStyle();
5849a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int height = lineHeight(true, currentStyle->isHorizontalWritingMode() ? HorizontalLine : VerticalLine);
58508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    enum CaretAlignment { alignLeft, alignRight, alignCenter };
58528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    CaretAlignment alignment = alignLeft;
58548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    switch (currentStyle->textAlign()) {
58568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case TAAUTO:
58578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case JUSTIFY:
5858a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (!currentStyle->isLeftToRightDirection())
58598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                alignment = alignRight;
58608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
58618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case LEFT:
58628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case WEBKIT_LEFT:
58638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
58648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case CENTER:
58658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case WEBKIT_CENTER:
58668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            alignment = alignCenter;
58678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
58688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case RIGHT:
58698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case WEBKIT_RIGHT:
58708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            alignment = alignRight;
58718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
58722bde8e466a4451c7319e3a072d118917957d6554Steve Block        case TASTART:
58732bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (!currentStyle->isLeftToRightDirection())
58742bde8e466a4451c7319e3a072d118917957d6554Steve Block                alignment = alignRight;
58752bde8e466a4451c7319e3a072d118917957d6554Steve Block            break;
58762bde8e466a4451c7319e3a072d118917957d6554Steve Block        case TAEND:
58772bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (currentStyle->isLeftToRightDirection())
58782bde8e466a4451c7319e3a072d118917957d6554Steve Block                alignment = alignRight;
58792bde8e466a4451c7319e3a072d118917957d6554Steve Block            break;
58808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
58818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int x = borderLeft() + paddingLeft();
58838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int w = width();
58848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    switch (alignment) {
58868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case alignLeft:
58878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
58888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case alignCenter:
58898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            x = (x + w - (borderRight() + paddingRight())) / 2;
58908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
58918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case alignRight:
58925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            x = w - (borderRight() + paddingRight()) - caretWidth;
58938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
58948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
58958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
58968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (extraWidthToEndOfLine) {
58978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (isRenderBlock()) {
58988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            *extraWidthToEndOfLine = w - (x + caretWidth);
58998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else {
59008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // FIXME: This code looks wrong.
59018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // myRight and containerRight are set up, but then clobbered.
59028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // So *extraWidthToEndOfLine will always be 0 here.
59038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
59048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            int myRight = x + caretWidth;
59058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // FIXME: why call localToAbsoluteForContent() twice here, too?
59068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            FloatPoint absRightPoint = localToAbsolute(FloatPoint(myRight, 0));
59078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
5908bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            int containerRight = containingBlock()->x() + containingBlockLogicalWidthForContent();
59098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            FloatPoint absContainerPoint = localToAbsolute(FloatPoint(containerRight, 0));
59108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
59118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            *extraWidthToEndOfLine = absContainerPoint.x() - absRightPoint.x();
59128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
59138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
59148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
59158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int y = paddingTop() + borderTop();
59168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
59178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return IntRect(x, y, caretWidth, height);
59188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
59198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
5920d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid RenderBlock::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
59218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
59228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // For blocks inside inlines, we go ahead and include margins so that we run right up to the
59238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // inline boxes above and below us (thus getting merged with them to form a single irregular
59248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // shape).
5925e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (inlineElementContinuation()) {
59268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // FIXME: This check really isn't accurate.
5927e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        bool nextInlineHasLineBox = inlineElementContinuation()->firstLineBox();
59288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // FIXME: This is wrong. The principal renderer may not be the continuation preceding this block.
5929bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // FIXME: This is wrong for block-flows that are horizontal.
5930bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // https://bugs.webkit.org/show_bug.cgi?id=46781
5931e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        bool prevInlineHasLineBox = toRenderInline(inlineElementContinuation()->node()->renderer())->firstLineBox();
5932bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        int topMargin = prevInlineHasLineBox ? collapsedMarginBefore() : 0;
5933bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        int bottomMargin = nextInlineHasLineBox ? collapsedMarginAfter() : 0;
5934d0825bca7fe65beaee391d30da42e937db621564Steve Block        IntRect rect(tx, ty - topMargin, width(), height() + topMargin + bottomMargin);
5935d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (!rect.isEmpty())
5936d0825bca7fe65beaee391d30da42e937db621564Steve Block            rects.append(rect);
5937d0825bca7fe65beaee391d30da42e937db621564Steve Block    } else if (width() && height())
5938d0825bca7fe65beaee391d30da42e937db621564Steve Block        rects.append(IntRect(tx, ty, width(), height()));
59398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
59408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!hasOverflowClip() && !hasControlClip()) {
5941231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
594281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            int top = max(curr->lineTop(), curr->logicalTop());
594381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            int bottom = min(curr->lineBottom(), curr->logicalTop() + curr->logicalHeight());
5944bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            IntRect rect(tx + curr->x(), ty + top, curr->logicalWidth(), bottom - top);
5945d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (!rect.isEmpty())
5946d0825bca7fe65beaee391d30da42e937db621564Steve Block                rects.append(rect);
5947231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
59488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
59498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
59508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (!curr->isText() && !curr->isListMarker() && curr->isBox()) {
59518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                RenderBox* box = toRenderBox(curr);
59528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                FloatPoint pos;
59538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                // FIXME: This doesn't work correctly with transforms.
59548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if (box->layer())
59558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    pos = curr->localToAbsolute();
59568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                else
59578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    pos = FloatPoint(tx + box->x(), ty + box->y());
5958d0825bca7fe65beaee391d30da42e937db621564Steve Block                box->addFocusRingRects(rects, pos.x(), pos.y());
59598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
59608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
59618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
59628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
5963e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (inlineElementContinuation())
5964e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        inlineElementContinuation()->addFocusRingRects(rects,
5965e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block                                                       tx - x() + inlineElementContinuation()->containingBlock()->x(),
5966e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block                                                       ty - y() + inlineElementContinuation()->containingBlock()->y());
59678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
59688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
5969231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockRenderBlock* RenderBlock::createAnonymousBlock(bool isFlexibleBox) const
59708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
59712bde8e466a4451c7319e3a072d118917957d6554Steve Block    RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
59728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
5973231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    RenderBlock* newBox = 0;
5974231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (isFlexibleBox) {
5975231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        newStyle->setDisplay(BOX);
5976231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        newBox = new (renderArena()) RenderFlexibleBox(document() /* anonymous box */);
5977231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    } else {
5978231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        newStyle->setDisplay(BLOCK);
5979231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
5980231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
5981231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
59828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    newBox->setStyle(newStyle.release());
59838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return newBox;
59848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
59858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
59865af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeRenderBlock* RenderBlock::createAnonymousBlockWithSameTypeAs(RenderBlock* otherAnonymousBlock) const
59875af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
59885af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (otherAnonymousBlock->isAnonymousColumnsBlock())
59895af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return createAnonymousColumnsBlock();
59905af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (otherAnonymousBlock->isAnonymousColumnSpanBlock())
59915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return createAnonymousColumnSpanBlock();
59925af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return createAnonymousBlock(otherAnonymousBlock->style()->display() == BOX);
59935af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
59945af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
59955af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeRenderBlock* RenderBlock::createAnonymousColumnsBlock() const
59965af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
59972bde8e466a4451c7319e3a072d118917957d6554Steve Block    RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
59985af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newStyle->inheritColumnPropertiesFrom(style());
59995af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newStyle->setDisplay(BLOCK);
60005af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
60015af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
60025af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newBox->setStyle(newStyle.release());
60035af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return newBox;
60045af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
60055af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
60065af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeRenderBlock* RenderBlock::createAnonymousColumnSpanBlock() const
60075af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
60082bde8e466a4451c7319e3a072d118917957d6554Steve Block    RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
60095af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newStyle->setColumnSpan(true);
60105af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newStyle->setDisplay(BLOCK);
60115af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
60125af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
60135af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    newBox->setStyle(newStyle.release());
60145af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return newBox;
60155af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
60165af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
60172fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockint RenderBlock::nextPageLogicalTop(int logicalOffset) const
601868513a70bcd92384395513322f1b801e7bf9c729Steve Block{
601968513a70bcd92384395513322f1b801e7bf9c729Steve Block    LayoutState* layoutState = view()->layoutState();
6020f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!layoutState->m_pageLogicalHeight)
60212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return logicalOffset;
602268513a70bcd92384395513322f1b801e7bf9c729Steve Block
60232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // The logicalOffset is in our coordinate space.  We can add in our pushed offset.
6024f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int pageLogicalHeight = layoutState->m_pageLogicalHeight;
60252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
60262bde8e466a4451c7319e3a072d118917957d6554Steve Block    int offset = isHorizontalWritingMode() ? delta.height() : delta.width();
60272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight;
60282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return logicalOffset + remainingLogicalHeight;
602968513a70bcd92384395513322f1b801e7bf9c729Steve Block}
603068513a70bcd92384395513322f1b801e7bf9c729Steve Block
603168513a70bcd92384395513322f1b801e7bf9c729Steve Blockstatic bool inNormalFlow(RenderBox* child)
603268513a70bcd92384395513322f1b801e7bf9c729Steve Block{
603368513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderBlock* curr = child->containingBlock();
603468513a70bcd92384395513322f1b801e7bf9c729Steve Block    RenderBlock* initialBlock = child->view();
603568513a70bcd92384395513322f1b801e7bf9c729Steve Block    while (curr && curr != initialBlock) {
603668513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (curr->hasColumns())
603768513a70bcd92384395513322f1b801e7bf9c729Steve Block            return true;
603868513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (curr->isFloatingOrPositioned())
603968513a70bcd92384395513322f1b801e7bf9c729Steve Block            return false;
604068513a70bcd92384395513322f1b801e7bf9c729Steve Block        curr = curr->containingBlock();
604168513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
604268513a70bcd92384395513322f1b801e7bf9c729Steve Block    return true;
604368513a70bcd92384395513322f1b801e7bf9c729Steve Block}
604468513a70bcd92384395513322f1b801e7bf9c729Steve Block
60452fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockint RenderBlock::applyBeforeBreak(RenderBox* child, int logicalOffset)
604668513a70bcd92384395513322f1b801e7bf9c729Steve Block{
604768513a70bcd92384395513322f1b801e7bf9c729Steve Block    // FIXME: Add page break checking here when we support printing.
604868513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
6049f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
605068513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool checkBeforeAlways = (checkColumnBreaks && child->style()->columnBreakBefore() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakBefore() == PBALWAYS);
605168513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (checkBeforeAlways && inNormalFlow(child)) {
605268513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (checkColumnBreaks)
60532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            view()->layoutState()->addForcedColumnBreak(logicalOffset);
60542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return nextPageLogicalTop(logicalOffset);
605568513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
60562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return logicalOffset;
605768513a70bcd92384395513322f1b801e7bf9c729Steve Block}
605868513a70bcd92384395513322f1b801e7bf9c729Steve Block
60592fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockint RenderBlock::applyAfterBreak(RenderBox* child, int logicalOffset, MarginInfo& marginInfo)
606068513a70bcd92384395513322f1b801e7bf9c729Steve Block{
606168513a70bcd92384395513322f1b801e7bf9c729Steve Block    // FIXME: Add page break checking here when we support printing.
606268513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
6063f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
606468513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool checkAfterAlways = (checkColumnBreaks && child->style()->columnBreakAfter() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakAfter() == PBALWAYS);
606568513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (checkAfterAlways && inNormalFlow(child)) {
6066bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        marginInfo.setMarginAfterQuirk(true); // Cause margins to be discarded for any following content.
606768513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (checkColumnBreaks)
60682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            view()->layoutState()->addForcedColumnBreak(logicalOffset);
60692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return nextPageLogicalTop(logicalOffset);
607068513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
60712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return logicalOffset;
607268513a70bcd92384395513322f1b801e7bf9c729Steve Block}
607368513a70bcd92384395513322f1b801e7bf9c729Steve Block
60742fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockint RenderBlock::adjustForUnsplittableChild(RenderBox* child, int logicalOffset, bool includeMargins)
607568513a70bcd92384395513322f1b801e7bf9c729Steve Block{
607668513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool isUnsplittable = child->isReplaced() || child->scrollsOverflow();
607768513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!isUnsplittable)
60782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return logicalOffset;
60792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int childLogicalHeight = logicalHeightForChild(child) + (includeMargins ? marginBeforeForChild(child) + marginAfterForChild(child) : 0);
608068513a70bcd92384395513322f1b801e7bf9c729Steve Block    LayoutState* layoutState = view()->layoutState();
608168513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (layoutState->m_columnInfo)
60822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        layoutState->m_columnInfo->updateMinimumColumnHeight(childLogicalHeight);
6083f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int pageLogicalHeight = layoutState->m_pageLogicalHeight;
60842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!pageLogicalHeight || childLogicalHeight > pageLogicalHeight)
60852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return logicalOffset;
60862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
60872bde8e466a4451c7319e3a072d118917957d6554Steve Block    int offset = isHorizontalWritingMode() ? delta.height() : delta.width();
60882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight;
60892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (remainingLogicalHeight < childLogicalHeight)
60902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return logicalOffset + remainingLogicalHeight;
60912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return logicalOffset;
609268513a70bcd92384395513322f1b801e7bf9c729Steve Block}
609368513a70bcd92384395513322f1b801e7bf9c729Steve Block
609468513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, int& delta)
609568513a70bcd92384395513322f1b801e7bf9c729Steve Block{
609668513a70bcd92384395513322f1b801e7bf9c729Steve Block    // FIXME: For now we paginate using line overflow.  This ensures that lines don't overlap at all when we
609768513a70bcd92384395513322f1b801e7bf9c729Steve Block    // put a strut between them for pagination purposes.  However, this really isn't the desired rendering, since
609868513a70bcd92384395513322f1b801e7bf9c729Steve 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
609968513a70bcd92384395513322f1b801e7bf9c729Steve Block    // of the first column.
610068513a70bcd92384395513322f1b801e7bf9c729Steve Block    //
610168513a70bcd92384395513322f1b801e7bf9c729Steve Block    // The rendering we would like to see is one where the lineTop is at the top of the column, and any line overflow
610268513a70bcd92384395513322f1b801e7bf9c729Steve Block    // simply spills out above the top of the column.  This effect would match what happens at the top of the first column.
610368513a70bcd92384395513322f1b801e7bf9c729Steve Block    // We can't achieve this rendering, however, until we stop columns from clipping to the column bounds (thus allowing
610468513a70bcd92384395513322f1b801e7bf9c729Steve Block    // for overflow to occur), and then cache visible overflow for each column rect.
610568513a70bcd92384395513322f1b801e7bf9c729Steve Block    //
610668513a70bcd92384395513322f1b801e7bf9c729Steve Block    // Furthermore, the paint we have to do when a column has overflow has to be special.  We need to exclude
610768513a70bcd92384395513322f1b801e7bf9c729Steve Block    // content that paints in a previous column (and content that paints in the following column).
610868513a70bcd92384395513322f1b801e7bf9c729Steve Block    //
610968513a70bcd92384395513322f1b801e7bf9c729Steve Block    // FIXME: Another problem with simply moving lines is that the available line width may change (because of floats).
611068513a70bcd92384395513322f1b801e7bf9c729Steve 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
611168513a70bcd92384395513322f1b801e7bf9c729Steve Block    // line and all following lines.
611268513a70bcd92384395513322f1b801e7bf9c729Steve Block    LayoutState* layoutState = view()->layoutState();
6113f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int pageLogicalHeight = layoutState->m_pageLogicalHeight;
61142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    IntRect logicalVisualOverflow = lineBox->logicalVisualOverflowRect(lineBox->lineTop(), lineBox->lineBottom());
61152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    int logicalOffset = logicalVisualOverflow.y();
61162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    int lineHeight = logicalVisualOverflow.maxY() - logicalOffset;
611768513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (layoutState->m_columnInfo)
611868513a70bcd92384395513322f1b801e7bf9c729Steve Block        layoutState->m_columnInfo->updateMinimumColumnHeight(lineHeight);
61192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    logicalOffset += delta;
612068513a70bcd92384395513322f1b801e7bf9c729Steve Block    lineBox->setPaginationStrut(0);
6121f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!pageLogicalHeight || lineHeight > pageLogicalHeight)
612268513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
61232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    IntSize offsetDelta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
61242bde8e466a4451c7319e3a072d118917957d6554Steve Block    int offset = isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width();
61252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int remainingLogicalHeight = pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight;
61262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (remainingLogicalHeight < lineHeight) {
61272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        int totalLogicalHeight = lineHeight + max(0, logicalOffset);
61282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (lineBox == firstRootBox() && totalLogicalHeight < pageLogicalHeight && !isPositioned() && !isTableCell())
61292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            setPaginationStrut(remainingLogicalHeight + max(0, logicalOffset));
613068513a70bcd92384395513322f1b801e7bf9c729Steve Block        else {
61312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            delta += remainingLogicalHeight;
61322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            lineBox->setPaginationStrut(remainingLogicalHeight);
613368513a70bcd92384395513322f1b801e7bf9c729Steve Block        }
613468513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
613568513a70bcd92384395513322f1b801e7bf9c729Steve Block}
6136a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6137a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::collapsedMarginBeforeForChild(RenderBox* child) const
6138a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
6139a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // If the child has the same directionality as we do, then we can just return its
6140a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // collapsed margin.
6141a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!child->isWritingModeRoot())
6142a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->collapsedMarginBefore();
6143a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6144a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // The child has a different directionality.  If the child is parallel, then it's just
6145a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // flipped relative to us.  We can use the collapsed margin for the opposite edge.
61462bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
6147a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->collapsedMarginAfter();
6148a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6149a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // The child is perpendicular to us, which means its margins don't collapse but are on the
6150a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // "logical left/right" sides of the child box.  We can just return the raw margin in this case.
6151a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return marginBeforeForChild(child);
6152a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6153a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6154a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::collapsedMarginAfterForChild(RenderBox* child) const
6155a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
6156a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // If the child has the same directionality as we do, then we can just return its
6157a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // collapsed margin.
6158a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!child->isWritingModeRoot())
6159a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->collapsedMarginAfter();
6160a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6161a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // The child has a different directionality.  If the child is parallel, then it's just
6162a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // flipped relative to us.  We can use the collapsed margin for the opposite edge.
61632bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
6164a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->collapsedMarginBefore();
6165a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6166a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // The child is perpendicular to us, which means its margins don't collapse but are on the
6167a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // "logical left/right" side of the child box.  We can just return the raw margin in this case.
6168a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return marginAfterForChild(child);
6169a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6170a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6171a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::marginBeforeForChild(RenderBoxModelObject* child) const
6172a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
6173a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    switch (style()->writingMode()) {
6174a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case TopToBottomWritingMode:
6175a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginTop();
6176a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case BottomToTopWritingMode:
6177a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginBottom();
6178a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case LeftToRightWritingMode:
6179a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginLeft();
6180a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case RightToLeftWritingMode:
6181a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginRight();
6182a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6183a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ASSERT_NOT_REACHED();
6184a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return child->marginTop();
6185a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6186a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6187a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::marginAfterForChild(RenderBoxModelObject* child) const
6188a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
6189a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    switch (style()->writingMode()) {
6190a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case TopToBottomWritingMode:
6191a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginBottom();
6192a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case BottomToTopWritingMode:
6193a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginTop();
6194a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case LeftToRightWritingMode:
6195a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginRight();
6196a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case RightToLeftWritingMode:
6197a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return child->marginLeft();
6198a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6199a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ASSERT_NOT_REACHED();
6200a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return child->marginBottom();
6201a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6202a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6203a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::marginStartForChild(RenderBoxModelObject* child) const
6204a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
62052bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
6206a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return style()->isLeftToRightDirection() ? child->marginLeft() : child->marginRight();
6207a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return style()->isLeftToRightDirection() ? child->marginTop() : child->marginBottom();
6208a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6209a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6210a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::marginEndForChild(RenderBoxModelObject* child) const
6211a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
62122bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
6213a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return style()->isLeftToRightDirection() ? child->marginRight() : child->marginLeft();
6214a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return style()->isLeftToRightDirection() ? child->marginBottom() : child->marginTop();
6215a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6216a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6217a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setMarginStartForChild(RenderBox* child, int margin)
6218a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
62192bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode()) {
6220a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->isLeftToRightDirection())
6221a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginLeft(margin);
6222a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
6223a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginRight(margin);
6224a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else {
6225a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->isLeftToRightDirection())
6226a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginTop(margin);
6227a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
6228a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginBottom(margin);
6229a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6230a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6231a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6232a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setMarginEndForChild(RenderBox* child, int margin)
6233a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
62342bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode()) {
6235a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->isLeftToRightDirection())
6236a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginRight(margin);
6237a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
6238a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginLeft(margin);
6239a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else {
6240a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->isLeftToRightDirection())
6241a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginBottom(margin);
6242a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
6243a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            child->setMarginTop(margin);
6244a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6245a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6246a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6247a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setMarginBeforeForChild(RenderBox* child, int margin)
6248a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
6249a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    switch (style()->writingMode()) {
6250a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case TopToBottomWritingMode:
6251a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginTop(margin);
6252a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6253a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case BottomToTopWritingMode:
6254a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginBottom(margin);
6255a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6256a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case LeftToRightWritingMode:
6257a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginLeft(margin);
6258a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6259a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case RightToLeftWritingMode:
6260a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginRight(margin);
6261a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6262a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6263a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6264a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6265a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setMarginAfterForChild(RenderBox* child, int margin)
6266a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
6267a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    switch (style()->writingMode()) {
6268a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case TopToBottomWritingMode:
6269a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginBottom(margin);
6270a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6271a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case BottomToTopWritingMode:
6272a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginTop(margin);
6273a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6274a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case LeftToRightWritingMode:
6275a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginRight(margin);
6276a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6277a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case RightToLeftWritingMode:
6278a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        child->setMarginLeft(margin);
6279a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        break;
6280a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6281a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6282a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6283a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochRenderBlock::MarginValues RenderBlock::marginValuesForChild(RenderBox* child)
6284a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
6285a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int childBeforePositive = 0;
6286a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int childBeforeNegative = 0;
6287a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int childAfterPositive = 0;
6288a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int childAfterNegative = 0;
6289a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6290a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int beforeMargin = 0;
6291a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int afterMargin = 0;
6292a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6293a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0;
6294a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6295a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // If the child has the same directionality as we do, then we can just return its
6296a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // margins in the same direction.
6297a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!child->isWritingModeRoot()) {
6298a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (childRenderBlock) {
6299a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBeforePositive = childRenderBlock->maxPositiveMarginBefore();
6300a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBeforeNegative = childRenderBlock->maxNegativeMarginBefore();
6301a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childAfterPositive = childRenderBlock->maxPositiveMarginAfter();
6302a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childAfterNegative = childRenderBlock->maxNegativeMarginAfter();
6303a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        } else {
6304a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            beforeMargin = child->marginBefore();
6305a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            afterMargin = child->marginAfter();
6306a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
63072bde8e466a4451c7319e3a072d118917957d6554Steve Block    } else if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) {
6308a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // The child has a different directionality.  If the child is parallel, then it's just
6309a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // flipped relative to us.  We can use the margins for the opposite edges.
6310a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (childRenderBlock) {
6311a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBeforePositive = childRenderBlock->maxPositiveMarginAfter();
6312a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBeforeNegative = childRenderBlock->maxNegativeMarginAfter();
6313a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childAfterPositive = childRenderBlock->maxPositiveMarginBefore();
6314a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childAfterNegative = childRenderBlock->maxNegativeMarginBefore();
6315a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        } else {
6316a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            beforeMargin = child->marginAfter();
6317a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            afterMargin = child->marginBefore();
6318a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
6319a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else {
6320a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // The child is perpendicular to us, which means its margins don't collapse but are on the
6321a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // "logical left/right" sides of the child box.  We can just return the raw margin in this case.
6322a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        beforeMargin = marginBeforeForChild(child);
6323a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        afterMargin = marginAfterForChild(child);
6324a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6325a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6326a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Resolve uncollapsing margins into their positive/negative buckets.
6327a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (beforeMargin) {
6328a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (beforeMargin > 0)
6329a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBeforePositive = beforeMargin;
6330a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
6331a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childBeforeNegative = -beforeMargin;
6332a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6333a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (afterMargin) {
6334a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (afterMargin > 0)
6335a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childAfterPositive = afterMargin;
6336a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
6337a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            childAfterNegative = -afterMargin;
6338a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6339a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6340a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return MarginValues(childBeforePositive, childBeforeNegative, childAfterPositive, childAfterNegative);
6341a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
6342a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
63438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst char* RenderBlock::renderName() const
63448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
63458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isBody())
63468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "RenderBody"; // FIXME: Temporary hack until we know that the regression tests pass.
63478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
63488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isFloating())
63498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "RenderBlock (floating)";
63508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isPositioned())
63518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "RenderBlock (positioned)";
63525af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (isAnonymousColumnsBlock())
63535af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return "RenderBlock (anonymous multi-column)";
63545af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (isAnonymousColumnSpanBlock())
63555af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return "RenderBlock (anonymous multi-column span)";
63568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isAnonymousBlock())
63578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "RenderBlock (anonymous)";
63588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (isAnonymous())
63598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "RenderBlock (generated)";
63608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isRelPositioned())
63618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "RenderBlock (relative positioned)";
63628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isRunIn())
63638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "RenderBlock (run-in)";
63648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return "RenderBlock";
63658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
63668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
636781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline void RenderBlock::FloatingObjects::clear()
636881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
636981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_set.clear();
637081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_leftObjectsCount = 0;
637181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_rightObjectsCount = 0;
637281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
637381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
637481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline void RenderBlock::FloatingObjects::increaseObjectsCount(FloatingObject::Type type)
637581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
637681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (type == FloatingObject::FloatLeft)
637781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_leftObjectsCount++;
637881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    else
637981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_rightObjectsCount++;
638081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
638181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
638281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline void RenderBlock::FloatingObjects::decreaseObjectsCount(FloatingObject::Type type)
638381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
638481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (type == FloatingObject::FloatLeft)
638581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_leftObjectsCount--;
638681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    else
638781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_rightObjectsCount--;
638881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
638981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
63908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
6391