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

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutTableSection.cpp

Issue 2584143003: Repeat footers in paginated context (Closed)
Patch Set: bug 656232 Created 3 years, 4 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 unified diff | Download patch
OLDNEW
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, 2008, 2009, 2010, 2013 Apple Inc. 7 * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2013 Apple Inc.
8 * All rights reserved. 8 * All rights reserved.
9 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) 9 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
10 * 10 *
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 } 88 }
89 89
90 LayoutTableSection::LayoutTableSection(Element* element) 90 LayoutTableSection::LayoutTableSection(Element* element)
91 : LayoutTableBoxComponent(element), 91 : LayoutTableBoxComponent(element),
92 c_col_(0), 92 c_col_(0),
93 c_row_(0), 93 c_row_(0),
94 needs_cell_recalc_(false), 94 needs_cell_recalc_(false),
95 force_full_paint_(false), 95 force_full_paint_(false),
96 has_multiple_cell_levels_(false), 96 has_multiple_cell_levels_(false),
97 has_spanning_cells_(false), 97 has_spanning_cells_(false),
98 is_repeating_header_group_(false) { 98 is_repeating_header_group_(false),
99 is_repeating_footer_group_(false) {
99 // init LayoutObject attributes 100 // init LayoutObject attributes
100 SetInline(false); // our object is not Inline 101 SetInline(false); // our object is not Inline
101 } 102 }
102 103
103 LayoutTableSection::~LayoutTableSection() {} 104 LayoutTableSection::~LayoutTableSection() {}
104 105
105 void LayoutTableSection::StyleDidChange(StyleDifference diff, 106 void LayoutTableSection::StyleDidChange(StyleDifference diff,
106 const ComputedStyle* old_style) { 107 const ComputedStyle* old_style) {
107 DCHECK(Style()->Display() == EDisplay::kTableFooterGroup || 108 DCHECK(Style()->Display() == EDisplay::kTableFooterGroup ||
108 Style()->Display() == EDisplay::kTableRowGroup || 109 Style()->Display() == EDisplay::kTableRowGroup ||
(...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 DCHECK(!NeedsLayout()); 1210 DCHECK(!NeedsLayout());
1210 1211
1211 SetLogicalHeight(LayoutUnit(row_pos_[total_rows])); 1212 SetLogicalHeight(LayoutUnit(row_pos_[total_rows]));
1212 1213
1213 ComputeOverflowFromDescendants(); 1214 ComputeOverflowFromDescendants();
1214 } 1215 }
1215 1216
1216 int LayoutTableSection::PaginationStrutForRow(LayoutTableRow* row, 1217 int LayoutTableSection::PaginationStrutForRow(LayoutTableRow* row,
1217 LayoutUnit logical_offset) const { 1218 LayoutUnit logical_offset) const {
1218 DCHECK(row); 1219 DCHECK(row);
1219 if (row->GetPaginationBreakability() == kAllowAnyBreaks) 1220 const LayoutTableSection* footer = Table()->Footer();
1221 bool make_room_for_repeating_footer =
1222 footer && footer->IsRepeatingFooterGroup() && row->RowIndex();
1223 if (!make_room_for_repeating_footer &&
1224 row->GetPaginationBreakability() == kAllowAnyBreaks)
1220 return 0; 1225 return 0;
1221 if (!IsPageLogicalHeightKnown()) 1226 if (!IsPageLogicalHeightKnown())
1222 return 0; 1227 return 0;
1223 LayoutUnit page_logical_height = PageLogicalHeightForOffset(logical_offset); 1228 LayoutUnit page_logical_height = PageLogicalHeightForOffset(logical_offset);
1224 // If the row is too tall for the page don't insert a strut. 1229 // If the row is too tall for the page don't insert a strut.
1225 LayoutUnit row_logical_height = row->LogicalHeight(); 1230 LayoutUnit row_logical_height = row->LogicalHeight();
1226 if (row_logical_height > page_logical_height) 1231 if (row_logical_height > page_logical_height)
1227 return 0; 1232 return 0;
1228 1233
1234 if (make_room_for_repeating_footer) {
1235 row_logical_height +=
1236 View()->GetLayoutState()->HeightOffsetForTableFooters();
1237 }
1238
1229 LayoutUnit remaining_logical_height = PageRemainingLogicalHeightForOffset( 1239 LayoutUnit remaining_logical_height = PageRemainingLogicalHeightForOffset(
1230 logical_offset, LayoutBlock::kAssociateWithLatterPage); 1240 logical_offset, LayoutBlock::kAssociateWithLatterPage);
1231 if (remaining_logical_height >= row_logical_height) 1241 if (remaining_logical_height >= row_logical_height)
1232 return 0; // It fits fine where it is. No need to break. 1242 return 0; // It fits fine where it is. No need to break.
1233 LayoutUnit pagination_strut = CalculatePaginationStrutToFitContent( 1243 LayoutUnit pagination_strut = CalculatePaginationStrutToFitContent(
1234 logical_offset, remaining_logical_height, row_logical_height); 1244 logical_offset, remaining_logical_height, row_logical_height);
1235 if (pagination_strut == remaining_logical_height && 1245 if (pagination_strut == remaining_logical_height &&
1236 remaining_logical_height == page_logical_height) { 1246 remaining_logical_height == page_logical_height) {
1237 // Don't break if we were at the top of a page, and we failed to fit the 1247 // Don't break if we were at the top of a page, and we failed to fit the
1238 // content completely. No point in leaving a page completely blank. 1248 // content completely. No point in leaving a page completely blank.
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after
1905 // pagination struts inside some cell in this row that we need to get rid of. 1915 // pagination struts inside some cell in this row that we need to get rid of.
1906 row_object.SetLogicalTop(row_object.LogicalTop() + pagination_strut); 1916 row_object.SetLogicalTop(row_object.LogicalTop() + pagination_strut);
1907 layouter.SetChildNeedsLayout(&row_object); 1917 layouter.SetChildNeedsLayout(&row_object);
1908 row_object.LayoutIfNeeded(); 1918 row_object.LayoutIfNeeded();
1909 1919
1910 // It's very likely that re-laying out (and nuking pagination struts inside 1920 // It's very likely that re-laying out (and nuking pagination struts inside
1911 // cells) gave us a new height. 1921 // cells) gave us a new height.
1912 row_object.SetLogicalHeight(LayoutUnit(LogicalHeightForRow(row_object))); 1922 row_object.SetLogicalHeight(LayoutUnit(LogicalHeightForRow(row_object)));
1913 } 1923 }
1914 1924
1915 bool LayoutTableSection::HeaderGroupShouldRepeat() const { 1925 bool LayoutTableSection::GroupShouldRepeat() const {
1916 if (Table()->Header() != this) 1926 DCHECK(Table()->Header() == this || Table()->Footer() == this);
1927 if (GetPaginationBreakability() == kAllowAnyBreaks)
1917 return false; 1928 return false;
1918 1929
1919 if (GetPaginationBreakability() == kAllowAnyBreaks)
1920 return false;
1921 // TODO(rhogan): Sections can be self-painting. 1930 // TODO(rhogan): Sections can be self-painting.
1922 if (HasSelfPaintingLayer()) 1931 if (HasSelfPaintingLayer())
1923 return false; 1932 return false;
1933
1924 // If we don't know the page height yet, just assume we fit. 1934 // If we don't know the page height yet, just assume we fit.
1925 if (!IsPageLogicalHeightKnown()) 1935 if (!IsPageLogicalHeightKnown())
1926 return true; 1936 return true;
1927 LayoutUnit page_height = PageLogicalHeightForOffset(LayoutUnit()); 1937 LayoutUnit page_height = PageLogicalHeightForOffset(LayoutUnit());
1928 1938
1929 if (LogicalHeight() > page_height) 1939 if (LogicalHeight() > page_height)
1930 return false; 1940 return false;
1931 1941
1932 // See https://drafts.csswg.org/css-tables-3/#repeated-headers which says 1942 // See https://drafts.csswg.org/css-tables-3/#repeated-headers which says
1933 // a header/footer can repeat if it takes up less than a quarter of the page. 1943 // a header/footer can repeat if it takes up less than a quarter of the page.
1934 if (LogicalHeight() > 0 && page_height / LogicalHeight() < 4) 1944 if (LogicalHeight() > 0 && page_height / LogicalHeight() < 4)
1935 return false; 1945 return false;
1936 1946
1937 return true; 1947 return true;
1938 } 1948 }
1939 1949
1940 bool LayoutTableSection::MapToVisualRectInAncestorSpaceInternal( 1950 bool LayoutTableSection::MapToVisualRectInAncestorSpaceInternal(
1941 const LayoutBoxModelObject* ancestor, 1951 const LayoutBoxModelObject* ancestor,
1942 TransformState& transform_state, 1952 TransformState& transform_state,
1943 VisualRectFlags flags) const { 1953 VisualRectFlags flags) const {
1944 if (ancestor == this) 1954 if (ancestor == this)
1945 return true; 1955 return true;
1946 // Repeating table headers are painted once per fragmentation page/column. 1956 // Repeating table headers and footers are painted once per
1957 // page/column. So we need to use the rect for the entire table because
1958 // the repeating headers/footers will appear throughout it.
1947 // This does not go through the regular fragmentation machinery, so we need 1959 // This does not go through the regular fragmentation machinery, so we need
1948 // special code to expand the invalidation rect to contain all positions of 1960 // special code to expand the invalidation rect to contain all positions of
1949 // the header in all columns. 1961 // the header in all columns.
1950 // Note that this is in flow thread coordinates, not visual coordinates. The 1962 // Note that this is in flow thread coordinates, not visual coordinates. The
1951 // enclosing LayoutFlowThread will convert to visual coordinates. 1963 // enclosing LayoutFlowThread will convert to visual coordinates.
1952 if (IsRepeatingHeaderGroup()) { 1964 if (IsRepeatingHeaderGroup() || IsRepeatingFooterGroup()) {
1953 transform_state.Flatten(); 1965 transform_state.Flatten();
1954 FloatRect rect = transform_state.LastPlanarQuad().BoundingBox(); 1966 FloatRect rect = transform_state.LastPlanarQuad().BoundingBox();
1955 rect.SetHeight(Table()->LogicalHeight()); 1967 rect.SetHeight(Table()->LogicalHeight());
1956 transform_state.SetQuad(FloatQuad(rect)); 1968 transform_state.SetQuad(FloatQuad(rect));
1969 return Table()->MapToVisualRectInAncestorSpaceInternal(
1970 ancestor, transform_state, flags);
1957 } 1971 }
1958 return LayoutTableBoxComponent::MapToVisualRectInAncestorSpaceInternal( 1972 return LayoutTableBoxComponent::MapToVisualRectInAncestorSpaceInternal(
1959 ancestor, transform_state, flags); 1973 ancestor, transform_state, flags);
1960 } 1974 }
1961 1975
1962 bool LayoutTableSection::PaintedOutputOfObjectHasNoEffectRegardlessOfSize() 1976 bool LayoutTableSection::PaintedOutputOfObjectHasNoEffectRegardlessOfSize()
1963 const { 1977 const {
1964 // LayoutTableSection paints background from columns. 1978 // LayoutTableSection paints background from columns.
1965 if (Table()->HasColElements()) 1979 if (Table()->HasColElements())
1966 return false; 1980 return false;
1967 return LayoutTableBoxComponent:: 1981 return LayoutTableBoxComponent::
1968 PaintedOutputOfObjectHasNoEffectRegardlessOfSize(); 1982 PaintedOutputOfObjectHasNoEffectRegardlessOfSize();
1969 } 1983 }
1970 1984
1971 } // namespace blink 1985 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698