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 // TODO: Accounting for the border-spacing here is wrong. |
| 92 LayoutUnit header_group_offset = |
| 93 table->BlockOffsetToFirstRepeatableHeader() + table->VBorderSpacing(); |
| 94 // The first row in the table may have a pagination strut before it so we need |
| 95 // to account for that when establishing its position. |
| 96 LayoutUnit strut_on_first_row; |
| 97 LayoutTableSection* top_section = table->TopSection(); |
| 98 if (top_section) { |
| 99 if (LayoutTableRow* row = top_section->FirstRow()) |
| 100 strut_on_first_row = row->PaginationStrut(); |
| 101 } |
| 102 header_group_offset += strut_on_first_row; |
| 103 LayoutUnit total_height_of_rows = |
| 104 sections_rect.Height() + IntMod(header_group_offset, page_height); |
| 105 total_height_of_rows -= (layout_table_section_.LogicalHeight() - |
| 106 layout_table_section_.FirstRow()->PaginationStrut()); |
| 107 |
| 108 // Move the offset to the top of the page the table starts on. |
| 109 LayoutPoint pagination_offset = paint_offset; |
| 110 pagination_offset.Move(LayoutUnit(), -total_height_of_rows); |
| 111 |
| 112 // Paint up to the last page that needs painting. |
| 113 LayoutUnit bottom_bound = |
| 114 std::min(LayoutUnit(paint_info.GetCullRect().rect_.MaxY()), |
| 115 pagination_offset.Y() + total_height_of_rows - page_height); |
| 116 |
| 117 // If the first row in the table would overlap with the footer on the first |
| 118 // page then don't repeat the footer there. |
| 119 if (top_section) { |
| 120 LayoutUnit height_of_previous_footers = |
| 121 table->RowOffsetFromRepeatingFooter(); |
| 122 LayoutUnit offset_for_footer = page_height - height_of_previous_footers; |
| 123 if (top_section->FirstRow() && |
| 124 header_group_offset + top_section->FirstRow()->LogicalHeight() > |
| 125 offset_for_footer) |
| 126 pagination_offset.Move(LayoutUnit(), page_height); |
| 127 } |
| 128 |
| 129 // Paint a footer on each page from first to next-to-last. |
| 130 while (pagination_offset.Y() < bottom_bound) { |
| 131 LayoutPoint nested_offset = pagination_offset; |
| 132 LayoutUnit height_of_previous_footers = |
| 133 table->RowOffsetFromRepeatingFooter(); |
| 134 LayoutUnit offset_for_footer = page_height - height_of_previous_footers; |
| 135 nested_offset.Move(LayoutUnit(), offset_for_footer); |
| 136 if (item_to_paint == kPaintCollapsedBorders) { |
| 137 PaintCollapsedSectionBorders(paint_info, nested_offset); |
| 138 } else { |
| 139 PaintSection(paint_info, nested_offset); |
| 140 } |
| 141 pagination_offset.Move(0, page_height.ToInt()); |
| 142 } |
| 143 } |
| 144 |
78 void TableSectionPainter::Paint(const PaintInfo& paint_info, | 145 void TableSectionPainter::Paint(const PaintInfo& paint_info, |
79 const LayoutPoint& paint_offset) { | 146 const LayoutPoint& paint_offset) { |
80 ObjectPainter(layout_table_section_) | 147 ObjectPainter(layout_table_section_) |
81 .CheckPaintOffset(paint_info, paint_offset); | 148 .CheckPaintOffset(paint_info, paint_offset); |
82 PaintSection(paint_info, paint_offset); | 149 PaintSection(paint_info, paint_offset); |
83 LayoutTable* table = layout_table_section_.Table(); | 150 LayoutTable* table = layout_table_section_.Table(); |
84 if (table->Header() == layout_table_section_) | 151 if (table->Header() == layout_table_section_) { |
85 PaintRepeatingHeaderGroup(paint_info, paint_offset, kPaintSection); | 152 PaintRepeatingHeaderGroup(paint_info, paint_offset, kPaintSection); |
| 153 } else if (table->Footer() == layout_table_section_) { |
| 154 PaintRepeatingFooterGroup(paint_info, paint_offset, kPaintSection); |
| 155 } |
86 } | 156 } |
87 | 157 |
88 void TableSectionPainter::PaintSection(const PaintInfo& paint_info, | 158 void TableSectionPainter::PaintSection(const PaintInfo& paint_info, |
89 const LayoutPoint& paint_offset) { | 159 const LayoutPoint& paint_offset) { |
90 DCHECK(!layout_table_section_.NeedsLayout()); | 160 DCHECK(!layout_table_section_.NeedsLayout()); |
91 // avoid crashing on bugs that cause us to paint with dirty layout | 161 // avoid crashing on bugs that cause us to paint with dirty layout |
92 if (layout_table_section_.NeedsLayout()) | 162 if (layout_table_section_.NeedsLayout()) |
93 return; | 163 return; |
94 | 164 |
95 unsigned total_rows = layout_table_section_.NumRows(); | 165 unsigned total_rows = layout_table_section_.NumRows(); |
(...skipping 16 matching lines...) Expand all Loading... |
112 if (ShouldPaintSelfOutline(paint_info.phase)) | 182 if (ShouldPaintSelfOutline(paint_info.phase)) |
113 ObjectPainter(layout_table_section_) | 183 ObjectPainter(layout_table_section_) |
114 .PaintOutline(paint_info, adjusted_paint_offset); | 184 .PaintOutline(paint_info, adjusted_paint_offset); |
115 } | 185 } |
116 | 186 |
117 void TableSectionPainter::PaintCollapsedBorders( | 187 void TableSectionPainter::PaintCollapsedBorders( |
118 const PaintInfo& paint_info, | 188 const PaintInfo& paint_info, |
119 const LayoutPoint& paint_offset) { | 189 const LayoutPoint& paint_offset) { |
120 PaintCollapsedSectionBorders(paint_info, paint_offset); | 190 PaintCollapsedSectionBorders(paint_info, paint_offset); |
121 LayoutTable* table = layout_table_section_.Table(); | 191 LayoutTable* table = layout_table_section_.Table(); |
122 if (table->Header() == layout_table_section_) | 192 if (table->Header() == layout_table_section_) { |
123 PaintRepeatingHeaderGroup(paint_info, paint_offset, kPaintCollapsedBorders); | 193 PaintRepeatingHeaderGroup(paint_info, paint_offset, kPaintCollapsedBorders); |
| 194 } else if (table->Footer() == layout_table_section_) { |
| 195 PaintRepeatingFooterGroup(paint_info, paint_offset, kPaintCollapsedBorders); |
| 196 } |
124 } | 197 } |
125 | 198 |
126 void TableSectionPainter::PaintCollapsedSectionBorders( | 199 void TableSectionPainter::PaintCollapsedSectionBorders( |
127 const PaintInfo& paint_info, | 200 const PaintInfo& paint_info, |
128 const LayoutPoint& paint_offset) { | 201 const LayoutPoint& paint_offset) { |
129 if (!layout_table_section_.NumRows() || | 202 if (!layout_table_section_.NumRows() || |
130 !layout_table_section_.Table()->EffectiveColumns().size()) | 203 !layout_table_section_.Table()->EffectiveColumns().size()) |
131 return; | 204 return; |
132 | 205 |
133 LayoutPoint adjusted_paint_offset = | 206 LayoutPoint adjusted_paint_offset = |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 const PaintInfo& paint_info_for_cells, | 445 const PaintInfo& paint_info_for_cells, |
373 const LayoutPoint& paint_offset) { | 446 const LayoutPoint& paint_offset) { |
374 if (!cell.HasSelfPaintingLayer() && !cell.Row()->HasSelfPaintingLayer()) { | 447 if (!cell.HasSelfPaintingLayer() && !cell.Row()->HasSelfPaintingLayer()) { |
375 LayoutPoint cell_point = | 448 LayoutPoint cell_point = |
376 layout_table_section_.FlipForWritingModeForChild(&cell, paint_offset); | 449 layout_table_section_.FlipForWritingModeForChild(&cell, paint_offset); |
377 cell.Paint(paint_info_for_cells, cell_point); | 450 cell.Paint(paint_info_for_cells, cell_point); |
378 } | 451 } |
379 } | 452 } |
380 | 453 |
381 } // namespace blink | 454 } // namespace blink |
OLD | NEW |