Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Side by Side Diff: third_party/WebKit/Source/core/paint/TableCellPainter.cpp

Issue 2791433003: Fix Border collapsing with colpsan / rowspan cells
Patch Set: bug 2902 Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698