From 0b91af36774553210843c74723a6fcf8a1593fd8 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 30 May 2013 22:56:15 -0700 Subject: [PATCH] Refactor a bit and compute vertical margins as well. --- src/components/main/layout/block.rs | 47 +++++++++++++++++++---------- src/components/main/layout/box.rs | 15 +++++---- src/components/main/layout/model.rs | 22 ++++++++++---- 3 files changed, 54 insertions(+), 30 deletions(-) diff --git a/src/components/main/layout/block.rs b/src/components/main/layout/block.rs index 3e26acf669b..0dee3e1c45f 100644 --- a/src/components/main/layout/block.rs +++ b/src/components/main/layout/block.rs @@ -106,7 +106,9 @@ impl BlockFlowData { these widths will not include child elements, just padding etc. */ self.box.map(|&box| { //Can compute border width here since it doesn't depend on anything - box.compute_borders(); + do box.with_model |model| { + model.compute_borders(box.style()) + } min_width = min_width.add(&box.get_min_width(ctx)); pref_width = pref_width.add(&box.get_pref_width(ctx)); }); @@ -182,16 +184,37 @@ impl BlockFlowData { let mut x_offset = Au(0); self.box.map(|&box| { - box.compute_padding(remaining_width); - let available_width = remaining_width - box.get_noncontent_width(); + do box.with_model |model| { + model.compute_padding(box.style(), remaining_width); - do box.compute_width(remaining_width) |width, left_margin, right_margin| { - self.compute_horiz(width, left_margin, right_margin, available_width) + let available_width = remaining_width - model.noncontent_width(); + + let margin_top = MaybeAuto::from_margin(box.style().margin_top()).spec_or_default(Au(0)); + let margin_bottom = MaybeAuto::from_margin(box.style().margin_bottom()).spec_or_default(Au(0)); + + let (width, margin_left, margin_right) = (MaybeAuto::from_width(box.style().width()), + MaybeAuto::from_margin(box.style().margin_left()), + MaybeAuto::from_margin(box.style().margin_right())); + + let (width, margin_left, margin_right) = + self.compute_horiz(width, margin_left, margin_right, available_width); + + model.margin.top = margin_top; + model.margin.right = margin_right; + model.margin.bottom = margin_bottom; + model.margin.left = margin_left; + + x_offset = model.offset(); + remaining_width = remaining_width - model.noncontent_width(); } - let content_box = box.content_box(); - x_offset = content_box.origin.x; - remaining_width = content_box.size.width; + do box.with_mut_base |base| { + let bp_width = base.model.padding.left + base.model.padding.right + + base.model.border.left + base.model.border.right; + + base.position.size.width = remaining_width + bp_width; + base.position.origin.x = base.model.margin.left; + } }); for BlockFlow(self).each_child |kid| { @@ -222,15 +245,7 @@ impl BlockFlowData { self.common.position.size.height = height; - let _used_top = Au(0); - let _used_bot = Au(0); - self.box.map(|&box| { - do box.with_mut_base |base| { - base.position.origin.y = Au(0); - base.position.size.height = height; - let (_used_top, _used_bot) = box.get_used_height(); - } }); } diff --git a/src/components/main/layout/box.rs b/src/components/main/layout/box.rs index 4e79a6205ab..2b825ba67a1 100644 --- a/src/components/main/layout/box.rs +++ b/src/components/main/layout/box.rs @@ -8,7 +8,7 @@ use css::node_style::StyledNode; use layout::context::LayoutContext; use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData, ToGfxColor}; use layout::flow::FlowContext; -use layout::model::{BoxModel,MaybeAuto}; +use layout::model::{BoxModel}; use layout::text; use core::cell::Cell; @@ -487,16 +487,15 @@ pub impl RenderBox { } } + fn with_model(&self, callback: &fn(&mut BoxModel) -> R) -> R { + do self.with_imm_base |base| { + callback(&mut base.model) + } + } + /// The box formed by the content edge as defined in CSS 2.1 § 8.1. Coordinates are relative to /// the owning flow. fn content_box(&self) -> Rect { - do self.with_imm_base |base| { - let origin = Point2D(base.position.origin.x + base.model.border.left + base.model.padding.left, - base.position.origin.y); - let size = Size2D(base.position.size.width - self.get_noncontent_width(), - base.position.size.height); - Rect(origin, size) - } } /// The box formed by the border edge as defined in CSS 2.1 § 8.1. Coordinates are relative to diff --git a/src/components/main/layout/model.rs b/src/components/main/layout/model.rs index 9ed6a5b8de4..765ac12e5b1 100644 --- a/src/components/main/layout/model.rs +++ b/src/components/main/layout/model.rs @@ -27,7 +27,7 @@ pub struct BoxModel { border: SideOffsets2D, padding: SideOffsets2D, margin: SideOffsets2D, - content_width: Au, + cb_width: Au, } /// Useful helper data type when computing values for blocks and positioned elements. @@ -75,13 +75,12 @@ impl Zero for BoxModel { border: Zero::zero(), padding: Zero::zero(), margin: Zero::zero(), - content_width: Zero::zero(), + cb_width: Zero::zero(), } } fn is_zero(&self) -> bool { - self.padding.is_zero() && self.border.is_zero() && self.margin.is_zero() && - self.content_width.is_zero() + self.padding.is_zero() && self.border.is_zero() && self.margin.is_zero() } } @@ -102,8 +101,18 @@ impl BoxModel { self.padding.left = self.compute_padding_length(style.padding_left(), cb_width); } + pub fn noncontent_width(&self) -> Au { + let left = self.margin.left + self.border.left + self.padding.left; + let right = self.margin.right + self.border.right + self.padding.right; + left + right + } + + pub fn offset(&self) -> Au { + self.margin.left + self.border.left + self.padding.left + } + /// Helper function to compute the border width in app units from the CSS border width. - fn compute_border_width(&self, width: CSSBorderWidth) -> Au { + priv fn compute_border_width(&self, width: CSSBorderWidth) -> Au { match width { CSSBorderWidthLength(Px(v)) | CSSBorderWidthLength(Em(v)) | @@ -117,7 +126,7 @@ impl BoxModel { } } - fn compute_padding_length(&self, padding: CSSPadding, cb_width: Au) -> Au{ + priv fn compute_padding_length(&self, padding: CSSPadding, cb_width: Au) -> Au { match padding { CSSPaddingLength(Px(v)) | CSSPaddingLength(Pt(v)) | @@ -128,6 +137,7 @@ impl BoxModel { CSSPaddingPercentage(p) => cb_width.scale_by(p) } } + } //