diff --git a/src/components/main/layout/block.rs b/src/components/main/layout/block.rs index c73cbb2a494..6057a7a20bf 100644 --- a/src/components/main/layout/block.rs +++ b/src/components/main/layout/block.rs @@ -134,8 +134,8 @@ impl BlockFlowData { let (left_margin, right_margin) = match width{ Auto => (left_margin, right_margin), Specified(width) => { - let left = left_margin.spec_or_default(Au(0)); - let right = right_margin.spec_or_default(Au(0)); + let left = left_margin.specified_or_zero(); + let right = right_margin.specified_or_zero(); if((left + right + width) > available_width) { (Specified(left), Specified(right)) @@ -202,14 +202,16 @@ impl BlockFlowData { // Top and bottom margins for blocks are 0 if auto. let margin_top = MaybeAuto::from_margin(style.margin_top(), - remaining_width).spec_or_default(Au(0)); + remaining_width, + style.font_size()).specified_or_zero(); let margin_bottom = MaybeAuto::from_margin(style.margin_bottom(), - remaining_width).spec_or_default(Au(0)); + remaining_width, + style.font_size()).specified_or_zero(); let (width, margin_left, margin_right) = - (MaybeAuto::from_width(style.width(), remaining_width), - MaybeAuto::from_margin(style.margin_left(), remaining_width), - MaybeAuto::from_margin(style.margin_right(), remaining_width)); + (MaybeAuto::from_width(style.width(), remaining_width, style.font_size()), + MaybeAuto::from_margin(style.margin_left(), remaining_width, style.font_size()), + MaybeAuto::from_margin(style.margin_right(), remaining_width, style.font_size())); let (width, margin_left, margin_right) = self.compute_horiz(width, margin_left, @@ -297,8 +299,8 @@ impl BlockFlowData { for self.box.iter().advance |&box| { let style = box.style(); - let maybe_height = MaybeAuto::from_height(style.height(), Au(0)); - let maybe_height = maybe_height.spec_or_default(Au(0)); + let maybe_height = MaybeAuto::from_height(style.height(), Au(0), style.font_size()); + let maybe_height = maybe_height.specified_or_zero(); height = geometry::max(height, maybe_height); } diff --git a/src/components/main/layout/box.rs b/src/components/main/layout/box.rs index fe4cd77aa89..1839d93dfc0 100644 --- a/src/components/main/layout/box.rs +++ b/src/components/main/layout/box.rs @@ -388,16 +388,30 @@ impl RenderBox { if(!base.node.is_element()) { Au(0) } else { + let style = self.style(); + let font_size = style.font_size(); + let width = MaybeAuto::from_width(style.width(), + Au(0), + font_size).specified_or_zero(); + let margin_left = MaybeAuto::from_margin(style.margin_left(), + Au(0), + font_size).specified_or_zero(); + let margin_right = MaybeAuto::from_margin(style.margin_right(), + Au(0), + font_size).specified_or_zero(); + let padding_left = base.model.compute_padding_length(style.padding_left(), + Au(0), + font_size); + let padding_right = base.model.compute_padding_length(style.padding_right(), + Au(0), + font_size); + let border_left = base.model.compute_border_width(style.border_left_width(), + font_size); + let border_right = base.model.compute_border_width(style.border_right_width(), + font_size); - let w = MaybeAuto::from_width(self.style().width(), Au(0)).spec_or_default(Au(0)); - let ml = MaybeAuto::from_margin(self.style().margin_left(), Au(0)).spec_or_default(Au(0)); - let mr = MaybeAuto::from_margin(self.style().margin_right(), Au(0)).spec_or_default(Au(0)); - let pl = base.model.compute_padding_length(self.style().padding_left(), Au(0)); - let pr = base.model.compute_padding_length(self.style().padding_right(), Au(0)); - let bl = base.model.compute_border_width(self.style().border_left_width()); - let br = base.model.compute_border_width(self.style().border_right_width()); - - w + ml + mr + pl + pr + bl + br + width + margin_left + margin_right + padding_left + padding_right + + border_left + border_right } } } diff --git a/src/components/main/layout/float.rs b/src/components/main/layout/float.rs index 898ce9ebfe2..9681f6e1f64 100644 --- a/src/components/main/layout/float.rs +++ b/src/components/main/layout/float.rs @@ -106,13 +106,17 @@ impl FloatFlowData { // Margins for floats are 0 if auto. let margin_top = MaybeAuto::from_margin(style.margin_top(), - remaining_width).spec_or_default(Au(0)); + remaining_width, + style.font_size()).specified_or_zero(); let margin_bottom = MaybeAuto::from_margin(style.margin_bottom(), - remaining_width).spec_or_default(Au(0)); + remaining_width, + style.font_size()).specified_or_zero(); let margin_left = MaybeAuto::from_margin(style.margin_left(), - remaining_width).spec_or_default(Au(0)); + remaining_width, + style.font_size()).specified_or_zero(); let margin_right = MaybeAuto::from_margin(style.margin_right(), - remaining_width).spec_or_default(Au(0)); + remaining_width, + style.font_size()).specified_or_zero(); @@ -122,7 +126,8 @@ impl FloatFlowData { let width = MaybeAuto::from_width(style.width(), - remaining_width).spec_or_default(shrink_to_fit); + remaining_width, + style.font_size()).specified_or_default(shrink_to_fit); debug!("assign_widths_float -- width: %?", width); model.margin.top = margin_top; @@ -197,9 +202,10 @@ impl FloatFlowData { //TODO(eatkinson): compute heights properly using the 'height' property. for self.box.iter().advance |&box| { - let height_prop = - MaybeAuto::from_height(box.style().height(), Au(0)).spec_or_default(Au(0)); + MaybeAuto::from_height(box.style().height(), + Au(0), + box.style().font_size()).specified_or_zero(); height = geometry::max(height, height_prop) + noncontent_height; debug!("assign_height_float -- height: %?", height); diff --git a/src/components/main/layout/model.rs b/src/components/main/layout/model.rs index 4bd45dabe17..148223a2a3d 100644 --- a/src/components/main/layout/model.rs +++ b/src/components/main/layout/model.rs @@ -10,7 +10,7 @@ use gfx::geometry::Au; use newcss::complete::CompleteStyle; use newcss::units::{Em, Pt, Px}; use newcss::values::{CSSBorderWidth, CSSBorderWidthLength, CSSBorderWidthMedium}; -use newcss::values::{CSSBorderWidthThick, CSSBorderWidthThin}; +use newcss::values::{CSSBorderWidthThick, CSSBorderWidthThin, CSSFontSize, CSSFontSizeLength}; use newcss::values::{CSSWidth, CSSWidthLength, CSSWidthPercentage, CSSWidthAuto}; use newcss::values::{CSSHeight, CSSHeightLength, CSSHeightPercentage, CSSHeightAuto}; use newcss::values::{CSSMargin, CSSMarginLength, CSSMarginPercentage, CSSMarginAuto}; @@ -30,47 +30,66 @@ pub enum MaybeAuto { Specified(Au), } -impl MaybeAuto{ - pub fn from_margin(margin: CSSMargin, cb_width: Au) -> MaybeAuto{ +impl MaybeAuto { + pub fn from_margin(margin: CSSMargin, containing_width: Au, font_size: CSSFontSize) -> MaybeAuto { match margin { CSSMarginAuto => Auto, - //FIXME(eatkinson): Compute percents properly - CSSMarginPercentage(percent) => Specified(cb_width.scale_by(percent/100.0)), - //FIXME(eatkinson): Compute pt and em values properly - CSSMarginLength(Px(v)) | - CSSMarginLength(Pt(v)) | - CSSMarginLength(Em(v)) => Specified(Au::from_frac_px(v)), + CSSMarginPercentage(percent) => Specified(containing_width.scale_by(percent/100.0)), + CSSMarginLength(Px(v)) => Specified(Au::from_frac_px(v)), + CSSMarginLength(Pt(v)) => Specified(Au::from_pt(v)), + CSSMarginLength(Em(em)) => { + match font_size { + CSSFontSizeLength(Px(v)) => Specified(Au::from_frac_px(em * v)), + CSSFontSizeLength(Pt(v)) => Specified(Au::from_pt(em * v)), + _ => fail!(~"expected non-relative font size"), + } + } } } - pub fn from_width(width: CSSWidth, cb_width: Au) -> MaybeAuto{ - match width{ + pub fn from_width(width: CSSWidth, containing_width: Au, font_size: CSSFontSize) -> MaybeAuto { + match width { CSSWidthAuto => Auto, - CSSWidthPercentage(percent) => Specified(cb_width.scale_by(percent/100.0)), - //FIXME(eatkinson): Compute pt and em values properly - CSSWidthLength(Px(v)) | - CSSWidthLength(Pt(v)) | - CSSWidthLength(Em(v)) => Specified(Au::from_frac_px(v)), + CSSWidthPercentage(percent) => Specified(containing_width.scale_by(percent/100.0)), + CSSWidthLength(Px(v)) => Specified(Au::from_frac_px(v)), + CSSWidthLength(Pt(v)) => Specified(Au::from_pt(v)), + CSSWidthLength(Em(em)) => { + match font_size { + CSSFontSizeLength(Px(v)) => Specified(Au::from_frac_px(em * v)), + CSSFontSizeLength(Pt(v)) => Specified(Au::from_pt(em * v)), + _ => fail!(~"expected non-relative font size"), + } + } } } - pub fn from_height(height: CSSHeight, cb_height: Au) -> MaybeAuto{ + pub fn from_height(height: CSSHeight, cb_height: Au, font_size: CSSFontSize) -> MaybeAuto { match height { CSSHeightAuto => Auto, CSSHeightPercentage(percent) => Specified(cb_height.scale_by(percent/100.0)), - //FIXME(eatkinson): Compute pt and em values properly - CSSHeightLength(Px(v)) | - CSSHeightLength(Pt(v)) | - CSSHeightLength(Em(v)) => Specified(Au::from_frac_px(v)), + CSSHeightLength(Px(v)) => Specified(Au::from_frac_px(v)), + CSSHeightLength(Pt(v)) => Specified(Au::from_pt(v)), + CSSHeightLength(Em(em)) => { + match font_size { + CSSFontSizeLength(Px(v)) => Specified(Au::from_frac_px(em * v)), + CSSFontSizeLength(Pt(v)) => Specified(Au::from_pt(em * v)), + _ => fail!(~"expected non-relative font size"), + } + } + } } - pub fn spec_or_default(&self, default: Au) -> Au{ - match *self{ + pub fn specified_or_default(&self, default: Au) -> Au { + match *self { Auto => default, - Specified(value) => value + Specified(value) => value, } } + + pub fn specified_or_zero(&self) -> Au { + self.specified_or_default(Au(0)) + } } impl Zero for BoxModel { @@ -92,17 +111,17 @@ impl BoxModel { /// Populates the box model parameters from the given computed style. pub fn compute_borders(&mut self, style: CompleteStyle) { // Compute the borders. - self.border.top = self.compute_border_width(style.border_top_width()); - self.border.right = self.compute_border_width(style.border_right_width()); - self.border.bottom = self.compute_border_width(style.border_bottom_width()); - self.border.left = self.compute_border_width(style.border_left_width()); + self.border.top = self.compute_border_width(style.border_top_width(), style.font_size()); + self.border.right = self.compute_border_width(style.border_right_width(), style.font_size()); + self.border.bottom = self.compute_border_width(style.border_bottom_width(), style.font_size()); + self.border.left = self.compute_border_width(style.border_left_width(), style.font_size()); } - pub fn compute_padding(&mut self, style: CompleteStyle, cb_width: Au){ - self.padding.top = self.compute_padding_length(style.padding_top(), cb_width); - self.padding.right = self.compute_padding_length(style.padding_right(), cb_width); - self.padding.bottom = self.compute_padding_length(style.padding_bottom(), cb_width); - self.padding.left = self.compute_padding_length(style.padding_left(), cb_width); + pub fn compute_padding(&mut self, style: CompleteStyle, containing_width: Au) { + self.padding.top = self.compute_padding_length(style.padding_top(), containing_width, style.font_size()); + self.padding.right = self.compute_padding_length(style.padding_right(), containing_width, style.font_size()); + self.padding.bottom = self.compute_padding_length(style.padding_bottom(), containing_width, style.font_size()); + self.padding.left = self.compute_padding_length(style.padding_left(), containing_width, style.font_size()); } pub fn noncontent_width(&self) -> Au { @@ -116,28 +135,34 @@ impl BoxModel { } /// Helper function to compute the border width in app units from the CSS border width. - pub fn compute_border_width(&self, width: CSSBorderWidth) -> Au { + pub fn compute_border_width(&self, width: CSSBorderWidth, font_size: CSSFontSize) -> Au { match width { - CSSBorderWidthLength(Px(v)) | - CSSBorderWidthLength(Em(v)) | - CSSBorderWidthLength(Pt(v)) => { - // FIXME(pcwalton): Handle `em` and `pt` correctly. - Au::from_frac_px(v) - } + CSSBorderWidthLength(Px(v)) => Au::from_frac_px(v), + CSSBorderWidthLength(Pt(v)) => Au::from_pt(v), + CSSBorderWidthLength(Em(em)) => { + match font_size { + CSSFontSizeLength(Px(v)) => Au::from_frac_px(em * v), + CSSFontSizeLength(Pt(v)) => Au::from_pt(em * v), + _ => fail!(~"expected non-relative font size"), + } + }, CSSBorderWidthThin => Au::from_px(1), CSSBorderWidthMedium => Au::from_px(5), CSSBorderWidthThick => Au::from_px(10), } } - pub fn compute_padding_length(&self, padding: CSSPadding, content_box_width: Au) -> Au { + pub fn compute_padding_length(&self, padding: CSSPadding, content_box_width: Au, font_size: CSSFontSize) -> Au { match padding { - CSSPaddingLength(Px(v)) | - CSSPaddingLength(Pt(v)) | - CSSPaddingLength(Em(v)) => { - // FIXME(eatkinson): Handle 'em' and 'pt' correctly - Au::from_frac_px(v) - } + CSSPaddingLength(Px(v)) => Au::from_frac_px(v), + CSSPaddingLength(Pt(v)) => Au::from_pt(v), + CSSPaddingLength(Em(em)) => { + match font_size { + CSSFontSizeLength(Px(v)) => Au::from_frac_px(em * v), + CSSFontSizeLength(Pt(v)) => Au::from_pt(em * v), + _ => fail!(~"expected non-relative font size"), + } + }, CSSPaddingPercentage(p) => content_box_width.scale_by(p/100.0) } } diff --git a/src/support/css/rust-css b/src/support/css/rust-css index 7a584804a98..8b9cf93fb03 160000 --- a/src/support/css/rust-css +++ b/src/support/css/rust-css @@ -1 +1 @@ -Subproject commit 7a584804a98b5731fb53d216c3f059e5a0c7ea5c +Subproject commit 8b9cf93fb03027d0f125afbd84cf758bd8d2d676