mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Implement toy inline layout
This commit is contained in:
parent
1cab10d8ba
commit
dccee997e8
7 changed files with 175 additions and 19 deletions
|
@ -52,3 +52,4 @@ impl of tree::wr_tree_ops<node> for node_scope {
|
|||
self.wr(node) { |n| f(n.tree) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,9 @@ impl reader_methods<T:send,A> for handle<T,A> {
|
|||
}
|
||||
|
||||
fn set_aux(p: @A) unsafe {
|
||||
let p2 = p;
|
||||
unsafe::forget(p2); // Bump the reference count.
|
||||
|
||||
(**self).rd_aux = ptr::addr_of(*p);
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,22 @@ impl of tree::wr_tree_ops<@box> for btree {
|
|||
}
|
||||
}
|
||||
|
||||
impl layout_methods_priv for @box {
|
||||
#[doc="Dumps the box tree, for debugging, with indentation."]
|
||||
fn dump_indent(indent: uint) {
|
||||
let mut s = "";
|
||||
uint::range(0u, indent) {
|
||||
|_i|
|
||||
s += " ";
|
||||
}
|
||||
|
||||
s += #fmt("%?", self.kind);
|
||||
#debug["%s", s];
|
||||
|
||||
for btree.each_child(self) { |kid| kid.dump_indent(indent + 1u) }
|
||||
}
|
||||
}
|
||||
|
||||
impl layout_methods for @box {
|
||||
#[doc="The main reflow routine."]
|
||||
fn reflow(available_width: au) {
|
||||
|
@ -77,6 +93,36 @@ impl layout_methods for @box {
|
|||
|
||||
#debug["reflow_intrinsic size=%?", self.bounds];
|
||||
}
|
||||
|
||||
#[doc="Dumps the box tree, for debugging."]
|
||||
fn dump() {
|
||||
self.dump_indent(0u);
|
||||
}
|
||||
}
|
||||
|
||||
// Debugging
|
||||
|
||||
impl node_methods_priv for node {
|
||||
#[doc="Dumps the node tree, for debugging, with indentation."]
|
||||
fn dump_indent(indent: uint) {
|
||||
let mut s = "";
|
||||
uint::range(0u, indent) {
|
||||
|_i|
|
||||
s += " ";
|
||||
}
|
||||
|
||||
s += #fmt("%?", self.rd({ |n| n.kind }));
|
||||
#debug["%s", s];
|
||||
|
||||
for ntree.each_child(self) { |kid| kid.dump_indent(indent + 1u) }
|
||||
}
|
||||
}
|
||||
|
||||
impl node_methods for node {
|
||||
#[doc="Dumps the subtree rooted at this node, for debugging."]
|
||||
fn dump() {
|
||||
self.dump_indent(0u);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -3,13 +3,27 @@
|
|||
import dom::base::{nk_div, nk_img, node};
|
||||
import dom::rcu::reader_methods;
|
||||
import gfx::geom;
|
||||
import /*layout::*/base::{bk_block, bk_intrinsic, box, box_kind, btree, ntree};
|
||||
import /*layout::*/base::{rd_tree_ops, wr_tree_ops};
|
||||
import /*layout::*/style::style::{di_block, di_inline};
|
||||
import /*layout::*/base::{bk_block, bk_inline, bk_intrinsic, box, box_kind};
|
||||
import /*layout::*/base::{btree, node_methods, ntree, rd_tree_ops};
|
||||
import /*layout::*/base::wr_tree_ops;
|
||||
import /*layout::*/style::style::{di_block, di_inline, style_methods};
|
||||
import util::tree;
|
||||
|
||||
export box_builder_methods;
|
||||
|
||||
enum ctxt = {
|
||||
// The parent node that we're scanning.
|
||||
parent_node: node,
|
||||
// The parent box that these boxes will be added to.
|
||||
parent_box: @box,
|
||||
|
||||
// The current anonymous box that we're currently appending inline nodes
|
||||
// to.
|
||||
//
|
||||
// See CSS2 9.2.1.1.
|
||||
mut anon_box: option<@box>
|
||||
};
|
||||
|
||||
fn new_box(n: node, kind: box_kind) -> @box {
|
||||
@box({tree: tree::empty(),
|
||||
node: n,
|
||||
|
@ -17,13 +31,87 @@ fn new_box(n: node, kind: box_kind) -> @box {
|
|||
kind: kind })
|
||||
}
|
||||
|
||||
impl box_builder_priv_methods for node {
|
||||
fn construct_boxes() -> @box {
|
||||
let b = new_box(self, self.determine_box_kind());
|
||||
self.aux::<()>({ |a| a.box = some(b); });
|
||||
ret b;
|
||||
fn create_context(parent_node: node, parent_box: @box) -> ctxt {
|
||||
ret ctxt({
|
||||
parent_node: parent_node,
|
||||
parent_box: parent_box,
|
||||
mut anon_box: none
|
||||
});
|
||||
}
|
||||
|
||||
impl methods for ctxt {
|
||||
#[doc="
|
||||
Constructs boxes for the parent's children, when the parent's 'display'
|
||||
attribute is 'block'.
|
||||
"]
|
||||
fn construct_boxes_for_block_children() {
|
||||
for ntree.each_child(self.parent_node) {
|
||||
|kid|
|
||||
|
||||
// Create boxes for the child. Get its primary box.
|
||||
let kid_box = kid.construct_boxes();
|
||||
|
||||
// Determine the child's display.
|
||||
let disp = kid.get_computed_style().display;
|
||||
if disp != di_inline {
|
||||
self.finish_anonymous_box_if_necessary();
|
||||
}
|
||||
|
||||
// Add the child's box to the current enclosing box or the current
|
||||
// anonymous box.
|
||||
alt kid.get_computed_style().display {
|
||||
di_block { btree.add_child(self.parent_box, kid_box); }
|
||||
di_inline {
|
||||
let anon_box = alt self.anon_box {
|
||||
none {
|
||||
let b = new_box(kid, bk_inline);
|
||||
self.anon_box = some(b);
|
||||
b
|
||||
}
|
||||
some(b) { b }
|
||||
};
|
||||
btree.add_child(anon_box, kid_box);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Constructs boxes for the parent's children, when the parent's 'display'
|
||||
attribute is 'inline'.
|
||||
"]
|
||||
fn construct_boxes_for_inline_children() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
#[doc="Constructs boxes for the parent's children."]
|
||||
fn construct_boxes_for_children() {
|
||||
#debug("parent node:");
|
||||
self.parent_node.dump();
|
||||
|
||||
alt self.parent_node.get_computed_style().display {
|
||||
di_block { self.construct_boxes_for_block_children(); }
|
||||
di_inline { self.construct_boxes_for_inline_children(); }
|
||||
}
|
||||
|
||||
self.finish_anonymous_box_if_necessary();
|
||||
assert self.anon_box.is_none();
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Flushes the anonymous box we're creating if it exists. This appends the
|
||||
anonymous box to the block.
|
||||
"]
|
||||
fn finish_anonymous_box_if_necessary() {
|
||||
alt self.anon_box {
|
||||
none { /* Nothing to do. */ }
|
||||
some(b) { btree.add_child(self.parent_box, b); }
|
||||
}
|
||||
self.anon_box = none;
|
||||
}
|
||||
}
|
||||
|
||||
impl box_builder_priv for node {
|
||||
#[doc="
|
||||
Determines the kind of box that this node needs. Also, for images,
|
||||
computes the intrinsic size.
|
||||
|
@ -37,15 +125,15 @@ impl box_builder_priv_methods for node {
|
|||
}
|
||||
|
||||
impl box_builder_methods for node {
|
||||
#[doc="Creates boxes for a subtree. This is the entry point."]
|
||||
fn construct_boxes_for_subtree() -> @box {
|
||||
let p_box = self.construct_boxes();
|
||||
for ntree.each_child(self) {
|
||||
|c|
|
||||
let c_box = c.construct_boxes_for_subtree();
|
||||
btree.add_child(p_box, c_box);
|
||||
#[doc="Creates boxes for this node. This is the entry point."]
|
||||
fn construct_boxes() -> @box {
|
||||
let box_kind = self.determine_box_kind();
|
||||
let my_box = new_box(self, box_kind);
|
||||
if box_kind == bk_block {
|
||||
let cx = create_context(self, my_box);
|
||||
cx.construct_boxes_for_children();
|
||||
}
|
||||
ret p_box;
|
||||
ret my_box;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@ import gfx::geom;
|
|||
import gfx::renderer;
|
||||
import dom::base::node;
|
||||
import dom::rcu::scope;
|
||||
import /*layout::*/base::*;
|
||||
import /*layout::*/style::style::style_methods;
|
||||
import base::*;
|
||||
import box_builder::box_builder_methods;
|
||||
import dl = display_list;
|
||||
|
||||
|
@ -29,9 +29,14 @@ fn layout(to_renderer: chan<renderer::msg>) -> chan<msg> {
|
|||
ping(ch) { ch.send(content::pong); }
|
||||
exit { break; }
|
||||
build(node) {
|
||||
#debug("layout: received layout request");
|
||||
#debug("layout: received layout request for:");
|
||||
node.dump();
|
||||
|
||||
node.recompute_style_for_subtree();
|
||||
let this_box = node.construct_boxes_for_subtree();
|
||||
|
||||
let this_box = node.construct_boxes();
|
||||
this_box.dump();
|
||||
|
||||
this_box.reflow(geom::px_to_au(800));
|
||||
let dlist = build_display_list(this_box);
|
||||
to_renderer.send(renderer::render(dlist));
|
||||
|
|
|
@ -32,10 +32,17 @@ impl style_priv for node {
|
|||
fn recompute_style() {
|
||||
let default_style: computed_style =
|
||||
default_style_for_node_kind(self.rd { |n| n.kind });
|
||||
|
||||
#debug("recomputing style; parent node:");
|
||||
self.dump();
|
||||
|
||||
let the_layout_data = @layout_data({
|
||||
mut computed_style: default_style,
|
||||
mut box: none
|
||||
});
|
||||
|
||||
#debug("layout data: %?", the_layout_data);
|
||||
|
||||
self.set_aux(the_layout_data);
|
||||
}
|
||||
}
|
||||
|
|
6
test-inline.html
Normal file
6
test-inline.html
Normal file
|
@ -0,0 +1,6 @@
|
|||
<div>
|
||||
<img></img>
|
||||
<div>
|
||||
<img></img><img></img><img></img>
|
||||
</div>
|
||||
</div>
|
Loading…
Add table
Add a link
Reference in a new issue