mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Compute border spacing info beforehand
This commit is contained in:
parent
7cd3daa76f
commit
108ecc1f4d
2 changed files with 59 additions and 19 deletions
|
@ -781,17 +781,54 @@ impl TableLikeFlow for BlockFlow {
|
||||||
debug_assert!(self.fragment.style.get_inheritedtable().border_collapse ==
|
debug_assert!(self.fragment.style.get_inheritedtable().border_collapse ==
|
||||||
border_collapse::T::Separate || block_direction_spacing == Au(0));
|
border_collapse::T::Separate || block_direction_spacing == Au(0));
|
||||||
|
|
||||||
|
fn border_spacing_for_row(fragment: &Fragment, row: &TableRowFlow,
|
||||||
if self.base.restyle_damage.contains(ServoRestyleDamage::REFLOW) {
|
block_direction_spacing: Au) -> Au {
|
||||||
let mut sizes = vec![];
|
match fragment.style.get_inheritedtable().border_collapse {
|
||||||
let mut incoming_rowspan_data = vec![];
|
border_collapse::T::Separate => block_direction_spacing,
|
||||||
|
border_collapse::T::Collapse => {
|
||||||
for kid in self.base.child_iter_mut() {
|
row.collapsed_border_spacing.block_start
|
||||||
if kid.is_table_row() {
|
|
||||||
sizes.push(kid.as_mut_table_row()
|
|
||||||
.compute_block_size_table_row_base(layout_context, &mut incoming_rowspan_data))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.base.restyle_damage.contains(ServoRestyleDamage::REFLOW) {
|
||||||
|
// (size, cumulative_border_spacing)
|
||||||
|
let mut sizes = vec![(Au(0), Au(0))];
|
||||||
|
// The amount of border spacing up to and including this row,
|
||||||
|
// but not including the spacing beneath it
|
||||||
|
let mut cumulative_border = Au(0);
|
||||||
|
let mut incoming_rowspan_data = vec![];
|
||||||
|
|
||||||
|
// First pass: Compute block-direction border spacings
|
||||||
|
// XXXManishearth this can be done in tandem with the second pass,
|
||||||
|
// provided we never hit any rowspan cases
|
||||||
|
for kid in self.base.child_iter_mut()
|
||||||
|
.filter(|k| k.is_table_row())
|
||||||
|
.skip(1) {
|
||||||
|
cumulative_border +=
|
||||||
|
border_spacing_for_row(&self.fragment, kid.as_table_row(),
|
||||||
|
block_direction_spacing);
|
||||||
|
// we haven't calculated sizes yet
|
||||||
|
sizes.push((Au(0), cumulative_border));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second pass: Compute row block sizes
|
||||||
|
// [expensive: iterates over cells]
|
||||||
|
let mut i = 0;
|
||||||
|
for kid in self.base.child_iter_mut() {
|
||||||
|
if kid.is_table_row() {
|
||||||
|
let size = kid.as_mut_table_row()
|
||||||
|
.compute_block_size_table_row_base(layout_context,
|
||||||
|
&mut incoming_rowspan_data,
|
||||||
|
&sizes,
|
||||||
|
i);
|
||||||
|
sizes[i].0 = size;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Third pass: Assign block sizes to rows and cells
|
||||||
|
// [expensive: iterates over cells]
|
||||||
let mut effects_rows = 0;
|
let mut effects_rows = 0;
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
for kid in self.base.child_iter_mut() {
|
for kid in self.base.child_iter_mut() {
|
||||||
|
@ -811,11 +848,15 @@ impl TableLikeFlow for BlockFlow {
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Our current border-box position.
|
// Our current border-box position.
|
||||||
let block_start_border_padding = self.fragment.border_padding.block_start;
|
let block_start_border_padding = self.fragment.border_padding.block_start;
|
||||||
let mut current_block_offset = block_start_border_padding;
|
let mut current_block_offset = block_start_border_padding;
|
||||||
let mut has_rows = false;
|
let mut has_rows = false;
|
||||||
|
|
||||||
|
// Fourth pass: Compute block positions
|
||||||
|
// XXXManishearth this can be merged with the third pass
|
||||||
|
|
||||||
// At this point, `current_block_offset` is at the content edge of our box. Now iterate
|
// At this point, `current_block_offset` is at the content edge of our box. Now iterate
|
||||||
// over children.
|
// over children.
|
||||||
for kid in self.base.child_iter_mut() {
|
for kid in self.base.child_iter_mut() {
|
||||||
|
@ -824,12 +865,8 @@ impl TableLikeFlow for BlockFlow {
|
||||||
has_rows = true;
|
has_rows = true;
|
||||||
let child_table_row = kid.as_table_row();
|
let child_table_row = kid.as_table_row();
|
||||||
current_block_offset = current_block_offset +
|
current_block_offset = current_block_offset +
|
||||||
match self.fragment.style.get_inheritedtable().border_collapse {
|
border_spacing_for_row(&self.fragment, child_table_row,
|
||||||
border_collapse::T::Separate => block_direction_spacing,
|
block_direction_spacing)
|
||||||
border_collapse::T::Collapse => {
|
|
||||||
child_table_row.collapsed_border_spacing.block_start
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this point, `current_block_offset` is at the border edge of the child.
|
// At this point, `current_block_offset` is at the border edge of the child.
|
||||||
|
@ -874,6 +911,7 @@ impl TableLikeFlow for BlockFlow {
|
||||||
self.fragment.border_box.start.b = Au(0);
|
self.fragment.border_box.start.b = Au(0);
|
||||||
self.base.position.size.block = current_block_offset;
|
self.base.position.size.block = current_block_offset;
|
||||||
|
|
||||||
|
// Fifth pass: Assign absolute position info
|
||||||
// Write in the size of the relative containing block for children. (This information
|
// Write in the size of the relative containing block for children. (This information
|
||||||
// is also needed to handle RTL.)
|
// is also needed to handle RTL.)
|
||||||
for kid in self.base.child_iter_mut() {
|
for kid in self.base.child_iter_mut() {
|
||||||
|
|
|
@ -114,7 +114,9 @@ impl TableRowFlow {
|
||||||
/// methods
|
/// methods
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn compute_block_size_table_row_base<'a>(&'a mut self, layout_context: &LayoutContext,
|
pub fn compute_block_size_table_row_base<'a>(&'a mut self, layout_context: &LayoutContext,
|
||||||
incoming_rowspan_data: &mut Vec<Au>) -> Au {
|
incoming_rowspan_data: &mut Vec<Au>,
|
||||||
|
border_info: &[(Au, Au)],
|
||||||
|
row_index: usize) -> Au {
|
||||||
// XXXManishearth skip this when the REFLOW flag is unset if it is not affected by other
|
// XXXManishearth skip this when the REFLOW flag is unset if it is not affected by other
|
||||||
// rows
|
// rows
|
||||||
fn include_sizes_from_previous_rows(col: &mut usize,
|
fn include_sizes_from_previous_rows(col: &mut usize,
|
||||||
|
@ -185,16 +187,16 @@ impl TableRowFlow {
|
||||||
block_size
|
block_size
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assign_block_size_to_self_and_children(&mut self, sizes: &[Au], index: usize, effects_rows: &mut u32) {
|
pub fn assign_block_size_to_self_and_children(&mut self, sizes: &[(Au, Au)], index: usize, effects_rows: &mut u32) {
|
||||||
// Assign the block-size of kid fragments, which is the same value as own block-size.
|
// Assign the block-size of kid fragments, which is the same value as own block-size.
|
||||||
let block_size = sizes[index];
|
let block_size = sizes[index].0;
|
||||||
for kid in self.block_flow.base.child_iter_mut() {
|
for kid in self.block_flow.base.child_iter_mut() {
|
||||||
let child_table_cell = kid.as_mut_table_cell();
|
let child_table_cell = kid.as_mut_table_cell();
|
||||||
let block_size = if child_table_cell.row_span > 1 {
|
let block_size = if child_table_cell.row_span > 1 {
|
||||||
*effects_rows = max(*effects_rows, child_table_cell.row_span);
|
*effects_rows = max(*effects_rows, child_table_cell.row_span);
|
||||||
// XXXManishearth support border spacing and such
|
// XXXManishearth support border spacing and such
|
||||||
sizes[index..].iter().take(child_table_cell.row_span as usize)
|
sizes[index..].iter().take(child_table_cell.row_span as usize)
|
||||||
.fold(Au(0), |accum, size| accum + *size)
|
.fold(Au(0), |accum, size| accum + size.0)
|
||||||
} else {
|
} else {
|
||||||
block_size
|
block_size
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue