mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Handle overlarge rowspans by keeping track of largest leftover incoming sizes
This commit is contained in:
parent
746acf7e2b
commit
0261762fa4
2 changed files with 35 additions and 12 deletions
|
@ -815,17 +815,27 @@ impl TableLikeFlow for BlockFlow {
|
||||||
// Second pass: Compute row block sizes
|
// Second pass: Compute row block sizes
|
||||||
// [expensive: iterates over cells]
|
// [expensive: iterates over cells]
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
|
let mut overflow = Au(0);
|
||||||
for kid in self.base.child_iter_mut() {
|
for kid in self.base.child_iter_mut() {
|
||||||
if kid.is_table_row() {
|
if kid.is_table_row() {
|
||||||
let size = kid.as_mut_table_row()
|
let (size, oflo) = 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,
|
&mut incoming_rowspan_data,
|
||||||
&sizes,
|
&sizes,
|
||||||
i);
|
i);
|
||||||
sizes[i].0 = size;
|
sizes[i].0 = size;
|
||||||
|
overflow = oflo;
|
||||||
i += 1;
|
i += 1;
|
||||||
|
// new rowgroups stop rowspans
|
||||||
|
} else if kid.is_table_rowgroup() {
|
||||||
|
if i > 0 {
|
||||||
|
sizes[i - 1].0 = cmp::max(sizes[i - 1].0, overflow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if i > 0 {
|
||||||
|
sizes[i - 1].0 = cmp::max(sizes[i - 1].0, overflow);
|
||||||
|
}
|
||||||
|
|
||||||
// Third pass: Assign block sizes to rows and cells
|
// Third pass: Assign block sizes to rows and cells
|
||||||
// [expensive: iterates over cells]
|
// [expensive: iterates over cells]
|
||||||
|
|
|
@ -106,34 +106,39 @@ impl TableRowFlow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Assign block-size for table-row flow.
|
/// Compute block-size for table-row flow.
|
||||||
///
|
///
|
||||||
/// TODO(pcwalton): This doesn't handle floats and positioned elements right.
|
/// TODO(pcwalton): This doesn't handle floats and positioned elements right.
|
||||||
///
|
///
|
||||||
/// inline(always) because this is only ever called by in-order or non-in-order top-level
|
/// Returns the block size, as well as the size this should be if this is the last row
|
||||||
/// methods
|
|
||||||
#[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>,
|
incoming_rowspan_data: &mut Vec<Au>,
|
||||||
border_info: &[(Au, Au)], // (_, cumulative_border_size)
|
border_info: &[(Au, Au)], // (_, cumulative_border_size)
|
||||||
row_index: usize) -> Au {
|
row_index: usize) -> (Au, 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,
|
||||||
incoming_rowspan: &[u32],
|
incoming_rowspan: &[u32],
|
||||||
incoming_rowspan_data: &mut Vec<Au>,
|
incoming_rowspan_data: &mut Vec<Au>,
|
||||||
max_block_size: &mut Au) {
|
max_block_size: &mut Au,
|
||||||
|
largest_leftover_incoming_size: &mut Au) {
|
||||||
while let Some(span) = incoming_rowspan.get(*col) {
|
while let Some(span) = incoming_rowspan.get(*col) {
|
||||||
if *span <= 1 {
|
if *span <= 1 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*max_block_size = max(*max_block_size, incoming_rowspan_data[*col]);
|
let incoming = incoming_rowspan_data[*col];
|
||||||
|
*max_block_size = max(*max_block_size, incoming);
|
||||||
|
if *span > 2 {
|
||||||
|
*largest_leftover_incoming_size = max(*largest_leftover_incoming_size,
|
||||||
|
incoming * (*span - 1) as i32)
|
||||||
|
}
|
||||||
*col += 1;
|
*col += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Per CSS 2.1 § 17.5.3, find max_y = max(computed `block-size`, minimum block-size of
|
// Per CSS 2.1 § 17.5.3, find max_y = max(computed `block-size`, minimum block-size of
|
||||||
// all cells).
|
// all cells).
|
||||||
let mut max_block_size = Au(0);
|
let mut max_block_size = Au(0);
|
||||||
|
let mut largest_leftover_incoming_size = Au(0);
|
||||||
let thread_id = self.block_flow.base.thread_id;
|
let thread_id = self.block_flow.base.thread_id;
|
||||||
let content_box = self.block_flow.base.position
|
let content_box = self.block_flow.base.position
|
||||||
- self.block_flow.fragment.border_padding
|
- self.block_flow.fragment.border_padding
|
||||||
|
@ -142,7 +147,8 @@ impl TableRowFlow {
|
||||||
let mut col = 0;
|
let mut col = 0;
|
||||||
for kid in self.block_flow.base.child_iter_mut() {
|
for kid in self.block_flow.base.child_iter_mut() {
|
||||||
include_sizes_from_previous_rows(&mut col, &self.incoming_rowspan,
|
include_sizes_from_previous_rows(&mut col, &self.incoming_rowspan,
|
||||||
incoming_rowspan_data, &mut max_block_size);
|
incoming_rowspan_data, &mut max_block_size,
|
||||||
|
&mut largest_leftover_incoming_size);
|
||||||
kid.place_float_if_applicable();
|
kid.place_float_if_applicable();
|
||||||
if !kid.base().flags.is_float() {
|
if !kid.base().flags.is_float() {
|
||||||
kid.assign_block_size_for_inorder_child_if_necessary(layout_context,
|
kid.assign_block_size_for_inorder_child_if_necessary(layout_context,
|
||||||
|
@ -167,8 +173,9 @@ impl TableRowFlow {
|
||||||
if incoming_rowspan_data.len() <= col {
|
if incoming_rowspan_data.len() <= col {
|
||||||
incoming_rowspan_data.resize(col + 1, Au(0));
|
incoming_rowspan_data.resize(col + 1, Au(0));
|
||||||
}
|
}
|
||||||
// XXXManishearth rowspan can overflow the table
|
|
||||||
let border_sizes_spanned = get_spanned_border_size(border_info, row_index, row_span);
|
let border_sizes_spanned = get_spanned_border_size(border_info, row_index, row_span);
|
||||||
|
let pressure_copy = cell_block_size_pressure;
|
||||||
|
|
||||||
cell_block_size_pressure -= border_sizes_spanned;
|
cell_block_size_pressure -= border_sizes_spanned;
|
||||||
|
|
||||||
// XXXManishearth in case this row covers more than cell_block_size_pressure / row_span
|
// XXXManishearth in case this row covers more than cell_block_size_pressure / row_span
|
||||||
|
@ -176,12 +183,18 @@ impl TableRowFlow {
|
||||||
// require an extra slow-path loop, sadly.
|
// require an extra slow-path loop, sadly.
|
||||||
cell_block_size_pressure /= row_span as i32;
|
cell_block_size_pressure /= row_span as i32;
|
||||||
incoming_rowspan_data[col] = cell_block_size_pressure;
|
incoming_rowspan_data[col] = cell_block_size_pressure;
|
||||||
|
|
||||||
|
// If this ends up being the last row, it needs to cover
|
||||||
|
// *all* this space
|
||||||
|
largest_leftover_incoming_size = max(largest_leftover_incoming_size,
|
||||||
|
pressure_copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
max_block_size = max(max_block_size, cell_block_size_pressure);
|
max_block_size = max(max_block_size, cell_block_size_pressure);
|
||||||
col += column_span;
|
col += column_span;
|
||||||
}
|
}
|
||||||
include_sizes_from_previous_rows(&mut col, &self.incoming_rowspan, incoming_rowspan_data, &mut max_block_size);
|
include_sizes_from_previous_rows(&mut col, &self.incoming_rowspan, incoming_rowspan_data, &mut max_block_size,
|
||||||
|
&mut largest_leftover_incoming_size);
|
||||||
|
|
||||||
let mut block_size = max_block_size;
|
let mut block_size = max_block_size;
|
||||||
// TODO: Percentage block-size
|
// TODO: Percentage block-size
|
||||||
|
@ -193,7 +206,7 @@ impl TableRowFlow {
|
||||||
MaybeAuto::Auto => block_size,
|
MaybeAuto::Auto => block_size,
|
||||||
MaybeAuto::Specified(value) => max(value, block_size),
|
MaybeAuto::Specified(value) => max(value, block_size),
|
||||||
};
|
};
|
||||||
block_size
|
(block_size, largest_leftover_incoming_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assign_block_size_to_self_and_children(&mut self, sizes: &[(Au, 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) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue