Abstract the process of attaching boxes to flows. Remove parent-child box pointer setup.

This commit is contained in:
Brian J. Burg 2012-10-10 10:56:28 -07:00
parent 59c4da3130
commit a86e22ccfb
5 changed files with 46 additions and 29 deletions

View file

@ -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<au>,
c: &Point2D<au>, 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<au>,
offset: &Point2D<au>, list: &dl::DisplayList) {

View file

@ -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())
}

View file

@ -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<au>,
offset: &Point2D<au>, &dl::DisplayList);
pure fn foldl_boxes_for_node<B: Copy>(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<au>,
offset: &Point2D<au>, list: &dl::DisplayList) {
match self {

View file

@ -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<au>, c: &Point2D<au>, 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<au>,
offset: &Point2D<au>, list: &dl::DisplayList) {

View file

@ -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<au>,
c: &Point2D<au>, 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<au>,
offset: &Point2D<au>, list: &dl::DisplayList) {
assert self.starts_root_flow();