aboutsummaryrefslogtreecommitdiffstats
path: root/src/servo/layout/block.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/servo/layout/block.rs')
-rw-r--r--src/servo/layout/block.rs88
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