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