Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutTableSection.cpp

Issue 2534413004: Made varied number of cells in each row based on row's requirement. (Closed)
Patch Set: Fixed Layout test crash. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1997 Martin Jones (mjones@kde.org) 2 * Copyright (C) 1997 Martin Jones (mjones@kde.org)
3 * (C) 1997 Torben Weis (weis@kde.org) 3 * (C) 1997 Torben Weis (weis@kde.org)
4 * (C) 1998 Waldo Bastian (bastian@kde.org) 4 * (C) 1998 Waldo Bastian (bastian@kde.org)
5 * (C) 1999 Lars Knoll (knoll@kde.org) 5 * (C) 1999 Lars Knoll (knoll@kde.org)
6 * (C) 1999 Antti Koivisto (koivisto@kde.org) 6 * (C) 1999 Antti Koivisto (koivisto@kde.org)
7 * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2013 Apple Inc. 7 * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2013 Apple Inc.
8 * All rights reserved. 8 * All rights reserved.
9 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) 9 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
10 * 10 *
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 if (!beforeChild) 203 if (!beforeChild)
204 setRowLogicalHeightToRowStyleLogicalHeight(m_grid[insertionRow]); 204 setRowLogicalHeightToRowStyleLogicalHeight(m_grid[insertionRow]);
205 205
206 if (beforeChild && beforeChild->parent() != this) 206 if (beforeChild && beforeChild->parent() != this)
207 beforeChild = splitAnonymousBoxesAroundChild(beforeChild); 207 beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
208 208
209 ASSERT(!beforeChild || beforeChild->isTableRow()); 209 ASSERT(!beforeChild || beforeChild->isTableRow());
210 LayoutTableBoxComponent::addChild(child, beforeChild); 210 LayoutTableBoxComponent::addChild(child, beforeChild);
211 } 211 }
212 212
213 void LayoutTableSection::ensureRows(unsigned numRows) { 213 void LayoutTableSection::ensureRows(unsigned numRows) {
mstensho (USE GERRIT) 2017/01/03 15:18:41 Could make this inline now, just like ensureCol()
a.suchit 2017/01/04 10:35:18 Done.
214 if (numRows <= m_grid.size()) 214 if (numRows > m_grid.size())
215 return; 215 m_grid.grow(numRows);
216
217 unsigned oldSize = m_grid.size();
218 m_grid.grow(numRows);
219
220 unsigned effectiveColumnCount = std::max(1u, table()->numEffectiveColumns());
221 for (unsigned row = oldSize; row < m_grid.size(); ++row)
222 m_grid[row].row.grow(effectiveColumnCount);
223 } 216 }
224 217
225 static inline void checkThatVectorIsDOMOrdered( 218 static inline void checkThatVectorIsDOMOrdered(
226 const Vector<LayoutTableCell*, 1>& cells) { 219 const Vector<LayoutTableCell*, 1>& cells) {
227 #ifndef NDEBUG 220 #ifndef NDEBUG
228 // This function should be called on a non-empty vector. 221 // This function should be called on a non-empty vector.
229 ASSERT(cells.size() > 0); 222 ASSERT(cells.size() > 0);
230 223
231 const LayoutTableCell* previousCell = cells[0]; 224 const LayoutTableCell* previousCell = cells[0];
232 for (size_t i = 1; i < cells.size(); ++i) { 225 for (size_t i = 1; i < cells.size(); ++i) {
(...skipping 21 matching lines...) Expand all
254 // representation will have drifted from the table's representation. Also 247 // representation will have drifted from the table's representation. Also
255 // recalcCells will call addCell at a later time after sync'ing our columns' 248 // recalcCells will call addCell at a later time after sync'ing our columns'
256 // with the table's. 249 // with the table's.
257 if (needsCellRecalc()) 250 if (needsCellRecalc())
258 return; 251 return;
259 252
260 unsigned rSpan = cell->rowSpan(); 253 unsigned rSpan = cell->rowSpan();
261 unsigned cSpan = cell->colSpan(); 254 unsigned cSpan = cell->colSpan();
262 const Vector<LayoutTable::ColumnStruct>& columns = 255 const Vector<LayoutTable::ColumnStruct>& columns =
263 table()->effectiveColumns(); 256 table()->effectiveColumns();
264 unsigned nCols = columns.size();
265 unsigned insertionRow = row->rowIndex(); 257 unsigned insertionRow = row->rowIndex();
266 258
267 // ### mozilla still seems to do the old HTML way, even for strict DTD 259 // ### mozilla still seems to do the old HTML way, even for strict DTD
268 // (see the annotation on table cell layouting in the CSS specs and the 260 // (see the annotation on table cell layouting in the CSS specs and the
269 // testcase below: 261 // testcase below:
270 // <TABLE border> 262 // <TABLE border>
271 // <TR><TD>1 <TD rowspan="2">2 <TD>3 <TD>4 263 // <TR><TD>1 <TD rowspan="2">2 <TD>3 <TD>4
272 // <TR><TD colspan="2">5 264 // <TR><TD colspan="2">5
273 // </TABLE> 265 // </TABLE>
274 while (m_cCol < nCols && (cellAt(insertionRow, m_cCol).hasCells() || 266 while (m_cCol < numCols(insertionRow) &&
275 cellAt(insertionRow, m_cCol).inColSpan)) 267 (cellAt(insertionRow, m_cCol).hasCells() ||
268 cellAt(insertionRow, m_cCol).inColSpan))
276 m_cCol++; 269 m_cCol++;
277 270
278 updateLogicalHeightForCell(m_grid[insertionRow], cell); 271 updateLogicalHeightForCell(m_grid[insertionRow], cell);
279 272
280 ensureRows(insertionRow + rSpan); 273 ensureRows(insertionRow + rSpan);
281 274
282 m_grid[insertionRow].rowLayoutObject = row; 275 m_grid[insertionRow].rowLayoutObject = row;
283 276
284 unsigned col = m_cCol; 277 unsigned col = m_cCol;
285 // tell the cell where it is 278 // tell the cell where it is
286 bool inColSpan = false; 279 bool inColSpan = false;
287 while (cSpan) { 280 while (cSpan) {
288 unsigned currentSpan; 281 unsigned currentSpan;
289 if (m_cCol >= nCols) { 282 if (m_cCol >= columns.size()) {
290 table()->appendEffectiveColumn(cSpan); 283 table()->appendEffectiveColumn(cSpan);
291 currentSpan = cSpan; 284 currentSpan = cSpan;
292 } else { 285 } else {
293 if (cSpan < columns[m_cCol].span) 286 if (cSpan < columns[m_cCol].span)
294 table()->splitEffectiveColumn(m_cCol, cSpan); 287 table()->splitEffectiveColumn(m_cCol, cSpan);
295 currentSpan = columns[m_cCol].span; 288 currentSpan = columns[m_cCol].span;
296 } 289 }
297 for (unsigned r = 0; r < rSpan; r++) { 290 for (unsigned r = 0; r < rSpan; r++) {
291 ensureCol(insertionRow + r, m_cCol);
298 CellStruct& c = cellAt(insertionRow + r, m_cCol); 292 CellStruct& c = cellAt(insertionRow + r, m_cCol);
299 ASSERT(cell); 293 ASSERT(cell);
300 c.cells.append(cell); 294 c.cells.append(cell);
301 checkThatVectorIsDOMOrdered(c.cells); 295 checkThatVectorIsDOMOrdered(c.cells);
302 // If cells overlap then we take the slow path for painting. 296 // If cells overlap then we take the slow path for painting.
303 if (c.cells.size() > 1) 297 if (c.cells.size() > 1)
304 m_hasMultipleCellLevels = true; 298 m_hasMultipleCellLevels = true;
305 if (inColSpan) 299 if (inColSpan)
306 c.inColSpan = true; 300 c.inColSpan = true;
307 } 301 }
(...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 1126
1133 // FIXME: Changing the height without a layout can change the overflow so it 1127 // FIXME: Changing the height without a layout can change the overflow so it
1134 // seems wrong. 1128 // seems wrong.
1135 1129
1136 unsigned totalRows = m_grid.size(); 1130 unsigned totalRows = m_grid.size();
1137 1131
1138 // Set the width of our section now. The rows will also be this width. 1132 // Set the width of our section now. The rows will also be this width.
1139 setLogicalWidth(table()->contentLogicalWidth()); 1133 setLogicalWidth(table()->contentLogicalWidth());
1140 1134
1141 int vspacing = table()->vBorderSpacing(); 1135 int vspacing = table()->vBorderSpacing();
1142 unsigned nEffCols = table()->numEffectiveColumns();
1143 LayoutState state(*this); 1136 LayoutState state(*this);
1144 1137
1145 // Set the rows' location and size. 1138 // Set the rows' location and size.
1146 for (unsigned r = 0; r < totalRows; r++) { 1139 for (unsigned r = 0; r < totalRows; r++) {
1147 LayoutTableRow* rowLayoutObject = m_grid[r].rowLayoutObject; 1140 LayoutTableRow* rowLayoutObject = m_grid[r].rowLayoutObject;
1148 if (rowLayoutObject) { 1141 if (rowLayoutObject) {
1149 rowLayoutObject->setLogicalLocation(LayoutPoint(0, m_rowPos[r])); 1142 rowLayoutObject->setLogicalLocation(LayoutPoint(0, m_rowPos[r]));
1150 rowLayoutObject->setLogicalWidth(logicalWidth()); 1143 rowLayoutObject->setLogicalWidth(logicalWidth());
1151 LayoutUnit rowLogicalHeight(m_rowPos[r + 1] - m_rowPos[r] - vspacing); 1144 LayoutUnit rowLogicalHeight(m_rowPos[r + 1] - m_rowPos[r] - vspacing);
1152 if (state.isPaginated() && r + 1 < totalRows) { 1145 if (state.isPaginated() && r + 1 < totalRows) {
1153 // If the next row has a pagination strut, we need to subtract it. It 1146 // If the next row has a pagination strut, we need to subtract it. It
1154 // should not be included in this row's height. 1147 // should not be included in this row's height.
1155 if (LayoutTableRow* nextRowObject = m_grid[r + 1].rowLayoutObject) 1148 if (LayoutTableRow* nextRowObject = m_grid[r + 1].rowLayoutObject)
1156 rowLogicalHeight -= nextRowObject->paginationStrut(); 1149 rowLogicalHeight -= nextRowObject->paginationStrut();
1157 } 1150 }
1158 rowLayoutObject->setLogicalHeight(rowLogicalHeight); 1151 rowLayoutObject->setLogicalHeight(rowLogicalHeight);
1159 rowLayoutObject->updateLayerTransformAfterLayout(); 1152 rowLayoutObject->updateLayerTransformAfterLayout();
1160 } 1153 }
1161 } 1154 }
1162 1155
1163 // Vertically align and flex the cells in each row. 1156 // Vertically align and flex the cells in each row.
1164 for (unsigned r = 0; r < totalRows; r++) { 1157 for (unsigned r = 0; r < totalRows; r++) {
1165 LayoutTableRow* rowLayoutObject = m_grid[r].rowLayoutObject; 1158 LayoutTableRow* rowLayoutObject = m_grid[r].rowLayoutObject;
1166 1159
1167 for (unsigned c = 0; c < nEffCols; c++) { 1160 for (unsigned c = 0; c < numCols(r); c++) {
1168 CellStruct& cs = cellAt(r, c); 1161 CellStruct& cs = cellAt(r, c);
1169 LayoutTableCell* cell = cs.primaryCell(); 1162 LayoutTableCell* cell = cs.primaryCell();
1170 1163
1171 if (!cell || cs.inColSpan) 1164 if (!cell || cs.inColSpan)
1172 continue; 1165 continue;
1173 1166
1174 if (cell->rowIndex() != r) 1167 if (cell->rowIndex() != r)
1175 continue; // Rowspanned cells are handled in the first row they occur. 1168 continue; // Rowspanned cells are handled in the first row they occur.
1176 1169
1177 int rHeight; 1170 int rHeight;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1221 } 1214 }
1222 } 1215 }
1223 if (rowLayoutObject) 1216 if (rowLayoutObject)
1224 rowLayoutObject->computeOverflow(); 1217 rowLayoutObject->computeOverflow();
1225 } 1218 }
1226 1219
1227 ASSERT(!needsLayout()); 1220 ASSERT(!needsLayout());
1228 1221
1229 setLogicalHeight(LayoutUnit(m_rowPos[totalRows])); 1222 setLogicalHeight(LayoutUnit(m_rowPos[totalRows]));
1230 1223
1231 computeOverflowFromCells(totalRows, nEffCols); 1224 computeOverflowFromCells(totalRows, table()->numEffectiveColumns());
1232 } 1225 }
1233 1226
1234 int LayoutTableSection::paginationStrutForRow(LayoutTableRow* row, 1227 int LayoutTableSection::paginationStrutForRow(LayoutTableRow* row,
1235 LayoutUnit logicalOffset) const { 1228 LayoutUnit logicalOffset) const {
1236 DCHECK(row); 1229 DCHECK(row);
1237 if (row->getPaginationBreakability() == AllowAnyBreaks) 1230 if (row->getPaginationBreakability() == AllowAnyBreaks)
1238 return 0; 1231 return 0;
1239 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset); 1232 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
1240 if (!pageLogicalHeight) 1233 if (!pageLogicalHeight)
1241 return 0; 1234 return 0;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1277 : gMaxAllowedOverflowingCellRatioForFastPaintPath * totalCellsCount; 1270 : gMaxAllowedOverflowingCellRatioForFastPaintPath * totalCellsCount;
1278 1271
1279 m_overflow.reset(); 1272 m_overflow.reset();
1280 m_overflowingCells.clear(); 1273 m_overflowingCells.clear();
1281 m_forceSlowPaintPathWithOverflowingCell = false; 1274 m_forceSlowPaintPathWithOverflowingCell = false;
1282 #if ENABLE(ASSERT) 1275 #if ENABLE(ASSERT)
1283 bool hasOverflowingCell = false; 1276 bool hasOverflowingCell = false;
1284 #endif 1277 #endif
1285 // Now that our height has been determined, add in overflow from cells. 1278 // Now that our height has been determined, add in overflow from cells.
1286 for (unsigned r = 0; r < totalRows; r++) { 1279 for (unsigned r = 0; r < totalRows; r++) {
1287 for (unsigned c = 0; c < nEffCols; c++) { 1280 for (unsigned c = 0; c < numCols(r); c++) {
1288 CellStruct& cs = cellAt(r, c); 1281 CellStruct& cs = cellAt(r, c);
1289 LayoutTableCell* cell = cs.primaryCell(); 1282 LayoutTableCell* cell = cs.primaryCell();
1290 if (!cell || cs.inColSpan) 1283 if (!cell || cs.inColSpan)
1291 continue; 1284 continue;
1292 if (r < totalRows - 1 && cell == primaryCellAt(r + 1, c)) 1285 if (r < totalRows - 1 && cell == primaryCellAt(r + 1, c))
1293 continue; 1286 continue;
1294 addOverflowFromChild(cell); 1287 addOverflowFromChild(cell);
1295 #if ENABLE(ASSERT) 1288 #if ENABLE(ASSERT)
1296 hasOverflowingCell |= cell->hasVisualOverflow(); 1289 hasOverflowingCell |= cell->hasVisualOverflow();
1297 #endif 1290 #endif
(...skipping 12 matching lines...) Expand all
1310 } 1303 }
1311 } 1304 }
1312 1305
1313 ASSERT(hasOverflowingCell == this->hasOverflowingCell()); 1306 ASSERT(hasOverflowingCell == this->hasOverflowingCell());
1314 } 1307 }
1315 1308
1316 bool LayoutTableSection::recalcChildOverflowAfterStyleChange() { 1309 bool LayoutTableSection::recalcChildOverflowAfterStyleChange() {
1317 ASSERT(childNeedsOverflowRecalcAfterStyleChange()); 1310 ASSERT(childNeedsOverflowRecalcAfterStyleChange());
1318 clearChildNeedsOverflowRecalcAfterStyleChange(); 1311 clearChildNeedsOverflowRecalcAfterStyleChange();
1319 unsigned totalRows = m_grid.size(); 1312 unsigned totalRows = m_grid.size();
1320 unsigned numEffCols = table()->numEffectiveColumns();
1321 bool childrenOverflowChanged = false; 1313 bool childrenOverflowChanged = false;
1322 for (unsigned r = 0; r < totalRows; r++) { 1314 for (unsigned r = 0; r < totalRows; r++) {
1323 LayoutTableRow* rowLayouter = rowLayoutObjectAt(r); 1315 LayoutTableRow* rowLayouter = rowLayoutObjectAt(r);
1324 if (!rowLayouter || 1316 if (!rowLayouter ||
1325 !rowLayouter->childNeedsOverflowRecalcAfterStyleChange()) 1317 !rowLayouter->childNeedsOverflowRecalcAfterStyleChange())
1326 continue; 1318 continue;
1327 rowLayouter->clearChildNeedsOverflowRecalcAfterStyleChange(); 1319 rowLayouter->clearChildNeedsOverflowRecalcAfterStyleChange();
1328 bool rowChildrenOverflowChanged = false; 1320 bool rowChildrenOverflowChanged = false;
1329 for (unsigned c = 0; c < numEffCols; c++) { 1321 for (unsigned c = 0; c < numCols(r); c++) {
1330 CellStruct& cs = cellAt(r, c); 1322 CellStruct& cs = cellAt(r, c);
1331 LayoutTableCell* cell = cs.primaryCell(); 1323 LayoutTableCell* cell = cs.primaryCell();
1332 if (!cell || cs.inColSpan || !cell->needsOverflowRecalcAfterStyleChange()) 1324 if (!cell || cs.inColSpan || !cell->needsOverflowRecalcAfterStyleChange())
1333 continue; 1325 continue;
1334 rowChildrenOverflowChanged |= cell->recalcOverflowAfterStyleChange(); 1326 rowChildrenOverflowChanged |= cell->recalcOverflowAfterStyleChange();
1335 } 1327 }
1336 if (rowChildrenOverflowChanged) 1328 if (rowChildrenOverflowChanged)
1337 rowLayouter->computeOverflow(); 1329 rowLayouter->computeOverflow();
1338 childrenOverflowChanged |= rowChildrenOverflowChanged; 1330 childrenOverflowChanged |= rowChildrenOverflowChanged;
1339 } 1331 }
1340 // TODO(crbug.com/604136): Add visual overflow from rows too. 1332 // TODO(crbug.com/604136): Add visual overflow from rows too.
1341 if (childrenOverflowChanged) 1333 if (childrenOverflowChanged)
1342 computeOverflowFromCells(totalRows, numEffCols); 1334 computeOverflowFromCells(totalRows, table()->numEffectiveColumns());
1343 return childrenOverflowChanged; 1335 return childrenOverflowChanged;
1344 } 1336 }
1345 1337
1346 void LayoutTableSection::markAllCellsWidthsDirtyAndOrNeedsLayout( 1338 void LayoutTableSection::markAllCellsWidthsDirtyAndOrNeedsLayout(
1347 LayoutTable::WhatToMarkAllCells whatToMark) { 1339 LayoutTable::WhatToMarkAllCells whatToMark) {
1348 for (LayoutTableRow* row = firstRow(); row; row = row->nextRow()) { 1340 for (LayoutTableRow* row = firstRow(); row; row = row->nextRow()) {
1349 for (LayoutTableCell* cell = row->firstCell(); cell; 1341 for (LayoutTableCell* cell = row->firstCell(); cell;
1350 cell = cell->nextCell()) { 1342 cell = cell->nextCell()) {
1351 cell->setPreferredLogicalWidthsDirty(); 1343 cell->setPreferredLogicalWidthsDirty();
1352 if (whatToMark == LayoutTable::MarkDirtyAndNeedsLayout) 1344 if (whatToMark == LayoutTable::MarkDirtyAndNeedsLayout)
(...skipping 19 matching lines...) Expand all
1372 1364
1373 const BorderValue& rb = side == BorderBefore 1365 const BorderValue& rb = side == BorderBefore
1374 ? firstRow()->style()->borderBefore() 1366 ? firstRow()->style()->borderBefore()
1375 : lastRow()->style()->borderAfter(); 1367 : lastRow()->style()->borderAfter();
1376 if (rb.style() == BorderStyleHidden) 1368 if (rb.style() == BorderStyleHidden)
1377 return -1; 1369 return -1;
1378 if (rb.style() > BorderStyleHidden && rb.width() > borderWidth) 1370 if (rb.style() > BorderStyleHidden && rb.width() > borderWidth)
1379 borderWidth = rb.width(); 1371 borderWidth = rb.width();
1380 1372
1381 bool allHidden = true; 1373 bool allHidden = true;
1374 unsigned r = side == BorderBefore ? 0 : m_grid.size() - 1;
1382 for (unsigned c = 0; c < totalCols; c++) { 1375 for (unsigned c = 0; c < totalCols; c++) {
1383 const CellStruct& current = 1376 if (c >= numCols(r))
mstensho (USE GERRIT) 2017/01/03 15:18:41 Might just as well clamp totalCols to numCols(r),
a.suchit 2017/01/04 10:35:18 Done.
1384 cellAt(side == BorderBefore ? 0 : m_grid.size() - 1, c); 1377 break;
1378 const CellStruct& current = cellAt(r, c);
1385 if (current.inColSpan || !current.hasCells()) 1379 if (current.inColSpan || !current.hasCells())
1386 continue; 1380 continue;
1387 const ComputedStyle& primaryCellStyle = current.primaryCell()->styleRef(); 1381 const ComputedStyle& primaryCellStyle = current.primaryCell()->styleRef();
1388 // FIXME: Make this work with perpendicular and flipped cells. 1382 // FIXME: Make this work with perpendicular and flipped cells.
1389 const BorderValue& cb = side == BorderBefore 1383 const BorderValue& cb = side == BorderBefore
1390 ? primaryCellStyle.borderBefore() 1384 ? primaryCellStyle.borderBefore()
1391 : primaryCellStyle.borderAfter(); 1385 : primaryCellStyle.borderAfter();
1392 // FIXME: Don't repeat for the same col group 1386 // FIXME: Don't repeat for the same col group
1393 LayoutTableCol* col = 1387 LayoutTableCol* col =
1394 table()->colElementAtAbsoluteColumn(c).innermostColOrColGroup(); 1388 table()->colElementAtAbsoluteColumn(c).innermostColOrColGroup();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1441 const BorderValue& gb = side == BorderStart ? col->style()->borderStart() 1435 const BorderValue& gb = side == BorderStart ? col->style()->borderStart()
1442 : col->style()->borderEnd(); 1436 : col->style()->borderEnd();
1443 if (gb.style() == BorderStyleHidden) 1437 if (gb.style() == BorderStyleHidden)
1444 return -1; 1438 return -1;
1445 if (gb.style() > BorderStyleHidden && gb.width() > borderWidth) 1439 if (gb.style() > BorderStyleHidden && gb.width() > borderWidth)
1446 borderWidth = gb.width(); 1440 borderWidth = gb.width();
1447 } 1441 }
1448 1442
1449 bool allHidden = true; 1443 bool allHidden = true;
1450 for (unsigned r = 0; r < m_grid.size(); r++) { 1444 for (unsigned r = 0; r < m_grid.size(); r++) {
1445 if (colIndex >= numCols(r))
1446 continue;
1451 const CellStruct& current = cellAt(r, colIndex); 1447 const CellStruct& current = cellAt(r, colIndex);
1452 if (!current.hasCells()) 1448 if (!current.hasCells())
1453 continue; 1449 continue;
1454 // FIXME: Don't repeat for the same cell 1450 // FIXME: Don't repeat for the same cell
1455 const ComputedStyle& primaryCellStyle = current.primaryCell()->styleRef(); 1451 const ComputedStyle& primaryCellStyle = current.primaryCell()->styleRef();
1456 const ComputedStyle& primaryCellParentStyle = 1452 const ComputedStyle& primaryCellParentStyle =
1457 current.primaryCell()->parent()->styleRef(); 1453 current.primaryCell()->parent()->styleRef();
1458 // FIXME: Make this work with perpendicular and flipped cells. 1454 // FIXME: Make this work with perpendicular and flipped cells.
1459 const BorderValue& cb = side == BorderStart ? primaryCellStyle.borderStart() 1455 const BorderValue& cb = side == BorderStart ? primaryCellStyle.borderStart()
1460 : primaryCellStyle.borderEnd(); 1456 : primaryCellStyle.borderEnd();
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
1692 void LayoutTableSection::setNeedsCellRecalc() { 1688 void LayoutTableSection::setNeedsCellRecalc() {
1693 m_needsCellRecalc = true; 1689 m_needsCellRecalc = true;
1694 if (LayoutTable* t = table()) 1690 if (LayoutTable* t = table())
1695 t->setNeedsSectionRecalc(); 1691 t->setNeedsSectionRecalc();
1696 } 1692 }
1697 1693
1698 unsigned LayoutTableSection::numEffectiveColumns() const { 1694 unsigned LayoutTableSection::numEffectiveColumns() const {
1699 unsigned result = 0; 1695 unsigned result = 0;
1700 1696
1701 for (unsigned r = 0; r < m_grid.size(); ++r) { 1697 for (unsigned r = 0; r < m_grid.size(); ++r) {
1702 for (unsigned c = result; c < table()->numEffectiveColumns(); ++c) { 1698 for (unsigned c = result; c < numCols(r); ++c) {
1703 const CellStruct& cell = cellAt(r, c); 1699 const CellStruct& cell = cellAt(r, c);
1704 if (cell.hasCells() || cell.inColSpan) 1700 if (cell.hasCells() || cell.inColSpan)
1705 result = c; 1701 result = c;
1706 } 1702 }
1707 } 1703 }
1708 1704
1709 return result + 1; 1705 return result + 1;
1710 } 1706 }
1711 1707
1712 const BorderValue& LayoutTableSection::borderAdjoiningStartCell( 1708 const BorderValue& LayoutTableSection::borderAdjoiningStartCell(
1713 const LayoutTableCell* cell) const { 1709 const LayoutTableCell* cell) const {
1714 ASSERT(cell->isFirstOrLastCellInRow()); 1710 ASSERT(cell->isFirstOrLastCellInRow());
1715 return hasSameDirectionAs(cell) ? style()->borderStart() 1711 return hasSameDirectionAs(cell) ? style()->borderStart()
1716 : style()->borderEnd(); 1712 : style()->borderEnd();
1717 } 1713 }
1718 1714
1719 const BorderValue& LayoutTableSection::borderAdjoiningEndCell( 1715 const BorderValue& LayoutTableSection::borderAdjoiningEndCell(
1720 const LayoutTableCell* cell) const { 1716 const LayoutTableCell* cell) const {
1721 ASSERT(cell->isFirstOrLastCellInRow()); 1717 ASSERT(cell->isFirstOrLastCellInRow());
1722 return hasSameDirectionAs(cell) ? style()->borderEnd() 1718 return hasSameDirectionAs(cell) ? style()->borderEnd()
1723 : style()->borderStart(); 1719 : style()->borderStart();
1724 } 1720 }
1725 1721
1726 const LayoutTableCell* LayoutTableSection::firstRowCellAdjoiningTableStart() 1722 const LayoutTableCell* LayoutTableSection::firstRowCellAdjoiningTableStart()
1727 const { 1723 const {
1728 unsigned adjoiningStartCellColumnIndex = 1724 unsigned adjoiningStartCellColumnIndex =
1729 hasSameDirectionAs(table()) ? 0 : table()->lastEffectiveColumnIndex(); 1725 hasSameDirectionAs(table()) ? 0 : table()->lastEffectiveColumnIndex();
1730 return cellAt(0, adjoiningStartCellColumnIndex).primaryCell(); 1726 return primaryCellAt(0, adjoiningStartCellColumnIndex);
1731 } 1727 }
1732 1728
1733 const LayoutTableCell* LayoutTableSection::firstRowCellAdjoiningTableEnd() 1729 const LayoutTableCell* LayoutTableSection::firstRowCellAdjoiningTableEnd()
1734 const { 1730 const {
1735 unsigned adjoiningEndCellColumnIndex = 1731 unsigned adjoiningEndCellColumnIndex =
1736 hasSameDirectionAs(table()) ? table()->lastEffectiveColumnIndex() : 0; 1732 hasSameDirectionAs(table()) ? table()->lastEffectiveColumnIndex() : 0;
1737 return cellAt(0, adjoiningEndCellColumnIndex).primaryCell(); 1733 return primaryCellAt(0, adjoiningEndCellColumnIndex);
1738 } 1734 }
1739 1735
1740 void LayoutTableSection::appendEffectiveColumn(unsigned pos) { 1736 void LayoutTableSection::appendEffectiveColumn(unsigned pos) {
1741 ASSERT(!m_needsCellRecalc); 1737 ASSERT(!m_needsCellRecalc);
1742 1738
1743 for (unsigned row = 0; row < m_grid.size(); ++row) 1739 for (unsigned row = 0; row < m_grid.size(); ++row)
1744 m_grid[row].row.resize(pos + 1); 1740 m_grid[row].row.resize(pos + 1);
1745 } 1741 }
1746 1742
1747 void LayoutTableSection::splitEffectiveColumn(unsigned pos, unsigned first) { 1743 void LayoutTableSection::splitEffectiveColumn(unsigned pos, unsigned first) {
1748 ASSERT(!m_needsCellRecalc); 1744 ASSERT(!m_needsCellRecalc);
1749 1745
1750 if (m_cCol > pos) 1746 if (m_cCol > pos)
1751 m_cCol++; 1747 m_cCol++;
1752 for (unsigned row = 0; row < m_grid.size(); ++row) { 1748 for (unsigned row = 0; row < m_grid.size(); ++row) {
1753 Row& r = m_grid[row].row; 1749 Row& r = m_grid[row].row;
1750 ensureCol(row, pos + 1);
1754 r.insert(pos + 1, CellStruct()); 1751 r.insert(pos + 1, CellStruct());
1755 if (r[pos].hasCells()) { 1752 if (r[pos].hasCells()) {
1756 r[pos + 1].cells.appendVector(r[pos].cells); 1753 r[pos + 1].cells.appendVector(r[pos].cells);
1757 LayoutTableCell* cell = r[pos].primaryCell(); 1754 LayoutTableCell* cell = r[pos].primaryCell();
1758 ASSERT(cell); 1755 ASSERT(cell);
1759 ASSERT(cell->colSpan() >= (r[pos].inColSpan ? 1u : 0)); 1756 ASSERT(cell->colSpan() >= (r[pos].inColSpan ? 1u : 0));
1760 unsigned colleft = cell->colSpan() - r[pos].inColSpan; 1757 unsigned colleft = cell->colSpan() - r[pos].inColSpan;
1761 if (first > colleft) 1758 if (first > colleft)
1762 r[pos + 1].inColSpan = 0; 1759 r[pos + 1].inColSpan = 0;
1763 else 1760 else
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1811 1808
1812 LayoutRect tableAlignedRect = 1809 LayoutRect tableAlignedRect =
1813 logicalRectForWritingModeAndDirection(hitTestRect); 1810 logicalRectForWritingModeAndDirection(hitTestRect);
1814 CellSpan rowSpan = spannedRows(tableAlignedRect); 1811 CellSpan rowSpan = spannedRows(tableAlignedRect);
1815 CellSpan columnSpan = spannedEffectiveColumns(tableAlignedRect); 1812 CellSpan columnSpan = spannedEffectiveColumns(tableAlignedRect);
1816 1813
1817 // Now iterate over the spanned rows and columns. 1814 // Now iterate over the spanned rows and columns.
1818 for (unsigned hitRow = rowSpan.start(); hitRow < rowSpan.end(); ++hitRow) { 1815 for (unsigned hitRow = rowSpan.start(); hitRow < rowSpan.end(); ++hitRow) {
1819 for (unsigned hitColumn = columnSpan.start(); hitColumn < columnSpan.end(); 1816 for (unsigned hitColumn = columnSpan.start(); hitColumn < columnSpan.end();
1820 ++hitColumn) { 1817 ++hitColumn) {
1818 if (hitColumn >= numCols(hitRow))
1819 continue;
mstensho (USE GERRIT) 2017/01/03 15:18:41 Should break instead.
a.suchit 2017/01/04 10:35:18 Done.
1820
1821 CellStruct& current = cellAt(hitRow, hitColumn); 1821 CellStruct& current = cellAt(hitRow, hitColumn);
1822 1822
1823 // If the cell is empty, there's nothing to do 1823 // If the cell is empty, there's nothing to do
1824 if (!current.hasCells()) 1824 if (!current.hasCells())
1825 continue; 1825 continue;
1826 1826
1827 for (unsigned i = current.cells.size(); i;) { 1827 for (unsigned i = current.cells.size(); i;) {
1828 --i; 1828 --i;
1829 LayoutTableCell* cell = current.cells[i]; 1829 LayoutTableCell* cell = current.cells[i];
1830 LayoutPoint cellPoint = 1830 LayoutPoint cellPoint =
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
2079 // the header in all columns. 2079 // the header in all columns.
2080 // Note that this is in flow thread coordinates, not visual coordinates. The 2080 // Note that this is in flow thread coordinates, not visual coordinates. The
2081 // enclosing LayoutFlowThread will convert to visual coordinates. 2081 // enclosing LayoutFlowThread will convert to visual coordinates.
2082 if (table()->header() == this && isRepeatingHeaderGroup()) 2082 if (table()->header() == this && isRepeatingHeaderGroup())
2083 rect.setHeight(table()->logicalHeight()); 2083 rect.setHeight(table()->logicalHeight());
2084 return LayoutTableBoxComponent::mapToVisualRectInAncestorSpace(ancestor, rect, 2084 return LayoutTableBoxComponent::mapToVisualRectInAncestorSpace(ancestor, rect,
2085 flags); 2085 flags);
2086 } 2086 }
2087 2087
2088 } // namespace blink 2088 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698