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, 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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 : LayoutTableBoxComponent(element), | 90 : LayoutTableBoxComponent(element), |
91 c_col_(0), | 91 c_col_(0), |
92 c_row_(0), | 92 c_row_(0), |
93 outer_border_start_(0), | 93 outer_border_start_(0), |
94 outer_border_end_(0), | 94 outer_border_end_(0), |
95 outer_border_before_(0), | 95 outer_border_before_(0), |
96 outer_border_after_(0), | 96 outer_border_after_(0), |
97 needs_cell_recalc_(false), | 97 needs_cell_recalc_(false), |
98 force_full_paint_(false), | 98 force_full_paint_(false), |
99 has_multiple_cell_levels_(false), | 99 has_multiple_cell_levels_(false), |
100 has_spanning_cells_(false) { | 100 has_spanning_cells_(false), |
| 101 is_repeating_header_group_(false) { |
101 // init LayoutObject attributes | 102 // init LayoutObject attributes |
102 SetInline(false); // our object is not Inline | 103 SetInline(false); // our object is not Inline |
103 } | 104 } |
104 | 105 |
105 LayoutTableSection::~LayoutTableSection() {} | 106 LayoutTableSection::~LayoutTableSection() {} |
106 | 107 |
107 void LayoutTableSection::StyleDidChange(StyleDifference diff, | 108 void LayoutTableSection::StyleDidChange(StyleDifference diff, |
108 const ComputedStyle* old_style) { | 109 const ComputedStyle* old_style) { |
109 DCHECK(Style()->Display() == EDisplay::kTableFooterGroup || | 110 DCHECK(Style()->Display() == EDisplay::kTableFooterGroup || |
110 Style()->Display() == EDisplay::kTableRowGroup || | 111 Style()->Display() == EDisplay::kTableRowGroup || |
(...skipping 1935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2046 } | 2047 } |
2047 | 2048 |
2048 if (!row_is_at_top_of_column) | 2049 if (!row_is_at_top_of_column) |
2049 return; | 2050 return; |
2050 } | 2051 } |
2051 // We need to push this row to the next fragmentainer. If there are repeated | 2052 // We need to push this row to the next fragmentainer. If there are repeated |
2052 // table headers, we need to make room for those at the top of the next | 2053 // table headers, we need to make room for those at the top of the next |
2053 // fragmentainer, above this row. Otherwise, this row will just go at the top | 2054 // fragmentainer, above this row. Otherwise, this row will just go at the top |
2054 // of the next fragmentainer. | 2055 // of the next fragmentainer. |
2055 | 2056 |
2056 LayoutTableSection* header = Table()->Header(); | |
2057 if (row_object.IsFirstRowInSectionAfterHeader()) | |
2058 Table()->SetRowOffsetFromRepeatingHeader(LayoutUnit()); | |
2059 // Border spacing from the previous row has pushed this row just past the top | 2057 // Border spacing from the previous row has pushed this row just past the top |
2060 // of the page, so we must reposition it to the top of the page and avoid any | 2058 // of the page, so we must reposition it to the top of the page and avoid any |
2061 // repeating header. | 2059 // repeating header. |
2062 if (row_is_at_top_of_column && offset_from_top_of_page) | 2060 if (row_is_at_top_of_column && offset_from_top_of_page) |
2063 pagination_strut -= offset_from_top_of_page.ToInt(); | 2061 pagination_strut -= offset_from_top_of_page.ToInt(); |
2064 | 2062 |
2065 // If we have a header group we will paint it at the top of each page, | 2063 // If we have a header group we will paint it at the top of each page, |
2066 // move the rows down to accomodate it. | 2064 // move the rows down to accomodate it. |
| 2065 LayoutTableSection* header = Table()->Header(); |
2067 if (header && header != this) | 2066 if (header && header != this) |
2068 pagination_strut += Table()->RowOffsetFromRepeatingHeader().ToInt(); | 2067 pagination_strut += Table()->RowOffsetFromRepeatingHeader().ToInt(); |
2069 row_object.SetPaginationStrut(LayoutUnit(pagination_strut)); | 2068 row_object.SetPaginationStrut(LayoutUnit(pagination_strut)); |
2070 | 2069 |
2071 // We have inserted a pagination strut before the row. Adjust the logical top | 2070 // We have inserted a pagination strut before the row. Adjust the logical top |
2072 // and re-lay out. We no longer want to break inside the row, but rather | 2071 // and re-lay out. We no longer want to break inside the row, but rather |
2073 // *before* it. From the previous layout pass, there are most likely | 2072 // *before* it. From the previous layout pass, there are most likely |
2074 // pagination struts inside some cell in this row that we need to get rid of. | 2073 // pagination struts inside some cell in this row that we need to get rid of. |
2075 row_object.SetLogicalTop(row_object.LogicalTop() + pagination_strut); | 2074 row_object.SetLogicalTop(row_object.LogicalTop() + pagination_strut); |
2076 layouter.SetChildNeedsLayout(&row_object); | 2075 layouter.SetChildNeedsLayout(&row_object); |
2077 row_object.LayoutIfNeeded(); | 2076 row_object.LayoutIfNeeded(); |
2078 | 2077 |
2079 // It's very likely that re-laying out (and nuking pagination struts inside | 2078 // It's very likely that re-laying out (and nuking pagination struts inside |
2080 // cells) gave us a new height. | 2079 // cells) gave us a new height. |
2081 row_object.SetLogicalHeight(LayoutUnit(LogicalHeightForRow(row_object))); | 2080 row_object.SetLogicalHeight(LayoutUnit(LogicalHeightForRow(row_object))); |
2082 } | 2081 } |
2083 | 2082 |
2084 bool LayoutTableSection::IsRepeatingHeaderGroup() const { | 2083 bool LayoutTableSection::HeaderGroupShouldRepeat() const { |
2085 if (GetPaginationBreakability() == LayoutBox::kAllowAnyBreaks) | 2084 if (Table()->Header() != this) |
2086 return false; | 2085 return false; |
2087 // TODO(rhogan): Should we paint a header repeatedly if it's self-painting? | 2086 |
| 2087 if (GetPaginationBreakability() == kAllowAnyBreaks) |
| 2088 return false; |
| 2089 // TODO(rhogan): Sections can be self-painting. |
2088 if (HasSelfPaintingLayer()) | 2090 if (HasSelfPaintingLayer()) |
2089 return false; | 2091 return false; |
2090 LayoutUnit page_height = Table()->PageLogicalHeightForOffset(LayoutUnit()); | 2092 LayoutUnit page_height = PageLogicalHeightForOffset(LayoutUnit()); |
| 2093 // If we don't know the page height yet, just assume we fit. |
2091 if (!page_height) | 2094 if (!page_height) |
2092 return false; | 2095 return true; |
2093 | 2096 |
2094 if (LogicalHeight() > page_height) | 2097 if (LogicalHeight() > page_height) |
2095 return false; | 2098 return false; |
2096 | 2099 |
2097 // If the first row of the section after the header group doesn't fit on the | 2100 // See https://drafts.csswg.org/css-tables-3/#repeated-headers which says |
2098 // page, then don't repeat the header on each page. | 2101 // a header/footer can repeat if it takes up less than a quarter of the page. |
2099 // See https://drafts.csswg.org/css-tables-3/#repeated-headers | 2102 if (LogicalHeight() > 0 && page_height / LogicalHeight() < 4) |
2100 LayoutTableSection* section_below = Table()->SectionBelow(this); | 2103 return false; |
2101 if (!section_below) | |
2102 return true; | |
2103 if (LayoutTableRow* first_row = section_below->FirstRow()) { | |
2104 if (first_row->PaginationStrut() || | |
2105 first_row->LogicalHeight() > page_height) | |
2106 return false; | |
2107 } | |
2108 | 2104 |
2109 return true; | 2105 return true; |
2110 } | 2106 } |
2111 | 2107 |
2112 bool LayoutTableSection::MapToVisualRectInAncestorSpaceInternal( | 2108 bool LayoutTableSection::MapToVisualRectInAncestorSpaceInternal( |
2113 const LayoutBoxModelObject* ancestor, | 2109 const LayoutBoxModelObject* ancestor, |
2114 TransformState& transform_state, | 2110 TransformState& transform_state, |
2115 VisualRectFlags flags) const { | 2111 VisualRectFlags flags) const { |
2116 if (ancestor == this) | 2112 if (ancestor == this) |
2117 return true; | 2113 return true; |
2118 // Repeating table headers are painted once per fragmentation page/column. | 2114 // Repeating table headers are painted once per fragmentation page/column. |
2119 // This does not go through the regular fragmentation machinery, so we need | 2115 // This does not go through the regular fragmentation machinery, so we need |
2120 // special code to expand the invalidation rect to contain all positions of | 2116 // special code to expand the invalidation rect to contain all positions of |
2121 // the header in all columns. | 2117 // the header in all columns. |
2122 // Note that this is in flow thread coordinates, not visual coordinates. The | 2118 // Note that this is in flow thread coordinates, not visual coordinates. The |
2123 // enclosing LayoutFlowThread will convert to visual coordinates. | 2119 // enclosing LayoutFlowThread will convert to visual coordinates. |
2124 if (Table()->Header() == this && IsRepeatingHeaderGroup()) { | 2120 if (IsRepeatingHeaderGroup()) { |
2125 transform_state.Flatten(); | 2121 transform_state.Flatten(); |
2126 FloatRect rect = transform_state.LastPlanarQuad().BoundingBox(); | 2122 FloatRect rect = transform_state.LastPlanarQuad().BoundingBox(); |
2127 rect.SetHeight(Table()->LogicalHeight()); | 2123 rect.SetHeight(Table()->LogicalHeight()); |
2128 transform_state.SetQuad(FloatQuad(rect)); | 2124 transform_state.SetQuad(FloatQuad(rect)); |
2129 } | 2125 } |
2130 return LayoutTableBoxComponent::MapToVisualRectInAncestorSpaceInternal( | 2126 return LayoutTableBoxComponent::MapToVisualRectInAncestorSpaceInternal( |
2131 ancestor, transform_state, flags); | 2127 ancestor, transform_state, flags); |
2132 } | 2128 } |
2133 | 2129 |
2134 bool LayoutTableSection::PaintedOutputOfObjectHasNoEffectRegardlessOfSize() | 2130 bool LayoutTableSection::PaintedOutputOfObjectHasNoEffectRegardlessOfSize() |
2135 const { | 2131 const { |
2136 // LayoutTableSection paints background from columns. | 2132 // LayoutTableSection paints background from columns. |
2137 if (Table()->HasColElements()) | 2133 if (Table()->HasColElements()) |
2138 return false; | 2134 return false; |
2139 return LayoutTableBoxComponent:: | 2135 return LayoutTableBoxComponent:: |
2140 PaintedOutputOfObjectHasNoEffectRegardlessOfSize(); | 2136 PaintedOutputOfObjectHasNoEffectRegardlessOfSize(); |
2141 } | 2137 } |
2142 | 2138 |
2143 } // namespace blink | 2139 } // namespace blink |
OLD | NEW |