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 |