Chromium Code Reviews| Index: third_party/WebKit/Source/core/layout/LayoutTableSection.cpp |
| diff --git a/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp b/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp |
| index 95efd6a7998bde5fe64d5ea338105f0a3f094c00..5092c0119a5f0e427e563f9ced407d17010b7b6a 100644 |
| --- a/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp |
| +++ b/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp |
| @@ -1232,7 +1232,8 @@ void LayoutTableSection::LayoutRows() { |
| } |
| int LayoutTableSection::PaginationStrutForRow(LayoutTableRow* row, |
| - LayoutUnit logical_offset) const { |
| + LayoutUnit logical_offset, |
| + bool& can_repeat_footer) const { |
|
mstensho (USE GERRIT)
2017/04/24 11:57:16
I think calculating can_repeat_footer should be om
|
| DCHECK(row); |
| if (row->GetPaginationBreakability() == kAllowAnyBreaks) |
| return 0; |
| @@ -1244,6 +1245,17 @@ int LayoutTableSection::PaginationStrutForRow(LayoutTableRow* row, |
| if (row_logical_height > page_logical_height) |
| return 0; |
| + LayoutTableSection* footer = Table()->Footer(); |
| + bool footer_wants_to_repeat = |
| + footer && footer != this && |
| + footer->GetPaginationBreakability() != kAllowAnyBreaks && |
| + Table()->RowOffsetFromRepeatingHeader() && row->RowIndex(); |
|
mstensho (USE GERRIT)
2017/04/24 11:57:16
RowOffsetFromRepeatingHeader() suggests that we de
|
| + if (footer_wants_to_repeat) { |
| + if (row_logical_height + footer->LogicalHeight() <= page_logical_height) { |
|
mstensho (USE GERRIT)
2017/04/24 11:57:16
... however, if there *is* a repeating header, we
|
| + row_logical_height += footer->LogicalHeight(); |
| + } |
| + } |
| + |
| LayoutUnit remaining_logical_height = PageRemainingLogicalHeightForOffset( |
| logical_offset, LayoutBlock::kAssociateWithLatterPage); |
| if (remaining_logical_height >= row_logical_height) |
| @@ -1256,6 +1268,10 @@ int LayoutTableSection::PaginationStrutForRow(LayoutTableRow* row, |
| // content completely. No point in leaving a page completely blank. |
| return 0; |
| } |
| + |
| + if (footer && remaining_logical_height >= |
| + (footer->LogicalHeight() - Table()->VBorderSpacing())) |
| + can_repeat_footer = true; |
| // Table layout parts only work on integers, so we have to round. Round up, to |
| // make sure that no fraction ever gets left behind in the previous |
| // fragmentainer. |
| @@ -2051,8 +2067,9 @@ void LayoutTableSection::AdjustRowForPagination(LayoutTableRow& row_object, |
| SubtreeLayoutScope& layouter) { |
| row_object.SetPaginationStrut(LayoutUnit()); |
| row_object.SetLogicalHeight(LayoutUnit(LogicalHeightForRow(row_object))); |
| - int pagination_strut = |
| - PaginationStrutForRow(&row_object, row_object.LogicalTop()); |
| + bool can_repeat_footer = false; |
| + int pagination_strut = PaginationStrutForRow( |
| + &row_object, row_object.LogicalTop(), can_repeat_footer); |
| bool row_is_at_top_of_column = false; |
| LayoutUnit offset_from_top_of_page; |
| if (!pagination_strut) { |
| @@ -2086,6 +2103,16 @@ void LayoutTableSection::AdjustRowForPagination(LayoutTableRow& row_object, |
| if (row_is_at_top_of_column && offset_from_top_of_page) |
| pagination_strut -= offset_from_top_of_page.ToInt(); |
| + LayoutTableSection* footer = Table()->Footer(); |
| + if (footer && footer != this && header != this && |
| + footer->GetPaginationBreakability() != kAllowAnyBreaks && |
| + Table()->RowOffsetFromRepeatingHeader() && can_repeat_footer) { |
|
mstensho (USE GERRIT)
2017/04/24 11:57:16
Check can_repeat_footer first.
|
| + unsigned page = FloorToInt((LogicalTop() + row_object.LogicalTop()) / |
| + PageLogicalHeightForOffset(LayoutUnit())); |
|
mstensho (USE GERRIT)
2017/04/24 11:57:16
PageLogicalHeightForOffset() may be 0 (initial col
|
| + Table()->SetPositionOfRepeatingFooterGroupOnPage( |
| + page, LogicalTop() + row_object.LogicalTop()); |
|
mstensho (USE GERRIT)
2017/04/24 11:57:16
Then again, do we really need to allow individual
|
| + } |
| + |
| // If we have a header group we will paint it at the top of each page, |
| // move the rows down to accomodate it. |
| if (header && header != this) |
| @@ -2105,6 +2132,25 @@ void LayoutTableSection::AdjustRowForPagination(LayoutTableRow& row_object, |
| row_object.SetLogicalHeight(LayoutUnit(LogicalHeightForRow(row_object))); |
| } |
| +bool LayoutTableSection::IsRepeatingFooterGroup() const { |
| + if (GetPaginationBreakability() == LayoutBox::kAllowAnyBreaks) |
|
mstensho (USE GERRIT)
2017/04/24 11:57:16
LayoutBox:: scope unnecessary.
|
| + return false; |
| + // TODO(rhogan): Should we paint a header repeatedly if it's self-painting? |
|
mstensho (USE GERRIT)
2017/04/24 11:57:16
I don't think it's currently possible to have a se
|
| + if (HasSelfPaintingLayer()) |
| + return false; |
| + LayoutUnit page_height = Table()->PageLogicalHeightForOffset(LayoutUnit()); |
|
mstensho (USE GERRIT)
2017/04/24 11:57:16
If "page" height isn't uniform (e.g. a multicol co
|
| + if (!page_height) |
| + return false; |
| + if (LogicalHeight() > page_height) |
| + return false; |
| + // If the first row of the section after the header group doesn't fit on the |
| + // page, then don't repeat the header on each page. |
| + // See https://drafts.csswg.org/css-tables-3/#repeated-headers |
| + if (Table()->Header() && !Table()->Header()->IsRepeatingHeaderGroup()) |
| + return false; |
| + return true; |
| +} |
| + |
| bool LayoutTableSection::IsRepeatingHeaderGroup() const { |
| if (GetPaginationBreakability() == LayoutBox::kAllowAnyBreaks) |
| return false; |
| @@ -2139,6 +2185,17 @@ bool LayoutTableSection::MapToVisualRectInAncestorSpaceInternal( |
| VisualRectFlags flags) const { |
| if (ancestor == this) |
| return true; |
| + |
| + if (Table()->Footer() == this && IsRepeatingFooterGroup()) { |
| + transform_state.Flatten(); |
| + FloatRect rect = transform_state.LastPlanarQuad().BoundingBox(); |
| + rect.SetHeight(Table()->LogicalHeight()); |
|
mstensho (USE GERRIT)
2017/04/24 11:57:16
Introducing a lot of duplicated code here (shared
|
| + transform_state.SetQuad(FloatQuad(rect)); |
| + bool mapped = Table()->MapToVisualRectInAncestorSpaceInternal( |
|
mstensho (USE GERRIT)
2017/04/24 11:57:16
We here skip the table section, ignoring its posit
|
| + ancestor, transform_state, flags); |
| + return mapped; |
| + } |
| + |
| // Repeating table headers are painted once per fragmentation page/column. |
| // This does not go through the regular fragmentation machinery, so we need |
| // special code to expand the invalidation rect to contain all positions of |