diff --git a/src/components/main/layout/block.rs b/src/components/main/layout/block.rs index 656d17530be..3fa9906423a 100644 --- a/src/components/main/layout/block.rs +++ b/src/components/main/layout/block.rs @@ -249,11 +249,13 @@ impl BlockFlowData { pub fn assign_height_block(@mut self, ctx: &mut LayoutContext) { let mut cur_y = Au(0); let mut top_offset = Au(0); + let mut left_offset = Au(0); for self.box.each |&box| { do box.with_model |model| { top_offset = model.margin.top + model.border.top + model.padding.top; cur_y += top_offset; + left_offset = model.offset(); } } @@ -268,7 +270,7 @@ impl BlockFlowData { // visit child[i] // repeat until all children are visited. // last_child.floats_out -> self.floats_out (done at the end of this method) - let mut float_ctx = self.common.floats_in.clone(); + let mut float_ctx = self.common.floats_in.translate(Point2D(-left_offset, -top_offset)); for BlockFlow(self).each_child |kid| { do kid.with_mut_base |child_node| { child_node.floats_in = float_ctx.clone(); @@ -310,7 +312,7 @@ impl BlockFlowData { self.common.position.size.height = height + noncontent_height; - self.common.floats_out = float_ctx.translate(Point2D(Au(0), self.common.position.size.height)); + self.common.floats_out = float_ctx.translate(Point2D(left_offset, self.common.position.size.height)); } pub fn build_display_list_block(@mut self, diff --git a/src/components/main/layout/float.rs b/src/components/main/layout/float.rs index c63c21dbf25..d1ea3c3fdc8 100644 --- a/src/components/main/layout/float.rs +++ b/src/components/main/layout/float.rs @@ -27,6 +27,8 @@ pub struct FloatFlowData { containing_width: Au, + /// Parent clobbers our position, so store it separately + rel_pos: Point2D, /// Index into the box list for inline floats index: Option, @@ -40,6 +42,7 @@ impl FloatFlowData { containing_width: Au(0), box: None, index: None, + rel_pos: Point2D(Au(0), Au(0)), } } @@ -210,10 +213,10 @@ impl FloatFlowData { f_type: FloatLeft, }; + // 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(@mut self, @@ -221,15 +224,17 @@ impl FloatFlowData { dirty: &Rect, offset: &Point2D, list: &Cell>) { + + let offset = *offset + self.rel_pos; self.box.map(|&box| { - box.build_display_list(builder, dirty, offset, list) + box.build_display_list(builder, dirty, &offset, list) }); // go deeper into the flow tree let flow = FloatFlow(self); for flow.each_child |child| { - flow.build_display_list_for_child(builder, child, dirty, offset, list) + flow.build_display_list_for_child(builder, child, dirty, &offset, list) } } } diff --git a/src/components/main/layout/float_context.rs b/src/components/main/layout/float_context.rs index 0d026ecc942..50fbb5a452b 100644 --- a/src/components/main/layout/float_context.rs +++ b/src/components/main/layout/float_context.rs @@ -122,7 +122,10 @@ impl FloatContextBase{ match self.float_data[self.floats_used - 1] { None => fail!("FloatContext error: floats should never be None here"), - Some(float) => float.bounds.origin + Some(float) => { + debug!("Returning float position: %?", float.bounds.origin + self.offset); + float.bounds.origin + self.offset + } } } @@ -135,6 +138,10 @@ impl FloatContextBase{ (max(top_1, top_2), min(bottom_1, bottom_2)) } + debug!("available_rect: trying to find space at %?", top); + + let top = top - self.offset.y; + // Relevant dimensions for the right-most left float let mut (max_left, l_top, l_bottom) = (Au(0) - self.offset.x, None, None); // Relevant dimensions for the left-most right float @@ -183,7 +190,15 @@ impl FloatContextBase{ (None, None, None, None) => return None, _ => fail!("Reached unreachable state when computing float area") }; - assert!(max_left < min_right, "Float position error"); + + // When the window is smaller than the float, we will return a rect + // with negative width. + assert!(max_left < min_right + || max_left > max_x - self.offset.x + || min_right < Au(0) - self.offset.x + ,"Float position error"); + + //TODO(eatkinson): do we need to do something similar for heights? assert!(top < bottom, "Float position error"); Some(Rect{ @@ -212,11 +227,13 @@ impl FloatContextBase{ /// LOCAL COORDINATES. i.e. must be translated before placed /// in the float list fn place_float(&self, info: &PlacementInfo) -> Point2D{ + debug!("place_float: Placing float with width %? and height %?", info.width, info.height); // Can't go any higher than previous floats or // previous elements in the document. - let mut float_y = max(info.ceiling, self.max_y); + let mut float_y = max(info.ceiling, self.max_y + self.offset.y); loop { let maybe_location = self.available_rect(float_y, info.height, info.max_width); + debug!("place_float: Got available rect: %? for y-pos: %?", maybe_location, float_y); match maybe_location { // If there are no floats blocking us, return the current location // TODO(eatknson): integrate with overflow