| 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 |