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, 2007, 2008, 2009 Apple Inc. | 7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. |
8 * All rights reserved. | 8 * All rights reserved. |
9 * | 9 * |
10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 m_absoluteColumnIndex(unsetColumnIndex), | 60 m_absoluteColumnIndex(unsetColumnIndex), |
61 m_cellWidthChanged(false), | 61 m_cellWidthChanged(false), |
62 m_intrinsicPaddingBefore(0), | 62 m_intrinsicPaddingBefore(0), |
63 m_intrinsicPaddingAfter(0) { | 63 m_intrinsicPaddingAfter(0) { |
64 // We only update the flags when notified of DOM changes in | 64 // We only update the flags when notified of DOM changes in |
65 // colSpanOrRowSpanChanged() so we need to set their initial values here in | 65 // colSpanOrRowSpanChanged() so we need to set their initial values here in |
66 // case something asks for colSpan()/rowSpan() before then. | 66 // case something asks for colSpan()/rowSpan() before then. |
67 updateColAndRowSpanFlags(); | 67 updateColAndRowSpanFlags(); |
68 } | 68 } |
69 | 69 |
| 70 LayoutTableCell::CollapsedBorderValues::CollapsedBorderValues( |
| 71 const LayoutTable& layoutTable, |
| 72 const CollapsedBorderValue& startBorder, |
| 73 const CollapsedBorderValue& endBorder, |
| 74 const CollapsedBorderValue& beforeBorder, |
| 75 const CollapsedBorderValue& afterBorder) |
| 76 : m_layoutTable(layoutTable), |
| 77 m_startBorder(startBorder), |
| 78 m_endBorder(endBorder), |
| 79 m_beforeBorder(beforeBorder), |
| 80 m_afterBorder(afterBorder) {} |
| 81 |
| 82 void LayoutTableCell::CollapsedBorderValues::setCollapsedBorderValues( |
| 83 const CollapsedBorderValues& other) { |
| 84 m_startBorder = other.startBorder(); |
| 85 m_endBorder = other.endBorder(); |
| 86 m_beforeBorder = other.beforeBorder(); |
| 87 m_afterBorder = other.afterBorder(); |
| 88 } |
| 89 |
| 90 String LayoutTableCell::CollapsedBorderValues::debugName() const { |
| 91 return "CollapsedBorderValues"; |
| 92 } |
| 93 |
| 94 LayoutRect LayoutTableCell::CollapsedBorderValues::visualRect() const { |
| 95 return m_layoutTable.visualRect(); |
| 96 } |
| 97 |
70 void LayoutTableCell::willBeRemovedFromTree() { | 98 void LayoutTableCell::willBeRemovedFromTree() { |
71 LayoutBlockFlow::willBeRemovedFromTree(); | 99 LayoutBlockFlow::willBeRemovedFromTree(); |
72 | 100 |
73 section()->setNeedsCellRecalc(); | 101 section()->setNeedsCellRecalc(); |
74 | 102 |
75 // When borders collapse, removing a cell can affect the the width of | 103 // When borders collapse, removing a cell can affect the the width of |
76 // neighboring cells. | 104 // neighboring cells. |
77 LayoutTable* enclosingTable = table(); | 105 LayoutTable* enclosingTable = table(); |
78 DCHECK(enclosingTable); | 106 DCHECK(enclosingTable); |
79 if (!enclosingTable->collapseBorders()) | 107 if (!enclosingTable->collapseBorders()) |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 clearIntrinsicPadding(); | 493 clearIntrinsicPadding(); |
466 | 494 |
467 // If border was changed, notify table. | 495 // If border was changed, notify table. |
468 if (!parent()) | 496 if (!parent()) |
469 return; | 497 return; |
470 LayoutTable* table = this->table(); | 498 LayoutTable* table = this->table(); |
471 if (!table) | 499 if (!table) |
472 return; | 500 return; |
473 if (!table->selfNeedsLayout() && !table->normalChildNeedsLayout() && | 501 if (!table->selfNeedsLayout() && !table->normalChildNeedsLayout() && |
474 oldStyle && oldStyle->border() != style()->border()) | 502 oldStyle && oldStyle->border() != style()->border()) |
475 table->invalidateCollapsedBorders(PaintInvalidationStyleChange); | 503 table->invalidateCollapsedBorders(); |
476 | 504 |
477 if (LayoutTableBoxComponent::doCellsHaveDirtyWidth(*this, *table, diff, | 505 if (LayoutTableBoxComponent::doCellsHaveDirtyWidth(*this, *table, diff, |
478 *oldStyle)) { | 506 *oldStyle)) { |
479 if (previousCell()) { | 507 if (previousCell()) { |
480 // TODO(dgrogan) Add a layout test showing that setChildNeedsLayout is | 508 // TODO(dgrogan) Add a layout test showing that setChildNeedsLayout is |
481 // needed instead of setNeedsLayout. | 509 // needed instead of setNeedsLayout. |
482 previousCell()->setChildNeedsLayout(); | 510 previousCell()->setChildNeedsLayout(); |
483 previousCell()->setPreferredLogicalWidthsDirty(MarkOnlyThis); | 511 previousCell()->setPreferredLogicalWidthsDirty(MarkOnlyThis); |
484 } | 512 } |
485 if (nextCell()) { | 513 if (nextCell()) { |
(...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1268 : 0)) / | 1296 : 0)) / |
1269 2; | 1297 2; |
1270 return 0; | 1298 return 0; |
1271 } | 1299 } |
1272 | 1300 |
1273 void LayoutTableCell::paint(const PaintInfo& paintInfo, | 1301 void LayoutTableCell::paint(const PaintInfo& paintInfo, |
1274 const LayoutPoint& paintOffset) const { | 1302 const LayoutPoint& paintOffset) const { |
1275 TableCellPainter(*this).paint(paintInfo, paintOffset); | 1303 TableCellPainter(*this).paint(paintInfo, paintOffset); |
1276 } | 1304 } |
1277 | 1305 |
1278 static void addBorderStyle(Vector<CollapsedBorderValue>& borderValues, | 1306 static void addBorderStyle(LayoutTable::CollapsedBorderValues& borderValues, |
1279 CollapsedBorderValue borderValue) { | 1307 CollapsedBorderValue borderValue) { |
1280 if (!borderValue.isVisible()) | 1308 if (!borderValue.isVisible()) |
1281 return; | 1309 return; |
1282 size_t count = borderValues.size(); | 1310 size_t count = borderValues.size(); |
1283 for (size_t i = 0; i < count; ++i) { | 1311 for (size_t i = 0; i < count; ++i) { |
1284 if (borderValues[i].isSameIgnoringColor(borderValue)) | 1312 if (borderValues[i].isSameIgnoringColor(borderValue)) |
1285 return; | 1313 return; |
1286 } | 1314 } |
1287 borderValues.append(borderValue); | 1315 borderValues.append(borderValue); |
1288 } | 1316 } |
1289 | 1317 |
1290 bool LayoutTableCell::collectBorderValues( | 1318 void LayoutTableCell::collectBorderValues( |
1291 Vector<CollapsedBorderValue>& borderValues) { | 1319 LayoutTable::CollapsedBorderValues& borderValues) { |
1292 CollapsedBorderValues newValues = { | 1320 CollapsedBorderValues newValues( |
1293 computeCollapsedStartBorder(), computeCollapsedEndBorder(), | 1321 *table(), computeCollapsedStartBorder(), computeCollapsedEndBorder(), |
1294 computeCollapsedBeforeBorder(), computeCollapsedAfterBorder()}; | 1322 computeCollapsedBeforeBorder(), computeCollapsedAfterBorder()); |
1295 | 1323 |
1296 bool changed = false; | 1324 bool changed = false; |
1297 if (newValues.allBordersAreInvisible()) { | 1325 if (!newValues.startBorder().isVisible() && |
| 1326 !newValues.endBorder().isVisible() && |
| 1327 !newValues.beforeBorder().isVisible() && |
| 1328 !newValues.afterBorder().isVisible()) { |
1298 changed = !!m_collapsedBorderValues; | 1329 changed = !!m_collapsedBorderValues; |
1299 m_collapsedBorderValues = nullptr; | 1330 m_collapsedBorderValues = nullptr; |
1300 } else if (!m_collapsedBorderValues) { | 1331 } else if (!m_collapsedBorderValues) { |
1301 changed = true; | 1332 changed = true; |
1302 m_collapsedBorderValues = wrapUnique(new CollapsedBorderValues(newValues)); | 1333 m_collapsedBorderValues = wrapUnique(new CollapsedBorderValues( |
| 1334 *table(), newValues.startBorder(), newValues.endBorder(), |
| 1335 newValues.beforeBorder(), newValues.afterBorder())); |
1303 } else { | 1336 } else { |
1304 changed = !m_collapsedBorderValues->bordersVisuallyEqual(newValues); | 1337 // We check visuallyEquals so that the table cell is invalidated only if a |
| 1338 // changed collapsed border is visible in the first place. |
| 1339 changed = !m_collapsedBorderValues->startBorder().visuallyEquals( |
| 1340 newValues.startBorder()) || |
| 1341 !m_collapsedBorderValues->endBorder().visuallyEquals( |
| 1342 newValues.endBorder()) || |
| 1343 !m_collapsedBorderValues->beforeBorder().visuallyEquals( |
| 1344 newValues.beforeBorder()) || |
| 1345 !m_collapsedBorderValues->afterBorder().visuallyEquals( |
| 1346 newValues.afterBorder()); |
1305 if (changed) | 1347 if (changed) |
1306 *m_collapsedBorderValues = newValues; | 1348 m_collapsedBorderValues->setCollapsedBorderValues(newValues); |
1307 } | 1349 } |
1308 | 1350 |
1309 addBorderStyle(borderValues, newValues.startBorder); | 1351 // If collapsed borders changed, invalidate the cell's display item client on |
1310 addBorderStyle(borderValues, newValues.endBorder); | 1352 // the table's backing. |
1311 addBorderStyle(borderValues, newValues.beforeBorder); | 1353 // TODO(crbug.com/451090#c5): Need a way to invalidate/repaint the borders |
1312 addBorderStyle(borderValues, newValues.afterBorder); | 1354 // only. |
1313 return changed; | 1355 if (changed) |
| 1356 ObjectPaintInvalidator(*table()) |
| 1357 .slowSetPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient( |
| 1358 *this, PaintInvalidationStyleChange); |
| 1359 |
| 1360 addBorderStyle(borderValues, newValues.startBorder()); |
| 1361 addBorderStyle(borderValues, newValues.endBorder()); |
| 1362 addBorderStyle(borderValues, newValues.beforeBorder()); |
| 1363 addBorderStyle(borderValues, newValues.afterBorder()); |
1314 } | 1364 } |
1315 | 1365 |
1316 void LayoutTableCell::sortBorderValues( | 1366 void LayoutTableCell::sortBorderValues( |
1317 Vector<CollapsedBorderValue>& borderValues) { | 1367 LayoutTable::CollapsedBorderValues& borderValues) { |
1318 std::sort(borderValues.begin(), borderValues.end(), compareBorders); | 1368 std::sort(borderValues.begin(), borderValues.end(), compareBorders); |
1319 } | 1369 } |
1320 | 1370 |
1321 void LayoutTableCell::paintBoxDecorationBackground( | 1371 void LayoutTableCell::paintBoxDecorationBackground( |
1322 const PaintInfo& paintInfo, | 1372 const PaintInfo& paintInfo, |
1323 const LayoutPoint& paintOffset) const { | 1373 const LayoutPoint& paintOffset) const { |
1324 TableCellPainter(*this).paintBoxDecorationBackground(paintInfo, paintOffset); | 1374 TableCellPainter(*this).paintBoxDecorationBackground(paintInfo, paintOffset); |
1325 } | 1375 } |
1326 | 1376 |
1327 void LayoutTableCell::paintMask(const PaintInfo& paintInfo, | 1377 void LayoutTableCell::paintMask(const PaintInfo& paintInfo, |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1402 } | 1452 } |
1403 | 1453 |
1404 void LayoutTableCell::invalidateDisplayItemClients( | 1454 void LayoutTableCell::invalidateDisplayItemClients( |
1405 PaintInvalidationReason reason) const { | 1455 PaintInvalidationReason reason) const { |
1406 LayoutBlockFlow::invalidateDisplayItemClients(reason); | 1456 LayoutBlockFlow::invalidateDisplayItemClients(reason); |
1407 | 1457 |
1408 if (!usesCompositedCellDisplayItemClients()) | 1458 if (!usesCompositedCellDisplayItemClients()) |
1409 return; | 1459 return; |
1410 | 1460 |
1411 ObjectPaintInvalidator invalidator(*this); | 1461 ObjectPaintInvalidator invalidator(*this); |
| 1462 if (m_collapsedBorderValues) |
| 1463 invalidator.invalidateDisplayItemClient(*m_collapsedBorderValues, reason); |
1412 if (m_rowBackgroundDisplayItemClient) { | 1464 if (m_rowBackgroundDisplayItemClient) { |
1413 invalidator.invalidateDisplayItemClient(*m_rowBackgroundDisplayItemClient, | 1465 invalidator.invalidateDisplayItemClient(*m_rowBackgroundDisplayItemClient, |
1414 reason); | 1466 reason); |
1415 } | 1467 } |
1416 } | 1468 } |
1417 | 1469 |
1418 // TODO(lunalu): Deliberately dump the "inner" box of table cells, since that | 1470 // TODO(lunalu): Deliberately dump the "inner" box of table cells, since that |
1419 // is what current results reflect. We'd like to clean up the results to dump | 1471 // is what current results reflect. We'd like to clean up the results to dump |
1420 // both the outer box and the intrinsic padding so that both bits of information | 1472 // both the outer box and the intrinsic padding so that both bits of information |
1421 // are captured by the results. | 1473 // are captured by the results. |
1422 LayoutRect LayoutTableCell::debugRect() const { | 1474 LayoutRect LayoutTableCell::debugRect() const { |
1423 LayoutRect rect = LayoutRect( | 1475 LayoutRect rect = LayoutRect( |
1424 location().x(), location().y() + intrinsicPaddingBefore(), size().width(), | 1476 location().x(), location().y() + intrinsicPaddingBefore(), size().width(), |
1425 size().height() - intrinsicPaddingBefore() - intrinsicPaddingAfter()); | 1477 size().height() - intrinsicPaddingBefore() - intrinsicPaddingAfter()); |
1426 | 1478 |
1427 LayoutBlock* cb = containingBlock(); | 1479 LayoutBlock* cb = containingBlock(); |
1428 if (cb) | 1480 if (cb) |
1429 cb->adjustChildDebugRect(rect); | 1481 cb->adjustChildDebugRect(rect); |
1430 | 1482 |
1431 return rect; | 1483 return rect; |
1432 } | 1484 } |
1433 | 1485 |
1434 void LayoutTableCell::adjustChildDebugRect(LayoutRect& r) const { | 1486 void LayoutTableCell::adjustChildDebugRect(LayoutRect& r) const { |
1435 r.move(0, -intrinsicPaddingBefore()); | 1487 r.move(0, -intrinsicPaddingBefore()); |
1436 } | 1488 } |
1437 | 1489 |
1438 } // namespace blink | 1490 } // namespace blink |
OLD | NEW |