| 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/TableCellPainter.h" | 5 #include "core/paint/TableCellPainter.h" |
| 6 | 6 |
| 7 #include "core/layout/LayoutTableCell.h" | 7 #include "core/layout/LayoutTableCell.h" |
| 8 #include "core/paint/BlockPainter.h" | 8 #include "core/paint/BlockPainter.h" |
| 9 #include "core/paint/BoxPainter.h" | 9 #include "core/paint/BoxPainter.h" |
| 10 #include "core/paint/LayoutObjectDrawingRecorder.h" | 10 #include "core/paint/LayoutObjectDrawingRecorder.h" |
| 11 #include "core/paint/ObjectPainter.h" | 11 #include "core/paint/ObjectPainter.h" |
| 12 #include "core/paint/PaintInfo.h" | 12 #include "core/paint/PaintInfo.h" |
| 13 #include "platform/graphics/GraphicsContextStateSaver.h" | 13 #include "platform/graphics/GraphicsContextStateSaver.h" |
| 14 #include "platform/graphics/paint/DrawingRecorder.h" | 14 #include "platform/graphics/paint/DrawingRecorder.h" |
| 15 | 15 |
| 16 namespace blink { | 16 namespace blink { |
| 17 | 17 |
| 18 static const CollapsedBorderValue& CollapsedLeftBorder( | |
| 19 const ComputedStyle& style_for_cell_flow, | |
| 20 const LayoutTableCell::CollapsedBorderValues& values) { | |
| 21 if (style_for_cell_flow.IsHorizontalWritingMode()) { | |
| 22 return style_for_cell_flow.IsLeftToRightDirection() ? values.StartBorder() | |
| 23 : values.EndBorder(); | |
| 24 } | |
| 25 return style_for_cell_flow.IsFlippedBlocksWritingMode() | |
| 26 ? values.AfterBorder() | |
| 27 : values.BeforeBorder(); | |
| 28 } | |
| 29 | |
| 30 static const CollapsedBorderValue& CollapsedRightBorder( | |
| 31 const ComputedStyle& style_for_cell_flow, | |
| 32 const LayoutTableCell::CollapsedBorderValues& values) { | |
| 33 if (style_for_cell_flow.IsHorizontalWritingMode()) { | |
| 34 return style_for_cell_flow.IsLeftToRightDirection() ? values.EndBorder() | |
| 35 : values.StartBorder(); | |
| 36 } | |
| 37 return style_for_cell_flow.IsFlippedBlocksWritingMode() | |
| 38 ? values.BeforeBorder() | |
| 39 : values.AfterBorder(); | |
| 40 } | |
| 41 | |
| 42 static const CollapsedBorderValue& CollapsedTopBorder( | |
| 43 const ComputedStyle& style_for_cell_flow, | |
| 44 const LayoutTableCell::CollapsedBorderValues& values) { | |
| 45 if (style_for_cell_flow.IsHorizontalWritingMode()) | |
| 46 return values.BeforeBorder(); | |
| 47 return style_for_cell_flow.IsLeftToRightDirection() ? values.StartBorder() | |
| 48 : values.EndBorder(); | |
| 49 } | |
| 50 | |
| 51 static const CollapsedBorderValue& CollapsedBottomBorder( | |
| 52 const ComputedStyle& style_for_cell_flow, | |
| 53 const LayoutTableCell::CollapsedBorderValues& values) { | |
| 54 if (style_for_cell_flow.IsHorizontalWritingMode()) | |
| 55 return values.AfterBorder(); | |
| 56 return style_for_cell_flow.IsLeftToRightDirection() ? values.EndBorder() | |
| 57 : values.StartBorder(); | |
| 58 } | |
| 59 | |
| 60 void TableCellPainter::Paint(const PaintInfo& paint_info, | 18 void TableCellPainter::Paint(const PaintInfo& paint_info, |
| 61 const LayoutPoint& paint_offset) { | 19 const LayoutPoint& paint_offset) { |
| 62 BlockPainter(layout_table_cell_).Paint(paint_info, paint_offset); | 20 BlockPainter(layout_table_cell_).Paint(paint_info, paint_offset); |
| 63 } | 21 } |
| 64 | 22 |
| 65 static EBorderStyle CollapsedBorderStyle(EBorderStyle style) { | |
| 66 if (style == kBorderStyleOutset) | |
| 67 return kBorderStyleGroove; | |
| 68 if (style == kBorderStyleInset) | |
| 69 return kBorderStyleRidge; | |
| 70 return style; | |
| 71 } | |
| 72 | |
| 73 const DisplayItemClient& TableCellPainter::DisplayItemClientForBorders() const { | 23 const DisplayItemClient& TableCellPainter::DisplayItemClientForBorders() const { |
| 74 // TODO(wkorman): We may need to handle PaintInvalidationDelayedFull. | 24 // TODO(wkorman): We may need to handle PaintInvalidationDelayedFull. |
| 75 // http://crbug.com/657186 | 25 // http://crbug.com/657186 |
| 76 return layout_table_cell_.UsesCompositedCellDisplayItemClients() | 26 return layout_table_cell_.UsesCompositedCellDisplayItemClients() |
| 77 ? static_cast<const DisplayItemClient&>( | 27 ? static_cast<const DisplayItemClient&>( |
| 78 *layout_table_cell_.GetCollapsedBorderValues()) | 28 *layout_table_cell_.GetCollapsedBorderValues()) |
| 79 : layout_table_cell_; | 29 : layout_table_cell_; |
| 80 } | 30 } |
| 81 | 31 |
| 82 void TableCellPainter::PaintCollapsedBorders( | |
| 83 const PaintInfo& paint_info, | |
| 84 const LayoutPoint& paint_offset, | |
| 85 const CollapsedBorderValue& current_border_value) { | |
| 86 if (layout_table_cell_.Style()->Visibility() != EVisibility::kVisible) | |
| 87 return; | |
| 88 | |
| 89 LayoutPoint adjusted_paint_offset = | |
| 90 paint_offset + layout_table_cell_.Location(); | |
| 91 if (!BlockPainter(layout_table_cell_) | |
| 92 .IntersectsPaintRect(paint_info, adjusted_paint_offset)) | |
| 93 return; | |
| 94 | |
| 95 const LayoutTableCell::CollapsedBorderValues* values = | |
| 96 layout_table_cell_.GetCollapsedBorderValues(); | |
| 97 if (!values) | |
| 98 return; | |
| 99 | |
| 100 const ComputedStyle& style_for_cell_flow = | |
| 101 layout_table_cell_.StyleForCellFlow(); | |
| 102 const CollapsedBorderValue& left_border_value = | |
| 103 CollapsedLeftBorder(style_for_cell_flow, *values); | |
| 104 const CollapsedBorderValue& right_border_value = | |
| 105 CollapsedRightBorder(style_for_cell_flow, *values); | |
| 106 const CollapsedBorderValue& top_border_value = | |
| 107 CollapsedTopBorder(style_for_cell_flow, *values); | |
| 108 const CollapsedBorderValue& bottom_border_value = | |
| 109 CollapsedBottomBorder(style_for_cell_flow, *values); | |
| 110 | |
| 111 int display_item_type = DisplayItem::kTableCollapsedBorderBase; | |
| 112 if (top_border_value.ShouldPaint(current_border_value)) | |
| 113 display_item_type |= DisplayItem::kTableCollapsedBorderTop; | |
| 114 if (bottom_border_value.ShouldPaint(current_border_value)) | |
| 115 display_item_type |= DisplayItem::kTableCollapsedBorderBottom; | |
| 116 if (left_border_value.ShouldPaint(current_border_value)) | |
| 117 display_item_type |= DisplayItem::kTableCollapsedBorderLeft; | |
| 118 if (right_border_value.ShouldPaint(current_border_value)) | |
| 119 display_item_type |= DisplayItem::kTableCollapsedBorderRight; | |
| 120 if (display_item_type == DisplayItem::kTableCollapsedBorderBase) | |
| 121 return; | |
| 122 | |
| 123 int top_width = top_border_value.Width(); | |
| 124 int bottom_width = bottom_border_value.Width(); | |
| 125 int left_width = left_border_value.Width(); | |
| 126 int right_width = right_border_value.Width(); | |
| 127 | |
| 128 // Adjust our x/y/width/height so that we paint the collapsed borders at the | |
| 129 // correct location. | |
| 130 LayoutRect paint_rect = | |
| 131 PaintRectNotIncludingVisualOverflow(adjusted_paint_offset); | |
| 132 IntRect border_rect = PixelSnappedIntRect( | |
| 133 paint_rect.X() - left_width / 2, paint_rect.Y() - top_width / 2, | |
| 134 paint_rect.Width() + left_width / 2 + (right_width + 1) / 2, | |
| 135 paint_rect.Height() + top_width / 2 + (bottom_width + 1) / 2); | |
| 136 | |
| 137 GraphicsContext& graphics_context = paint_info.context; | |
| 138 const DisplayItemClient& client = DisplayItemClientForBorders(); | |
| 139 if (DrawingRecorder::UseCachedDrawingIfPossible( | |
| 140 graphics_context, client, | |
| 141 static_cast<DisplayItem::Type>(display_item_type))) | |
| 142 return; | |
| 143 | |
| 144 DrawingRecorder recorder(graphics_context, client, | |
| 145 static_cast<DisplayItem::Type>(display_item_type), | |
| 146 border_rect); | |
| 147 Color cell_color = layout_table_cell_.ResolveColor(CSSPropertyColor); | |
| 148 | |
| 149 // We never paint diagonals at the joins. We simply let the border with the | |
| 150 // highest precedence paint on top of borders with lower precedence. | |
| 151 if (display_item_type & DisplayItem::kTableCollapsedBorderTop) { | |
| 152 ObjectPainter::DrawLineForBoxSide( | |
| 153 graphics_context, border_rect.X(), border_rect.Y(), border_rect.MaxX(), | |
| 154 border_rect.Y() + top_width, kBSTop, | |
| 155 top_border_value.GetColor().Resolve(cell_color), | |
| 156 CollapsedBorderStyle(top_border_value.Style()), 0, 0, true); | |
| 157 } | |
| 158 if (display_item_type & DisplayItem::kTableCollapsedBorderBottom) { | |
| 159 ObjectPainter::DrawLineForBoxSide( | |
| 160 graphics_context, border_rect.X(), border_rect.MaxY() - bottom_width, | |
| 161 border_rect.MaxX(), border_rect.MaxY(), kBSBottom, | |
| 162 bottom_border_value.GetColor().Resolve(cell_color), | |
| 163 CollapsedBorderStyle(bottom_border_value.Style()), 0, 0, true); | |
| 164 } | |
| 165 if (display_item_type & DisplayItem::kTableCollapsedBorderLeft) { | |
| 166 ObjectPainter::DrawLineForBoxSide( | |
| 167 graphics_context, border_rect.X(), border_rect.Y(), | |
| 168 border_rect.X() + left_width, border_rect.MaxY(), kBSLeft, | |
| 169 left_border_value.GetColor().Resolve(cell_color), | |
| 170 CollapsedBorderStyle(left_border_value.Style()), 0, 0, true); | |
| 171 } | |
| 172 if (display_item_type & DisplayItem::kTableCollapsedBorderRight) { | |
| 173 ObjectPainter::DrawLineForBoxSide( | |
| 174 graphics_context, border_rect.MaxX() - right_width, border_rect.Y(), | |
| 175 border_rect.MaxX(), border_rect.MaxY(), kBSRight, | |
| 176 right_border_value.GetColor().Resolve(cell_color), | |
| 177 CollapsedBorderStyle(right_border_value.Style()), 0, 0, true); | |
| 178 } | |
| 179 } | |
| 180 | |
| 181 void TableCellPainter::PaintContainerBackgroundBehindCell( | 32 void TableCellPainter::PaintContainerBackgroundBehindCell( |
| 182 const PaintInfo& paint_info, | 33 const PaintInfo& paint_info, |
| 183 const LayoutPoint& paint_offset, | 34 const LayoutPoint& paint_offset, |
| 184 const LayoutObject& background_object) { | 35 const LayoutObject& background_object) { |
| 185 DCHECK(background_object != layout_table_cell_); | 36 DCHECK(background_object != layout_table_cell_); |
| 186 | 37 |
| 187 if (layout_table_cell_.Style()->Visibility() != EVisibility::kVisible) | 38 if (layout_table_cell_.Style()->Visibility() != EVisibility::kVisible) |
| 188 return; | 39 return; |
| 189 | 40 |
| 190 LayoutTable* table = layout_table_cell_.Table(); | 41 LayoutTable* table = layout_table_cell_.Table(); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 BoxPainter(layout_table_cell_).PaintMaskImages(paint_info, paint_rect); | 140 BoxPainter(layout_table_cell_).PaintMaskImages(paint_info, paint_rect); |
| 290 } | 141 } |
| 291 | 142 |
| 292 LayoutRect TableCellPainter::PaintRectNotIncludingVisualOverflow( | 143 LayoutRect TableCellPainter::PaintRectNotIncludingVisualOverflow( |
| 293 const LayoutPoint& paint_offset) { | 144 const LayoutPoint& paint_offset) { |
| 294 return LayoutRect(paint_offset, | 145 return LayoutRect(paint_offset, |
| 295 LayoutSize(layout_table_cell_.PixelSnappedSize())); | 146 LayoutSize(layout_table_cell_.PixelSnappedSize())); |
| 296 } | 147 } |
| 297 | 148 |
| 298 } // namespace blink | 149 } // namespace blink |
| OLD | NEW |