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 <algorithm> | 7 #include <algorithm> |
8 #include "core/layout/LayoutTableCell.h" | 8 #include "core/layout/LayoutTableCell.h" |
9 #include "core/layout/LayoutTableCol.h" | 9 #include "core/layout/LayoutTableCol.h" |
10 #include "core/layout/LayoutTableRow.h" | 10 #include "core/layout/LayoutTableRow.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 13 matching lines...) Expand all Loading... |
68 nested_offset.Move(LayoutUnit(), height_of_previous_headers); | 68 nested_offset.Move(LayoutUnit(), height_of_previous_headers); |
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 } else { | 71 } else { |
72 PaintSection(paint_info, nested_offset); | 72 PaintSection(paint_info, nested_offset); |
73 } | 73 } |
74 pagination_offset.Move(0, page_height.ToInt()); | 74 pagination_offset.Move(0, page_height.ToInt()); |
75 } | 75 } |
76 } | 76 } |
77 | 77 |
| 78 void TableSectionPainter::PaintRepeatingFooterGroup( |
| 79 const PaintInfo& paint_info, |
| 80 const LayoutPoint& paint_offset, |
| 81 ItemToPaint item_to_paint) { |
| 82 if (!layout_table_section_.IsRepeatingFooterGroup()) |
| 83 return; |
| 84 |
| 85 // Work out the top position of the table so we can decide |
| 86 // which page to paint the first footer on. |
| 87 LayoutTable* table = layout_table_section_.Table(); |
| 88 LayoutRect sections_rect(LayoutPoint(), table->Size()); |
| 89 table->SubtractCaptionRect(sections_rect); |
| 90 LayoutUnit page_height = table->PageLogicalHeightForOffset(LayoutUnit()); |
| 91 LayoutUnit height_of_previous_footers = table->RowOffsetFromRepeatingFooter(); |
| 92 LayoutUnit offset_for_footer = page_height - height_of_previous_footers; |
| 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 && top_section->FirstRow() && |
| 122 IntMod(header_group_offset, page_height) + |
| 123 top_section->FirstRow()->LogicalHeight() > |
| 124 offset_for_footer) { |
| 125 pagination_offset.Move(LayoutUnit(), page_height); |
| 126 } |
| 127 |
| 128 // Paint a footer on each page from first to next-to-last. |
| 129 while (pagination_offset.Y() < bottom_bound) { |
| 130 LayoutPoint nested_offset = pagination_offset; |
| 131 nested_offset.Move(LayoutUnit(), offset_for_footer); |
| 132 if (item_to_paint == kPaintCollapsedBorders) { |
| 133 PaintCollapsedSectionBorders(paint_info, nested_offset); |
| 134 } else { |
| 135 PaintSection(paint_info, nested_offset); |
| 136 } |
| 137 pagination_offset.Move(0, page_height.ToInt()); |
| 138 } |
| 139 } |
| 140 |
78 void TableSectionPainter::Paint(const PaintInfo& paint_info, | 141 void TableSectionPainter::Paint(const PaintInfo& paint_info, |
79 const LayoutPoint& paint_offset) { | 142 const LayoutPoint& paint_offset) { |
80 ObjectPainter(layout_table_section_) | 143 ObjectPainter(layout_table_section_) |
81 .CheckPaintOffset(paint_info, paint_offset); | 144 .CheckPaintOffset(paint_info, paint_offset); |
82 PaintSection(paint_info, paint_offset); | 145 PaintSection(paint_info, paint_offset); |
83 LayoutTable* table = layout_table_section_.Table(); | 146 LayoutTable* table = layout_table_section_.Table(); |
84 if (table->Header() == layout_table_section_) | 147 if (table->Header() == layout_table_section_) { |
85 PaintRepeatingHeaderGroup(paint_info, paint_offset, kPaintSection); | 148 PaintRepeatingHeaderGroup(paint_info, paint_offset, kPaintSection); |
| 149 } else if (table->Footer() == layout_table_section_) { |
| 150 PaintRepeatingFooterGroup(paint_info, paint_offset, kPaintSection); |
| 151 } |
86 } | 152 } |
87 | 153 |
88 void TableSectionPainter::PaintSection(const PaintInfo& paint_info, | 154 void TableSectionPainter::PaintSection(const PaintInfo& paint_info, |
89 const LayoutPoint& paint_offset) { | 155 const LayoutPoint& paint_offset) { |
90 DCHECK(!layout_table_section_.NeedsLayout()); | 156 DCHECK(!layout_table_section_.NeedsLayout()); |
91 // avoid crashing on bugs that cause us to paint with dirty layout | 157 // avoid crashing on bugs that cause us to paint with dirty layout |
92 if (layout_table_section_.NeedsLayout()) | 158 if (layout_table_section_.NeedsLayout()) |
93 return; | 159 return; |
94 | 160 |
95 unsigned total_rows = layout_table_section_.NumRows(); | 161 unsigned total_rows = layout_table_section_.NumRows(); |
(...skipping 16 matching lines...) Expand all Loading... |
112 if (ShouldPaintSelfOutline(paint_info.phase)) | 178 if (ShouldPaintSelfOutline(paint_info.phase)) |
113 ObjectPainter(layout_table_section_) | 179 ObjectPainter(layout_table_section_) |
114 .PaintOutline(paint_info, adjusted_paint_offset); | 180 .PaintOutline(paint_info, adjusted_paint_offset); |
115 } | 181 } |
116 | 182 |
117 void TableSectionPainter::PaintCollapsedBorders( | 183 void TableSectionPainter::PaintCollapsedBorders( |
118 const PaintInfo& paint_info, | 184 const PaintInfo& paint_info, |
119 const LayoutPoint& paint_offset) { | 185 const LayoutPoint& paint_offset) { |
120 PaintCollapsedSectionBorders(paint_info, paint_offset); | 186 PaintCollapsedSectionBorders(paint_info, paint_offset); |
121 LayoutTable* table = layout_table_section_.Table(); | 187 LayoutTable* table = layout_table_section_.Table(); |
122 if (table->Header() == layout_table_section_) | 188 if (table->Header() == layout_table_section_) { |
123 PaintRepeatingHeaderGroup(paint_info, paint_offset, kPaintCollapsedBorders); | 189 PaintRepeatingHeaderGroup(paint_info, paint_offset, kPaintCollapsedBorders); |
| 190 } else if (table->Footer() == layout_table_section_) { |
| 191 PaintRepeatingFooterGroup(paint_info, paint_offset, kPaintCollapsedBorders); |
| 192 } |
124 } | 193 } |
125 | 194 |
126 void TableSectionPainter::PaintCollapsedSectionBorders( | 195 void TableSectionPainter::PaintCollapsedSectionBorders( |
127 const PaintInfo& paint_info, | 196 const PaintInfo& paint_info, |
128 const LayoutPoint& paint_offset) { | 197 const LayoutPoint& paint_offset) { |
129 if (!layout_table_section_.NumRows() || | 198 if (!layout_table_section_.NumRows() || |
130 !layout_table_section_.Table()->EffectiveColumns().size()) | 199 !layout_table_section_.Table()->EffectiveColumns().size()) |
131 return; | 200 return; |
132 | 201 |
133 LayoutPoint adjusted_paint_offset = | 202 LayoutPoint adjusted_paint_offset = |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 const PaintInfo& paint_info_for_cells, | 441 const PaintInfo& paint_info_for_cells, |
373 const LayoutPoint& paint_offset) { | 442 const LayoutPoint& paint_offset) { |
374 if (!cell.HasSelfPaintingLayer() && !cell.Row()->HasSelfPaintingLayer()) { | 443 if (!cell.HasSelfPaintingLayer() && !cell.Row()->HasSelfPaintingLayer()) { |
375 LayoutPoint cell_point = | 444 LayoutPoint cell_point = |
376 layout_table_section_.FlipForWritingModeForChild(&cell, paint_offset); | 445 layout_table_section_.FlipForWritingModeForChild(&cell, paint_offset); |
377 cell.Paint(paint_info_for_cells, cell_point); | 446 cell.Paint(paint_info_for_cells, cell_point); |
378 } | 447 } |
379 } | 448 } |
380 | 449 |
381 } // namespace blink | 450 } // namespace blink |
OLD | NEW |