OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/paint/TableSectionPainter.h" | 5 #include "core/paint/TableSectionPainter.h" |
6 | 6 |
7 #include "core/layout/LayoutTableCell.h" | 7 #include "core/layout/LayoutTableCell.h" |
8 #include "core/layout/LayoutTableCol.h" | 8 #include "core/layout/LayoutTableCol.h" |
9 #include "core/layout/LayoutTableRow.h" | 9 #include "core/layout/LayoutTableRow.h" |
10 #include "core/paint/BoxClipper.h" | 10 #include "core/paint/BoxClipper.h" |
(...skipping 21 matching lines...) Expand all Loading... |
32 | 32 |
33 LayoutUnit header_group_offset = table->BlockOffsetToFirstRepeatableHeader(); | 33 LayoutUnit header_group_offset = table->BlockOffsetToFirstRepeatableHeader(); |
34 // The header may have a pagination strut before it so we need to account for | 34 // The header may have a pagination strut before it so we need to account for |
35 // that when establishing its position. | 35 // that when establishing its position. |
36 LayoutUnit strut_on_first_row; | 36 LayoutUnit strut_on_first_row; |
37 if (LayoutTableRow* row = layout_table_section_.FirstRow()) | 37 if (LayoutTableRow* row = layout_table_section_.FirstRow()) |
38 strut_on_first_row = row->PaginationStrut(); | 38 strut_on_first_row = row->PaginationStrut(); |
39 header_group_offset += strut_on_first_row; | 39 header_group_offset += strut_on_first_row; |
40 LayoutUnit offset_to_next_page = | 40 LayoutUnit offset_to_next_page = |
41 page_height - IntMod(header_group_offset, page_height); | 41 page_height - IntMod(header_group_offset, page_height); |
42 // Move paginationOffset to the top of the next page. | 42 // Move pagination_offset to the top of the next page. |
43 pagination_offset.Move(LayoutUnit(), offset_to_next_page); | 43 pagination_offset.Move(LayoutUnit(), offset_to_next_page); |
44 // Now move paginationOffset to the top of the page the cull rect starts on. | 44 // Now move pagination_offset to the top of the page the cull rect starts on. |
45 if (paint_info.GetCullRect().rect_.Y() > pagination_offset.Y()) { | 45 if (paint_info.GetCullRect().rect_.Y() > pagination_offset.Y()) { |
46 pagination_offset.Move(LayoutUnit(), | 46 pagination_offset.Move(LayoutUnit(), |
47 page_height * ((paint_info.GetCullRect().rect_.Y() - | 47 page_height * ((paint_info.GetCullRect().rect_.Y() - |
48 pagination_offset.Y()) / | 48 pagination_offset.Y()) / |
49 page_height) | 49 page_height) |
50 .ToInt()); | 50 .ToInt()); |
51 } | 51 } |
52 | 52 |
53 // We only want to consider pages where we going to paint a row, so exclude | 53 // We only want to consider pages where we going to paint a row, so exclude |
54 // captions and border spacing from the table. | 54 // captions and border spacing from the table. |
(...skipping 14 matching lines...) Expand all Loading... |
69 if (item_to_paint == kPaintCollapsedBorders) { | 69 if (item_to_paint == kPaintCollapsedBorders) { |
70 PaintCollapsedSectionBorders(paint_info, nested_offset, | 70 PaintCollapsedSectionBorders(paint_info, nested_offset, |
71 current_border_value); | 71 current_border_value); |
72 } else { | 72 } else { |
73 PaintSection(paint_info, nested_offset); | 73 PaintSection(paint_info, nested_offset); |
74 } | 74 } |
75 pagination_offset.Move(0, page_height.ToInt()); | 75 pagination_offset.Move(0, page_height.ToInt()); |
76 } | 76 } |
77 } | 77 } |
78 | 78 |
| 79 void TableSectionPainter::PaintRepeatingFooterGroup( |
| 80 const PaintInfo& paint_info, |
| 81 const LayoutPoint& paint_offset, |
| 82 const CollapsedBorderValue& current_border_value, |
| 83 ItemToPaint item_to_paint) { |
| 84 if (!layout_table_section_.IsRepeatingFooterGroup()) |
| 85 return; |
| 86 |
| 87 // Work out the top position of the table so we can decide |
| 88 // which page to paint the first footer on. |
| 89 LayoutTable* table = layout_table_section_.Table(); |
| 90 LayoutRect sections_rect(LayoutPoint(), table->Size()); |
| 91 table->SubtractCaptionRect(sections_rect); |
| 92 LayoutUnit page_height = table->PageLogicalHeightForOffset(LayoutUnit()); |
| 93 // TODO: Accounting for the border-spacing here is wrong. |
| 94 LayoutUnit header_group_offset = |
| 95 table->BlockOffsetToFirstRepeatableHeader() + table->VBorderSpacing(); |
| 96 // The first row in the table may have a pagination strut before it so we need |
| 97 // to account for that when establishing its position. |
| 98 LayoutUnit strut_on_first_row; |
| 99 LayoutTableSection* top_section = table->TopSection(); |
| 100 if (top_section) { |
| 101 if (LayoutTableRow* row = top_section->FirstRow()) |
| 102 strut_on_first_row = row->PaginationStrut(); |
| 103 } |
| 104 header_group_offset += strut_on_first_row; |
| 105 LayoutUnit total_height_of_rows = |
| 106 sections_rect.Height() + IntMod(header_group_offset, page_height); |
| 107 total_height_of_rows -= (layout_table_section_.LogicalHeight() - |
| 108 layout_table_section_.FirstRow()->PaginationStrut()); |
| 109 |
| 110 // Move the offset to the top of the page the table starts on. |
| 111 LayoutPoint pagination_offset = paint_offset; |
| 112 pagination_offset.Move(LayoutUnit(), -total_height_of_rows); |
| 113 |
| 114 // Paint up to the last page that needs painting. |
| 115 LayoutUnit bottom_bound = |
| 116 std::min(LayoutUnit(paint_info.GetCullRect().rect_.MaxY()), |
| 117 pagination_offset.Y() + total_height_of_rows - page_height); |
| 118 |
| 119 // If the first row in the table would overlap with the footer on the first |
| 120 // page then don't repeat the footer there. |
| 121 if (top_section) { |
| 122 LayoutUnit height_of_previous_footers = |
| 123 table->RowOffsetFromRepeatingFooter(); |
| 124 LayoutUnit offset_for_footer = page_height - height_of_previous_footers; |
| 125 if (top_section->FirstRow() && |
| 126 header_group_offset + top_section->FirstRow()->LogicalHeight() > |
| 127 offset_for_footer) |
| 128 pagination_offset.Move(LayoutUnit(), page_height); |
| 129 } |
| 130 |
| 131 // Paint a footer on each page from first to next-to-last. |
| 132 while (pagination_offset.Y() < bottom_bound) { |
| 133 LayoutPoint nested_offset = pagination_offset; |
| 134 LayoutUnit height_of_previous_footers = |
| 135 table->RowOffsetFromRepeatingFooter(); |
| 136 LayoutUnit offset_for_footer = page_height - height_of_previous_footers; |
| 137 nested_offset.Move(LayoutUnit(), offset_for_footer); |
| 138 if (item_to_paint == kPaintCollapsedBorders) { |
| 139 PaintCollapsedSectionBorders(paint_info, nested_offset, |
| 140 current_border_value); |
| 141 } else { |
| 142 PaintSection(paint_info, nested_offset); |
| 143 } |
| 144 pagination_offset.Move(0, page_height.ToInt()); |
| 145 } |
| 146 } |
| 147 |
79 void TableSectionPainter::Paint(const PaintInfo& paint_info, | 148 void TableSectionPainter::Paint(const PaintInfo& paint_info, |
80 const LayoutPoint& paint_offset) { | 149 const LayoutPoint& paint_offset) { |
81 ObjectPainter(layout_table_section_) | 150 ObjectPainter(layout_table_section_) |
82 .CheckPaintOffset(paint_info, paint_offset); | 151 .CheckPaintOffset(paint_info, paint_offset); |
83 PaintSection(paint_info, paint_offset); | 152 PaintSection(paint_info, paint_offset); |
84 LayoutTable* table = layout_table_section_.Table(); | 153 LayoutTable* table = layout_table_section_.Table(); |
85 if (table->Header() == layout_table_section_) | 154 if (table->Header() == layout_table_section_) { |
86 PaintRepeatingHeaderGroup(paint_info, paint_offset, CollapsedBorderValue(), | 155 PaintRepeatingHeaderGroup(paint_info, paint_offset, CollapsedBorderValue(), |
87 kPaintSection); | 156 kPaintSection); |
| 157 } else if (table->Footer() == layout_table_section_) { |
| 158 PaintRepeatingFooterGroup(paint_info, paint_offset, CollapsedBorderValue(), |
| 159 kPaintSection); |
| 160 } |
88 } | 161 } |
89 | 162 |
90 void TableSectionPainter::PaintSection(const PaintInfo& paint_info, | 163 void TableSectionPainter::PaintSection(const PaintInfo& paint_info, |
91 const LayoutPoint& paint_offset) { | 164 const LayoutPoint& paint_offset) { |
92 DCHECK(!layout_table_section_.NeedsLayout()); | 165 DCHECK(!layout_table_section_.NeedsLayout()); |
93 // avoid crashing on bugs that cause us to paint with dirty layout | 166 // avoid crashing on bugs that cause us to paint with dirty layout |
94 if (layout_table_section_.NeedsLayout()) | 167 if (layout_table_section_.NeedsLayout()) |
95 return; | 168 return; |
96 | 169 |
97 unsigned total_rows = layout_table_section_.NumRows(); | 170 unsigned total_rows = layout_table_section_.NumRows(); |
(...skipping 17 matching lines...) Expand all Loading... |
115 ObjectPainter(layout_table_section_) | 188 ObjectPainter(layout_table_section_) |
116 .PaintOutline(paint_info, adjusted_paint_offset); | 189 .PaintOutline(paint_info, adjusted_paint_offset); |
117 } | 190 } |
118 | 191 |
119 void TableSectionPainter::PaintCollapsedBorders( | 192 void TableSectionPainter::PaintCollapsedBorders( |
120 const PaintInfo& paint_info, | 193 const PaintInfo& paint_info, |
121 const LayoutPoint& paint_offset, | 194 const LayoutPoint& paint_offset, |
122 const CollapsedBorderValue& current_border_value) { | 195 const CollapsedBorderValue& current_border_value) { |
123 PaintCollapsedSectionBorders(paint_info, paint_offset, current_border_value); | 196 PaintCollapsedSectionBorders(paint_info, paint_offset, current_border_value); |
124 LayoutTable* table = layout_table_section_.Table(); | 197 LayoutTable* table = layout_table_section_.Table(); |
125 if (table->Header() == layout_table_section_) | 198 if (table->Header() == layout_table_section_) { |
126 PaintRepeatingHeaderGroup(paint_info, paint_offset, current_border_value, | 199 PaintRepeatingHeaderGroup(paint_info, paint_offset, current_border_value, |
127 kPaintCollapsedBorders); | 200 kPaintCollapsedBorders); |
| 201 } else if (table->Footer() == layout_table_section_) { |
| 202 PaintRepeatingFooterGroup(paint_info, paint_offset, current_border_value, |
| 203 kPaintCollapsedBorders); |
| 204 } |
128 } | 205 } |
129 | 206 |
130 void TableSectionPainter::PaintCollapsedSectionBorders( | 207 void TableSectionPainter::PaintCollapsedSectionBorders( |
131 const PaintInfo& paint_info, | 208 const PaintInfo& paint_info, |
132 const LayoutPoint& paint_offset, | 209 const LayoutPoint& paint_offset, |
133 const CollapsedBorderValue& current_border_value) { | 210 const CollapsedBorderValue& current_border_value) { |
134 if (!layout_table_section_.NumRows() || | 211 if (!layout_table_section_.NumRows() || |
135 !layout_table_section_.Table()->EffectiveColumns().size()) | 212 !layout_table_section_.Table()->EffectiveColumns().size()) |
136 return; | 213 return; |
137 | 214 |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 const PaintInfo& paint_info_for_cells, | 457 const PaintInfo& paint_info_for_cells, |
381 const LayoutPoint& paint_offset) { | 458 const LayoutPoint& paint_offset) { |
382 if (!cell.HasSelfPaintingLayer() && !cell.Row()->HasSelfPaintingLayer()) { | 459 if (!cell.HasSelfPaintingLayer() && !cell.Row()->HasSelfPaintingLayer()) { |
383 LayoutPoint cell_point = | 460 LayoutPoint cell_point = |
384 layout_table_section_.FlipForWritingModeForChild(&cell, paint_offset); | 461 layout_table_section_.FlipForWritingModeForChild(&cell, paint_offset); |
385 cell.Paint(paint_info_for_cells, cell_point); | 462 cell.Paint(paint_info_for_cells, cell_point); |
386 } | 463 } |
387 } | 464 } |
388 | 465 |
389 } // namespace blink | 466 } // namespace blink |
OLD | NEW |