diff --git a/src/servo/layout/block.rs b/src/servo/layout/block.rs index 00678809300..ac75961c176 100644 --- a/src/servo/layout/block.rs +++ b/src/servo/layout/block.rs @@ -27,6 +27,7 @@ trait BlockLayout { fn bubble_widths_block(@self, ctx: &LayoutContext); fn assign_widths_block(@self, ctx: &LayoutContext); fn assign_height_block(@self, ctx: &LayoutContext); + fn accept_new_box_block(@self, ctx: &LayoutContext, @RenderBox); fn build_display_list_block(@self, a: &dl::DisplayListBuilder, b: &Rect, c: &Point2D, d: &dl::DisplayList); @@ -142,6 +143,13 @@ impl FlowContext : BlockLayout { } } + fn accept_new_box_block(@self, _ctx: &LayoutContext, box: @RenderBox) { + assert self.starts_block_flow(); + assert self.block().box.is_none(); + + self.block().box = Some(box); + } + fn build_display_list_block(@self, builder: &dl::DisplayListBuilder, dirty: &Rect, offset: &Point2D, list: &dl::DisplayList) { diff --git a/src/servo/layout/box_builder.rs b/src/servo/layout/box_builder.rs index 251344e0fdb..738bc84246d 100644 --- a/src/servo/layout/box_builder.rs +++ b/src/servo/layout/box_builder.rs @@ -39,11 +39,8 @@ impl LayoutTreeBuilder { /** Creates necessary box(es) and flow context(s) for the current DOM node, and recurses on its children. */ - fn construct_recursively(layout_ctx: &LayoutContext, cur_node: Node, - parent_ctx: @FlowContext, parent_box: Option<@RenderBox>) { - + fn construct_recursively(layout_ctx: &LayoutContext, cur_node: Node, parent_ctx: @FlowContext) { let style = cur_node.style(); - // DEBUG let n_str = fmt!("%?", cur_node.read(|n| copy n.kind )); debug!("Considering node: %?", n_str); @@ -89,42 +86,28 @@ impl LayoutTreeBuilder { } }; - // store reference to the flow context which contains any boxes - // that correspond to cur_node + // store reference to the flow context which contains any + // boxes that correspond to cur_node. These boxes may + // eventually be elided or split, but the mapping between + // nodes and FlowContexts should not change during layout. assert cur_node.has_aux(); do cur_node.aux |data| { data.flow = Some(next_ctx) } // make box, add box to any context-specific list. - let mut new_box = self.make_box(layout_ctx, box_type, cur_node, parent_ctx); + let new_box = self.make_box(layout_ctx, box_type, cur_node, parent_ctx); debug!("Assign ^box to flow: %?", next_ctx.debug_str()); + next_ctx.accept_new_box(layout_ctx, new_box); - match *next_ctx { - InlineFlow(*) => { - next_ctx.inline().boxes.push(new_box); - - if (parent_box.is_some()) { - let parent = parent_box.get(); - - // connect the box to its parent box - debug!("In inline flow f%?, set child b%? of parent b%?", - next_ctx.d().id, parent.d().id, new_box.d().id); - RenderBoxTree.add_child(parent, new_box); - } - } - BlockFlow(*) => next_ctx.block().box = Some(new_box), - _ => {} // TODO: float lists, etc. - }; - - + // if this is a new flow, attach to parent flow. if !core::box::ptr_eq(next_ctx, parent_ctx) { debug!("Adding child flow f%? of f%?", parent_ctx.d().id, next_ctx.d().id); FlowTree.add_child(parent_ctx, next_ctx); } - // recurse - // TODO: don't set parent box unless this is an inline flow? + + // recurse on child nodes. do NodeTree.each_child(&cur_node) |child_node| { - self.construct_recursively(layout_ctx, *child_node, next_ctx, Some(new_box)); true + self.construct_recursively(layout_ctx, *child_node, next_ctx); true } // Fixup any irregularities, such as split inlines (CSS 2.1 Section 9.2.1.1) @@ -176,7 +159,7 @@ impl LayoutTreeBuilder { called on root DOM element. */ fn construct_trees(layout_ctx: &LayoutContext, root: Node) -> Result<@FlowContext, ()> { self.root_ctx = Some(self.make_ctx(Flow_Root)); - self.construct_recursively(layout_ctx, root, self.root_ctx.get(), None); + self.construct_recursively(layout_ctx, root, self.root_ctx.get()); return Ok(self.root_ctx.get()) } diff --git a/src/servo/layout/flow.rs b/src/servo/layout/flow.rs index 380ab5d32f9..559deff29ab 100644 --- a/src/servo/layout/flow.rs +++ b/src/servo/layout/flow.rs @@ -70,6 +70,7 @@ trait FlowContextMethods { fn bubble_widths(@self, &LayoutContext); fn assign_widths(@self, &LayoutContext); fn assign_height(@self, &LayoutContext); + fn accept_new_box(@self, &LayoutContext, @RenderBox); fn build_display_list_recurse(@self, &dl::DisplayListBuilder, dirty: &Rect, offset: &Point2D, &dl::DisplayList); pure fn foldl_boxes_for_node(Node, +seed: B, cb: pure fn&(+a: B,@RenderBox) -> B) -> B; @@ -166,6 +167,15 @@ impl FlowContext : FlowContextMethods { } } + fn accept_new_box(@self, ctx: &LayoutContext, box: @RenderBox) { + match self { + @BlockFlow(*) => self.accept_new_box_block(ctx, box), + @InlineFlow(*) => self.accept_new_box_inline(ctx, box), + @RootFlow(*) => self.accept_new_box_root(ctx, box), + _ => fail fmt!("Tried to accept_new_box of flow: %?", self) + } + } + fn build_display_list_recurse(@self, builder: &dl::DisplayListBuilder, dirty: &Rect, offset: &Point2D, list: &dl::DisplayList) { match self { diff --git a/src/servo/layout/inline.rs b/src/servo/layout/inline.rs index 074ba0105ed..4d9f6812134 100644 --- a/src/servo/layout/inline.rs +++ b/src/servo/layout/inline.rs @@ -191,6 +191,7 @@ trait InlineLayout { fn bubble_widths_inline(@self, ctx: &LayoutContext); fn assign_widths_inline(@self, ctx: &LayoutContext); fn assign_height_inline(@self, ctx: &LayoutContext); + fn accept_new_box_inline(@self, &LayoutContext, @RenderBox); fn build_display_list_inline(@self, a: &dl::DisplayListBuilder, b: &Rect, c: &Point2D, d: &dl::DisplayList); } @@ -287,6 +288,13 @@ impl FlowContext : InlineLayout { // during inline flowing. } + fn accept_new_box_inline(@self, _ctx: &LayoutContext, box: @RenderBox) { + assert self.starts_inline_flow(); + + self.inline().boxes.push(box); + // TODO: use the boxlistbuilder + } + fn build_display_list_inline(@self, builder: &dl::DisplayListBuilder, dirty: &Rect, offset: &Point2D, list: &dl::DisplayList) { diff --git a/src/servo/layout/root.rs b/src/servo/layout/root.rs index aa7dff3a0d5..24073333b0e 100644 --- a/src/servo/layout/root.rs +++ b/src/servo/layout/root.rs @@ -25,6 +25,7 @@ trait RootLayout { fn bubble_widths_root(@self, ctx: &LayoutContext); fn assign_widths_root(@self, ctx: &LayoutContext); fn assign_height_root(@self, ctx: &LayoutContext); + fn accept_new_box_root(@self, ctx: &LayoutContext, @RenderBox); fn build_display_list_root(@self, a: &dl::DisplayListBuilder, b: &Rect, c: &Point2D, d: &dl::DisplayList); @@ -58,6 +59,13 @@ impl FlowContext : RootLayout { self.assign_height_block(ctx); } + fn accept_new_box_root(@self, _ctx: &LayoutContext, box: @RenderBox) { + assert self.starts_root_flow(); + assert self.root().box.is_none(); + + self.root().box = Some(box); + } + fn build_display_list_root(@self, builder: &dl::DisplayListBuilder, dirty: &Rect, offset: &Point2D, list: &dl::DisplayList) { assert self.starts_root_flow();