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. All rights
reserved. | 7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights
reserved. |
8 * | 8 * |
9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
(...skipping 27 matching lines...) Expand all Loading... |
38 #include "platform/geometry/TransformState.h" | 38 #include "platform/geometry/TransformState.h" |
39 #include "wtf/PtrUtil.h" | 39 #include "wtf/PtrUtil.h" |
40 | 40 |
41 namespace blink { | 41 namespace blink { |
42 | 42 |
43 using namespace HTMLNames; | 43 using namespace HTMLNames; |
44 | 44 |
45 struct SameSizeAsLayoutTableCell : public LayoutBlockFlow { | 45 struct SameSizeAsLayoutTableCell : public LayoutBlockFlow { |
46 unsigned bitfields; | 46 unsigned bitfields; |
47 int paddings[2]; | 47 int paddings[2]; |
48 void* pointer; | 48 void* pointer1; |
| 49 void* pointer2; |
49 }; | 50 }; |
50 | 51 |
51 static_assert(sizeof(LayoutTableCell) == sizeof(SameSizeAsLayoutTableCell), | 52 static_assert(sizeof(LayoutTableCell) == sizeof(SameSizeAsLayoutTableCell), |
52 "LayoutTableCell should stay small"); | 53 "LayoutTableCell should stay small"); |
53 static_assert(sizeof(CollapsedBorderValue) == 8, | 54 static_assert(sizeof(CollapsedBorderValue) == 8, |
54 "CollapsedBorderValue should stay small"); | 55 "CollapsedBorderValue should stay small"); |
55 | 56 |
56 LayoutTableCell::LayoutTableCell(Element* element) | 57 LayoutTableCell::LayoutTableCell(Element* element) |
57 : LayoutBlockFlow(element), | 58 : LayoutBlockFlow(element), |
58 m_absoluteColumnIndex(unsetColumnIndex), | 59 m_absoluteColumnIndex(unsetColumnIndex), |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 int LayoutTableCell::cellBaselinePosition() const { | 437 int LayoutTableCell::cellBaselinePosition() const { |
437 // <http://www.w3.org/TR/2007/CR-CSS21-20070719/tables.html#height-layout>: Th
e baseline of a cell is the baseline of | 438 // <http://www.w3.org/TR/2007/CR-CSS21-20070719/tables.html#height-layout>: Th
e baseline of a cell is the baseline of |
438 // the first in-flow line box in the cell, or the first in-flow table-row in t
he cell, whichever comes first. If there | 439 // the first in-flow line box in the cell, or the first in-flow table-row in t
he cell, whichever comes first. If there |
439 // is no such line box or table-row, the baseline is the bottom of content edg
e of the cell box. | 440 // is no such line box or table-row, the baseline is the bottom of content edg
e of the cell box. |
440 int firstLineBaseline = firstLineBoxBaseline(); | 441 int firstLineBaseline = firstLineBoxBaseline(); |
441 if (firstLineBaseline != -1) | 442 if (firstLineBaseline != -1) |
442 return firstLineBaseline; | 443 return firstLineBaseline; |
443 return (borderBefore() + paddingBefore() + contentLogicalHeight()).toInt(); | 444 return (borderBefore() + paddingBefore() + contentLogicalHeight()).toInt(); |
444 } | 445 } |
445 | 446 |
| 447 void LayoutTableCell::ensureIsReadyForPaintInvalidation() { |
| 448 LayoutBlockFlow::ensureIsReadyForPaintInvalidation(); |
| 449 if (!usesCompositedCellDisplayItemClients()) |
| 450 return; |
| 451 if (!m_rowBackgroundDisplayItemClient) { |
| 452 m_rowBackgroundDisplayItemClient = |
| 453 wrapUnique(new LayoutTableCell::RowBackgroundDisplayItemClient(*row())); |
| 454 } |
| 455 } |
| 456 |
446 void LayoutTableCell::styleDidChange(StyleDifference diff, | 457 void LayoutTableCell::styleDidChange(StyleDifference diff, |
447 const ComputedStyle* oldStyle) { | 458 const ComputedStyle* oldStyle) { |
448 DCHECK_EQ(style()->display(), EDisplay::TableCell); | 459 DCHECK_EQ(style()->display(), EDisplay::TableCell); |
449 | 460 |
450 LayoutBlockFlow::styleDidChange(diff, oldStyle); | 461 LayoutBlockFlow::styleDidChange(diff, oldStyle); |
451 setHasBoxDecorationBackground(true); | 462 setHasBoxDecorationBackground(true); |
452 | 463 |
453 if (parent() && section() && oldStyle && | 464 if (parent() && section() && oldStyle && |
454 style()->height() != oldStyle->height()) | 465 style()->height() != oldStyle->height()) |
455 section()->rowLogicalHeightChanged(row()); | 466 section()->rowLogicalHeightChanged(row()); |
(...skipping 21 matching lines...) Expand all Loading... |
477 previousCell()->setPreferredLogicalWidthsDirty(MarkOnlyThis); | 488 previousCell()->setPreferredLogicalWidthsDirty(MarkOnlyThis); |
478 } | 489 } |
479 if (nextCell()) { | 490 if (nextCell()) { |
480 // TODO(dgrogan) Add a layout test showing that setChildNeedsLayout is nee
ded instead of setNeedsLayout. | 491 // TODO(dgrogan) Add a layout test showing that setChildNeedsLayout is nee
ded instead of setNeedsLayout. |
481 nextCell()->setChildNeedsLayout(); | 492 nextCell()->setChildNeedsLayout(); |
482 nextCell()->setPreferredLogicalWidthsDirty(MarkOnlyThis); | 493 nextCell()->setPreferredLogicalWidthsDirty(MarkOnlyThis); |
483 } | 494 } |
484 } | 495 } |
485 } | 496 } |
486 | 497 |
487 // The following rules apply for resolving conflicts and figuring out which bord
er | 498 LayoutTableCell::RowBackgroundDisplayItemClient::RowBackgroundDisplayItemClient( |
488 // to use. | 499 const LayoutTableRow& layoutTableRow) |
489 // (1) Borders with the 'border-style' of 'hidden' take precedence over all othe
r conflicting | 500 : m_layoutTableRow(layoutTableRow) {} |
490 // borders. Any border with this value suppresses all borders at this location. | 501 |
491 // (2) Borders with a style of 'none' have the lowest priority. Only if the bord
er properties of all | 502 String LayoutTableCell::RowBackgroundDisplayItemClient::debugName() const { |
492 // the elements meeting at this edge are 'none' will the border be omitted (but
note that 'none' is | 503 return "RowBackground"; |
493 // the default value for the border style.) | 504 } |
494 // (3) If none of the styles are 'hidden' and at least one of them is not 'none'
, then narrow borders | 505 |
495 // are discarded in favor of wider ones. If several have the same 'border-width'
then styles are preferred | 506 LayoutRect LayoutTableCell::RowBackgroundDisplayItemClient::visualRect() const { |
496 // in this order: 'double', 'solid', 'dashed', 'dotted', 'ridge', 'outset', 'gro
ove', and the lowest: 'inset'. | 507 return m_layoutTableRow.visualRect(); |
497 // (4) If border styles differ only in color, then a style set on a cell wins ov
er one on a row, | 508 } |
498 // which wins over a row group, column, column group and, lastly, table. It is u
ndefined which color | 509 |
499 // is used when two elements of the same type disagree. | 510 // The following rules apply for resolving conflicts and figuring out which |
| 511 // border to use. |
| 512 // (1) Borders with the 'border-style' of 'hidden' take precedence over all |
| 513 // other conflicting borders. Any border with this value suppresses all |
| 514 // borders at this location. |
| 515 // (2) Borders with a style of 'none' have the lowest priority. Only if the |
| 516 // border properties of all the elements meeting at this edge are 'none' |
| 517 // will the border be omitted (but note that 'none' is the default value for |
| 518 // the border style.) |
| 519 // (3) If none of the styles are 'hidden' and at least one of them is not |
| 520 // 'none', then narrow borders are discarded in favor of wider ones. If |
| 521 // several have the same 'border-width' then styles are preferred in this |
| 522 // order: 'double', 'solid', 'dashed', 'dotted', 'ridge', 'outset', |
| 523 // 'groove', and the lowest: 'inset'. |
| 524 // (4) If border styles differ only in color, then a style set on a cell wins |
| 525 // over one on a row, which wins over a row group, column, column group and, |
| 526 // lastly, table. It is undefined which color is used when two elements of |
| 527 // the same type disagree. |
500 static bool compareBorders(const CollapsedBorderValue& border1, | 528 static bool compareBorders(const CollapsedBorderValue& border1, |
501 const CollapsedBorderValue& border2) { | 529 const CollapsedBorderValue& border2) { |
502 // Sanity check the values passed in. The null border have lowest priority. | 530 // Sanity check the values passed in. The null border have lowest priority. |
503 if (!border2.exists()) | 531 if (!border2.exists()) |
504 return false; | 532 return false; |
505 if (!border1.exists()) | 533 if (!border1.exists()) |
506 return true; | 534 return true; |
507 | 535 |
508 // Rule #1 above. | 536 // Rule #1 above. |
509 if (border1.style() == BorderStyleHidden) | 537 if (border1.style() == BorderStyleHidden) |
(...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1368 | 1396 |
1369 bool LayoutTableCell::backgroundIsKnownToBeOpaqueInRect( | 1397 bool LayoutTableCell::backgroundIsKnownToBeOpaqueInRect( |
1370 const LayoutRect& localRect) const { | 1398 const LayoutRect& localRect) const { |
1371 // If this object has layer, the area of collapsed borders should be transpare
nt | 1399 // If this object has layer, the area of collapsed borders should be transpare
nt |
1372 // to expose the collapsed borders painted on the underlying layer. | 1400 // to expose the collapsed borders painted on the underlying layer. |
1373 if (hasLayer() && table()->collapseBorders()) | 1401 if (hasLayer() && table()->collapseBorders()) |
1374 return false; | 1402 return false; |
1375 return LayoutBlockFlow::backgroundIsKnownToBeOpaqueInRect(localRect); | 1403 return LayoutBlockFlow::backgroundIsKnownToBeOpaqueInRect(localRect); |
1376 } | 1404 } |
1377 | 1405 |
1378 bool LayoutTableCell::usesTableAsAdditionalDisplayItemClient() const { | 1406 bool LayoutTableCell::usesCompositedCellDisplayItemClients() const { |
1379 // In certain cases such as collapsed borders for composited table cells we | 1407 // In certain cases such as collapsed borders for composited table cells we |
1380 // paint content for the cell into the table graphics layer backing and so | 1408 // paint content for the cell into the table graphics layer backing and so |
1381 // must use the table's visual rect. | 1409 // must use the table's visual rect. |
1382 return (hasLayer() && layer()->compositingState() != NotComposited) || | 1410 return (hasLayer() && layer()->compositingState() != NotComposited) || |
1383 RuntimeEnabledFeatures::slimmingPaintV2Enabled(); | 1411 RuntimeEnabledFeatures::slimmingPaintV2Enabled(); |
1384 } | 1412 } |
1385 | 1413 |
1386 void LayoutTableCell::invalidateDisplayItemClients( | 1414 void LayoutTableCell::invalidateDisplayItemClients( |
1387 PaintInvalidationReason reason) const { | 1415 PaintInvalidationReason reason) const { |
1388 if (m_collapsedBorderValues && usesTableAsAdditionalDisplayItemClient()) { | 1416 LayoutBlockFlow::invalidateDisplayItemClients(reason); |
1389 ObjectPaintInvalidator(*this).invalidateDisplayItemClient( | 1417 |
1390 *m_collapsedBorderValues, reason); | 1418 if (!usesCompositedCellDisplayItemClients()) |
| 1419 return; |
| 1420 |
| 1421 ObjectPaintInvalidator invalidator(*this); |
| 1422 if (m_collapsedBorderValues) |
| 1423 invalidator.invalidateDisplayItemClient(*m_collapsedBorderValues, reason); |
| 1424 if (m_rowBackgroundDisplayItemClient) { |
| 1425 invalidator.invalidateDisplayItemClient(*m_rowBackgroundDisplayItemClient, |
| 1426 reason); |
1391 } | 1427 } |
1392 LayoutBlockFlow::invalidateDisplayItemClients(reason); | |
1393 } | 1428 } |
1394 | 1429 |
1395 // TODO(lunalu): Deliberately dump the "inner" box of table cells, since that | 1430 // TODO(lunalu): Deliberately dump the "inner" box of table cells, since that |
1396 // is what current results reflect. We'd like to clean up the results to dump | 1431 // is what current results reflect. We'd like to clean up the results to dump |
1397 // both the outer box and the intrinsic padding so that both bits of | 1432 // both the outer box and the intrinsic padding so that both bits of |
1398 // information are captured by the results. | 1433 // information are captured by the results. |
1399 LayoutRect LayoutTableCell::debugRect() const { | 1434 LayoutRect LayoutTableCell::debugRect() const { |
1400 LayoutRect rect = LayoutRect( | 1435 LayoutRect rect = LayoutRect( |
1401 location().x(), location().y() + intrinsicPaddingBefore(), size().width(), | 1436 location().x(), location().y() + intrinsicPaddingBefore(), size().width(), |
1402 size().height() - intrinsicPaddingBefore() - intrinsicPaddingAfter()); | 1437 size().height() - intrinsicPaddingBefore() - intrinsicPaddingAfter()); |
1403 | 1438 |
1404 LayoutBlock* cb = containingBlock(); | 1439 LayoutBlock* cb = containingBlock(); |
1405 if (cb) | 1440 if (cb) |
1406 cb->adjustChildDebugRect(rect); | 1441 cb->adjustChildDebugRect(rect); |
1407 | 1442 |
1408 return rect; | 1443 return rect; |
1409 } | 1444 } |
1410 | 1445 |
1411 void LayoutTableCell::adjustChildDebugRect(LayoutRect& r) const { | 1446 void LayoutTableCell::adjustChildDebugRect(LayoutRect& r) const { |
1412 r.move(0, -intrinsicPaddingBefore()); | 1447 r.move(0, -intrinsicPaddingBefore()); |
1413 } | 1448 } |
1414 | 1449 |
1415 } // namespace blink | 1450 } // namespace blink |
OLD | NEW |