diff --git a/components/layout/table.rs b/components/layout/table.rs index 8df43d0821d..4f70c334dc7 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -784,14 +784,14 @@ impl TableLikeFlow for BlockFlow { if self.base.restyle_damage.contains(ServoRestyleDamage::REFLOW) { let mut sizes = vec![]; + let mut incoming_rowspan_data = vec![]; for kid in self.base.child_iter_mut() { if kid.is_table_row() { sizes.push(kid.as_mut_table_row() - .compute_block_size_table_row_base(layout_context)) + .compute_block_size_table_row_base(layout_context, &mut incoming_rowspan_data)) } } - let mut effects_rows = 0; let mut i = 0; for kid in self.base.child_iter_mut() { diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index 8e9e94c6356..3f8f5b54d4d 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -114,8 +114,20 @@ impl TableRowFlow { /// inline(always) because this is only ever called by in-order or non-in-order top-level /// methods #[inline(always)] - pub fn compute_block_size_table_row_base<'a>(&'a mut self, layout_context: &LayoutContext) -> Au { + pub fn compute_block_size_table_row_base<'a>(&'a mut self, layout_context: &LayoutContext, incoming_rowspan_data: &mut Vec) -> Au { if self.block_flow.base.restyle_damage.contains(ServoRestyleDamage::REFLOW) { + fn include_sizes_from_previous_rows(col: &mut usize, + incoming_rowspan: &[u32], + incoming_rowspan_data: &mut Vec, + max_block_size: &mut Au) { + while let Some(span) = incoming_rowspan.get(*col) { + if *span <= 1 { + break; + } + *max_block_size = max(*max_block_size, incoming_rowspan_data[*col]); + *col += 1; + } + } // Per CSS 2.1 ยง 17.5.3, find max_y = max(computed `block-size`, minimum block-size of // all cells). let mut max_block_size = Au(0); @@ -124,7 +136,9 @@ impl TableRowFlow { - self.block_flow.fragment.border_padding - self.block_flow.fragment.margin; + let mut col = 0; for kid in self.block_flow.base.child_iter_mut() { + include_sizes_from_previous_rows(&mut col, &self.incoming_rowspan, incoming_rowspan_data, &mut max_block_size); kid.place_float_if_applicable(); if !kid.base().flags.is_float() { kid.assign_block_size_for_inorder_child_if_necessary(layout_context, @@ -133,19 +147,28 @@ impl TableRowFlow { } let row_span; + let column_span; + let cell_total; { let cell = kid.as_mut_table_cell(); row_span = cell.row_span as i32; - max_block_size = - max(max_block_size, cell.total_block_size() / row_span); + column_span = cell.column_span as usize; + cell_total = cell.total_block_size(); } - { - let child_node = kid.mut_base(); - child_node.position.start.b = Au(0); - max_block_size = max(max_block_size, child_node.position.size.block / row_span); + let child_node = kid.mut_base(); + child_node.position.start.b = Au(0); + let cell_block_size = max(cell_total, child_node.position.size.block); + max_block_size = max(max_block_size, cell_block_size / row_span); + + if row_span > 1 { + if incoming_rowspan_data.len() <= col { + incoming_rowspan_data.resize(col + 1, Au(0)); + } + incoming_rowspan_data[col] = cell_block_size / row_span; } + col += column_span; } - // XXXManishearth include overages from spanning cells from previous rows + include_sizes_from_previous_rows(&mut col, &self.incoming_rowspan, incoming_rowspan_data, &mut max_block_size); let mut block_size = max_block_size; // TODO: Percentage block-size