Make TableCellStyleIterator operate on immutable flows

This commit is contained in:
Manish Goregaokar 2018-02-14 16:00:42 -08:00
parent 265a2ab2cc
commit 21140e7a0a
2 changed files with 68 additions and 15 deletions

View file

@ -14,7 +14,7 @@ use display_list::{BlockFlowDisplayListBuilding, BorderPaintingMode};
use display_list::{DisplayListBuildState, StackingContextCollectionFlags, StackingContextCollectionState}; use display_list::{DisplayListBuildState, StackingContextCollectionFlags, StackingContextCollectionState};
use euclid::Point2D; use euclid::Point2D;
use flow::{BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ImmutableFlowUtils, GetBaseFlow, OpaqueFlow}; use flow::{BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ImmutableFlowUtils, GetBaseFlow, OpaqueFlow};
use flow_list::MutFlowListIterator; use flow_list::{FlowListIterator, MutFlowListIterator};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx_traits::print_tree::PrintTree; use gfx_traits::print_tree::PrintTree;
use layout_debug; use layout_debug;
@ -882,20 +882,66 @@ enum NextBlockCollapsedBorders<'a> {
/// Iterator over all the rows of a table, which also /// Iterator over all the rows of a table, which also
/// provides the Fragment for rowgroups if any /// provides the Fragment for rowgroups if any
struct TableRowAndGroupIterator<'a> { struct TableRowAndGroupIterator<'a> {
kids: MutFlowListIterator<'a>, kids: FlowListIterator<'a>,
group: Option<(&'a Fragment, MutFlowListIterator<'a>)> group: Option<(&'a Fragment, FlowListIterator<'a>)>
} }
impl<'a> TableRowAndGroupIterator<'a> { impl<'a> TableRowAndGroupIterator<'a> {
fn new(base: &'a mut BaseFlow) -> Self { fn new(base: &'a BaseFlow) -> Self {
TableRowAndGroupIterator { TableRowAndGroupIterator {
kids: base.child_iter_mut(), kids: base.child_iter(),
group: None, group: None,
} }
} }
} }
impl<'a> Iterator for TableRowAndGroupIterator<'a> { impl<'a> Iterator for TableRowAndGroupIterator<'a> {
type Item = (Option<&'a Fragment>, &'a TableRowFlow);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
// If we're inside a rowgroup, iterate through the rowgroup's children.
if let Some(ref mut group) = self.group {
if let Some(grandkid) = group.1.next() {
return Some((Some(group.0), grandkid.as_table_row()))
}
}
// Otherwise, iterate through the table's children.
self.group = None;
match self.kids.next() {
Some(kid) => {
if kid.is_table_rowgroup() {
let mut rowgroup = kid.as_table_rowgroup();
let iter = rowgroup.block_flow.base.child_iter();
self.group = Some((&rowgroup.block_flow.fragment, iter));
self.next()
} else if kid.is_table_row() {
Some((None, kid.as_table_row()))
} else {
self.next() // Skip children that are not rows or rowgroups
}
}
None => None
}
}
}
/// Iterator over all the rows of a table, which also
/// provides the Fragment for rowgroups if any
struct MutTableRowAndGroupIterator<'a> {
kids: MutFlowListIterator<'a>,
group: Option<(&'a Fragment, MutFlowListIterator<'a>)>
}
impl<'a> MutTableRowAndGroupIterator<'a> {
fn new(base: &'a mut BaseFlow) -> Self {
MutTableRowAndGroupIterator {
kids: base.child_iter_mut(),
group: None,
}
}
}
impl<'a> Iterator for MutTableRowAndGroupIterator<'a> {
type Item = (Option<&'a Fragment>, &'a mut TableRowFlow); type Item = (Option<&'a Fragment>, &'a mut TableRowFlow);
#[inline] #[inline]
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
@ -926,11 +972,11 @@ impl<'a> Iterator for TableRowAndGroupIterator<'a> {
} }
/// Iterator over all the rows of a table /// Iterator over all the rows of a table
struct TableRowIterator<'a>(TableRowAndGroupIterator<'a>); struct TableRowIterator<'a>(MutTableRowAndGroupIterator<'a>);
impl<'a> TableRowIterator<'a> { impl<'a> TableRowIterator<'a> {
fn new(base: &'a mut BaseFlow) -> Self { fn new(base: &'a mut BaseFlow) -> Self {
TableRowIterator(TableRowAndGroupIterator::new(base)) TableRowIterator(MutTableRowAndGroupIterator::new(base))
} }
} }
@ -961,7 +1007,7 @@ struct TableCellStyleIterator<'table> {
struct TableCellStyleIteratorRowInfo<'table> { struct TableCellStyleIteratorRowInfo<'table> {
row: &'table Fragment, row: &'table Fragment,
rowgroup: Option<&'table Fragment>, rowgroup: Option<&'table Fragment>,
cell_iterator: MutFlowListIterator<'table>, cell_iterator: FlowListIterator<'table>,
} }
impl<'table> TableCellStyleIterator<'table> { impl<'table> TableCellStyleIterator<'table> {
@ -971,7 +1017,7 @@ impl<'table> TableCellStyleIterator<'table> {
Some(TableCellStyleIteratorRowInfo { Some(TableCellStyleIteratorRowInfo {
row: &row.block_flow.fragment, row: &row.block_flow.fragment,
rowgroup: group, rowgroup: group,
cell_iterator: row.block_flow.base.child_iter_mut() cell_iterator: row.block_flow.base.child_iter()
}) })
} else { } else {
None None
@ -985,7 +1031,7 @@ impl<'table> TableCellStyleIterator<'table> {
} }
struct TableCellStyleInfo<'table> { struct TableCellStyleInfo<'table> {
cell: &'table mut TableCellFlow, cell: &'table TableCellFlow,
colgroup_style: Option<Arc<Background>>, colgroup_style: Option<Arc<Background>>,
col_style: Option<Arc<Background>>, col_style: Option<Arc<Background>>,
rowgroup_style: Option<&'table Background>, rowgroup_style: Option<&'table Background>,
@ -1000,7 +1046,7 @@ impl<'table> Iterator for TableCellStyleIterator<'table> {
if let Some(cell) = row_info.cell_iterator.next() { if let Some(cell) = row_info.cell_iterator.next() {
let rowgroup_style = row_info.rowgroup.map(|r| r.style().get_background()); let rowgroup_style = row_info.rowgroup.map(|r| r.style().get_background());
let row_style = row_info.row.style().get_background(); let row_style = row_info.row.style().get_background();
let cell = cell.as_mut_table_cell(); let cell = cell.as_table_cell();
let (col_style, colgroup_style) = if let Some(column_style) = let (col_style, colgroup_style) = if let Some(column_style) =
self.column_styles.get(self.column_index_relative as usize) { self.column_styles.get(self.column_index_relative as usize) {
let styles = (column_style.col_style.clone(), column_style.colgroup_style.clone()); let styles = (column_style.col_style.clone(), column_style.colgroup_style.clone());
@ -1038,7 +1084,7 @@ impl<'table> Iterator for TableCellStyleIterator<'table> {
*row_info = TableCellStyleIteratorRowInfo { *row_info = TableCellStyleIteratorRowInfo {
row: &row.block_flow.fragment, row: &row.block_flow.fragment,
rowgroup: group, rowgroup: group,
cell_iterator: row.block_flow.base.child_iter_mut() cell_iterator: row.block_flow.base.child_iter()
}; };
self.column_index_relative = 0; self.column_index_relative = 0;
self.column_index_relative_offset = 0; self.column_index_relative_offset = 0;
@ -1059,7 +1105,7 @@ impl<'table> Iterator for TableCellStyleIterator<'table> {
} }
impl<'table> TableCellStyleInfo<'table> { impl<'table> TableCellStyleInfo<'table> {
fn build_display_list(&mut self, mut state: &mut DisplayListBuildState, table_style: &'table ComputedValues) { fn build_display_list(&self, mut state: &mut DisplayListBuildState, table_style: &'table ComputedValues) {
if !self.cell.visible { if !self.cell.visible {
return return
} }
@ -1103,7 +1149,7 @@ impl<'table> TableCellStyleInfo<'table> {
} }
build_dl(self.row_style, &mut state); build_dl(self.row_style, &mut state);
} }
// the restyle damage will be set in TableCellFlow::build_display_list()
self.cell.block_flow.build_display_list_for_block(state, border_painting_mode) self.cell.block_flow.build_display_list_for_block_no_damage(state, border_painting_mode)
} }
} }

View file

@ -247,8 +247,15 @@ impl Flow for TableCellFlow {
} }
fn build_display_list(&mut self, _: &mut DisplayListBuildState) { fn build_display_list(&mut self, _: &mut DisplayListBuildState) {
use style::servo::restyle_damage::ServoRestyleDamage;
// This is handled by TableCellStyleInfo::build_display_list() // This is handled by TableCellStyleInfo::build_display_list()
// when the containing table builds its display list // when the containing table builds its display list
if self.visible {
// we skip setting the damage in TableCellStyleInfo::build_display_list()
// because we only have immutable access
self.block_flow.fragment.restyle_damage.remove(ServoRestyleDamage::REPAINT);
}
} }
fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) { fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) {