RenderBlock.cpp revision c9773ed4ca308bb2b8e70f49ba7fbaa35b1f46a2
18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (C) 1999 Antti Koivisto (koivisto@kde.org) 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (C) 2007 David Smith (catfish.man@gmail.com) 5d0825bca7fe65beaee391d30da42e937db621564Steve Block * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. 6967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * Copyright (C) Research In Motion Limited 2010. All rights reserved. 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version. 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful, 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details. 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB. If not, write to 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA. 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderBlock.h" 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 275abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#include "ColumnInfo.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Element.h" 308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "FloatQuad.h" 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameView.h" 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "GraphicsContext.h" 345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "HTMLFormElement.h" 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h" 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HitTestResult.h" 372bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "InlineIterator.h" 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "InlineTextBox.h" 3965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "PaintInfo.h" 402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "RenderCombineText.h" 41231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "RenderFlexibleBox.h" 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderImage.h" 43635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "RenderInline.h" 44545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch#include "RenderLayer.h" 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderMarquee.h" 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderReplica.h" 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderTableCell.h" 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderTextFragment.h" 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderTheme.h" 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderView.h" 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SelectionController.h" 525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "Settings.h" 53ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "TextRun.h" 54643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "TransformState.h" 55635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <wtf/StdLibExtras.h> 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_LAYOUT 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Settings.h" 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std; 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace WTF; 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace Unicode; 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames; 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttypedef WTF::HashMap<const RenderBox*, ColumnInfo*> ColumnInfoMap; 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic ColumnInfoMap* gColumnInfoMap = 0; 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttypedef WTF::HashMap<const RenderBlock*, HashSet<RenderBox*>*> PercentHeightDescendantsMap; 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic PercentHeightDescendantsMap* gPercentHeightDescendantsMap = 0; 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttypedef WTF::HashMap<const RenderBox*, HashSet<RenderBlock*>*> PercentHeightContainerMap; 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic PercentHeightContainerMap* gPercentHeightContainerMap = 0; 77635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qiantypedef WTF::HashMap<RenderBlock*, ListHashSet<RenderInline*>*> ContinuationOutlineTableMap; 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochtypedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet; 810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic int gDelayUpdateScrollInfo = 0; 820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0; 830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 8454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Blockbool RenderBlock::s_canPropagateFloatIntoSibling = false; 8554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Our MarginInfo state used when laying out block children. 87bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenRenderBlock::MarginInfo::MarginInfo(RenderBlock* block, int beforeBorderPadding, int afterBorderPadding) 88bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen : m_atBeforeSideOfBlock(true) 89bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen , m_atAfterSideOfBlock(false) 90bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen , m_marginBeforeQuirk(false) 91bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen , m_marginAfterQuirk(false) 92bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen , m_determinedMarginBeforeQuirk(false) 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Whether or not we can collapse our own margins with our children. We don't do this 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // if we had any border/padding (obviously), if we're the root or HTML elements, or if 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // we're positioned, floating, a table cell. 97bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_canCollapseWithChildren = !block->isRenderView() && !block->isRoot() && !block->isPositioned() 98bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen && !block->isFloating() && !block->isTableCell() && !block->hasOverflowClip() && !block->isInlineBlockOrInlineTable() 99a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch && !block->isWritingModeRoot(); 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 101bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_canCollapseMarginBeforeWithChildren = m_canCollapseWithChildren && (beforeBorderPadding == 0) && block->style()->marginBeforeCollapse() != MSEPARATE; 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If any height other than auto is specified in CSS, then we don't collapse our bottom 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // margins with our children's margins. To do otherwise would be to risk odd visual 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // effects when the children overflow out of the parent block and yet still collapse 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // with it. We also don't collapse if we have any bottom border/padding. 107bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_canCollapseMarginAfterWithChildren = m_canCollapseWithChildren && (afterBorderPadding == 0) && 108bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen (block->style()->logicalHeight().isAuto() && block->style()->logicalHeight().value() == 0) && block->style()->marginAfterCollapse() != MSEPARATE; 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 110bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_quirkContainer = block->isTableCell() || block->isBody() || block->style()->marginBeforeCollapse() == MDISCARD || 111bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen block->style()->marginAfterCollapse() == MDISCARD; 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 113a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_positiveMargin = m_canCollapseMarginBeforeWithChildren ? block->maxPositiveMarginBefore() : 0; 114a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_negativeMargin = m_canCollapseMarginBeforeWithChildren ? block->maxNegativeMarginBefore() : 0; 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// ------------------------------------------------------------------------------------------------------- 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderBlock::RenderBlock(Node* node) 1208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian : RenderBox(node) 1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_floatingObjects(0) 1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_positionedObjects(0) 12368513a70bcd92384395513322f1b801e7bf9c729Steve Block , m_rareData(0) 1248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian , m_lineHeight(-1) 12565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch , m_beingDestroyed(false) 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian setChildrenInline(true); 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderBlock::~RenderBlock() 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 13281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (m_floatingObjects) 13381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch deleteAllValues(m_floatingObjects->set()); 1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (hasColumns()) 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete gColumnInfoMap->take(this); 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (gPercentHeightDescendantsMap) { 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->take(this)) { 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HashSet<RenderBox*>::iterator end = descendantSet->end(); 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (HashSet<RenderBox*>::iterator descendant = descendantSet->begin(); descendant != end; ++descendant) { 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(*descendant); 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(containerSet); 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!containerSet) 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(containerSet->contains(this)); 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project containerSet->remove(this); 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (containerSet->isEmpty()) { 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gPercentHeightContainerMap->remove(*descendant); 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete containerSet; 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete descendantSet; 1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::destroy() 1598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 16065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Mark as being destroyed to avoid trouble with merges in removeChild(). 16165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch m_beingDestroyed = true; 16265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 163643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will 164643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise. 165643ca7872b450ea4efacab6188849e5aac2ba161Steve Block children()->destroyLeftoverChildren(); 1668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 167643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // Destroy our continuation before anything other than anonymous children. 168643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // The reason we don't destroy it before anonymous children is that they may 169643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // have continuations of their own that are anonymous children of our continuation. 170cad810f21b803229eb11403f9209855525a25d57Steve Block RenderBoxModelObject* continuation = this->continuation(); 171cad810f21b803229eb11403f9209855525a25d57Steve Block if (continuation) { 172cad810f21b803229eb11403f9209855525a25d57Steve Block continuation->destroy(); 173cad810f21b803229eb11403f9209855525a25d57Steve Block setContinuation(0); 174643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 175643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 1768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!documentBeingDestroyed()) { 1778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (firstLineBox()) { 1788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // We can't wait for RenderBox::destroy to clear the selection, 1798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // because by then we will have nuked the line boxes. 1808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // FIXME: The SelectionController should be responsible for this when it 1818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // is notified of DOM mutations. 1828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (isSelectionBorder()) 1838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian view()->clearSelection(); 1848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // If we are an anonymous block, then our line boxes might have children 1868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // that will outlast this block. In the non-anonymous block case those 1878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // children will be destroyed by the time we return from this function. 1888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (isAnonymousBlock()) { 189dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox()) { 1908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian while (InlineBox* childBox = box->firstChild()) 1918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian childBox->remove(); 1928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 1938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 194c9773ed4ca308bb2b8e70f49ba7fbaa35b1f46a2Steve Block } else if (parent()) 1958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian parent()->dirtyLinesFromChangedChild(this); 1968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 1978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_lineBoxes.deleteLineBoxes(renderArena()); 1998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderBox::destroy(); 2018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 2028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::styleWillChange(StyleDifference diff, const RenderStyle* newStyle) 2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 20554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block s_canPropagateFloatIntoSibling = style() ? !isFloatingOrPositioned() && !avoidsFloats() : false; 20654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block 20765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch setReplaced(newStyle->isDisplayInlineType()); 208635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 2098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (style() && parent() && diff == StyleDifferenceLayout && style()->position() != newStyle->position()) { 210635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (newStyle->position() == StaticPosition) 211635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Clear our positioned objects list. Our absolutely positioned descendants will be 212635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // inserted into our containing block's positioned objects list during layout. 213635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project removePositionedObjects(0); 214635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project else if (style()->position() == StaticPosition) { 215635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Remove our absolutely positioned descendants from their current containing block. 216635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // They will be inserted into our positioned objects list during layout. 217635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderObject* cb = parent(); 218635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project while (cb && (cb->style()->position() == StaticPosition || (cb->isInline() && !cb->isReplaced())) && !cb->isRenderView()) { 219635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (cb->style()->position() == RelativePosition && cb->isInline() && !cb->isReplaced()) { 220635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project cb = cb->containingBlock(); 221635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project break; 222635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 223635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project cb = cb->parent(); 224635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 225635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 226635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (cb->isRenderBlock()) 2278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian toRenderBlock(cb)->removePositionedObjects(this); 228635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 229383cc12851b723ebdaf6dddc7cb16d62cf7c7c7eSteve Block 230383cc12851b723ebdaf6dddc7cb16d62cf7c7c7eSteve Block if (containsFloats() && !isFloating() && !isPositioned() && (newStyle->position() == AbsolutePosition || newStyle->position() == FixedPosition)) 231383cc12851b723ebdaf6dddc7cb16d62cf7c7c7eSteve Block markAllDescendantsWithFloatsForLayout(); 232635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 233635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 2348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderBox::styleWillChange(diff, newStyle); 2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) 2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderBox::styleDidChange(diff, oldStyle); 2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 241545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (!isAnonymousBlock()) { 242545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // Ensure that all of our continuation blocks pick up the new style. 243545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch for (RenderBlock* currCont = blockElementContinuation(); currCont; currCont = currCont->blockElementContinuation()) { 244545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RenderBoxModelObject* nextCont = currCont->continuation(); 245545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch currCont->setContinuation(0); 246545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch currCont->setStyle(style()); 247545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch currCont->setContinuation(nextCont); 248545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch } 249545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch } 250545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: We could save this call when the change only affected non-inherited properties 2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { 2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (child->isAnonymousBlock()) { 2542bde8e466a4451c7319e3a072d118917957d6554Steve Block RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style()); 2555af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (style()->specifiesColumns()) { 2565af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (child->style()->specifiesColumns()) 2575af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newStyle->inheritColumnPropertiesFrom(style()); 2585af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (child->style()->columnSpan()) 2595af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newStyle->setColumnSpan(true); 2605af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } 2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newStyle->setDisplay(BLOCK); 2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project child->setStyle(newStyle.release()); 2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_lineHeight = -1; 2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Update pseudos for :before and :after now. 269635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!isAnonymous() && document()->usesBeforeAfterRules() && canHaveChildren()) { 2708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian updateBeforeAfterContent(BEFORE); 2718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian updateBeforeAfterContent(AFTER); 2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 27354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block 27454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block // After our style changed, if we lose our ability to propagate floats into next sibling 2754fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block // blocks, then we need to find the top most parent containing that overhanging float and 2764fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block // then mark its descendants with floats for layout and clear all floats from its next 2774fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block // sibling blocks that exist in our floating objects list. See bug 56299 and 62875. 27854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block bool canPropagateFloatIntoSibling = !isFloatingOrPositioned() && !avoidsFloats(); 27954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block if (diff == StyleDifferenceLayout && s_canPropagateFloatIntoSibling && !canPropagateFloatIntoSibling && hasOverhangingFloats()) { 2804fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block RenderBlock* parentBlock = this; 2814fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 2824fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block FloatingObjectSetIterator end = floatingObjectSet.end(); 2834fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block 2844fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block for (RenderObject* curr = parent(); curr && !curr->isRenderView(); curr = curr->parent()) { 2854fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block if (curr->isRenderBlock()) { 2864fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block RenderBlock* currBlock = toRenderBlock(curr); 2874fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block 2884fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block if (currBlock->hasOverhangingFloats()) { 2894fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) { 2904fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block RenderBox* renderer = (*it)->renderer(); 2914fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block if (currBlock->hasOverhangingFloat(renderer)) { 2924fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block parentBlock = currBlock; 2934fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block break; 2944fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block } 2954fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block } 2964fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block } 2974fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block } 2984fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block } 2994fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block 3004fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block parentBlock->markAllDescendantsWithFloatsForLayout(); 3014fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block parentBlock->markSiblingsWithFloatsForLayout(); 30254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block } 3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::updateBeforeAfterContent(PseudoId pseudoId) 3068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 3078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // If this is an anonymous wrapper, then the parent applies its own pseudo-element style to it. 3088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (parent() && parent()->createsAnonymousWrapper()) 3098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return; 3108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return children()->updateBeforeAfterContent(this, pseudoId); 3118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 3125af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 313545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRenderBlock* RenderBlock::continuationBefore(RenderObject* beforeChild) 314545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{ 315545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (beforeChild && beforeChild->parent() == this) 316545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return this; 317545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 318545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RenderBlock* curr = toRenderBlock(continuation()); 319545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RenderBlock* nextToLast = this; 320545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RenderBlock* last = this; 321545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch while (curr) { 322545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (beforeChild && beforeChild->parent() == curr) { 323545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (curr->firstChild() == beforeChild) 324545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return last; 325545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return curr; 326545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch } 327545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 328545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch nextToLast = last; 329545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch last = curr; 330545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch curr = toRenderBlock(curr->continuation()); 331545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch } 332545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 333545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (!beforeChild && !last->firstChild()) 334545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return nextToLast; 335545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return last; 336545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch} 337545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 338545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid RenderBlock::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild) 339545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{ 340545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RenderBlock* flow = continuationBefore(beforeChild); 341545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch ASSERT(!beforeChild || beforeChild->parent()->isAnonymousColumnSpanBlock() || beforeChild->parent()->isRenderBlock()); 342545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RenderBoxModelObject* beforeChildParent = 0; 343545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (beforeChild) 344545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch beforeChildParent = toRenderBoxModelObject(beforeChild->parent()); 345545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch else { 346545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RenderBoxModelObject* cont = flow->continuation(); 347545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (cont) 348545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch beforeChildParent = cont; 349545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch else 350545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch beforeChildParent = flow; 351545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch } 352545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 353545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (newChild->isFloatingOrPositioned()) 354545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild); 355545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 356545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // A continuation always consists of two potential candidates: a block or an anonymous 357545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // column span box holding column span children. 358545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch bool childIsNormal = newChild->isInline() || !newChild->style()->columnSpan(); 359545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch bool bcpIsNormal = beforeChildParent->isInline() || !beforeChildParent->style()->columnSpan(); 360545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch bool flowIsNormal = flow->isInline() || !flow->style()->columnSpan(); 361545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 362545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (flow == beforeChildParent) 363545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return flow->addChildIgnoringContinuation(newChild, beforeChild); 364545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 365545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // The goal here is to match up if we can, so that we can coalesce and create the 366545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // minimal # of continuations needed for the inline. 367545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (childIsNormal == bcpIsNormal) 368545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild); 369545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (flowIsNormal == childIsNormal) 370545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return flow->addChildIgnoringContinuation(newChild, 0); // Just treat like an append. 371545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild); 372545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch} 373545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 374545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 3755af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild) 3765af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 3775af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke ASSERT(!continuation()); // We don't yet support column spans that aren't immediate children of the multi-column block. 3785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 3795af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // The goal is to locate a suitable box in which to place our child. 380bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen RenderBlock* beforeChildParent = toRenderBlock(beforeChild && beforeChild->parent()->isRenderBlock() ? beforeChild->parent() : lastChild()); 3818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 3825af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // If the new child is floating or positioned it can just go in that block. 3835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (newChild->isFloatingOrPositioned()) 3845af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild); 3855af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 3865af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // See if the child can be placed in the box. 3875af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke bool newChildHasColumnSpan = newChild->style()->columnSpan() && !newChild->isInline(); 3885af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke bool beforeChildParentHoldsColumnSpans = beforeChildParent->isAnonymousColumnSpanBlock(); 3895af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 3905af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (newChildHasColumnSpan == beforeChildParentHoldsColumnSpans) 3915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild); 3925af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 3935af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (!beforeChild) { 3945af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // Create a new block of the correct type. 3955af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock(); 3965af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke children()->appendChildNode(this, newBox); 3975af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0); 3985af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return; 3995af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } 4005af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 4015af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RenderObject* immediateChild = beforeChild; 4025af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke bool isPreviousBlockViable = true; 4035af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke while (immediateChild->parent() != this) { 4045af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (isPreviousBlockViable) 4055af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke isPreviousBlockViable = !immediateChild->previousSibling(); 4065af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke immediateChild = immediateChild->parent(); 4075af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } 4085af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (isPreviousBlockViable && immediateChild->previousSibling()) 4095af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return toRenderBlock(immediateChild->previousSibling())->addChildIgnoringAnonymousColumnBlocks(newChild, 0); // Treat like an append. 4105af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 4115af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // Split our anonymous blocks. 4125af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RenderObject* newBeforeChild = splitAnonymousBlocksAroundChild(beforeChild); 4135af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 4145af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // Create a new anonymous box of the appropriate type. 4155af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock(); 4165af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke children()->insertChildNode(this, newBox, newBeforeChild); 4175af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0); 4185af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return; 4195af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 4205af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 421545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRenderBlock* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBlock) 422545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{ 423545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch for (RenderObject* curr = this; curr; curr = curr->parent()) { 424545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (!curr->isRenderBlock() || curr->isFloatingOrPositioned() || curr->isTableCell() || curr->isRoot() || curr->isRenderView() || curr->hasOverflowClip() 425545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch || curr->isInlineBlockOrInlineTable()) 426545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return 0; 427545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 428545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RenderBlock* currBlock = toRenderBlock(curr); 429545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (currBlock->style()->specifiesColumns() && (allowAnonymousColumnBlock || !currBlock->isAnonymousColumnsBlock())) 430545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return currBlock; 431545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 432545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (currBlock->isAnonymousColumnSpanBlock()) 433545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return 0; 434545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch } 435545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return 0; 436545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch} 437545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 438545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRenderBlock* RenderBlock::clone() const 439545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{ 440cad810f21b803229eb11403f9209855525a25d57Steve Block RenderBlock* cloneBlock; 441cad810f21b803229eb11403f9209855525a25d57Steve Block if (isAnonymousBlock()) 442cad810f21b803229eb11403f9209855525a25d57Steve Block cloneBlock = createAnonymousBlock(); 443cad810f21b803229eb11403f9209855525a25d57Steve Block else { 444cad810f21b803229eb11403f9209855525a25d57Steve Block cloneBlock = new (renderArena()) RenderBlock(node()); 445cad810f21b803229eb11403f9209855525a25d57Steve Block cloneBlock->setStyle(style()); 446cad810f21b803229eb11403f9209855525a25d57Steve Block } 447cad810f21b803229eb11403f9209855525a25d57Steve Block cloneBlock->setChildrenInline(childrenInline()); 448cad810f21b803229eb11403f9209855525a25d57Steve Block return cloneBlock; 449545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch} 450545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 451545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock, 452545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RenderBlock* middleBlock, 453545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RenderObject* beforeChild, RenderBoxModelObject* oldCont) 454545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{ 455545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // Create a clone of this inline. 456cad810f21b803229eb11403f9209855525a25d57Steve Block RenderBlock* cloneBlock = clone(); 457cad810f21b803229eb11403f9209855525a25d57Steve Block if (!isAnonymousBlock()) 4584a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch cloneBlock->setContinuation(oldCont); 459545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 460545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // Now take all of the children from beforeChild to the end and remove 461545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // them from |this| and place them in the clone. 462545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (!beforeChild && isAfterContent(lastChild())) 463545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch beforeChild = lastChild(); 464545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch moveChildrenTo(cloneBlock, beforeChild, 0); 465545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 466545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // Hook |clone| up as the continuation of the middle block. 4674a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch if (!cloneBlock->isAnonymousBlock()) 4684a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch middleBlock->setContinuation(cloneBlock); 469545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 470545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // We have been reparented and are now under the fromBlock. We need 471545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // to walk up our block parent chain until we hit the containing anonymous columns block. 472545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // Once we hit the anonymous columns block we're done. 473545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RenderBoxModelObject* curr = toRenderBoxModelObject(parent()); 474545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RenderBoxModelObject* currChild = this; 475545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 476545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch while (curr && curr != fromBlock) { 4774a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch ASSERT(curr->isRenderBlock()); 478545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 479545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RenderBlock* blockCurr = toRenderBlock(curr); 480545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 481545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // Create a new clone. 482545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RenderBlock* cloneChild = cloneBlock; 483cad810f21b803229eb11403f9209855525a25d57Steve Block cloneBlock = blockCurr->clone(); 484545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 485545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // Insert our child clone as the first child. 486545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch cloneBlock->children()->appendChildNode(cloneBlock, cloneChild); 487545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 488545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // Hook the clone up as a continuation of |curr|. Note we do encounter 489545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // anonymous blocks possibly as we walk up the block chain. When we split an 490545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // anonymous block, there's no need to do any continuation hookup, since we haven't 491545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // actually split a real element. 492545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (!blockCurr->isAnonymousBlock()) { 493545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch oldCont = blockCurr->continuation(); 494545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch blockCurr->setContinuation(cloneBlock); 495545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch cloneBlock->setContinuation(oldCont); 496545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch } 497545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 498545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // Someone may have indirectly caused a <q> to split. When this happens, the :after content 499545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // has to move into the inline continuation. Call updateBeforeAfterContent to ensure that the inline's :after 500545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // content gets properly destroyed. 501545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (document()->usesBeforeAfterRules()) 502545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch blockCurr->children()->updateBeforeAfterContent(blockCurr, AFTER); 503545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 504545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // Now we need to take all of the children starting from the first child 505545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // *after* currChild and append them all to the clone. 506545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RenderObject* afterContent = isAfterContent(cloneBlock->lastChild()) ? cloneBlock->lastChild() : 0; 507545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch blockCurr->moveChildrenTo(cloneBlock, currChild->nextSibling(), 0, afterContent); 508545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 509545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // Keep walking up the chain. 510545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch currChild = curr; 511545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch curr = toRenderBoxModelObject(curr->parent()); 512545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch } 513545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 514545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // Now we are at the columns block level. We need to put the clone into the toBlock. 515545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch toBlock->children()->appendChildNode(toBlock, cloneBlock); 516545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 517545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // Now take all the children after currChild and remove them from the fromBlock 518545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // and put them in the toBlock. 519545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch fromBlock->moveChildrenTo(toBlock, currChild->nextSibling(), 0); 520545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch} 521545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 522545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid RenderBlock::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox, 523545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RenderObject* newChild, RenderBoxModelObject* oldCont) 524545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{ 525545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RenderBlock* pre = 0; 526545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RenderBlock* block = containingColumnsBlock(); 527545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 528545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // Delete our line boxes before we do the inline split into continuations. 529545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch block->deleteLineBoxTree(); 530545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 531545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch bool madeNewBeforeBlock = false; 532545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (block->isAnonymousColumnsBlock()) { 533545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // We can reuse this block and make it the preBlock of the next continuation. 534545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch pre = block; 535545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch pre->removePositionedObjects(0); 536545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch block = toRenderBlock(block->parent()); 537545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch } else { 538545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // No anonymous block available for use. Make one. 539545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch pre = block->createAnonymousColumnsBlock(); 540545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch pre->setChildrenInline(false); 541545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch madeNewBeforeBlock = true; 542545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch } 543545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 544545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RenderBlock* post = block->createAnonymousColumnsBlock(); 545545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch post->setChildrenInline(false); 546545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 547545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling(); 548545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (madeNewBeforeBlock) 549545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch block->children()->insertChildNode(block, pre, boxFirst); 550545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch block->children()->insertChildNode(block, newBlockBox, boxFirst); 551545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch block->children()->insertChildNode(block, post, boxFirst); 552545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch block->setChildrenInline(false); 553545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 554545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (madeNewBeforeBlock) 555545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch block->moveChildrenTo(pre, boxFirst, 0); 556545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 557545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch splitBlocks(pre, post, newBlockBox, beforeChild, oldCont); 558545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 559545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting 560545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // time in makeChildrenNonInline by just setting this explicitly up front. 561545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch newBlockBox->setChildrenInline(false); 562545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 563545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // We delayed adding the newChild until now so that the |newBlockBox| would be fully 564545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // connected, thus allowing newChild access to a renderArena should it need 565545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // to wrap itself in additional boxes (e.g., table construction). 566545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch newBlockBox->addChild(newChild); 567545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 568545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // Always just do a full layout in order to ensure that line boxes (especially wrappers for images) 569545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // get deleted properly. Because objects moves from the pre block into the post block, we want to 570545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // make new line boxes instead of leaving the old line boxes around. 571545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch pre->setNeedsLayoutAndPrefWidthsRecalc(); 572545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch block->setNeedsLayoutAndPrefWidthsRecalc(); 573545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch post->setNeedsLayoutAndPrefWidthsRecalc(); 574545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch} 575545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 5765af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeRenderObject* RenderBlock::splitAnonymousBlocksAroundChild(RenderObject* beforeChild) 5775af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 5785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke while (beforeChild->parent() != this) { 5795af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RenderBlock* blockToSplit = toRenderBlock(beforeChild->parent()); 5805af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (blockToSplit->firstChild() != beforeChild) { 5815af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // We have to split the parentBlock into two blocks. 5825af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RenderBlock* post = createAnonymousBlockWithSameTypeAs(blockToSplit); 5835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke post->setChildrenInline(blockToSplit->childrenInline()); 5845af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RenderBlock* parentBlock = toRenderBlock(blockToSplit->parent()); 5855af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke parentBlock->children()->insertChildNode(parentBlock, post, blockToSplit->nextSibling()); 5865af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke blockToSplit->moveChildrenTo(post, beforeChild, 0, blockToSplit->hasLayer()); 5875af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke post->setNeedsLayoutAndPrefWidthsRecalc(); 5885af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke blockToSplit->setNeedsLayoutAndPrefWidthsRecalc(); 5895af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke beforeChild = post; 5905af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } else 5915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke beforeChild = blockToSplit; 5925af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } 5935af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return beforeChild; 5945af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 5955af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 5965af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild) 5975af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 5985af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RenderBlock* pre = 0; 5995af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RenderBlock* post = 0; 6005af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RenderBlock* block = this; // Eventually block will not just be |this|, but will also be a block nested inside |this|. Assign to a variable 6015af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // so that we don't have to patch all of the rest of the code later on. 6025af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 6035af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // Delete the block's line boxes before we do the split. 6045af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke block->deleteLineBoxTree(); 605545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 6065af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (beforeChild && beforeChild->parent() != this) 6075af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke beforeChild = splitAnonymousBlocksAroundChild(beforeChild); 608545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 6095af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (beforeChild != firstChild()) { 6105af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke pre = block->createAnonymousColumnsBlock(); 6115af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke pre->setChildrenInline(block->childrenInline()); 6125af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } 6135af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 6145af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (beforeChild) { 6155af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke post = block->createAnonymousColumnsBlock(); 6165af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke post->setChildrenInline(block->childrenInline()); 6175af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } 6185af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 6195af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RenderObject* boxFirst = block->firstChild(); 6205af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (pre) 6215af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke block->children()->insertChildNode(block, pre, boxFirst); 6225af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke block->children()->insertChildNode(block, newBlockBox, boxFirst); 6235af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (post) 6245af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke block->children()->insertChildNode(block, post, boxFirst); 6255af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke block->setChildrenInline(false); 6265af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 6275af96e2c7b73ebc627c6894727826a7576d31758Leon 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). 6285af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke block->moveChildrenTo(pre, boxFirst, beforeChild, true); 6295af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke block->moveChildrenTo(post, beforeChild, 0, true); 6305af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 6315af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting 6325af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // time in makeChildrenNonInline by just setting this explicitly up front. 6335af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newBlockBox->setChildrenInline(false); 6345af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 6355af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // We delayed adding the newChild until now so that the |newBlockBox| would be fully 6365af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // connected, thus allowing newChild access to a renderArena should it need 6375af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // to wrap itself in additional boxes (e.g., table construction). 6385af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newBlockBox->addChild(newChild); 6395af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 6405af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // Always just do a full layout in order to ensure that line boxes (especially wrappers for images) 6415af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // get deleted properly. Because objects moved from the pre block into the post block, we want to 6425af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // make new line boxes instead of leaving the old line boxes around. 6435af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (pre) 6445af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke pre->setNeedsLayoutAndPrefWidthsRecalc(); 6455af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke block->setNeedsLayoutAndPrefWidthsRecalc(); 6465af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (post) 6475af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke post->setNeedsLayoutAndPrefWidthsRecalc(); 6485af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 6495af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 650545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRenderBlock* RenderBlock::columnsBlockForSpanningElement(RenderObject* newChild) 6515af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 652545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // FIXME: This function is the gateway for the addition of column-span support. It will 653545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // be added to in three stages: 6545af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // (1) Immediate children of a multi-column block can span. 6555af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // (2) Nested block-level children with only block-level ancestors between them and the multi-column block can span. 6565af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // (3) Nested children with block or inline ancestors between them and the multi-column block can span (this is when we 6575af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // cross the streams and have to cope with both types of continuations mixed together). 658545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // This function currently supports (1) and (2). 659545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RenderBlock* columnsBlockAncestor = 0; 660545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isFloatingOrPositioned() 661545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch && !newChild->isInline() && !isAnonymousColumnSpanBlock()) { 662545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (style()->specifiesColumns()) 663545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch columnsBlockAncestor = this; 664bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen else if (parent() && parent()->isRenderBlock()) 665545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch columnsBlockAncestor = toRenderBlock(parent())->containingColumnsBlock(false); 666545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch } 667545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return columnsBlockAncestor; 6685af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 6695af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 6705af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild) 6718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Make sure we don't append things after :after-generated content if we have it. 673dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!beforeChild) { 674dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block RenderObject* lastRenderer = lastChild(); 675dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (isAfterContent(lastRenderer)) 676dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block beforeChild = lastRenderer; 677dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if (lastRenderer && lastRenderer->isAnonymousBlock() && isAfterContent(lastRenderer->lastChild())) 678dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block beforeChild = lastRenderer->lastChild(); 679dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the requested beforeChild is not one of our children, then this is because 6828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // there is an anonymous container within this object that contains the beforeChild. 6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (beforeChild && beforeChild->parent() != this) { 6848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* anonymousChild = beforeChild->parent(); 6858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(anonymousChild); 6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (anonymousChild->parent() != this) 6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project anonymousChild = anonymousChild->parent(); 6898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(anonymousChild->isAnonymous()); 6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (anonymousChild->isAnonymousBlock()) { 6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Insert the child into the anonymous block box instead of here. 6948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild) 6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project beforeChild->parent()->addChild(newChild, beforeChild); 6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 6978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian addChild(newChild, beforeChild->parent()); 6988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 6998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 7008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(anonymousChild->isTable()); 7028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if ((newChild->isTableCol() && newChild->style()->display() == TABLE_COLUMN_GROUP) 7038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian || (newChild->isRenderBlock() && newChild->style()->display() == TABLE_CAPTION) 7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project || newChild->isTableSection() 7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project || newChild->isTableRow() 7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project || newChild->isTableCell()) { 7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Insert into the anonymous table. 7088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project anonymousChild->addChild(newChild, beforeChild); 7098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 7108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 7118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Go on to insert before the anonymous table. 7138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project beforeChild = anonymousChild; 7148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 7158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7164a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch // Check for a spanning element in columns. 7174a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch RenderBlock* columnsBlockAncestor = columnsBlockForSpanningElement(newChild); 7184a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch if (columnsBlockAncestor) { 7194a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch // We are placing a column-span element inside a block. 7204a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch RenderBlock* newBox = createAnonymousColumnSpanBlock(); 7214a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch 7224a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch if (columnsBlockAncestor != this) { 7234a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch // We are nested inside a multi-column element and are being split by the span. We have to break up 7244a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch // our block into continuations. 7254a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch RenderBoxModelObject* oldContinuation = continuation(); 7264a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch setContinuation(newBox); 7274a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch 7284a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch // Someone may have put a <p> inside a <q>, causing a split. When this happens, the :after content 7294a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch // has to move into the inline continuation. Call updateBeforeAfterContent to ensure that our :after 7304a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch // content gets properly destroyed. 7314a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch bool isLastChild = (beforeChild == lastChild()); 7324a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch if (document()->usesBeforeAfterRules()) 7334a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch children()->updateBeforeAfterContent(this, AFTER); 7344a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch if (isLastChild && beforeChild != lastChild()) 7354a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch beforeChild = 0; // We destroyed the last child, so now we need to update our insertion 7364a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch // point to be 0. It's just a straight append now. 7374a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch 7384a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch splitFlow(beforeChild, newBox, newChild, oldContinuation); 7394a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch return; 7404a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch } 7414a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch 7424a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch // We have to perform a split of this block's children. This involves creating an anonymous block box to hold 7434a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch // the column-spanning |newChild|. We take all of the children from before |newChild| and put them into 7444a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch // one anonymous columns block, and all of the children after |newChild| go into another anonymous block. 7454a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch makeChildrenAnonymousColumnBlocks(beforeChild, newBox, newChild); 7464a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch return; 7474a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch } 7484a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch 7494a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch bool madeBoxesNonInline = false; 7504a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch 7518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // A block has to either have all of its children inline, or all of its children as blocks. 7528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // So, if our children are currently inline and a block child has to be inserted, we move all our 7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // inline children into anonymous block boxes. 7548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrPositioned()) { 7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This is a block with inline content. Wrap the inline content in anonymous blocks. 7568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project makeChildrenNonInline(beforeChild); 7578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project madeBoxesNonInline = true; 7588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (beforeChild && beforeChild->parent() != this) { 7608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project beforeChild = beforeChild->parent(); 7618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(beforeChild->isAnonymousBlock()); 7628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(beforeChild->parent() == this); 7638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 7648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } else if (!childrenInline() && (newChild->isFloatingOrPositioned() || newChild->isInline())) { 7658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If we're inserting an inline child but all of our children are blocks, then we have to make sure 7668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise 7678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // a new one is created and inserted into our list of children in the appropriate position. 7688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild(); 7698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (afterChild && afterChild->isAnonymousBlock()) { 7718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project afterChild->addChild(newChild); 7728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 7738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 7748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (newChild->isInline()) { 7768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // No suitable existing anonymous box - create a new one. 7778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderBlock* newBox = createAnonymousBlock(); 7788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderBox::addChild(newBox, beforeChild); 7798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newBox->addChild(newChild); 7808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 7818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 7828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 7838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderBox::addChild(newChild, beforeChild); 7858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRenderBlock()) 7878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian toRenderBlock(parent())->removeLeftoverAnonymousBlock(this); 7888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // this object may be dead here 7898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild) 7925af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 793545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (continuation() && !isAnonymousBlock()) 794545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return addChildToContinuation(newChild, beforeChild); 795545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return addChildIgnoringContinuation(newChild, beforeChild); 796545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch} 797545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 798545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild) 799545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{ 800545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (!isAnonymousBlock() && firstChild() && (firstChild()->isAnonymousColumnsBlock() || firstChild()->isAnonymousColumnSpanBlock())) 8015af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return addChildToAnonymousColumnBlocks(newChild, beforeChild); 8025af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild); 8035af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 8045af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 8058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void getInlineRun(RenderObject* start, RenderObject* boundary, 8068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject*& inlineRunStart, 8078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject*& inlineRunEnd) 8088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Beginning at |start| we find the largest contiguous run of inlines that 8108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // we can. We denote the run with start and end points, |inlineRunStart| 8118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // and |inlineRunEnd|. Note that these two values may be the same if 8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // we encounter only one inline. 8138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // 8148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We skip any non-inlines we encounter as long as we haven't found any 8158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // inlines yet. 8168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // 8178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // |boundary| indicates a non-inclusive boundary point. Regardless of whether |boundary| 8188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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 8198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // a non-inline. 8208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Start by skipping as many non-inlines as we can. 8228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject * curr = start; 8238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool sawInline; 8248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project do { 8258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (curr && !(curr->isInline() || curr->isFloatingOrPositioned())) 8268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project curr = curr->nextSibling(); 8278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineRunStart = inlineRunEnd = curr; 8298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!curr) 8318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; // No more inline children to be found. 8328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project sawInline = curr->isInline(); 8348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project curr = curr->nextSibling(); 8368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (curr && (curr->isInline() || curr->isFloatingOrPositioned()) && (curr != boundary)) { 8378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineRunEnd = curr; 8388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (curr->isInline()) 8398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project sawInline = true; 8408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project curr = curr->nextSibling(); 8418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } while (!sawInline); 8438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::deleteLineBoxTree() 8468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_lineBoxes.deleteLineBoxTree(renderArena()); 8488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 8498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 8500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochRootInlineBox* RenderBlock::createRootInlineBox() 8518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 8528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return new (renderArena()) RootInlineBox(this); 8538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 8548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 8550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochRootInlineBox* RenderBlock::createAndAppendRootInlineBox() 8568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 8570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch RootInlineBox* rootBox = createRootInlineBox(); 8588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_lineBoxes.appendLineBox(rootBox); 8598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return rootBox; 8608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 861643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 8625af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::moveChildTo(RenderBlock* to, RenderObject* child, RenderObject* beforeChild, bool fullRemoveInsert) 863643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 864643ca7872b450ea4efacab6188849e5aac2ba161Steve Block ASSERT(this == child->parent()); 865643ca7872b450ea4efacab6188849e5aac2ba161Steve Block ASSERT(!beforeChild || to == beforeChild->parent()); 8665af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke to->children()->insertChildNode(to, children()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert); 867d0825bca7fe65beaee391d30da42e937db621564Steve Block} 868d0825bca7fe65beaee391d30da42e937db621564Steve Block 8695af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkevoid RenderBlock::moveChildrenTo(RenderBlock* to, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert) 870d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 871d0825bca7fe65beaee391d30da42e937db621564Steve Block ASSERT(!beforeChild || to == beforeChild->parent()); 8725af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RenderObject* nextChild = startChild; 8735af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke while (nextChild && nextChild != endChild) { 874d0825bca7fe65beaee391d30da42e937db621564Steve Block RenderObject* child = nextChild; 875d0825bca7fe65beaee391d30da42e937db621564Steve Block nextChild = child->nextSibling(); 8765af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke to->children()->insertChildNode(to, children()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert); 8775af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (child == endChild) 8785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return; 879d0825bca7fe65beaee391d30da42e937db621564Steve Block } 880d0825bca7fe65beaee391d30da42e937db621564Steve Block} 881d0825bca7fe65beaee391d30da42e937db621564Steve Block 8828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint) 8838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // makeChildrenNonInline takes a block whose children are *all* inline and it 8858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // makes sure that inline children are coalesced under anonymous 8868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // blocks. If |insertionPoint| is defined, then it represents the insertion point for 8878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the new block child that is causing us to have to wrap all the inlines. This 8888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // means that we cannot coalesce inlines before |insertionPoint| with inlines following 8898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // |insertionPoint|, because the new child is going to be inserted in between the inlines, 8908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // splitting them. 8918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(isInlineBlockOrInlineTable() || !isInline()); 8928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!insertionPoint || insertionPoint->parent() == this); 8938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian setChildrenInline(false); 8958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject *child = firstChild(); 8978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!child) 8988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 8998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project deleteLineBoxTree(); 9018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (child) { 9038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject *inlineRunStart, *inlineRunEnd; 9048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd); 9058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!inlineRunStart) 9078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 9088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project child = inlineRunEnd->nextSibling(); 9108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderBlock* block = createAnonymousBlock(); 9128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian children()->insertChildNode(this, block, inlineRunStart); 9135af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke moveChildrenTo(block, inlineRunStart, child); 9148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG 9178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RenderObject *c = firstChild(); c; c = c->nextSibling()) 9188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!c->isInline()); 9198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 9208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project repaint(); 9228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child) 9258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 9268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ASSERT(child->isAnonymousBlock()); 9278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ASSERT(!child->childrenInline()); 9288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 9295af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (child->continuation() || (child->firstChild() && (child->isAnonymousColumnSpanBlock() || child->isAnonymousColumnsBlock()))) 9308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return; 9318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 9328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderObject* firstAnChild = child->m_children.firstChild(); 9338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderObject* lastAnChild = child->m_children.lastChild(); 9348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (firstAnChild) { 9358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderObject* o = firstAnChild; 9368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian while (o) { 9378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian o->setParent(this); 9388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian o = o->nextSibling(); 9398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 9408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian firstAnChild->setPreviousSibling(child->previousSibling()); 9418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian lastAnChild->setNextSibling(child->nextSibling()); 9428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (child->previousSibling()) 9438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian child->previousSibling()->setNextSibling(firstAnChild); 9448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (child->nextSibling()) 9458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian child->nextSibling()->setPreviousSibling(lastAnChild); 9465af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 9475af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (child == m_children.firstChild()) 9485af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke m_children.setFirstChild(firstAnChild); 9495af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (child == m_children.lastChild()) 9505af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke m_children.setLastChild(lastAnChild); 9518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } else { 9525af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (child == m_children.firstChild()) 9535af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke m_children.setFirstChild(child->nextSibling()); 9545af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (child == m_children.lastChild()) 9555af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke m_children.setLastChild(child->previousSibling()); 9565af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 9578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (child->previousSibling()) 9588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian child->previousSibling()->setNextSibling(child->nextSibling()); 9598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (child->nextSibling()) 9608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian child->nextSibling()->setPreviousSibling(child->previousSibling()); 9618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 9628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian child->setParent(0); 9638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian child->setPreviousSibling(0); 9648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian child->setNextSibling(0); 9658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 9668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian child->children()->setFirstChild(0); 9678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian child->m_next = 0; 9688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 9698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian child->destroy(); 9708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 9718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 9725af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkestatic bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObject* prev, RenderObject* next) 9735af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 9745af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (oldChild->documentBeingDestroyed() || oldChild->isInline() || oldChild->virtualContinuation()) 9755af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return false; 9765af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 9772bde8e466a4451c7319e3a072d118917957d6554Steve Block if (oldChild->parent() && oldChild->parent()->isDetails()) 9782bde8e466a4451c7319e3a072d118917957d6554Steve Block return false; 9792bde8e466a4451c7319e3a072d118917957d6554Steve Block 98065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if ((prev && (!prev->isAnonymousBlock() || toRenderBlock(prev)->continuation() || toRenderBlock(prev)->beingDestroyed())) 98165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch || (next && (!next->isAnonymousBlock() || toRenderBlock(next)->continuation() || toRenderBlock(next)->beingDestroyed()))) 9825af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return false; 9835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 984967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch // FIXME: This check isn't required when inline run-ins can't be split into continuations. 985967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (prev && prev->firstChild() && prev->firstChild()->isInline() && prev->firstChild()->isRunIn()) 986967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return false; 987967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 9885af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if ((prev && (prev->isRubyRun() || prev->isRubyBase())) 9895af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke || (next && (next->isRubyRun() || next->isRubyBase()))) 9905af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return false; 9915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 9925af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (!prev || !next) 9935af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return true; 9945af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 9955af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // Make sure the types of the anonymous blocks match up. 9965af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return prev->isAnonymousColumnsBlock() == next->isAnonymousColumnsBlock() 997cad810f21b803229eb11403f9209855525a25d57Steve Block && prev->isAnonymousColumnSpanBlock() == next->isAnonymousColumnSpanBlock(); 9985af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 9995af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 10008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::removeChild(RenderObject* oldChild) 10018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 10028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If this child is a block, and if our previous and next siblings are 10038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // both anonymous blocks with inline content, then we can go ahead and 10048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // fold the inline content back together. 10058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* prev = oldChild->previousSibling(); 10068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* next = oldChild->nextSibling(); 10075af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, prev, next); 10085af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (canMergeAnonymousBlocks && prev && next) { 10098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project prev->setNeedsLayoutAndPrefWidthsRecalc(); 10108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderBlock* nextBlock = toRenderBlock(next); 10118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderBlock* prevBlock = toRenderBlock(prev); 10125af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 10135af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (prev->childrenInline() != next->childrenInline()) { 10145af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RenderBlock* inlineChildrenBlock = prev->childrenInline() ? prevBlock : nextBlock; 10155af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RenderBlock* blockChildrenBlock = prev->childrenInline() ? nextBlock : prevBlock; 10165af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 10175af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // Place the inline children block inside of the block children block instead of deleting it. 10185af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // In order to reuse it, we have to reset it to just be a generic anonymous block. Make sure 10195af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // to clear out inherited column properties by just making a new style, and to also clear the 10205af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // column span flag if it is set. 10215af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke ASSERT(!inlineChildrenBlock->continuation()); 10222bde8e466a4451c7319e3a072d118917957d6554Steve Block RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style()); 10235af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke children()->removeChildNode(this, inlineChildrenBlock, inlineChildrenBlock->hasLayer()); 10245af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke inlineChildrenBlock->setStyle(newStyle); 10255af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 10265af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // Now just put the inlineChildrenBlock inside the blockChildrenBlock. 10275af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke blockChildrenBlock->children()->insertChildNode(blockChildrenBlock, inlineChildrenBlock, prev == inlineChildrenBlock ? blockChildrenBlock->firstChild() : 0, 10285af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke inlineChildrenBlock->hasLayer() || blockChildrenBlock->hasLayer()); 10295af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke next->setNeedsLayoutAndPrefWidthsRecalc(); 1030cad810f21b803229eb11403f9209855525a25d57Steve Block 1031cad810f21b803229eb11403f9209855525a25d57Steve Block // inlineChildrenBlock got reparented to blockChildrenBlock, so it is no longer a child 1032cad810f21b803229eb11403f9209855525a25d57Steve Block // of "this". we null out prev or next so that is not used later in the function. 1033cad810f21b803229eb11403f9209855525a25d57Steve Block if (inlineChildrenBlock == prevBlock) 1034cad810f21b803229eb11403f9209855525a25d57Steve Block prev = 0; 1035cad810f21b803229eb11403f9209855525a25d57Steve Block else 1036cad810f21b803229eb11403f9209855525a25d57Steve Block next = 0; 10375af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } else { 10385af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // Take all the children out of the |next| block and put them in 10395af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // the |prev| block. 104065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch nextBlock->moveAllChildrenTo(prevBlock, nextBlock->hasLayer() || prevBlock->hasLayer()); 1041cad810f21b803229eb11403f9209855525a25d57Steve Block 10425af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // Delete the now-empty block's lines and nuke it. 10435af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke nextBlock->deleteLineBoxTree(); 10445af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke nextBlock->destroy(); 1045cad810f21b803229eb11403f9209855525a25d57Steve Block next = 0; 10465af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } 10478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 10488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderBox::removeChild(oldChild); 10508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* child = prev ? prev : next; 10525af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && !isFlexibleBox()) { 10538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The removal has knocked us down to containing only a single anonymous 10548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // box. We can go ahead and pull the content right back up into our 10558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // box. 10568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project setNeedsLayoutAndPrefWidthsRecalc(); 10575af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke setChildrenInline(child->childrenInline()); 10585af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RenderBlock* anonBlock = toRenderBlock(children()->removeChildNode(this, child, child->hasLayer())); 10595af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke anonBlock->moveAllChildrenTo(this, child->hasLayer()); 10608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Delete the now-empty block's lines and nuke it. 10618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project anonBlock->deleteLineBoxTree(); 10628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project anonBlock->destroy(); 10638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1064d0825bca7fe65beaee391d30da42e937db621564Steve Block 10655af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (!firstChild() && !documentBeingDestroyed()) { 10665af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // If this was our last child be sure to clear out our line boxes. 10675af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (childrenInline()) 10685af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke lineBoxes()->deleteLineBoxes(renderArena()); 10695af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } 10708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 10718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::isSelfCollapsingBlock() const 10738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 10748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We are not self-collapsing if we 10758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // (a) have a non-zero height according to layout (an optimization to avoid wasting time) 10768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // (b) are a table, 10778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // (c) have border/padding, 10788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // (d) have a min-height 10798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // (e) have specified that one of our margins can't collapse using a CSS extension 1080a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (logicalHeight() > 0 1081a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch || isTable() || borderAndPaddingLogicalHeight() 1082a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch || style()->logicalMinHeight().isPositive() 1083bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen || style()->marginBeforeCollapse() == MSEPARATE || style()->marginAfterCollapse() == MSEPARATE) 10848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 10858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1086a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch Length logicalHeightLength = style()->logicalHeight(); 1087a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool hasAutoHeight = logicalHeightLength.isAuto(); 1088a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (logicalHeightLength.isPercent() && !document()->inQuirksMode()) { 10898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hasAutoHeight = true; 10908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RenderBlock* cb = containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) { 1091a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (cb->style()->logicalHeight().isFixed() || cb->isTableCell()) 10928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hasAutoHeight = false; 10938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 10948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 10958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the height is 0 or auto, then whether or not we are a self-collapsing block depends 10978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // on whether we have content that is all self-collapsing or not. 1098a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (hasAutoHeight || ((logicalHeightLength.isFixed() || logicalHeightLength.isPercent()) && logicalHeightLength.isZero())) { 10998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the block has inline children, see if we generated any line boxes. If we have any 11008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // line boxes, then we can't be self-collapsing, since we have content. 11018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (childrenInline()) 11028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return !firstLineBox(); 11038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Whether or not we collapse is dependent on whether all our normal flow children 11058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // are also self-collapsing. 1106635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) { 11078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (child->isFloatingOrPositioned()) 11088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 11098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!child->isSelfCollapsingBlock()) 11108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 11118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 11138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 11158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 11168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid RenderBlock::startDelayUpdateScrollInfo() 11180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 11190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (gDelayUpdateScrollInfo == 0) { 11200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(!gDelayedUpdateScrollInfoSet); 11210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet; 11220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 11230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(gDelayedUpdateScrollInfoSet); 11240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ++gDelayUpdateScrollInfo; 11250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 11260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 11270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid RenderBlock::finishDelayUpdateScrollInfo() 11280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 11290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch --gDelayUpdateScrollInfo; 11300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(gDelayUpdateScrollInfo >= 0); 11310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (gDelayUpdateScrollInfo == 0) { 11320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(gDelayedUpdateScrollInfoSet); 11330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1134643ca7872b450ea4efacab6188849e5aac2ba161Steve Block OwnPtr<DelayedUpdateScrollInfoSet> infoSet(gDelayedUpdateScrollInfoSet); 1135643ca7872b450ea4efacab6188849e5aac2ba161Steve Block gDelayedUpdateScrollInfoSet = 0; 1136643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 1137643ca7872b450ea4efacab6188849e5aac2ba161Steve Block for (DelayedUpdateScrollInfoSet::iterator it = infoSet->begin(); it != infoSet->end(); ++it) { 11380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch RenderBlock* block = *it; 11390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (block->hasOverflowClip()) { 11400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch block->layer()->updateScrollInfoAfterLayout(); 11410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 11420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 11430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 11440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 11450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 11460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid RenderBlock::updateScrollInfoAfterLayout() 11470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 11480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (hasOverflowClip()) { 11490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (gDelayUpdateScrollInfo) 11500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch gDelayedUpdateScrollInfoSet->add(this); 11510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch else 11520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch layer()->updateScrollInfoAfterLayout(); 11530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 11540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 11550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 11568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::layout() 11578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 11588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Update our first letter info now. 11598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project updateFirstLetter(); 11608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Table cells call layoutBlock directly, so don't add any logic here. Put code into 11628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // layoutBlock(). 11638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project layoutBlock(false); 11648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // It's safe to check for control clip here, since controls can never be table cells. 1166231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // If we have a lightweight clip, there can never be any overflow from children. 1167231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (hasControlClip() && m_overflow) 1168231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block clearLayoutOverflow(); 11698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 11708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1171f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderBlock::layoutBlock(bool relayoutChildren, int pageLogicalHeight) 11728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 11738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(needsLayout()); 11748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isInline() && !isInlineBlockOrInlineTable()) // Inline <form>s inside various table elements can 11768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; // cause us to come in here. Just bail. 11778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11782bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!relayoutChildren && simplifiedLayout()) 11798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 11808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian LayoutRepainter repainter(*this, m_everHadLayout && checkForRepaintDuringLayout()); 11828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1183a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int oldWidth = logicalWidth(); 11848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int oldColumnWidth = desiredColumnWidth(); 11858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1186bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen computeLogicalWidth(); 11878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project calcColumnWidth(); 11888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1189231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_overflow.clear(); 11908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1191bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (oldWidth != logicalWidth() || oldColumnWidth != desiredColumnWidth()) 11928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project relayoutChildren = true; 11938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_LAYOUT 119523e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang checkAndSetRelayoutChildren(&relayoutChildren); 11968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 11978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project clearFloats(); 11998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1200bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int previousHeight = logicalHeight(); 1201bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen setLogicalHeight(0); 1202f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch bool hasSpecifiedPageLogicalHeight = false; 1203f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch bool pageLogicalHeightChanged = false; 120468513a70bcd92384395513322f1b801e7bf9c729Steve Block ColumnInfo* colInfo = columnInfo(); 120568513a70bcd92384395513322f1b801e7bf9c729Steve Block if (hasColumns()) { 1206f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!pageLogicalHeight) { 120768513a70bcd92384395513322f1b801e7bf9c729Steve Block // We need to go ahead and set our explicit page height if one exists, so that we can 120868513a70bcd92384395513322f1b801e7bf9c729Steve Block // avoid doing two layout passes. 1209bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen computeLogicalHeight(); 1210bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int columnHeight = contentLogicalHeight(); 121168513a70bcd92384395513322f1b801e7bf9c729Steve Block if (columnHeight > 0) { 1212f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch pageLogicalHeight = columnHeight; 1213f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch hasSpecifiedPageLogicalHeight = true; 121468513a70bcd92384395513322f1b801e7bf9c729Steve Block } 1215bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen setLogicalHeight(0); 121668513a70bcd92384395513322f1b801e7bf9c729Steve Block } 1217f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (colInfo->columnHeight() != pageLogicalHeight && m_everHadLayout) { 1218f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch colInfo->setColumnHeight(pageLogicalHeight); 1219f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch pageLogicalHeightChanged = true; 122068513a70bcd92384395513322f1b801e7bf9c729Steve Block } 122168513a70bcd92384395513322f1b801e7bf9c729Steve Block 1222f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!hasSpecifiedPageLogicalHeight && !pageLogicalHeight) 122368513a70bcd92384395513322f1b801e7bf9c729Steve Block colInfo->clearForcedBreaks(); 122468513a70bcd92384395513322f1b801e7bf9c729Steve Block } 122568513a70bcd92384395513322f1b801e7bf9c729Steve Block 1226f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode(), pageLogicalHeight, pageLogicalHeightChanged, colInfo); 1227635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 12285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track 12298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // our current maximal positive and negative margins. These values are used when we 12308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // are collapsed with adjacent blocks, so for example, if you have block A and B 12318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // collapsing together, then you'd take the maximal positive margin from both A and B 12328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // and subtract it from the maximal negative margin from both A and B to get the 12338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // true collapsed margin. This algorithm is recursive, so when we finish layout() 12348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // our block knows its current maximal positive/negative values. 12358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // 12368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Start out by setting our margin values to our current margins. Table cells have 12378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // no margins, so we don't fill in the values for table cells. 12388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool isCell = isTableCell(); 12398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!isCell) { 12408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project initMaxMarginValues(); 124168513a70bcd92384395513322f1b801e7bf9c729Steve Block 1242bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen setMarginBeforeQuirk(style()->marginBefore().quirk()); 1243bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen setMarginAfterQuirk(style()->marginAfter().quirk()); 12448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Node* n = node(); 12468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (n && n->hasTagName(formTag) && static_cast<HTMLFormElement*>(n)->isMalformed()) { 12478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // See if this form is malformed (i.e., unclosed). If so, don't give the form 12488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // a bottom margin. 1249bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen setMaxMarginAfterValues(0, 0); 12508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 125168513a70bcd92384395513322f1b801e7bf9c729Steve Block 125268513a70bcd92384395513322f1b801e7bf9c729Steve Block setPaginationStrut(0); 12538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // For overflow:scroll blocks, ensure we have both scrollbars in place always. 12568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (scrollsOverflow()) { 12578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->overflowX() == OSCROLL) 12588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian layer()->setHasHorizontalScrollbar(true); 12598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->overflowY() == OSCROLL) 12608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian layer()->setHasVerticalScrollbar(true); 12618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1263a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int repaintLogicalTop = 0; 1264a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int repaintLogicalBottom = 0; 1265a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int maxFloatLogicalBottom = 0; 1266e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (!firstChild() && !isAnonymousBlock()) 12676c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen setChildrenInline(true); 12688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (childrenInline()) 1269a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch layoutInlineChildren(relayoutChildren, repaintLogicalTop, repaintLogicalBottom); 12708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 1271a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch layoutBlockChildren(relayoutChildren, maxFloatLogicalBottom); 12728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Expand our intrinsic height to encompass floats. 1274a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int toAdd = borderAfter() + paddingAfter() + scrollbarLogicalHeight(); 1275a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (lowestFloatLogicalBottom() > (logicalHeight() - toAdd) && expandsToEncloseOverhangingFloats()) 1276a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeight(lowestFloatLogicalBottom() + toAdd); 12778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1278f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (layoutColumns(hasSpecifiedPageLogicalHeight, pageLogicalHeight, statePusher)) 127968513a70bcd92384395513322f1b801e7bf9c729Steve Block return; 128068513a70bcd92384395513322f1b801e7bf9c729Steve Block 12818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Calculate our new height. 1282bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int oldHeight = logicalHeight(); 1283f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch int oldClientAfterEdge = clientLogicalBottom(); 1284bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen computeLogicalHeight(); 1285bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int newHeight = logicalHeight(); 1286bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (oldHeight != newHeight) { 1287a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (oldHeight > newHeight && maxFloatLogicalBottom > newHeight && !childrenInline()) { 12888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // One of our children's floats may have become an overhanging float for us. We need to look for it. 12898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { 12908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (child->isBlockFlow() && !child->isFloatingOrPositioned()) { 12918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderBlock* block = toRenderBlock(child); 1292a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (block->lowestFloatLogicalBottom() + block->logicalTop() > newHeight) 1293a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch addOverhangingFloats(block, -block->logicalLeft(), -block->logicalTop(), false); 12948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1298231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1299bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (previousHeight != newHeight) 13008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project relayoutChildren = true; 13018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1302231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block layoutPositionedObjects(relayoutChildren || isRoot()); 13038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1304f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway). 1305f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch computeOverflow(oldClientAfterEdge); 1306231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1307635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project statePusher.pop(); 13088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1309f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (view()->layoutState()->m_pageLogicalHeight) 13102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(logicalTop())); 1311f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1312f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch updateLayerTransform(); 131368513a70bcd92384395513322f1b801e7bf9c729Steve Block 13148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if 13158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // we overflow or not. 13160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch updateScrollInfoAfterLayout(); 13178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Repaint with our new bounds if they are different from our old bounds. 13198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian bool didFullRepaint = repainter.repaintAfterLayout(); 1320a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!didFullRepaint && repaintLogicalTop != repaintLogicalBottom && (style()->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) { 1321f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // FIXME: We could tighten up the left and right invalidation points if we let layoutInlineChildren fill them in based off the particular lines 1322f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // it had to lay out. We wouldn't need the hasOverflowClip() hack in that case either. 1323f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch int repaintLogicalLeft = logicalLeftVisualOverflow(); 1324f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch int repaintLogicalRight = logicalRightVisualOverflow(); 1325f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (hasOverflowClip()) { 1326f05b935882198ccf7d81675736e3aeb089c5113aBen 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. 1327f05b935882198ccf7d81675736e3aeb089c5113aBen 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. 1328f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // layoutInlineChildren should be patched to compute the entire repaint rect. 1329f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch repaintLogicalLeft = min(repaintLogicalLeft, logicalLeftLayoutOverflow()); 1330f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch repaintLogicalRight = max(repaintLogicalRight, logicalRightLayoutOverflow()); 1331f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 1332a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1333a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch IntRect repaintRect; 13342bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isHorizontalWritingMode()) 1335a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch repaintRect = IntRect(repaintLogicalLeft, repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop); 1336a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch else 1337a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch repaintRect = IntRect(repaintLogicalTop, repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft); 13388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1339e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // The repaint rect may be split across columns, in which case adjustRectForColumns() will return the union. 1340e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block adjustRectForColumns(repaintRect); 13418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project repaintRect.inflate(maximalOutlineSize(PaintPhaseOutline)); 13438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (hasOverflowClip()) { 13458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Adjust repaint rect for scroll offset 1346dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block repaintRect.move(-layer()->scrolledContentOffset()); 13478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Don't allow this rect to spill out of our overflow box. 1349635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project repaintRect.intersect(IntRect(0, 0, width(), height())); 13508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Make sure the rect is still non-empty after intersecting for overflow above 13538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!repaintRect.isEmpty()) { 13548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project repaintRectangle(repaintRect); // We need to do a partial repaint of our content. 13558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (hasReflection()) 13565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian repaintRectangle(reflectedRect(repaintRect)); 13578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project setNeedsLayout(false); 13608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 13618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1362f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderBlock::addOverflowFromChildren() 1363f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 1364f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!hasColumns()) { 1365f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (childrenInline()) 1366f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch addOverflowFromInlineChildren(); 1367f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch else 1368f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch addOverflowFromBlockChildren(); 1369f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } else { 1370f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch ColumnInfo* colInfo = columnInfo(); 1371f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (columnCount(colInfo)) { 1372f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch IntRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1); 13732bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isHorizontalWritingMode()) { 13742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int overflowLeft = !style()->isLeftToRightDirection() ? min(0, lastRect.x()) : 0; 13752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int overflowRight = style()->isLeftToRightDirection() ? max(width(), lastRect.maxX()) : 0; 13762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int overflowHeight = borderBefore() + paddingBefore() + colInfo->columnHeight(); 13772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block addLayoutOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight)); 13782bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!hasOverflowClip()) 13792bde8e466a4451c7319e3a072d118917957d6554Steve Block addVisualOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight)); 13802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } else { 13812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block IntRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1); 13822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int overflowTop = !style()->isLeftToRightDirection() ? min(0, lastRect.y()) : 0; 13832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int overflowBottom = style()->isLeftToRightDirection() ? max(height(), lastRect.maxY()) : 0; 13842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int overflowWidth = borderBefore() + paddingBefore() + colInfo->columnHeight(); 13852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block addLayoutOverflow(IntRect(0, overflowTop, overflowWidth, overflowBottom - overflowTop)); 13862bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!hasOverflowClip()) 13872bde8e466a4451c7319e3a072d118917957d6554Steve Block addVisualOverflow(IntRect(0, overflowTop, overflowWidth, overflowBottom - overflowTop)); 13882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1389f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 1390f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 1391f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 1392f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1393f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderBlock::computeOverflow(int oldClientAfterEdge, bool recomputeFloats) 1394f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 1395f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // Add overflow from children. 1396f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch addOverflowFromChildren(); 1397f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1398f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!hasColumns() && (recomputeFloats || isRoot() || expandsToEncloseOverhangingFloats() || hasSelfPaintingLayer())) 1399f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch addOverflowFromFloats(); 1400f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1401f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // Add in the overflow from positioned objects. 1402f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch addOverflowFromPositionedObjects(); 1403f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1404f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (hasOverflowClip()) { 1405f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // When we have overflow clip, propagate the original spillout since it will include collapsed bottom margins 1406f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // and bottom padding. Set the axis we don't care about to be 1, since we want this overflow to always 1407f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // be considered reachable. 1408f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch IntRect clientRect(clientBoxRect()); 1409f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch IntRect rectToApply; 14102bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isHorizontalWritingMode()) 1411f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch rectToApply = IntRect(clientRect.x(), clientRect.y(), 1, max(0, oldClientAfterEdge - clientRect.y())); 1412f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch else 1413f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch rectToApply = IntRect(clientRect.x(), clientRect.y(), max(0, oldClientAfterEdge - clientRect.x()), 1); 1414f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch addLayoutOverflow(rectToApply); 1415f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 1416f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1417f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // Add visual overflow from box-shadow and reflections. 1418f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch addShadowOverflow(); 1419f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 1420f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1421231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid RenderBlock::addOverflowFromBlockChildren() 1422231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 1423231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) { 1424231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!child->isFloatingOrPositioned()) 1425231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block addOverflowFromChild(child); 1426231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 1427231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 1428231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1429231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid RenderBlock::addOverflowFromFloats() 1430231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 1431231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!m_floatingObjects) 1432231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 143381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 143481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 143581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator end = floatingObjectSet.end(); 143681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) { 143781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* r = *it; 1438f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (r->m_isDescendant) 14392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block addOverflowFromChild(r->m_renderer, IntSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r))); 1440231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 1441231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 1442231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 1443231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1444f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderBlock::addOverflowFromPositionedObjects() 1445f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 1446f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!m_positionedObjects) 1447f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return; 1448f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1449f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch RenderBox* positionedObject; 1450f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch Iterator end = m_positionedObjects->end(); 1451f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch for (Iterator it = m_positionedObjects->begin(); it != end; ++it) { 1452f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch positionedObject = *it; 1453f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1454f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // Fixed positioned elements don't contribute to layout overflow, since they don't scroll with the content. 1455f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (positionedObject->style()->position() != FixedPosition) 1456f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch addOverflowFromChild(positionedObject); 1457f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 1458f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 1459f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1460635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool RenderBlock::expandsToEncloseOverhangingFloats() const 1461635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 1462bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen return isInlineBlockOrInlineTable() || isFloatingOrPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBox()) 1463a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch || hasColumns() || isTableCell() || isFieldset() || isWritingModeRoot(); 1464635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 1465635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1466635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marginInfo) 14678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 14682bde8e466a4451c7319e3a072d118917957d6554Steve Block bool isHorizontal = isHorizontalWritingMode(); 146981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch bool hasStaticBlockPosition = child->style()->hasStaticBlockPosition(isHorizontal); 147081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch RenderLayer* childLayer = child->layer(); 147181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 14722bde8e466a4451c7319e3a072d118917957d6554Steve Block childLayer->setStaticInlinePosition(borderAndPaddingStart()); 14732bde8e466a4451c7319e3a072d118917957d6554Steve Block 14742bde8e466a4451c7319e3a072d118917957d6554Steve Block int logicalTop = logicalHeight(); 14752bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!marginInfo.canCollapseWithMarginBefore()) { 14762bde8e466a4451c7319e3a072d118917957d6554Steve Block child->computeBlockDirectionMargins(this); 14772bde8e466a4451c7319e3a072d118917957d6554Steve Block int marginBefore = marginBeforeForChild(child); 14782bde8e466a4451c7319e3a072d118917957d6554Steve Block int collapsedBeforePos = marginInfo.positiveMargin(); 14792bde8e466a4451c7319e3a072d118917957d6554Steve Block int collapsedBeforeNeg = marginInfo.negativeMargin(); 14802bde8e466a4451c7319e3a072d118917957d6554Steve Block if (marginBefore > 0) { 14812bde8e466a4451c7319e3a072d118917957d6554Steve Block if (marginBefore > collapsedBeforePos) 14822bde8e466a4451c7319e3a072d118917957d6554Steve Block collapsedBeforePos = marginBefore; 14832bde8e466a4451c7319e3a072d118917957d6554Steve Block } else { 14842bde8e466a4451c7319e3a072d118917957d6554Steve Block if (-marginBefore > collapsedBeforeNeg) 14852bde8e466a4451c7319e3a072d118917957d6554Steve Block collapsedBeforeNeg = -marginBefore; 14868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 14872bde8e466a4451c7319e3a072d118917957d6554Steve Block logicalTop += (collapsedBeforePos - collapsedBeforeNeg) - marginBefore; 14882bde8e466a4451c7319e3a072d118917957d6554Steve Block } 14892bde8e466a4451c7319e3a072d118917957d6554Steve Block if (childLayer->staticBlockPosition() != logicalTop) { 14902bde8e466a4451c7319e3a072d118917957d6554Steve Block childLayer->setStaticBlockPosition(logicalTop); 14912bde8e466a4451c7319e3a072d118917957d6554Steve Block if (hasStaticBlockPosition) 1492643ca7872b450ea4efacab6188849e5aac2ba161Steve Block child->setChildNeedsLayout(true, false); 14938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 14948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 14958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::adjustFloatingBlock(const MarginInfo& marginInfo) 14978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 14988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The float should be positioned taking into account the bottom margin 14998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // of the previous flow. We add that margin into the height, get the 15008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // float positioned properly, and then subtract the margin out of the 15018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // height again. In the case of self-collapsing blocks, we always just 15028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // use the top margins, since the self-collapsing block collapsed its 15038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // own bottom margin into its top margin. 15048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // 15058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Note also that the previous flow may collapse its margin into the top of 15068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // our block. If this is the case, then we do not add the margin in to our 15078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // height when computing the position of the float. This condition can be tested 1508bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // for by simply calling canCollapseWithMarginBefore. See 15098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for 15108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // an example of this scenario. 1511bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int marginOffset = marginInfo.canCollapseWithMarginBefore() ? 0 : marginInfo.margin(); 1512a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeight(logicalHeight() + marginOffset); 15138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project positionNewFloats(); 1514a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeight(logicalHeight() - marginOffset); 15158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 15168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool RenderBlock::handleSpecialChild(RenderBox* child, const MarginInfo& marginInfo) 15188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 15195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Handle in the given order 15205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return handlePositionedChild(child, marginInfo) 15215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian || handleFloatingChild(child, marginInfo) 15225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian || handleRunInChild(child); 15238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 15248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool RenderBlock::handlePositionedChild(RenderBox* child, const MarginInfo& marginInfo) 15278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 15288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (child->isPositioned()) { 15298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project child->containingBlock()->insertPositionedObject(child); 15308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project adjustPositionedBlock(child, marginInfo); 15315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return true; 15328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 15335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return false; 15348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 15358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool RenderBlock::handleFloatingChild(RenderBox* child, const MarginInfo& marginInfo) 15378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 15388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (child->isFloating()) { 15398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project insertFloatingObject(child); 15408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project adjustFloatingBlock(marginInfo); 15415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return true; 15428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 15435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return false; 15448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 15458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool RenderBlock::handleRunInChild(RenderBox* child) 15478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 15488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // See if we have a run-in element with inline children. If the 15498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // children aren't inline, then just treat the run-in as a normal 15508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // block. 1551231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!child->isRunIn() || !child->childrenInline()) 1552231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 1553231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // FIXME: We don't handle non-block elements with run-in for now. 1554231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!child->isRenderBlock()) 15555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return false; 1556635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 15570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch RenderBlock* blockRunIn = toRenderBlock(child); 15585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian RenderObject* curr = blockRunIn->nextSibling(); 15599a26d18f4c7e98b479be700575d003f873214550John Reck if (!curr || !curr->isRenderBlock() || !curr->childrenInline() || curr->isRunIn() || curr->isAnonymous() || curr->isFloatingOrPositioned()) 15605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return false; 15615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 15625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian RenderBlock* currBlock = toRenderBlock(curr); 15635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1564538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block // First we destroy any :before/:after content. It will be regenerated by the new inline. 1565538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block // Exception is if the run-in itself is generated. 1566538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block if (child->style()->styleType() != BEFORE && child->style()->styleType() != AFTER) { 1567538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block RenderObject* generatedContent; 1568538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block if (child->getCachedPseudoStyle(BEFORE) && (generatedContent = child->beforePseudoElementRenderer())) 1569538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block generatedContent->destroy(); 1570538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block if (child->getCachedPseudoStyle(AFTER) && (generatedContent = child->afterPseudoElementRenderer())) 1571538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block generatedContent->destroy(); 1572538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block } 1573538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block 15745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Remove the old child. 15755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian children()->removeChildNode(this, blockRunIn); 1576635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 15775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Create an inline. 15785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Node* runInNode = blockRunIn->node(); 15795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian RenderInline* inlineRunIn = new (renderArena()) RenderInline(runInNode ? runInNode : document()); 15805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian inlineRunIn->setStyle(blockRunIn->style()); 15815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1582538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block // Move the nodes from the old child to the new child 15836c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen for (RenderObject* runInChild = blockRunIn->firstChild(); runInChild;) { 15846c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen RenderObject* nextSibling = runInChild->nextSibling(); 1585538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block blockRunIn->children()->removeChildNode(blockRunIn, runInChild, false); 1586538b01d6410e7c7a5b2faabe7b84c80ddc32d5f3Steve Block inlineRunIn->addChild(runInChild); // Use addChild instead of appendChildNode since it handles correct placement of the children relative to :after-generated content. 15876c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen runInChild = nextSibling; 15888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 15895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 15902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben 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 15912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // anything before the first child. e.g. details tag. See https://bugs.webkit.org/show_bug.cgi?id=58228. 15922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch currBlock->addChild(inlineRunIn, currBlock->firstChild()); 15935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 15945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // If the run-in had an element, we need to set the new renderer. 15955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (runInNode) 15965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian runInNode->setRenderer(inlineRunIn); 15975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1598bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // Destroy the block run-in, which includes deleting its line box tree. 1599bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen blockRunIn->deleteLineBoxTree(); 16005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian blockRunIn->destroy(); 16015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 16025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // The block acts like an inline, so just null out its 16035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // position. 16045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 16055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return true; 16068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 16078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianint RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo) 16098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1610a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // Get the four margin values for the child and cache them. 1611a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch const MarginValues childMargins = marginValuesForChild(child); 1612a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 16138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Get our max pos and neg top margins. 1614a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int posTop = childMargins.positiveMarginBefore(); 1615a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int negTop = childMargins.negativeMarginBefore(); 16168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // For self-collapsing blocks, collapse our bottom margins into our 16188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // top to get new posTop and negTop values. 16198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (child->isSelfCollapsingBlock()) { 1620a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch posTop = max(posTop, childMargins.positiveMarginAfter()); 1621a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch negTop = max(negTop, childMargins.negativeMarginAfter()); 16228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 16238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // See if the top margin is quirky. We only care if this child has 16258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // margins that will collapse with us. 1626bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen bool topQuirk = child->isMarginBeforeQuirk() || style()->marginBeforeCollapse() == MDISCARD; 16278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1628bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (marginInfo.canCollapseWithMarginBefore()) { 16298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This child is collapsing with the top of the 16308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // block. If it has larger margin values, then we need to update 16318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // our own maximal values. 16325ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !topQuirk) 1633a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setMaxMarginBeforeValues(max(posTop, maxPositiveMarginBefore()), max(negTop, maxNegativeMarginBefore())); 16348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The minute any of the margins involved isn't a quirk, don't 16368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // collapse it away, even if the margin is smaller (www.webreference.com 16378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // has an example of this, a <dt> with 0.8em author-specified inside 16388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // a <dl> inside a <td>. 1639a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!marginInfo.determinedMarginBeforeQuirk() && !topQuirk && (posTop - negTop)) { 1640bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen setMarginBeforeQuirk(false); 1641bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen marginInfo.setDeterminedMarginBeforeQuirk(true); 16428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 16438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1644a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!marginInfo.determinedMarginBeforeQuirk() && topQuirk && !marginBefore()) 16458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We have no top margin and our top child has a quirky margin. 16468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We will pick up this quirky margin and pass it through. 16478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This deals with the <td><div><p> case. 16488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Don't do this for a block that split two inlines though. You do 16498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // still apply margins in this case. 1650bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen setMarginBeforeQuirk(true); 16518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 16528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1653bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (marginInfo.quirkContainer() && marginInfo.atBeforeSideOfBlock() && (posTop - negTop)) 1654bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen marginInfo.setMarginBeforeQuirk(topQuirk); 16558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1656a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int beforeCollapseLogicalTop = logicalHeight(); 1657a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int logicalTop = beforeCollapseLogicalTop; 16588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (child->isSelfCollapsingBlock()) { 16598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This child has no height. We need to compute our 16608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // position before we collapse the child's margins together, 16618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // so that we can get an accurate position for the zero-height block. 1662a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int collapsedBeforePos = max(marginInfo.positiveMargin(), childMargins.positiveMarginBefore()); 1663a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int collapsedBeforeNeg = max(marginInfo.negativeMargin(), childMargins.negativeMarginBefore()); 1664a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch marginInfo.setMargin(collapsedBeforePos, collapsedBeforeNeg); 16658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Now collapse the child's margins together, which means examining our 16678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // bottom margin values as well. 1668a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch marginInfo.setPositiveMarginIfLarger(childMargins.positiveMarginAfter()); 1669a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch marginInfo.setNegativeMarginIfLarger(childMargins.negativeMarginAfter()); 16708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1671bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (!marginInfo.canCollapseWithMarginBefore()) 16728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We need to make sure that the position of the self-collapsing block 16738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // is correct, since it could have overflowing content 16748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // that needs to be positioned correctly (e.g., a block that 16758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // had a specified height of 0 but that actually had subcontent). 1676a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch logicalTop = logicalHeight() + collapsedBeforePos - collapsedBeforeNeg; 16778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 16788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1679bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (child->style()->marginBeforeCollapse() == MSEPARATE) { 1680a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeight(logicalHeight() + marginInfo.margin() + marginBeforeForChild(child)); 1681a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch logicalTop = logicalHeight(); 16828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1683bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen else if (!marginInfo.atBeforeSideOfBlock() || 1684bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen (!marginInfo.canCollapseMarginBeforeWithChildren() 1685bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.marginBeforeQuirk()))) { 16868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We're collapsing with a previous sibling's margins and not 16878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // with the top of the block. 1688a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeight(logicalHeight() + max(marginInfo.positiveMargin(), posTop) - max(marginInfo.negativeMargin(), negTop)); 1689a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch logicalTop = logicalHeight(); 16908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 16918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1692a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch marginInfo.setPositiveMargin(childMargins.positiveMarginAfter()); 1693a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch marginInfo.setNegativeMargin(childMargins.negativeMarginAfter()); 16948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (marginInfo.margin()) 1696bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen marginInfo.setMarginAfterQuirk(child->isMarginAfterQuirk() || style()->marginAfterCollapse() == MDISCARD); 16978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 16988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 169968513a70bcd92384395513322f1b801e7bf9c729Steve Block // If margins would pull us past the top of the next page, then we need to pull back and pretend like the margins 170068513a70bcd92384395513322f1b801e7bf9c729Steve Block // collapsed into the page edge. 170168513a70bcd92384395513322f1b801e7bf9c729Steve Block bool paginated = view()->layoutState()->isPaginated(); 1702a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (paginated && logicalTop > beforeCollapseLogicalTop) { 1703a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int oldLogicalTop = logicalTop; 17042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block logicalTop = min(logicalTop, nextPageLogicalTop(beforeCollapseLogicalTop)); 1705a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop)); 170668513a70bcd92384395513322f1b801e7bf9c729Steve Block } 1707a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return logicalTop; 17088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 17098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 17108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianint RenderBlock::clearFloatsIfNeeded(RenderBox* child, MarginInfo& marginInfo, int oldTopPosMargin, int oldTopNegMargin, int yPos) 17118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 17128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int heightIncrease = getClearDelta(child, yPos); 17138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!heightIncrease) 17148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return yPos; 17158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 17168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (child->isSelfCollapsingBlock()) { 17178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // For self-collapsing blocks that clear, they can still collapse their 17188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // margins with following siblings. Reset the current margins to represent 17198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the self-collapsing block's margins only. 1720231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // CSS2.1 states: 1721231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // "An element that has had clearance applied to it never collapses its top margin with its parent block's bottom margin. 1722231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Therefore if we are at the bottom of the block, let's go ahead and reset margins to only include the 1723231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // self-collapsing block's bottom margin. 1724231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bool atBottomOfBlock = true; 1725231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block for (RenderBox* curr = child->nextSiblingBox(); curr && atBottomOfBlock; curr = curr->nextSiblingBox()) { 1726231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!curr->isFloatingOrPositioned()) 1727231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block atBottomOfBlock = false; 1728231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 1729a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1730a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch MarginValues childMargins = marginValuesForChild(child); 1731231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (atBottomOfBlock) { 1732a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch marginInfo.setPositiveMargin(childMargins.positiveMarginAfter()); 1733a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch marginInfo.setNegativeMargin(childMargins.negativeMarginAfter()); 1734231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } else { 1735a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch marginInfo.setPositiveMargin(max(childMargins.positiveMarginBefore(), childMargins.positiveMarginAfter())); 1736a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch marginInfo.setNegativeMargin(max(childMargins.negativeMarginBefore(), childMargins.negativeMarginAfter())); 1737231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 17388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1739231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Adjust our height such that we are ready to be collapsed with subsequent siblings (or the bottom 1740231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // of the parent block). 1741bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen setLogicalHeight(child->y() - max(0, marginInfo.margin())); 17428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else 17438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Increase our height by the amount we had to clear. 1744bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen setLogicalHeight(height() + heightIncrease); 17458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1746bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (marginInfo.canCollapseWithMarginBefore()) { 17478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We can no longer collapse with the top of the block since a clear 17488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // occurred. The empty blocks collapse into the cleared block. 17498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: This isn't quite correct. Need clarification for what to do 17508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // if the height the cleared block is offset by is smaller than the 17518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // margins involved. 1752bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen setMaxMarginBeforeValues(oldTopPosMargin, oldTopNegMargin); 1753bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen marginInfo.setAtBeforeSideOfBlock(false); 17548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 17558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 17568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return yPos + heightIncrease; 17578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 17588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1759a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::estimateLogicalTopPosition(RenderBox* child, const MarginInfo& marginInfo) 17608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 17618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: We need to eliminate the estimation of vertical position, because when it's wrong we sometimes trigger a pathological 17628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // relayout if there are intruding floats. 1763a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int logicalTopEstimate = logicalHeight(); 1764bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (!marginInfo.canCollapseWithMarginBefore()) { 1765a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int childMarginBefore = child->selfNeedsLayout() ? marginBeforeForChild(child) : collapsedMarginBeforeForChild(child); 1766a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch logicalTopEstimate += max(marginInfo.margin(), childMarginBefore); 17678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 176868513a70bcd92384395513322f1b801e7bf9c729Steve Block 176968513a70bcd92384395513322f1b801e7bf9c729Steve Block bool paginated = view()->layoutState()->isPaginated(); 177068513a70bcd92384395513322f1b801e7bf9c729Steve Block 1771a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // Adjust logicalTopEstimate down to the next page if the margins are so large that we don't fit on the current 177268513a70bcd92384395513322f1b801e7bf9c729Steve Block // page. 1773a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (paginated && logicalTopEstimate > logicalHeight()) 17742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block logicalTopEstimate = min(logicalTopEstimate, nextPageLogicalTop(logicalHeight())); 177568513a70bcd92384395513322f1b801e7bf9c729Steve Block 1776a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch logicalTopEstimate += getClearDelta(child, logicalTopEstimate); 177768513a70bcd92384395513322f1b801e7bf9c729Steve Block 177868513a70bcd92384395513322f1b801e7bf9c729Steve Block if (paginated) { 177968513a70bcd92384395513322f1b801e7bf9c729Steve Block // If the object has a page or column break value of "before", then we should shift to the top of the next page. 1780a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch logicalTopEstimate = applyBeforeBreak(child, logicalTopEstimate); 178168513a70bcd92384395513322f1b801e7bf9c729Steve Block 178268513a70bcd92384395513322f1b801e7bf9c729Steve 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. 1783a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch logicalTopEstimate = adjustForUnsplittableChild(child, logicalTopEstimate); 178468513a70bcd92384395513322f1b801e7bf9c729Steve Block 178568513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!child->selfNeedsLayout() && child->isRenderBlock()) 1786a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch logicalTopEstimate += toRenderBlock(child)->paginationStrut(); 178768513a70bcd92384395513322f1b801e7bf9c729Steve Block } 178868513a70bcd92384395513322f1b801e7bf9c729Steve Block 1789a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return logicalTopEstimate; 17908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 17918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1792a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::determineLogicalLeftPositionForChild(RenderBox* child) 17938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1794a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int startPosition = borderStart() + paddingStart(); 1795a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + availableLogicalWidth(); 1796a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1797a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // Add in our start margin. 1798a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int childMarginStart = marginStartForChild(child); 1799a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int newPosition = startPosition + childMarginStart; 18008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1801a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats. They need 1802a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // to shift over as necessary to dodge any floats that might get in the way. 1803a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (child->avoidsFloats()) { 1804a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int startOff = style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(logicalHeight(), false) : totalAvailableLogicalWidth - logicalRightOffsetForLine(logicalHeight(), false); 1805a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (style()->textAlign() != WEBKIT_CENTER && !child->style()->marginStartUsing(style()).isAuto()) { 1806a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (childMarginStart < 0) 1807a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch startOff += childMarginStart; 1808a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch newPosition = max(newPosition, startOff); // Let the float sit in the child's margin if it can fit. 1809a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } else if (startOff != startPosition) { 1810a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // The object is shifting to the "end" side of the block. The object might be centered, so we need to 1811a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // recalculate our inline direction margins. Note that the containing block content 1812a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // width computation will take into account the delta between |startOff| and |startPosition| 1813a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // so that we can just pass the content width in directly to the |computeMarginsInContainingBlockInlineDirection| 1814a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // function. 1815a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->computeInlineDirectionMargins(this, availableLogicalWidthForLine(logicalTopForChild(child), false), logicalWidthForChild(child)); 1816a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch newPosition = startOff + marginStartForChild(child); 18178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 18188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1819a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1820a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalLeftForChild(child, style()->isLeftToRightDirection() ? newPosition : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child), ApplyLayoutDelta); 18218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 18228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::setCollapsedBottomMargin(const MarginInfo& marginInfo) 18248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1825bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()) { 18268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Update our max pos/neg bottom margins, since we collapsed our bottom margins 18278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // with our children. 1828a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setMaxMarginAfterValues(max(maxPositiveMarginAfter(), marginInfo.positiveMargin()), max(maxNegativeMarginAfter(), marginInfo.negativeMargin())); 18298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1830bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (!marginInfo.marginAfterQuirk()) 1831bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen setMarginAfterQuirk(false); 18328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1833a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (marginInfo.marginAfterQuirk() && marginAfter() == 0) 18348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We have no bottom margin and our last child has a quirky margin. 18358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We will pick up this quirky margin and pass it through. 18368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This deals with the <td><div><p> case. 1837bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen setMarginAfterQuirk(true); 18388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 18398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 18408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1841a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::handleAfterSideOfBlock(int beforeSide, int afterSide, MarginInfo& marginInfo) 18428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1843bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen marginInfo.setAtAfterSideOfBlock(true); 18448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If we can't collapse with children then go ahead and add in the bottom margin. 1846bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (!marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore() 1847bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.marginAfterQuirk())) 1848a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeight(logicalHeight() + marginInfo.margin()); 18498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Now add in our bottom border/padding. 1851a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeight(logicalHeight() + afterSide); 18528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Negative margins can cause our height to shrink below our minimal height (border/padding). 18548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If this happens, ensure that the computed height is increased to the minimal height. 1855a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeight(max(logicalHeight(), beforeSide + afterSide)); 18568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Update our bottom collapsed margin info. 18588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project setCollapsedBottomMargin(marginInfo); 18598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 18608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1861a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setLogicalLeftForChild(RenderBox* child, int logicalLeft, ApplyLayoutDeltaMode applyDelta) 1862a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 18632bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isHorizontalWritingMode()) { 1864a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (applyDelta == ApplyLayoutDelta) 1865a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch view()->addLayoutDelta(IntSize(child->x() - logicalLeft, 0)); 1866a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->setX(logicalLeft); 1867a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } else { 1868a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (applyDelta == ApplyLayoutDelta) 1869a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch view()->addLayoutDelta(IntSize(0, child->y() - logicalLeft)); 1870a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->setY(logicalLeft); 1871a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 1872a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 1873a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1874a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setLogicalTopForChild(RenderBox* child, int logicalTop, ApplyLayoutDeltaMode applyDelta) 1875a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 18762bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isHorizontalWritingMode()) { 1877a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (applyDelta == ApplyLayoutDelta) 1878a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch view()->addLayoutDelta(IntSize(0, child->y() - logicalTop)); 1879a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->setY(logicalTop); 1880a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } else { 1881a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (applyDelta == ApplyLayoutDelta) 1882a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch view()->addLayoutDelta(IntSize(child->x() - logicalTop, 0)); 1883a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->setX(logicalTop); 1884a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 1885a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 1886a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1887a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatLogicalBottom) 18888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 18898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (gPercentHeightDescendantsMap) { 18908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (HashSet<RenderBox*>* descendants = gPercentHeightDescendantsMap->get(this)) { 18918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HashSet<RenderBox*>::iterator end = descendants->end(); 18928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (HashSet<RenderBox*>::iterator it = descendants->begin(); it != end; ++it) { 18938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderBox* box = *it; 18948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (box != this) { 18958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (box->normalChildNeedsLayout()) 18968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 18978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project box->setChildNeedsLayout(true, false); 18988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project box = box->containingBlock(); 18998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(box); 19008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!box) 19018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 19028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1907a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int beforeEdge = borderBefore() + paddingBefore(); 1908a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeight(); 19098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1910a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeight(beforeEdge); 19118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The margin struct caches all our current margin collapsing state. The compact struct caches state when we encounter compacts, 1913a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch MarginInfo marginInfo(this, beforeEdge, afterEdge); 19148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Fieldsets need to find their legend and position it inside the border of the object. 19164576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // The legend then gets skipped during normal layout. The same is true for ruby text. 19174576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // It doesn't get included in the normal layout process but is instead skipped. 19184576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang RenderObject* childToExclude = layoutSpecialExcludedChild(relayoutChildren); 19198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1920a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int previousFloatLogicalBottom = 0; 1921a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch maxFloatLogicalBottom = 0; 19228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian RenderBox* next = firstChildBox(); 19245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 19255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian while (next) { 19265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian RenderBox* child = next; 19275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian next = child->nextSiblingBox(); 19285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 19294576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (childToExclude == child) 19304576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang continue; // Skip this child, since it will be positioned by the specialized subclass (fieldsets and ruby runs). 19318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Make sure we layout children if they need it. 19338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into 19348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // an auto value. Add a method to determine this, so that we can avoid the relayout. 1935a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (relayoutChildren || ((child->style()->logicalHeight().isPercent() || child->style()->logicalMinHeight().isPercent() || child->style()->logicalMaxHeight().isPercent()) && !isRenderView())) 19368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project child->setChildNeedsLayout(true, false); 19378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1938a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // If relayoutChildren is set and the child has percentage padding, we also need to invalidate the child's pref widths. 1939a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (relayoutChildren && (child->style()->paddingStart().isPercent() || child->style()->paddingEnd().isPercent())) 1940bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen child->setPreferredLogicalWidthsDirty(true, false); 19418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Handle the four types of special elements first. These include positioned content, floating content, compacts and 19438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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. 19445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (handleSpecialChild(child, marginInfo)) 19458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 19468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1947231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Lay out the child. 1948a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch layoutBlockChild(child, marginInfo, previousFloatLogicalBottom, maxFloatLogicalBottom); 1949231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 1950231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1951231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Now do the handling of the bottom of the block, adding in our bottom border/padding and 1952231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // determining the correct collapsed bottom margin information. 1953a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch handleAfterSideOfBlock(beforeEdge, afterEdge, marginInfo); 1954231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 19558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1956a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, int& previousFloatLogicalBottom, int& maxFloatLogicalBottom) 1957231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 1958a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int oldPosMarginBefore = maxPositiveMarginBefore(); 1959a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int oldNegMarginBefore = maxNegativeMarginBefore(); 19608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1961a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // The child is a normal flow object. Compute the margins we will use for collapsing now. 1962bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen child->computeBlockDirectionMargins(this); 19638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1964a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // Do not allow a collapse if the margin-before-collapse style is set to SEPARATE. 1965bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (child->style()->marginBeforeCollapse() == MSEPARATE) { 1966bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen marginInfo.setAtBeforeSideOfBlock(false); 1967231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block marginInfo.clearMargin(); 1968231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 1969231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1970a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // Try to guess our correct logical top position. In most cases this guess will 1971a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // be correct. Only if we're wrong (when we compute the real logical top position) 1972231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // will we have to potentially relayout. 1973a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int logicalTopEstimate = estimateLogicalTopPosition(child, marginInfo); 1974231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1975231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Cache our old rect so that we can dirty the proper repaint rects if the child moves. 1976231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block IntRect oldRect(child->x(), child->y() , child->width(), child->height()); 1977a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int oldLogicalTop = logicalTopForChild(child); 1978a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1979635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#ifndef NDEBUG 1980231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block IntSize oldLayoutDelta = view()->layoutDelta(); 1981635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif 1982231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Go ahead and position the child as though it didn't collapse with the top. 1983a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalTopForChild(child, logicalTopEstimate, ApplyLayoutDelta); 1984231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 198568513a70bcd92384395513322f1b801e7bf9c729Steve Block RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0; 1986231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bool markDescendantsWithFloats = false; 1987a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (logicalTopEstimate != oldLogicalTop && !child->avoidsFloats() && childRenderBlock && childRenderBlock->containsFloats()) 1988231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block markDescendantsWithFloats = true; 1989231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) { 1990231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // If an element might be affected by the presence of floats, then always mark it for 1991231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // layout. 1992a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int fb = max(previousFloatLogicalBottom, lowestFloatLogicalBottom()); 1993a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (fb > logicalTopEstimate) 19948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project markDescendantsWithFloats = true; 1995231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 19968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 199768513a70bcd92384395513322f1b801e7bf9c729Steve Block if (childRenderBlock) { 1998231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (markDescendantsWithFloats) 199968513a70bcd92384395513322f1b801e7bf9c729Steve Block childRenderBlock->markAllDescendantsWithFloatsForLayout(); 2000a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!child->isWritingModeRoot()) 2001a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch previousFloatLogicalBottom = max(previousFloatLogicalBottom, oldLogicalTop + childRenderBlock->lowestFloatLogicalBottom()); 2002231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 20038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2004a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!child->needsLayout()) 2005a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->markForPaginationRelayoutIfNeeded(); 200668513a70bcd92384395513322f1b801e7bf9c729Steve Block 2007231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bool childHadLayout = child->m_everHadLayout; 2008231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bool childNeededLayout = child->needsLayout(); 2009231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (childNeededLayout) 2010231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block child->layout(); 20118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 201268513a70bcd92384395513322f1b801e7bf9c729Steve Block // Cache if we are at the top of the block right now. 2013bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock(); 201468513a70bcd92384395513322f1b801e7bf9c729Steve Block 2015231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Now determine the correct ypos based off examination of collapsing margin 2016231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // values. 2017a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int logicalTopBeforeClear = collapseMargins(child, marginInfo); 20188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2019231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Now check for clear. 2020a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int logicalTopAfterClear = clearFloatsIfNeeded(child, marginInfo, oldPosMarginBefore, oldNegMarginBefore, logicalTopBeforeClear); 20218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2022a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool paginated = view()->layoutState()->isPaginated(); 202368513a70bcd92384395513322f1b801e7bf9c729Steve Block if (paginated) { 2024a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int oldTop = logicalTopAfterClear; 202568513a70bcd92384395513322f1b801e7bf9c729Steve Block 202668513a70bcd92384395513322f1b801e7bf9c729Steve Block // If the object has a page or column break value of "before", then we should shift to the top of the next page. 2027a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch logicalTopAfterClear = applyBeforeBreak(child, logicalTopAfterClear); 202868513a70bcd92384395513322f1b801e7bf9c729Steve Block 202968513a70bcd92384395513322f1b801e7bf9c729Steve 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. 2030a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int logicalTopBeforeUnsplittableAdjustment = logicalTopAfterClear; 2031a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChild(child, logicalTopAfterClear); 203268513a70bcd92384395513322f1b801e7bf9c729Steve Block 203368513a70bcd92384395513322f1b801e7bf9c729Steve Block int paginationStrut = 0; 2034a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustment - logicalTopBeforeUnsplittableAdjustment; 203568513a70bcd92384395513322f1b801e7bf9c729Steve Block if (unsplittableAdjustmentDelta) 203668513a70bcd92384395513322f1b801e7bf9c729Steve Block paginationStrut = unsplittableAdjustmentDelta; 203768513a70bcd92384395513322f1b801e7bf9c729Steve Block else if (childRenderBlock && childRenderBlock->paginationStrut()) 203868513a70bcd92384395513322f1b801e7bf9c729Steve Block paginationStrut = childRenderBlock->paginationStrut(); 203968513a70bcd92384395513322f1b801e7bf9c729Steve Block 204068513a70bcd92384395513322f1b801e7bf9c729Steve Block if (paginationStrut) { 204168513a70bcd92384395513322f1b801e7bf9c729Steve Block // We are willing to propagate out to our parent block as long as we were at the top of the block prior 204268513a70bcd92384395513322f1b801e7bf9c729Steve Block // to collapsing our margins, and as long as we didn't clear or move as a result of other pagination. 2043a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (atBeforeSideOfBlock && oldTop == logicalTopBeforeClear && !isPositioned() && !isTableCell()) { 204468513a70bcd92384395513322f1b801e7bf9c729Steve Block // FIXME: Should really check if we're exceeding the page height before propagating the strut, but we don't 204568513a70bcd92384395513322f1b801e7bf9c729Steve Block // have all the information to do so (the strut only has the remaining amount to push). Gecko gets this wrong too 204668513a70bcd92384395513322f1b801e7bf9c729Steve Block // and pushes to the next page anyway, so not too concerned about it. 2047a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setPaginationStrut(logicalTopAfterClear + paginationStrut); 204868513a70bcd92384395513322f1b801e7bf9c729Steve Block if (childRenderBlock) 204968513a70bcd92384395513322f1b801e7bf9c729Steve Block childRenderBlock->setPaginationStrut(0); 205068513a70bcd92384395513322f1b801e7bf9c729Steve Block } else 2051a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch logicalTopAfterClear += paginationStrut; 205268513a70bcd92384395513322f1b801e7bf9c729Steve Block } 205368513a70bcd92384395513322f1b801e7bf9c729Steve Block 205468513a70bcd92384395513322f1b801e7bf9c729Steve Block // Similar to how we apply clearance. Go ahead and boost height() to be the place where we're going to position the child. 2055a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeight(logicalHeight() + (logicalTopAfterClear - oldTop)); 205668513a70bcd92384395513322f1b801e7bf9c729Steve Block } 205768513a70bcd92384395513322f1b801e7bf9c729Steve Block 2058a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalTopForChild(child, logicalTopAfterClear, ApplyLayoutDelta); 2059231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 2060a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // Now we have a final top position. See if it really does end up being different from our estimate. 2061a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (logicalTopAfterClear != logicalTopEstimate) { 2062231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (child->shrinkToAvoidFloats()) { 2063231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // The child's width depends on the line width. 2064231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // When the child shifts to clear an item, its width can 2065231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // change (because it has more available line width). 2066231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // So go ahead and mark the item as dirty. 2067231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block child->setChildNeedsLayout(true, false); 20688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 206968513a70bcd92384395513322f1b801e7bf9c729Steve Block if (childRenderBlock) { 207068513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!child->avoidsFloats() && childRenderBlock->containsFloats()) 207168513a70bcd92384395513322f1b801e7bf9c729Steve Block childRenderBlock->markAllDescendantsWithFloatsForLayout(); 2072a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!child->needsLayout()) 2073a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->markForPaginationRelayoutIfNeeded(); 207468513a70bcd92384395513322f1b801e7bf9c729Steve Block } 207568513a70bcd92384395513322f1b801e7bf9c729Steve Block 2076231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Our guess was wrong. Make the child lay itself out again. 2077231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block child->layoutIfNeeded(); 2078231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 20798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2080231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // We are no longer at the top of the block if we encounter a non-empty child. 2081231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // This has to be done after checking for clear, so that margins can be reset if a clear occurred. 2082bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (marginInfo.atBeforeSideOfBlock() && !child->isSelfCollapsingBlock()) 2083bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen marginInfo.setAtBeforeSideOfBlock(false); 20848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2085a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // Now place the child in the correct left position 2086a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch determineLogicalLeftPositionForChild(child); 20878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2088231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Update our height now that the child has been placed in the correct position. 2089a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeight(logicalHeight() + logicalHeightForChild(child)); 2090bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (child->style()->marginAfterCollapse() == MSEPARATE) { 2091a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeight(logicalHeight() + marginAfterForChild(child)); 2092231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block marginInfo.clearMargin(); 2093231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 2094231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // If the child has overhanging floats that intrude into following siblings (or possibly out 2095231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // of this block), then the parent gets notified of the floats now. 209668513a70bcd92384395513322f1b801e7bf9c729Steve Block if (childRenderBlock && childRenderBlock->containsFloats()) 2097a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch maxFloatLogicalBottom = max(maxFloatLogicalBottom, addOverhangingFloats(toRenderBlock(child), -child->logicalLeft(), -child->logicalTop(), !childNeededLayout)); 20988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2099231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block IntSize childOffset(child->x() - oldRect.x(), child->y() - oldRect.y()); 2100231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (childOffset.width() || childOffset.height()) { 2101231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block view()->addLayoutDelta(childOffset); 21028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2103231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // If the child moved, we have to repaint it as well as any floating/positioned 2104231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // descendants. An exception is if we need a layout. In this case, we know we're going to 2105231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // repaint ourselves (and the child) anyway. 2106231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (childHadLayout && !selfNeedsLayout() && child->checkForRepaintDuringLayout()) 2107231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block child->repaintDuringLayoutIfMoved(oldRect); 2108231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 21098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2110231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!childHadLayout && child->checkForRepaintDuringLayout()) { 2111231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block child->repaint(); 2112231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block child->repaintOverhangingFloats(true); 21138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 21148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 211568513a70bcd92384395513322f1b801e7bf9c729Steve Block if (paginated) { 211668513a70bcd92384395513322f1b801e7bf9c729Steve Block // Check for an after page/column break. 21172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int newHeight = applyAfterBreak(child, logicalHeight(), marginInfo); 211868513a70bcd92384395513322f1b801e7bf9c729Steve Block if (newHeight != height()) 2119bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen setLogicalHeight(newHeight); 212068513a70bcd92384395513322f1b801e7bf9c729Steve Block } 212168513a70bcd92384395513322f1b801e7bf9c729Steve Block 2122231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(oldLayoutDelta == view()->layoutDelta()); 21238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 21248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21252bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid RenderBlock::simplifiedNormalFlowLayout() 21268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 21272bde8e466a4451c7319e3a072d118917957d6554Steve Block if (childrenInline()) { 21282bde8e466a4451c7319e3a072d118917957d6554Steve Block ListHashSet<RootInlineBox*> lineBoxes; 21292bde8e466a4451c7319e3a072d118917957d6554Steve Block bool endOfInline = false; 21302bde8e466a4451c7319e3a072d118917957d6554Steve Block RenderObject* o = bidiFirst(this, 0, false); 21312bde8e466a4451c7319e3a072d118917957d6554Steve Block while (o) { 21322bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!o->isPositioned() && (o->isReplaced() || o->isFloating())) { 21332bde8e466a4451c7319e3a072d118917957d6554Steve Block o->layoutIfNeeded(); 21342bde8e466a4451c7319e3a072d118917957d6554Steve Block if (toRenderBox(o)->inlineBoxWrapper()) { 21352bde8e466a4451c7319e3a072d118917957d6554Steve Block RootInlineBox* box = toRenderBox(o)->inlineBoxWrapper()->root(); 21362bde8e466a4451c7319e3a072d118917957d6554Steve Block lineBoxes.add(box); 21372bde8e466a4451c7319e3a072d118917957d6554Steve Block } 21382bde8e466a4451c7319e3a072d118917957d6554Steve Block } else if (o->isText() || (o->isRenderInline() && !endOfInline)) 21392bde8e466a4451c7319e3a072d118917957d6554Steve Block o->setNeedsLayout(false); 21402bde8e466a4451c7319e3a072d118917957d6554Steve Block o = bidiNext(this, o, 0, false, &endOfInline); 21412bde8e466a4451c7319e3a072d118917957d6554Steve Block } 21422bde8e466a4451c7319e3a072d118917957d6554Steve Block 21432bde8e466a4451c7319e3a072d118917957d6554Steve Block // FIXME: Glyph overflow will get lost in this case, but not really a big deal. 21442bde8e466a4451c7319e3a072d118917957d6554Steve Block GlyphOverflowAndFallbackFontsMap textBoxDataMap; 21452bde8e466a4451c7319e3a072d118917957d6554Steve Block for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it != lineBoxes.end(); ++it) { 21462bde8e466a4451c7319e3a072d118917957d6554Steve Block RootInlineBox* box = *it; 21472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap); 21482bde8e466a4451c7319e3a072d118917957d6554Steve Block } 21492bde8e466a4451c7319e3a072d118917957d6554Steve Block } else { 21502bde8e466a4451c7319e3a072d118917957d6554Steve Block for (RenderBox* box = firstChildBox(); box; box = box->nextSiblingBox()) { 21512bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!box->isPositioned()) 21522bde8e466a4451c7319e3a072d118917957d6554Steve Block box->layoutIfNeeded(); 21532bde8e466a4451c7319e3a072d118917957d6554Steve Block } 21542bde8e466a4451c7319e3a072d118917957d6554Steve Block } 21552bde8e466a4451c7319e3a072d118917957d6554Steve Block} 21562bde8e466a4451c7319e3a072d118917957d6554Steve Block 21572bde8e466a4451c7319e3a072d118917957d6554Steve Blockbool RenderBlock::simplifiedLayout() 21582bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 21592bde8e466a4451c7319e3a072d118917957d6554Steve Block if ((!posChildNeedsLayout() && !needsSimplifiedNormalFlowLayout()) || normalChildNeedsLayout() || selfNeedsLayout()) 21608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 21618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21626b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode()); 21632bde8e466a4451c7319e3a072d118917957d6554Steve Block 21642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (needsPositionedMovementLayout() && !tryLayoutDoingPositionedMovementOnly()) 21652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 21668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21672bde8e466a4451c7319e3a072d118917957d6554Steve Block // Lay out positioned descendants or objects that just need to recompute overflow. 21682bde8e466a4451c7319e3a072d118917957d6554Steve Block if (needsSimplifiedNormalFlowLayout()) 21692bde8e466a4451c7319e3a072d118917957d6554Steve Block simplifiedNormalFlowLayout(); 21702bde8e466a4451c7319e3a072d118917957d6554Steve Block 21712bde8e466a4451c7319e3a072d118917957d6554Steve Block // Lay out our positioned objects if our positioned child bit is set. 21722bde8e466a4451c7319e3a072d118917957d6554Steve Block if (posChildNeedsLayout()) 21732bde8e466a4451c7319e3a072d118917957d6554Steve Block layoutPositionedObjects(false); 21748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2175f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // Recompute our overflow information. 2176f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // FIXME: We could do better here by computing a temporary overflow object from layoutPositionedObjects and only 2177f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // updating our overflow if we either used to have overflow or if the new temporary object has overflow. 2178f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // For now just always recompute overflow. This is no worse performance-wise than the old code that called rightmostPosition and 2179f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // lowestPosition on every relayout so it's not a regression. 2180f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_overflow.clear(); 2181f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch computeOverflow(clientLogicalBottom(), true); 2182f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 2183635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project statePusher.pop(); 2184f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 2185f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch updateLayerTransform(); 21868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch updateScrollInfoAfterLayout(); 21888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project setNeedsLayout(false); 21908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 21918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 21928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::layoutPositionedObjects(bool relayoutChildren) 21948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2195f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!m_positionedObjects) 2196f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return; 2197f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 2198f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (hasColumns()) 2199f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch view()->layoutState()->clearPaginationInformation(); // Positioned objects are not part of the column flow, so they don't paginate with the columns. 220068513a70bcd92384395513322f1b801e7bf9c729Steve Block 2201f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch RenderBox* r; 2202f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch Iterator end = m_positionedObjects->end(); 2203f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch for (Iterator it = m_positionedObjects->begin(); it != end; ++it) { 2204f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch r = *it; 2205f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the 2206f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // non-positioned block. Rather than trying to detect all of these movement cases, we just always lay out positioned 2207f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // objects that are positioned implicitly like this. Such objects are rare, and so in typical DHTML menu usage (where everything is 2208f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // positioned explicitly) this should not incur a performance penalty. 22092bde8e466a4451c7319e3a072d118917957d6554Steve Block if (relayoutChildren || (r->style()->hasStaticBlockPosition(isHorizontalWritingMode()) && r->parent() != this && r->parent()->isBlockFlow())) 2210f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch r->setChildNeedsLayout(true, false); 22118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2212f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths. 2213f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (relayoutChildren && (r->style()->paddingStart().isPercent() || r->style()->paddingEnd().isPercent())) 2214f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch r->setPreferredLogicalWidthsDirty(true, false); 221568513a70bcd92384395513322f1b801e7bf9c729Steve Block 2216f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!r->needsLayout()) 2217f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch r->markForPaginationRelayoutIfNeeded(); 2218f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 2219f05b935882198ccf7d81675736e3aeb089c5113aBen 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 2220f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // and we hit the available width constraint, the layoutIfNeeded() will catch it and do a full layout. 22212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (r->needsPositionedMovementLayoutOnly() && r->tryLayoutDoingPositionedMovementOnly()) 22222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch r->setNeedsLayout(false); 2223f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch r->layoutIfNeeded(); 22248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2225f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 2226f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (hasColumns()) 2227f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch view()->layoutState()->m_columnInfo = columnInfo(); // FIXME: Kind of gross. We just put this back into the layout state so that pop() will work. 22288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 22298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::markPositionedObjectsForLayout() 22318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 22328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_positionedObjects) { 2233635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderBox* r; 22348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Iterator end = m_positionedObjects->end(); 22358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (Iterator it = m_positionedObjects->begin(); it != end; ++it) { 22368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project r = *it; 22378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project r->setChildNeedsLayout(true); 22388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 22398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 22408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 22418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2242a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::markForPaginationRelayoutIfNeeded() 2243a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 2244a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!needsLayout()); 2245a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (needsLayout()) 2246a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return; 2247a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 22482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(logicalTop()) != pageLogicalOffset())) 2249a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setChildNeedsLayout(true, false); 2250a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 2251a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 22528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::repaintOverhangingFloats(bool paintAllDescendants) 22538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 22548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Repaint any overhanging floats (if we know we're the one to paint them). 225554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block // Otherwise, bail out. 225654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block if (!hasOverhangingFloats()) 225754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block return; 22588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 225954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block // FIXME: Avoid disabling LayoutState. At the very least, don't disable it for floats originating 226054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block // in this block. Better yet would be to push extra state for the containers of other floats. 226154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block view()->disableLayoutState(); 226254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 226354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block FloatingObjectSetIterator end = floatingObjectSet.end(); 226454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) { 226554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block FloatingObject* r = *it; 226654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block // Only repaint the object if it is overhanging, is not in its own layer, and 226754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block // is our responsibility to paint (m_shouldPaint is set). When paintAllDescendants is true, the latter 226854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block // condition is replaced with being a descendant of us. 226954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block if (logicalBottomForFloat(r) > logicalHeight() && ((paintAllDescendants && r->m_renderer->isDescendantOf(this)) || r->m_shouldPaint) && !r->m_renderer->hasSelfPaintingLayer()) { 227054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block r->m_renderer->repaint(); 227154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block r->m_renderer->repaintOverhangingFloats(); 22728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 22738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 227454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block view()->enableLayoutState(); 22758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 22768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 22778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paint(PaintInfo& paintInfo, int tx, int ty) 22788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2279635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project tx += x(); 2280635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ty += y(); 22818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PaintPhase phase = paintInfo.phase; 22838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check if we need to do anything at all. 22858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView 22868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // paints the root's background. 2287635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!isRoot()) { 2288f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch IntRect overflowBox = visualOverflowRect(); 22892bde8e466a4451c7319e3a072d118917957d6554Steve Block flipForWritingMode(overflowBox); 22908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project overflowBox.inflate(maximalOutlineSize(paintInfo.phase)); 22918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project overflowBox.move(tx, ty); 22928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!overflowBox.intersects(paintInfo.rect)) 22938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 22948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 22958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian bool pushedClip = pushContentsClip(paintInfo, tx, ty); 22978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian paintObject(paintInfo, tx, ty); 22988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (pushedClip) 22998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian popContentsClip(paintInfo, phase, tx, ty); 23008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with 23028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // z-index. We paint after we painted the background/border, so that the scrollbars will 23038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // sit above the background/border. 2304ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.shouldPaintWithinRoot(this)) 23058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian layer()->paintOverflowControls(paintInfo.context, tx, ty, paintInfo.rect); 23068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 23078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::paintColumnRules(PaintInfo& paintInfo, int tx, int ty) 23098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 2310dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block const Color& ruleColor = style()->visitedDependentColor(CSSPropertyWebkitColumnRuleColor); 23118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian bool ruleTransparent = style()->columnRuleIsTransparent(); 23128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian EBorderStyle ruleStyle = style()->columnRuleStyle(); 23138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int ruleWidth = style()->columnRuleWidth(); 23148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int colGap = columnGap(); 23158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent && ruleWidth <= colGap; 23168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!renderRule) 23178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return; 23188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 23198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // We need to do multiple passes, breaking up our child painting into strips. 23205abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick ColumnInfo* colInfo = columnInfo(); 232168513a70bcd92384395513322f1b801e7bf9c729Steve Block unsigned colCount = columnCount(colInfo); 23222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int currLogicalLeftOffset = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth(); 23232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int ruleAdd = logicalLeftOffsetForContent(); 23242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int ruleLogicalLeft = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth(); 23258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian for (unsigned i = 0; i < colCount; i++) { 232668513a70bcd92384395513322f1b801e7bf9c729Steve Block IntRect colRect = columnRectAt(colInfo, i); 23278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 23282bde8e466a4451c7319e3a072d118917957d6554Steve Block int inlineDirectionSize = isHorizontalWritingMode() ? colRect.width() : colRect.height(); 23292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 23308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Move to the next position. 2331a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (style()->isLeftToRightDirection()) { 23322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ruleLogicalLeft += inlineDirectionSize + colGap / 2; 23332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block currLogicalLeftOffset += inlineDirectionSize + colGap; 23348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } else { 23352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ruleLogicalLeft -= (inlineDirectionSize + colGap / 2); 23362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block currLogicalLeftOffset -= (inlineDirectionSize + colGap); 23378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 23388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 23398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Now paint the column rule. 23408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (i < colCount - 1) { 23412bde8e466a4451c7319e3a072d118917957d6554Steve Block int ruleLeft = isHorizontalWritingMode() ? tx + ruleLogicalLeft - ruleWidth / 2 + ruleAdd : tx + borderBefore() + paddingBefore(); 23422bde8e466a4451c7319e3a072d118917957d6554Steve Block int ruleRight = isHorizontalWritingMode() ? ruleLeft + ruleWidth : ruleLeft + contentWidth(); 23432bde8e466a4451c7319e3a072d118917957d6554Steve Block int ruleTop = isHorizontalWritingMode() ? ty + borderTop() + paddingTop() : ty + ruleLogicalLeft - ruleWidth / 2 + ruleAdd; 23442bde8e466a4451c7319e3a072d118917957d6554Steve Block int ruleBottom = isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleWidth; 23452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block drawLineForBoxSide(paintInfo.context, ruleLeft, ruleTop, ruleRight, ruleBottom, 2346a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch style()->isLeftToRightDirection() ? BSLeft : BSRight, ruleColor, ruleStyle, 0, 0); 23478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 23488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 23492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ruleLogicalLeft = currLogicalLeftOffset; 23508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 23518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 23528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::paintColumnContents(PaintInfo& paintInfo, int tx, int ty, bool paintingFloats) 23548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 23558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We need to do multiple passes, breaking up our child painting into strips. 23568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project GraphicsContext* context = paintInfo.context; 23575abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick ColumnInfo* colInfo = columnInfo(); 235868513a70bcd92384395513322f1b801e7bf9c729Steve Block unsigned colCount = columnCount(colInfo); 23596c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (!colCount) 23606c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen return; 23612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int currLogicalTopOffset = 0; 23628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (unsigned i = 0; i < colCount; i++) { 23638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // For each rect, we clip to the rect, and then we adjust our coords. 236468513a70bcd92384395513322f1b801e7bf9c729Steve Block IntRect colRect = columnRectAt(colInfo, i); 23652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block flipForWritingMode(colRect); 23662bde8e466a4451c7319e3a072d118917957d6554Steve Block int logicalLeftOffset = (isHorizontalWritingMode() ? colRect.x() : colRect.y()) - logicalLeftOffsetForContent(); 23672bde8e466a4451c7319e3a072d118917957d6554Steve Block IntSize offset = isHorizontalWritingMode() ? IntSize(logicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, logicalLeftOffset); 23688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project colRect.move(tx, ty); 23698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PaintInfo info(paintInfo); 23708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project info.rect.intersect(colRect); 23718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2372e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (!info.rect.isEmpty()) { 2373e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block context->save(); 2374e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 2375e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block // Each strip pushes a clip, since column boxes are specified as being 2376e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block // like overflow:hidden. 2377e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block context->clip(colRect); 23782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2379e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block // Adjust our x and y when painting. 23802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int finalX = tx + offset.width(); 23812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int finalY = ty + offset.height(); 2382e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (paintingFloats) 2383e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block paintFloats(info, finalX, finalY, paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip); 2384e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block else 2385e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block paintContents(info, finalX, finalY); 23868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2387e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block context->restore(); 2388e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block } 23892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 23902bde8e466a4451c7319e3a072d118917957d6554Steve Block int blockDelta = (isHorizontalWritingMode() ? colRect.height() : colRect.width()); 23912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (style()->isFlippedBlocksWritingMode()) 23922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block currLogicalTopOffset += blockDelta; 23938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian else 23942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block currLogicalTopOffset -= blockDelta; 23958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 23968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 23978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintContents(PaintInfo& paintInfo, int tx, int ty) 23998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 24008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Avoid painting descendants of the root element when stylesheets haven't loaded. This eliminates FOUC. 24018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document 24028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // will do a full repaint(). 24032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (document()->didLayoutWithPendingStylesheets() && !isRenderView()) 24048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 24058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (childrenInline()) 24078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_lineBoxes.paint(this, paintInfo, tx, ty); 24088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 24098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project paintChildren(paintInfo, tx, ty); 24108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 24118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty) 24138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 24148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase; 24158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase; 24168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We don't paint our own background, but we do let the kids paint their backgrounds. 24188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PaintInfo info(paintInfo); 24198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project info.phase = newPhase; 2420ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block info.updatePaintingRootForChildren(this); 24215ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 242268513a70bcd92384395513322f1b801e7bf9c729Steve Block // FIXME: Paint-time pagination is obsolete and is now only used by embedded WebViews inside AppKit 242368513a70bcd92384395513322f1b801e7bf9c729Steve Block // NSViews. Do not add any more code for this. 24245ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen RenderView* renderView = view(); 242568513a70bcd92384395513322f1b801e7bf9c729Steve Block bool usePrintRect = !renderView->printRect().isEmpty(); 24265ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 2427635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) { 24288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check for page-break-before: always, and if it's set, break and bail. 242968513a70bcd92384395513322f1b801e7bf9c729Steve Block bool checkBeforeAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakBefore() == PBALWAYS); 2430545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (checkBeforeAlways 2431dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block && (ty + child->y()) > paintInfo.rect.y() 24322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block && (ty + child->y()) < paintInfo.rect.maxY()) { 2433635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project view()->setBestTruncatedAt(ty + child->y(), this, true); 24348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 24358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 24368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24375ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (!child->isFloating() && child->isReplaced() && usePrintRect && child->height() <= renderView->printRect().height()) { 24385ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // Paginate block-level replaced elements. 24392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (ty + child->y() + child->height() > renderView->printRect().maxY()) { 24405ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (ty + child->y() < renderView->truncatedAt()) 24415ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen renderView->setBestTruncatedAt(ty + child->y(), child); 24425ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // If we were able to truncate, don't paint. 24435ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (ty + child->y() >= renderView->truncatedAt()) 24445ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen break; 24455ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen } 24465ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen } 24475ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 244828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu IntPoint childPoint = flipForWritingMode(child, IntPoint(tx, ty), ParentToChildFlippingAdjustment); 24498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!child->hasSelfPaintingLayer() && !child->isFloating()) 2450e14391e94c850b8bd03680c23b38978db68687a8John Reck child->paint(info, childPoint.x(), childPoint.y()); 24518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check for page-break-after: always, and if it's set, break and bail. 245368513a70bcd92384395513322f1b801e7bf9c729Steve Block bool checkAfterAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakAfter() == PBALWAYS); 2454545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (checkAfterAlways 2455dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block && (ty + child->y() + child->height()) > paintInfo.rect.y() 24562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block && (ty + child->y() + child->height()) < paintInfo.rect.maxY()) { 2457bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen view()->setBestTruncatedAt(ty + child->y() + child->height() + max(0, child->collapsedMarginAfter()), this, true); 24588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 24598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 24608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 24618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 24628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2463635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::paintCaret(PaintInfo& paintInfo, int tx, int ty, CaretType type) 24648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 246568513a70bcd92384395513322f1b801e7bf9c729Steve Block SelectionController* selection = type == CursorCaret ? frame()->selection() : frame()->page()->dragCaretController(); 2466635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 24675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Paint the caret if the SelectionController says so or if caret browsing is enabled 2468545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch bool caretBrowsing = frame()->settings() && frame()->settings()->caretBrowsingEnabled(); 2469635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderObject* caretPainter = selection->caretRenderer(); 24705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (caretPainter == this && (selection->isContentEditable() || caretBrowsing)) { 2471635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Convert the painting offset into the local coordinate system of this renderer, 2472635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // to match the localCaretRect computed by the SelectionController 2473635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project offsetForContents(tx, ty); 2474635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 24758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (type == CursorCaret) 2476545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch frame()->selection()->paintCaret(paintInfo.context, tx, ty, paintInfo.rect); 24778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 247868513a70bcd92384395513322f1b801e7bf9c729Steve Block frame()->selection()->paintDragCaret(paintInfo.context, tx, ty, paintInfo.rect); 24798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 24808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 24818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintObject(PaintInfo& paintInfo, int tx, int ty) 24838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 24848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PaintPhase paintPhase = paintInfo.phase; 24858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // 1. paint background, borders etc 24878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && style()->visibility() == VISIBLE) { 24888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (hasBoxDecorations()) 24898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian paintBoxDecorations(paintInfo, tx, ty); 24908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (hasColumns()) 24918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian paintColumnRules(paintInfo, tx, ty); 24928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 24938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (paintPhase == PaintPhaseMask && style()->visibility() == VISIBLE) { 24958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project paintMask(paintInfo, tx, ty); 24968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 24978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 24988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We're done. We don't bother painting any children. 25008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (paintPhase == PaintPhaseBlockBackground) 25018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 25028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2503dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div). 25048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int scrolledX = tx; 25058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int scrolledY = ty; 2506dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (hasOverflowClip()) { 2507dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block IntSize offset = layer()->scrolledContentOffset(); 2508dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block scrolledX -= offset.width(); 2509dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block scrolledY -= offset.height(); 2510dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 25118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 25128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // 2. paint contents 25138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (paintPhase != PaintPhaseSelfOutline) { 25148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (hasColumns()) 25158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian paintColumnContents(paintInfo, scrolledX, scrolledY); 25168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 25178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project paintContents(paintInfo, scrolledX, scrolledY); 25188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 25198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 25208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // 3. paint selection 25218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: Make this work with multi column layouts. For now don't fill gaps. 25228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool isPrinting = document()->printing(); 25238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!isPrinting && !hasColumns()) 25248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project paintSelection(paintInfo, scrolledX, scrolledY); // Fill in gaps in selection on lines and between blocks. 25258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 25268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // 4. paint floats. 2527635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip) { 25288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (hasColumns()) 25298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian paintColumnContents(paintInfo, scrolledX, scrolledY, true); 25308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 25318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project paintFloats(paintInfo, scrolledX, scrolledY, paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip); 25328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 25338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 25348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // 5. paint outline. 2535635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE) 2536dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block paintOutline(paintInfo.context, tx, ty, width(), height()); 25378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 25388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // 6. paint continuation outlines. 2539635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) { 2540e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block RenderInline* inlineCont = inlineElementContinuation(); 2541e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (inlineCont && inlineCont->hasOutline() && inlineCont->style()->visibility() == VISIBLE) { 2542e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block RenderInline* inlineRenderer = toRenderInline(inlineCont->node()->renderer()); 2543e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke RenderBlock* cb = containingBlock(); 2544e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 2545e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke bool inlineEnclosedInSelfPaintingLayer = false; 2546e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke for (RenderBoxModelObject* box = inlineRenderer; box != cb; box = box->parent()->enclosingBoxModelObject()) { 2547e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (box->hasSelfPaintingLayer()) { 2548e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke inlineEnclosedInSelfPaintingLayer = true; 2549e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke break; 2550e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke } 2551e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke } 2552e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 2553e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (!inlineEnclosedInSelfPaintingLayer) 2554e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke cb->addContinuationWithOutline(inlineRenderer); 25558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian else if (!inlineRenderer->firstLineBox()) 25568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian inlineRenderer->paintOutline(paintInfo.context, tx - x() + inlineRenderer->containingBlock()->x(), 25578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ty - y() + inlineRenderer->containingBlock()->y()); 25588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 25598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project paintContinuationOutlines(paintInfo, tx, ty); 25608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 25618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 25628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // 7. paint caret. 25638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground, 25648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // then paint the caret. 2565635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (paintPhase == PaintPhaseForeground) { 2566635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project paintCaret(paintInfo, scrolledX, scrolledY, CursorCaret); 2567635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project paintCaret(paintInfo, scrolledX, scrolledY, DragCaret); 25688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 25698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 25708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 25712fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockIntPoint RenderBlock::flipFloatForWritingMode(const FloatingObject* child, const IntPoint& point) const 25722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 25732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!style()->isFlippedBlocksWritingMode()) 25742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return point; 25752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 25762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // This is similar to the ParentToChildFlippingAdjustment in RenderBox::flipForWritingMode. We have to subtract out our left/top offsets twice, since 25772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // it's going to get added back in. We hide this complication here so that the calling code looks normal for the unflipped 25782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // case. 25792bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isHorizontalWritingMode()) 25802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return IntPoint(point.x(), point.y() + height() - child->renderer()->height() - 2 * yPositionForFloatIncludingMargin(child)); 25812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return IntPoint(point.x() + width() - child->width() - 2 * xPositionForFloatIncludingMargin(child), point.y()); 25822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 25832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 25848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintFloats(PaintInfo& paintInfo, int tx, int ty, bool preservePhase) 25858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 25868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_floatingObjects) 25878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 25888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 258981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 259081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator end = floatingObjectSet.end(); 259181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) { 259281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* r = *it; 25938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Only paint the object if our m_shouldPaint flag is set. 25948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) { 25958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PaintInfo currentPaintInfo(paintInfo); 25968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground; 25972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block IntPoint childPoint = flipFloatForWritingMode(r, IntPoint(tx + xPositionForFloatIncludingMargin(r) - r->m_renderer->x(), ty + yPositionForFloatIncludingMargin(r) - r->m_renderer->y())); 2598e14391e94c850b8bd03680c23b38978db68687a8John Reck r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y()); 25998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!preservePhase) { 26008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project currentPaintInfo.phase = PaintPhaseChildBlockBackgrounds; 2601e14391e94c850b8bd03680c23b38978db68687a8John Reck r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y()); 26028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project currentPaintInfo.phase = PaintPhaseFloat; 2603e14391e94c850b8bd03680c23b38978db68687a8John Reck r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y()); 26048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project currentPaintInfo.phase = PaintPhaseForeground; 2605e14391e94c850b8bd03680c23b38978db68687a8John Reck r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y()); 26068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project currentPaintInfo.phase = PaintPhaseOutline; 2607e14391e94c850b8bd03680c23b38978db68687a8John Reck r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y()); 26088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 26098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 26108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 26118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 26128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 26138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintEllipsisBoxes(PaintInfo& paintInfo, int tx, int ty) 26148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2615ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block if (!paintInfo.shouldPaintWithinRoot(this) || !firstLineBox()) 26168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 26178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 26188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->visibility() == VISIBLE && paintInfo.phase == PaintPhaseForeground) { 26198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We can check the first box and last box and avoid painting if we don't 26208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // intersect. 26218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int yPos = ty + firstLineBox()->y(); 2622bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int h = lastLineBox()->y() + lastLineBox()->logicalHeight() - firstLineBox()->y(); 26232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (yPos >= paintInfo.rect.maxY() || yPos + h <= paintInfo.rect.y()) 26248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 26258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 26268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // See if our boxes intersect with the dirty rect. If so, then we paint 26278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // them. Note that boxes can easily overlap, so we can't make any assumptions 26288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // based off positions of our first line box or our last line box. 26298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) { 26308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian yPos = ty + curr->y(); 2631bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen h = curr->logicalHeight(); 26322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (curr->ellipsisBox() && yPos < paintInfo.rect.maxY() && yPos + h > paintInfo.rect.y()) 26332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch curr->paintEllipsisBox(paintInfo, tx, ty, curr->lineTop(), curr->lineBottom()); 26348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 26358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 26368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 26378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2638e78cbe89e6f337f2f1fe40315be88f742b547151Steve BlockRenderInline* RenderBlock::inlineElementContinuation() const 2639e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block{ 2640cad810f21b803229eb11403f9209855525a25d57Steve Block RenderBoxModelObject* continuation = this->continuation(); 2641cad810f21b803229eb11403f9209855525a25d57Steve Block return continuation && continuation->isInline() ? toRenderInline(continuation) : 0; 2642e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block} 2643e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 2644e78cbe89e6f337f2f1fe40315be88f742b547151Steve BlockRenderBlock* RenderBlock::blockElementContinuation() const 2645e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block{ 2646cad810f21b803229eb11403f9209855525a25d57Steve Block RenderBoxModelObject* currentContinuation = continuation(); 2647cad810f21b803229eb11403f9209855525a25d57Steve Block if (!currentContinuation || currentContinuation->isInline()) 2648e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block return 0; 2649cad810f21b803229eb11403f9209855525a25d57Steve Block RenderBlock* nextContinuation = toRenderBlock(currentContinuation); 2650e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (nextContinuation->isAnonymousBlock()) 2651e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block return nextContinuation->blockElementContinuation(); 2652545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return nextContinuation; 2653e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block} 2654e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 2655635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic ContinuationOutlineTableMap* continuationOutlineTable() 26568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2657635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ()); 26588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return &table; 26598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 26608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 26618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::addContinuationWithOutline(RenderInline* flow) 26628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 26638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We can't make this work if the inline is in a layer. We'll just rely on the broken 26648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // way of painting. 2665e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(!flow->layer() && !flow->isInlineElementContinuation()); 26668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2667635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ContinuationOutlineTableMap* table = continuationOutlineTable(); 26688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ListHashSet<RenderInline*>* continuations = table->get(this); 26698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!continuations) { 26708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian continuations = new ListHashSet<RenderInline*>; 26718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project table->set(this, continuations); 26728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 26738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 26748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continuations->add(flow); 26758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 26768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 267781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochbool RenderBlock::paintsContinuationOutline(RenderInline* flow) 267881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 267981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ContinuationOutlineTableMap* table = continuationOutlineTable(); 268081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (table->isEmpty()) 268181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return false; 268281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 268381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ListHashSet<RenderInline*>* continuations = table->get(this); 268481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (!continuations) 268581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return false; 268681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 268781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return continuations->contains(flow); 268881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 268981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 26908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintContinuationOutlines(PaintInfo& info, int tx, int ty) 26918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2692635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ContinuationOutlineTableMap* table = continuationOutlineTable(); 26938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (table->isEmpty()) 26948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 26958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 26968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ListHashSet<RenderInline*>* continuations = table->get(this); 26978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!continuations) 26988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 26998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 27008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Paint each continuation outline. 27018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ListHashSet<RenderInline*>::iterator end = continuations->end(); 27028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian for (ListHashSet<RenderInline*>::iterator it = continuations->begin(); it != end; ++it) { 27038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Need to add in the coordinates of the intervening blocks. 27048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderInline* flow = *it; 27058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderBlock* block = flow->containingBlock(); 27068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for ( ; block && block != this; block = block->containingBlock()) { 2707635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project tx += block->x(); 2708635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ty += block->y(); 27098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 27108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(block); 27118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project flow->paintOutline(info.context, tx, ty); 27128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 27138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 27148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Delete 27158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete continuations; 27168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project table->remove(this); 27178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 27188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 27198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::shouldPaintSelectionGaps() const 27208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 27218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot(); 27228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 27238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 27248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::isSelectionRoot() const 27258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 27268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!node()) 27278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 27288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 27298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: Eventually tables should have to learn how to fill gaps between cells, at least in simple non-spanning cases. 27308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isTable()) 27318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 27328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 27338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isBody() || isRoot() || hasOverflowClip() || isRelPositioned() || 27348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project isFloatingOrPositioned() || isTableCell() || isInlineBlockOrInlineTable() || hasTransform() || 273528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu hasReflection() || hasMask() || isWritingModeRoot()) 27368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 27378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 27388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (view() && view()->selectionStart()) { 27398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Node* startElement = view()->selectionStart()->node(); 27408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (startElement && startElement->rootEditableElement() == node()) 27418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 27428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 27438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 27448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 27458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 27468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2747643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockGapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer) 27488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 27498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!needsLayout()); 27508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 27518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!shouldPaintSelectionGaps()) 27528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return GapRects(); 27538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2754643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // FIXME: this is broken with transforms 2755643ca7872b450ea4efacab6188849e5aac2ba161Steve Block TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint()); 2756643ca7872b450ea4efacab6188849e5aac2ba161Steve Block mapLocalToContainer(repaintContainer, false, false, transformState); 2757dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block IntPoint offsetFromRepaintContainer = roundedIntPoint(transformState.mappedPoint()); 2758643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 27598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (hasOverflowClip()) 2760dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block offsetFromRepaintContainer -= layer()->scrolledContentOffset(); 27618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2762635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project int lastTop = 0; 276328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int lastLeft = logicalLeftSelectionOffset(this, lastTop); 276428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int lastRight = logicalRightSelectionOffset(this, lastTop); 27658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 276628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu return selectionGaps(this, offsetFromRepaintContainer, IntSize(), lastTop, lastLeft, lastRight); 27678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 27688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 27698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty) 27708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 27718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (shouldPaintSelectionGaps() && paintInfo.phase == PaintPhaseForeground) { 2772635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project int lastTop = 0; 277328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int lastLeft = logicalLeftSelectionOffset(this, lastTop); 277428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int lastRight = logicalRightSelectionOffset(this, lastTop); 27758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project paintInfo.context->save(); 277628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu IntRect gapRectsBounds = selectionGaps(this, IntPoint(tx, ty), IntSize(), lastTop, lastLeft, lastRight, &paintInfo); 2777643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!gapRectsBounds.isEmpty()) { 2778643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (RenderLayer* layer = enclosingLayer()) { 2779d0825bca7fe65beaee391d30da42e937db621564Steve Block gapRectsBounds.move(IntSize(-tx, -ty)); 2780d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!hasLayer()) { 27816b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner IntRect localBounds(gapRectsBounds); 27826b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner flipForWritingMode(localBounds); 27836b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner gapRectsBounds = localToContainerQuad(FloatRect(localBounds), layer->renderer()).enclosingBoundingBox(); 2784692e5dbf12901edacf14812a6fae25462920af42Steve Block gapRectsBounds.move(layer->scrolledContentOffset()); 2785d0825bca7fe65beaee391d30da42e937db621564Steve Block } 2786643ca7872b450ea4efacab6188849e5aac2ba161Steve Block layer->addBlockSelectionGapsBounds(gapRectsBounds); 2787643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 2788643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 27898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project paintInfo.context->restore(); 27908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 27918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 27928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 279328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic void clipOutPositionedObjects(const PaintInfo* paintInfo, const IntPoint& offset, RenderBlock::PositionedObjectsListHashSet* positionedObjects) 27948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 27958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!positionedObjects) 27968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 27978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2798e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block RenderBlock::PositionedObjectsListHashSet::const_iterator end = positionedObjects->end(); 2799e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) { 2800635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderBox* r = *it; 280128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r->y(), r->width(), r->height())); 28028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 28038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 28048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 280528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic int blockDirectionOffset(RenderBlock* rootBlock, const IntSize& offsetFromRootBlock) 280628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{ 28072bde8e466a4451c7319e3a072d118917957d6554Steve Block return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.height() : offsetFromRootBlock.width(); 280828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu} 280928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu 281028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic int inlineDirectionOffset(RenderBlock* rootBlock, const IntSize& offsetFromRootBlock) 281128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{ 28122bde8e466a4451c7319e3a072d118917957d6554Steve Block return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.width() : offsetFromRootBlock.height(); 281328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu} 281428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu 281528040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuIntRect RenderBlock::logicalRectToPhysicalRect(const IntPoint& rootBlockPhysicalPosition, const IntRect& logicalRect) 281628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{ 281728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu IntRect result; 28182bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isHorizontalWritingMode()) 281928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu result = logicalRect; 282028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu else 282128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu result = IntRect(logicalRect.y(), logicalRect.x(), logicalRect.height(), logicalRect.width()); 282228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu flipForWritingMode(result); 282328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu result.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y()); 282428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu return result; 282528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu} 282628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu 282728040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuGapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock, 282828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo) 28298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 28308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore. 28318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Clip out floating and positioned objects when painting selection gaps. 28328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (paintInfo) { 28338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Note that we don't clip out overflow for positioned objects. We just stick to the border box. 283428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu IntRect flippedBlockRect = IntRect(offsetFromRootBlock.width(), offsetFromRootBlock.height(), width(), height()); 283528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu rootBlock->flipForWritingMode(flippedBlockRect); 283628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu flippedBlockRect.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y()); 283781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), m_positionedObjects.get()); 28388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isBody() || isRoot()) // The <body> must make sure to examine its containingBlock's positioned objects. 28398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock()) 284081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch clipOutPositionedObjects(paintInfo, IntPoint(cb->x(), cb->y()), cb->m_positionedObjects.get()); // FIXME: Not right for flipped writing modes. 28418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_floatingObjects) { 284281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 284381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator end = floatingObjectSet.end(); 284481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) { 284581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* r = *it; 28462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block IntRect floatBox = IntRect(offsetFromRootBlock.width() + xPositionForFloatIncludingMargin(r), 28472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block offsetFromRootBlock.height() + yPositionForFloatIncludingMargin(r), 284828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu r->m_renderer->width(), r->m_renderer->height()); 284928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu rootBlock->flipForWritingMode(floatBox); 285028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu floatBox.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y()); 285128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu paintInfo->context->clipOut(floatBox); 28528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 28538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 28548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 28558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 28568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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 28578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // fixed). 28588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project GapRects result; 28598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!isBlockFlow()) // FIXME: Make multi-column selection gap filling work someday. 28608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result; 28618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 28625af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (hasColumns() || hasTransform() || style()->columnSpan()) { 28638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: We should learn how to gap fill multiple columns and transforms eventually. 286428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight(); 286528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight()); 286628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight()); 28678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result; 28688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 28698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 28708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (childrenInline()) 287128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu result = inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo); 28728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 287328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo); 28748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 28758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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. 28768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd)) 287728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, 287828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu logicalHeight(), paintInfo)); 28798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result; 28808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 28818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 288228040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuGapRects RenderBlock::inlineSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock, 288328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo) 28848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 28858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project GapRects result; 28868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 28878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool containsStart = selectionState() == SelectionStart || selectionState() == SelectionBoth; 28888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 28898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!firstLineBox()) { 28908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (containsStart) { 289128040489d744e0c5d475a88663056c9040ed5320Teng-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 28928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // case. 289328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight(); 289428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight()); 289528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight()); 28968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 28978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result; 28988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 28998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RootInlineBox* lastSelectedLine = 0; 29018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RootInlineBox* curr; 29028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (curr = firstRootBox(); curr && !curr->hasSelectedChildren(); curr = curr->nextRootBox()) { } 29038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Now paint the gaps for the lines. 29058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (; curr && curr->hasSelectedChildren(); curr = curr->nextRootBox()) { 29068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int selTop = curr->selectionTop(); 29078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int selHeight = curr->selectionHeight(); 29088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!containsStart && !lastSelectedLine && 29108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project selectionState() != SelectionStart && selectionState() != SelectionBoth) 291128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, 291228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu selTop, paintInfo)); 291328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu 291428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu IntRect logicalRect(curr->logicalLeft(), selTop, curr->logicalWidth(), selTop + selHeight); 29152bde8e466a4451c7319e3a072d118917957d6554Steve Block logicalRect.move(isHorizontalWritingMode() ? offsetFromRootBlock : IntSize(offsetFromRootBlock.height(), offsetFromRootBlock.width())); 291628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu IntRect physicalRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect); 29172bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!paintInfo || (isHorizontalWritingMode() && physicalRect.y() < paintInfo->rect.maxY() && physicalRect.maxY() > paintInfo->rect.y()) 29182bde8e466a4451c7319e3a072d118917957d6554Steve Block || (!isHorizontalWritingMode() && physicalRect.x() < paintInfo->rect.maxX() && physicalRect.maxX() > paintInfo->rect.x())) 291928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu result.unite(curr->lineSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, selTop, selHeight, paintInfo)); 29208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lastSelectedLine = curr; 29228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 29238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (containsStart && !lastSelectedLine) 29258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // VisibleSelection must start just after our last line. 29268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lastSelectedLine = lastRootBox(); 29278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (lastSelectedLine && selectionState() != SelectionEnd && selectionState() != SelectionBoth) { 29298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Go ahead and update our lastY to be the bottom of the last selected line. 293028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + lastSelectedLine->selectionBottom(); 293128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom()); 293228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu lastLogicalRight = logicalRightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom()); 29338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 29348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result; 29358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 29368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 293728040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuGapRects RenderBlock::blockSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock, 293828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo) 29398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 29408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project GapRects result; 29418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Go ahead and jump right to the first block child that contains some selected objects. 2943635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderBox* curr; 2944635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project for (curr = firstChildBox(); curr && curr->selectionState() == SelectionNone; curr = curr->nextSiblingBox()) { } 29458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2946635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project for (bool sawSelectionEnd = false; curr && !sawSelectionEnd; curr = curr->nextSiblingBox()) { 29478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project SelectionState childState = curr->selectionState(); 29488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (childState == SelectionBoth || childState == SelectionEnd) 29498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project sawSelectionEnd = true; 29508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (curr->isFloatingOrPositioned()) 29528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; // We must be a normal flow object in order to even be considered. 29538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (curr->isRelPositioned() && curr->hasLayer()) { 29558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the relposition offset is anything other than 0, then treat this just like an absolute positioned element. 29568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Just disregard it completely. 2957635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project IntSize relOffset = curr->layer()->relativePositionOffset(); 2958635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (relOffset.width() || relOffset.height()) 29598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 29608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 29618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTable(); // FIXME: Eventually we won't special-case table like this. 29638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool fillBlockGaps = paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone); 29648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (fillBlockGaps) { 29658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We need to fill the vertical gap above this object. 29668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (childState == SelectionEnd || childState == SelectionInside) 29678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Fill the gap above the object. 296828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, 296928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu curr->logicalTop(), paintInfo)); 29708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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* 29728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // our object. We know this if the selection did not end inside our object. 29738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (paintsOwnSelection && (childState == SelectionStart || sawSelectionEnd)) 29748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project childState = SelectionNone; 29758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Fill side gaps on this object based off its state. 29778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool leftGap, rightGap; 297828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu getSelectionGapInfo(childState, leftGap, rightGap); 29798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (leftGap) 298128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu result.uniteLeft(logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalLeft(), curr->logicalTop(), curr->logicalHeight(), paintInfo)); 29828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (rightGap) 298328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalRight(), curr->logicalTop(), curr->logicalHeight(), paintInfo)); 29848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 298528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu // Update lastLogicalTop to be just underneath the object. lastLogicalLeft and lastLogicalRight extend as far as 29868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // they can without bumping into floating or positioned objects. Ideally they will go right up 29878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // to the border of the root selection block. 298828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + curr->logicalBottom(); 298928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logicalBottom()); 299028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logicalBottom()); 29918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else if (childState != SelectionNone) 29928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We must be a block that has some selected object inside it. Go ahead and recur. 299328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu result.unite(toRenderBlock(curr)->selectionGaps(rootBlock, rootBlockPhysicalPosition, IntSize(offsetFromRootBlock.width() + curr->x(), offsetFromRootBlock.height() + curr->y()), 299428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo)); 29958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 29968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result; 29978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 29988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 299928040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuIntRect RenderBlock::blockSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock, 300028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int lastLogicalTop, int lastLogicalLeft, int lastLogicalRight, int logicalBottom, const PaintInfo* paintInfo) 30018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 300228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int logicalTop = lastLogicalTop; 300328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int logicalHeight = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalBottom - logicalTop; 300428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu if (logicalHeight <= 0) 30058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return IntRect(); 30068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Get the selection offsets for the bottom of the gap 300828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int logicalLeft = max(lastLogicalLeft, logicalLeftSelectionOffset(rootBlock, logicalBottom)); 300928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int logicalRight = min(lastLogicalRight, logicalRightSelectionOffset(rootBlock, logicalBottom)); 301028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int logicalWidth = logicalRight - logicalLeft; 301128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu if (logicalWidth <= 0) 30128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return IntRect(); 30138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 301428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(logicalLeft, logicalTop, logicalWidth, logicalHeight)); 30158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (paintInfo) 3016643ca7872b450ea4efacab6188849e5aac2ba161Steve Block paintInfo->context->fillRect(gapRect, selectionBackgroundColor(), style()->colorSpace()); 30178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return gapRect; 30188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 30198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 302028040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuIntRect RenderBlock::logicalLeftSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock, 302128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu RenderObject* selObj, int logicalLeft, int logicalTop, int logicalHeight, const PaintInfo* paintInfo) 30228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 302328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop; 302428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int rootBlockLogicalLeft = max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight)); 302528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int rootBlockLogicalRight = min(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalLeft, min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight))); 302628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft; 302728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu if (rootBlockLogicalWidth <= 0) 30288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return IntRect(); 30298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 303028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight)); 30318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (paintInfo) 3032643ca7872b450ea4efacab6188849e5aac2ba161Steve Block paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace()); 30338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return gapRect; 30348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 30358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 303628040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuIntRect RenderBlock::logicalRightSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock, 303728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu RenderObject* selObj, int logicalRight, int logicalTop, int logicalHeight, const PaintInfo* paintInfo) 30388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 303928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop; 304028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int rootBlockLogicalLeft = max(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalRight, max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight))); 304128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int rootBlockLogicalRight = min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight)); 304228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft; 304328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu if (rootBlockLogicalWidth <= 0) 30448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return IntRect(); 30458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 304628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight)); 30478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (paintInfo) 3048643ca7872b450ea4efacab6188849e5aac2ba161Steve Block paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace()); 30498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return gapRect; 30508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 30518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 305228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuvoid RenderBlock::getSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap) 30538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3054a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool ltr = style()->isLeftToRightDirection(); 30558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project leftGap = (state == RenderObject::SelectionInside) || 30568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (state == RenderObject::SelectionEnd && ltr) || 30578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (state == RenderObject::SelectionStart && !ltr); 30588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rightGap = (state == RenderObject::SelectionInside) || 30598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (state == RenderObject::SelectionStart && ltr) || 30608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (state == RenderObject::SelectionEnd && !ltr); 30618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 30628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 306328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuint RenderBlock::logicalLeftSelectionOffset(RenderBlock* rootBlock, int position) 30648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 306528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int logicalLeft = logicalLeftOffsetForLine(position, false); 306628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu if (logicalLeft == logicalLeftOffsetForContent()) { 30678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (rootBlock != this) 30688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The border can potentially be further extended by our containingBlock(). 306928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu return containingBlock()->logicalLeftSelectionOffset(rootBlock, position + logicalTop()); 307028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu return logicalLeft; 307128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu } else { 30728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderBlock* cb = this; 30738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (cb != rootBlock) { 307428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu logicalLeft += cb->logicalLeft(); 30758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project cb = cb->containingBlock(); 30768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 30778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 307828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu return logicalLeft; 30798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 30808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 308128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuint RenderBlock::logicalRightSelectionOffset(RenderBlock* rootBlock, int position) 30828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 308328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int logicalRight = logicalRightOffsetForLine(position, false); 308428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu if (logicalRight == logicalRightOffsetForContent()) { 30858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (rootBlock != this) 30868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The border can potentially be further extended by our containingBlock(). 308728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu return containingBlock()->logicalRightSelectionOffset(rootBlock, position + logicalTop()); 308828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu return logicalRight; 308928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu } else { 30908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderBlock* cb = this; 30918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (cb != rootBlock) { 309228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu logicalRight += cb->logicalLeft(); 30938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project cb = cb->containingBlock(); 30948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 30958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 309628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu return logicalRight; 30978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 30988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3099635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::insertPositionedObject(RenderBox* o) 31008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 31018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Create the list of special objects if we don't aleady have one 31028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_positionedObjects) 310381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_positionedObjects = adoptPtr(new PositionedObjectsListHashSet); 31048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_positionedObjects->add(o); 31068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 31078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3108635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::removePositionedObject(RenderBox* o) 31098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 31108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_positionedObjects) 31118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_positionedObjects->remove(o); 31128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 31138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::removePositionedObjects(RenderBlock* o) 31158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 31168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_positionedObjects) 31178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 31188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3119635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderBox* r; 31208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Iterator end = m_positionedObjects->end(); 31228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3123635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Vector<RenderBox*, 16> deadObjects; 31248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (Iterator it = m_positionedObjects->begin(); it != end; ++it) { 31268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project r = *it; 31278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!o || r->isDescendantOf(o)) { 31288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (o) 31298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project r->setChildNeedsLayout(true, false); 31308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // It is parent blocks job to add positioned child to positioned objects list of its containing block 31328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Parent layout needs to be invalidated to ensure this happens. 31338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* p = r->parent(); 31348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (p && !p->isRenderBlock()) 31358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project p = p->parent(); 31368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (p) 31378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project p->setChildNeedsLayout(true); 31388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project deadObjects.append(r); 31408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 31418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 31428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (unsigned i = 0; i < deadObjects.size(); i++) 31448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_positionedObjects->remove(deadObjects.at(i)); 31458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 31468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 314768513a70bcd92384395513322f1b801e7bf9c729Steve BlockRenderBlock::FloatingObject* RenderBlock::insertFloatingObject(RenderBox* o) 31488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 31498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(o->isFloating()); 31508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Create the list of special objects if we don't aleady have one 315281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (!m_floatingObjects) 315381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_floatingObjects = adoptPtr(new FloatingObjects); 315481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch else { 31558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Don't insert the object again if it's already in the list 315681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 315781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(o); 315881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (it != floatingObjectSet.end()) 315981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return *it; 31608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 31618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Create the special object entry & append it to the list 31638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FloatingObject* newObj = new FloatingObject(o->style()->floating() == FLEFT ? FloatingObject::FloatLeft : FloatingObject::FloatRight); 316568513a70bcd92384395513322f1b801e7bf9c729Steve Block 316668513a70bcd92384395513322f1b801e7bf9c729Steve Block // Our location is irrelevant if we're unsplittable or no pagination is in effect. 316768513a70bcd92384395513322f1b801e7bf9c729Steve Block // Just go ahead and lay out the float. 3168a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool isChildRenderBlock = o->isRenderBlock(); 3169f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (isChildRenderBlock && !o->needsLayout() && view()->layoutState()->pageLogicalHeightChanged()) 3170a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch o->setChildNeedsLayout(true, false); 3171a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 3172f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch bool affectedByPagination = isChildRenderBlock && view()->layoutState()->m_pageLogicalHeight; 3173a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!affectedByPagination || isWritingModeRoot()) // We are unsplittable if we're a block flow root. 317468513a70bcd92384395513322f1b801e7bf9c729Steve Block o->layoutIfNeeded(); 317568513a70bcd92384395513322f1b801e7bf9c729Steve Block else { 3176bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen o->computeLogicalWidth(); 3177bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen o->computeBlockDirectionMargins(this); 317868513a70bcd92384395513322f1b801e7bf9c729Steve Block } 3179a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalWidthForFloat(newObj, logicalWidthForChild(o) + marginStartForChild(o) + marginEndForChild(o)); 318068513a70bcd92384395513322f1b801e7bf9c729Steve Block 31818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian newObj->m_shouldPaint = !o->hasSelfPaintingLayer(); // If a layer exists, the float will paint itself. Otherwise someone else will. 31828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newObj->m_isDescendant = true; 31838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newObj->m_renderer = o; 31848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 318581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_floatingObjects->increaseObjectsCount(newObj->type()); 318681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_floatingObjects->set().add(newObj); 318768513a70bcd92384395513322f1b801e7bf9c729Steve Block 318868513a70bcd92384395513322f1b801e7bf9c729Steve Block return newObj; 31898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 31908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3191635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::removeFloatingObject(RenderBox* o) 31928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 31938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_floatingObjects) { 319481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 319581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet::iterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(o); 319681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (it != floatingObjectSet.end()) { 319781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* r = *it; 319881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (childrenInline()) { 319981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch int logicalTop = logicalTopForFloat(r); 320081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch int logicalBottom = logicalBottomForFloat(r); 320181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 320281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // Fix for https://bugs.webkit.org/show_bug.cgi?id=54995. 320381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (logicalBottom < 0 || logicalBottom < logicalTop || logicalTop == numeric_limits<int>::max()) 320481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch logicalBottom = numeric_limits<int>::max(); 320581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch else { 3206dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Special-case zero- and less-than-zero-height floats: those don't touch 3207dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // the line that they're on, but it still needs to be dirtied. This is 3208dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // accomplished by pretending they have a height of 1. 320981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch logicalBottom = max(logicalBottom, logicalTop + 1); 3210dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 321154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block if (r->m_originatingLine) { 321254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block ASSERT(r->m_originatingLine->renderer() == this); 321354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block r->m_originatingLine->markDirty(); 321454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block#if !ASSERT_DISABLED 321554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block r->m_originatingLine = 0; 321654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block#endif 321754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block } 321881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch markLinesDirtyInBlockRange(0, logicalBottom); 32198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 322081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_floatingObjects->decreaseObjectsCount(r->type()); 322181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch floatingObjectSet.remove(it); 322254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block ASSERT(!r->m_originatingLine); 322381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch delete r; 32248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 32258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 32268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 32278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 32282fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid RenderBlock::removeFloatingObjectsBelow(FloatingObject* lastFloat, int logicalOffset) 322968513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 323068513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!m_floatingObjects) 323168513a70bcd92384395513322f1b801e7bf9c729Steve Block return; 323268513a70bcd92384395513322f1b801e7bf9c729Steve Block 323381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 323481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* curr = floatingObjectSet.last(); 32352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block while (curr != lastFloat && (!curr->isPlaced() || logicalTopForFloat(curr) >= logicalOffset)) { 323681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_floatingObjects->decreaseObjectsCount(curr->type()); 323781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch floatingObjectSet.removeLast(); 323854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block ASSERT(!curr->m_originatingLine); 323981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch delete curr; 324081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch curr = floatingObjectSet.last(); 324168513a70bcd92384395513322f1b801e7bf9c729Steve Block } 324268513a70bcd92384395513322f1b801e7bf9c729Steve Block} 324368513a70bcd92384395513322f1b801e7bf9c729Steve Block 32448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::positionNewFloats() 32458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 32468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_floatingObjects) 32478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 324881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 324981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 325081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (floatingObjectSet.isEmpty()) 325181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return false; 32528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 32538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If all floats have already been positioned, then we have no work to do. 325481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (floatingObjectSet.last()->isPlaced()) 32558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 32568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 32578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Move backwards through our floating object list until we find a float that has 32588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // already been positioned. Then we'll be able to move forward, positioning all of 32598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the new floats that need it. 326081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator it = floatingObjectSet.end(); 326181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch --it; // Go to last item. 326281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator begin = floatingObjectSet.begin(); 326381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* lastPlacedFloatingObject = 0; 326481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch while (it != begin) { 326581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch --it; 326681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if ((*it)->isPlaced()) { 326781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch lastPlacedFloatingObject = *it; 326881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ++it; 326981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch break; 327081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 32718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 32728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3273a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int logicalTop = logicalHeight(); 32748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3275a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // The float cannot start above the top position of the last positioned float. 327681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (lastPlacedFloatingObject) 327781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch logicalTop = max(logicalTopForFloat(lastPlacedFloatingObject), logicalTop); 32788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 327981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator end = floatingObjectSet.end(); 32808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Now walk through the set of unpositioned floats and place them. 328181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch for (; it != end; ++it) { 328281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* floatingObject = *it; 32838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The containing block is responsible for positioning floats, so if we have floats in our 32848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // list that come from somewhere else, do not attempt to position them. 328581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (floatingObject->renderer()->containingBlock() != this) 32868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 32878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3288a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RenderBox* childBox = floatingObject->renderer(); 3289a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int childLogicalLeftMargin = style()->isLeftToRightDirection() ? marginStartForChild(childBox) : marginEndForChild(childBox); 32908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3291a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int rightOffset = logicalRightOffsetForContent(); // Constant part of right offset. 3292a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int leftOffset = logicalLeftOffsetForContent(); // Constant part of left offset. 3293a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int floatLogicalWidth = logicalWidthForFloat(floatingObject); // The width we look for. 3294a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (rightOffset - leftOffset < floatLogicalWidth) 3295a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch floatLogicalWidth = rightOffset - leftOffset; // Never look for more than what will be available. 32968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3297a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch IntRect oldRect(childBox->x(), childBox->y() , childBox->width(), childBox->height()); 329868513a70bcd92384395513322f1b801e7bf9c729Steve Block 3299a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (childBox->style()->clear() & CLEFT) 3300a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch logicalTop = max(lowestFloatLogicalBottom(FloatingObject::FloatLeft), logicalTop); 3301a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (childBox->style()->clear() & CRIGHT) 3302a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch logicalTop = max(lowestFloatLogicalBottom(FloatingObject::FloatRight), logicalTop); 33038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3304a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int floatLogicalLeft; 3305a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (childBox->style()->floating() == FLEFT) { 33068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int heightRemainingLeft = 1; 33078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int heightRemainingRight = 1; 3308a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch floatLogicalLeft = logicalLeftOffsetForLine(logicalTop, leftOffset, false, &heightRemainingLeft); 3309a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch while (logicalRightOffsetForLine(logicalTop, rightOffset, false, &heightRemainingRight) - floatLogicalLeft < floatLogicalWidth) { 3310a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch logicalTop += min(heightRemainingLeft, heightRemainingRight); 3311a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch floatLogicalLeft = logicalLeftOffsetForLine(logicalTop, leftOffset, false, &heightRemainingLeft); 33128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3313a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch floatLogicalLeft = max(0, floatLogicalLeft); 33148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 33158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int heightRemainingLeft = 1; 33168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int heightRemainingRight = 1; 3317a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch floatLogicalLeft = logicalRightOffsetForLine(logicalTop, rightOffset, false, &heightRemainingRight); 3318a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch while (floatLogicalLeft - logicalLeftOffsetForLine(logicalTop, leftOffset, false, &heightRemainingLeft) < floatLogicalWidth) { 3319a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch logicalTop += min(heightRemainingLeft, heightRemainingRight); 3320a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch floatLogicalLeft = logicalRightOffsetForLine(logicalTop, rightOffset, false, &heightRemainingRight); 33218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3322a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch floatLogicalLeft -= logicalWidthForFloat(floatingObject); // Use the original width of the float here, since the local variable 3323a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // |floatLogicalWidth| was capped to the available line width. 3324a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // See fast/block/float/clamped-right-float.html. 33258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3326a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 3327a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalLeftForFloat(floatingObject, floatLogicalLeft); 3328a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalLeftForChild(childBox, floatLogicalLeft + childLogicalLeftMargin); 3329a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalTopForChild(childBox, logicalTop + marginBeforeForChild(childBox)); 33308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 333168513a70bcd92384395513322f1b801e7bf9c729Steve Block if (view()->layoutState()->isPaginated()) { 3332a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RenderBlock* childBlock = childBox->isRenderBlock() ? toRenderBlock(childBox) : 0; 33338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3334a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!childBox->needsLayout()) 3335a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch childBox->markForPaginationRelayoutIfNeeded();; 3336a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch childBox->layoutIfNeeded(); 333768513a70bcd92384395513322f1b801e7bf9c729Steve Block 333868513a70bcd92384395513322f1b801e7bf9c729Steve Block // If we are unsplittable and don't fit, then we need to move down. 333968513a70bcd92384395513322f1b801e7bf9c729Steve Block // We include our margins as part of the unsplittable area. 3340a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int newLogicalTop = adjustForUnsplittableChild(childBox, logicalTop, true); 334168513a70bcd92384395513322f1b801e7bf9c729Steve Block 334268513a70bcd92384395513322f1b801e7bf9c729Steve Block // See if we have a pagination strut that is making us move down further. 334368513a70bcd92384395513322f1b801e7bf9c729Steve Block // Note that an unsplittable child can't also have a pagination strut, so this is 334468513a70bcd92384395513322f1b801e7bf9c729Steve Block // exclusive with the case above. 334568513a70bcd92384395513322f1b801e7bf9c729Steve Block if (childBlock && childBlock->paginationStrut()) { 3346a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch newLogicalTop += childBlock->paginationStrut(); 334768513a70bcd92384395513322f1b801e7bf9c729Steve Block childBlock->setPaginationStrut(0); 334868513a70bcd92384395513322f1b801e7bf9c729Steve Block } 334968513a70bcd92384395513322f1b801e7bf9c729Steve Block 3350a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (newLogicalTop != logicalTop) { 3351a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch floatingObject->m_paginationStrut = newLogicalTop - logicalTop; 3352a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch logicalTop = newLogicalTop; 3353a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalTopForChild(childBox, logicalTop + marginBeforeForChild(childBox)); 335468513a70bcd92384395513322f1b801e7bf9c729Steve Block if (childBlock) 335568513a70bcd92384395513322f1b801e7bf9c729Steve Block childBlock->setChildNeedsLayout(true, false); 3356a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch childBox->layoutIfNeeded(); 335768513a70bcd92384395513322f1b801e7bf9c729Steve Block } 335868513a70bcd92384395513322f1b801e7bf9c729Steve Block } 335968513a70bcd92384395513322f1b801e7bf9c729Steve Block 3360a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalTopForFloat(floatingObject, logicalTop); 3361a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeightForFloat(floatingObject, logicalHeightForChild(childBox) + marginBeforeForChild(childBox) + marginAfterForChild(childBox)); 3362a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 3363a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch floatingObject->setIsPlaced(); 3364a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 33658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the child moved, we have to repaint it. 3366a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (childBox->checkForRepaintDuringLayout()) 3367a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch childBox->repaintDuringLayoutIfMoved(oldRect); 33688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 33698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 33708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 33718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::newLine(EClear clear) 33738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 33748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project positionNewFloats(); 33758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // set y position 33768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int newY = 0; 33770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch switch (clear) 33788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 33798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case CLEFT: 3380a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch newY = lowestFloatLogicalBottom(FloatingObject::FloatLeft); 33818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 33828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case CRIGHT: 3383a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch newY = lowestFloatLogicalBottom(FloatingObject::FloatRight); 33848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 33858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case CBOTH: 3386a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch newY = lowestFloatLogicalBottom(); 33878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project default: 33888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 33898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3390635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (height() < newY) 3391bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen setLogicalHeight(newY); 33928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 33938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::addPercentHeightDescendant(RenderBox* descendant) 33958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 33968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!gPercentHeightDescendantsMap) { 33978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gPercentHeightDescendantsMap = new PercentHeightDescendantsMap; 33988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gPercentHeightContainerMap = new PercentHeightContainerMap; 33998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 34008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(this); 34028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!descendantSet) { 34038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project descendantSet = new HashSet<RenderBox*>; 34048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gPercentHeightDescendantsMap->set(this, descendantSet); 34058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 34068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool added = descendantSet->add(descendant).second; 34078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!added) { 34088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(gPercentHeightContainerMap->get(descendant)); 34098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(gPercentHeightContainerMap->get(descendant)->contains(this)); 34108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 34118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 34128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(descendant); 34148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!containerSet) { 34158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project containerSet = new HashSet<RenderBlock*>; 34168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gPercentHeightContainerMap->set(descendant, containerSet); 34178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 34188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!containerSet->contains(this)); 34198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project containerSet->add(this); 34208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 34218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::removePercentHeightDescendant(RenderBox* descendant) 34238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 34248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!gPercentHeightContainerMap) 34258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 34268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->take(descendant); 34288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!containerSet) 34298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 34308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HashSet<RenderBlock*>::iterator end = containerSet->end(); 34328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (HashSet<RenderBlock*>::iterator it = containerSet->begin(); it != end; ++it) { 34338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderBlock* container = *it; 34348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(container); 34358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(descendantSet); 34368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!descendantSet) 34378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 34388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(descendantSet->contains(descendant)); 34398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project descendantSet->remove(descendant); 34408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (descendantSet->isEmpty()) { 34418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gPercentHeightDescendantsMap->remove(container); 34428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete descendantSet; 34438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 34448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 34458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete containerSet; 34478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 34488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianHashSet<RenderBox*>* RenderBlock::percentHeightDescendants() const 34508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 34518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0; 34528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 34538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34542bde8e466a4451c7319e3a072d118917957d6554Steve Block// FIXME: The logicalLeftOffsetForLine/logicalRightOffsetForLine functions are very slow if there are many floats 34552bde8e466a4451c7319e3a072d118917957d6554Steve Block// present. We need to add a structure to floating objects to represent "lines" of floats. Then instead of checking 34562bde8e466a4451c7319e3a072d118917957d6554Steve Block// each float individually, we'd just walk backwards through the "lines" and stop when we hit a line that is fully above 34572bde8e466a4451c7319e3a072d118917957d6554Steve Block// the vertical offset that we'd like to check. Computing the "lines" would be rather complicated, but could replace the left 34582bde8e466a4451c7319e3a072d118917957d6554Steve Block// objects and right objects count hack that is currently used here. 3459a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::logicalLeftOffsetForLine(int logicalTop, int fixedOffset, bool applyTextIndent, int* heightRemaining) const 34608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 34618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int left = fixedOffset; 346281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (m_floatingObjects && m_floatingObjects->hasLeftObjects()) { 3463a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (heightRemaining) 3464a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch *heightRemaining = 1; 346581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 34662bde8e466a4451c7319e3a072d118917957d6554Steve Block // We know the list is non-empty, since we have "left" objects to search for. 34672bde8e466a4451c7319e3a072d118917957d6554Steve Block // Therefore we can assume that begin != end, and that we can do at least one 34682bde8e466a4451c7319e3a072d118917957d6554Steve Block // decrement. 346981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 34702bde8e466a4451c7319e3a072d118917957d6554Steve Block FloatingObjectSetIterator begin = floatingObjectSet.begin(); 34712bde8e466a4451c7319e3a072d118917957d6554Steve Block FloatingObjectSetIterator it = floatingObjectSet.end(); 34722bde8e466a4451c7319e3a072d118917957d6554Steve Block do { 34732bde8e466a4451c7319e3a072d118917957d6554Steve Block --it; 347481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* r = *it; 3475a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (r->isPlaced() && logicalTopForFloat(r) <= logicalTop && logicalBottomForFloat(r) > logicalTop 3476a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch && r->type() == FloatingObject::FloatLeft 3477a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch && logicalRightForFloat(r) > left) { 34782bde8e466a4451c7319e3a072d118917957d6554Steve Block left = max(left, logicalRightForFloat(r)); 3479a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (heightRemaining) 3480a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch *heightRemaining = logicalBottomForFloat(r) - logicalTop; 34818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 34822bde8e466a4451c7319e3a072d118917957d6554Steve Block } while (it != begin); 34838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 34848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3485a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (applyTextIndent && style()->isLeftToRightDirection()) { 3486635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project int cw = 0; 34878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->textIndent().isPercent()) 3488bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen cw = containingBlock()->availableLogicalWidth(); 34898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project left += style()->textIndent().calcMinValue(cw); 34908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 34918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return left; 34938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 34948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3495a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::logicalRightOffsetForLine(int logicalTop, int fixedOffset, bool applyTextIndent, int* heightRemaining) const 34968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 34978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int right = fixedOffset; 34988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 349981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (m_floatingObjects && m_floatingObjects->hasRightObjects()) { 3500a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (heightRemaining) 3501a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch *heightRemaining = 1; 35022bde8e466a4451c7319e3a072d118917957d6554Steve Block 35032bde8e466a4451c7319e3a072d118917957d6554Steve Block // We know the list is non-empty, since we have "right" objects to search for. 35042bde8e466a4451c7319e3a072d118917957d6554Steve Block // Therefore we can assume that begin != end, and that we can do at least one 35052bde8e466a4451c7319e3a072d118917957d6554Steve Block // decrement. 350681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 35072bde8e466a4451c7319e3a072d118917957d6554Steve Block FloatingObjectSetIterator begin = floatingObjectSet.begin(); 35082bde8e466a4451c7319e3a072d118917957d6554Steve Block FloatingObjectSetIterator it = floatingObjectSet.end(); 35092bde8e466a4451c7319e3a072d118917957d6554Steve Block do { 35102bde8e466a4451c7319e3a072d118917957d6554Steve Block --it; 351181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* r = *it; 3512a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (r->isPlaced() && logicalTopForFloat(r) <= logicalTop && logicalBottomForFloat(r) > logicalTop 3513a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch && r->type() == FloatingObject::FloatRight 3514a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch && logicalLeftForFloat(r) < right) { 35152bde8e466a4451c7319e3a072d118917957d6554Steve Block right = min(right, logicalLeftForFloat(r)); 3516a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (heightRemaining) 3517a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch *heightRemaining = logicalBottomForFloat(r) - logicalTop; 35188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 35192bde8e466a4451c7319e3a072d118917957d6554Steve Block } while (it != begin); 35208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 35218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3522a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (applyTextIndent && !style()->isLeftToRightDirection()) { 3523635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project int cw = 0; 35248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->textIndent().isPercent()) 3525bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen cw = containingBlock()->availableLogicalWidth(); 35268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project right -= style()->textIndent().calcMinValue(cw); 35278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 35288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return right; 35308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 35318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 353281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochint RenderBlock::availableLogicalWidthForLine(int position, bool firstLine) const 35338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3534bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int result = logicalRightOffsetForLine(position, firstLine) - logicalLeftOffsetForLine(position, firstLine); 35358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return (result < 0) ? 0 : result; 35368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 35378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3538a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::nextFloatLogicalBottomBelow(int logicalHeight) const 35398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 35408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_floatingObjects) 35418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 35428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int bottom = INT_MAX; 354481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 354581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator end = floatingObjectSet.end(); 354681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) { 354781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* r = *it; 3548a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int floatBottom = logicalBottomForFloat(r); 3549a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (floatBottom > logicalHeight) 3550a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bottom = min(floatBottom, bottom); 35518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 35528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return bottom == INT_MAX ? 0 : bottom; 35548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 35558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3556a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::lowestFloatLogicalBottom(FloatingObject::Type floatType) const 35578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3558a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!m_floatingObjects) 3559a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return 0; 3560a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int lowestFloatBottom = 0; 356181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 356281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator end = floatingObjectSet.end(); 356381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) { 356481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* r = *it; 3565a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (r->isPlaced() && r->type() & floatType) 3566a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch lowestFloatBottom = max(lowestFloatBottom, logicalBottomForFloat(r)); 3567a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 3568a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return lowestFloatBottom; 35698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 35708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3571a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::markLinesDirtyInBlockRange(int logicalTop, int logicalBottom, RootInlineBox* highest) 35728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3573a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (logicalTop >= logicalBottom) 35748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 35758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RootInlineBox* lowestDirtyLine = lastRootBox(); 35778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RootInlineBox* afterLowest = lowestDirtyLine; 35782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block while (lowestDirtyLine && lowestDirtyLine->blockLogicalHeight() >= logicalBottom && logicalBottom < numeric_limits<int>::max()) { 35798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project afterLowest = lowestDirtyLine; 35808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lowestDirtyLine = lowestDirtyLine->prevRootBox(); 35818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 35828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 358381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch while (afterLowest && afterLowest != highest && (afterLowest->blockLogicalHeight() >= logicalTop || afterLowest->blockLogicalHeight() < 0)) { 35848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project afterLowest->markDirty(); 35858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project afterLowest = afterLowest->prevRootBox(); 35868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 35878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 35888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::clearFloats() 35908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 35918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Inline blocks are covered by the isReplaced() check in the avoidFloats method. 35928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (avoidsFloats() || isRoot() || isRenderView() || isFloatingOrPositioned() || isTableCell()) { 359381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (m_floatingObjects) { 359481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch deleteAllValues(m_floatingObjects->set()); 35958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_floatingObjects->clear(); 359681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 35978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 35988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 35998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 36008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project typedef HashMap<RenderObject*, FloatingObject*> RendererToFloatInfoMap; 36018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RendererToFloatInfoMap floatMap; 36028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 36038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_floatingObjects) { 360481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 36058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (childrenInline()) { 360681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet::iterator end = floatingObjectSet.end(); 360781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch for (FloatingObjectSet::iterator it = floatingObjectSet.begin(); it != end; ++it) { 360881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* f = *it; 36098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project floatMap.add(f->m_renderer, f); 361081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 36118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else 361281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch deleteAllValues(floatingObjectSet); 361381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_floatingObjects->clear(); 36148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 36158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3616545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // We should not process floats if the parent node is not a RenderBlock. Otherwise, we will add 3617545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // floats in an invalid context. This will cause a crash arising from a bad cast on the parent. 3618545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch // See <rdar://problem/8049753>, where float property is applied on a text node in a SVG. 3619545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (!parent() || !parent()->isRenderBlock()) 3620545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return; 3621545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 36228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Attempt to locate a previous sibling with overhanging floats. We skip any elements that are 36238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // out of flow (like floating/positioned elements), and we also skip over any objects that may have shifted 36248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // to avoid floats. 36258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool parentHasFloats = false; 3626a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RenderBlock* parentBlock = toRenderBlock(parent()); 3627635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderObject* prev = previousSibling(); 36288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian while (prev && (prev->isFloatingOrPositioned() || !prev->isBox() || !prev->isRenderBlock() || toRenderBlock(prev)->avoidsFloats())) { 36298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (prev->isFloating()) 36308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project parentHasFloats = true; 36318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project prev = prev->previousSibling(); 36328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 36338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 36348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // First add in floats from the parent. 3635a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int logicalTopOffset = logicalTop(); 3636a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (parentHasFloats) 3637a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch addIntrudingFloats(parentBlock, parentBlock->logicalLeftOffsetForContent(), logicalTopOffset); 3638635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 3639a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int logicalLeftOffset = 0; 36408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (prev) 3641a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch logicalTopOffset -= toRenderBox(prev)->logicalTop(); 3642a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch else { 3643a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch prev = parentBlock; 3644a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch logicalLeftOffset += parentBlock->logicalLeftOffsetForContent(); 36458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 36468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 36478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Add overhanging floats from the previous RenderBlock, but only if it has a float that intrudes into our space. 3648635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!prev || !prev->isRenderBlock()) 3649635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 3650635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 36518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderBlock* block = toRenderBlock(prev); 3652a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (block->m_floatingObjects && block->lowestFloatLogicalBottom() > logicalTopOffset) 3653a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch addIntrudingFloats(block, logicalLeftOffset, logicalTopOffset); 36548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 36558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (childrenInline()) { 3656a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int changeLogicalTop = numeric_limits<int>::max(); 3657a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int changeLogicalBottom = numeric_limits<int>::min(); 36588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_floatingObjects) { 365981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 366081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator end = floatingObjectSet.end(); 366181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) { 366281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* f = *it; 36638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FloatingObject* oldFloatingObject = floatMap.get(f->m_renderer); 3664a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int logicalBottom = logicalBottomForFloat(f); 36658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (oldFloatingObject) { 3666a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int oldLogicalBottom = logicalBottomForFloat(oldFloatingObject); 3667a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (logicalWidthForFloat(f) != logicalWidthForFloat(oldFloatingObject) || logicalLeftForFloat(f) != logicalLeftForFloat(oldFloatingObject)) { 3668a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch changeLogicalTop = 0; 3669a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch changeLogicalBottom = max(changeLogicalBottom, max(logicalBottom, oldLogicalBottom)); 3670a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } else if (logicalBottom != oldLogicalBottom) { 3671a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch changeLogicalTop = min(changeLogicalTop, min(logicalBottom, oldLogicalBottom)); 3672a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch changeLogicalBottom = max(changeLogicalBottom, max(logicalBottom, oldLogicalBottom)); 36738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 36748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 36758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project floatMap.remove(f->m_renderer); 367654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block if (oldFloatingObject->m_originatingLine) { 367754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block ASSERT(oldFloatingObject->m_originatingLine->renderer() == this); 367854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block oldFloatingObject->m_originatingLine->markDirty(); 367954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block } 36808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete oldFloatingObject; 36818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 3682a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch changeLogicalTop = 0; 3683a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch changeLogicalBottom = max(changeLogicalBottom, logicalBottom); 36848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 36858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 36868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 36878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 36888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RendererToFloatInfoMap::iterator end = floatMap.end(); 36898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RendererToFloatInfoMap::iterator it = floatMap.begin(); it != end; ++it) { 36908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FloatingObject* floatingObject = (*it).second; 36918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!floatingObject->m_isDescendant) { 3692a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch changeLogicalTop = 0; 3693a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch changeLogicalBottom = max(changeLogicalBottom, logicalBottomForFloat(floatingObject)); 36948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 36958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 36968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project deleteAllValues(floatMap); 36978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3698a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch markLinesDirtyInBlockRange(changeLogicalTop, changeLogicalBottom); 36998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 37008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 37018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3702a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::addOverhangingFloats(RenderBlock* child, int logicalLeftOffset, int logicalTopOffset, bool makeChildPaintOtherFloats) 37038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 37048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Prevent floats from being added to the canvas by the root element, e.g., <html>. 3705a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (child->hasOverflowClip() || !child->containsFloats() || child->isRoot() || child->hasColumns() || child->isWritingModeRoot()) 37068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 37078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 37082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int childLogicalTop = child->logicalTop(); 3709a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int lowestFloatLogicalBottom = 0; 37108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3711231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Floats that will remain the child's responsibility to paint should factor into its 3712231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // overflow. 371381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator childEnd = child->m_floatingObjects->set().end(); 371481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch for (FloatingObjectSetIterator childIt = child->m_floatingObjects->set().begin(); childIt != childEnd; ++childIt) { 371581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* r = *childIt; 37162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int logicalBottomForFloat = min(this->logicalBottomForFloat(r), numeric_limits<int>::max() - childLogicalTop); 37172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int logicalBottom = childLogicalTop + logicalBottomForFloat; 3718a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch lowestFloatLogicalBottom = max(lowestFloatLogicalBottom, logicalBottom); 37198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3720a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (logicalBottom > logicalHeight()) { 37218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the object is not in the list, we add it now. 37228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!containsFloat(r->m_renderer)) { 37232bde8e466a4451c7319e3a072d118917957d6554Steve Block int leftOffset = isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset; 37242bde8e466a4451c7319e3a072d118917957d6554Steve Block int topOffset = isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset; 37252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->x() - leftOffset, r->y() - topOffset, r->width(), r->height())); 37268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project floatingObj->m_renderer = r->m_renderer; 37278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 37288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The nearest enclosing layer always paints the float (so that zindex and stacking 37298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // behaves properly). We always want to propagate the desire to paint the float as 37308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // far out as we can, to the outermost block that overlaps the float, stopping only 37318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // if we hit a self-painting layer boundary. 3732f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (r->m_renderer->enclosingFloatPaintingLayer() == enclosingFloatPaintingLayer()) 37338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project r->m_shouldPaint = false; 37348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 37358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project floatingObj->m_shouldPaint = false; 37368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3737f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch floatingObj->m_isDescendant = true; 3738f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 37398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We create the floating object list lazily. 374081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (!m_floatingObjects) 374181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_floatingObjects = adoptPtr(new FloatingObjects); 374281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 374381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_floatingObjects->increaseObjectsCount(floatingObj->type()); 374481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_floatingObjects->set().add(floatingObj); 37458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3746f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } else { 3747f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (makeChildPaintOtherFloats && !r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer() && 3748f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch r->m_renderer->isDescendantOf(child) && r->m_renderer->enclosingFloatPaintingLayer() == child->enclosingFloatPaintingLayer()) { 3749f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // The float is not overhanging from this block, so if it is a descendant of the child, the child should 3750f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // paint it (the other case is that it is intruding into the child), unless it has its own layer or enclosing 3751f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // layer. 3752f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // If makeChildPaintOtherFloats is false, it means that the child must already know about all the floats 3753f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // it should paint. 3754f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch r->m_shouldPaint = true; 3755f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 3756f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 3757f05b935882198ccf7d81675736e3aeb089c5113aBen 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 3758f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // child now. 3759f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (r->m_isDescendant) 37602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block child->addOverflowFromChild(r->m_renderer, IntSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r))); 3761f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 37628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3763a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return lowestFloatLogicalBottom; 37648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 37658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 37664fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Blockbool RenderBlock::hasOverhangingFloat(RenderBox* renderer) 37674fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block{ 37684fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block if (!m_floatingObjects || hasColumns() || !parent()) 37694fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block return false; 37704fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block 37714fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 37724fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block FloatingObjectSetIterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(renderer); 37734fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block if (it == floatingObjectSet.end()) 37744fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block return false; 37754fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block 37764fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block return logicalBottomForFloat(*it) > logicalHeight(); 37774fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block} 37784fb1f2dd7e874d968a0effac0dd1e0ea8e94f46dSteve Block 3779a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::addIntrudingFloats(RenderBlock* prev, int logicalLeftOffset, int logicalTopOffset) 37808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 37818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the parent or previous sibling doesn't have any floats to add, don't bother. 37828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!prev->m_floatingObjects) 37838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 37848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 37852bde8e466a4451c7319e3a072d118917957d6554Steve Block logicalLeftOffset += (isHorizontalWritingMode() ? marginLeft() : marginTop()); 378681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 378781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet& prevSet = prev->m_floatingObjects->set(); 378881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator prevEnd = prevSet.end(); 378981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch for (FloatingObjectSetIterator prevIt = prevSet.begin(); prevIt != prevEnd; ++prevIt) { 379081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* r = *prevIt; 3791a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (logicalBottomForFloat(r) > logicalTopOffset) { 379281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (!m_floatingObjects || !m_floatingObjects->set().contains(r)) { 37932bde8e466a4451c7319e3a072d118917957d6554Steve Block int leftOffset = isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset; 37942bde8e466a4451c7319e3a072d118917957d6554Steve Block int topOffset = isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset; 3795a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 37962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->x() - leftOffset, r->y() - topOffset, r->width(), r->height())); 3797a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 37988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Applying the child's margin makes no sense in the case where the child was passed in. 3799a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // since this margin was added already through the modification of the |logicalLeftOffset| variable 3800a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // above. |logicalLeftOffset| will equal the margin in this case, so it's already been taken 3801a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // into account. Only apply this code if prev is the parent, since otherwise the left margin 38028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // will get applied twice. 38036b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (prev != parent()) { 38042bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isHorizontalWritingMode()) 38052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block floatingObj->setX(floatingObj->x() + prev->marginLeft()); 38066b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner else 38072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block floatingObj->setY(floatingObj->y() + prev->marginTop()); 38086b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 3809a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 38108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project floatingObj->m_shouldPaint = false; // We are not in the direct inheritance chain for this float. We will never paint it. 38118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project floatingObj->m_renderer = r->m_renderer; 38128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 38138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We create the floating object list lazily. 381481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (!m_floatingObjects) 381581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_floatingObjects = adoptPtr(new FloatingObjects); 381681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_floatingObjects->increaseObjectsCount(floatingObj->type()); 381781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_floatingObjects->set().add(floatingObj); 38188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 38198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 38208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 38218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 38228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 38238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::avoidsFloats() const 38248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 38258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Floats can't intrude into our box if we have a non-auto column count or width. 38268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return RenderBox::avoidsFloats() || !style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth(); 38278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 38288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 382981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochbool RenderBlock::containsFloat(RenderBox* renderer) 38308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 383181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return m_floatingObjects && m_floatingObjects->set().contains<RenderBox*, FloatingObjectHashTranslator>(renderer); 38328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 38338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3834635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove, bool inLayout) 38358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 383668513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!m_everHadLayout) 383768513a70bcd92384395513322f1b801e7bf9c729Steve Block return; 383868513a70bcd92384395513322f1b801e7bf9c729Steve Block 3839635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project setChildNeedsLayout(true, !inLayout); 38408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 38418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (floatToRemove) 38428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project removeFloatingObject(floatToRemove); 38438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 38448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Iterate over our children and mark them as needed. 38458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!childrenInline()) { 38468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { 38478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if ((!floatToRemove && child->isFloatingOrPositioned()) || !child->isRenderBlock()) 38488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian continue; 38498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderBlock* childBlock = toRenderBlock(child); 38508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if ((floatToRemove ? childBlock->containsFloat(floatToRemove) : childBlock->containsFloats()) || childBlock->shrinkToAvoidFloats()) 38518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian childBlock->markAllDescendantsWithFloatsForLayout(floatToRemove, inLayout); 38528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 38538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 38548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 38558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 385654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Blockvoid RenderBlock::markSiblingsWithFloatsForLayout() 385754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block{ 385854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 385954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block FloatingObjectSetIterator end = floatingObjectSet.end(); 386054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) { 386154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block if (logicalBottomForFloat(*it) > logicalHeight()) { 386254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block RenderBox* floatingBox = (*it)->renderer(); 386354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block 386454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block RenderObject* next = nextSibling(); 386554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block while (next) { 386654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block if (next->isRenderBlock() && !next->isFloatingOrPositioned() && !toRenderBlock(next)->avoidsFloats()) { 386754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block RenderBlock* nextBlock = toRenderBlock(next); 386854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block if (nextBlock->containsFloat(floatingBox)) 386954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block nextBlock->markAllDescendantsWithFloatsForLayout(floatingBox); 387054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block else 387154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block break; 387254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block } 387354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block 387454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block next = next->nextSibling(); 387554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block } 387654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block } 387754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block } 387854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block} 387954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block 38808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianint RenderBlock::getClearDelta(RenderBox* child, int yPos) 38818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 38828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // There is no need to compute clearance if we have no floats. 38838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!containsFloats()) 38848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 38858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 38868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // At least one float is present. We need to perform the clearance computation. 38878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool clearSet = child->style()->clear() != CNONE; 38888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int bottom = 0; 38898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project switch (child->style()->clear()) { 38908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case CNONE: 38918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 38928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case CLEFT: 3893a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bottom = lowestFloatLogicalBottom(FloatingObject::FloatLeft); 38948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 38958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case CRIGHT: 3896a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bottom = lowestFloatLogicalBottom(FloatingObject::FloatRight); 38978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 38988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case CBOTH: 3899a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bottom = lowestFloatLogicalBottom(); 39008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 39018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 39028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 39038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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). 39048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int result = clearSet ? max(0, bottom - yPos) : 0; 3905231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!result && child->avoidsFloats()) { 3906d0825bca7fe65beaee391d30da42e937db621564Steve Block int y = yPos; 3907d0825bca7fe65beaee391d30da42e937db621564Steve Block while (true) { 3908bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int widthAtY = availableLogicalWidthForLine(y, false); 3909e14391e94c850b8bd03680c23b38978db68687a8John Reck if (widthAtY == availableLogicalWidth()) 3910d0825bca7fe65beaee391d30da42e937db621564Steve Block return y - yPos; 3911d0825bca7fe65beaee391d30da42e937db621564Steve Block 3912d0825bca7fe65beaee391d30da42e937db621564Steve Block int oldChildY = child->y(); 3913d0825bca7fe65beaee391d30da42e937db621564Steve Block int oldChildWidth = child->width(); 3914d0825bca7fe65beaee391d30da42e937db621564Steve Block child->setY(y); 3915bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen child->computeLogicalWidth(); 3916d0825bca7fe65beaee391d30da42e937db621564Steve Block int childWidthAtY = child->width(); 3917d0825bca7fe65beaee391d30da42e937db621564Steve Block child->setY(oldChildY); 3918d0825bca7fe65beaee391d30da42e937db621564Steve Block child->setWidth(oldChildWidth); 3919d0825bca7fe65beaee391d30da42e937db621564Steve Block 3920d0825bca7fe65beaee391d30da42e937db621564Steve Block if (childWidthAtY <= widthAtY) 3921d0825bca7fe65beaee391d30da42e937db621564Steve Block return y - yPos; 3922d0825bca7fe65beaee391d30da42e937db621564Steve Block 3923a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch y = nextFloatLogicalBottomBelow(y); 3924d0825bca7fe65beaee391d30da42e937db621564Steve Block ASSERT(y >= yPos); 3925d0825bca7fe65beaee391d30da42e937db621564Steve Block if (y < yPos) 3926d0825bca7fe65beaee391d30da42e937db621564Steve Block break; 3927d0825bca7fe65beaee391d30da42e937db621564Steve Block } 3928d0825bca7fe65beaee391d30da42e937db621564Steve Block ASSERT_NOT_REACHED(); 3929231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 39308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result; 39318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 39328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 39330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool RenderBlock::isPointInOverflowControl(HitTestResult& result, int _x, int _y, int _tx, int _ty) 39348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 39358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!scrollsOverflow()) 39368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 39378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 39380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return layer()->hitTestOverflowControls(result, IntPoint(_x - _tx, _y - _ty)); 39398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 39408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 39418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction) 39428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3943635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project int tx = _tx + x(); 3944635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project int ty = _ty + y(); 39458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3946635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!isRenderView()) { 39478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check if we need to do anything at all. 3948f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch IntRect overflowBox = visualOverflowRect(); 39498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project overflowBox.move(tx, ty); 3950a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!overflowBox.intersects(result.rectForPoint(_x, _y))) 39518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 39528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 39538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 39548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) && isPointInOverflowControl(result, _x, _y, tx, ty)) { 39558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian updateHitTestResult(result, IntPoint(_x - tx, _y - ty)); 3956ad3386af2204fbbc9033a6dcced2f9b0adcd6f10Steve Block // FIXME: isPointInOverflowControl() doesn't handle rect-based tests yet. 3957db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block if (!result.addNodeToRectBasedTestResult(node(), _x, _y)) 3958db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block return true; 39598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 39608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 39618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // If we have clipping, then we can't have any spillout. 39628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer(); 39638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian bool useClip = (hasControlClip() || useOverflowClip); 3964a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch IntRect hitTestArea(result.rectForPoint(_x, _y)); 39652bde8e466a4451c7319e3a072d118917957d6554Steve Block bool checkChildren = !useClip || (hasControlClip() ? controlClipRect(tx, ty).intersects(hitTestArea) : overflowClipRect(tx, ty, IncludeOverlayScrollbarSize).intersects(hitTestArea)); 39668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (checkChildren) { 39678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Hit test descendants first. 39688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int scrolledX = tx; 39698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int scrolledY = ty; 3970dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (hasOverflowClip()) { 3971dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block IntSize offset = layer()->scrolledContentOffset(); 3972dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block scrolledX -= offset.width(); 3973dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block scrolledY -= offset.height(); 3974dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 39758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 39768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Hit test contents if we don't have columns. 39775abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (!hasColumns()) { 39785abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (hitTestContents(request, result, _x, _y, scrolledX, scrolledY, hitTestAction)) { 39795abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick updateHitTestResult(result, IntPoint(_x - tx, _y - ty)); 39805abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return true; 39815abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 39825abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (hitTestAction == HitTestFloat && hitTestFloats(request, result, _x, _y, scrolledX, scrolledY)) 39835abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return true; 39845abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } else if (hitTestColumns(request, result, _x, _y, scrolledX, scrolledY, hitTestAction)) { 39856c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen updateHitTestResult(result, IntPoint(_x - tx, _y - ty)); 39868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 39876c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 39888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 39898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3990635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Now hit test our background 3991635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) { 3992635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project IntRect boundsRect(tx, ty, width(), height()); 3993a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (visibleToHitTesting() && boundsRect.intersects(result.rectForPoint(_x, _y))) { 39946b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner updateHitTestResult(result, flipForWritingMode(IntPoint(_x - tx, _y - ty))); 3995db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block if (!result.addNodeToRectBasedTestResult(node(), _x, _y, boundsRect)) 3996db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block return true; 39978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 39988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 39998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 40008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 40018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 40028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 40035abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickbool RenderBlock::hitTestFloats(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty) 40045abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{ 40055abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (!m_floatingObjects) 40065abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return false; 40075abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 40085abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (isRenderView()) { 40095abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick tx += toRenderView(this)->frameView()->scrollX(); 40105abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick ty += toRenderView(this)->frameView()->scrollY(); 40115abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 40125abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 401381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 401481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator begin = floatingObjectSet.begin(); 401581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch for (FloatingObjectSetIterator it = floatingObjectSet.end(); it != begin;) { 401681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch --it; 401781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* floatingObject = *it; 40185abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (floatingObject->m_shouldPaint && !floatingObject->m_renderer->hasSelfPaintingLayer()) { 40192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int xOffset = xPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->x(); 40202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int yOffset = yPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->y(); 40212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block IntPoint childPoint = flipFloatForWritingMode(floatingObject, IntPoint(tx + xOffset, ty + yOffset)); 402228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu if (floatingObject->m_renderer->hitTest(request, result, IntPoint(x, y), childPoint.x(), childPoint.y())) { 402328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu updateHitTestResult(result, IntPoint(x - childPoint.x(), y - childPoint.y())); 40245abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return true; 40255abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 40265abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 40275abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 40285abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 40295abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return false; 40305abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick} 40315abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 40328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction) 40338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 40348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We need to do multiple passes, breaking up our hit testing into strips. 40355abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick ColumnInfo* colInfo = columnInfo(); 403668513a70bcd92384395513322f1b801e7bf9c729Steve Block int colCount = columnCount(colInfo); 40376c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (!colCount) 40386c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen return false; 40392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int logicalLeft = logicalLeftOffsetForContent(); 40402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int currLogicalTopOffset = 0; 4041e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int i; 40422bde8e466a4451c7319e3a072d118917957d6554Steve Block bool isHorizontal = isHorizontalWritingMode(); 40432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block for (i = 0; i < colCount; i++) { 40442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block IntRect colRect = columnRectAt(colInfo, i); 40452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int blockDelta = (isHorizontal ? colRect.height() : colRect.width()); 40462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (style()->isFlippedBlocksWritingMode()) 40472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block currLogicalTopOffset += blockDelta; 40482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block else 40492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block currLogicalTopOffset -= blockDelta; 40502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 4051e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block for (i = colCount - 1; i >= 0; i--) { 405268513a70bcd92384395513322f1b801e7bf9c729Steve Block IntRect colRect = columnRectAt(colInfo, i); 40532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block flipForWritingMode(colRect); 40542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft; 40552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int blockDelta = (isHorizontal ? colRect.height() : colRect.width()); 40562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (style()->isFlippedBlocksWritingMode()) 40572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block currLogicalTopOffset -= blockDelta; 40582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block else 40592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block currLogicalTopOffset += blockDelta; 40608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project colRect.move(tx, ty); 40618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4062a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (colRect.intersects(result.rectForPoint(x, y))) { 40638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The point is inside this column. 40648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Adjust tx and ty to change where we hit test. 40658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 40662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block IntSize offset = isHorizontal ? IntSize(currLogicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, currLogicalLeftOffset); 40672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int finalX = tx + offset.width(); 40682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int finalY = ty + offset.height(); 4069a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (result.isRectBasedTest() && !colRect.contains(result.rectForPoint(x, y))) 4070db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block hitTestContents(request, result, x, y, finalX, finalY, hitTestAction); 4071db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block else 40725abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return hitTestContents(request, result, x, y, finalX, finalY, hitTestAction) || (hitTestAction == HitTestFloat && hitTestFloats(request, result, x, y, finalX, finalY)); 40738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 40748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 40758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 40768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 40778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 40788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 40798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::hitTestContents(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction) 40808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 40818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (childrenInline() && !isTable()) { 40828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We have to hit-test our line boxes. 40836c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (m_lineBoxes.hitTest(this, request, result, x, y, tx, ty, hitTestAction)) 40848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 40858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 40868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Hit test our children. 40878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HitTestAction childHitTest = hitTestAction; 40888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (hitTestAction == HitTestChildBlockBackgrounds) 40898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project childHitTest = HitTestChildBlockBackground; 40908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian for (RenderBox* child = lastChildBox(); child; child = child->previousSiblingBox()) { 409128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu IntPoint childPoint = flipForWritingMode(child, IntPoint(tx, ty), ParentToChildFlippingAdjustment); 409228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu if (!child->hasSelfPaintingLayer() && !child->isFloating() && child->nodeAtPoint(request, result, x, y, childPoint.x(), childPoint.y(), childHitTest)) 40938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 40948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 40958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 40968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 40978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 40988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 40998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 41008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPosition RenderBlock::positionForBox(InlineBox *box, bool start) const 41018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 41028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!box) 41038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Position(); 41048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 41058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!box->renderer()->node()) 41068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return Position(node(), start ? caretMinOffset() : caretMaxOffset()); 41078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 41088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!box->isInlineTextBox()) 41098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return Position(box->renderer()->node(), start ? box->renderer()->caretMinOffset() : box->renderer()->caretMaxOffset()); 41108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 41118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineTextBox *textBox = static_cast<InlineTextBox *>(box); 41128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return Position(box->renderer()->node(), start ? textBox->start() : textBox->start() + textBox->len()); 41138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 41148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 41158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// FIXME: This function should go on RenderObject as an instance method. Then 41165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian// all cases in which positionForPoint recurs could call this instead to 41178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// prevent crossing editable boundaries. This would require many tests. 41186b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerstatic VisiblePosition positionForPointRespectingEditingBoundaries(RenderBlock* parent, RenderBox* child, const IntPoint& pointInParentCoordinates) 41198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 41206b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // FIXME: This is wrong if the child's writing-mode is different from the parent's. 41215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian IntPoint pointInChildCoordinates(pointInParentCoordinates - child->location()); 41228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 41238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // If this is an anonymous renderer, we just recur normally 41248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Node* childNode = child->node(); 41258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!childNode) 41265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return child->positionForPoint(pointInChildCoordinates); 41278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 41288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Otherwise, first make sure that the editability of the parent and child agree. 41298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // If they don't agree, then we return a visible position just before or after the child 41308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderObject* ancestor = parent; 41318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian while (ancestor && !ancestor->node()) 41328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ancestor = ancestor->parent(); 41338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 41348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // If we can't find an ancestor to check editability on, or editability is unchanged, we recur like normal 41352bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!ancestor || ancestor->node()->rendererIsEditable() == childNode->rendererIsEditable()) 41365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return child->positionForPoint(pointInChildCoordinates); 41378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 41386b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // Otherwise return before or after the child, depending on if the click was to the logical left or logical right of the child 41396b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner int childMiddle = parent->logicalWidthForChild(child) / 2; 41402bde8e466a4451c7319e3a072d118917957d6554Steve Block int logicalLeft = parent->isHorizontalWritingMode() ? pointInChildCoordinates.x() : pointInChildCoordinates.y(); 41416b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (logicalLeft < childMiddle) 41428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return ancestor->createVisiblePosition(childNode->nodeIndex(), DOWNSTREAM); 41438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return ancestor->createVisiblePosition(childNode->nodeIndex() + 1, UPSTREAM); 41448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 41458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 41466b70adc33054f8aee8c54d0f460458a9df11b8a5Russell BrennerVisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint& pointInLogicalContents) 41478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 41485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(childrenInline()); 41498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 41505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!firstRootBox()) 41515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return createVisiblePosition(0, DOWNSTREAM); 41528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 41538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // look for the closest line box in the root box which is at the passed-in y coordinate 41545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian InlineBox* closestBox = 0; 41555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian RootInlineBox* firstRootBoxWithChildren = 0; 41565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian RootInlineBox* lastRootBoxWithChildren = 0; 41575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) { 4158643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!root->firstLeafChild()) 41595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian continue; 41605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!firstRootBoxWithChildren) 41615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian firstRootBoxWithChildren = root; 41625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian lastRootBoxWithChildren = root; 41635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 41648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // check if this root line box is located at this y coordinate 41656b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (pointInLogicalContents.y() < root->selectionBottom()) { 41666b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner closestBox = root->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x()); 41678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (closestBox) 41688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian break; 41698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 41708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 41718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4172545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch bool moveCaretToBoundary = document()->frame()->editor()->behavior().shouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom(); 41735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 4174545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (!moveCaretToBoundary && !closestBox && lastRootBoxWithChildren) { 41755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // y coordinate is below last root line box, pretend we hit it 41766b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner closestBox = lastRootBoxWithChildren->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x()); 41775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 41788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 41798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (closestBox) { 41806b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (moveCaretToBoundary && pointInLogicalContents.y() < firstRootBoxWithChildren->selectionTop()) { 41815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // y coordinate is above first root line box, so return the start of the first 41825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return VisiblePosition(positionForBox(firstRootBoxWithChildren->firstLeafChild(), true), DOWNSTREAM); 41835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 41845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 41856b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // pass the box a top position that is inside it 41866b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner IntPoint point(pointInLogicalContents.x(), closestBox->logicalTop()); 41872bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!isHorizontalWritingMode()) 41886b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner point = point.transposedPoint(); 41896b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (closestBox->renderer()->isReplaced()) 41906b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return positionForPointRespectingEditingBoundaries(this, toRenderBox(closestBox->renderer()), point); 41916b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return closestBox->renderer()->positionForPoint(point); 41925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 41935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 41945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (lastRootBoxWithChildren) { 41955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // We hit this case for Mac behavior when the Y coordinate is below the last box. 4196545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch ASSERT(moveCaretToBoundary); 41972bde8e466a4451c7319e3a072d118917957d6554Steve Block InlineBox* logicallyLastBox; 41982bde8e466a4451c7319e3a072d118917957d6554Steve Block if (lastRootBoxWithChildren->getLogicalEndBoxWithNode(logicallyLastBox)) 41992bde8e466a4451c7319e3a072d118917957d6554Steve Block return VisiblePosition(positionForBox(logicallyLastBox, false), DOWNSTREAM); 42008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 42018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 42025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Can't reach this. We have a root line box, but it has no kids. 42038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // FIXME: This should ASSERT_NOT_REACHED(), but clicking on placeholder text 42045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // seems to hit this code path. 42055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return createVisiblePosition(0, DOWNSTREAM); 42065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 42075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 42085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianstatic inline bool isChildHitTestCandidate(RenderBox* box) 42095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 42105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return box->height() && box->style()->visibility() == VISIBLE && !box->isFloatingOrPositioned(); 42118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 42128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 42138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianVisiblePosition RenderBlock::positionForPoint(const IntPoint& point) 42148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 42158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (isTable()) 42168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return RenderBox::positionForPoint(point); 42178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 42188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (isReplaced()) { 42196b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // FIXME: This seems wrong when the object's writing-mode doesn't match the line's writing-mode. 42202bde8e466a4451c7319e3a072d118917957d6554Steve Block int pointLogicalLeft = isHorizontalWritingMode() ? point.x() : point.y(); 42212bde8e466a4451c7319e3a072d118917957d6554Steve Block int pointLogicalTop = isHorizontalWritingMode() ? point.y() : point.x(); 42226b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 42236b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (pointLogicalTop < 0 || (pointLogicalTop < logicalHeight() && pointLogicalLeft < 0)) 42248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return createVisiblePosition(caretMinOffset(), DOWNSTREAM); 42256b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (pointLogicalTop >= logicalHeight() || (pointLogicalTop >= 0 && pointLogicalLeft >= logicalWidth())) 42268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return createVisiblePosition(caretMaxOffset(), DOWNSTREAM); 42278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 42288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 42295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int contentsX = point.x(); 42305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int contentsY = point.y(); 42315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian offsetForContents(contentsX, contentsY); 42325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian IntPoint pointInContents(contentsX, contentsY); 42336b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner IntPoint pointInLogicalContents(pointInContents); 42342bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!isHorizontalWritingMode()) 42356b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner pointInLogicalContents = pointInLogicalContents.transposedPoint(); 42368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 42375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (childrenInline()) 42386b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return positionForPointWithInlineChildren(pointInLogicalContents); 42398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 42406b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (lastChildBox() && pointInContents.y() > lastChildBox()->logicalTop()) { 42415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian for (RenderBox* childBox = lastChildBox(); childBox; childBox = childBox->previousSiblingBox()) { 42425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (isChildHitTestCandidate(childBox)) 42435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents); 42445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 42455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } else { 42465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) { 42475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // We hit child if our click is above the bottom of its padding box (like IE6/7 and FF3). 42486b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (isChildHitTestCandidate(childBox) && pointInContents.y() < childBox->logicalBottom()) 42495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents); 42505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 42518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 42528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 42535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // We only get here if there are no hit test candidate children below the click. 42548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return RenderBox::positionForPoint(point); 42558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 42568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4257635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBlock::offsetForContents(int& tx, int& ty) const 4258635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 4259dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block IntPoint contentsPoint(tx, ty); 4260dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 4261635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (hasOverflowClip()) 4262dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block contentsPoint += layer()->scrolledContentOffset(); 4263635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 4264dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (hasColumns()) 4265635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project adjustPointToColumnContents(contentsPoint); 4266dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 4267dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block tx = contentsPoint.x(); 4268dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ty = contentsPoint.y(); 4269635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 4270635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 427168513a70bcd92384395513322f1b801e7bf9c729Steve Blockint RenderBlock::availableLogicalWidth() const 427268513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 427368513a70bcd92384395513322f1b801e7bf9c729Steve Block // If we have multiple columns, then the available logical width is reduced to our column width. 427468513a70bcd92384395513322f1b801e7bf9c729Steve Block if (hasColumns()) 427568513a70bcd92384395513322f1b801e7bf9c729Steve Block return desiredColumnWidth(); 427668513a70bcd92384395513322f1b801e7bf9c729Steve Block return RenderBox::availableLogicalWidth(); 42778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 42788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 42798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderBlock::columnGap() const 42808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 42818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->hasNormalColumnGap()) 42828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return style()->fontDescription().computedPixelSize(); // "1em" is recommended as the normal gap setting. Matches <p> margins. 42838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return static_cast<int>(style()->columnGap()); 42848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 42858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 42868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::calcColumnWidth() 42878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 42888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Calculate our column width and column count. 42898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned desiredColumnCount = 1; 42902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int desiredColumnWidth = contentLogicalWidth(); 42918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 42928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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. 4293f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (document()->paginated() || (style()->hasAutoColumnCount() && style()->hasAutoColumnWidth())) { 42948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth); 42958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 42968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 42978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 42988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int availWidth = desiredColumnWidth; 42998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int colGap = columnGap(); 43008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int colWidth = max(1, static_cast<int>(style()->columnWidth())); 43018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int colCount = max(1, static_cast<int>(style()->columnCount())); 43028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 43032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (style()->hasAutoColumnWidth() && !style()->hasAutoColumnCount()) { 43042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch desiredColumnCount = colCount; 43052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch desiredColumnWidth = max<int>(0, (availWidth - ((desiredColumnCount - 1) * colGap)) / desiredColumnCount); 43062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } else if (!style()->hasAutoColumnWidth() && style()->hasAutoColumnCount()) { 43072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch desiredColumnCount = max<int>(1, (float)(availWidth + colGap) / (colWidth + colGap)); 43082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap; 43098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 43102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch desiredColumnCount = max(min<int>(colCount, (float)(availWidth + colGap) / (colWidth + colGap)), 1); 43112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap; 43128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 43138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth); 43148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 43158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 43168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::setDesiredColumnCountAndWidth(int count, int width) 43178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 43185af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke bool destroyColumns = !firstChild() 43195af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke || (count == 1 && style()->hasAutoColumnWidth()) 43205af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke || firstChild()->isAnonymousColumnsBlock() 432168513a70bcd92384395513322f1b801e7bf9c729Steve Block || firstChild()->isAnonymousColumnSpanBlock(); 43225af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (destroyColumns) { 43238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (hasColumns()) { 43248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete gColumnInfoMap->take(this); 43258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian setHasColumns(false); 43268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 43278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 43288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ColumnInfo* info; 43298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (hasColumns()) 43308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project info = gColumnInfoMap->get(this); 43318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 43328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!gColumnInfoMap) 43338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gColumnInfoMap = new ColumnInfoMap; 43348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project info = new ColumnInfo; 43358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gColumnInfoMap->add(this, info); 43368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian setHasColumns(true); 43378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 43385abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick info->setDesiredColumnCount(count); 43395abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick info->setDesiredColumnWidth(width); 43408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 43418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 43428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 43438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderBlock::desiredColumnWidth() const 43448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 43458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!hasColumns()) 43462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return contentLogicalWidth(); 43475abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return gColumnInfoMap->get(this)->desiredColumnWidth(); 43488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 43498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 43508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectunsigned RenderBlock::desiredColumnCount() const 43518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 43528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!hasColumns()) 43538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 1; 43545abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return gColumnInfoMap->get(this)->desiredColumnCount(); 43558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 43568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 43575abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain MerrickColumnInfo* RenderBlock::columnInfo() const 43588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 43598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!hasColumns()) 43608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 43615abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return gColumnInfoMap->get(this); 43628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 43638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 436468513a70bcd92384395513322f1b801e7bf9c729Steve Blockunsigned RenderBlock::columnCount(ColumnInfo* colInfo) const 43658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 436668513a70bcd92384395513322f1b801e7bf9c729Steve Block ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo); 436768513a70bcd92384395513322f1b801e7bf9c729Steve Block return colInfo->columnCount(); 436868513a70bcd92384395513322f1b801e7bf9c729Steve Block} 43698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 437068513a70bcd92384395513322f1b801e7bf9c729Steve BlockIntRect RenderBlock::columnRectAt(ColumnInfo* colInfo, unsigned index) const 437168513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 437268513a70bcd92384395513322f1b801e7bf9c729Steve Block ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo); 43738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 437468513a70bcd92384395513322f1b801e7bf9c729Steve Block // Compute the appropriate rect based off our information. 43752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int colLogicalWidth = colInfo->desiredColumnWidth(); 43762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int colLogicalHeight = colInfo->columnHeight(); 43772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int colLogicalTop = borderBefore() + paddingBefore(); 43788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int colGap = columnGap(); 43792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int colLogicalLeft = style()->isLeftToRightDirection() ? 43802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block logicalLeftOffsetForContent() + (index * (colLogicalWidth + colGap)) 43812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block : logicalLeftOffsetForContent() + contentLogicalWidth() - colLogicalWidth - (index * (colLogicalWidth + colGap)); 43822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block IntRect rect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight); 43832bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isHorizontalWritingMode()) 43842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return IntRect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight); 43852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return IntRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogicalWidth); 438668513a70bcd92384395513322f1b801e7bf9c729Steve Block} 43878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4388f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochbool RenderBlock::layoutColumns(bool hasSpecifiedPageLogicalHeight, int pageLogicalHeight, LayoutStateMaintainer& statePusher) 438968513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 4390f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!hasColumns()) 4391f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return false; 4392f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 4393f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // FIXME: We don't balance properly at all in the presence of forced page breaks. We need to understand what 4394f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // the distance between forced page breaks is so that we can avoid making the minimum column height too tall. 4395f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch ColumnInfo* colInfo = columnInfo(); 4396f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch int desiredColumnCount = colInfo->desiredColumnCount(); 4397f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!hasSpecifiedPageLogicalHeight) { 4398f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch int columnHeight = pageLogicalHeight; 4399f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch int minColumnCount = colInfo->forcedBreaks() + 1; 4400f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (minColumnCount >= desiredColumnCount) { 4401f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // The forced page breaks are in control of the balancing. Just set the column height to the 4402f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // maximum page break distance. 4403f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!pageLogicalHeight) { 4404f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch int distanceBetweenBreaks = max(colInfo->maximumDistanceBetweenForcedBreaks(), 44052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block view()->layoutState()->pageLogicalOffset(borderBefore() + paddingBefore() + contentLogicalHeight()) - colInfo->forcedBreakOffset()); 4406f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch columnHeight = max(colInfo->minimumColumnHeight(), distanceBetweenBreaks); 440768513a70bcd92384395513322f1b801e7bf9c729Steve Block } 44082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } else if (contentLogicalHeight() > pageLogicalHeight * desiredColumnCount) { 4409f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // Now that we know the intrinsic height of the columns, we have to rebalance them. 44102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block columnHeight = max(colInfo->minimumColumnHeight(), (int)ceilf((float)contentLogicalHeight() / desiredColumnCount)); 4411f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 44128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4413f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (columnHeight && columnHeight != pageLogicalHeight) { 4414f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch statePusher.pop(); 4415f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_everHadLayout = true; 4416f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch layoutBlock(false, columnHeight); 4417f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return true; 44188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4419f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 4420f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 4421f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (pageLogicalHeight) 44222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block colInfo->setColumnCountAndHeight(ceilf((float)contentLogicalHeight() / pageLogicalHeight), pageLogicalHeight); 4423f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 4424f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (columnCount(colInfo)) { 44252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block setLogicalHeight(borderBefore() + paddingBefore() + colInfo->columnHeight() + borderAfter() + paddingAfter() + scrollbarLogicalHeight()); 4426f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_overflow.clear(); 4427643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 44288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 442968513a70bcd92384395513322f1b801e7bf9c729Steve Block return false; 44308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 44318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 44328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::adjustPointToColumnContents(IntPoint& point) const 44338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 44348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Just bail if we have no columns. 44358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!hasColumns()) 44368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 44378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 44385abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick ColumnInfo* colInfo = columnInfo(); 443968513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!columnCount(colInfo)) 44405abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return; 44418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 44428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Determine which columns we intersect. 44438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int colGap = columnGap(); 44442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int halfColGap = colGap / 2; 444568513a70bcd92384395513322f1b801e7bf9c729Steve Block IntPoint columnPoint(columnRectAt(colInfo, 0).location()); 44462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int logicalOffset = 0; 44475abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick for (unsigned i = 0; i < colInfo->columnCount(); i++) { 44488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Add in half the column gap to the left and right of the rect. 444968513a70bcd92384395513322f1b801e7bf9c729Steve Block IntRect colRect = columnRectAt(colInfo, i); 44502bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isHorizontalWritingMode()) { 44512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block IntRect gapAndColumnRect(colRect.x() - halfColGap, colRect.y(), colRect.width() + colGap, colRect.height()); 44522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRect.maxX()) { 44532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // FIXME: The clamping that follows is not completely right for right-to-left 44542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // content. 44552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Clamp everything above the column to its top left. 44562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (point.y() < gapAndColumnRect.y()) 44572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block point = gapAndColumnRect.location(); 44582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Clamp everything below the column to the next column's top left. If there is 44592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // no next column, this still maps to just after this column. 44602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block else if (point.y() >= gapAndColumnRect.maxY()) { 44612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block point = gapAndColumnRect.location(); 44622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block point.move(0, gapAndColumnRect.height()); 44632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 44642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 44652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // We're inside the column. Translate the x and y into our column coordinate space. 44662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block point.move(columnPoint.x() - colRect.x(), logicalOffset); 44672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return; 4468dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 44692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 44702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Move to the next position. 44712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block logicalOffset += colRect.height(); 44722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } else { 44732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block IntRect gapAndColumnRect(colRect.x(), colRect.y() - halfColGap, colRect.width(), colRect.height() + colGap); 44742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (point.y() >= gapAndColumnRect.y() && point.y() < gapAndColumnRect.maxY()) { 44752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // FIXME: The clamping that follows is not completely right for right-to-left 44762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // content. 44772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Clamp everything above the column to its top left. 44782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (point.x() < gapAndColumnRect.x()) 44792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block point = gapAndColumnRect.location(); 44802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Clamp everything below the column to the next column's top left. If there is 44812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // no next column, this still maps to just after this column. 44822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block else if (point.x() >= gapAndColumnRect.maxX()) { 44832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block point = gapAndColumnRect.location(); 44842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block point.move(gapAndColumnRect.width(), 0); 44852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 4486dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 44872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // We're inside the column. Translate the x and y into our column coordinate space. 44882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block point.move(logicalOffset, columnPoint.y() - colRect.y()); 44892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return; 44902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 44912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 44922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Move to the next position. 44932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block logicalOffset += colRect.width(); 44948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 44958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 44968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 44978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 44988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::adjustRectForColumns(IntRect& r) const 44998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 45008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Just bail if we have no columns. 45018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!hasColumns()) 45028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 45038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 45045abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick ColumnInfo* colInfo = columnInfo(); 45058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 45068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Begin with a result rect that is empty. 45078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project IntRect result; 45088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 45098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Determine which columns we intersect. 451068513a70bcd92384395513322f1b801e7bf9c729Steve Block unsigned colCount = columnCount(colInfo); 45116c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (!colCount) 45126c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen return; 4513e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 45142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int logicalLeft = logicalLeftOffsetForContent(); 45152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int currLogicalOffset = 0; 45162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 45176c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen for (unsigned i = 0; i < colCount; i++) { 451868513a70bcd92384395513322f1b801e7bf9c729Steve Block IntRect colRect = columnRectAt(colInfo, i); 45198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project IntRect repaintRect = r; 45202bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isHorizontalWritingMode()) { 45212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int currXOffset = colRect.x() - logicalLeft; 45222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block repaintRect.move(currXOffset, currLogicalOffset); 45232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block currLogicalOffset -= colRect.height(); 45242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } else { 45252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int currYOffset = colRect.y() - logicalLeft; 45262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block repaintRect.move(currLogicalOffset, currYOffset); 45272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block currLogicalOffset -= colRect.width(); 45282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 45298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project repaintRect.intersect(colRect); 45308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result.unite(repaintRect); 45318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 45328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 45338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project r = result; 45348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 45358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 45362fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockIntPoint RenderBlock::flipForWritingModeIncludingColumns(const IntPoint& point) const 45372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 45382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT(hasColumns()); 45392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!hasColumns() || !style()->isFlippedBlocksWritingMode()) 45402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return point; 45412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ColumnInfo* colInfo = columnInfo(); 45422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int columnLogicalHeight = colInfo->columnHeight(); 45432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight(); 45442bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isHorizontalWritingMode()) 45452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return IntPoint(point.x(), expandedLogicalHeight - point.y()); 45462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return IntPoint(expandedLogicalHeight - point.x(), point.y()); 45472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 45482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 45492fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid RenderBlock::flipForWritingModeIncludingColumns(IntRect& rect) const 45502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 45512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT(hasColumns()); 45522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!hasColumns() || !style()->isFlippedBlocksWritingMode()) 45532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return; 45542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 45552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ColumnInfo* colInfo = columnInfo(); 45562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int columnLogicalHeight = colInfo->columnHeight(); 45572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight(); 45582bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isHorizontalWritingMode()) 45592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block rect.setY(expandedLogicalHeight - rect.maxY()); 45602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block else 45612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block rect.setX(expandedLogicalHeight - rect.maxX()); 45622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 45632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 4564692e5dbf12901edacf14812a6fae25462920af42Steve Blockvoid RenderBlock::adjustForColumns(IntSize& offset, const IntPoint& point) const 4565692e5dbf12901edacf14812a6fae25462920af42Steve Block{ 4566692e5dbf12901edacf14812a6fae25462920af42Steve Block if (!hasColumns()) 4567692e5dbf12901edacf14812a6fae25462920af42Steve Block return; 4568692e5dbf12901edacf14812a6fae25462920af42Steve Block 45695abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick ColumnInfo* colInfo = columnInfo(); 45705abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 45712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int logicalLeft = logicalLeftOffsetForContent(); 457268513a70bcd92384395513322f1b801e7bf9c729Steve Block size_t colCount = columnCount(colInfo); 45732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int colLogicalWidth = colInfo->desiredColumnWidth(); 45742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int colLogicalHeight = colInfo->columnHeight(); 45752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 457668513a70bcd92384395513322f1b801e7bf9c729Steve Block for (size_t i = 0; i < colCount; ++i) { 45772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Compute the edges for a given column in the block progression direction. 45782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block IntRect sliceRect = IntRect(logicalLeft, borderBefore() + paddingBefore() + i * colLogicalHeight, colLogicalWidth, colLogicalHeight); 45792bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!isHorizontalWritingMode()) 45802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block sliceRect = sliceRect.transposedRect(); 45812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 45822fc2651226baac27029e38c9d6ef883fa32084dbSteve 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). 45832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block flipForWritingModeIncludingColumns(sliceRect); 45842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 45852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int logicalOffset = style()->isFlippedBlocksWritingMode() ? (colCount - 1 - i) * colLogicalHeight : i * colLogicalHeight; 4586692e5dbf12901edacf14812a6fae25462920af42Steve Block 45872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Now we're in the same coordinate space as the point. See if it is inside the rectangle. 45882bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isHorizontalWritingMode()) { 45892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (point.y() >= sliceRect.y() && point.y() < sliceRect.maxY()) { 45902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block offset.expand(columnRectAt(colInfo, i).x() - logicalLeft, -logicalOffset); 45912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return; 45922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 45932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } else { 45942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (point.x() >= sliceRect.x() && point.x() < sliceRect.maxX()) { 45952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block offset.expand(-logicalOffset, columnRectAt(colInfo, i).y() - logicalLeft); 45962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return; 45972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 45982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 4599692e5dbf12901edacf14812a6fae25462920af42Steve Block } 4600692e5dbf12901edacf14812a6fae25462920af42Steve Block} 4601692e5dbf12901edacf14812a6fae25462920af42Steve Block 4602bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBlock::computePreferredLogicalWidths() 46038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4604bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen ASSERT(preferredLogicalWidthsDirty()); 46058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project updateFirstLetter(); 46078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4608a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!isTableCell() && style()->logicalWidth().isFixed() && style()->logicalWidth().value() > 0) 4609a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeContentBoxLogicalWidth(style()->logicalWidth().value()); 46108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 4611bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_minPreferredLogicalWidth = 0; 4612bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_maxPreferredLogicalWidth = 0; 46138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (childrenInline()) 4615bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen computeInlinePreferredLogicalWidths(); 46168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 4617bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen computeBlockPreferredLogicalWidths(); 46188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4619bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_maxPreferredLogicalWidth = max(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth); 46208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!style()->autoWrap() && childrenInline()) { 4622bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth; 46238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // A horizontal marquee with inline children has no minimum width. 46258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (layer() && layer()->marquee() && layer()->marquee()->isHorizontal()) 4626bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_minPreferredLogicalWidth = 0; 46278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 46288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4629f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch int scrollbarWidth = 0; 4630f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (hasOverflowClip() && style()->overflowY() == OSCROLL) { 4631f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch layer()->setHasVerticalScrollbar(true); 4632f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch scrollbarWidth = verticalScrollbarWidth(); 4633f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_maxPreferredLogicalWidth += scrollbarWidth; 4634f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 4635f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 46368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isTableCell()) { 463728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu Length w = toRenderTableCell(this)->styleOrColLogicalWidth(); 4638f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (w.isFixed() && w.value() > 0) { 4639bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_maxPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(w.value())); 4640f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch scrollbarWidth = 0; 4641f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 46428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4643f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 4644f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_minPreferredLogicalWidth += scrollbarWidth; 46458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 46468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4647a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (style()->logicalMinWidth().isFixed() && style()->logicalMinWidth().value() > 0) { 4648a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMinWidth().value())); 4649a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMinWidth().value())); 46508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 46518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4652a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (style()->logicalMaxWidth().isFixed() && style()->logicalMaxWidth().value() != undefinedLength) { 4653a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMaxWidth().value())); 4654a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMaxWidth().value())); 46558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 46568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4657f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch int borderAndPadding = borderAndPaddingLogicalWidth(); 4658f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_minPreferredLogicalWidth += borderAndPadding; 4659f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_maxPreferredLogicalWidth += borderAndPadding; 46608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4661bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen setPreferredLogicalWidthsDirty(false); 46628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 46638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstruct InlineMinMaxIterator { 46658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* InlineMinMaxIterator is a class that will iterate over all render objects that contribute to 46668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inline min/max width calculations. Note the following about the way it walks: 46678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (1) Positioned content is skipped (since it does not contribute to min/max width of a block) 46688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (2) We do not drill into the children of floats or replaced elements, since you can't break 46698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in the middle of such an element. 46708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side can have 46718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project distinct borders/margin/padding that contribute to the min/max width. 46728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project*/ 46738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* parent; 46748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* current; 46758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool endOfInline; 46768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineMinMaxIterator(RenderObject* p, bool end = false) 46788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project :parent(p), current(p), endOfInline(end) {} 46798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* next(); 46818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}; 46828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderObject* InlineMinMaxIterator::next() 46848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 46858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* result = 0; 46868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool oldEndOfInline = endOfInline; 46878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project endOfInline = false; 46888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (current || current == parent) { 46898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!oldEndOfInline && 46908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (current == parent || 46918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (!current->isFloating() && !current->isReplaced() && !current->isPositioned()))) 46928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = current->firstChild(); 46938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!result) { 46948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We hit the end of our inline. (It was empty, e.g., <span></span>.) 4695635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!oldEndOfInline && current->isRenderInline()) { 46968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = current; 46978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project endOfInline = true; 46988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 46998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 47008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (current && current != parent) { 47028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = current->nextSibling(); 47038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (result) break; 47048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project current = current->parent(); 4705635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (current && current != parent && current->isRenderInline()) { 47068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = current; 47078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project endOfInline = true; 47088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 47098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 47108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 47118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 47128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!result) 47148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 47158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4716635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!result->isPositioned() && (result->isText() || result->isFloating() || result->isReplaced() || result->isRenderInline())) 47178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 47188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project current = result; 47208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = 0; 47218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 47228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Update our position. 47248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project current = result; 47258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return current; 47268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 47278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic int getBPMWidth(int childValue, Length cssUnit) 47298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 47308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (cssUnit.type() != Auto) 47318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return (cssUnit.isFixed() ? cssUnit.value() : childValue); 47328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 47338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 47348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic int getBorderPaddingMargin(const RenderBoxModelObject* child, bool endOfInline) 47368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 47378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderStyle* cstyle = child->style(); 47382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (endOfInline) 47392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return getBPMWidth(child->marginEnd(), cstyle->marginEnd()) + 47402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block getBPMWidth(child->paddingEnd(), cstyle->paddingEnd()) + 47412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block child->borderEnd(); 47422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return getBPMWidth(child->marginStart(), cstyle->marginStart()) + 47432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block getBPMWidth(child->paddingStart(), cstyle->paddingStart()) + 47442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block child->borderStart(); 47458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 47468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 474781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic inline void stripTrailingSpace(float& inlineMax, float& inlineMin, 47488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* trailingSpaceChild) 47498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 47508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (trailingSpaceChild && trailingSpaceChild->isText()) { 47518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Collapse away the trailing space at the end of a block. 4752635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderText* t = toRenderText(trailingSpaceChild); 47538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const UChar space = ' '; 47548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const Font& font = t->style()->font(); // FIXME: This ignores first-line. 475581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float spaceWidth = font.width(TextRun(&space, 1)); 47568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineMax -= spaceWidth + font.wordSpacing(); 47578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (inlineMin > inlineMax) 47588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineMin = inlineMax; 47598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 47608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 47618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 476281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic inline void updatePreferredWidth(int& preferredWidth, float& result) 476381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 476481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch int snappedResult = ceilf(result); 476581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch preferredWidth = max(snappedResult, preferredWidth); 476681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 476781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 4768bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBlock::computeInlinePreferredLogicalWidths() 47698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 477081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float inlineMax = 0; 477181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float inlineMin = 0; 47728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int cw = containingBlock()->contentLogicalWidth(); 47748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If we are at the start of a line, we want to ignore all white-space. 47768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Also strip spaces if we previously had text that ended in a trailing space. 47778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool stripFrontSpaces = true; 47788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* trailingSpaceChild = 0; 47798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Firefox and Opera will allow a table cell to grow to fit an image inside it under 47818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // very specific cirucumstances (in order to match common WinIE renderings). 47828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.) 47832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block bool allowImagesToBreak = !document()->inQuirksMode() || !isTableCell() || !style()->logicalWidth().isIntrinsicOrAuto(); 47848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool autoWrap, oldAutoWrap; 47868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project autoWrap = oldAutoWrap = style()->autoWrap(); 47878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineMinMaxIterator childIterator(this); 47898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool addedTextIndent = false; // Only gets added in once. 47908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* prevFloat = 0; 47918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (RenderObject* child = childIterator.next()) { 47928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project autoWrap = child->isReplaced() ? child->parent()->style()->autoWrap() : 47938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project child->style()->autoWrap(); 47948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!child->isBR()) { 47968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Step One: determine whether or not we need to go ahead and 47978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // terminate our current line. Each discrete chunk can become 47988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the new min-width, if it is the widest chunk seen so far, and 47998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // it can also become the max-width. 48008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Children fall into three categories: 48028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // (1) An inline flow object. These objects always have a min/max of 0, 48038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // and are included in the iteration solely so that their margins can 48048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // be added in. 48058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // 48068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // (2) An inline non-text non-flow object, e.g., an inline replaced element. 48078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // These objects can always be on a line by themselves, so in this situation 48088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // we need to go ahead and break the current line, and then add in our own 48098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // margins and min/max width on its own line, and then terminate the line. 48108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // 48118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // (3) A text object. Text runs can have breakable characters at the start, 48128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the middle or the end. They may also lose whitespace off the front if 48138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // we're already ignoring whitespace. In order to compute accurate min-width 48148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // information, we need three pieces of information. 48158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // (a) the min-width of the first non-breakable run. Should be 0 if the text string 48168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // starts with whitespace. 48178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // (b) the min-width of the last non-breakable run. Should be 0 if the text string 48188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // ends with whitespace. 48198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // (c) the min/max width of the string (trimmed for whitespace). 48208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // 48218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the text string starts with whitespace, then we need to go ahead and 48228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // terminate our current line (unless we're already in a whitespace stripping 48238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // mode. 48248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // 48258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the text string has a breakable character in the middle, but didn't start 48268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // with whitespace, then we add the width of the first non-breakable run and 48278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // then end the current line. We then need to use the intermediate min/max width 48288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // values (if any of them are larger than our current min/max). We then look at 48298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the width of the last non-breakable run and use that to start a new line 48308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // (unless we end in whitespace). 48318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderStyle* cstyle = child->style(); 483281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float childMin = 0; 483381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float childMax = 0; 48348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!child->isText()) { 48368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Case (1) and (2). Inline replaced and inline flow elements. 4837635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (child->isRenderInline()) { 48388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Add in padding/border/margin from the appropriate side of 48398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the element. 484081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float bpm = getBorderPaddingMargin(toRenderInline(child), childIterator.endOfInline); 48418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project childMin += bpm; 48428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project childMax += bpm; 48438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineMin += childMin; 48458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineMax += childMax; 48468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4847bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen child->setPreferredLogicalWidthsDirty(false); 48488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 48498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Inline replaced elts add in their margins to their min/max values. 485081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float margins = 0; 48512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Length startMargin = cstyle->marginStart(); 48522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Length endMargin = cstyle->marginEnd(); 48532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (startMargin.isFixed()) 48542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block margins += startMargin.value(); 48552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (endMargin.isFixed()) 48562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block margins += endMargin.value(); 48578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project childMin += margins; 48588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project childMax += margins; 48598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 48608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 48618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!child->isRenderInline() && !child->isText()) { 48638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Case (2). Inline replaced elements and floats. 48648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Go ahead and terminate the current line as far as 48658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // minwidth is concerned. 4866bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen childMin += child->minPreferredLogicalWidth(); 4867bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen childMax += child->maxPreferredLogicalWidth(); 48688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool clearPreviousFloat; 48708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (child->isFloating()) { 48718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project clearPreviousFloat = (prevFloat 48728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian && ((prevFloat->style()->floating() == FLEFT && (child->style()->clear() & CLEFT)) 48738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian || (prevFloat->style()->floating() == FRIGHT && (child->style()->clear() & CRIGHT)))); 48748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project prevFloat = child; 48758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else 48768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project clearPreviousFloat = false; 48778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak; 48798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if ((canBreakReplacedElement && (autoWrap || oldAutoWrap)) || clearPreviousFloat) { 488081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin); 48818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineMin = 0; 48828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 48838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If we're supposed to clear the previous float, then terminate maxwidth as well. 48858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (clearPreviousFloat) { 488681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax); 48878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineMax = 0; 48888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 48898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Add in text-indent. This is added in only once. 48918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int ti = 0; 48928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!addedTextIndent) { 48938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project addedTextIndent = true; 48948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ti = style()->textIndent().calcMinValue(cw); 48952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block childMin += ti; 48962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block childMax += ti; 48978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 48988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Add our width to the max. 49008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineMax += childMax; 49018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 49028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!autoWrap || !canBreakReplacedElement) { 49038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (child->isFloating()) 490481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch updatePreferredWidth(m_minPreferredLogicalWidth, childMin); 49058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 49068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineMin += childMin; 49078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 49088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Now check our line. 490981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch updatePreferredWidth(m_minPreferredLogicalWidth, childMin); 49108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 49118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Now start a new line. 49128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineMin = 0; 49138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 49148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 49158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We are no longer stripping whitespace at the start of 49168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // a line. 49178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!child->isFloating()) { 49188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project stripFrontSpaces = false; 49198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project trailingSpaceChild = 0; 49208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 49218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else if (child->isText()) { 49228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Case (3). Text. 4923635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderText* t = toRenderText(child); 49248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 49258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (t->isWordBreak()) { 492681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin); 49278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineMin = 0; 49288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 49298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 49308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 49312bde8e466a4451c7319e3a072d118917957d6554Steve Block if (t->style()->hasTextCombine() && t->isCombineText()) 49322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block toRenderCombineText(t)->combineText(); 49332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 49348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Determine if we have a breakable character. Pass in 49358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // whether or not we should ignore any spaces at the front 49368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // of the string. If those are going to be stripped out, 49378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // then they shouldn't be considered in the breakable char 49388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // check. 49398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool hasBreakableChar, hasBreak; 494081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float beginMin, endMin; 49418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool beginWS, endWS; 494281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float beginMax, endMax; 49438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project t->trimmedPrefWidths(inlineMax, beginMin, beginWS, endMin, endWS, 49448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hasBreakableChar, hasBreak, beginMax, endMax, 49458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project childMin, childMax, stripFrontSpaces); 49468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 49478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This text object will not be rendered, but it may still provide a breaking opportunity. 49488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!hasBreak && childMax == 0) { 49498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (autoWrap && (beginWS || endWS)) { 495081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin); 49518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineMin = 0; 49528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 49538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 49548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 49558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 49568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (stripFrontSpaces) 49578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project trailingSpaceChild = child; 49588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 49598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project trailingSpaceChild = 0; 49608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 49618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Add in text-indent. This is added in only once. 49628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int ti = 0; 49638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!addedTextIndent) { 49648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project addedTextIndent = true; 49658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ti = style()->textIndent().calcMinValue(cw); 49668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project childMin+=ti; beginMin += ti; 49678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project childMax+=ti; beginMax += ti; 49688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 49698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 49708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If we have no breakable characters at all, 49718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // then this is the easy case. We add ourselves to the current 49728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // min and max and continue. 49738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!hasBreakableChar) { 49748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineMin += childMin; 49758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 49768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We have a breakable character. Now we need to know if 49778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // we start and end with whitespace. 49788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (beginWS) 49798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Go ahead and end the current line. 498081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin); 49818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 49828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineMin += beginMin; 498381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin); 49848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project childMin -= ti; 49858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 49868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 49878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineMin = childMin; 49888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 49898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (endWS) { 49908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We end in whitespace, which means we can go ahead 49918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // and end our current line. 499281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin); 49938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineMin = 0; 49948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 499581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin); 49968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineMin = endMin; 49978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 49988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 49998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 50008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (hasBreak) { 50018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineMax += beginMax; 500281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax); 500381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch updatePreferredWidth(m_maxPreferredLogicalWidth, childMax); 50048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineMax = endMax; 50058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else 50068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineMax += childMax; 50078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5008643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 5009643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // Ignore spaces after a list marker. 5010643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (child->isListMarker()) 5011643ca7872b450ea4efacab6188849e5aac2ba161Steve Block stripFrontSpaces = true; 50128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 501381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin); 501481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax); 50158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project inlineMin = inlineMax = 0; 50168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project stripFrontSpaces = true; 50178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project trailingSpaceChild = 0; 50188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 50198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 50208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project oldAutoWrap = autoWrap; 50218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 50228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 50238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->collapseWhiteSpace()) 50248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project stripTrailingSpace(inlineMax, inlineMin, trailingSpaceChild); 50258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 502681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin); 502781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax); 50288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 50298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 50308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Use a very large value (in effect infinite). 50318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define BLOCK_MAX_WIDTH 15000 50328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5033bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBlock::computeBlockPreferredLogicalWidths() 50348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 50358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool nowrap = style()->whiteSpace() == NOWRAP; 50368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 50378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject *child = firstChild(); 50388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int floatLeftWidth = 0, floatRightWidth = 0; 50398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (child) { 50408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Positioned children don't affect the min/max width 50418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (child->isPositioned()) { 50428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project child = child->nextSibling(); 50438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 50448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 50458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 50468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (child->isFloating() || (child->isBox() && toRenderBox(child)->avoidsFloats())) { 50478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int floatTotalWidth = floatLeftWidth + floatRightWidth; 50488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (child->style()->clear() & CLEFT) { 5049bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_maxPreferredLogicalWidth = max(floatTotalWidth, m_maxPreferredLogicalWidth); 50508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project floatLeftWidth = 0; 50518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 50528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (child->style()->clear() & CRIGHT) { 5053bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_maxPreferredLogicalWidth = max(floatTotalWidth, m_maxPreferredLogicalWidth); 50548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project floatRightWidth = 0; 50558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 50568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 50578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 50588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // A margin basically has three types: fixed, percentage, and auto (variable). 50598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Auto and percentage margins simply become 0 when computing min/max width. 50608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Fixed margins can be added in as is. 50612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Length startMarginLength = child->style()->marginStart(); 50622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Length endMarginLength = child->style()->marginEnd(); 50632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int margin = 0; 50642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int marginStart = 0; 50652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int marginEnd = 0; 50662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (startMarginLength.isFixed()) 50672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block marginStart += startMarginLength.value(); 50682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (endMarginLength.isFixed()) 50692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block marginEnd += endMarginLength.value(); 50702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block margin = marginStart + marginEnd; 50718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5072bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int w = child->minPreferredLogicalWidth() + margin; 5073bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_minPreferredLogicalWidth = max(w, m_minPreferredLogicalWidth); 50748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 50758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // IE ignores tables for calculation of nowrap. Makes some sense. 50768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (nowrap && !child->isTable()) 5077bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_maxPreferredLogicalWidth = max(w, m_maxPreferredLogicalWidth); 50788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5079bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen w = child->maxPreferredLogicalWidth() + margin; 50808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 50818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!child->isFloating()) { 50828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (child->isBox() && toRenderBox(child)->avoidsFloats()) { 50838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Determine a left and right max value based off whether or not the floats can fit in the 50848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // margins of the object. For negative margins, we will attempt to overlap the float if the negative margin 50858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // is smaller than the float width. 50862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block bool ltr = containingBlock()->style()->isLeftToRightDirection(); 50872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int marginLogicalLeft = ltr ? marginStart : marginEnd; 50882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int marginLogicalRight = ltr ? marginEnd : marginStart; 50892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int maxLeft = marginLogicalLeft > 0 ? max(floatLeftWidth, marginLogicalLeft) : floatLeftWidth + marginLogicalLeft; 50902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int maxRight = marginLogicalRight > 0 ? max(floatRightWidth, marginLogicalRight) : floatRightWidth + marginLogicalRight; 5091bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen w = child->maxPreferredLogicalWidth() + maxLeft + maxRight; 50928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project w = max(w, floatLeftWidth + floatRightWidth); 50938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 50948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 5095bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_maxPreferredLogicalWidth = max(floatLeftWidth + floatRightWidth, m_maxPreferredLogicalWidth); 50968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project floatLeftWidth = floatRightWidth = 0; 50978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 50988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 50998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (child->isFloating()) { 51008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->floating() == FLEFT) 51018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project floatLeftWidth += w; 51028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 51038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project floatRightWidth += w; 51048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else 5105bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_maxPreferredLogicalWidth = max(w, m_maxPreferredLogicalWidth); 51068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 51078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // A very specific WinIE quirk. 51088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Example: 51098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* 51108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project <div style="position:absolute; width:100px; top:50px;"> 51118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project <div style="position:absolute;left:0px;top:50px;height:50px;background-color:green"> 51128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project <table style="width:100%"><tr><td></table> 51138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project </div> 51148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project </div> 51158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 51168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // In the above example, the inner absolute positioned block should have a computed width 51178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // of 100px because of the table. 51188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We can achieve this effect by making the maxwidth of blocks that contain tables 51198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // with percentage widths be infinite (as long as they are not inside a table cell). 51202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (document()->inQuirksMode() && child->style()->logicalWidth().isPercent() && 5121bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen !isTableCell() && child->isTable() && m_maxPreferredLogicalWidth < BLOCK_MAX_WIDTH) { 51228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderBlock* cb = containingBlock(); 51238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (!cb->isRenderView() && !cb->isTableCell()) 51248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project cb = cb->containingBlock(); 51258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!cb->isTableCell()) 5126bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_maxPreferredLogicalWidth = BLOCK_MAX_WIDTH; 51278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 51288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 51298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project child = child->nextSibling(); 51308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 51318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 51328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Always make sure these values are non-negative. 5133bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_minPreferredLogicalWidth = max(0, m_minPreferredLogicalWidth); 5134bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_maxPreferredLogicalWidth = max(0, m_maxPreferredLogicalWidth); 51358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5136bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_maxPreferredLogicalWidth = max(floatLeftWidth + floatRightWidth, m_maxPreferredLogicalWidth); 51378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 51388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 51398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBlock::hasLineIfEmpty() const 51408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 51410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!node()) 51420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return false; 51430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 51442bde8e466a4451c7319e3a072d118917957d6554Steve Block if (node()->rendererIsEditable() && node()->rootEditableElement() == node()) 51450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return true; 51460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 5147cad810f21b803229eb11403f9209855525a25d57Steve Block if (node()->isShadowRoot() && (node()->shadowHost()->hasTagName(inputTag))) 51480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return true; 51490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 51500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return false; 51518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 51528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5153a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::lineHeight(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const 51548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 51558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Inline blocks are replaced elements. Otherwise, just pass off to 51568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the base class. If we're being queried as though we're the root line 51578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // box, then the fact that we're an inline-block is irrelevant, and we behave 51588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // just like a block. 5159a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (isReplaced() && linePositionMode == PositionOnContainingLine) 5160a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return RenderBox::lineHeight(firstLine, direction, linePositionMode); 5161a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 51628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (firstLine && document()->usesFirstLineRules()) { 51638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderStyle* s = style(firstLine); 51648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (s != style()) 51658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return s->computedLineHeight(); 51668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 51678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 51688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (m_lineHeight == -1) 51698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_lineHeight = style()->computedLineHeight(); 51708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 51718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return m_lineHeight; 51728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 51738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 51746b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerint RenderBlock::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const 51758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 51768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Inline blocks are replaced elements. Otherwise, just pass off to 51778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the base class. If we're being queried as though we're the root line 51788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // box, then the fact that we're an inline-block is irrelevant, and we behave 51798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // just like a block. 5180a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (isReplaced() && linePositionMode == PositionOnContainingLine) { 51818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // For "leaf" theme objects, let the theme decide what the baseline position is. 51828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: Might be better to have a custom CSS property instead, so that if the theme 51838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // is turned off, checkboxes/radios will still have decent baselines. 5184a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // FIXME: Need to patch form controls to deal with vertical lines. 51858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->hasAppearance() && !theme()->isControlContainer(style()->appearance())) 51868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return theme()->baselinePosition(this); 51878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 51888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // CSS2.1 states that the baseline of an inline block is the baseline of the last line box in 51898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the normal flow. We make an exception for marquees, since their baselines are meaningless 51908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // (the content inside them moves). This matches WinIE as well, which just bottom-aligns them. 51918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We also give up on finding a baseline if we have a vertical scrollbar, or if we are scrolled 51928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // vertically (e.g., an overflow:hidden block that has had scrollTop moved) or if the baseline is outside 51938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // of our content box. 5194a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool ignoreBaseline = (layer() && (layer()->marquee() || (direction == HorizontalLine ? (layer()->verticalScrollbar() || layer()->scrollYOffset() != 0) 51956b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner : (layer()->horizontalScrollbar() || layer()->scrollXOffset() != 0)))) || (isWritingModeRoot() && !isRubyRun()); 51966b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 5197a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int baselinePos = ignoreBaseline ? -1 : lastLineBoxBaseline(); 5198a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 5199a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int bottomOfContent = direction == HorizontalLine ? borderTop() + paddingTop() + contentHeight() : borderRight() + paddingRight() + contentWidth(); 5200a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (baselinePos != -1 && baselinePos <= bottomOfContent) 5201a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return direction == HorizontalLine ? marginTop() + baselinePos : marginRight() + baselinePos; 5202a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 52036b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode); 52048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5205a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 52062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block const FontMetrics& fontMetrics = style(firstLine)->fontMetrics(); 52072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2; 52088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 52098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 52108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianint RenderBlock::firstLineBoxBaseline() const 52118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 52126b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (!isBlockFlow() || (isWritingModeRoot() && !isRubyRun())) 52138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return -1; 52148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 52158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (childrenInline()) { 52168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (firstLineBox()) 52172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return firstLineBox()->logicalTop() + style(true)->fontMetrics().ascent(firstRootBox()->baselineType()); 52188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 52198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return -1; 52208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 52218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 5222635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project for (RenderBox* curr = firstChildBox(); curr; curr = curr->nextSiblingBox()) { 52238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!curr->isFloatingOrPositioned()) { 52248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int result = curr->firstLineBoxBaseline(); 52258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (result != -1) 5226a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return curr->logicalTop() + result; // Translate to our coordinate space. 52278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 52288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 52298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 52308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 52318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return -1; 52328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 52338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 52348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianint RenderBlock::lastLineBoxBaseline() const 52358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 52366b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (!isBlockFlow() || (isWritingModeRoot() && !isRubyRun())) 52378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return -1; 52388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 52392bde8e466a4451c7319e3a072d118917957d6554Steve Block LineDirectionMode lineDirection = isHorizontalWritingMode() ? HorizontalLine : VerticalLine; 5240a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 52418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (childrenInline()) { 5242a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!firstLineBox() && hasLineIfEmpty()) { 52432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics(); 52442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return fontMetrics.ascent() 52452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2 52462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight()); 5247a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 52488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (lastLineBox()) 52492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->fontMetrics().ascent(lastRootBox()->baselineType()); 52508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return -1; 5251a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } else { 52528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool haveNormalFlowChild = false; 5253635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project for (RenderBox* curr = lastChildBox(); curr; curr = curr->previousSiblingBox()) { 52548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!curr->isFloatingOrPositioned()) { 52558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project haveNormalFlowChild = true; 52568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int result = curr->lastLineBoxBaseline(); 52578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (result != -1) 5258a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return curr->logicalTop() + result; // Translate to our coordinate space. 52598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 52608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5261a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!haveNormalFlowChild && 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 } 52688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 52698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return -1; 52708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 52718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5272635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool RenderBlock::containsNonZeroBidiLevel() const 5273635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 5274635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) { 5275635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project for (InlineBox* box = root->firstLeafChild(); box; box = box->nextLeafChild()) { 5276635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (box->bidiLevel()) 5277635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return true; 5278635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 5279635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 5280635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return false; 5281635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 5282635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 52838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderBlock* RenderBlock::firstLineBlock() const 52848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5285635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderBlock* firstLineBlock = const_cast<RenderBlock*>(this); 52868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool hasPseudo = false; 52878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (true) { 52888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian hasPseudo = firstLineBlock->style()->hasPseudoStyle(FIRST_LINE); 52898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (hasPseudo) 52908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 52918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* parentBlock = firstLineBlock->parent(); 52928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (firstLineBlock->isReplaced() || firstLineBlock->isFloating() || 52938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project !parentBlock || parentBlock->firstChild() != firstLineBlock || !parentBlock->isBlockFlow()) 52948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 5295635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(parentBlock->isRenderBlock()); 52968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian firstLineBlock = toRenderBlock(parentBlock); 52978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 52988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 52998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!hasPseudo) 53008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 53018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5302635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return firstLineBlock; 53038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 53048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 530568513a70bcd92384395513322f1b801e7bf9c729Steve Blockstatic RenderStyle* styleForFirstLetter(RenderObject* firstLetterBlock, RenderObject* firstLetterContainer) 530668513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 530768513a70bcd92384395513322f1b801e7bf9c729Steve Block RenderStyle* pseudoStyle = firstLetterBlock->getCachedPseudoStyle(FIRST_LETTER, firstLetterContainer->firstLineStyle()); 530868513a70bcd92384395513322f1b801e7bf9c729Steve Block // Force inline display (except for floating first-letters). 530968513a70bcd92384395513322f1b801e7bf9c729Steve Block pseudoStyle->setDisplay(pseudoStyle->isFloating() ? BLOCK : INLINE); 531068513a70bcd92384395513322f1b801e7bf9c729Steve Block // CSS2 says first-letter can't be positioned. 531168513a70bcd92384395513322f1b801e7bf9c729Steve Block pseudoStyle->setPosition(StaticPosition); 531268513a70bcd92384395513322f1b801e7bf9c729Steve Block return pseudoStyle; 531368513a70bcd92384395513322f1b801e7bf9c729Steve Block} 531468513a70bcd92384395513322f1b801e7bf9c729Steve Block 5315a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch// CSS 2.1 http://www.w3.org/TR/CSS21/selector.html#first-letter 5316a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch// "Punctuation (i.e, characters defined in Unicode [UNICODE] in the "open" (Ps), "close" (Pe), 5317a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch// "initial" (Pi). "final" (Pf) and "other" (Po) punctuation classes), that precedes or follows the first letter should be included" 5318a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic inline bool isPunctuationForFirstLetter(UChar c) 5319a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 5320a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch CharCategory charCategory = category(c); 5321a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return charCategory == Punctuation_Open 5322a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch || charCategory == Punctuation_Close 5323a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch || charCategory == Punctuation_InitialQuote 5324a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch || charCategory == Punctuation_FinalQuote 5325a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch || charCategory == Punctuation_Other; 5326a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 5327a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 5328a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic inline bool shouldSkipForFirstLetter(UChar c) 5329a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 5330a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return isSpaceOrNewline(c) || c == noBreakSpace || isPunctuationForFirstLetter(c); 5331a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 5332a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 53338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::updateFirstLetter() 53348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 53358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!document()->usesFirstLetterRules()) 53368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 53378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Don't recur 53388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (style()->styleType() == FIRST_LETTER) 53398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 53408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 53418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: We need to destroy the first-letter object if it is no longer the first child. Need to find 53428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // an efficient way to check for that situation though before implementing anything. 53438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* firstLetterBlock = this; 53448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool hasPseudoStyle = false; 53458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (true) { 53468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We only honor first-letter if the firstLetterBlock can have children in the DOM. This correctly 53478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // prevents form controls from honoring first-letter. 53488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian hasPseudoStyle = firstLetterBlock->style()->hasPseudoStyle(FIRST_LETTER) 53498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project && firstLetterBlock->canHaveChildren(); 53508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (hasPseudoStyle) 53518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 53528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* parentBlock = firstLetterBlock->parent(); 53538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (firstLetterBlock->isReplaced() || !parentBlock || parentBlock->firstChild() != firstLetterBlock || 53548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project !parentBlock->isBlockFlow()) 53558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 53568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project firstLetterBlock = parentBlock; 53578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 53588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 53598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!hasPseudoStyle) 53608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 53618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 53628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Drill into inlines looking for our first text child. 53638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* currChild = firstLetterBlock->firstChild(); 53646c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen while (currChild && ((!currChild->isReplaced() && !currChild->isRenderButton() && !currChild->isMenuList()) || currChild->isFloatingOrPositioned()) && !currChild->isText()) { 53658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (currChild->isFloatingOrPositioned()) { 53666c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (currChild->style()->styleType() == FIRST_LETTER) { 53676c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen currChild = currChild->firstChild(); 53688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 53696c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 53708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project currChild = currChild->nextSibling(); 53718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else 53728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project currChild = currChild->firstChild(); 53738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 53748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 53758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Get list markers out of the way. 53768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (currChild && currChild->isListMarker()) 53778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project currChild = currChild->nextSibling(); 53788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 53798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!currChild) 53808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 53818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 53828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the child already has style, then it has already been created, so we just want 53838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // to update it. 538468513a70bcd92384395513322f1b801e7bf9c729Steve Block if (currChild->parent()->style()->styleType() == FIRST_LETTER) { 538568513a70bcd92384395513322f1b801e7bf9c729Steve Block RenderObject* firstLetter = currChild->parent(); 538668513a70bcd92384395513322f1b801e7bf9c729Steve Block RenderObject* firstLetterContainer = firstLetter->parent(); 538768513a70bcd92384395513322f1b801e7bf9c729Steve Block RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer); 538868513a70bcd92384395513322f1b801e7bf9c729Steve Block 538968513a70bcd92384395513322f1b801e7bf9c729Steve Block if (Node::diff(firstLetter->style(), pseudoStyle) == Node::Detach) { 539068513a70bcd92384395513322f1b801e7bf9c729Steve Block // The first-letter renderer needs to be replaced. Create a new renderer of the right type. 539168513a70bcd92384395513322f1b801e7bf9c729Steve Block RenderObject* newFirstLetter; 539268513a70bcd92384395513322f1b801e7bf9c729Steve Block if (pseudoStyle->display() == INLINE) 539368513a70bcd92384395513322f1b801e7bf9c729Steve Block newFirstLetter = new (renderArena()) RenderInline(document()); 539468513a70bcd92384395513322f1b801e7bf9c729Steve Block else 539568513a70bcd92384395513322f1b801e7bf9c729Steve Block newFirstLetter = new (renderArena()) RenderBlock(document()); 539668513a70bcd92384395513322f1b801e7bf9c729Steve Block newFirstLetter->setStyle(pseudoStyle); 539768513a70bcd92384395513322f1b801e7bf9c729Steve Block 539868513a70bcd92384395513322f1b801e7bf9c729Steve Block // Move the first letter into the new renderer. 539968513a70bcd92384395513322f1b801e7bf9c729Steve Block view()->disableLayoutState(); 540068513a70bcd92384395513322f1b801e7bf9c729Steve Block while (RenderObject* child = firstLetter->firstChild()) { 540168513a70bcd92384395513322f1b801e7bf9c729Steve Block if (child->isText()) 54022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch toRenderText(child)->removeAndDestroyTextBoxes(); 540368513a70bcd92384395513322f1b801e7bf9c729Steve Block firstLetter->removeChild(child); 540468513a70bcd92384395513322f1b801e7bf9c729Steve Block newFirstLetter->addChild(child, 0); 540568513a70bcd92384395513322f1b801e7bf9c729Steve Block } 540681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 540781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch RenderTextFragment* remainingText = 0; 540881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch RenderObject* nextSibling = firstLetter->nextSibling(); 540981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch RenderObject* next = nextSibling; 541081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch while (next) { 541181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (next->isText() && toRenderText(next)->isTextFragment()) { 541281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch remainingText = toRenderTextFragment(next); 541381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch break; 541481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 541581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch next = next->nextSibling(); 541681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 541781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (remainingText) { 541881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ASSERT(remainingText->node()->renderer() == remainingText); 541981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // Replace the old renderer with the new one. 542081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch remainingText->setFirstLetter(newFirstLetter); 542181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 542268513a70bcd92384395513322f1b801e7bf9c729Steve Block firstLetter->destroy(); 542368513a70bcd92384395513322f1b801e7bf9c729Steve Block firstLetter = newFirstLetter; 542481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch firstLetterContainer->addChild(firstLetter, nextSibling); 542568513a70bcd92384395513322f1b801e7bf9c729Steve Block view()->enableLayoutState(); 542668513a70bcd92384395513322f1b801e7bf9c729Steve Block } else 542768513a70bcd92384395513322f1b801e7bf9c729Steve Block firstLetter->setStyle(pseudoStyle); 542868513a70bcd92384395513322f1b801e7bf9c729Steve Block 542968513a70bcd92384395513322f1b801e7bf9c729Steve Block for (RenderObject* genChild = firstLetter->firstChild(); genChild; genChild = genChild->nextSibling()) { 54308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (genChild->isText()) 543168513a70bcd92384395513322f1b801e7bf9c729Steve Block genChild->setStyle(pseudoStyle); 54328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 543368513a70bcd92384395513322f1b801e7bf9c729Steve Block 54348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 54358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 54368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 543768513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!currChild->isText() || currChild->isBR()) 543868513a70bcd92384395513322f1b801e7bf9c729Steve Block return; 543968513a70bcd92384395513322f1b801e7bf9c729Steve Block 54408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the child does not already have style, we create it here. 544168513a70bcd92384395513322f1b801e7bf9c729Steve Block RenderObject* firstLetterContainer = currChild->parent(); 54428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 544368513a70bcd92384395513322f1b801e7bf9c729Steve Block // Our layout state is not valid for the repaints we are going to trigger by 544468513a70bcd92384395513322f1b801e7bf9c729Steve Block // adding and removing children of firstLetterContainer. 544568513a70bcd92384395513322f1b801e7bf9c729Steve Block view()->disableLayoutState(); 544668513a70bcd92384395513322f1b801e7bf9c729Steve Block 544768513a70bcd92384395513322f1b801e7bf9c729Steve Block RenderText* textObj = toRenderText(currChild); 544868513a70bcd92384395513322f1b801e7bf9c729Steve Block 544968513a70bcd92384395513322f1b801e7bf9c729Steve Block // Create our pseudo style now that we have our firstLetterContainer determined. 545068513a70bcd92384395513322f1b801e7bf9c729Steve Block RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer); 545168513a70bcd92384395513322f1b801e7bf9c729Steve Block 545268513a70bcd92384395513322f1b801e7bf9c729Steve Block RenderObject* firstLetter = 0; 545368513a70bcd92384395513322f1b801e7bf9c729Steve Block if (pseudoStyle->display() == INLINE) 545468513a70bcd92384395513322f1b801e7bf9c729Steve Block firstLetter = new (renderArena()) RenderInline(document()); 545568513a70bcd92384395513322f1b801e7bf9c729Steve Block else 545668513a70bcd92384395513322f1b801e7bf9c729Steve Block firstLetter = new (renderArena()) RenderBlock(document()); 545768513a70bcd92384395513322f1b801e7bf9c729Steve Block firstLetter->setStyle(pseudoStyle); 545868513a70bcd92384395513322f1b801e7bf9c729Steve Block firstLetterContainer->addChild(firstLetter, currChild); 545968513a70bcd92384395513322f1b801e7bf9c729Steve Block 546068513a70bcd92384395513322f1b801e7bf9c729Steve Block // The original string is going to be either a generated content string or a DOM node's 546168513a70bcd92384395513322f1b801e7bf9c729Steve Block // string. We want the original string before it got transformed in case first-letter has 546268513a70bcd92384395513322f1b801e7bf9c729Steve Block // no text-transform or a different text-transform applied to it. 546368513a70bcd92384395513322f1b801e7bf9c729Steve Block RefPtr<StringImpl> oldText = textObj->originalText(); 546468513a70bcd92384395513322f1b801e7bf9c729Steve Block ASSERT(oldText); 546568513a70bcd92384395513322f1b801e7bf9c729Steve Block 546668513a70bcd92384395513322f1b801e7bf9c729Steve Block if (oldText && oldText->length() > 0) { 546768513a70bcd92384395513322f1b801e7bf9c729Steve Block unsigned length = 0; 546868513a70bcd92384395513322f1b801e7bf9c729Steve Block 5469a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // Account for leading spaces and punctuation. 5470a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch while (length < oldText->length() && shouldSkipForFirstLetter((*oldText)[length])) 54718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project length++; 54728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5473a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // Account for first letter. 547468513a70bcd92384395513322f1b801e7bf9c729Steve Block length++; 5475a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 5476a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // Keep looking for whitespace and allowed punctuation, but avoid 5477a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // accumulating just whitespace into the :first-letter. 5478a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch for (unsigned scanLength = length; scanLength < oldText->length(); ++scanLength) { 5479a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch UChar c = (*oldText)[scanLength]; 5480a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 5481a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!shouldSkipForFirstLetter(c)) 5482a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch break; 548368513a70bcd92384395513322f1b801e7bf9c729Steve Block 5484a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (isPunctuationForFirstLetter(c)) 5485a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch length = scanLength + 1; 5486a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 5487a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 5488a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // Construct a text fragment for the text after the first letter. 5489a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // This text fragment might be empty. 549068513a70bcd92384395513322f1b801e7bf9c729Steve Block RenderTextFragment* remainingText = 549168513a70bcd92384395513322f1b801e7bf9c729Steve Block new (renderArena()) RenderTextFragment(textObj->node() ? textObj->node() : textObj->document(), oldText.get(), length, oldText->length() - length); 549268513a70bcd92384395513322f1b801e7bf9c729Steve Block remainingText->setStyle(textObj->style()); 549368513a70bcd92384395513322f1b801e7bf9c729Steve Block if (remainingText->node()) 549468513a70bcd92384395513322f1b801e7bf9c729Steve Block remainingText->node()->setRenderer(remainingText); 549568513a70bcd92384395513322f1b801e7bf9c729Steve Block 5496ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch firstLetterContainer->addChild(remainingText, textObj); 549768513a70bcd92384395513322f1b801e7bf9c729Steve Block firstLetterContainer->removeChild(textObj); 549868513a70bcd92384395513322f1b801e7bf9c729Steve Block remainingText->setFirstLetter(firstLetter); 549968513a70bcd92384395513322f1b801e7bf9c729Steve Block 550068513a70bcd92384395513322f1b801e7bf9c729Steve Block // construct text fragment for the first letter 550168513a70bcd92384395513322f1b801e7bf9c729Steve Block RenderTextFragment* letter = 550268513a70bcd92384395513322f1b801e7bf9c729Steve Block new (renderArena()) RenderTextFragment(remainingText->node() ? remainingText->node() : remainingText->document(), oldText.get(), 0, length); 550368513a70bcd92384395513322f1b801e7bf9c729Steve Block letter->setStyle(pseudoStyle); 550468513a70bcd92384395513322f1b801e7bf9c729Steve Block firstLetter->addChild(letter); 550568513a70bcd92384395513322f1b801e7bf9c729Steve Block 550668513a70bcd92384395513322f1b801e7bf9c729Steve Block textObj->destroy(); 55078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 550868513a70bcd92384395513322f1b801e7bf9c729Steve Block view()->enableLayoutState(); 55098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 55108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 55118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Helper methods for obtaining the last line, computing line counts and heights for line counts 55128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// (crawling into blocks). 55138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool shouldCheckLines(RenderObject* obj) 55148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5515635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return !obj->isFloatingOrPositioned() && !obj->isRunIn() && 55168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project obj->isBlockFlow() && obj->style()->height().isAuto() && 55178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (!obj->isFlexibleBox() || obj->style()->boxOrient() == VERTICAL); 55188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 55198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 55208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic RootInlineBox* getLineAtIndex(RenderBlock* block, int i, int& count) 55218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 55228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (block->style()->visibility() == VISIBLE) { 55238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (block->childrenInline()) { 55248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) { 55258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (count++ == i) 55268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return box; 55278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 55288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 55298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 55308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RenderObject* obj = block->firstChild(); obj; obj = obj->nextSibling()) { 55318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (shouldCheckLines(obj)) { 55328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RootInlineBox *box = getLineAtIndex(toRenderBlock(obj), i, count); 55338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (box) 55348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return box; 55358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 55368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 55378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 55388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 55398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 55408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 55418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5542635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic int getHeightForLineCount(RenderBlock* block, int l, bool includeBottom, int& count) 55438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 55448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (block->style()->visibility() == VISIBLE) { 55458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (block->childrenInline()) { 55468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) { 55478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (++count == l) 5548231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return box->lineBottom() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : 0); 55498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 55508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 55518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 5552635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderBox* normalFlowChildWithoutLines = 0; 5553635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project for (RenderBox* obj = block->firstChildBox(); obj; obj = obj->nextSiblingBox()) { 55548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (shouldCheckLines(obj)) { 55558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int result = getHeightForLineCount(toRenderBlock(obj), l, false, count); 55568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (result != -1) 5557635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return result + obj->y() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : 0); 55588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5559635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project else if (!obj->isFloatingOrPositioned() && !obj->isRunIn()) 55608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project normalFlowChildWithoutLines = obj; 55618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 55628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (normalFlowChildWithoutLines && l == 0) 5563635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return normalFlowChildWithoutLines->y() + normalFlowChildWithoutLines->height(); 55648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 55658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 55668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 55678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return -1; 55688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 55698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 55708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRootInlineBox* RenderBlock::lineAtIndex(int i) 55718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 55728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int count = 0; 55738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return getLineAtIndex(this, i, count); 55748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 55758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 55768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderBlock::lineCount() 55778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 55788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int count = 0; 55798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->visibility() == VISIBLE) { 55808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (childrenInline()) 55818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) 55828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project count++; 55838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 55848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling()) 55858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (shouldCheckLines(obj)) 55868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian count += toRenderBlock(obj)->lineCount(); 55878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 55888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return count; 55898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 55908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 55918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderBlock::heightForLineCount(int l) 55928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 55938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int count = 0; 55948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return getHeightForLineCount(this, l, true, count); 55958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 55968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 55978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::adjustForBorderFit(int x, int& left, int& right) const 55988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 55998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We don't deal with relative positioning. Our assumption is that you shrink to fit the lines without accounting 56008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // for either overflow or translations via relative positioning. 56018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->visibility() == VISIBLE) { 56028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (childrenInline()) { 56038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) { 56048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (box->firstChild()) 560581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch left = min(left, x + static_cast<int>(box->firstChild()->x())); 56068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (box->lastChild()) 560781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch right = max(right, x + static_cast<int>(ceilf(box->lastChild()->logicalRight()))); 56088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 56098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 56108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 5611635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project for (RenderBox* obj = firstChildBox(); obj; obj = obj->nextSiblingBox()) { 56128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!obj->isFloatingOrPositioned()) { 56138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (obj->isBlockFlow() && !obj->hasOverflowClip()) 56148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian toRenderBlock(obj)->adjustForBorderFit(x + obj->x(), left, right); 56158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else if (obj->style()->visibility() == VISIBLE) { 56168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We are a replaced element or some kind of non-block-flow object. 5617635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project left = min(left, x + obj->x()); 5618635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project right = max(right, x + obj->x() + obj->width()); 56198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 56208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 56218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 56228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 56238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 56248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_floatingObjects) { 562581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 562681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator end = floatingObjectSet.end(); 562781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) { 562881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* r = *it; 56298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Only examine the object if our m_shouldPaint flag is set. 56308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (r->m_shouldPaint) { 56312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int floatLeft = xPositionForFloatIncludingMargin(r) - r->m_renderer->x(); 56328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int floatRight = floatLeft + r->m_renderer->width(); 56338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project left = min(left, floatLeft); 56348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project right = max(right, floatRight); 56358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 56368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 56378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 56388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 56398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 56408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 56418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::borderFitAdjust(int& x, int& w) const 56428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 56438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->borderFit() == BorderFitBorder) 56448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 56458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 56468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Walk any normal flow lines to snugly fit. 56478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int left = INT_MAX; 56488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int right = INT_MIN; 56498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int oldWidth = w; 56508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project adjustForBorderFit(0, left, right); 56518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (left != INT_MAX) { 56528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project left -= (borderLeft() + paddingLeft()); 56538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (left > 0) { 56548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project x += left; 56558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project w -= left; 56568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 56578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 56588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (right != INT_MIN) { 56598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project right += (borderRight() + paddingRight()); 56608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (right < oldWidth) 56618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project w -= (oldWidth - right); 56628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 56638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 56648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 56658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::clearTruncation() 56668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 56678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->visibility() == VISIBLE) { 56688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (childrenInline() && hasMarkupTruncation()) { 56698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project setHasMarkupTruncation(false); 56708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) 56718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project box->clearTruncation(); 56728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 56738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 56748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling()) 56758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (shouldCheckLines(obj)) 56768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian toRenderBlock(obj)->clearTruncation(); 56778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 56788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 56798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5680bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBlock::setMaxMarginBeforeValues(int pos, int neg) 56818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 568268513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!m_rareData) { 5683a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (pos == RenderBlockRareData::positiveMarginBeforeDefault(this) && neg == RenderBlockRareData::negativeMarginBeforeDefault(this)) 56848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 568568513a70bcd92384395513322f1b801e7bf9c729Steve Block m_rareData = new RenderBlockRareData(this); 56868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5687a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_rareData->m_margins.setPositiveMarginBefore(pos); 5688a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_rareData->m_margins.setNegativeMarginBefore(neg); 56898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 56908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5691bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBlock::setMaxMarginAfterValues(int pos, int neg) 56928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 569368513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!m_rareData) { 5694a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (pos == RenderBlockRareData::positiveMarginAfterDefault(this) && neg == RenderBlockRareData::negativeMarginAfterDefault(this)) 569568513a70bcd92384395513322f1b801e7bf9c729Steve Block return; 569668513a70bcd92384395513322f1b801e7bf9c729Steve Block m_rareData = new RenderBlockRareData(this); 569768513a70bcd92384395513322f1b801e7bf9c729Steve Block } 5698a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_rareData->m_margins.setPositiveMarginAfter(pos); 5699a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_rareData->m_margins.setNegativeMarginAfter(neg); 570068513a70bcd92384395513322f1b801e7bf9c729Steve Block} 570168513a70bcd92384395513322f1b801e7bf9c729Steve Block 570268513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid RenderBlock::setPaginationStrut(int strut) 570368513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 570468513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!m_rareData) { 570568513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!strut) 57068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 570768513a70bcd92384395513322f1b801e7bf9c729Steve Block m_rareData = new RenderBlockRareData(this); 57088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 570968513a70bcd92384395513322f1b801e7bf9c729Steve Block m_rareData->m_paginationStrut = strut; 571068513a70bcd92384395513322f1b801e7bf9c729Steve Block} 571168513a70bcd92384395513322f1b801e7bf9c729Steve Block 5712f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderBlock::setPageLogicalOffset(int logicalOffset) 571368513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 571468513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!m_rareData) { 5715f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!logicalOffset) 571668513a70bcd92384395513322f1b801e7bf9c729Steve Block return; 571768513a70bcd92384395513322f1b801e7bf9c729Steve Block m_rareData = new RenderBlockRareData(this); 571868513a70bcd92384395513322f1b801e7bf9c729Steve Block } 5719f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_rareData->m_pageLogicalOffset = logicalOffset; 57208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 57218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 57225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid RenderBlock::absoluteRects(Vector<IntRect>& rects, int tx, int ty) 57238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 57248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // For blocks inside inlines, we go ahead and include margins so that we run right up to the 57258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // inline boxes above and below us (thus getting merged with them to form a single irregular 57268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // shape). 5727e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (isAnonymousBlockContinuation()) { 5728bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // FIXME: This is wrong for block-flows that are horizontal. 5729bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // https://bugs.webkit.org/show_bug.cgi?id=46781 5730bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen rects.append(IntRect(tx, ty - collapsedMarginBefore(), 5731bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen width(), height() + collapsedMarginBefore() + collapsedMarginAfter())); 5732e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block continuation()->absoluteRects(rects, 5733e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block tx - x() + inlineElementContinuation()->containingBlock()->x(), 5734e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ty - y() + inlineElementContinuation()->containingBlock()->y()); 57358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } else 57368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian rects.append(IntRect(tx, ty, width(), height())); 57378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 57388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 57395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid RenderBlock::absoluteQuads(Vector<FloatQuad>& quads) 57408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 57418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // For blocks inside inlines, we go ahead and include margins so that we run right up to the 57428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // inline boxes above and below us (thus getting merged with them to form a single irregular 57438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // shape). 5744e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (isAnonymousBlockContinuation()) { 5745bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // FIXME: This is wrong for block-flows that are horizontal. 5746bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // https://bugs.webkit.org/show_bug.cgi?id=46781 5747bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen FloatRect localRect(0, -collapsedMarginBefore(), 5748bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen width(), height() + collapsedMarginBefore() + collapsedMarginAfter()); 57498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian quads.append(localToAbsoluteQuad(localRect)); 5750e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block continuation()->absoluteQuads(quads); 57518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } else 57528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width(), height()))); 57538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 57548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 57558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianIntRect RenderBlock::rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth) 57568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 57578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian IntRect r(RenderBox::rectWithOutlineForRepaint(repaintContainer, outlineWidth)); 5758e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (isAnonymousBlockContinuation()) 5759bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen r.inflateY(collapsedMarginBefore()); // FIXME: This is wrong for block-flows that are horizontal. 57608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return r; 57618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 57628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 57638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianRenderObject* RenderBlock::hoverAncestor() const 57648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 5765e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block return isAnonymousBlockContinuation() ? continuation() : RenderBox::hoverAncestor(); 57668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 57678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 57688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::updateDragState(bool dragOn) 57698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 57708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderBox::updateDragState(dragOn); 5771e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (continuation()) 5772e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block continuation()->updateDragState(dragOn); 57738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 57748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 57758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianRenderStyle* RenderBlock::outlineStyleForRepaint() const 57768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 5777e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block return isAnonymousBlockContinuation() ? continuation()->style() : style(); 57788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 57798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 57808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::childBecameNonInline(RenderObject*) 57818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 57828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian makeChildrenNonInline(); 57838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (isAnonymousBlock() && parent() && parent()->isRenderBlock()) 57848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian toRenderBlock(parent())->removeLeftoverAnonymousBlock(this); 57858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // |this| may be dead here 57868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 57878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 57888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBlock::updateHitTestResult(HitTestResult& result, const IntPoint& point) 57898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 57908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (result.innerNode()) 57918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return; 57928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 57938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Node* n = node(); 5794e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (isAnonymousBlockContinuation()) 57958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // We are in the margins of block elements that are part of a continuation. In 5796e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block // this case we're actually still inside the enclosing element that was 57978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // split. Go ahead and set our inner node accordingly. 5798e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block n = continuation()->node(); 57998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 58008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (n) { 58018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian result.setInnerNode(n); 58028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!result.innerNonSharedNode()) 58038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian result.setInnerNonSharedNode(n); 58048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian result.setLocalPoint(point); 58058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 58068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 58078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 58088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianIntRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, int* extraWidthToEndOfLine) 58098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 58108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Do the normal calculation in most cases. 58118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (firstChild()) 58128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return RenderBox::localCaretRect(inlineBox, caretOffset, extraWidthToEndOfLine); 58138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 58148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // This is a special case: 58158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // The element is not an inline element, and it's empty. So we have to 58168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // calculate a fake position to indicate where objects are to be inserted. 58178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 58188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // FIXME: This does not take into account either :first-line or :first-letter 58198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // However, as soon as some content is entered, the line boxes will be 58208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // constructed and this kludge is not called any more. So only the caret size 58218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // of an empty :first-line'd block is wrong. I think we can live with that. 58228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderStyle* currentStyle = firstLineStyle(); 5823a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int height = lineHeight(true, currentStyle->isHorizontalWritingMode() ? HorizontalLine : VerticalLine); 58248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 58258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian enum CaretAlignment { alignLeft, alignRight, alignCenter }; 58268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 58278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian CaretAlignment alignment = alignLeft; 58288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 58298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian switch (currentStyle->textAlign()) { 58308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian case TAAUTO: 58318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian case JUSTIFY: 5832a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!currentStyle->isLeftToRightDirection()) 58338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian alignment = alignRight; 58348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian break; 58358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian case LEFT: 58368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian case WEBKIT_LEFT: 58378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian break; 58388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian case CENTER: 58398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian case WEBKIT_CENTER: 58408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian alignment = alignCenter; 58418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian break; 58428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian case RIGHT: 58438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian case WEBKIT_RIGHT: 58448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian alignment = alignRight; 58458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian break; 58462bde8e466a4451c7319e3a072d118917957d6554Steve Block case TASTART: 58472bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!currentStyle->isLeftToRightDirection()) 58482bde8e466a4451c7319e3a072d118917957d6554Steve Block alignment = alignRight; 58492bde8e466a4451c7319e3a072d118917957d6554Steve Block break; 58502bde8e466a4451c7319e3a072d118917957d6554Steve Block case TAEND: 58512bde8e466a4451c7319e3a072d118917957d6554Steve Block if (currentStyle->isLeftToRightDirection()) 58522bde8e466a4451c7319e3a072d118917957d6554Steve Block alignment = alignRight; 58532bde8e466a4451c7319e3a072d118917957d6554Steve Block break; 58548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 58558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 58568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int x = borderLeft() + paddingLeft(); 58578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int w = width(); 58588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 58598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian switch (alignment) { 58608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian case alignLeft: 58618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian break; 58628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian case alignCenter: 58638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian x = (x + w - (borderRight() + paddingRight())) / 2; 58648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian break; 58658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian case alignRight: 58665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian x = w - (borderRight() + paddingRight()) - caretWidth; 58678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian break; 58688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 58698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 58708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (extraWidthToEndOfLine) { 58718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (isRenderBlock()) { 58728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian *extraWidthToEndOfLine = w - (x + caretWidth); 58738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } else { 58748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // FIXME: This code looks wrong. 58758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // myRight and containerRight are set up, but then clobbered. 58768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // So *extraWidthToEndOfLine will always be 0 here. 58778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 58788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int myRight = x + caretWidth; 58798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // FIXME: why call localToAbsoluteForContent() twice here, too? 58808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian FloatPoint absRightPoint = localToAbsolute(FloatPoint(myRight, 0)); 58818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 5882bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int containerRight = containingBlock()->x() + containingBlockLogicalWidthForContent(); 58838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian FloatPoint absContainerPoint = localToAbsolute(FloatPoint(containerRight, 0)); 58848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 58858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian *extraWidthToEndOfLine = absContainerPoint.x() - absRightPoint.x(); 58868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 58878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 58888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 58898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int y = paddingTop() + borderTop(); 58908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 58918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return IntRect(x, y, caretWidth, height); 58928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 58938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 5894d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid RenderBlock::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty) 58958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 58968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // For blocks inside inlines, we go ahead and include margins so that we run right up to the 58978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // inline boxes above and below us (thus getting merged with them to form a single irregular 58988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // shape). 5899e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (inlineElementContinuation()) { 59008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // FIXME: This check really isn't accurate. 5901e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block bool nextInlineHasLineBox = inlineElementContinuation()->firstLineBox(); 59028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // FIXME: This is wrong. The principal renderer may not be the continuation preceding this block. 5903bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // FIXME: This is wrong for block-flows that are horizontal. 5904bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // https://bugs.webkit.org/show_bug.cgi?id=46781 5905e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block bool prevInlineHasLineBox = toRenderInline(inlineElementContinuation()->node()->renderer())->firstLineBox(); 5906bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int topMargin = prevInlineHasLineBox ? collapsedMarginBefore() : 0; 5907bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int bottomMargin = nextInlineHasLineBox ? collapsedMarginAfter() : 0; 5908d0825bca7fe65beaee391d30da42e937db621564Steve Block IntRect rect(tx, ty - topMargin, width(), height() + topMargin + bottomMargin); 5909d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!rect.isEmpty()) 5910d0825bca7fe65beaee391d30da42e937db621564Steve Block rects.append(rect); 5911d0825bca7fe65beaee391d30da42e937db621564Steve Block } else if (width() && height()) 5912d0825bca7fe65beaee391d30da42e937db621564Steve Block rects.append(IntRect(tx, ty, width(), height())); 59138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 59148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!hasOverflowClip() && !hasControlClip()) { 5915231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) { 591681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch int top = max(curr->lineTop(), curr->logicalTop()); 591781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch int bottom = min(curr->lineBottom(), curr->logicalTop() + curr->logicalHeight()); 5918bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen IntRect rect(tx + curr->x(), ty + top, curr->logicalWidth(), bottom - top); 5919d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!rect.isEmpty()) 5920d0825bca7fe65beaee391d30da42e937db621564Steve Block rects.append(rect); 5921231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 59228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 59238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) { 59248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!curr->isText() && !curr->isListMarker() && curr->isBox()) { 59258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderBox* box = toRenderBox(curr); 59268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian FloatPoint pos; 59278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // FIXME: This doesn't work correctly with transforms. 59288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (box->layer()) 59298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian pos = curr->localToAbsolute(); 59308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian else 59318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian pos = FloatPoint(tx + box->x(), ty + box->y()); 5932d0825bca7fe65beaee391d30da42e937db621564Steve Block box->addFocusRingRects(rects, pos.x(), pos.y()); 59338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 59348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 59358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 59368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 5937e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (inlineElementContinuation()) 5938e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block inlineElementContinuation()->addFocusRingRects(rects, 5939e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block tx - x() + inlineElementContinuation()->containingBlock()->x(), 5940e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ty - y() + inlineElementContinuation()->containingBlock()->y()); 59418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 59428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 5943231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockRenderBlock* RenderBlock::createAnonymousBlock(bool isFlexibleBox) const 59448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 59452bde8e466a4451c7319e3a072d118917957d6554Steve Block RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style()); 59468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 5947231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block RenderBlock* newBox = 0; 5948231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (isFlexibleBox) { 5949231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block newStyle->setDisplay(BOX); 5950231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block newBox = new (renderArena()) RenderFlexibleBox(document() /* anonymous box */); 5951231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } else { 5952231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block newStyle->setDisplay(BLOCK); 5953231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block newBox = new (renderArena()) RenderBlock(document() /* anonymous box */); 5954231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 5955231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 59568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian newBox->setStyle(newStyle.release()); 59578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return newBox; 59588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 59598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 59605af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeRenderBlock* RenderBlock::createAnonymousBlockWithSameTypeAs(RenderBlock* otherAnonymousBlock) const 59615af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 59625af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (otherAnonymousBlock->isAnonymousColumnsBlock()) 59635af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return createAnonymousColumnsBlock(); 59645af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (otherAnonymousBlock->isAnonymousColumnSpanBlock()) 59655af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return createAnonymousColumnSpanBlock(); 59665af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return createAnonymousBlock(otherAnonymousBlock->style()->display() == BOX); 59675af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 59685af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 59695af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeRenderBlock* RenderBlock::createAnonymousColumnsBlock() const 59705af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 59712bde8e466a4451c7319e3a072d118917957d6554Steve Block RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style()); 59725af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newStyle->inheritColumnPropertiesFrom(style()); 59735af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newStyle->setDisplay(BLOCK); 59745af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 59755af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */); 59765af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newBox->setStyle(newStyle.release()); 59775af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return newBox; 59785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 59795af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 59805af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeRenderBlock* RenderBlock::createAnonymousColumnSpanBlock() const 59815af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 59822bde8e466a4451c7319e3a072d118917957d6554Steve Block RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style()); 59835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newStyle->setColumnSpan(true); 59845af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newStyle->setDisplay(BLOCK); 59855af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 59865af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */); 59875af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newBox->setStyle(newStyle.release()); 59885af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return newBox; 59895af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 59905af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 59912fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockint RenderBlock::nextPageLogicalTop(int logicalOffset) const 599268513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 599368513a70bcd92384395513322f1b801e7bf9c729Steve Block LayoutState* layoutState = view()->layoutState(); 5994f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!layoutState->m_pageLogicalHeight) 59952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return logicalOffset; 599668513a70bcd92384395513322f1b801e7bf9c729Steve Block 59972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // The logicalOffset is in our coordinate space. We can add in our pushed offset. 5998f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch int pageLogicalHeight = layoutState->m_pageLogicalHeight; 59992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset; 60002bde8e466a4451c7319e3a072d118917957d6554Steve Block int offset = isHorizontalWritingMode() ? delta.height() : delta.width(); 60012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight; 60022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return logicalOffset + remainingLogicalHeight; 600368513a70bcd92384395513322f1b801e7bf9c729Steve Block} 600468513a70bcd92384395513322f1b801e7bf9c729Steve Block 600568513a70bcd92384395513322f1b801e7bf9c729Steve Blockstatic bool inNormalFlow(RenderBox* child) 600668513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 600768513a70bcd92384395513322f1b801e7bf9c729Steve Block RenderBlock* curr = child->containingBlock(); 600868513a70bcd92384395513322f1b801e7bf9c729Steve Block RenderBlock* initialBlock = child->view(); 600968513a70bcd92384395513322f1b801e7bf9c729Steve Block while (curr && curr != initialBlock) { 601068513a70bcd92384395513322f1b801e7bf9c729Steve Block if (curr->hasColumns()) 601168513a70bcd92384395513322f1b801e7bf9c729Steve Block return true; 601268513a70bcd92384395513322f1b801e7bf9c729Steve Block if (curr->isFloatingOrPositioned()) 601368513a70bcd92384395513322f1b801e7bf9c729Steve Block return false; 601468513a70bcd92384395513322f1b801e7bf9c729Steve Block curr = curr->containingBlock(); 601568513a70bcd92384395513322f1b801e7bf9c729Steve Block } 601668513a70bcd92384395513322f1b801e7bf9c729Steve Block return true; 601768513a70bcd92384395513322f1b801e7bf9c729Steve Block} 601868513a70bcd92384395513322f1b801e7bf9c729Steve Block 60192fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockint RenderBlock::applyBeforeBreak(RenderBox* child, int logicalOffset) 602068513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 602168513a70bcd92384395513322f1b801e7bf9c729Steve Block // FIXME: Add page break checking here when we support printing. 602268513a70bcd92384395513322f1b801e7bf9c729Steve Block bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns(); 6023f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this. 602468513a70bcd92384395513322f1b801e7bf9c729Steve Block bool checkBeforeAlways = (checkColumnBreaks && child->style()->columnBreakBefore() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakBefore() == PBALWAYS); 602568513a70bcd92384395513322f1b801e7bf9c729Steve Block if (checkBeforeAlways && inNormalFlow(child)) { 602668513a70bcd92384395513322f1b801e7bf9c729Steve Block if (checkColumnBreaks) 60272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block view()->layoutState()->addForcedColumnBreak(logicalOffset); 60282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return nextPageLogicalTop(logicalOffset); 602968513a70bcd92384395513322f1b801e7bf9c729Steve Block } 60302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return logicalOffset; 603168513a70bcd92384395513322f1b801e7bf9c729Steve Block} 603268513a70bcd92384395513322f1b801e7bf9c729Steve Block 60332fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockint RenderBlock::applyAfterBreak(RenderBox* child, int logicalOffset, MarginInfo& marginInfo) 603468513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 603568513a70bcd92384395513322f1b801e7bf9c729Steve Block // FIXME: Add page break checking here when we support printing. 603668513a70bcd92384395513322f1b801e7bf9c729Steve Block bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns(); 6037f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this. 603868513a70bcd92384395513322f1b801e7bf9c729Steve Block bool checkAfterAlways = (checkColumnBreaks && child->style()->columnBreakAfter() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakAfter() == PBALWAYS); 603968513a70bcd92384395513322f1b801e7bf9c729Steve Block if (checkAfterAlways && inNormalFlow(child)) { 6040bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen marginInfo.setMarginAfterQuirk(true); // Cause margins to be discarded for any following content. 604168513a70bcd92384395513322f1b801e7bf9c729Steve Block if (checkColumnBreaks) 60422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block view()->layoutState()->addForcedColumnBreak(logicalOffset); 60432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return nextPageLogicalTop(logicalOffset); 604468513a70bcd92384395513322f1b801e7bf9c729Steve Block } 60452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return logicalOffset; 604668513a70bcd92384395513322f1b801e7bf9c729Steve Block} 604768513a70bcd92384395513322f1b801e7bf9c729Steve Block 60482fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockint RenderBlock::adjustForUnsplittableChild(RenderBox* child, int logicalOffset, bool includeMargins) 604968513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 605068513a70bcd92384395513322f1b801e7bf9c729Steve Block bool isUnsplittable = child->isReplaced() || child->scrollsOverflow(); 605168513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!isUnsplittable) 60522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return logicalOffset; 60532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int childLogicalHeight = logicalHeightForChild(child) + (includeMargins ? marginBeforeForChild(child) + marginAfterForChild(child) : 0); 605468513a70bcd92384395513322f1b801e7bf9c729Steve Block LayoutState* layoutState = view()->layoutState(); 605568513a70bcd92384395513322f1b801e7bf9c729Steve Block if (layoutState->m_columnInfo) 60562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block layoutState->m_columnInfo->updateMinimumColumnHeight(childLogicalHeight); 6057f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch int pageLogicalHeight = layoutState->m_pageLogicalHeight; 60582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!pageLogicalHeight || childLogicalHeight > pageLogicalHeight) 60592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return logicalOffset; 60602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset; 60612bde8e466a4451c7319e3a072d118917957d6554Steve Block int offset = isHorizontalWritingMode() ? delta.height() : delta.width(); 60622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight; 60632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (remainingLogicalHeight < childLogicalHeight) 60642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return logicalOffset + remainingLogicalHeight; 60652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return logicalOffset; 606668513a70bcd92384395513322f1b801e7bf9c729Steve Block} 606768513a70bcd92384395513322f1b801e7bf9c729Steve Block 606868513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, int& delta) 606968513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 607068513a70bcd92384395513322f1b801e7bf9c729Steve Block // FIXME: For now we paginate using line overflow. This ensures that lines don't overlap at all when we 607168513a70bcd92384395513322f1b801e7bf9c729Steve Block // put a strut between them for pagination purposes. However, this really isn't the desired rendering, since 607268513a70bcd92384395513322f1b801e7bf9c729Steve 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 607368513a70bcd92384395513322f1b801e7bf9c729Steve Block // of the first column. 607468513a70bcd92384395513322f1b801e7bf9c729Steve Block // 607568513a70bcd92384395513322f1b801e7bf9c729Steve Block // The rendering we would like to see is one where the lineTop is at the top of the column, and any line overflow 607668513a70bcd92384395513322f1b801e7bf9c729Steve Block // simply spills out above the top of the column. This effect would match what happens at the top of the first column. 607768513a70bcd92384395513322f1b801e7bf9c729Steve Block // We can't achieve this rendering, however, until we stop columns from clipping to the column bounds (thus allowing 607868513a70bcd92384395513322f1b801e7bf9c729Steve Block // for overflow to occur), and then cache visible overflow for each column rect. 607968513a70bcd92384395513322f1b801e7bf9c729Steve Block // 608068513a70bcd92384395513322f1b801e7bf9c729Steve Block // Furthermore, the paint we have to do when a column has overflow has to be special. We need to exclude 608168513a70bcd92384395513322f1b801e7bf9c729Steve Block // content that paints in a previous column (and content that paints in the following column). 608268513a70bcd92384395513322f1b801e7bf9c729Steve Block // 608368513a70bcd92384395513322f1b801e7bf9c729Steve Block // FIXME: Another problem with simply moving lines is that the available line width may change (because of floats). 608468513a70bcd92384395513322f1b801e7bf9c729Steve 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 608568513a70bcd92384395513322f1b801e7bf9c729Steve Block // line and all following lines. 608668513a70bcd92384395513322f1b801e7bf9c729Steve Block LayoutState* layoutState = view()->layoutState(); 6087f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch int pageLogicalHeight = layoutState->m_pageLogicalHeight; 60882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch IntRect logicalVisualOverflow = lineBox->logicalVisualOverflowRect(lineBox->lineTop(), lineBox->lineBottom()); 60892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int logicalOffset = logicalVisualOverflow.y(); 60902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int lineHeight = logicalVisualOverflow.maxY() - logicalOffset; 609168513a70bcd92384395513322f1b801e7bf9c729Steve Block if (layoutState->m_columnInfo) 609268513a70bcd92384395513322f1b801e7bf9c729Steve Block layoutState->m_columnInfo->updateMinimumColumnHeight(lineHeight); 60932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block logicalOffset += delta; 609468513a70bcd92384395513322f1b801e7bf9c729Steve Block lineBox->setPaginationStrut(0); 6095f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!pageLogicalHeight || lineHeight > pageLogicalHeight) 609668513a70bcd92384395513322f1b801e7bf9c729Steve Block return; 60972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block IntSize offsetDelta = layoutState->m_layoutOffset - layoutState->m_pageOffset; 60982bde8e466a4451c7319e3a072d118917957d6554Steve Block int offset = isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width(); 60992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int remainingLogicalHeight = pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight; 61002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (remainingLogicalHeight < lineHeight) { 61012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int totalLogicalHeight = lineHeight + max(0, logicalOffset); 61022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (lineBox == firstRootBox() && totalLogicalHeight < pageLogicalHeight && !isPositioned() && !isTableCell()) 61032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block setPaginationStrut(remainingLogicalHeight + max(0, logicalOffset)); 610468513a70bcd92384395513322f1b801e7bf9c729Steve Block else { 61052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block delta += remainingLogicalHeight; 61062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block lineBox->setPaginationStrut(remainingLogicalHeight); 610768513a70bcd92384395513322f1b801e7bf9c729Steve Block } 610868513a70bcd92384395513322f1b801e7bf9c729Steve Block } 610968513a70bcd92384395513322f1b801e7bf9c729Steve Block} 6110a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 6111a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::collapsedMarginBeforeForChild(RenderBox* child) const 6112a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 6113a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // If the child has the same directionality as we do, then we can just return its 6114a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // collapsed margin. 6115a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!child->isWritingModeRoot()) 6116a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return child->collapsedMarginBefore(); 6117a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 6118a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // The child has a different directionality. If the child is parallel, then it's just 6119a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // flipped relative to us. We can use the collapsed margin for the opposite edge. 61202bde8e466a4451c7319e3a072d118917957d6554Steve Block if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) 6121a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return child->collapsedMarginAfter(); 6122a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 6123a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // The child is perpendicular to us, which means its margins don't collapse but are on the 6124a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // "logical left/right" sides of the child box. We can just return the raw margin in this case. 6125a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return marginBeforeForChild(child); 6126a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 6127a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 6128a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::collapsedMarginAfterForChild(RenderBox* child) const 6129a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 6130a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // If the child has the same directionality as we do, then we can just return its 6131a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // collapsed margin. 6132a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!child->isWritingModeRoot()) 6133a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return child->collapsedMarginAfter(); 6134a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 6135a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // The child has a different directionality. If the child is parallel, then it's just 6136a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // flipped relative to us. We can use the collapsed margin for the opposite edge. 61372bde8e466a4451c7319e3a072d118917957d6554Steve Block if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) 6138a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return child->collapsedMarginBefore(); 6139a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 6140a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // The child is perpendicular to us, which means its margins don't collapse but are on the 6141a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // "logical left/right" side of the child box. We can just return the raw margin in this case. 6142a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return marginAfterForChild(child); 6143a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 6144a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 6145a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::marginBeforeForChild(RenderBoxModelObject* child) const 6146a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 6147a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch switch (style()->writingMode()) { 6148a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case TopToBottomWritingMode: 6149a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return child->marginTop(); 6150a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case BottomToTopWritingMode: 6151a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return child->marginBottom(); 6152a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case LeftToRightWritingMode: 6153a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return child->marginLeft(); 6154a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case RightToLeftWritingMode: 6155a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return child->marginRight(); 6156a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 6157a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT_NOT_REACHED(); 6158a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return child->marginTop(); 6159a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 6160a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 6161a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::marginAfterForChild(RenderBoxModelObject* child) const 6162a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 6163a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch switch (style()->writingMode()) { 6164a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case TopToBottomWritingMode: 6165a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return child->marginBottom(); 6166a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case BottomToTopWritingMode: 6167a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return child->marginTop(); 6168a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case LeftToRightWritingMode: 6169a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return child->marginRight(); 6170a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case RightToLeftWritingMode: 6171a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return child->marginLeft(); 6172a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 6173a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT_NOT_REACHED(); 6174a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return child->marginBottom(); 6175a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 6176a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 6177a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::marginStartForChild(RenderBoxModelObject* child) const 6178a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 61792bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isHorizontalWritingMode()) 6180a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return style()->isLeftToRightDirection() ? child->marginLeft() : child->marginRight(); 6181a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return style()->isLeftToRightDirection() ? child->marginTop() : child->marginBottom(); 6182a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 6183a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 6184a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBlock::marginEndForChild(RenderBoxModelObject* child) const 6185a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 61862bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isHorizontalWritingMode()) 6187a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return style()->isLeftToRightDirection() ? child->marginRight() : child->marginLeft(); 6188a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return style()->isLeftToRightDirection() ? child->marginBottom() : child->marginTop(); 6189a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 6190a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 6191a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setMarginStartForChild(RenderBox* child, int margin) 6192a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 61932bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isHorizontalWritingMode()) { 6194a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (style()->isLeftToRightDirection()) 6195a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->setMarginLeft(margin); 6196a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch else 6197a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->setMarginRight(margin); 6198a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } else { 6199a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (style()->isLeftToRightDirection()) 6200a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->setMarginTop(margin); 6201a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch else 6202a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->setMarginBottom(margin); 6203a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 6204a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 6205a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 6206a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setMarginEndForChild(RenderBox* child, int margin) 6207a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 62082bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isHorizontalWritingMode()) { 6209a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (style()->isLeftToRightDirection()) 6210a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->setMarginRight(margin); 6211a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch else 6212a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->setMarginLeft(margin); 6213a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } else { 6214a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (style()->isLeftToRightDirection()) 6215a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->setMarginBottom(margin); 6216a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch else 6217a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->setMarginTop(margin); 6218a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 6219a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 6220a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 6221a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setMarginBeforeForChild(RenderBox* child, int margin) 6222a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 6223a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch switch (style()->writingMode()) { 6224a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case TopToBottomWritingMode: 6225a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->setMarginTop(margin); 6226a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch break; 6227a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case BottomToTopWritingMode: 6228a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->setMarginBottom(margin); 6229a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch break; 6230a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case LeftToRightWritingMode: 6231a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->setMarginLeft(margin); 6232a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch break; 6233a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case RightToLeftWritingMode: 6234a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->setMarginRight(margin); 6235a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch break; 6236a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 6237a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 6238a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 6239a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::setMarginAfterForChild(RenderBox* child, int margin) 6240a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 6241a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch switch (style()->writingMode()) { 6242a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case TopToBottomWritingMode: 6243a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->setMarginBottom(margin); 6244a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch break; 6245a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case BottomToTopWritingMode: 6246a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->setMarginTop(margin); 6247a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch break; 6248a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case LeftToRightWritingMode: 6249a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->setMarginRight(margin); 6250a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch break; 6251a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case RightToLeftWritingMode: 6252a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch child->setMarginLeft(margin); 6253a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch break; 6254a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 6255a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 6256a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 6257a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochRenderBlock::MarginValues RenderBlock::marginValuesForChild(RenderBox* child) 6258a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 6259a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int childBeforePositive = 0; 6260a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int childBeforeNegative = 0; 6261a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int childAfterPositive = 0; 6262a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int childAfterNegative = 0; 6263a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 6264a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int beforeMargin = 0; 6265a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int afterMargin = 0; 6266a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 6267a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0; 6268a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 6269a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // If the child has the same directionality as we do, then we can just return its 6270a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // margins in the same direction. 6271a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!child->isWritingModeRoot()) { 6272a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (childRenderBlock) { 6273a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch childBeforePositive = childRenderBlock->maxPositiveMarginBefore(); 6274a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch childBeforeNegative = childRenderBlock->maxNegativeMarginBefore(); 6275a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch childAfterPositive = childRenderBlock->maxPositiveMarginAfter(); 6276a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch childAfterNegative = childRenderBlock->maxNegativeMarginAfter(); 6277a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } else { 6278a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch beforeMargin = child->marginBefore(); 6279a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch afterMargin = child->marginAfter(); 6280a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 62812bde8e466a4451c7319e3a072d118917957d6554Steve Block } else if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) { 6282a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // The child has a different directionality. If the child is parallel, then it's just 6283a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // flipped relative to us. We can use the margins for the opposite edges. 6284a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (childRenderBlock) { 6285a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch childBeforePositive = childRenderBlock->maxPositiveMarginAfter(); 6286a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch childBeforeNegative = childRenderBlock->maxNegativeMarginAfter(); 6287a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch childAfterPositive = childRenderBlock->maxPositiveMarginBefore(); 6288a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch childAfterNegative = childRenderBlock->maxNegativeMarginBefore(); 6289a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } else { 6290a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch beforeMargin = child->marginAfter(); 6291a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch afterMargin = child->marginBefore(); 6292a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 6293a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } else { 6294a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // The child is perpendicular to us, which means its margins don't collapse but are on the 6295a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // "logical left/right" sides of the child box. We can just return the raw margin in this case. 6296a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch beforeMargin = marginBeforeForChild(child); 6297a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch afterMargin = marginAfterForChild(child); 6298a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 6299a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 6300a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // Resolve uncollapsing margins into their positive/negative buckets. 6301a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (beforeMargin) { 6302a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (beforeMargin > 0) 6303a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch childBeforePositive = beforeMargin; 6304a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch else 6305a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch childBeforeNegative = -beforeMargin; 6306a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 6307a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (afterMargin) { 6308a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (afterMargin > 0) 6309a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch childAfterPositive = afterMargin; 6310a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch else 6311a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch childAfterNegative = -afterMargin; 6312a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 6313a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 6314a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return MarginValues(childBeforePositive, childBeforeNegative, childAfterPositive, childAfterNegative); 6315a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 6316a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 63178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst char* RenderBlock::renderName() const 63188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 63198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isBody()) 63208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return "RenderBody"; // FIXME: Temporary hack until we know that the regression tests pass. 63218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 63228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isFloating()) 63238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return "RenderBlock (floating)"; 63248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isPositioned()) 63258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return "RenderBlock (positioned)"; 63265af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (isAnonymousColumnsBlock()) 63275af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return "RenderBlock (anonymous multi-column)"; 63285af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (isAnonymousColumnSpanBlock()) 63295af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return "RenderBlock (anonymous multi-column span)"; 63308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isAnonymousBlock()) 63318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return "RenderBlock (anonymous)"; 63328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else if (isAnonymous()) 63338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return "RenderBlock (generated)"; 63348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isRelPositioned()) 63358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return "RenderBlock (relative positioned)"; 63368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isRunIn()) 63378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return "RenderBlock (run-in)"; 63388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return "RenderBlock"; 63398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 63408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 634181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline void RenderBlock::FloatingObjects::clear() 634281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 634381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_set.clear(); 634481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_leftObjectsCount = 0; 634581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_rightObjectsCount = 0; 634681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 634781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 634881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline void RenderBlock::FloatingObjects::increaseObjectsCount(FloatingObject::Type type) 634981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 635081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (type == FloatingObject::FloatLeft) 635181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_leftObjectsCount++; 635281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch else 635381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_rightObjectsCount++; 635481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 635581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 635681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline void RenderBlock::FloatingObjects::decreaseObjectsCount(FloatingObject::Type type) 635781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 635881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (type == FloatingObject::FloatLeft) 635981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_leftObjectsCount--; 636081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch else 636181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_rightObjectsCount--; 636281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 636381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 63648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore 6365