try to reset flows which need reflow, since reflow isn't yet idempotent

This commit is contained in:
Clark Gaebel 2014-10-10 11:25:41 -04:00
parent d168501555
commit f552e2f750
13 changed files with 310 additions and 82 deletions

View file

@ -32,7 +32,7 @@ use floats::Floats;
use flow_list::{FlowList, FlowListIterator, MutFlowListIterator};
use flow_ref::FlowRef;
use fragment::{Fragment, TableRowFragment, TableCellFragment};
use incremental::RestyleDamage;
use incremental::{RestyleDamage, Reflow};
use inline::InlineFlow;
use model::{CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo};
use parallel::FlowParallelInfo;
@ -444,7 +444,13 @@ pub trait MutableFlowUtils {
/// This is called in a bottom-up traversal (specifically, the assign-block-size traversal).
/// So, kids have their flow origin already set. In the case of absolute flow kids, they have
/// their hypothetical box position already set.
fn collect_static_block_offsets_from_children(&mut self);
fn collect_static_block_offsets_from_children(self);
fn propagate_restyle_damage(self);
/// At the moment, reflow isn't idempotent. This function resets this flow
/// (and all its descendants, recursively), and marks them as needing reflow.
fn nonincremental_reset(self);
}
pub trait MutableOwnedFlowUtils {
@ -601,6 +607,7 @@ impl FlowFlags {
/// The Descendants of a flow.
///
/// Also, details about their position wrt this flow.
#[deriving(Clone)]
pub struct Descendants {
/// Links to every descendant. This must be private because it is unsafe to leak `FlowRef`s to
/// layout.
@ -1167,9 +1174,9 @@ impl<'a> MutableFlowUtils for &'a mut Flow + 'a {
/// assign-block-size traversal). So, kids have their flow origin already set.
/// In the case of absolute flow kids, they have their hypothetical box
/// position already set.
fn collect_static_block_offsets_from_children(&mut self) {
fn collect_static_block_offsets_from_children(self) {
let mut absolute_descendant_block_offsets = Vec::new();
for kid in mut_base(*self).child_iter() {
for kid in mut_base(self).child_iter() {
let mut gives_absolute_offsets = true;
if kid.is_block_like() {
let kid_block = kid.as_block();
@ -1201,7 +1208,88 @@ impl<'a> MutableFlowUtils for &'a mut Flow + 'a {
}
}
}
mut_base(*self).abs_descendants.static_block_offsets = absolute_descendant_block_offsets
mut_base(self).abs_descendants.static_block_offsets = absolute_descendant_block_offsets
}
fn propagate_restyle_damage(self) {
struct DirtyFloats {
left: bool,
right: bool,
}
fn doit(flow: &mut Flow, down: RestyleDamage, dirty_floats: &mut DirtyFloats) -> RestyleDamage {
match flow.float_clearance() {
clear::none => {}
clear::left => {
(*dirty_floats).left = false;
}
clear::right => {
(*dirty_floats).right = false;
}
clear::both => {
(*dirty_floats).left = false;
(*dirty_floats).right = false;
}
}
match flow.float_kind() {
float::none => {}
float::left => {
(*dirty_floats).left = true;
}
float::right => {
(*dirty_floats).right = true;
}
}
let mut my_damage = mut_base(flow).restyle_damage;
my_damage.insert(down);
if (*dirty_floats).left || (*dirty_floats).right {
my_damage = RestyleDamage::all();
}
let down_damage = my_damage.propagate_down();
for kid in child_iter(flow) {
my_damage.insert(doit(kid, down_damage, dirty_floats));
}
mut_base(flow).restyle_damage = my_damage;
my_damage.propagate_up()
}
doit(self, RestyleDamage::empty(), &mut DirtyFloats { left: false, right: false });
}
fn nonincremental_reset(self) {
fn reset_flow(flow: &mut Flow) {
let base = mut_base(flow);
if !base.restyle_damage.contains(Reflow) {
return
}
let writing_mode = base.writing_mode;
base.position = LogicalRect::zero(writing_mode);
base.overflow = LogicalRect::zero(writing_mode);
base.floats = Floats::new(writing_mode);
base.collapsible_margins = CollapsibleMargins::new();
base.abs_position = Zero::zero();
base.block_container_explicit_block_size = None;
base.display_list = DisplayList::new();
base.layers = DList::new();
base.absolute_position_info = AbsolutePositionInfo::new(writing_mode);
}
reset_flow(self);
for child in child_iter(self) {
child.nonincremental_reset();
}
}
}