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