aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/main/layout/float.rs
diff options
context:
space:
mode:
authorEric Atkinson <eatkinson@mozilla.com>2013-07-17 13:31:57 -0700
committerEric Atkinson <eatkinson@mozilla.com>2013-08-09 00:05:31 -0700
commiteb1b40db13a13c27269c57bad60433e0597bbbeb (patch)
treebe0edfdc4ad402fc54052b817b6e97926751e9b0 /src/components/main/layout/float.rs
parent73e7b6519b64160c802acd5175c01aacfd0daba6 (diff)
downloadservo-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.rs100
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,