mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-26 19:32:06 -05:00
LibWeb: Snap table grid to device pixels in collapsed borders mode
Before painting the borders, build a grid snapped to device pixels and use it to construct the rectangles for the cell edges. Also adjust their starting coordinate and size such that they join correctly without overhangs. This approach works at all zoom levels.
This commit is contained in:
parent
9466512847
commit
ea6e079e07
1 changed files with 151 additions and 52 deletions
|
@ -47,9 +47,27 @@ enum class EdgeDirection {
|
|||
Vertical,
|
||||
};
|
||||
|
||||
struct DeviceBorderData {
|
||||
Color color { Color::Transparent };
|
||||
CSS::LineStyle line_style { CSS::LineStyle::None };
|
||||
DevicePixels width { 0 };
|
||||
};
|
||||
|
||||
struct DeviceBorderDataWithElementKind {
|
||||
DeviceBorderData border_data;
|
||||
Painting::PaintableBox::ConflictingElementKind element_kind { Painting::PaintableBox::ConflictingElementKind::Cell };
|
||||
};
|
||||
|
||||
struct DeviceBordersDataWithElementKind {
|
||||
DeviceBorderDataWithElementKind top;
|
||||
DeviceBorderDataWithElementKind right;
|
||||
DeviceBorderDataWithElementKind bottom;
|
||||
DeviceBorderDataWithElementKind left;
|
||||
};
|
||||
|
||||
struct BorderEdgePaintingInfo {
|
||||
DevicePixelRect rect;
|
||||
PaintableBox::BorderDataWithElementKind border_data_with_element_kind;
|
||||
DeviceBorderDataWithElementKind border_data_with_element_kind;
|
||||
EdgeDirection direction;
|
||||
Optional<size_t> row;
|
||||
Optional<size_t> column;
|
||||
|
@ -81,18 +99,29 @@ static Optional<size_t> column_index_for_element_kind(size_t index, Painting::Pa
|
|||
}
|
||||
}
|
||||
|
||||
static DevicePixels half_ceil(DevicePixels width)
|
||||
{
|
||||
return ceil(static_cast<double>(width.value()) / 2);
|
||||
}
|
||||
|
||||
static DevicePixels half_floor(DevicePixels width)
|
||||
{
|
||||
return floor(static_cast<double>(width.value()) / 2);
|
||||
}
|
||||
|
||||
static BorderEdgePaintingInfo make_right_cell_edge(
|
||||
PaintContext& context,
|
||||
CSSPixelRect const& right_cell_rect,
|
||||
CSSPixelRect const& cell_rect,
|
||||
PaintableBox::BordersDataWithElementKind const& borders_data,
|
||||
DevicePixelRect const& right_cell_rect,
|
||||
DevicePixelRect const& cell_rect,
|
||||
DeviceBordersDataWithElementKind const& borders_data,
|
||||
CellCoordinates const& coordinates)
|
||||
{
|
||||
auto connect_top_offset = half_ceil(borders_data.top.border_data.width);
|
||||
auto connect_excess_height = connect_top_offset + half_floor(borders_data.bottom.border_data.width);
|
||||
DevicePixelRect right_border_rect = {
|
||||
context.rounded_device_pixels(right_cell_rect.x() - round(borders_data.right.border_data.width / 2)),
|
||||
context.rounded_device_pixels(cell_rect.y() - round(borders_data.top.border_data.width / 2)),
|
||||
context.rounded_device_pixels(borders_data.right.border_data.width),
|
||||
context.rounded_device_pixels(max(cell_rect.height(), right_cell_rect.height()) + round(borders_data.top.border_data.width / 2) + round(borders_data.bottom.border_data.width / 2)),
|
||||
right_cell_rect.x() - half_ceil(borders_data.right.border_data.width),
|
||||
cell_rect.y() - connect_top_offset,
|
||||
borders_data.right.border_data.width,
|
||||
max(cell_rect.height(), right_cell_rect.height()) + connect_excess_height,
|
||||
};
|
||||
return BorderEdgePaintingInfo {
|
||||
.rect = right_border_rect,
|
||||
|
@ -104,17 +133,18 @@ static BorderEdgePaintingInfo make_right_cell_edge(
|
|||
}
|
||||
|
||||
static BorderEdgePaintingInfo make_down_cell_edge(
|
||||
PaintContext& context,
|
||||
CSSPixelRect const& down_cell_rect,
|
||||
CSSPixelRect const& cell_rect,
|
||||
PaintableBox::BordersDataWithElementKind const& borders_data,
|
||||
DevicePixelRect const& down_cell_rect,
|
||||
DevicePixelRect const& cell_rect,
|
||||
DeviceBordersDataWithElementKind const& borders_data,
|
||||
CellCoordinates const& coordinates)
|
||||
{
|
||||
auto connect_left_offset = half_ceil(borders_data.left.border_data.width);
|
||||
auto connect_excess_width = connect_left_offset + half_floor(borders_data.right.border_data.width);
|
||||
DevicePixelRect down_border_rect = {
|
||||
context.rounded_device_pixels(cell_rect.x() - round(borders_data.left.border_data.width / 2)),
|
||||
context.rounded_device_pixels(down_cell_rect.y() - round(borders_data.bottom.border_data.width / 2)),
|
||||
context.rounded_device_pixels(max(cell_rect.width(), down_cell_rect.width()) + round(borders_data.left.border_data.width / 2) + round(borders_data.right.border_data.width / 2)),
|
||||
context.rounded_device_pixels(borders_data.bottom.border_data.width),
|
||||
cell_rect.x() - connect_left_offset,
|
||||
down_cell_rect.y() - half_ceil(borders_data.bottom.border_data.width),
|
||||
max(cell_rect.width(), down_cell_rect.width()) + connect_excess_width,
|
||||
borders_data.bottom.border_data.width,
|
||||
};
|
||||
return BorderEdgePaintingInfo {
|
||||
.rect = down_border_rect,
|
||||
|
@ -125,13 +155,15 @@ static BorderEdgePaintingInfo make_down_cell_edge(
|
|||
};
|
||||
}
|
||||
|
||||
static BorderEdgePaintingInfo make_first_row_top_cell_edge(PaintContext& context, CSSPixelRect const& cell_rect, PaintableBox::BordersDataWithElementKind const& borders_data, CellCoordinates const& coordinates)
|
||||
static BorderEdgePaintingInfo make_first_row_top_cell_edge(DevicePixelRect const& cell_rect, DeviceBordersDataWithElementKind const& borders_data, CellCoordinates const& coordinates)
|
||||
{
|
||||
auto connect_left_offset = half_ceil(borders_data.left.border_data.width.value());
|
||||
auto connect_excess_width = connect_left_offset + half_floor(borders_data.right.border_data.width.value());
|
||||
DevicePixelRect top_border_rect = {
|
||||
context.rounded_device_pixels(cell_rect.x() - round(borders_data.left.border_data.width / 2)),
|
||||
context.rounded_device_pixels(cell_rect.y() - round(borders_data.top.border_data.width / 2)),
|
||||
context.rounded_device_pixels(cell_rect.width()),
|
||||
context.rounded_device_pixels(borders_data.top.border_data.width),
|
||||
cell_rect.x() - connect_left_offset,
|
||||
cell_rect.y() - half_ceil(borders_data.top.border_data.width.value()),
|
||||
cell_rect.width() + connect_excess_width,
|
||||
borders_data.top.border_data.width,
|
||||
};
|
||||
return BorderEdgePaintingInfo {
|
||||
.rect = top_border_rect,
|
||||
|
@ -142,13 +174,15 @@ static BorderEdgePaintingInfo make_first_row_top_cell_edge(PaintContext& context
|
|||
};
|
||||
}
|
||||
|
||||
static BorderEdgePaintingInfo make_last_row_bottom_cell_edge(PaintContext& context, CSSPixelRect const& cell_rect, PaintableBox::BordersDataWithElementKind const& borders_data, CellCoordinates const& coordinates)
|
||||
static BorderEdgePaintingInfo make_last_row_bottom_cell_edge(DevicePixelRect const& cell_rect, DeviceBordersDataWithElementKind const& borders_data, CellCoordinates const& coordinates)
|
||||
{
|
||||
auto connect_left_offset = half_ceil(borders_data.left.border_data.width);
|
||||
auto connect_excess_width = connect_left_offset + half_floor(borders_data.right.border_data.width);
|
||||
DevicePixelRect bottom_border_rect = {
|
||||
context.rounded_device_pixels(cell_rect.x() - round(borders_data.left.border_data.width / 2)),
|
||||
context.rounded_device_pixels(cell_rect.y() + cell_rect.height() - round(borders_data.bottom.border_data.width / 2)),
|
||||
context.rounded_device_pixels(cell_rect.width() + round(borders_data.left.border_data.width / 2) + round(borders_data.right.border_data.width / 2)),
|
||||
context.rounded_device_pixels(borders_data.bottom.border_data.width),
|
||||
cell_rect.x() - connect_left_offset,
|
||||
cell_rect.y() + cell_rect.height() - half_ceil(borders_data.bottom.border_data.width),
|
||||
cell_rect.width() + connect_excess_width,
|
||||
borders_data.bottom.border_data.width,
|
||||
};
|
||||
return BorderEdgePaintingInfo {
|
||||
.rect = bottom_border_rect,
|
||||
|
@ -159,13 +193,15 @@ static BorderEdgePaintingInfo make_last_row_bottom_cell_edge(PaintContext& conte
|
|||
};
|
||||
}
|
||||
|
||||
static BorderEdgePaintingInfo make_first_column_left_cell_edge(PaintContext& context, CSSPixelRect const& cell_rect, PaintableBox::BordersDataWithElementKind const& borders_data, CellCoordinates const& coordinates)
|
||||
static BorderEdgePaintingInfo make_first_column_left_cell_edge(DevicePixelRect const& cell_rect, DeviceBordersDataWithElementKind const& borders_data, CellCoordinates const& coordinates)
|
||||
{
|
||||
auto connect_top_offset = half_ceil(borders_data.top.border_data.width);
|
||||
auto connect_excess_height = connect_top_offset + half_floor(borders_data.bottom.border_data.width);
|
||||
DevicePixelRect left_border_rect = {
|
||||
context.rounded_device_pixels(cell_rect.x() - round(borders_data.left.border_data.width / 2)),
|
||||
context.rounded_device_pixels(cell_rect.y() - round(borders_data.top.border_data.width / 2)),
|
||||
context.rounded_device_pixels(borders_data.left.border_data.width),
|
||||
context.rounded_device_pixels(cell_rect.height() + round(borders_data.top.border_data.width / 2)),
|
||||
cell_rect.x() - half_ceil(borders_data.left.border_data.width),
|
||||
cell_rect.y() - connect_top_offset,
|
||||
borders_data.left.border_data.width,
|
||||
cell_rect.height() + connect_excess_height,
|
||||
};
|
||||
return BorderEdgePaintingInfo {
|
||||
.rect = left_border_rect,
|
||||
|
@ -176,13 +212,15 @@ static BorderEdgePaintingInfo make_first_column_left_cell_edge(PaintContext& con
|
|||
};
|
||||
}
|
||||
|
||||
static BorderEdgePaintingInfo make_last_column_right_cell_edge(PaintContext& context, CSSPixelRect const& cell_rect, PaintableBox::BordersDataWithElementKind const& borders_data, CellCoordinates const& coordinates)
|
||||
static BorderEdgePaintingInfo make_last_column_right_cell_edge(DevicePixelRect const& cell_rect, DeviceBordersDataWithElementKind const& borders_data, CellCoordinates const& coordinates)
|
||||
{
|
||||
auto connect_top_offset = half_ceil(borders_data.top.border_data.width);
|
||||
auto connect_excess_height = connect_top_offset + half_floor(borders_data.bottom.border_data.width);
|
||||
DevicePixelRect right_border_rect = {
|
||||
context.rounded_device_pixels(cell_rect.x() + cell_rect.width() - round(borders_data.right.border_data.width / 2)),
|
||||
context.rounded_device_pixels(cell_rect.y() - round(borders_data.top.border_data.width / 2)),
|
||||
context.rounded_device_pixels(borders_data.right.border_data.width),
|
||||
context.rounded_device_pixels(cell_rect.height() + round(borders_data.top.border_data.width / 2) + round(borders_data.bottom.border_data.width / 2)),
|
||||
cell_rect.x() + cell_rect.width() - half_ceil(borders_data.right.border_data.width),
|
||||
cell_rect.y() - connect_top_offset,
|
||||
borders_data.right.border_data.width,
|
||||
cell_rect.height() + connect_excess_height,
|
||||
};
|
||||
return BorderEdgePaintingInfo {
|
||||
.rect = right_border_rect,
|
||||
|
@ -193,6 +231,15 @@ static BorderEdgePaintingInfo make_last_column_right_cell_edge(PaintContext& con
|
|||
};
|
||||
}
|
||||
|
||||
static CSS::BorderData css_border_data_from_device_border_data(DeviceBorderData const& device_border_data)
|
||||
{
|
||||
return CSS::BorderData {
|
||||
.color = device_border_data.color,
|
||||
.line_style = device_border_data.line_style,
|
||||
.width = device_border_data.width.value(),
|
||||
};
|
||||
}
|
||||
|
||||
static void paint_collected_edges(PaintContext& context, Vector<BorderEdgePaintingInfo>& border_edge_painting_info_list)
|
||||
{
|
||||
// This sorting step isn't part of the specification, but it matches the behavior of other browsers at border intersections, which aren't
|
||||
|
@ -219,12 +266,14 @@ static void paint_collected_edges(PaintContext& context, Vector<BorderEdgePainti
|
|||
}
|
||||
return a.row.has_value() ? b.row.value() < a.row.value() : false;
|
||||
}
|
||||
return Layout::TableFormattingContext::border_is_less_specific(a_border_data, b_border_data);
|
||||
return Layout::TableFormattingContext::border_is_less_specific(
|
||||
css_border_data_from_device_border_data(a_border_data),
|
||||
css_border_data_from_device_border_data(b_border_data));
|
||||
});
|
||||
|
||||
for (auto const& border_edge_painting_info : border_edge_painting_info_list) {
|
||||
auto const& border_data_with_element_kind = border_edge_painting_info.border_data_with_element_kind;
|
||||
CSSPixels width = border_data_with_element_kind.border_data.width;
|
||||
auto width = border_data_with_element_kind.border_data.width;
|
||||
if (width <= 0)
|
||||
continue;
|
||||
auto color = border_data_with_element_kind.border_data.color;
|
||||
|
@ -236,9 +285,9 @@ static void paint_collected_edges(PaintContext& context, Vector<BorderEdgePainti
|
|||
|
||||
if (border_style == CSS::LineStyle::Dotted) {
|
||||
Gfx::AntiAliasingPainter aa_painter { context.painter() };
|
||||
aa_painter.draw_line(p1.to_type<int>(), p2.to_type<int>(), color, width.to_double(), Gfx::Painter::LineStyle::Dotted);
|
||||
aa_painter.draw_line(p1.to_type<int>(), p2.to_type<int>(), color, width.value(), Gfx::Painter::LineStyle::Dotted);
|
||||
} else if (border_style == CSS::LineStyle::Dashed) {
|
||||
context.painter().draw_line(p1.to_type<int>(), p2.to_type<int>(), color, width.to_double(), Gfx::Painter::LineStyle::Dashed);
|
||||
context.painter().draw_line(p1.to_type<int>(), p2.to_type<int>(), color, width.value(), Gfx::Painter::LineStyle::Dashed);
|
||||
} else {
|
||||
// FIXME: Support the remaining line styles instead of rendering them as solid.
|
||||
context.painter().fill_rect(Gfx::IntRect(border_edge_painting_info.rect.location(), border_edge_painting_info.rect.size()), color);
|
||||
|
@ -246,6 +295,50 @@ static void paint_collected_edges(PaintContext& context, Vector<BorderEdgePainti
|
|||
}
|
||||
}
|
||||
|
||||
static HashMap<CellCoordinates, DevicePixelRect> snap_cells_to_device_coordinates(HashMap<CellCoordinates, PaintableBox const*> const& cell_coordinates_to_box, size_t row_count, size_t column_count, PaintContext const& context)
|
||||
{
|
||||
Vector<DevicePixels> y_line_coordinates;
|
||||
y_line_coordinates.resize(row_count + 1);
|
||||
Vector<DevicePixels> x_line_coordinates;
|
||||
x_line_coordinates.resize(column_count + 1);
|
||||
for (auto const& kv : cell_coordinates_to_box) {
|
||||
auto const& cell_box = kv.value;
|
||||
auto start_row_index = cell_box->table_cell_coordinates()->row_index;
|
||||
auto end_row_index = start_row_index + cell_box->table_cell_coordinates()->row_span;
|
||||
auto cell_rect = cell_box->absolute_border_box_rect();
|
||||
y_line_coordinates[start_row_index] = max(context.rounded_device_pixels(cell_rect.y()), y_line_coordinates[start_row_index]);
|
||||
y_line_coordinates[end_row_index] = max(context.rounded_device_pixels(cell_rect.y() + cell_rect.height()), y_line_coordinates[end_row_index]);
|
||||
auto start_column_index = cell_box->table_cell_coordinates()->column_index;
|
||||
auto end_column_index = start_column_index + cell_box->table_cell_coordinates()->column_span;
|
||||
x_line_coordinates[start_column_index] = max(context.rounded_device_pixels(cell_rect.x()), x_line_coordinates[start_column_index]);
|
||||
x_line_coordinates[end_column_index] = max(context.rounded_device_pixels(cell_rect.x() + cell_rect.width()), x_line_coordinates[end_column_index]);
|
||||
}
|
||||
HashMap<CellCoordinates, DevicePixelRect> cell_coordinates_to_device_rect;
|
||||
for (auto const& kv : cell_coordinates_to_box) {
|
||||
auto const& cell_box = kv.value;
|
||||
auto start_row_index = cell_box->table_cell_coordinates()->row_index;
|
||||
auto end_row_index = start_row_index + cell_box->table_cell_coordinates()->row_span;
|
||||
auto height = y_line_coordinates[end_row_index] - y_line_coordinates[start_row_index];
|
||||
auto start_column_index = cell_box->table_cell_coordinates()->column_index;
|
||||
auto end_column_index = start_column_index + cell_box->table_cell_coordinates()->column_span;
|
||||
auto width = x_line_coordinates[end_column_index] - x_line_coordinates[start_column_index];
|
||||
cell_coordinates_to_device_rect.set(kv.key, DevicePixelRect { x_line_coordinates[start_column_index], y_line_coordinates[start_row_index], width, height });
|
||||
}
|
||||
return cell_coordinates_to_device_rect;
|
||||
}
|
||||
|
||||
static DeviceBorderDataWithElementKind device_border_data_from_css_border_data(Painting::PaintableBox::BorderDataWithElementKind const& border_data_with_element_kind, PaintContext const& context)
|
||||
{
|
||||
return DeviceBorderDataWithElementKind {
|
||||
.border_data = {
|
||||
.color = border_data_with_element_kind.border_data.color,
|
||||
.line_style = border_data_with_element_kind.border_data.line_style,
|
||||
.width = context.rounded_device_pixels(border_data_with_element_kind.border_data.width),
|
||||
},
|
||||
.element_kind = border_data_with_element_kind.element_kind,
|
||||
};
|
||||
}
|
||||
|
||||
void paint_table_collapsed_borders(PaintContext& context, Layout::Node const& box)
|
||||
{
|
||||
// Partial implementation of painting according to the collapsing border model:
|
||||
|
@ -264,39 +357,46 @@ void paint_table_collapsed_borders(PaintContext& context, Layout::Node const& bo
|
|||
row_count = max(row_count, cell_box->table_cell_coordinates()->row_index + cell_box->table_cell_coordinates()->row_span);
|
||||
column_count = max(column_count, cell_box->table_cell_coordinates()->column_index + cell_box->table_cell_coordinates()->column_span);
|
||||
}
|
||||
auto cell_coordinates_to_device_rect = snap_cells_to_device_coordinates(cell_coordinates_to_box, row_count, column_count, context);
|
||||
for (auto const cell_box : cell_boxes) {
|
||||
auto borders_data = cell_box->override_borders_data().has_value() ? cell_box->override_borders_data().value() : PaintableBox::BordersDataWithElementKind {
|
||||
auto css_borders_data = cell_box->override_borders_data().has_value() ? cell_box->override_borders_data().value() : PaintableBox::BordersDataWithElementKind {
|
||||
.top = { .border_data = cell_box->box_model().border.top == 0 ? CSS::BorderData() : cell_box->computed_values().border_top(), .element_kind = PaintableBox::ConflictingElementKind::Cell },
|
||||
.right = { .border_data = cell_box->box_model().border.right == 0 ? CSS::BorderData() : cell_box->computed_values().border_right(), .element_kind = PaintableBox::ConflictingElementKind::Cell },
|
||||
.bottom = { .border_data = cell_box->box_model().border.bottom == 0 ? CSS::BorderData() : cell_box->computed_values().border_bottom(), .element_kind = PaintableBox::ConflictingElementKind::Cell },
|
||||
.left = { .border_data = cell_box->box_model().border.left == 0 ? CSS::BorderData() : cell_box->computed_values().border_left(), .element_kind = PaintableBox::ConflictingElementKind::Cell },
|
||||
};
|
||||
auto cell_rect = cell_box->absolute_border_box_rect();
|
||||
DeviceBordersDataWithElementKind borders_data = {
|
||||
.top = device_border_data_from_css_border_data(css_borders_data.top, context),
|
||||
.right = device_border_data_from_css_border_data(css_borders_data.right, context),
|
||||
.bottom = device_border_data_from_css_border_data(css_borders_data.bottom, context),
|
||||
.left = device_border_data_from_css_border_data(css_borders_data.left, context),
|
||||
};
|
||||
auto cell_rect = cell_coordinates_to_device_rect.get({ cell_box->table_cell_coordinates()->row_index, cell_box->table_cell_coordinates()->column_index }).value();
|
||||
CellCoordinates right_cell_coordinates {
|
||||
.row_index = cell_box->table_cell_coordinates()->row_index,
|
||||
.column_index = cell_box->table_cell_coordinates()->column_index + cell_box->table_cell_coordinates()->column_span
|
||||
};
|
||||
auto maybe_right_cell = cell_coordinates_to_box.get(right_cell_coordinates);
|
||||
auto maybe_right_cell = cell_coordinates_to_device_rect.get(right_cell_coordinates);
|
||||
CellCoordinates down_cell_coordinates {
|
||||
.row_index = cell_box->table_cell_coordinates()->row_index + cell_box->table_cell_coordinates()->row_span,
|
||||
.column_index = cell_box->table_cell_coordinates()->column_index
|
||||
};
|
||||
auto maybe_down_cell = cell_coordinates_to_box.get(down_cell_coordinates);
|
||||
auto maybe_down_cell = cell_coordinates_to_device_rect.get(down_cell_coordinates);
|
||||
if (maybe_right_cell.has_value())
|
||||
border_edge_painting_info_list.append(make_right_cell_edge(context, maybe_right_cell.value()->absolute_border_box_rect(), cell_rect, borders_data, right_cell_coordinates));
|
||||
border_edge_painting_info_list.append(make_right_cell_edge(maybe_right_cell.value(), cell_rect, borders_data, right_cell_coordinates));
|
||||
if (maybe_down_cell.has_value())
|
||||
border_edge_painting_info_list.append(make_down_cell_edge(context, maybe_down_cell.value()->absolute_border_box_rect(), cell_rect, borders_data, down_cell_coordinates));
|
||||
border_edge_painting_info_list.append(make_down_cell_edge(maybe_down_cell.value(), cell_rect, borders_data, down_cell_coordinates));
|
||||
if (cell_box->table_cell_coordinates()->row_index == 0)
|
||||
border_edge_painting_info_list.append(make_first_row_top_cell_edge(context, cell_rect, borders_data,
|
||||
border_edge_painting_info_list.append(make_first_row_top_cell_edge(cell_rect, borders_data,
|
||||
{ .row_index = 0, .column_index = cell_box->table_cell_coordinates()->column_index }));
|
||||
if (cell_box->table_cell_coordinates()->row_index + cell_box->table_cell_coordinates()->row_span == row_count)
|
||||
border_edge_painting_info_list.append(make_last_row_bottom_cell_edge(context, cell_rect, borders_data,
|
||||
border_edge_painting_info_list.append(make_last_row_bottom_cell_edge(cell_rect, borders_data,
|
||||
{ .row_index = row_count - 1, .column_index = cell_box->table_cell_coordinates()->column_index }));
|
||||
if (cell_box->table_cell_coordinates()->column_index == 0)
|
||||
border_edge_painting_info_list.append(make_first_column_left_cell_edge(context, cell_rect, borders_data,
|
||||
border_edge_painting_info_list.append(make_first_column_left_cell_edge(cell_rect, borders_data,
|
||||
{ .row_index = cell_box->table_cell_coordinates()->row_index, .column_index = 0 }));
|
||||
if (cell_box->table_cell_coordinates()->column_index + cell_box->table_cell_coordinates()->column_span == column_count)
|
||||
border_edge_painting_info_list.append(make_last_column_right_cell_edge(context, cell_rect, borders_data,
|
||||
border_edge_painting_info_list.append(make_last_column_right_cell_edge(cell_rect, borders_data,
|
||||
{ .row_index = cell_box->table_cell_coordinates()->row_index, .column_index = column_count - 1 }));
|
||||
}
|
||||
|
||||
|
@ -321,5 +421,4 @@ void paint_table_collapsed_borders(PaintContext& context, Layout::Node const& bo
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue