Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |