From aab36e8ef5333e2b22e746e3f88d583f00c63147 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 10 May 2012 16:13:32 -0700 Subject: [PATCH] servo: Separate intrinsic sizes from block layout Source-Repo: https://github.com/servo/servo Source-Revision: 210434a9b8ee1c3d6ecdb0865d91218ce913f8df --- servo/src/servo/gfx/geom.rs | 8 ++++-- servo/src/servo/layout/base.rs | 39 +++++++++++++++------------ servo/src/servo/layout/box_builder.rs | 23 ++++++++++++---- servo/src/servo/layout/inline.rs | 4 +-- servo/src/servo/layout/style/style.rs | 2 +- 5 files changed, 49 insertions(+), 27 deletions(-) diff --git a/servo/src/servo/gfx/geom.rs b/servo/src/servo/gfx/geom.rs index a6b5aa68d7b1..7bc528f5a300 100644 --- a/servo/src/servo/gfx/geom.rs +++ b/servo/src/servo/gfx/geom.rs @@ -26,7 +26,11 @@ fn box(x: A, y: A, w: A, h: A) -> rect { fn zero_rect_au() -> rect { let z = au(0); - {mut origin: point(z, z), mut size: size(z, z)} + {mut origin: point(z, z), mut size: zero_size_au()} +} + +fn zero_size_au() -> size { + {mut width: au(0), mut height: au(0)} } fn px_to_au(i: int) -> au { @@ -35,4 +39,4 @@ fn px_to_au(i: int) -> au { fn au_to_px(au: au) -> int { *au / 60 -} \ No newline at end of file +} diff --git a/servo/src/servo/layout/base.rs b/servo/src/servo/layout/base.rs index 71aab6359819..4714fc0895cb 100644 --- a/servo/src/servo/layout/base.rs +++ b/servo/src/servo/layout/base.rs @@ -2,16 +2,23 @@ import dom::base::{nk_div, nk_img, node_data, node_kind, node}; import dom::rcu; import dom::rcu::reader_methods; import gfx::geom; -import gfx::geom::{size, rect, point, au}; +import gfx::geom::{size, rect, point, au, zero_size_au}; import /*layout::*/inline::inline_layout_methods; import /*layout::*/style::style::{computed_style, di_block, di_inline}; import /*layout::*/style::style::style_methods; import util::{tree}; +enum box_kind { + bk_block, + bk_inline, + bk_intrinsic(@geom::size) +} + enum box = { tree: tree::fields<@box>, node: node, - mut bounds: geom::rect + mut bounds: geom::rect, + kind: box_kind }; enum layout_data = { @@ -54,15 +61,16 @@ impl of tree::wr_tree_ops<@box> for btree { impl block_layout_methods for @box { #[doc="The main reflow routine."] fn reflow(available_width: au) { - alt self.node.get_computed_style().display { - di_block { self.reflow_block(available_width) } - di_inline { self.reflow_inline(available_width) } + alt self.kind { + bk_block { self.reflow_block(available_width) } + bk_inline { self.reflow_inline(available_width) } + bk_intrinsic(size) { self.reflow_intrinsic(*size) } } } #[doc="The main reflow routine for block layout."] fn reflow_block(available_width: au) { - assert self.node.get_computed_style().display == di_block; + assert self.kind == bk_block; // Root here is the root of the reflow, not necessarily the doc as // a whole. @@ -72,16 +80,6 @@ impl block_layout_methods for @box { // - generates root.bounds.origin for each child // - and recursively computes the bounds for each child - let k = self.node.rd() { |r| r.kind }; - alt k { - nk_img(size) { - self.bounds.size = size; - ret; - } - - nk_div { /* fallthrough */ } - } - let mut current_height = 0; for tree::each_child(btree, self) {|c| let mut blk_available_width = available_width; @@ -94,7 +92,14 @@ impl block_layout_methods for @box { self.bounds.size = {mut width: available_width, // FIXME mut height: au(current_height)}; - #debug["reflow_block root=%? size=%?", k, self.bounds]; + #debug["reflow_block size=%?", self.bounds]; + } + + #[doc="The trivial reflow routine for instrinsically-sized frames."] + fn reflow_intrinsic(size: geom::size) { + self.bounds.size = size; + + #debug["reflow_intrinsic size=%?", self.bounds]; } } diff --git a/servo/src/servo/layout/box_builder.rs b/servo/src/servo/layout/box_builder.rs index 35f1114d10d2..5efb1bc3c01c 100644 --- a/servo/src/servo/layout/box_builder.rs +++ b/servo/src/servo/layout/box_builder.rs @@ -1,26 +1,39 @@ #[doc="Creates CSS boxes from a DOM."] -import dom::base::node; +import dom::base::{nk_div, nk_img, node}; import dom::rcu::reader_methods; import gfx::geom; -import /*layout::*/base::{box, btree, ntree, rd_tree_ops, wr_tree_ops}; +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 util::tree; export box_builder_methods; -fn new_box(n: node) -> @box { +fn new_box(n: node, kind: box_kind) -> @box { @box({tree: tree::empty(), node: n, - mut bounds: geom::zero_rect_au()}) + mut bounds: geom::zero_rect_au(), + kind: kind }) } impl box_builder_priv_methods for node { fn construct_boxes() -> @box { - let b = new_box(self); + let b = new_box(self, self.determine_box_kind()); self.aux::<()>({ |a| a.box = some(b); }); ret b; } + + #[doc=" + Determines the kind of box that this node needs. Also, for images, + computes the intrinsic size. + "] + fn determine_box_kind() -> box_kind { + alt self.rd({ |n| n.kind }) { + nk_img(size) { bk_intrinsic(@size) } + nk_div { bk_block } + } + } } impl box_builder_methods for node { diff --git a/servo/src/servo/layout/inline.rs b/servo/src/servo/layout/inline.rs index d11c50f40ae4..1fd886644a2a 100644 --- a/servo/src/servo/layout/inline.rs +++ b/servo/src/servo/layout/inline.rs @@ -4,13 +4,13 @@ import dom::rcu; import dom::rcu::reader_methods; import gfx::geom::au; import /*layout::*/base::*; // FIXME: Can't get around import *; resolve bug. -import /*layout::*/style::style::{di_inline, style_methods}; +import /*layout::*/style::style::style_methods; import util::tree; #[doc="The main reflow routine for inline layout."] impl inline_layout_methods for @box { fn reflow_inline(available_width: au) { - assert self.node.get_computed_style().display == di_inline; + assert self.kind == bk_inline; // FIXME: This is clownshoes inline layout and is not even close to // correct. diff --git a/servo/src/servo/layout/style/style.rs b/servo/src/servo/layout/style/style.rs index 86ef324043ec..448f83707254 100644 --- a/servo/src/servo/layout/style/style.rs +++ b/servo/src/servo/layout/style/style.rs @@ -17,7 +17,7 @@ enum display { fn default_style_for_node_kind(kind : node_kind) -> computed_style { alt kind { nk_div { computed_style({ mut display: di_block }) } - nk_img(*) { computed_style({ mut display: di_block }) } + nk_img(*) { computed_style({ mut display: di_inline }) } } }