Handle row borders in border collapsing logic.

Fixes #11527.
This commit is contained in:
Gabriel Poesia 2016-07-13 14:14:26 -03:00
parent 5b46a59194
commit a3af2303d6
17 changed files with 147 additions and 58 deletions

View file

@ -311,12 +311,13 @@ impl Flow for TableFlow {
&mut self.collapsed_block_direction_border_widths_for_table);
previous_collapsed_block_end_borders =
PreviousBlockCollapsedBorders::FromPreviousRow(
row.final_collapsed_borders.block_end.clone())
row.final_collapsed_borders.block_end.clone());
}
first_row = false
}
};
}
computation.surrounding_size = computation.surrounding_size +
self.total_horizontal_spacing();
@ -425,7 +426,7 @@ impl Flow for TableFlow {
collapsed_inline_direction_border_widths_for_table,
&mut collapsed_block_direction_border_widths_for_table);
}
})
});
}
fn assign_block_size<'a>(&mut self, _: &'a LayoutContext<'a>) {
@ -589,7 +590,7 @@ impl ColumnIntrinsicInlineSize {
///
/// TODO(pcwalton): There will probably be some `border-collapse`-related info in here too
/// eventually.
#[derive(RustcEncodable, Clone, Copy)]
#[derive(RustcEncodable, Clone, Copy, Debug)]
pub struct ColumnComputedInlineSize {
/// The computed size of this inline column.
pub size: Au,
@ -629,27 +630,21 @@ fn perform_border_collapse_for_row(child_table_row: &mut TableRowFlow,
next_block_borders: NextBlockCollapsedBorders,
inline_spacing: &mut Vec<Au>,
block_spacing: &mut Vec<Au>) {
let number_of_borders_inline_direction = child_table_row.preliminary_collapsed_borders.inline.len();
// Compute interior inline borders.
for (i, this_inline_border) in child_table_row.preliminary_collapsed_borders
.inline
.iter()
.iter_mut()
.enumerate() {
child_table_row.final_collapsed_borders.inline.push_or_set(i, *this_inline_border);
if i == 0 {
child_table_row.final_collapsed_borders.inline[i].combine(&table_inline_borders.start);
} else if i + 1 == number_of_borders_inline_direction {
child_table_row.final_collapsed_borders.inline[i].combine(&table_inline_borders.end);
}
let inline_spacing = inline_spacing.get_mut_or_push(i, Au(0));
*inline_spacing = cmp::max(*inline_spacing, this_inline_border.width)
}
// Collapse edge interior borders with the table.
if let Some(ref mut first_inline_borders) = child_table_row.final_collapsed_borders
.inline
.get_mut(0) {
first_inline_borders.combine(&table_inline_borders.start)
}
if let Some(ref mut last_inline_borders) = child_table_row.final_collapsed_borders
.inline
.last_mut() {
last_inline_borders.combine(&table_inline_borders.end)
*inline_spacing = cmp::max(*inline_spacing, child_table_row.final_collapsed_borders.inline[i].width)
}
// Compute block-start borders.
@ -777,6 +772,7 @@ impl TableLikeFlow for BlockFlow {
}
/// Inline collapsed borders for the table itself.
#[derive(Debug)]
struct TableInlineCollapsedBorders {
/// The table border at the start of the inline direction.
start: CollapsedBorder,

View file

@ -245,10 +245,13 @@ impl Flow for TableRowFlow {
.style()
.get_inheritedtable()
.border_collapse == border_collapse::T::collapse;
// FIXME(pcwalton): Shouldn't use `CollapsedBorder::new()` here.
self.preliminary_collapsed_borders.reset(CollapsedBorder::new());
let row_style = &*self.block_flow.fragment.style;
self.preliminary_collapsed_borders.reset(
CollapsedBorder::inline_start(&row_style,
CollapsedBorderProvenance::FromTableRow));
{
let children_count = self.block_flow.base.children.len();
let mut iterator = self.block_flow.base.child_iter_mut().enumerate().peekable();
while let Some((i, kid)) = iterator.next() {
assert!(kid.is_table_cell());
@ -268,6 +271,8 @@ impl Flow for TableRowFlow {
// Perform border collapse if necessary.
if collapsing_borders {
perform_inline_direction_border_collapse_for_row(
row_style,
children_count,
i,
child_table_cell,
&mut iterator,
@ -829,10 +834,20 @@ pub struct BorderCollapseInfoForChildTableCell<'a> {
/// table row. This is done eagerly here so that at least the inline inside border collapse
/// computations can be parallelized across all the rows of the table.
fn perform_inline_direction_border_collapse_for_row(
row_style: &ServoComputedValues,
children_count: usize,
child_index: usize,
child_table_cell: &mut TableCellFlow,
iterator: &mut Peekable<Enumerate<MutFlowListIterator>>,
preliminary_collapsed_borders: &mut CollapsedBordersForRow) {
// In the first cell, combine its border with the one coming from the row.
if child_index == 0 {
let first_inline_border = &mut preliminary_collapsed_borders.inline[0];
first_inline_border.combine(
&CollapsedBorder::inline_start(&*child_table_cell.block_flow.fragment.style,
CollapsedBorderProvenance::FromPreviousTableCell));
}
let inline_collapsed_border = preliminary_collapsed_borders.inline.push_or_set(
child_index + 1,
CollapsedBorder::inline_end(&*child_table_cell.block_flow.fragment.style,
@ -845,12 +860,25 @@ fn perform_inline_direction_border_collapse_for_row(
CollapsedBorderProvenance::FromNextTableCell))
};
let block_start_border =
// In the last cell, also take into account the border that may
// come from the row.
if child_index + 1 == children_count {
inline_collapsed_border.combine(
&CollapsedBorder::inline_end(&row_style,
CollapsedBorderProvenance::FromTableRow));
}
let mut block_start_border =
CollapsedBorder::block_start(&*child_table_cell.block_flow.fragment.style,
CollapsedBorderProvenance::FromNextTableCell);
block_start_border.combine(
&CollapsedBorder::block_start(row_style, CollapsedBorderProvenance::FromTableRow));
preliminary_collapsed_borders.block_start.push_or_set(child_index, block_start_border);
let block_end_border =
let mut block_end_border =
CollapsedBorder::block_end(&*child_table_cell.block_flow.fragment.style,
CollapsedBorderProvenance::FromPreviousTableCell);
CollapsedBorderProvenance::FromPreviousTableCell);
block_end_border.combine(
&CollapsedBorder::block_end(row_style, CollapsedBorderProvenance::FromTableRow));
preliminary_collapsed_borders.block_end.push_or_set(child_index, block_end_border);
}