Fix up problems with float placement

This commit is contained in:
Eric Atkinson 2013-06-24 16:06:45 -07:00
parent 0c63dda290
commit 49f80fd894
3 changed files with 34 additions and 10 deletions

View file

@ -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<E:ExtraDisplayListData>(@mut self,

View file

@ -27,6 +27,8 @@ pub struct FloatFlowData {
containing_width: Au,
/// Parent clobbers our position, so store it separately
rel_pos: Point2D<Au>,
/// Index into the box list for inline floats
index: Option<uint>,
@ -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<E:ExtraDisplayListData>(@mut self,
@ -221,15 +224,17 @@ impl FloatFlowData {
dirty: &Rect<Au>,
offset: &Point2D<Au>,
list: &Cell<DisplayList<E>>) {
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)
}
}
}

View file

@ -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<Au>{
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