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, 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 28 matching lines...) Expand all Loading... | |
| 39 #include "platform/geometry/TransformState.h" | 39 #include "platform/geometry/TransformState.h" |
| 40 #include "wtf/PtrUtil.h" | 40 #include "wtf/PtrUtil.h" |
| 41 | 41 |
| 42 namespace blink { | 42 namespace blink { |
| 43 | 43 |
| 44 using namespace HTMLNames; | 44 using namespace HTMLNames; |
| 45 | 45 |
| 46 struct SameSizeAsLayoutTableCell : public LayoutBlockFlow { | 46 struct SameSizeAsLayoutTableCell : public LayoutBlockFlow { |
| 47 unsigned bitfields; | 47 unsigned bitfields; |
| 48 int paddings[2]; | 48 int paddings[2]; |
| 49 void* pointer; | 49 void* pointer1; |
| 50 void* pointer2; | |
| 50 }; | 51 }; |
| 51 | 52 |
| 52 static_assert(sizeof(LayoutTableCell) == sizeof(SameSizeAsLayoutTableCell), | 53 static_assert(sizeof(LayoutTableCell) == sizeof(SameSizeAsLayoutTableCell), |
| 53 "LayoutTableCell should stay small"); | 54 "LayoutTableCell should stay small"); |
| 54 static_assert(sizeof(CollapsedBorderValue) == 8, | 55 static_assert(sizeof(CollapsedBorderValue) == 8, |
| 55 "CollapsedBorderValue should stay small"); | 56 "CollapsedBorderValue should stay small"); |
| 56 | 57 |
| 57 LayoutTableCell::LayoutTableCell(Element* element) | 58 LayoutTableCell::LayoutTableCell(Element* element) |
| 58 : LayoutBlockFlow(element), | 59 : LayoutBlockFlow(element), |
| 59 m_absoluteColumnIndex(unsetColumnIndex), | 60 m_absoluteColumnIndex(unsetColumnIndex), |
| 60 m_cellWidthChanged(false), | 61 m_cellWidthChanged(false), |
| 61 m_intrinsicPaddingBefore(0), | 62 m_intrinsicPaddingBefore(0), |
| 62 m_intrinsicPaddingAfter(0) { | 63 m_intrinsicPaddingAfter(0) { |
| 63 // We only update the flags when notified of DOM changes in | 64 // We only update the flags when notified of DOM changes in |
| 64 // colSpanOrRowSpanChanged() so we need to set their initial values here in | 65 // colSpanOrRowSpanChanged() so we need to set their initial values here in |
| 65 // case something asks for colSpan()/rowSpan() before then. | 66 // case something asks for colSpan()/rowSpan() before then. |
| 66 updateColAndRowSpanFlags(); | 67 updateColAndRowSpanFlags(); |
| 67 } | 68 } |
| 68 | 69 |
| 69 LayoutTableCell::CollapsedBorderValues::CollapsedBorderValues( | 70 LayoutTableCell::CollapsedBorderValues::CollapsedBorderValues( |
| 70 const LayoutTable& layoutTable, | |
| 71 const CollapsedBorderValue& startBorder, | 71 const CollapsedBorderValue& startBorder, |
| 72 const CollapsedBorderValue& endBorder, | 72 const CollapsedBorderValue& endBorder, |
| 73 const CollapsedBorderValue& beforeBorder, | 73 const CollapsedBorderValue& beforeBorder, |
| 74 const CollapsedBorderValue& afterBorder) | 74 const CollapsedBorderValue& afterBorder) |
| 75 : m_layoutTable(layoutTable), | 75 : m_startBorder(startBorder), |
| 76 m_startBorder(startBorder), | |
| 77 m_endBorder(endBorder), | 76 m_endBorder(endBorder), |
| 78 m_beforeBorder(beforeBorder), | 77 m_beforeBorder(beforeBorder), |
| 79 m_afterBorder(afterBorder) {} | 78 m_afterBorder(afterBorder) {} |
| 80 | 79 |
| 81 void LayoutTableCell::CollapsedBorderValues::setCollapsedBorderValues( | 80 void LayoutTableCell::CollapsedBorderValues::setCollapsedBorderValues( |
| 82 const CollapsedBorderValues& other) { | 81 const CollapsedBorderValues& other) { |
| 83 m_startBorder = other.startBorder(); | 82 m_startBorder = other.startBorder(); |
| 84 m_endBorder = other.endBorder(); | 83 m_endBorder = other.endBorder(); |
| 85 m_beforeBorder = other.beforeBorder(); | 84 m_beforeBorder = other.beforeBorder(); |
| 86 m_afterBorder = other.afterBorder(); | 85 m_afterBorder = other.afterBorder(); |
| 87 } | 86 } |
| 88 | 87 |
| 89 String LayoutTableCell::CollapsedBorderValues::debugName() const { | 88 LayoutTableCell::CompositedTableCell::CompositedTableCell( |
| 90 return "CollapsedBorderValues"; | 89 const LayoutTable& layoutTable) |
| 90 : m_layoutTable(layoutTable) {} | |
| 91 | |
| 92 String LayoutTableCell::CompositedTableCell::debugName() const { | |
| 93 return "CompositedTableCell"; | |
| 91 } | 94 } |
| 92 | 95 |
| 93 LayoutRect LayoutTableCell::CollapsedBorderValues::visualRect() const { | 96 LayoutRect LayoutTableCell::CompositedTableCell::visualRect() const { |
| 94 return m_layoutTable.visualRect(); | 97 return m_layoutTable.visualRect(); |
| 95 } | 98 } |
| 96 | 99 |
| 97 void LayoutTableCell::willBeRemovedFromTree() { | 100 void LayoutTableCell::willBeRemovedFromTree() { |
| 98 LayoutBlockFlow::willBeRemovedFromTree(); | 101 LayoutBlockFlow::willBeRemovedFromTree(); |
| 99 | 102 |
| 100 section()->setNeedsCellRecalc(); | 103 section()->setNeedsCellRecalc(); |
| 101 | 104 |
| 102 // When borders collapse, removing a cell can affect the the width of | 105 // When borders collapse, removing a cell can affect the the width of |
| 103 // neighboring cells. | 106 // neighboring cells. |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 455 // The baseline of a cell is the baseline of the first in-flow line box in the | 458 // The baseline of a cell is the baseline of the first in-flow line box in the |
| 456 // cell, or the first in-flow table-row in the cell, whichever comes first. If | 459 // cell, or the first in-flow table-row in the cell, whichever comes first. If |
| 457 // there is no such line box or table-row, the baseline is the bottom of | 460 // there is no such line box or table-row, the baseline is the bottom of |
| 458 // content edge of the cell box. | 461 // content edge of the cell box. |
| 459 int firstLineBaseline = firstLineBoxBaseline(); | 462 int firstLineBaseline = firstLineBoxBaseline(); |
| 460 if (firstLineBaseline != -1) | 463 if (firstLineBaseline != -1) |
| 461 return firstLineBaseline; | 464 return firstLineBaseline; |
| 462 return (borderBefore() + paddingBefore() + contentLogicalHeight()).toInt(); | 465 return (borderBefore() + paddingBefore() + contentLogicalHeight()).toInt(); |
| 463 } | 466 } |
| 464 | 467 |
| 468 void LayoutTableCell::ensureIsReadyForPaintInvalidation() { | |
| 469 if (usesTableAsAdditionalDisplayItemClient() && !m_compositedTableCell) { | |
| 470 m_compositedTableCell = | |
| 471 wrapUnique(new LayoutTableCell::CompositedTableCell(*table())); | |
| 472 } | |
| 473 LayoutBlockFlow::ensureIsReadyForPaintInvalidation(); | |
| 474 } | |
| 475 | |
| 465 void LayoutTableCell::styleDidChange(StyleDifference diff, | 476 void LayoutTableCell::styleDidChange(StyleDifference diff, |
| 466 const ComputedStyle* oldStyle) { | 477 const ComputedStyle* oldStyle) { |
| 467 DCHECK_EQ(style()->display(), EDisplay::TableCell); | 478 DCHECK_EQ(style()->display(), EDisplay::TableCell); |
| 468 | 479 |
| 469 LayoutBlockFlow::styleDidChange(diff, oldStyle); | 480 LayoutBlockFlow::styleDidChange(diff, oldStyle); |
| 470 setHasBoxDecorationBackground(true); | 481 setHasBoxDecorationBackground(true); |
| 471 | 482 |
| 472 if (parent() && section() && oldStyle && | 483 if (parent() && section() && oldStyle && |
| 473 style()->height() != oldStyle->height()) | 484 style()->height() != oldStyle->height()) |
| 474 section()->rowLogicalHeightChanged(row()); | 485 section()->rowLogicalHeightChanged(row()); |
| (...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1287 for (size_t i = 0; i < count; ++i) { | 1298 for (size_t i = 0; i < count; ++i) { |
| 1288 if (borderValues[i].isSameIgnoringColor(borderValue)) | 1299 if (borderValues[i].isSameIgnoringColor(borderValue)) |
| 1289 return; | 1300 return; |
| 1290 } | 1301 } |
| 1291 borderValues.append(borderValue); | 1302 borderValues.append(borderValue); |
| 1292 } | 1303 } |
| 1293 | 1304 |
| 1294 void LayoutTableCell::collectBorderValues( | 1305 void LayoutTableCell::collectBorderValues( |
| 1295 LayoutTable::CollapsedBorderValues& borderValues) { | 1306 LayoutTable::CollapsedBorderValues& borderValues) { |
| 1296 CollapsedBorderValues newValues( | 1307 CollapsedBorderValues newValues( |
| 1297 *table(), computeCollapsedStartBorder(), computeCollapsedEndBorder(), | 1308 computeCollapsedStartBorder(), computeCollapsedEndBorder(), |
| 1298 computeCollapsedBeforeBorder(), computeCollapsedAfterBorder()); | 1309 computeCollapsedBeforeBorder(), computeCollapsedAfterBorder()); |
| 1299 | 1310 |
| 1300 bool changed = false; | 1311 bool changed = false; |
| 1301 if (!newValues.startBorder().isVisible() && | 1312 if (!newValues.startBorder().isVisible() && |
| 1302 !newValues.endBorder().isVisible() && | 1313 !newValues.endBorder().isVisible() && |
| 1303 !newValues.beforeBorder().isVisible() && | 1314 !newValues.beforeBorder().isVisible() && |
| 1304 !newValues.afterBorder().isVisible()) { | 1315 !newValues.afterBorder().isVisible()) { |
| 1305 changed = !!m_collapsedBorderValues; | 1316 changed = !!m_collapsedBorderValues; |
| 1306 m_collapsedBorderValues = nullptr; | 1317 m_collapsedBorderValues = nullptr; |
| 1307 } else if (!m_collapsedBorderValues) { | 1318 } else if (!m_collapsedBorderValues) { |
| 1308 changed = true; | 1319 changed = true; |
| 1309 m_collapsedBorderValues = wrapUnique(new CollapsedBorderValues( | 1320 m_collapsedBorderValues = wrapUnique(new CollapsedBorderValues( |
| 1310 *table(), newValues.startBorder(), newValues.endBorder(), | 1321 newValues.startBorder(), newValues.endBorder(), |
| 1311 newValues.beforeBorder(), newValues.afterBorder())); | 1322 newValues.beforeBorder(), newValues.afterBorder())); |
| 1312 } else { | 1323 } else { |
| 1313 // We check visuallyEquals so that the table cell is invalidated only if a | 1324 // We check visuallyEquals so that the table cell is invalidated only if a |
| 1314 // changed collapsed border is visible in the first place. | 1325 // changed collapsed border is visible in the first place. |
| 1315 changed = !m_collapsedBorderValues->startBorder().visuallyEquals( | 1326 changed = !m_collapsedBorderValues->startBorder().visuallyEquals( |
| 1316 newValues.startBorder()) || | 1327 newValues.startBorder()) || |
| 1317 !m_collapsedBorderValues->endBorder().visuallyEquals( | 1328 !m_collapsedBorderValues->endBorder().visuallyEquals( |
| 1318 newValues.endBorder()) || | 1329 newValues.endBorder()) || |
| 1319 !m_collapsedBorderValues->beforeBorder().visuallyEquals( | 1330 !m_collapsedBorderValues->beforeBorder().visuallyEquals( |
| 1320 newValues.beforeBorder()) || | 1331 newValues.beforeBorder()) || |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1422 } | 1433 } |
| 1423 | 1434 |
| 1424 bool LayoutTableCell::usesTableAsAdditionalDisplayItemClient() const { | 1435 bool LayoutTableCell::usesTableAsAdditionalDisplayItemClient() const { |
| 1425 // In certain cases such as collapsed borders for composited table cells we | 1436 // In certain cases such as collapsed borders for composited table cells we |
| 1426 // paint content for the cell into the table graphics layer backing and so | 1437 // paint content for the cell into the table graphics layer backing and so |
| 1427 // must use the table's visual rect. | 1438 // must use the table's visual rect. |
| 1428 return (hasLayer() && layer()->compositingState() != NotComposited) || | 1439 return (hasLayer() && layer()->compositingState() != NotComposited) || |
| 1429 RuntimeEnabledFeatures::slimmingPaintV2Enabled(); | 1440 RuntimeEnabledFeatures::slimmingPaintV2Enabled(); |
| 1430 } | 1441 } |
| 1431 | 1442 |
| 1443 const LayoutTableCell::CompositedTableCell* | |
| 1444 LayoutTableCell::compositedTableCell() const { | |
| 1445 return m_compositedTableCell.get(); | |
| 1446 } | |
| 1447 | |
| 1432 void LayoutTableCell::invalidateDisplayItemClients( | 1448 void LayoutTableCell::invalidateDisplayItemClients( |
| 1433 PaintInvalidationReason reason) const { | 1449 PaintInvalidationReason reason) const { |
| 1434 if (m_collapsedBorderValues && usesTableAsAdditionalDisplayItemClient()) { | 1450 if (usesTableAsAdditionalDisplayItemClient()) { |
|
wkorman
2016/11/01 21:14:48
Is it worth also making sure compositedTableCell()
Xianzhu
2016/11/01 21:28:14
DCHECK sgtm.
wkorman
2016/11/03 01:41:25
Done.
| |
| 1435 ObjectPaintInvalidator(*this).invalidateDisplayItemClient( | 1451 ObjectPaintInvalidator(*this).invalidateDisplayItemClient( |
| 1436 *m_collapsedBorderValues, reason); | 1452 *compositedTableCell(), reason); |
| 1437 } | 1453 } |
| 1438 LayoutBlockFlow::invalidateDisplayItemClients(reason); | 1454 LayoutBlockFlow::invalidateDisplayItemClients(reason); |
| 1439 } | 1455 } |
| 1440 | 1456 |
| 1441 // TODO(lunalu): Deliberately dump the "inner" box of table cells, since that | 1457 // TODO(lunalu): Deliberately dump the "inner" box of table cells, since that |
| 1442 // is what current results reflect. We'd like to clean up the results to dump | 1458 // is what current results reflect. We'd like to clean up the results to dump |
| 1443 // both the outer box and the intrinsic padding so that both bits of information | 1459 // both the outer box and the intrinsic padding so that both bits of information |
| 1444 // are captured by the results. | 1460 // are captured by the results. |
| 1445 LayoutRect LayoutTableCell::debugRect() const { | 1461 LayoutRect LayoutTableCell::debugRect() const { |
| 1446 LayoutRect rect = LayoutRect( | 1462 LayoutRect rect = LayoutRect( |
| 1447 location().x(), location().y() + intrinsicPaddingBefore(), size().width(), | 1463 location().x(), location().y() + intrinsicPaddingBefore(), size().width(), |
| 1448 size().height() - intrinsicPaddingBefore() - intrinsicPaddingAfter()); | 1464 size().height() - intrinsicPaddingBefore() - intrinsicPaddingAfter()); |
| 1449 | 1465 |
| 1450 LayoutBlock* cb = containingBlock(); | 1466 LayoutBlock* cb = containingBlock(); |
| 1451 if (cb) | 1467 if (cb) |
| 1452 cb->adjustChildDebugRect(rect); | 1468 cb->adjustChildDebugRect(rect); |
| 1453 | 1469 |
| 1454 return rect; | 1470 return rect; |
| 1455 } | 1471 } |
| 1456 | 1472 |
| 1457 void LayoutTableCell::adjustChildDebugRect(LayoutRect& r) const { | 1473 void LayoutTableCell::adjustChildDebugRect(LayoutRect& r) const { |
| 1458 r.move(0, -intrinsicPaddingBefore()); | 1474 r.move(0, -intrinsicPaddingBefore()); |
| 1459 } | 1475 } |
| 1460 | 1476 |
| 1461 } // namespace blink | 1477 } // namespace blink |
| OLD | NEW |