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) { | |
214 if (numRows <= m_grid.size()) | |
215 return; | |
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 } | |
224 | |
225 static inline void checkThatVectorIsDOMOrdered( | 213 static inline void checkThatVectorIsDOMOrdered( |
226 const Vector<LayoutTableCell*, 1>& cells) { | 214 const Vector<LayoutTableCell*, 1>& cells) { |
227 #ifndef NDEBUG | 215 #ifndef NDEBUG |
228 // This function should be called on a non-empty vector. | 216 // This function should be called on a non-empty vector. |
229 ASSERT(cells.size() > 0); | 217 ASSERT(cells.size() > 0); |
230 | 218 |
231 const LayoutTableCell* previousCell = cells[0]; | 219 const LayoutTableCell* previousCell = cells[0]; |
232 for (size_t i = 1; i < cells.size(); ++i) { | 220 for (size_t i = 1; i < cells.size(); ++i) { |
233 const LayoutTableCell* currentCell = cells[i]; | 221 const LayoutTableCell* currentCell = cells[i]; |
234 // The check assumes that all cells belong to the same row group. | 222 // The check assumes that all cells belong to the same row group. |
(...skipping 19 matching lines...) Expand all Loading... | |
254 // representation will have drifted from the table's representation. Also | 242 // representation will have drifted from the table's representation. Also |
255 // recalcCells will call addCell at a later time after sync'ing our columns' | 243 // recalcCells will call addCell at a later time after sync'ing our columns' |
256 // with the table's. | 244 // with the table's. |
257 if (needsCellRecalc()) | 245 if (needsCellRecalc()) |
258 return; | 246 return; |
259 | 247 |
260 unsigned rSpan = cell->rowSpan(); | 248 unsigned rSpan = cell->rowSpan(); |
261 unsigned cSpan = cell->colSpan(); | 249 unsigned cSpan = cell->colSpan(); |
262 const Vector<LayoutTable::ColumnStruct>& columns = | 250 const Vector<LayoutTable::ColumnStruct>& columns = |
263 table()->effectiveColumns(); | 251 table()->effectiveColumns(); |
264 unsigned nCols = columns.size(); | |
265 unsigned insertionRow = row->rowIndex(); | 252 unsigned insertionRow = row->rowIndex(); |
266 | 253 |
267 // ### mozilla still seems to do the old HTML way, even for strict DTD | 254 // ### 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 | 255 // (see the annotation on table cell layouting in the CSS specs and the |
269 // testcase below: | 256 // testcase below: |
270 // <TABLE border> | 257 // <TABLE border> |
271 // <TR><TD>1 <TD rowspan="2">2 <TD>3 <TD>4 | 258 // <TR><TD>1 <TD rowspan="2">2 <TD>3 <TD>4 |
272 // <TR><TD colspan="2">5 | 259 // <TR><TD colspan="2">5 |
273 // </TABLE> | 260 // </TABLE> |
274 while (m_cCol < nCols && (cellAt(insertionRow, m_cCol).hasCells() || | 261 while (m_cCol < numCols(insertionRow) && |
275 cellAt(insertionRow, m_cCol).inColSpan)) | 262 (cellAt(insertionRow, m_cCol).hasCells() || |
263 cellAt(insertionRow, m_cCol).inColSpan)) | |
276 m_cCol++; | 264 m_cCol++; |
277 | 265 |
278 updateLogicalHeightForCell(m_grid[insertionRow], cell); | 266 updateLogicalHeightForCell(m_grid[insertionRow], cell); |
279 | 267 |
280 ensureRows(insertionRow + rSpan); | 268 ensureRows(insertionRow + rSpan); |
281 | 269 |
282 m_grid[insertionRow].rowLayoutObject = row; | 270 m_grid[insertionRow].rowLayoutObject = row; |
283 | 271 |
284 unsigned col = m_cCol; | 272 unsigned col = m_cCol; |
285 // tell the cell where it is | 273 // tell the cell where it is |
286 bool inColSpan = false; | 274 bool inColSpan = false; |
287 while (cSpan) { | 275 while (cSpan) { |
288 unsigned currentSpan; | 276 unsigned currentSpan; |
289 if (m_cCol >= nCols) { | 277 if (m_cCol >= columns.size()) { |
290 table()->appendEffectiveColumn(cSpan); | 278 table()->appendEffectiveColumn(cSpan); |
291 currentSpan = cSpan; | 279 currentSpan = cSpan; |
292 } else { | 280 } else { |
293 if (cSpan < columns[m_cCol].span) | 281 if (cSpan < columns[m_cCol].span) |
294 table()->splitEffectiveColumn(m_cCol, cSpan); | 282 table()->splitEffectiveColumn(m_cCol, cSpan); |
295 currentSpan = columns[m_cCol].span; | 283 currentSpan = columns[m_cCol].span; |
296 } | 284 } |
297 for (unsigned r = 0; r < rSpan; r++) { | 285 for (unsigned r = 0; r < rSpan; r++) { |
286 ensureCols(insertionRow + r, m_cCol + 1); | |
298 CellStruct& c = cellAt(insertionRow + r, m_cCol); | 287 CellStruct& c = cellAt(insertionRow + r, m_cCol); |
299 ASSERT(cell); | 288 ASSERT(cell); |
300 c.cells.append(cell); | 289 c.cells.append(cell); |
301 checkThatVectorIsDOMOrdered(c.cells); | 290 checkThatVectorIsDOMOrdered(c.cells); |
302 // If cells overlap then we take the slow path for painting. | 291 // If cells overlap then we take the slow path for painting. |
303 if (c.cells.size() > 1) | 292 if (c.cells.size() > 1) |
304 m_hasMultipleCellLevels = true; | 293 m_hasMultipleCellLevels = true; |
305 if (inColSpan) | 294 if (inColSpan) |
306 c.inColSpan = true; | 295 c.inColSpan = true; |
307 } | 296 } |
(...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1132 | 1121 |
1133 // FIXME: Changing the height without a layout can change the overflow so it | 1122 // FIXME: Changing the height without a layout can change the overflow so it |
1134 // seems wrong. | 1123 // seems wrong. |
1135 | 1124 |
1136 unsigned totalRows = m_grid.size(); | 1125 unsigned totalRows = m_grid.size(); |
1137 | 1126 |
1138 // Set the width of our section now. The rows will also be this width. | 1127 // Set the width of our section now. The rows will also be this width. |
1139 setLogicalWidth(table()->contentLogicalWidth()); | 1128 setLogicalWidth(table()->contentLogicalWidth()); |
1140 | 1129 |
1141 int vspacing = table()->vBorderSpacing(); | 1130 int vspacing = table()->vBorderSpacing(); |
1142 unsigned nEffCols = table()->numEffectiveColumns(); | |
1143 LayoutState state(*this); | 1131 LayoutState state(*this); |
1144 | 1132 |
1145 // Set the rows' location and size. | 1133 // Set the rows' location and size. |
1146 for (unsigned r = 0; r < totalRows; r++) { | 1134 for (unsigned r = 0; r < totalRows; r++) { |
1147 LayoutTableRow* rowLayoutObject = m_grid[r].rowLayoutObject; | 1135 LayoutTableRow* rowLayoutObject = m_grid[r].rowLayoutObject; |
1148 if (rowLayoutObject) { | 1136 if (rowLayoutObject) { |
1149 rowLayoutObject->setLogicalLocation(LayoutPoint(0, m_rowPos[r])); | 1137 rowLayoutObject->setLogicalLocation(LayoutPoint(0, m_rowPos[r])); |
1150 rowLayoutObject->setLogicalWidth(logicalWidth()); | 1138 rowLayoutObject->setLogicalWidth(logicalWidth()); |
1151 LayoutUnit rowLogicalHeight(m_rowPos[r + 1] - m_rowPos[r] - vspacing); | 1139 LayoutUnit rowLogicalHeight(m_rowPos[r + 1] - m_rowPos[r] - vspacing); |
1152 if (state.isPaginated() && r + 1 < totalRows) { | 1140 if (state.isPaginated() && r + 1 < totalRows) { |
1153 // If the next row has a pagination strut, we need to subtract it. It | 1141 // If the next row has a pagination strut, we need to subtract it. It |
1154 // should not be included in this row's height. | 1142 // should not be included in this row's height. |
1155 if (LayoutTableRow* nextRowObject = m_grid[r + 1].rowLayoutObject) | 1143 if (LayoutTableRow* nextRowObject = m_grid[r + 1].rowLayoutObject) |
1156 rowLogicalHeight -= nextRowObject->paginationStrut(); | 1144 rowLogicalHeight -= nextRowObject->paginationStrut(); |
1157 } | 1145 } |
1158 rowLayoutObject->setLogicalHeight(rowLogicalHeight); | 1146 rowLayoutObject->setLogicalHeight(rowLogicalHeight); |
1159 rowLayoutObject->updateLayerTransformAfterLayout(); | 1147 rowLayoutObject->updateLayerTransformAfterLayout(); |
1160 } | 1148 } |
1161 } | 1149 } |
1162 | 1150 |
1163 // Vertically align and flex the cells in each row. | 1151 // Vertically align and flex the cells in each row. |
1164 for (unsigned r = 0; r < totalRows; r++) { | 1152 for (unsigned r = 0; r < totalRows; r++) { |
1165 LayoutTableRow* rowLayoutObject = m_grid[r].rowLayoutObject; | 1153 LayoutTableRow* rowLayoutObject = m_grid[r].rowLayoutObject; |
1166 | 1154 |
1167 for (unsigned c = 0; c < nEffCols; c++) { | 1155 for (unsigned c = 0; c < numCols(r); c++) { |
1168 CellStruct& cs = cellAt(r, c); | 1156 CellStruct& cs = cellAt(r, c); |
1169 LayoutTableCell* cell = cs.primaryCell(); | 1157 LayoutTableCell* cell = cs.primaryCell(); |
1170 | 1158 |
1171 if (!cell || cs.inColSpan) | 1159 if (!cell || cs.inColSpan) |
1172 continue; | 1160 continue; |
1173 | 1161 |
1174 if (cell->rowIndex() != r) | 1162 if (cell->rowIndex() != r) |
1175 continue; // Rowspanned cells are handled in the first row they occur. | 1163 continue; // Rowspanned cells are handled in the first row they occur. |
1176 | 1164 |
1177 int rHeight; | 1165 int rHeight; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1221 } | 1209 } |
1222 } | 1210 } |
1223 if (rowLayoutObject) | 1211 if (rowLayoutObject) |
1224 rowLayoutObject->computeOverflow(); | 1212 rowLayoutObject->computeOverflow(); |
1225 } | 1213 } |
1226 | 1214 |
1227 ASSERT(!needsLayout()); | 1215 ASSERT(!needsLayout()); |
1228 | 1216 |
1229 setLogicalHeight(LayoutUnit(m_rowPos[totalRows])); | 1217 setLogicalHeight(LayoutUnit(m_rowPos[totalRows])); |
1230 | 1218 |
1231 computeOverflowFromCells(totalRows, nEffCols); | 1219 computeOverflowFromCells(totalRows, table()->numEffectiveColumns()); |
1232 } | 1220 } |
1233 | 1221 |
1234 int LayoutTableSection::paginationStrutForRow(LayoutTableRow* row, | 1222 int LayoutTableSection::paginationStrutForRow(LayoutTableRow* row, |
1235 LayoutUnit logicalOffset) const { | 1223 LayoutUnit logicalOffset) const { |
1236 DCHECK(row); | 1224 DCHECK(row); |
1237 if (row->getPaginationBreakability() == AllowAnyBreaks) | 1225 if (row->getPaginationBreakability() == AllowAnyBreaks) |
1238 return 0; | 1226 return 0; |
1239 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset); | 1227 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset); |
1240 if (!pageLogicalHeight) | 1228 if (!pageLogicalHeight) |
1241 return 0; | 1229 return 0; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1277 : gMaxAllowedOverflowingCellRatioForFastPaintPath * totalCellsCount; | 1265 : gMaxAllowedOverflowingCellRatioForFastPaintPath * totalCellsCount; |
1278 | 1266 |
1279 m_overflow.reset(); | 1267 m_overflow.reset(); |
1280 m_overflowingCells.clear(); | 1268 m_overflowingCells.clear(); |
1281 m_forceSlowPaintPathWithOverflowingCell = false; | 1269 m_forceSlowPaintPathWithOverflowingCell = false; |
1282 #if ENABLE(ASSERT) | 1270 #if ENABLE(ASSERT) |
1283 bool hasOverflowingCell = false; | 1271 bool hasOverflowingCell = false; |
1284 #endif | 1272 #endif |
1285 // Now that our height has been determined, add in overflow from cells. | 1273 // Now that our height has been determined, add in overflow from cells. |
1286 for (unsigned r = 0; r < totalRows; r++) { | 1274 for (unsigned r = 0; r < totalRows; r++) { |
1287 for (unsigned c = 0; c < nEffCols; c++) { | 1275 for (unsigned c = 0; c < numCols(r); c++) { |
1288 CellStruct& cs = cellAt(r, c); | 1276 CellStruct& cs = cellAt(r, c); |
1289 LayoutTableCell* cell = cs.primaryCell(); | 1277 LayoutTableCell* cell = cs.primaryCell(); |
1290 if (!cell || cs.inColSpan) | 1278 if (!cell || cs.inColSpan) |
1291 continue; | 1279 continue; |
1292 if (r < totalRows - 1 && cell == primaryCellAt(r + 1, c)) | 1280 if (r < totalRows - 1 && cell == primaryCellAt(r + 1, c)) |
1293 continue; | 1281 continue; |
1294 addOverflowFromChild(cell); | 1282 addOverflowFromChild(cell); |
1295 #if ENABLE(ASSERT) | 1283 #if ENABLE(ASSERT) |
1296 hasOverflowingCell |= cell->hasVisualOverflow(); | 1284 hasOverflowingCell |= cell->hasVisualOverflow(); |
1297 #endif | 1285 #endif |
(...skipping 12 matching lines...) Expand all Loading... | |
1310 } | 1298 } |
1311 } | 1299 } |
1312 | 1300 |
1313 ASSERT(hasOverflowingCell == this->hasOverflowingCell()); | 1301 ASSERT(hasOverflowingCell == this->hasOverflowingCell()); |
1314 } | 1302 } |
1315 | 1303 |
1316 bool LayoutTableSection::recalcChildOverflowAfterStyleChange() { | 1304 bool LayoutTableSection::recalcChildOverflowAfterStyleChange() { |
1317 ASSERT(childNeedsOverflowRecalcAfterStyleChange()); | 1305 ASSERT(childNeedsOverflowRecalcAfterStyleChange()); |
1318 clearChildNeedsOverflowRecalcAfterStyleChange(); | 1306 clearChildNeedsOverflowRecalcAfterStyleChange(); |
1319 unsigned totalRows = m_grid.size(); | 1307 unsigned totalRows = m_grid.size(); |
1320 unsigned numEffCols = table()->numEffectiveColumns(); | |
1321 bool childrenOverflowChanged = false; | 1308 bool childrenOverflowChanged = false; |
1322 for (unsigned r = 0; r < totalRows; r++) { | 1309 for (unsigned r = 0; r < totalRows; r++) { |
1323 LayoutTableRow* rowLayouter = rowLayoutObjectAt(r); | 1310 LayoutTableRow* rowLayouter = rowLayoutObjectAt(r); |
1324 if (!rowLayouter || | 1311 if (!rowLayouter || |
1325 !rowLayouter->childNeedsOverflowRecalcAfterStyleChange()) | 1312 !rowLayouter->childNeedsOverflowRecalcAfterStyleChange()) |
1326 continue; | 1313 continue; |
1327 rowLayouter->clearChildNeedsOverflowRecalcAfterStyleChange(); | 1314 rowLayouter->clearChildNeedsOverflowRecalcAfterStyleChange(); |
1328 bool rowChildrenOverflowChanged = false; | 1315 bool rowChildrenOverflowChanged = false; |
1329 for (unsigned c = 0; c < numEffCols; c++) { | 1316 for (unsigned c = 0; c < numCols(r); c++) { |
1330 CellStruct& cs = cellAt(r, c); | 1317 CellStruct& cs = cellAt(r, c); |
1331 LayoutTableCell* cell = cs.primaryCell(); | 1318 LayoutTableCell* cell = cs.primaryCell(); |
1332 if (!cell || cs.inColSpan || !cell->needsOverflowRecalcAfterStyleChange()) | 1319 if (!cell || cs.inColSpan || !cell->needsOverflowRecalcAfterStyleChange()) |
1333 continue; | 1320 continue; |
1334 rowChildrenOverflowChanged |= cell->recalcOverflowAfterStyleChange(); | 1321 rowChildrenOverflowChanged |= cell->recalcOverflowAfterStyleChange(); |
1335 } | 1322 } |
1336 if (rowChildrenOverflowChanged) | 1323 if (rowChildrenOverflowChanged) |
1337 rowLayouter->computeOverflow(); | 1324 rowLayouter->computeOverflow(); |
1338 childrenOverflowChanged |= rowChildrenOverflowChanged; | 1325 childrenOverflowChanged |= rowChildrenOverflowChanged; |
1339 } | 1326 } |
1340 // TODO(crbug.com/604136): Add visual overflow from rows too. | 1327 // TODO(crbug.com/604136): Add visual overflow from rows too. |
1341 if (childrenOverflowChanged) | 1328 if (childrenOverflowChanged) |
1342 computeOverflowFromCells(totalRows, numEffCols); | 1329 computeOverflowFromCells(totalRows, table()->numEffectiveColumns()); |
1343 return childrenOverflowChanged; | 1330 return childrenOverflowChanged; |
1344 } | 1331 } |
1345 | 1332 |
1346 void LayoutTableSection::markAllCellsWidthsDirtyAndOrNeedsLayout( | 1333 void LayoutTableSection::markAllCellsWidthsDirtyAndOrNeedsLayout( |
1347 LayoutTable::WhatToMarkAllCells whatToMark) { | 1334 LayoutTable::WhatToMarkAllCells whatToMark) { |
1348 for (LayoutTableRow* row = firstRow(); row; row = row->nextRow()) { | 1335 for (LayoutTableRow* row = firstRow(); row; row = row->nextRow()) { |
1349 for (LayoutTableCell* cell = row->firstCell(); cell; | 1336 for (LayoutTableCell* cell = row->firstCell(); cell; |
1350 cell = cell->nextCell()) { | 1337 cell = cell->nextCell()) { |
1351 cell->setPreferredLogicalWidthsDirty(); | 1338 cell->setPreferredLogicalWidthsDirty(); |
1352 if (whatToMark == LayoutTable::MarkDirtyAndNeedsLayout) | 1339 if (whatToMark == LayoutTable::MarkDirtyAndNeedsLayout) |
1353 cell->setChildNeedsLayout(); | 1340 cell->setChildNeedsLayout(); |
1354 } | 1341 } |
1355 } | 1342 } |
1356 } | 1343 } |
1357 | 1344 |
1358 int LayoutTableSection::calcBlockDirectionOuterBorder( | 1345 int LayoutTableSection::calcBlockDirectionOuterBorder( |
1359 BlockBorderSide side) const { | 1346 BlockBorderSide side) const { |
1360 unsigned totalCols = table()->numEffectiveColumns(); | 1347 if (!m_grid.size() || !table()->numEffectiveColumns()) |
1361 if (!m_grid.size() || !totalCols) | |
1362 return 0; | 1348 return 0; |
1363 | 1349 |
1364 int borderWidth = 0; | 1350 int borderWidth = 0; |
1365 | 1351 |
1366 const BorderValue& sb = | 1352 const BorderValue& sb = |
1367 side == BorderBefore ? style()->borderBefore() : style()->borderAfter(); | 1353 side == BorderBefore ? style()->borderBefore() : style()->borderAfter(); |
1368 if (sb.style() == BorderStyleHidden) | 1354 if (sb.style() == BorderStyleHidden) |
1369 return -1; | 1355 return -1; |
1370 if (sb.style() > BorderStyleHidden) | 1356 if (sb.style() > BorderStyleHidden) |
1371 borderWidth = sb.width(); | 1357 borderWidth = sb.width(); |
1372 | 1358 |
1373 const BorderValue& rb = side == BorderBefore | 1359 const BorderValue& rb = side == BorderBefore |
1374 ? firstRow()->style()->borderBefore() | 1360 ? firstRow()->style()->borderBefore() |
1375 : lastRow()->style()->borderAfter(); | 1361 : lastRow()->style()->borderAfter(); |
1376 if (rb.style() == BorderStyleHidden) | 1362 if (rb.style() == BorderStyleHidden) |
1377 return -1; | 1363 return -1; |
1378 if (rb.style() > BorderStyleHidden && rb.width() > borderWidth) | 1364 if (rb.style() > BorderStyleHidden && rb.width() > borderWidth) |
1379 borderWidth = rb.width(); | 1365 borderWidth = rb.width(); |
1380 | 1366 |
1381 bool allHidden = true; | 1367 bool allHidden = true; |
1382 for (unsigned c = 0; c < totalCols; c++) { | 1368 unsigned r = side == BorderBefore ? 0 : m_grid.size() - 1; |
1383 const CellStruct& current = | 1369 for (unsigned c = 0; c < numCols(r); c++) { |
1384 cellAt(side == BorderBefore ? 0 : m_grid.size() - 1, c); | 1370 const CellStruct& current = cellAt(r, c); |
1385 if (current.inColSpan || !current.hasCells()) | 1371 if (current.inColSpan || !current.hasCells()) |
1386 continue; | 1372 continue; |
1387 const ComputedStyle& primaryCellStyle = current.primaryCell()->styleRef(); | 1373 const ComputedStyle& primaryCellStyle = current.primaryCell()->styleRef(); |
1388 // FIXME: Make this work with perpendicular and flipped cells. | 1374 // FIXME: Make this work with perpendicular and flipped cells. |
1389 const BorderValue& cb = side == BorderBefore | 1375 const BorderValue& cb = side == BorderBefore |
1390 ? primaryCellStyle.borderBefore() | 1376 ? primaryCellStyle.borderBefore() |
1391 : primaryCellStyle.borderAfter(); | 1377 : primaryCellStyle.borderAfter(); |
1392 // FIXME: Don't repeat for the same col group | 1378 // FIXME: Don't repeat for the same col group |
1393 LayoutTableCol* col = | 1379 LayoutTableCol* col = |
1394 table()->colElementAtAbsoluteColumn(c).innermostColOrColGroup(); | 1380 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() | 1427 const BorderValue& gb = side == BorderStart ? col->style()->borderStart() |
1442 : col->style()->borderEnd(); | 1428 : col->style()->borderEnd(); |
1443 if (gb.style() == BorderStyleHidden) | 1429 if (gb.style() == BorderStyleHidden) |
1444 return -1; | 1430 return -1; |
1445 if (gb.style() > BorderStyleHidden && gb.width() > borderWidth) | 1431 if (gb.style() > BorderStyleHidden && gb.width() > borderWidth) |
1446 borderWidth = gb.width(); | 1432 borderWidth = gb.width(); |
1447 } | 1433 } |
1448 | 1434 |
1449 bool allHidden = true; | 1435 bool allHidden = true; |
1450 for (unsigned r = 0; r < m_grid.size(); r++) { | 1436 for (unsigned r = 0; r < m_grid.size(); r++) { |
1437 if (colIndex >= numCols(r)) | |
1438 continue; | |
1451 const CellStruct& current = cellAt(r, colIndex); | 1439 const CellStruct& current = cellAt(r, colIndex); |
1452 if (!current.hasCells()) | 1440 if (!current.hasCells()) |
1453 continue; | 1441 continue; |
1454 // FIXME: Don't repeat for the same cell | 1442 // FIXME: Don't repeat for the same cell |
1455 const ComputedStyle& primaryCellStyle = current.primaryCell()->styleRef(); | 1443 const ComputedStyle& primaryCellStyle = current.primaryCell()->styleRef(); |
1456 const ComputedStyle& primaryCellParentStyle = | 1444 const ComputedStyle& primaryCellParentStyle = |
1457 current.primaryCell()->parent()->styleRef(); | 1445 current.primaryCell()->parent()->styleRef(); |
1458 // FIXME: Make this work with perpendicular and flipped cells. | 1446 // FIXME: Make this work with perpendicular and flipped cells. |
1459 const BorderValue& cb = side == BorderStart ? primaryCellStyle.borderStart() | 1447 const BorderValue& cb = side == BorderStart ? primaryCellStyle.borderStart() |
1460 : primaryCellStyle.borderEnd(); | 1448 : primaryCellStyle.borderEnd(); |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1692 void LayoutTableSection::setNeedsCellRecalc() { | 1680 void LayoutTableSection::setNeedsCellRecalc() { |
1693 m_needsCellRecalc = true; | 1681 m_needsCellRecalc = true; |
1694 if (LayoutTable* t = table()) | 1682 if (LayoutTable* t = table()) |
1695 t->setNeedsSectionRecalc(); | 1683 t->setNeedsSectionRecalc(); |
1696 } | 1684 } |
1697 | 1685 |
1698 unsigned LayoutTableSection::numEffectiveColumns() const { | 1686 unsigned LayoutTableSection::numEffectiveColumns() const { |
1699 unsigned result = 0; | 1687 unsigned result = 0; |
1700 | 1688 |
1701 for (unsigned r = 0; r < m_grid.size(); ++r) { | 1689 for (unsigned r = 0; r < m_grid.size(); ++r) { |
1702 for (unsigned c = result; c < table()->numEffectiveColumns(); ++c) { | 1690 for (unsigned c = result; c < numCols(r); ++c) { |
1703 const CellStruct& cell = cellAt(r, c); | 1691 const CellStruct& cell = cellAt(r, c); |
1704 if (cell.hasCells() || cell.inColSpan) | 1692 if (cell.hasCells() || cell.inColSpan) |
1705 result = c; | 1693 result = c; |
1706 } | 1694 } |
1707 } | 1695 } |
1708 | 1696 |
1709 return result + 1; | 1697 return result + 1; |
1710 } | 1698 } |
1711 | 1699 |
1712 const BorderValue& LayoutTableSection::borderAdjoiningStartCell( | 1700 const BorderValue& LayoutTableSection::borderAdjoiningStartCell( |
1713 const LayoutTableCell* cell) const { | 1701 const LayoutTableCell* cell) const { |
1714 ASSERT(cell->isFirstOrLastCellInRow()); | 1702 ASSERT(cell->isFirstOrLastCellInRow()); |
1715 return hasSameDirectionAs(cell) ? style()->borderStart() | 1703 return hasSameDirectionAs(cell) ? style()->borderStart() |
1716 : style()->borderEnd(); | 1704 : style()->borderEnd(); |
1717 } | 1705 } |
1718 | 1706 |
1719 const BorderValue& LayoutTableSection::borderAdjoiningEndCell( | 1707 const BorderValue& LayoutTableSection::borderAdjoiningEndCell( |
1720 const LayoutTableCell* cell) const { | 1708 const LayoutTableCell* cell) const { |
1721 ASSERT(cell->isFirstOrLastCellInRow()); | 1709 ASSERT(cell->isFirstOrLastCellInRow()); |
1722 return hasSameDirectionAs(cell) ? style()->borderEnd() | 1710 return hasSameDirectionAs(cell) ? style()->borderEnd() |
1723 : style()->borderStart(); | 1711 : style()->borderStart(); |
1724 } | 1712 } |
1725 | 1713 |
1726 const LayoutTableCell* LayoutTableSection::firstRowCellAdjoiningTableStart() | 1714 const LayoutTableCell* LayoutTableSection::firstRowCellAdjoiningTableStart() |
1727 const { | 1715 const { |
1728 unsigned adjoiningStartCellColumnIndex = | 1716 unsigned adjoiningStartCellColumnIndex = |
1729 hasSameDirectionAs(table()) ? 0 : table()->lastEffectiveColumnIndex(); | 1717 hasSameDirectionAs(table()) ? 0 : table()->lastEffectiveColumnIndex(); |
1730 return cellAt(0, adjoiningStartCellColumnIndex).primaryCell(); | 1718 return primaryCellAt(0, adjoiningStartCellColumnIndex); |
1731 } | 1719 } |
1732 | 1720 |
1733 const LayoutTableCell* LayoutTableSection::firstRowCellAdjoiningTableEnd() | 1721 const LayoutTableCell* LayoutTableSection::firstRowCellAdjoiningTableEnd() |
1734 const { | 1722 const { |
1735 unsigned adjoiningEndCellColumnIndex = | 1723 unsigned adjoiningEndCellColumnIndex = |
1736 hasSameDirectionAs(table()) ? table()->lastEffectiveColumnIndex() : 0; | 1724 hasSameDirectionAs(table()) ? table()->lastEffectiveColumnIndex() : 0; |
1737 return cellAt(0, adjoiningEndCellColumnIndex).primaryCell(); | 1725 return primaryCellAt(0, adjoiningEndCellColumnIndex); |
1738 } | 1726 } |
1739 | 1727 |
1740 void LayoutTableSection::appendEffectiveColumn(unsigned pos) { | 1728 void LayoutTableSection::appendEffectiveColumn(unsigned pos) { |
1741 ASSERT(!m_needsCellRecalc); | 1729 ASSERT(!m_needsCellRecalc); |
1742 | 1730 |
1743 for (unsigned row = 0; row < m_grid.size(); ++row) | 1731 for (unsigned row = 0; row < m_grid.size(); ++row) |
1744 m_grid[row].row.resize(pos + 1); | 1732 m_grid[row].row.resize(pos + 1); |
1745 } | 1733 } |
1746 | 1734 |
1747 void LayoutTableSection::splitEffectiveColumn(unsigned pos, unsigned first) { | 1735 void LayoutTableSection::splitEffectiveColumn(unsigned pos, unsigned first) { |
1748 ASSERT(!m_needsCellRecalc); | 1736 ASSERT(!m_needsCellRecalc); |
1749 | 1737 |
1750 if (m_cCol > pos) | 1738 if (m_cCol > pos) |
1751 m_cCol++; | 1739 m_cCol++; |
1752 for (unsigned row = 0; row < m_grid.size(); ++row) { | 1740 for (unsigned row = 0; row < m_grid.size(); ++row) { |
1753 Row& r = m_grid[row].row; | 1741 Row& r = m_grid[row].row; |
1742 ensureCols(row, pos + 1 + 1); | |
mstensho (USE GERRIT)
2017/01/04 10:56:06
pos + 2, perhaps? :)
a.suchit
2017/01/05 03:34:31
Done.
dgrogan
2017/09/19 00:47:43
Why is this extra +1 needed? Or, actually, why the
mstensho (USE GERRIT)
2017/09/19 19:10:26
Not much at all. :)
According to the WTF::Vector:
a.suchit2
2017/09/20 04:52:09
EnsureCols is used to ensure that insert would be
| |
1754 r.insert(pos + 1, CellStruct()); | 1743 r.insert(pos + 1, CellStruct()); |
1755 if (r[pos].hasCells()) { | 1744 if (r[pos].hasCells()) { |
1756 r[pos + 1].cells.appendVector(r[pos].cells); | 1745 r[pos + 1].cells.appendVector(r[pos].cells); |
1757 LayoutTableCell* cell = r[pos].primaryCell(); | 1746 LayoutTableCell* cell = r[pos].primaryCell(); |
1758 ASSERT(cell); | 1747 ASSERT(cell); |
1759 ASSERT(cell->colSpan() >= (r[pos].inColSpan ? 1u : 0)); | 1748 ASSERT(cell->colSpan() >= (r[pos].inColSpan ? 1u : 0)); |
1760 unsigned colleft = cell->colSpan() - r[pos].inColSpan; | 1749 unsigned colleft = cell->colSpan() - r[pos].inColSpan; |
1761 if (first > colleft) | 1750 if (first > colleft) |
1762 r[pos + 1].inColSpan = 0; | 1751 r[pos + 1].inColSpan = 0; |
1763 else | 1752 else |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1811 | 1800 |
1812 LayoutRect tableAlignedRect = | 1801 LayoutRect tableAlignedRect = |
1813 logicalRectForWritingModeAndDirection(hitTestRect); | 1802 logicalRectForWritingModeAndDirection(hitTestRect); |
1814 CellSpan rowSpan = spannedRows(tableAlignedRect); | 1803 CellSpan rowSpan = spannedRows(tableAlignedRect); |
1815 CellSpan columnSpan = spannedEffectiveColumns(tableAlignedRect); | 1804 CellSpan columnSpan = spannedEffectiveColumns(tableAlignedRect); |
1816 | 1805 |
1817 // Now iterate over the spanned rows and columns. | 1806 // Now iterate over the spanned rows and columns. |
1818 for (unsigned hitRow = rowSpan.start(); hitRow < rowSpan.end(); ++hitRow) { | 1807 for (unsigned hitRow = rowSpan.start(); hitRow < rowSpan.end(); ++hitRow) { |
1819 for (unsigned hitColumn = columnSpan.start(); hitColumn < columnSpan.end(); | 1808 for (unsigned hitColumn = columnSpan.start(); hitColumn < columnSpan.end(); |
1820 ++hitColumn) { | 1809 ++hitColumn) { |
1810 if (hitColumn >= numCols(hitRow)) | |
1811 break; | |
1812 | |
1821 CellStruct& current = cellAt(hitRow, hitColumn); | 1813 CellStruct& current = cellAt(hitRow, hitColumn); |
1822 | 1814 |
1823 // If the cell is empty, there's nothing to do | 1815 // If the cell is empty, there's nothing to do |
1824 if (!current.hasCells()) | 1816 if (!current.hasCells()) |
1825 continue; | 1817 continue; |
1826 | 1818 |
1827 for (unsigned i = current.cells.size(); i;) { | 1819 for (unsigned i = current.cells.size(); i;) { |
1828 --i; | 1820 --i; |
1829 LayoutTableCell* cell = current.cells[i]; | 1821 LayoutTableCell* cell = current.cells[i]; |
1830 LayoutPoint cellPoint = | 1822 LayoutPoint cellPoint = |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2079 // the header in all columns. | 2071 // the header in all columns. |
2080 // Note that this is in flow thread coordinates, not visual coordinates. The | 2072 // Note that this is in flow thread coordinates, not visual coordinates. The |
2081 // enclosing LayoutFlowThread will convert to visual coordinates. | 2073 // enclosing LayoutFlowThread will convert to visual coordinates. |
2082 if (table()->header() == this && isRepeatingHeaderGroup()) | 2074 if (table()->header() == this && isRepeatingHeaderGroup()) |
2083 rect.setHeight(table()->logicalHeight()); | 2075 rect.setHeight(table()->logicalHeight()); |
2084 return LayoutTableBoxComponent::mapToVisualRectInAncestorSpace(ancestor, rect, | 2076 return LayoutTableBoxComponent::mapToVisualRectInAncestorSpace(ancestor, rect, |
2085 flags); | 2077 flags); |
2086 } | 2078 } |
2087 | 2079 |
2088 } // namespace blink | 2080 } // namespace blink |
OLD | NEW |