diff options
author | Eric Atkinson <eatkinson@mozilla.com> | 2013-07-17 13:31:57 -0700 |
---|---|---|
committer | Eric Atkinson <eatkinson@mozilla.com> | 2013-08-09 00:05:31 -0700 |
commit | eb1b40db13a13c27269c57bad60433e0597bbbeb (patch) | |
tree | be0edfdc4ad402fc54052b817b6e97926751e9b0 /src/components/main/layout/float.rs | |
parent | 73e7b6519b64160c802acd5175c01aacfd0daba6 (diff) | |
download | servo-eb1b40db13a13c27269c57bad60433e0597bbbeb.tar.gz servo-eb1b40db13a13c27269c57bad60433e0597bbbeb.zip |
Don't use a whole in-order traversal for computing heights.
Diffstat (limited to 'src/components/main/layout/float.rs')
-rw-r--r-- | src/components/main/layout/float.rs | 100 |
1 files changed, 71 insertions, 29 deletions
diff --git a/src/components/main/layout/float.rs b/src/components/main/layout/float.rs index f8024464fd6..84f09723ebd 100644 --- a/src/components/main/layout/float.rs +++ b/src/components/main/layout/float.rs @@ -35,6 +35,9 @@ pub struct FloatFlowData { /// Index into the box list for inline floats index: Option<uint>, + /// Number of floated children + floated_children: uint, + } impl FloatFlowData { @@ -46,6 +49,7 @@ impl FloatFlowData { index: None, float_type: float_type, rel_pos: Point2D(Au(0), Au(0)), + floated_children: 0, } } @@ -63,7 +67,7 @@ impl FloatFlowData { pub fn bubble_widths_float(@mut self, ctx: &LayoutContext) { let mut min_width = Au(0); let mut pref_width = Au(0); - let mut num_floats = 1; + let mut num_floats = 0; for FloatFlow(self).each_child |child_ctx| { //assert!(child_ctx.starts_block_flow() || child_ctx.starts_inline_flow()); @@ -71,12 +75,12 @@ impl FloatFlowData { do child_ctx.with_mut_base |child_node| { min_width = geometry::max(min_width, child_node.min_width); pref_width = geometry::max(pref_width, child_node.pref_width); - num_floats = num_floats + child_node.num_floats; } } - self.common.num_floats = num_floats; + self.common.num_floats = 1; + self.floated_children = num_floats; self.box.map(|&box| { @@ -93,13 +97,16 @@ impl FloatFlowData { self.common.pref_width = pref_width; } - pub fn assign_widths_float(@mut self, _: &LayoutContext) { + pub fn assign_widths_float(@mut self) { debug!("assign_widths_float: assigning width for flow %?", self.common.id); // position.size.width is set by parent even though we don't know // position.origin yet. let mut remaining_width = self.common.position.size.width; self.containing_width = remaining_width; let mut x_offset = Au(0); + + // Parent usually sets this, but floats are never inorder + self.common.is_inorder = false; for self.box.iter().advance |&box| { let style = box.style(); @@ -154,25 +161,77 @@ impl FloatFlowData { self.common.position.size.width = remaining_width; + let has_inorder_children = self.common.num_floats > 0; for FloatFlow(self).each_child |kid| { //assert!(kid.starts_block_flow() || kid.starts_inline_flow()); do kid.with_mut_base |child_node| { child_node.position.origin.x = x_offset; child_node.position.size.width = remaining_width; + child_node.is_inorder = has_inorder_children; + + if !child_node.is_inorder { + child_node.floats_in = FloatContext::new(0); + } } } } - pub fn assign_height_float(@mut self, ctx: &mut LayoutContext) { - let mut float_ctx = FloatContext::new(self.common.num_floats); - for FloatFlow(self).each_child |kid| { - do kid.with_mut_base |child_node| { - child_node.floats_in = float_ctx.clone(); + pub fn assign_height_inorder_float(@mut self) { + debug!("assign_height_inorder_float: assigning height for float %?", self.common.id); + // assign_height_float was already called by the traversal function + // so this is well-defined + + let mut height = Au(0); + let mut full_noncontent_width = Au(0); + let mut full_noncontent_height = Au(0); + + self.box.map(|&box| { + height = do box.with_base |base| { + base.position.size.height + }; + + do box.with_base |base| { + + let noncontent_width = base.model.padding.left + base.model.padding.right + + base.model.border.left + base.model.border.right; + let noncontent_height = base.model.padding.top + base.model.padding.bottom + + base.model.border.top + base.model.border.bottom; + + full_noncontent_width = noncontent_width + base.model.margin.left + base.model.margin.right; + full_noncontent_height = noncontent_height + base.model.margin.top + base.model.margin.bottom; + } - kid.assign_height(ctx); - do kid.with_mut_base |child_node| { - float_ctx = child_node.floats_out.clone(); + + }); + + let info = PlacementInfo { + width: self.common.position.size.width + full_noncontent_width, + height: height + full_noncontent_height, + ceiling: Au(0), + max_width: self.containing_width, + f_type: self.float_type, + }; + + // Place the float and return the FloatContext back to the parent flow. + // After, grab the position and use that to set our position. + self.common.floats_out = self.common.floats_in.add_float(&info); + self.rel_pos = self.common.floats_out.last_float_pos(); + } + + pub fn assign_height_float(@mut self, ctx: &mut LayoutContext) { + debug!("assign_height_float: assigning height for float %?", self.common.id); + let has_inorder_children = self.common.num_floats > 0; + if has_inorder_children { + let mut float_ctx = FloatContext::new(self.floated_children); + for FloatFlow(self).each_child |kid| { + do kid.with_mut_base |child_node| { + child_node.floats_in = float_ctx.clone(); + } + kid.assign_height_inorder(ctx); + do kid.with_mut_base |child_node| { + float_ctx = child_node.floats_out.clone(); + } } } @@ -197,8 +256,6 @@ impl FloatFlowData { let mut noncontent_width = Au(0); let mut noncontent_height = Au(0); - let mut full_noncontent_width = Au(0); - let mut full_noncontent_height = Au(0); self.box.map(|&box| { do box.with_mut_base |base| { //The associated box is the border box of this flow @@ -210,8 +267,6 @@ impl FloatFlowData { base.model.border.top + base.model.border.bottom; base.position.size.height = height + noncontent_height; - full_noncontent_width = noncontent_width + base.model.margin.left + base.model.margin.right; - full_noncontent_height = noncontent_height + base.model.margin.top + base.model.margin.bottom; } }); @@ -229,19 +284,6 @@ impl FloatFlowData { base.position.size.height = height; } } - - let info = PlacementInfo { - width: self.common.position.size.width + full_noncontent_width, - height: height + full_noncontent_height, - ceiling: Au(0), - max_width: self.containing_width, - f_type: self.float_type, - }; - - // Place the float and return the FloatContext back to the parent flow. - // After, grab the position and use that to set our position. - self.common.floats_out = self.common.floats_in.add_float(&info); - self.rel_pos = self.common.floats_out.last_float_pos(); } pub fn build_display_list_float<E:ExtraDisplayListData>(@mut self, |