15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 1997 Martin Jones (mjones@kde.org) 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (C) 1997 Torben Weis (weis@kde.org) 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (C) 1998 Waldo Bastian (bastian@kde.org) 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (C) 1999 Lars Knoll (knoll@kde.org) 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (C) 1999 Antti Koivisto (koivisto@kde.org) 7d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2013 Apple Inc. All rights reserved. 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful, 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details. 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB. If not, write to 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA. 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 27e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "core/rendering/RenderTableSection.h" 28e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/paint/TableSectionPainter.h" 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <limits> 3119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)#include "core/rendering/GraphicsContextAnnotator.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/HitTestResult.h" 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/PaintInfo.h" 3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderTableCell.h" 3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderTableCol.h" 3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderTableRow.h" 3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderView.h" 38e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/rendering/SubtreeLayoutScope.h" 3902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "wtf/HashSet.h" 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 41c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace HTMLNames; 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// This variable is used to balance the memory consumption vs the paint invalidation time on big tables. 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static unsigned gMinTableSizeToUseFastPaintPathWithOverflowingCell = 75 * 75; 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 48591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic inline void setRowLogicalHeightToRowStyleLogicalHeight(RenderTableSection::RowStruct& row) 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(row.rowRenderer); 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) row.logicalHeight = row.rowRenderer->style()->logicalHeight(); 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline void updateLogicalHeightForCell(RenderTableSection::RowStruct& row, const RenderTableCell* cell) 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We ignore height settings on rowspan cells. 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cell->rowSpan() != 1) 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Length logicalHeight = cell->style()->logicalHeight(); 61591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (logicalHeight.isPositive()) { 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Length cRowLogicalHeight = row.logicalHeight; 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (logicalHeight.type()) { 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Percent: 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!(cRowLogicalHeight.isPercent()) 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || (cRowLogicalHeight.isPercent() && cRowLogicalHeight.percent() < logicalHeight.percent())) 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) row.logicalHeight = logicalHeight; 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Fixed: 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cRowLogicalHeight.type() < Percent 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || (cRowLogicalHeight.isFixed() && cRowLogicalHeight.value() < logicalHeight.value())) 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) row.logicalHeight = logicalHeight; 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 80e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)void RenderTableSection::CellStruct::trace(Visitor* visitor) 81e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles){ 82e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#if ENABLE(OILPAN) 83e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) visitor->trace(cells); 84e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#endif 85e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)} 86e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) 87e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)void RenderTableSection::RowStruct::trace(Visitor* visitor) 88e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles){ 89e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) visitor->trace(row); 90e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) visitor->trace(rowRenderer); 91e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)} 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 93926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)RenderTableSection::RenderTableSection(Element* element) 94926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) : RenderBox(element) 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_cCol(0) 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_cRow(0) 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_outerBorderStart(0) 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_outerBorderEnd(0) 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_outerBorderBefore(0) 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_outerBorderAfter(0) 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_needsCellRecalc(false) 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_hasMultipleCellLevels(false) 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // init RenderObject attributes 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setInline(false); // our object is not Inline 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderTableSection::~RenderTableSection() 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 112e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)void RenderTableSection::trace(Visitor* visitor) 113e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles){ 114e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#if ENABLE(OILPAN) 115e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) visitor->trace(m_children); 116e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) visitor->trace(m_grid); 117e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) visitor->trace(m_overflowingCells); 118e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) visitor->trace(m_cellsCollapsedBorders); 119e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#endif 120e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) RenderBox::trace(visitor); 121e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)} 122e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTableSection::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBox::styleDidChange(diff, oldStyle); 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) propagateStyleToAnonymousChildren(); 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If border was changed, notify table. 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderTable* table = this->table(); 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (table && !table->selfNeedsLayout() && !table->normalChildNeedsLayout() && oldStyle && oldStyle->border() != style()->border()) 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) table->invalidateCollapsedBorders(); 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTableSection::willBeRemovedFromTree() 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBox::willBeRemovedFromTree(); 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Preventively invalidate our cells as we may be re-inserted into 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // a new table which would require us to rebuild our structure. 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setNeedsCellRecalc(); 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild) 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!child->isTableRow()) { 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject* last = beforeChild; 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!last) 148d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) last = lastRow(); 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (last && last->isAnonymous() && !last->isBeforeOrAfterContent()) { 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (beforeChild == last) 151d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) beforeChild = last->slowFirstChild(); 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) last->addChild(child, beforeChild); 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (beforeChild && !beforeChild->isAnonymous() && beforeChild->parent() == this) { 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject* row = beforeChild->previousSibling(); 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (row && row->isTableRow() && row->isAnonymous()) { 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) row->addChild(child); 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If beforeChild is inside an anonymous cell/row, insert into the cell or into 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the anonymous row containing it, if there is one. 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject* lastBox = last; 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (lastBox && lastBox->parent()->isAnonymous() && !lastBox->isTableRow()) 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastBox = lastBox->parent(); 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (lastBox && lastBox->isAnonymous() && !lastBox->isBeforeOrAfterContent()) { 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastBox->addChild(child, beforeChild); 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject* row = RenderTableRow::createAnonymousWithParentRenderer(this); 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) addChild(row, beforeChild); 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) row->addChild(child); 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (beforeChild) 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setNeedsCellRecalc(); 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned insertionRow = m_cRow; 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++m_cRow; 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_cCol = 0; 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ensureRows(m_cRow); 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderTableRow* row = toRenderTableRow(child); 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_grid[insertionRow].rowRenderer = row; 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) row->setRowIndex(insertionRow); 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!beforeChild) 194591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch setRowLogicalHeightToRowStyleLogicalHeight(m_grid[insertionRow]); 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (beforeChild && beforeChild->parent() != this) 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) beforeChild = splitAnonymousBoxesAroundChild(beforeChild); 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!beforeChild || beforeChild->isTableRow()); 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBox::addChild(child, beforeChild); 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTableSection::ensureRows(unsigned numRows) 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (numRows <= m_grid.size()) 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned oldSize = m_grid.size(); 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_grid.grow(numRows); 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 211197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch unsigned effectiveColumnCount = std::max(1u, table()->numEffCols()); 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned row = oldSize; row < m_grid.size(); ++row) 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_grid[row].row.grow(effectiveColumnCount); 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTableSection::addCell(RenderTableCell* cell, RenderTableRow* row) 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We don't insert the cell if we need cell recalc as our internal columns' representation 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // will have drifted from the table's representation. Also recalcCells will call addCell 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // at a later time after sync'ing our columns' with the table's. 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (needsCellRecalc()) 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned rSpan = cell->rowSpan(); 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned cSpan = cell->colSpan(); 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const Vector<RenderTable::ColumnStruct>& columns = table()->columns(); 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned nCols = columns.size(); 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned insertionRow = row->rowIndex(); 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // ### mozilla still seems to do the old HTML way, even for strict DTD 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // (see the annotation on table cell layouting in the CSS specs and the testcase below: 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // <TABLE border> 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // <TR><TD>1 <TD rowspan="2">2 <TD>3 <TD>4 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // <TR><TD colspan="2">5 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // </TABLE> 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (m_cCol < nCols && (cellAt(insertionRow, m_cCol).hasCells() || cellAt(insertionRow, m_cCol).inColSpan)) 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_cCol++; 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateLogicalHeightForCell(m_grid[insertionRow], cell); 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ensureRows(insertionRow + rSpan); 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_grid[insertionRow].rowRenderer = row; 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned col = m_cCol; 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // tell the cell where it is 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool inColSpan = false; 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (cSpan) { 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned currentSpan; 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_cCol >= nCols) { 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) table()->appendColumn(cSpan); 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currentSpan = cSpan; 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cSpan < columns[m_cCol].span) 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) table()->splitColumn(m_cCol, cSpan); 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currentSpan = columns[m_cCol].span; 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned r = 0; r < rSpan; r++) { 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CellStruct& c = cellAt(insertionRow + r, m_cCol); 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(cell); 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) c.cells.append(cell); 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If cells overlap then we take the slow path for painting. 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (c.cells.size() > 1) 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_hasMultipleCellLevels = true; 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (inColSpan) 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) c.inColSpan = true; 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_cCol++; 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cSpan -= currentSpan; 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) inColSpan = true; 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cell->setCol(table()->effColToCol(col)); 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 27506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)bool RenderTableSection::rowHasOnlySpanningCells(unsigned row) 27606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){ 27706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) unsigned totalCols = m_grid[row].row.size(); 27806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 27906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) if (!totalCols) 28006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return false; 28106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 28206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) for (unsigned col = 0; col < totalCols; col++) { 28306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) const CellStruct& rowSpanCell = cellAt(row, col); 28406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 28506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // Empty cell is not a valid cell so it is not a rowspan cell. 28606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) if (rowSpanCell.cells.isEmpty()) 28706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return false; 28806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 28906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) if (rowSpanCell.cells[0]->rowSpan() == 1) 29006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return false; 29106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) } 29206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 29306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return true; 29406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)} 29506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 2967757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochvoid RenderTableSection::populateSpanningRowsHeightFromCell(RenderTableCell* cell, struct SpanningRowsHeight& spanningRowsHeight) 2977757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch{ 2987757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch const unsigned rowSpan = cell->rowSpan(); 2997757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch const unsigned rowIndex = cell->rowIndex(); 3007757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 3017757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing = cell->logicalHeightForRowSizing(); 3027757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 3037757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch spanningRowsHeight.rowHeight.resize(rowSpan); 3047757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch spanningRowsHeight.totalRowsHeight = 0; 3057757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch for (unsigned row = 0; row < rowSpan; row++) { 3067757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch unsigned actualRow = row + rowIndex; 30706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 3087757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch spanningRowsHeight.rowHeight[row] = m_rowPos[actualRow + 1] - m_rowPos[actualRow] - borderSpacingForRow(actualRow); 30906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) if (!spanningRowsHeight.rowHeight[row]) 310d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) spanningRowsHeight.isAnyRowWithOnlySpanningCells |= rowHasOnlySpanningCells(actualRow); 31106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 3127757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch spanningRowsHeight.totalRowsHeight += spanningRowsHeight.rowHeight[row]; 3137757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing -= borderSpacingForRow(actualRow); 3147757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch } 3157757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // We don't span the following row so its border-spacing (if any) should be included. 3167757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing += borderSpacingForRow(rowIndex + rowSpan - 1); 3177757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch} 3187757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 3197757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochvoid RenderTableSection::distributeExtraRowSpanHeightToPercentRows(RenderTableCell* cell, int totalPercent, int& extraRowSpanningHeight, Vector<int>& rowsHeight) 3207757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch{ 3217757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch if (!extraRowSpanningHeight || !totalPercent) 3227757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch return; 3237757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 3247757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch const unsigned rowSpan = cell->rowSpan(); 3257757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch const unsigned rowIndex = cell->rowIndex(); 326197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch int percent = std::min(totalPercent, 100); 3277757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch const int tableHeight = m_rowPos[m_grid.size()] + extraRowSpanningHeight; 3287757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 3297757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // Our algorithm matches Firefox. Extra spanning height would be distributed Only in first percent height rows 3307757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // those total percent is 100. Other percent rows would be uneffected even extra spanning height is remain. 3317757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch int accumulatedPositionIncrease = 0; 3327757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) { 3337757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch if (percent > 0 && extraRowSpanningHeight > 0) { 3347757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch if (m_grid[row].logicalHeight.isPercent()) { 3357757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch int toAdd = (tableHeight * m_grid[row].logicalHeight.percent() / 100) - rowsHeight[row - rowIndex]; 3367757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // FIXME: Note that this is wrong if we have a percentage above 100% and may make us grow 3377757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // above the available space. 3387757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 339197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch toAdd = std::min(toAdd, extraRowSpanningHeight); 3407757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch accumulatedPositionIncrease += toAdd; 3417757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch extraRowSpanningHeight -= toAdd; 3427757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch percent -= m_grid[row].logicalHeight.percent(); 3437757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch } 3447757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch } 3457757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch m_rowPos[row + 1] += accumulatedPositionIncrease; 3467757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch } 3477757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch} 3487757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 34907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch// Sometimes the multiplication of the 2 values below will overflow an integer. 35007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch// So we convert the parameters to 'long long' instead of 'int' to avoid the 35107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch// problem in this function. 35207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochstatic void updatePositionIncreasedWithRowHeight(long long extraHeight, long long rowHeight, long long totalHeight, int& accumulatedPositionIncrease, int& remainder) 35307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{ 35407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch COMPILE_ASSERT(sizeof(long long int) > sizeof(int), int_should_be_less_than_longlong); 35507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 35607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch accumulatedPositionIncrease += (extraHeight * rowHeight) / totalHeight; 35707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch remainder += (extraHeight * rowHeight) % totalHeight; 35807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch} 35907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 3609e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)// This is mainly used to distribute whole extra rowspanning height in percent rows when all spanning rows are 3619e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)// percent rows. 3629e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)// Distributing whole extra rowspanning height in percent rows based on the ratios of percent because this method works 3639e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)// same as percent distribution when only percent rows are present and percent is 100. Also works perfectly fine when 3649e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)// percent is not equal to 100. 3659e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)void RenderTableSection::distributeWholeExtraRowSpanHeightToPercentRows(RenderTableCell* cell, int totalPercent, int& extraRowSpanningHeight, Vector<int>& rowsHeight) 3669e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles){ 3679e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) if (!extraRowSpanningHeight || !totalPercent) 3689e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) return; 3699e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) 3709e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) const unsigned rowSpan = cell->rowSpan(); 3719e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) const unsigned rowIndex = cell->rowIndex(); 3729e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) int remainder = 0; 3739e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) 3749e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) int accumulatedPositionIncrease = 0; 3759e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) { 3769e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) if (m_grid[row].logicalHeight.isPercent()) { 3779e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) updatePositionIncreasedWithRowHeight(extraRowSpanningHeight, m_grid[row].logicalHeight.percent(), totalPercent, accumulatedPositionIncrease, remainder); 3789e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) 3799e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) // While whole extra spanning height is distributing in percent spanning rows, rational parts remains 3809e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) // in every integer division. So accumulating all remainder part in integer division and when total remainder 3819e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) // is equvalent to divisor then 1 unit increased in row position. 3829e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) // Note that this algorithm is biased towards adding more space towards the lower rows. 3839e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) if (remainder >= totalPercent) { 3849e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) remainder -= totalPercent; 3859e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) accumulatedPositionIncrease++; 3869e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) } 3879e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) } 3889e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) m_rowPos[row + 1] += accumulatedPositionIncrease; 3899e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) } 3909e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) 3919e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) ASSERT(!remainder); 3929e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) 3939e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) extraRowSpanningHeight -= accumulatedPositionIncrease; 3949e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)} 3959e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) 3967757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochvoid RenderTableSection::distributeExtraRowSpanHeightToAutoRows(RenderTableCell* cell, int totalAutoRowsHeight, int& extraRowSpanningHeight, Vector<int>& rowsHeight) 3977757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch{ 3987757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch if (!extraRowSpanningHeight || !totalAutoRowsHeight) 3997757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch return; 4007757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 4017757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch const unsigned rowSpan = cell->rowSpan(); 4027757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch const unsigned rowIndex = cell->rowIndex(); 4037757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch int accumulatedPositionIncrease = 0; 4047757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch int remainder = 0; 4057757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 4067757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // Aspect ratios of auto rows should not change otherwise table may look different than user expected. 4077757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // So extra height distributed in auto spanning rows based on their weight in spanning cell. 4087757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) { 4097757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch if (m_grid[row].logicalHeight.isAuto()) { 41007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch updatePositionIncreasedWithRowHeight(extraRowSpanningHeight, rowsHeight[row - rowIndex], totalAutoRowsHeight, accumulatedPositionIncrease, remainder); 4117757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 4127757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // While whole extra spanning height is distributing in auto spanning rows, rational parts remains 4137757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // in every integer division. So accumulating all remainder part in integer division and when total remainder 4147757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // is equvalent to divisor then 1 unit increased in row position. 4157757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // Note that this algorithm is biased towards adding more space towards the lower rows. 4167757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch if (remainder >= totalAutoRowsHeight) { 4177757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch remainder -= totalAutoRowsHeight; 4187757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch accumulatedPositionIncrease++; 4197757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch } 4207757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch } 4217757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch m_rowPos[row + 1] += accumulatedPositionIncrease; 4227757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch } 4237757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 4247757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch ASSERT(!remainder); 4257757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 4267757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch extraRowSpanningHeight -= accumulatedPositionIncrease; 4277757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch} 4287757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 4297757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochvoid RenderTableSection::distributeExtraRowSpanHeightToRemainingRows(RenderTableCell* cell, int totalRemainingRowsHeight, int& extraRowSpanningHeight, Vector<int>& rowsHeight) 4307757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch{ 4317757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch if (!extraRowSpanningHeight || !totalRemainingRowsHeight) 4327757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch return; 4337757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 4347757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch const unsigned rowSpan = cell->rowSpan(); 4357757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch const unsigned rowIndex = cell->rowIndex(); 4367757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch int accumulatedPositionIncrease = 0; 4377757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch int remainder = 0; 4387757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 4397757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // Aspect ratios of the rows should not change otherwise table may look different than user expected. 4407757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // So extra height distribution in remaining spanning rows based on their weight in spanning cell. 4417757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) { 4427757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch if (!m_grid[row].logicalHeight.isPercent()) { 44307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch updatePositionIncreasedWithRowHeight(extraRowSpanningHeight, rowsHeight[row - rowIndex], totalRemainingRowsHeight, accumulatedPositionIncrease, remainder); 4447757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 4457757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // While whole extra spanning height is distributing in remaining spanning rows, rational parts remains 4467757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // in every integer division. So accumulating all remainder part in integer division and when total remainder 4477757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // is equvalent to divisor then 1 unit increased in row position. 4487757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // Note that this algorithm is biased towards adding more space towards the lower rows. 4497757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch if (remainder >= totalRemainingRowsHeight) { 4507757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch remainder -= totalRemainingRowsHeight; 4517757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch accumulatedPositionIncrease++; 4527757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch } 4537757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch } 4547757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch m_rowPos[row + 1] += accumulatedPositionIncrease; 4557757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch } 4567757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 4577757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch ASSERT(!remainder); 4587757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 4597757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch extraRowSpanningHeight -= accumulatedPositionIncrease; 4607757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch} 4617757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 4628abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)static bool cellIsFullyIncludedInOtherCell(const RenderTableCell* cell1, const RenderTableCell* cell2) 463f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles){ 4648abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) return (cell1->rowIndex() >= cell2->rowIndex() && (cell1->rowIndex() + cell1->rowSpan()) <= (cell2->rowIndex() + cell2->rowSpan())); 4658abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)} 466f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 4678abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)// To avoid unneeded extra height distributions, we apply the following sorting algorithm: 4688abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)static bool compareRowSpanCellsInHeightDistributionOrder(const RenderTableCell* cell1, const RenderTableCell* cell2) 4698abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles){ 4708abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // Sorting bigger height cell first if cells are at same index with same span because we will skip smaller 4718abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // height cell to distribute it's extra height. 4728abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) if (cell1->rowIndex() == cell2->rowIndex() && cell1->rowSpan() == cell2->rowSpan()) 4738abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) return (cell1->logicalHeightForRowSizing() > cell2->logicalHeightForRowSizing()); 4748abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // Sorting inner most cell first because if inner spanning cell'e extra height is distributed then outer 4758abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // spanning cell's extra height will adjust accordingly. In reverse order, there is more chances that outer 4768abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // spanning cell's height will exceed than defined by user. 4778abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) if (cellIsFullyIncludedInOtherCell(cell1, cell2)) 4788abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) return true; 4798abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // Sorting lower row index first because first we need to apply the extra height of spanning cell which 4808abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // comes first in the table so lower rows's position would increment in sequence. 4811e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (!cellIsFullyIncludedInOtherCell(cell2, cell1)) 4828abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) return (cell1->rowIndex() < cell2->rowIndex()); 483f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 4848abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) return false; 485f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)} 486f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 48706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)bool RenderTableSection::isHeightNeededForRowHavingOnlySpanningCells(unsigned row) 48806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){ 48906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) unsigned totalCols = m_grid[row].row.size(); 49006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 49106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) if (!totalCols) 49206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return false; 49306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 49406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) for (unsigned col = 0; col < totalCols; col++) { 49506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) const CellStruct& rowSpanCell = cellAt(row, col); 49606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 49706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) if (rowSpanCell.cells.size()) { 49806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) RenderTableCell* cell = rowSpanCell.cells[0]; 49906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) const unsigned rowIndex = cell->rowIndex(); 50006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) const unsigned rowSpan = cell->rowSpan(); 50106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) int totalRowSpanCellHeight = 0; 50206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 50306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) for (unsigned row = 0; row < rowSpan; row++) { 50406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) unsigned actualRow = row + rowIndex; 50506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) totalRowSpanCellHeight += m_rowPos[actualRow + 1] - m_rowPos[actualRow]; 50606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) } 50706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) totalRowSpanCellHeight -= borderSpacingForRow(rowIndex + rowSpan - 1); 50806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 50906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) if (totalRowSpanCellHeight < cell->logicalHeightForRowSizing()) 51006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return true; 51106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) } 51206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) } 51306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 51406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return false; 51506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)} 51606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 51706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)unsigned RenderTableSection::calcRowHeightHavingOnlySpanningCells(unsigned row) 51806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){ 51906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) ASSERT(rowHasOnlySpanningCells(row)); 52006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 52106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) unsigned totalCols = m_grid[row].row.size(); 52206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 52306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) if (!totalCols) 52406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return 0; 52506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 52606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) unsigned rowHeight = 0; 52706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 52806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) for (unsigned col = 0; col < totalCols; col++) { 52906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) const CellStruct& rowSpanCell = cellAt(row, col); 53006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) if (rowSpanCell.cells.size() && rowSpanCell.cells[0]->rowSpan() > 1) 531197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch rowHeight = std::max(rowHeight, rowSpanCell.cells[0]->logicalHeightForRowSizing() / rowSpanCell.cells[0]->rowSpan()); 53206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) } 53306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 53406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return rowHeight; 53506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)} 53606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 53706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)void RenderTableSection::updateRowsHeightHavingOnlySpanningCells(RenderTableCell* cell, struct SpanningRowsHeight& spanningRowsHeight) 53806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){ 53906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) ASSERT(spanningRowsHeight.rowHeight.size()); 54006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 54106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) int accumulatedPositionIncrease = 0; 54206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) const unsigned rowSpan = cell->rowSpan(); 54306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) const unsigned rowIndex = cell->rowIndex(); 54406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 545f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) ASSERT_UNUSED(rowSpan, rowSpan == spanningRowsHeight.rowHeight.size()); 54606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 54706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) for (unsigned row = 0; row < spanningRowsHeight.rowHeight.size(); row++) { 54806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) unsigned actualRow = row + rowIndex; 54906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) if (!spanningRowsHeight.rowHeight[row] && rowHasOnlySpanningCells(actualRow) && isHeightNeededForRowHavingOnlySpanningCells(actualRow)) { 55006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) spanningRowsHeight.rowHeight[row] = calcRowHeightHavingOnlySpanningCells(actualRow); 55106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) accumulatedPositionIncrease += spanningRowsHeight.rowHeight[row]; 55206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) } 55306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) m_rowPos[actualRow + 1] += accumulatedPositionIncrease; 55406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) } 55506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 55606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) spanningRowsHeight.totalRowsHeight += accumulatedPositionIncrease; 55706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)} 55806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 559591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch// Distribute rowSpan cell height in rows those comes in rowSpan cell based on the ratio of row's height if 560591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch// 1. RowSpan cell height is greater then the total height of rows in rowSpan cell 561591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid RenderTableSection::distributeRowSpanHeightToRows(SpanningRenderTableCells& rowSpanCells) 562591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 563591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT(rowSpanCells.size()); 564591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 565f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) // 'rowSpanCells' list is already sorted based on the cells rowIndex in ascending order 566f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) // Arrange row spanning cell in the order in which we need to process first. 567f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) std::sort(rowSpanCells.begin(), rowSpanCells.end(), compareRowSpanCellsInHeightDistributionOrder); 568f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 569fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch unsigned extraHeightToPropagate = 0; 570fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch unsigned lastRowIndex = 0; 571fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch unsigned lastRowSpan = 0; 572591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 573fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch for (unsigned i = 0; i < rowSpanCells.size(); i++) { 574fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch RenderTableCell* cell = rowSpanCells[i]; 575591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 576fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch unsigned rowIndex = cell->rowIndex(); 577591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 578f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) unsigned rowSpan = cell->rowSpan(); 579f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 5803c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch unsigned spanningCellEndIndex = rowIndex + rowSpan; 5813c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch unsigned lastSpanningCellEndIndex = lastRowIndex + lastRowSpan; 5823c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 583f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) // Only heightest spanning cell will distribute it's extra height in row if more then one spanning cells 584f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) // present at same level. 585f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) if (rowIndex == lastRowIndex && rowSpan == lastRowSpan) 586fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch continue; 587591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 5883c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch int originalBeforePosition = m_rowPos[spanningCellEndIndex]; 5893c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 5903c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // When 2 spanning cells are ending at same row index then while extra height distribution of first spanning 5913c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // cell updates position of the last row so getting the original position of the last row in second spanning 5923c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // cell need to reduce the height changed by first spanning cell. 5933c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch if (spanningCellEndIndex == lastSpanningCellEndIndex) 5943c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch originalBeforePosition -= extraHeightToPropagate; 595591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 596fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch if (extraHeightToPropagate) { 5973c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch for (unsigned row = lastSpanningCellEndIndex + 1; row <= spanningCellEndIndex; row++) 598fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch m_rowPos[row] += extraHeightToPropagate; 5997757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch } 6007757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 601fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch lastRowIndex = rowIndex; 602fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch lastRowSpan = rowSpan; 6037757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 604fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch struct SpanningRowsHeight spanningRowsHeight; 6057757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 606fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch populateSpanningRowsHeightFromCell(cell, spanningRowsHeight); 607591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 608d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Here we are handling only row(s) who have only rowspanning cells and do not have any empty cell. 609d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (spanningRowsHeight.isAnyRowWithOnlySpanningCells) 61006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) updateRowsHeightHavingOnlySpanningCells(cell, spanningRowsHeight); 61106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 612d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // This code handle row(s) that have rowspanning cell(s) and at least one empty cell. 613d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Such rows are not handled below and end up having a height of 0. That would mean 614d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // content overlapping if one of their cells has any content. To avoid the problem, we 615d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // add all the remaining spanning cells' height to the last spanned row. 616d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // This means that we could grow a row past its 'height' or break percentage spreading 617d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // however this is better than overlapping content. 618d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // FIXME: Is there a better algorithm? 619d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!spanningRowsHeight.totalRowsHeight) { 620d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing) 621d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_rowPos[spanningCellEndIndex] += spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing + borderSpacingForRow(spanningCellEndIndex - 1); 622d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 623d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) extraHeightToPropagate = m_rowPos[spanningCellEndIndex] - originalBeforePosition; 624d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) continue; 625d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 626d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 627d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing <= spanningRowsHeight.totalRowsHeight) { 62806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) extraHeightToPropagate = m_rowPos[rowIndex + rowSpan] - originalBeforePosition; 629fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch continue; 63006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) } 631591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 632d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Below we are handling only row(s) who have at least one visible cell without rowspan value. 633fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch int totalPercent = 0; 634fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch int totalAutoRowsHeight = 0; 635fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch int totalRemainingRowsHeight = spanningRowsHeight.totalRowsHeight; 636fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch 637f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) // FIXME: Inner spanning cell height should not change if it have fixed height when it's parent spanning cell 638f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) // is distributing it's extra height in rows. 639f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 640fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch // Calculate total percentage, total auto rows height and total rows height except percent rows. 6413c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch for (unsigned row = rowIndex; row < spanningCellEndIndex; row++) { 642fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch if (m_grid[row].logicalHeight.isPercent()) { 643fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch totalPercent += m_grid[row].logicalHeight.percent(); 644fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch totalRemainingRowsHeight -= spanningRowsHeight.rowHeight[row - rowIndex]; 645fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch } else if (m_grid[row].logicalHeight.isAuto()) { 646fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch totalAutoRowsHeight += spanningRowsHeight.rowHeight[row - rowIndex]; 647fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch } 648fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch } 649fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch 650fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch int extraRowSpanningHeight = spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing - spanningRowsHeight.totalRowsHeight; 651fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch 6529e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) if (totalPercent < 100 && !totalAutoRowsHeight && !totalRemainingRowsHeight) { 6539e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) // Distributing whole extra rowspanning height in percent row when only non-percent rows height is 0. 6549e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) distributeWholeExtraRowSpanHeightToPercentRows(cell, totalPercent, extraRowSpanningHeight, spanningRowsHeight.rowHeight); 6559e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) } else { 6569e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) distributeExtraRowSpanHeightToPercentRows(cell, totalPercent, extraRowSpanningHeight, spanningRowsHeight.rowHeight); 6579e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) distributeExtraRowSpanHeightToAutoRows(cell, totalAutoRowsHeight, extraRowSpanningHeight, spanningRowsHeight.rowHeight); 6589e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) distributeExtraRowSpanHeightToRemainingRows(cell, totalRemainingRowsHeight, extraRowSpanningHeight, spanningRowsHeight.rowHeight); 6599e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) } 660fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch 661fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch ASSERT(!extraRowSpanningHeight); 662fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch 663fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch // Getting total changed height in the table 6643c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch extraHeightToPropagate = m_rowPos[spanningCellEndIndex] - originalBeforePosition; 665fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch } 666591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 667fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch if (extraHeightToPropagate) { 668591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // Apply changed height by rowSpan cells to rows present at the end of the table 6693c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch for (unsigned row = lastRowIndex + lastRowSpan + 1; row <= m_grid.size(); row++) 670fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch m_rowPos[row] += extraHeightToPropagate; 671591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 672591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 673591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 674591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch// Find out the baseline of the cell 675591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch// If the cell's baseline is more then the row's baseline then the cell's baseline become the row's baseline 676591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch// and if the row's baseline goes out of the row's boundries then adjust row height accordingly. 677591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid RenderTableSection::updateBaselineForCell(RenderTableCell* cell, unsigned row, LayoutUnit& baselineDescent) 678591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 679591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (!cell->isBaselineAligned()) 680591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return; 681591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 6823c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // Ignoring the intrinsic padding as it depends on knowing the row's baseline, which won't be accurate 6833c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // until the end of this function. 6843c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch LayoutUnit baselinePosition = cell->cellBaselinePosition() - cell->intrinsicPaddingBefore(); 6853c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch if (baselinePosition > cell->borderBefore() + (cell->paddingBefore() - cell->intrinsicPaddingBefore())) { 686197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_grid[row].baseline = std::max(m_grid[row].baseline, baselinePosition); 687591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 688591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch int cellStartRowBaselineDescent = 0; 689591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (cell->rowSpan() == 1) { 690197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch baselineDescent = std::max(baselineDescent, cell->logicalHeightForRowSizing() - baselinePosition); 691591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch cellStartRowBaselineDescent = baselineDescent; 692591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 693197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_rowPos[row + 1] = std::max<int>(m_rowPos[row + 1], m_rowPos[row] + m_grid[row].baseline + cellStartRowBaselineDescent); 694591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 695591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 696591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 6975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderTableSection::calcRowLogicalHeight() 6985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 699197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT) 70010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch SetLayoutNeededForbiddenScope layoutForbiddenScope(*this); 7015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 7025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!needsLayout()); 7045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderTableCell* cell; 70602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 7075d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // FIXME: This shouldn't use the same constructor as RenderView. 7085d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) LayoutState state(*this); 7095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_rowPos.resize(m_grid.size() + 1); 7118abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 7128abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // We ignore the border-spacing on any non-top section as it is already included in the previous section's last row position. 7138abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) if (this == table()->topSection()) 7148abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) m_rowPos[0] = table()->vBorderSpacing(); 7158abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) else 7168abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) m_rowPos[0] = 0; 717591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 718591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch SpanningRenderTableCells rowSpanCells; 719197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT) 7209bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) HashSet<const RenderTableCell*> uniqueCells; 7219bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)#endif 7225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned r = 0; r < m_grid.size(); r++) { 7245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_grid[r].baseline = 0; 7255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit baselineDescent = 0; 7265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Our base size is the biggest logical height from our cells' styles (excluding row spanning cells). 728197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_rowPos[r + 1] = std::max(m_rowPos[r] + minimumValueForLength(m_grid[r].logicalHeight, 0).round(), 0); 7295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Row& row = m_grid[r].row; 7315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned totalCols = row.size(); 7329bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) RenderTableCell* lastRowSpanCell = 0; 7335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned c = 0; c < totalCols; c++) { 7355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CellStruct& current = cellAt(r, c); 7365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < current.cells.size(); i++) { 7375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cell = current.cells[i]; 7385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (current.inColSpan && cell->rowSpan() == 1) 7395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 7405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 74109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (cell->rowSpan() > 1) { 74209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // For row spanning cells, we only handle them for the first row they span. This ensures we take their baseline into account. 74309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (lastRowSpanCell != cell && cell->rowIndex() == r) { 744197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT) 74509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ASSERT(!uniqueCells.contains(cell)); 74609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) uniqueCells.add(cell); 7479bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)#endif 7489bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) 74909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) rowSpanCells.append(cell); 75009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) lastRowSpanCell = cell; 751591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 75209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // Find out the baseline. The baseline is set on the first row in a rowSpan. 75309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) updateBaselineForCell(cell, r, baselineDescent); 754591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 75509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) continue; 756e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } 7575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 75809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ASSERT(cell->rowSpan() == 1); 75909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 7605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cell->hasOverrideHeight()) { 7615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cell->clearIntrinsicPadding(); 7625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cell->clearOverrideSize(); 763f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) cell->forceChildLayout(); 7645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 766197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_rowPos[r + 1] = std::max(m_rowPos[r + 1], m_rowPos[r] + cell->logicalHeightForRowSizing()); 767e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 76809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // Find out the baseline. 76909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) updateBaselineForCell(cell, r, baselineDescent); 7705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Add the border-spacing to our final position. 774591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_rowPos[r + 1] += borderSpacingForRow(r); 775197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_rowPos[r + 1] = std::max(m_rowPos[r + 1], m_rowPos[r]); 7765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 77809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!rowSpanCells.isEmpty()) 779591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch distributeRowSpanHeightToRows(rowSpanCells); 780591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 7815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!needsLayout()); 7825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_rowPos[m_grid.size()]; 7845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 7855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTableSection::layout() 7875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 7885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(needsLayout()); 7895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!needsCellRecalc()); 7905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!table()->needsSectionRecalc()); 7915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // addChild may over-grow m_grid but we don't want to throw away the memory too early as addChild 7935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // can be called in a loop (e.g during parsing). Doing it now ensures we have a stable-enough structure. 7945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_grid.shrinkToFit(); 7955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7965d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) LayoutState state(*this, locationOffset()); 7975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const Vector<int>& columnPos = table()->columnPositions(); 7995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 80010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch SubtreeLayoutScope layouter(*this); 8015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned r = 0; r < m_grid.size(); ++r) { 8025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Row& row = m_grid[r].row; 8035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned cols = row.size(); 8045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // First, propagate our table layout's information to the cells. This will mark the row as needing layout 8055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // if there was a column logical width change. 8065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned startColumn = 0; startColumn < cols; ++startColumn) { 8075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CellStruct& current = row[startColumn]; 8085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderTableCell* cell = current.primaryCell(); 8095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!cell || current.inColSpan) 8105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 8115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned endCol = startColumn; 8135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned cspan = cell->colSpan(); 8145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (cspan && endCol < cols) { 8155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(endCol < table()->columns().size()); 8165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cspan -= table()->columns()[endCol].span; 8175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endCol++; 8185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int tableLayoutLogicalWidth = columnPos[endCol] - columnPos[startColumn] - table()->hBorderSpacing(); 820e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) cell->setCellLogicalWidth(tableLayoutLogicalWidth, layouter); 8215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 823d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (RenderTableRow* rowRenderer = m_grid[r].rowRenderer) { 824d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!rowRenderer->needsLayout()) 825d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) rowRenderer->markForPaginationRelayoutIfNeeded(layouter); 8265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rowRenderer->layoutIfNeeded(); 827d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 8285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8303c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch clearNeedsLayout(); 8315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTableSection::distributeExtraLogicalHeightToPercentRows(int& extraLogicalHeight, int totalPercent) 8345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 8355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!totalPercent) 8365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 8375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned totalRows = m_grid.size(); 8395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int totalHeight = m_rowPos[totalRows] + extraLogicalHeight; 8405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int totalLogicalHeightAdded = 0; 841197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch totalPercent = std::min(totalPercent, 100); 8425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int rowHeight = m_rowPos[1] - m_rowPos[0]; 8435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned r = 0; r < totalRows; ++r) { 8445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (totalPercent > 0 && m_grid[r].logicalHeight.isPercent()) { 845197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch int toAdd = std::min<int>(extraLogicalHeight, (totalHeight * m_grid[r].logicalHeight.percent() / 100) - rowHeight); 8465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If toAdd is negative, then we don't want to shrink the row (this bug 8475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // affected Outlook Web Access). 848197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch toAdd = std::max(0, toAdd); 8495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) totalLogicalHeightAdded += toAdd; 8505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) extraLogicalHeight -= toAdd; 8515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) totalPercent -= m_grid[r].logicalHeight.percent(); 8525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(totalRows >= 1); 8545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (r < totalRows - 1) 8555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rowHeight = m_rowPos[r + 2] - m_rowPos[r + 1]; 8565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_rowPos[r + 1] += totalLogicalHeightAdded; 8575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTableSection::distributeExtraLogicalHeightToAutoRows(int& extraLogicalHeight, unsigned autoRowsCount) 8615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 8625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!autoRowsCount) 8635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 8645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int totalLogicalHeightAdded = 0; 8665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned r = 0; r < m_grid.size(); ++r) { 8675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (autoRowsCount > 0 && m_grid[r].logicalHeight.isAuto()) { 8685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Recomputing |extraLogicalHeightForRow| guarantees that we properly ditribute round |extraLogicalHeight|. 8695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int extraLogicalHeightForRow = extraLogicalHeight / autoRowsCount; 8705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) totalLogicalHeightAdded += extraLogicalHeightForRow; 8715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) extraLogicalHeight -= extraLogicalHeightForRow; 8725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --autoRowsCount; 8735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_rowPos[r + 1] += totalLogicalHeightAdded; 8755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTableSection::distributeRemainingExtraLogicalHeight(int& extraLogicalHeight) 8795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 8805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned totalRows = m_grid.size(); 8815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (extraLogicalHeight <= 0 || !m_rowPos[totalRows]) 8835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 8845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: m_rowPos[totalRows] - m_rowPos[0] is the total rows' size. 8865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int totalRowSize = m_rowPos[totalRows]; 8875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int totalLogicalHeightAdded = 0; 8885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int previousRowPosition = m_rowPos[0]; 8895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned r = 0; r < totalRows; r++) { 8905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // weight with the original height 8915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) totalLogicalHeightAdded += extraLogicalHeight * (m_rowPos[r + 1] - previousRowPosition) / totalRowSize; 8925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) previousRowPosition = m_rowPos[r + 1]; 8935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_rowPos[r + 1] += totalLogicalHeightAdded; 8945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) extraLogicalHeight -= totalLogicalHeightAdded; 8975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderTableSection::distributeExtraLogicalHeightToRows(int extraLogicalHeight) 9005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 9015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!extraLogicalHeight) 9025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return extraLogicalHeight; 9035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned totalRows = m_grid.size(); 9055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!totalRows) 9065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return extraLogicalHeight; 9075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_rowPos[totalRows] && nextSibling()) 9095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return extraLogicalHeight; 9105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned autoRowsCount = 0; 9125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int totalPercent = 0; 9135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned r = 0; r < totalRows; r++) { 9145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_grid[r].logicalHeight.isAuto()) 9155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++autoRowsCount; 9165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (m_grid[r].logicalHeight.isPercent()) 9175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) totalPercent += m_grid[r].logicalHeight.percent(); 9185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int remainingExtraLogicalHeight = extraLogicalHeight; 9215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) distributeExtraLogicalHeightToPercentRows(remainingExtraLogicalHeight, totalPercent); 9225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) distributeExtraLogicalHeightToAutoRows(remainingExtraLogicalHeight, autoRowsCount); 9235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) distributeRemainingExtraLogicalHeight(remainingExtraLogicalHeight); 9245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return extraLogicalHeight - remainingExtraLogicalHeight; 9255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 9265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 927e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)static bool shouldFlexCellChild(RenderObject* cellDescendant) 928e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){ 929e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) return cellDescendant->isReplaced() || (cellDescendant->isBox() && toRenderBox(cellDescendant)->scrollsOverflow()); 930e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)} 931e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 9325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTableSection::layoutRows() 9335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 934197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT) 93510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch SetLayoutNeededForbiddenScope layoutForbiddenScope(*this); 9365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 9375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!needsLayout()); 9395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 94007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // FIXME: Changing the height without a layout can change the overflow so it seems wrong. 94107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 9425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned totalRows = m_grid.size(); 9435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Set the width of our section now. The rows will also be this width. 9455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setLogicalWidth(table()->contentLogicalWidth()); 9465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_overflow.clear(); 9475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_overflowingCells.clear(); 9485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_forceSlowPaintPathWithOverflowingCell = false; 9495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int vspacing = table()->vBorderSpacing(); 9515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned nEffCols = table()->numEffCols(); 9525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9535d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) LayoutState state(*this, locationOffset()); 9545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned r = 0; r < totalRows; r++) { 9565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Set the row's x/y position and width/height. 9575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (RenderTableRow* rowRenderer = m_grid[r].rowRenderer) { 9585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rowRenderer->setLocation(LayoutPoint(0, m_rowPos[r])); 9595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rowRenderer->setLogicalWidth(logicalWidth()); 9605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rowRenderer->setLogicalHeight(m_rowPos[r + 1] - m_rowPos[r] - vspacing); 96176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) rowRenderer->updateLayerTransformAfterLayout(); 96207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch rowRenderer->clearAllOverflows(); 96307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch rowRenderer->addVisualEffectOverflow(); 9645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int rowHeightIncreaseForPagination = 0; 9675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned c = 0; c < nEffCols; c++) { 9695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CellStruct& cs = cellAt(r, c); 9705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderTableCell* cell = cs.primaryCell(); 9715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!cell || cs.inColSpan) 9735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 9745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int rowIndex = cell->rowIndex(); 9765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int rHeight = m_rowPos[rowIndex + cell->rowSpan()] - m_rowPos[rowIndex] - vspacing; 9775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Force percent height children to lay themselves out again. 9795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This will cause these children to grow to fill the cell. 9805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: There is still more work to do here to fully match WinIE (should 9815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // it become necessary to do so). In quirks mode, WinIE behaves like we 9825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // do, but it will clip the cells that spill out of the table section. In 9835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // strict mode, Mozilla and WinIE both regrow the table to accommodate the 9845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // new height of the cell (thus letting the percentages cause growth one 9855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // time only). We may also not be handling row-spanning cells correctly. 9865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 9875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Note also the oddity where replaced elements always flex, and yet blocks/tables do 9885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // not necessarily flex. WinIE is crazy and inconsistent, and we can't hope to 9895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // match the behavior perfectly, but we'll continue to refine it as we discover new 9905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // bugs. :) 9915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool cellChildrenFlex = false; 9925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool flexAllChildren = cell->style()->logicalHeight().isFixed() 9935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || (!table()->style()->logicalHeight().isAuto() && rHeight != cell->logicalHeight()); 9945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 995e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) for (RenderObject* child = cell->firstChild(); child; child = child->nextSibling()) { 996e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) if (!child->isText() && child->style()->logicalHeight().isPercent() 997e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) && (flexAllChildren || shouldFlexCellChild(child)) 998e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) && (!child->isTable() || toRenderTable(child)->hasSections())) { 999e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) cellChildrenFlex = true; 1000e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) break; 10015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1004e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) if (!cellChildrenFlex) { 1005e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) if (TrackedRendererListHashSet* percentHeightDescendants = cell->percentHeightDescendants()) { 1006e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) TrackedRendererListHashSet::iterator end = percentHeightDescendants->end(); 1007e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) for (TrackedRendererListHashSet::iterator it = percentHeightDescendants->begin(); it != end; ++it) { 1008e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) if (flexAllChildren || shouldFlexCellChild(*it)) { 1009e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) cellChildrenFlex = true; 10105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1011e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) } 10125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cellChildrenFlex) { 10175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Alignment within a cell is based off the calculated 10185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // height, which becomes irrelevant once the cell has 10195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // been resized based off its percentage. 10205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cell->setOverrideLogicalContentHeightFromRowHeight(rHeight); 1021f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) cell->forceChildLayout(); 10225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the baseline moved, we may have to update the data for our row. Find out the new baseline. 1024926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (cell->isBaselineAligned()) { 10255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit baseline = cell->cellBaselinePosition(); 10265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (baseline > cell->borderBefore() + cell->paddingBefore()) 1027197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_grid[r].baseline = std::max(m_grid[r].baseline, baseline); 10285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 103110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch SubtreeLayoutScope layouter(*cell); 1032e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) cell->computeIntrinsicPadding(rHeight, layouter); 10335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect oldCellRect = cell->frameRect(); 10355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setLogicalPositionForCell(cell, c); 10375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1038d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!cell->needsLayout()) 1039d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) cell->markForPaginationRelayoutIfNeeded(layouter); 10405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cell->layoutIfNeeded(); 10425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: Make pagination work with vertical tables. 10445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (view()->layoutState()->pageLogicalHeight() && cell->logicalHeight() != rHeight) { 10455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: Pagination might have made us change size. For now just shrink or grow the cell to fit without doing a relayout. 10465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We'll also do a basic increase of the row height to accommodate the cell if it's bigger, but this isn't quite right 10475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // either. It's at least stable though and won't result in an infinite # of relayouts that may never stabilize. 104807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch LayoutUnit oldLogicalHeight = cell->logicalHeight(); 104907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (oldLogicalHeight > rHeight) 1050197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch rowHeightIncreaseForPagination = std::max<int>(rowHeightIncreaseForPagination, oldLogicalHeight - rHeight); 10515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cell->setLogicalHeight(rHeight); 105207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch cell->computeOverflow(oldLogicalHeight, false); 10535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutSize childOffset(cell->location() - oldCellRect.location()); 10565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (childOffset.width() || childOffset.height()) { 10579e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) // If the child moved, we have to issue paint invalidations to it as well as any floating/positioned 1058f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) // descendants. An exception is if we need a layout. In this case, we know we're going to 10599e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) // issue paint invalidations ourselves (and the child) anyway. 1060197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (!table()->selfNeedsLayout() && cell->checkForPaintInvalidation()) 1061197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch cell->setMayNeedPaintInvalidation(true); 10625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (rowHeightIncreaseForPagination) { 10655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned rowIndex = r + 1; rowIndex <= totalRows; rowIndex++) 10665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_rowPos[rowIndex] += rowHeightIncreaseForPagination; 10675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned c = 0; c < nEffCols; ++c) { 1068e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) WillBeHeapVector<RawPtrWillBeMember<RenderTableCell>, 1>& cells = cellAt(r, c).cells; 106907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch for (size_t i = 0; i < cells.size(); ++i) { 107007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch LayoutUnit oldLogicalHeight = cells[i]->logicalHeight(); 107107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch cells[i]->setLogicalHeight(oldLogicalHeight + rowHeightIncreaseForPagination); 107207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch cells[i]->computeOverflow(oldLogicalHeight, false); 107307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 10745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!needsLayout()); 10795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setLogicalHeight(m_rowPos[totalRows]); 10815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 108253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) computeOverflowFromCells(totalRows, nEffCols); 108353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 108453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 108553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void RenderTableSection::computeOverflowFromCells() 108653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 108753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) unsigned totalRows = m_grid.size(); 108853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) unsigned nEffCols = table()->numEffCols(); 108953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) computeOverflowFromCells(totalRows, nEffCols); 109053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 109153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 109253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void RenderTableSection::computeOverflowFromCells(unsigned totalRows, unsigned nEffCols) 109353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 10945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned totalCellsCount = nEffCols * totalRows; 109551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) unsigned maxAllowedOverflowingCellsCount = totalCellsCount < gMinTableSizeToUseFastPaintPathWithOverflowingCell ? 0 : gMaxAllowedOverflowingCellRatioForFastPaintPath * totalCellsCount; 10965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1097197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT) 10985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool hasOverflowingCell = false; 10995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 11005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Now that our height has been determined, add in overflow from cells. 11015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned r = 0; r < totalRows; r++) { 11025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned c = 0; c < nEffCols; c++) { 11035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CellStruct& cs = cellAt(r, c); 11045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderTableCell* cell = cs.primaryCell(); 11055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!cell || cs.inColSpan) 11065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 11075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (r < totalRows - 1 && cell == primaryCellAt(r + 1, c)) 11085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 11095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) addOverflowFromChild(cell); 1110197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT) 11115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) hasOverflowingCell |= cell->hasVisualOverflow(); 11125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 11135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cell->hasVisualOverflow() && !m_forceSlowPaintPathWithOverflowingCell) { 11145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_overflowingCells.add(cell); 11155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_overflowingCells.size() > maxAllowedOverflowingCellsCount) { 11165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We need to set m_forcesSlowPaintPath only if there is a least one overflowing cells as the hit testing code rely on this information. 11175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_forceSlowPaintPathWithOverflowingCell = true; 11185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The slow path does not make any use of the overflowing cells info, don't hold on to the memory. 11195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_overflowingCells.clear(); 11205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(hasOverflowingCell == this->hasOverflowingCell()); 11265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 11275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 112809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)int RenderTableSection::calcBlockDirectionOuterBorder(BlockBorderSide side) const 11295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 11305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned totalCols = table()->numEffCols(); 11315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_grid.size() || !totalCols) 11325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 11335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned borderWidth = 0; 11355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 113609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) const BorderValue& sb = side == BorderBefore ? style()->borderBefore() : style()->borderAfter(); 11375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (sb.style() == BHIDDEN) 11385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -1; 11395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (sb.style() > BHIDDEN) 11405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) borderWidth = sb.width(); 11415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1142d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) const BorderValue& rb = side == BorderBefore ? firstRow()->style()->borderBefore() : lastRow()->style()->borderAfter(); 11435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (rb.style() == BHIDDEN) 11445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -1; 11455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (rb.style() > BHIDDEN && rb.width() > borderWidth) 11465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) borderWidth = rb.width(); 11475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool allHidden = true; 11495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned c = 0; c < totalCols; c++) { 115009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) const CellStruct& current = cellAt(side == BorderBefore ? 0 : m_grid.size() - 1, c); 11515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (current.inColSpan || !current.hasCells()) 11525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 115309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) const RenderStyle* primaryCellStyle = current.primaryCell()->style(); 115409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) const BorderValue& cb = side == BorderBefore ? primaryCellStyle->borderBefore() : primaryCellStyle->borderAfter(); // FIXME: Make this work with perpendicular and flipped cells. 11555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: Don't repeat for the same col group 11565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderTableCol* colGroup = table()->colElement(c); 11575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (colGroup) { 115809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) const BorderValue& gb = side == BorderBefore ? colGroup->style()->borderBefore() : colGroup->style()->borderAfter(); 11595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (gb.style() == BHIDDEN || cb.style() == BHIDDEN) 11605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 11615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allHidden = false; 11625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (gb.style() > BHIDDEN && gb.width() > borderWidth) 11635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) borderWidth = gb.width(); 11645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cb.style() > BHIDDEN && cb.width() > borderWidth) 11655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) borderWidth = cb.width(); 11665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 11675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cb.style() == BHIDDEN) 11685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 11695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allHidden = false; 11705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cb.style() > BHIDDEN && cb.width() > borderWidth) 11715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) borderWidth = cb.width(); 11725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (allHidden) 11755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -1; 11765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 117709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (side == BorderAfter) 117809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) borderWidth++; // Distribute rounding error 11795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return borderWidth / 2; 11805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 11815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 118209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)int RenderTableSection::calcInlineDirectionOuterBorder(InlineBorderSide side) const 11835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 11845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned totalCols = table()->numEffCols(); 11855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_grid.size() || !totalCols) 11865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 118709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) unsigned colIndex = side == BorderStart ? 0 : totalCols - 1; 11885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned borderWidth = 0; 11905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 119109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) const BorderValue& sb = side == BorderStart ? style()->borderStart() : style()->borderEnd(); 11925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (sb.style() == BHIDDEN) 11935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -1; 11945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (sb.style() > BHIDDEN) 11955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) borderWidth = sb.width(); 11965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 119709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (RenderTableCol* colGroup = table()->colElement(colIndex)) { 119809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) const BorderValue& gb = side == BorderStart ? colGroup->style()->borderStart() : colGroup->style()->borderEnd(); 11995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (gb.style() == BHIDDEN) 12005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -1; 12015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (gb.style() > BHIDDEN && gb.width() > borderWidth) 12025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) borderWidth = gb.width(); 12035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool allHidden = true; 12065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned r = 0; r < m_grid.size(); r++) { 120709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) const CellStruct& current = cellAt(r, colIndex); 12085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!current.hasCells()) 12095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 12105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: Don't repeat for the same cell 121109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) const RenderStyle* primaryCellStyle = current.primaryCell()->style(); 121209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) const RenderStyle* primaryCellParentStyle = current.primaryCell()->parent()->style(); 121309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) const BorderValue& cb = side == BorderStart ? primaryCellStyle->borderStart() : primaryCellStyle->borderEnd(); // FIXME: Make this work with perpendicular and flipped cells. 121409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) const BorderValue& rb = side == BorderStart ? primaryCellParentStyle->borderStart() : primaryCellParentStyle->borderEnd(); 12155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cb.style() == BHIDDEN || rb.style() == BHIDDEN) 12165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 12175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allHidden = false; 12185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cb.style() > BHIDDEN && cb.width() > borderWidth) 12195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) borderWidth = cb.width(); 12205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (rb.style() > BHIDDEN && rb.width() > borderWidth) 12215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) borderWidth = rb.width(); 12225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (allHidden) 12245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -1; 12255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 122609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if ((side == BorderStart) != table()->style()->isLeftToRightDirection()) 122709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) borderWidth++; // Distribute rounding error 122809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return borderWidth / 2; 12295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 12305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTableSection::recalcOuterBorder() 12325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 123309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_outerBorderBefore = calcBlockDirectionOuterBorder(BorderBefore); 123409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_outerBorderAfter = calcBlockDirectionOuterBorder(BorderAfter); 123509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_outerBorderStart = calcInlineDirectionOuterBorder(BorderStart); 123609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_outerBorderEnd = calcInlineDirectionOuterBorder(BorderEnd); 12375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 12385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderTableSection::firstLineBoxBaseline() const 12405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 12415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_grid.size()) 12425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -1; 12435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int firstLineBaseline = m_grid[0].baseline; 12455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstLineBaseline) 12465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return firstLineBaseline + m_rowPos[0]; 12475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstLineBaseline = -1; 12495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const Row& firstRow = m_grid[0].row; 12505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < firstRow.size(); ++i) { 12515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const CellStruct& cs = firstRow.at(i); 12525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const RenderTableCell* cell = cs.primaryCell(); 12535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Only cells with content have a baseline 12545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cell && cell->contentLogicalHeight()) 1255197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch firstLineBaseline = std::max<int>(firstLineBaseline, cell->logicalTop() + cell->paddingBefore() + cell->borderBefore() + cell->contentLogicalHeight()); 12565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return firstLineBaseline; 12595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 12605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTableSection::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) 12625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 12637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci TableSectionPainter(*this).paint(paintInfo, paintOffset); 12645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 12655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutRect RenderTableSection::logicalRectForWritingModeAndDirection(const LayoutRect& rect) const 12675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 12685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect tableAlignedRect(rect); 12695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) flipForWritingMode(tableAlignedRect); 12715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!style()->isHorizontalWritingMode()) 12735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tableAlignedRect = tableAlignedRect.transposedRect(); 12745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const Vector<int>& columnPos = table()->columnPositions(); 12765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: The table's direction should determine our row's direction, not the section's (see bug 96691). 12775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!style()->isLeftToRightDirection()) 12785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tableAlignedRect.setX(columnPos[columnPos.size() - 1] - tableAlignedRect.maxX()); 12795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return tableAlignedRect; 12815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 12825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)CellSpan RenderTableSection::dirtiedRows(const LayoutRect& damageRect) const 12845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 128502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch if (m_forceSlowPaintPathWithOverflowingCell) 12865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return fullTableRowSpan(); 12875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CellSpan coveredRows = spannedRows(damageRect); 12895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12909e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) // To issue paint invalidations for the border we might need to paint invalidate the first or last row even if they are not spanned themselves. 12915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (coveredRows.start() >= m_rowPos.size() - 1 && m_rowPos[m_rowPos.size() - 1] + table()->outerBorderAfter() >= damageRect.y()) 12925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --coveredRows.start(); 12935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!coveredRows.end() && m_rowPos[0] - table()->outerBorderBefore() <= damageRect.maxY()) 12955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++coveredRows.end(); 12965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return coveredRows; 12985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 12995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)CellSpan RenderTableSection::dirtiedColumns(const LayoutRect& damageRect) const 13015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 130202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch if (m_forceSlowPaintPathWithOverflowingCell) 13035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return fullTableColumnSpan(); 13045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CellSpan coveredColumns = spannedColumns(damageRect); 13065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const Vector<int>& columnPos = table()->columnPositions(); 13089e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) // To issue paint invalidations for the border we might need to paint invalidate the first or last column even if they are not spanned themselves. 13095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (coveredColumns.start() >= columnPos.size() - 1 && columnPos[columnPos.size() - 1] + table()->outerBorderEnd() >= damageRect.x()) 13105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --coveredColumns.start(); 13115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!coveredColumns.end() && columnPos[0] - table()->outerBorderStart() <= damageRect.maxX()) 13135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++coveredColumns.end(); 13145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return coveredColumns; 13165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)CellSpan RenderTableSection::spannedRows(const LayoutRect& flippedRect) const 13195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Find the first row that starts after rect top. 13215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned nextRow = std::upper_bound(m_rowPos.begin(), m_rowPos.end(), flippedRect.y()) - m_rowPos.begin(); 13225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (nextRow == m_rowPos.size()) 13245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return CellSpan(m_rowPos.size() - 1, m_rowPos.size() - 1); // After all rows. 13255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned startRow = nextRow > 0 ? nextRow - 1 : 0; 13275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Find the first row that starts after rect bottom. 13295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned endRow; 13305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_rowPos[nextRow] >= flippedRect.maxY()) 13315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endRow = nextRow; 13325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { 13335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endRow = std::upper_bound(m_rowPos.begin() + nextRow, m_rowPos.end(), flippedRect.maxY()) - m_rowPos.begin(); 13345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (endRow == m_rowPos.size()) 13355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endRow = m_rowPos.size() - 1; 13365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return CellSpan(startRow, endRow); 13395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)CellSpan RenderTableSection::spannedColumns(const LayoutRect& flippedRect) const 13425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const Vector<int>& columnPos = table()->columnPositions(); 13445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Find the first column that starts after rect left. 13465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // lower_bound doesn't handle the edge between two cells properly as it would wrongly return the 13475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // cell on the logical top/left. 13485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // upper_bound on the other hand properly returns the cell on the logical bottom/right, which also 13495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // matches the behavior of other browsers. 13505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned nextColumn = std::upper_bound(columnPos.begin(), columnPos.end(), flippedRect.x()) - columnPos.begin(); 13515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (nextColumn == columnPos.size()) 13535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return CellSpan(columnPos.size() - 1, columnPos.size() - 1); // After all columns. 13545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned startColumn = nextColumn > 0 ? nextColumn - 1 : 0; 13565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Find the first column that starts after rect right. 13585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned endColumn; 13595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (columnPos[nextColumn] >= flippedRect.maxX()) 13605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endColumn = nextColumn; 13615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { 13625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endColumn = std::upper_bound(columnPos.begin() + nextColumn, columnPos.end(), flippedRect.maxX()) - columnPos.begin(); 13635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (endColumn == columnPos.size()) 13645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endColumn = columnPos.size() - 1; 13655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return CellSpan(startColumn, endColumn); 13685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTableSection::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset) 13725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci TableSectionPainter(*this).paintObject(paintInfo, paintOffset); 13745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTableSection::imageChanged(WrappedImagePtr, const IntRect*) 13775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13789e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) // FIXME: Examine cells and issue paint invalidations of only the rect the image paints in. 13799e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) setShouldDoFullPaintInvalidation(true); 13805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTableSection::recalcCells() 13835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_needsCellRecalc); 13855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We reset the flag here to ensure that |addCell| works. This is safe to do as 13865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // fillRowsWithDefaultStartingAtPosition makes sure we match the table's columns 13875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // representation. 13885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_needsCellRecalc = false; 13895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_cCol = 0; 13915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_cRow = 0; 13925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_grid.clear(); 13935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1394d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) for (RenderTableRow* row = firstRow(); row; row = row->nextRow()) { 1395d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) unsigned insertionRow = m_cRow; 1396d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) ++m_cRow; 1397d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) m_cCol = 0; 1398d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) ensureRows(m_cRow); 13995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1400d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) m_grid[insertionRow].rowRenderer = row; 1401d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) row->setRowIndex(insertionRow); 1402d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) setRowLogicalHeightToRowStyleLogicalHeight(m_grid[insertionRow]); 14035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1404d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) for (RenderTableCell* cell = row->firstCell(); cell; cell = cell->nextCell()) 1405d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) addCell(cell, row); 14065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_grid.shrinkToFit(); 14095d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) setNeedsLayoutAndFullPaintInvalidation(); 14105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// FIXME: This function could be made O(1) in certain cases (like for the non-most-constrainive cells' case). 14137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid RenderTableSection::rowLogicalHeightChanged(RenderTableRow* row) 14145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (needsCellRecalc()) 14165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 14175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci unsigned rowIndex = row->rowIndex(); 1419591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch setRowLogicalHeightToRowStyleLogicalHeight(m_grid[rowIndex]); 14205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1421d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) for (RenderTableCell* cell = m_grid[rowIndex].rowRenderer->firstCell(); cell; cell = cell->nextCell()) 1422d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) updateLogicalHeightForCell(m_grid[rowIndex], cell); 14235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTableSection::setNeedsCellRecalc() 14265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_needsCellRecalc = true; 14285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (RenderTable* t = table()) 14295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) t->setNeedsSectionRecalc(); 14305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned RenderTableSection::numColumns() const 14335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned result = 0; 143502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 14365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned r = 0; r < m_grid.size(); ++r) { 14375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned c = result; c < table()->numEffCols(); ++c) { 14385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const CellStruct& cell = cellAt(r, c); 14395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cell.hasCells() || cell.inColSpan) 14405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result = c; 14415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 144302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 14445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result + 1; 14455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const BorderValue& RenderTableSection::borderAdjoiningStartCell(const RenderTableCell* cell) const 14485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(cell->isFirstOrLastCellInRow()); 14505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return hasSameDirectionAs(cell) ? style()->borderStart() : style()->borderEnd(); 14515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const BorderValue& RenderTableSection::borderAdjoiningEndCell(const RenderTableCell* cell) const 14545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(cell->isFirstOrLastCellInRow()); 14565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return hasSameDirectionAs(cell) ? style()->borderEnd() : style()->borderStart(); 14575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const RenderTableCell* RenderTableSection::firstRowCellAdjoiningTableStart() const 14605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned adjoiningStartCellColumnIndex = hasSameDirectionAs(table()) ? 0 : table()->lastColumnIndex(); 14625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return cellAt(0, adjoiningStartCellColumnIndex).primaryCell(); 14635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const RenderTableCell* RenderTableSection::firstRowCellAdjoiningTableEnd() const 14665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned adjoiningEndCellColumnIndex = hasSameDirectionAs(table()) ? table()->lastColumnIndex() : 0; 14685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return cellAt(0, adjoiningEndCellColumnIndex).primaryCell(); 14695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTableSection::appendColumn(unsigned pos) 14725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_needsCellRecalc); 14745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned row = 0; row < m_grid.size(); ++row) 14765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_grid[row].row.resize(pos + 1); 14775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTableSection::splitColumn(unsigned pos, unsigned first) 14805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_needsCellRecalc); 14825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_cCol > pos) 14845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_cCol++; 14855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned row = 0; row < m_grid.size(); ++row) { 14865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Row& r = m_grid[row].row; 14875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) r.insert(pos + 1, CellStruct()); 14885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (r[pos].hasCells()) { 1489d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) r[pos + 1].cells.appendVector(r[pos].cells); 14905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderTableCell* cell = r[pos].primaryCell(); 14915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(cell); 14925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(cell->colSpan() >= (r[pos].inColSpan ? 1u : 0)); 14935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned colleft = cell->colSpan() - r[pos].inColSpan; 14945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (first > colleft) 14955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) r[pos + 1].inColSpan = 0; 14965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 14975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) r[pos + 1].inColSpan = first + r[pos].inColSpan; 14985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 14995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) r[pos + 1].inColSpan = 0; 15005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 15035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Hit Testing 15055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderTableSection::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action) 15065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 15075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If we have no children then we have nothing to do. 1508d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (!firstRow()) 15095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 15105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Table sections cannot ever be hit tested. Effectively they do not exist. 15125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Just forward to our children always. 15135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutPoint adjustedLocation = accumulatedOffset + location(); 15145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 151509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (hasOverflowClip() && !locationInContainer.intersects(overflowClipRect(adjustedLocation))) 15165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 15175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (hasOverflowingCell()) { 1519d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) for (RenderTableRow* row = lastRow(); row; row = row->previousRow()) { 15205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: We have to skip over inline flows, since they can show up inside table rows 15215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // at the moment (a demoted inline <form> for example). If we ever implement a 15225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // table-specific hit-test method (which we should do for performance reasons anyway), 15235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // then we can remove this check. 1524d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (!row->hasSelfPaintingLayer()) { 1525d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) LayoutPoint childPoint = flipForWritingModeForChild(row, adjustedLocation); 1526d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (row->nodeAtPoint(request, result, locationInContainer, childPoint, action)) { 15275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateHitTestResult(result, toLayoutPoint(locationInContainer.point() - childPoint)); 15285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 15295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 15335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) recalcCellsIfNeeded(); 15365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect hitTestRect = locationInContainer.boundingBox(); 15385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) hitTestRect.moveBy(-adjustedLocation); 15395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect tableAlignedRect = logicalRectForWritingModeAndDirection(hitTestRect); 15415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CellSpan rowSpan = spannedRows(tableAlignedRect); 15425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CellSpan columnSpan = spannedColumns(tableAlignedRect); 15435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Now iterate over the spanned rows and columns. 15455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned hitRow = rowSpan.start(); hitRow < rowSpan.end(); ++hitRow) { 15465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned hitColumn = columnSpan.start(); hitColumn < columnSpan.end(); ++hitColumn) { 15475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CellStruct& current = cellAt(hitRow, hitColumn); 15485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the cell is empty, there's nothing to do 15505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!current.hasCells()) 15515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 15525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = current.cells.size() ; i; ) { 15545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --i; 15555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderTableCell* cell = current.cells[i]; 15565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutPoint cellPoint = flipForWritingModeForChild(cell, adjustedLocation); 15575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (static_cast<RenderObject*>(cell)->nodeAtPoint(request, result, locationInContainer, cellPoint, action)) { 15585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateHitTestResult(result, locationInContainer.point() - toLayoutSize(cellPoint)); 15595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 15605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!result.isRectBasedTest()) 15635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 15645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!result.isRectBasedTest()) 15665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 15675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 15705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 15715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTableSection::removeCachedCollapsedBorders(const RenderTableCell* cell) 15735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 15745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!table()->collapseBorders()) 15755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 157602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 15775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (int side = CBSBefore; side <= CBSEnd; ++side) 1578197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_cellsCollapsedBorders.remove(std::make_pair(cell, side)); 15795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 15805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTableSection::setCachedCollapsedBorder(const RenderTableCell* cell, CollapsedBorderSide side, CollapsedBorderValue border) 15825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 15835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(table()->collapseBorders()); 1584197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_cellsCollapsedBorders.set(std::make_pair(cell, side), border); 15855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 15865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)CollapsedBorderValue& RenderTableSection::cachedCollapsedBorder(const RenderTableCell* cell, CollapsedBorderSide side) 15885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 15895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(table()->collapseBorders()); 1590e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) WillBeHeapHashMap<pair<RawPtrWillBeMember<const RenderTableCell>, int>, CollapsedBorderValue>::iterator it = m_cellsCollapsedBorders.find(std::make_pair(cell, side)); 159151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) ASSERT_WITH_SECURITY_IMPLICATION(it != m_cellsCollapsedBorders.end()); 15925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return it->value; 15935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 15945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderTableSection* RenderTableSection::createAnonymousWithParentRenderer(const RenderObject* parent) 15965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 15975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(parent->style(), TABLE_ROW_GROUP); 1598f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) RenderTableSection* newSection = new RenderTableSection(0); 15998abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) newSection->setDocumentForAnonymous(&parent->document()); 16005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newSection->setStyle(newStyle.release()); 16015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newSection; 16025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 16035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTableSection::setLogicalPositionForCell(RenderTableCell* cell, unsigned effectiveColumn) const 16055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 16065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutPoint cellLocation(0, m_rowPos[cell->rowIndex()]); 16075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int horizontalBorderSpacing = table()->hBorderSpacing(); 16085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: The table's direction should determine our row's direction, not the section's (see bug 96691). 16105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!style()->isLeftToRightDirection()) 16115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cellLocation.setX(table()->columnPositions()[table()->numEffCols()] - table()->columnPositions()[table()->colToEffCol(cell->col() + cell->colSpan())] + horizontalBorderSpacing); 16125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 16135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cellLocation.setX(table()->columnPositions()[effectiveColumn] + horizontalBorderSpacing); 16145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cell->setLogicalLocation(cellLocation); 16165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 16175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1618c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 1619