mirror of
https://github.com/servo/servo.git
synced 2025-06-24 17:14:33 +01:00
Abstract the process of attaching boxes to flows. Remove parent-child box pointer setup.
This commit is contained in:
parent
59c4da3130
commit
a86e22ccfb
5 changed files with 46 additions and 29 deletions
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue