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