Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(497)

Unified Diff: third_party/WebKit/Source/core/layout/LayoutTableSection.cpp

Issue 2584143003: Repeat footers in paginated context (Closed)
Patch Set: bug 656232 Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698