diff options
Diffstat (limited to 'src/servo/layout/block.rs')
-rw-r--r-- | src/servo/layout/block.rs | 88 |
1 files changed, 57 insertions, 31 deletions
diff --git a/src/servo/layout/block.rs b/src/servo/layout/block.rs index 7b1fb67faa2..6d4cda5b31d 100644 --- a/src/servo/layout/block.rs +++ b/src/servo/layout/block.rs @@ -2,12 +2,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -// Block layout. +//! CSS block layout. use layout::box::{RenderBox}; use layout::context::LayoutContext; use layout::display_list_builder::{DisplayListBuilder, FlowDisplayListBuilderMethods}; -use layout::flow::{BlockFlow, FlowContext, InlineBlockFlow, RootFlow}; +use layout::flow::{BlockFlow, FlowContext, FlowData, InlineBlockFlow, RootFlow}; use layout::inline::InlineLayout; use au = gfx::geometry; @@ -18,23 +18,33 @@ use gfx::display_list::DisplayList; use gfx::geometry::Au; pub struct BlockFlowData { + /// Data common to all flows. + common: FlowData, + + /// The associated render box. box: Option<@mut RenderBox> } -pub fn BlockFlowData() -> BlockFlowData { - BlockFlowData { - box: None +impl BlockFlowData { + pub fn new(common: FlowData) -> BlockFlowData { + BlockFlowData { + common: common, + box: None, + } } } +/// NB: These are part of FlowContext, not part of BlockFlowData, because the root flow calls these +/// as well. It is not clear to me whether this needs to be the case, or whether `RootFlow` can be +/// merged into this. pub trait BlockLayout { fn starts_block_flow(&self) -> bool; - fn with_block_box(@mut self, &fn(box: &@mut RenderBox) -> ()) -> (); + fn with_block_box(&self, &fn(box: &@mut RenderBox) -> ()) -> (); - fn bubble_widths_block(@mut self, ctx: &LayoutContext); - fn assign_widths_block(@mut self, ctx: &LayoutContext); - fn assign_height_block(@mut self, ctx: &LayoutContext); - fn build_display_list_block(@mut self, + fn bubble_widths_block(&self, ctx: &LayoutContext); + fn assign_widths_block(&self, ctx: &LayoutContext); + fn assign_height_block(&self, ctx: &LayoutContext); + fn build_display_list_block(&self, a: &DisplayListBuilder, b: &Rect<Au>, c: &Point2D<Au>, @@ -49,17 +59,21 @@ impl BlockLayout for FlowContext { } } - /* Get the current flow's corresponding block box, if it exists, and do something with it. - This works on both BlockFlow and RootFlow, since they are mostly the same. */ - fn with_block_box(@mut self, cb: &fn(box: &@mut RenderBox) -> ()) -> () { + /// Get the current flow's corresponding block box, if it exists, and do something with it. + /// This works on both BlockFlow and RootFlow, since they are mostly the same. + fn with_block_box(&self, callback: &fn(box: &@mut RenderBox) -> ()) -> () { match *self { BlockFlow(*) => { let box = self.block().box; - for box.each |b| { cb(b); } + for box.each |b| { + callback(b); + } }, RootFlow(*) => { let mut box = self.root().box; - for box.each |b| { cb(b); } + for box.each |b| { + callback(b); + } }, _ => fail!(fmt!("Tried to do something with_block_box(), but this is a %?", self)) } @@ -74,7 +88,7 @@ impl BlockLayout for FlowContext { /* TODO: floats */ /* TODO: absolute contexts */ /* TODO: inline-blocks */ - fn bubble_widths_block(@mut self, ctx: &LayoutContext) { + fn bubble_widths_block(&self, ctx: &LayoutContext) { assert!(self.starts_block_flow()); let mut min_width = Au(0); @@ -84,8 +98,10 @@ impl BlockLayout for FlowContext { for self.each_child |child_ctx| { assert!(child_ctx.starts_block_flow() || child_ctx.starts_inline_flow()); - min_width = au::max(min_width, child_ctx.d().min_width); - pref_width = au::max(pref_width, child_ctx.d().pref_width); + do child_ctx.with_common_info |child_info| { + min_width = au::max(min_width, child_info.min_width); + pref_width = au::max(pref_width, child_info.pref_width); + } } /* if not an anonymous block context, add in block box's widths. @@ -95,8 +111,10 @@ impl BlockLayout for FlowContext { pref_width = pref_width.add(&box.get_pref_width(ctx)); } - self.d().min_width = min_width; - self.d().pref_width = pref_width; + do self.with_common_info |info| { + info.min_width = min_width; + info.pref_width = pref_width; + } } /* Recursively (top-down) determines the actual width of child @@ -106,10 +124,10 @@ impl BlockLayout for FlowContext { Dual boxes consume some width first, and the remainder is assigned to all child (block) contexts. */ - fn assign_widths_block(@mut self, _ctx: &LayoutContext) { + fn assign_widths_block(&self, _ctx: &LayoutContext) { assert!(self.starts_block_flow()); - let mut remaining_width = self.d().position.size.width; + let mut remaining_width = self.with_common_info(|info| info.position.size.width); let mut _right_used = Au(0); let mut left_used = Au(0); @@ -123,22 +141,28 @@ impl BlockLayout for FlowContext { for self.each_child |child_ctx| { assert!(child_ctx.starts_block_flow() || child_ctx.starts_inline_flow()); - child_ctx.d().position.origin.x = left_used; - child_ctx.d().position.size.width = remaining_width; + do child_ctx.with_common_info |child_info| { + child_info.position.origin.x = left_used; + child_info.position.size.width = remaining_width; + } } } - fn assign_height_block(@mut self, _ctx: &LayoutContext) { + fn assign_height_block(&self, _ctx: &LayoutContext) { assert!(self.starts_block_flow()); let mut cur_y = Au(0); for self.each_child |child_ctx| { - child_ctx.d().position.origin.y = cur_y; - cur_y += child_ctx.d().position.size.height; + do child_ctx.with_common_info |child_info| { + child_info.position.origin.y = cur_y; + cur_y += child_info.position.size.height; + } } - self.d().position.size.height = cur_y; + do self.with_common_info |info| { + info.position.size.height = cur_y; + } let _used_top = Au(0); let _used_bot = Au(0); @@ -150,9 +174,11 @@ impl BlockLayout for FlowContext { } } - fn build_display_list_block(@mut self, builder: &DisplayListBuilder, dirty: &Rect<Au>, - offset: &Point2D<Au>, list: &Cell<DisplayList>) { - + fn build_display_list_block(&self, + builder: &DisplayListBuilder, + dirty: &Rect<Au>, + offset: &Point2D<Au>, + list: &Cell<DisplayList>) { assert!(self.starts_block_flow()); // add box that starts block context |