From 668f28dc15c32c2e27e13c2feec5e5b2e033efe6 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 27 Mar 2012 15:04:21 -0700 Subject: [PATCH] first hack at block layout algorithm --- src/dom/rcu.rs | 6 +++ src/layout/base.rs | 96 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) diff --git a/src/dom/rcu.rs b/src/dom/rcu.rs index e69de29bb2d..bde372f0c71 100644 --- a/src/dom/rcu.rs +++ b/src/dom/rcu.rs @@ -0,0 +1,6 @@ +enum handle = @T; + +impl methods for handle { + fn get() -> @T { *self } +} + diff --git a/src/layout/base.rs b/src/layout/base.rs index e69de29bb2d..8268523261f 100644 --- a/src/layout/base.rs +++ b/src/layout/base.rs @@ -0,0 +1,96 @@ +import dom::rcu; +import dom::rcu::methods; + +// FIXME--mut should be inherited +type point = { mut x: A, mut y: A }; +type size = { mut width: A, mut height: A }; +type rect = { mut origin: point, mut size: size }; + +enum au = int; + +type tree_fields = { + parent: option, + first_child: option, + last_child: option, + prev_sibling: option, + next_sibling: option +}; + +enum box = @{ + tree: tree_fields, + node: node, + mut bounds: rect +}; + +type node_data = { + tree: tree_fields, + kind: node_kind, + + // Points to the primary box. Note that there may be multiple + // boxes per DOM node. + mut linfo: option, +}; + +enum node_kind { + nk_div, + nk_img(size) +} + +enum node = rcu::handle; + +iface tree { + fn tree_fields() -> tree_fields; +} + +impl of tree for box { + fn tree_fields() -> tree_fields { + ret self.tree; + } +} + +impl of tree for node { + fn tree_fields() -> tree_fields { + ret (*self).get().tree; + } +} + +fn each_child( + node: T, f: fn(T) -> bool) { + + let mut p = node.tree_fields().first_child; + loop { + alt p { + none { ret; } + some(c) { + if !f(c) { ret; } + p = c.tree_fields().next_sibling; + } + } + } +} + +fn reflow_block(root: box, available_width: au) { + // Root here is the root of the reflow, not necessarily the doc as + // a whole. + + alt (*root.node).get().kind { + nk_img(size) { + root.bounds.size = size; + ret; + } + + nk_div { /* fallthrough */ } + } + + let mut current_height = 0; + for each_child(root) {|c| + let mut blk_available_width = available_width; + // FIXME subtract borders, margins, etc + c.bounds.origin = {x: au(0), y: au(current_height)}; + reflow_block(c, blk_available_width); + current_height += *c.bounds.size.height; + } + + root.bounds.size = {width: available_width, // FIXME + height: au(current_height)}; +}