From 2eb6f39be27aa903789968d766a4e705544195f2 Mon Sep 17 00:00:00 2001 From: Margaret Meyerhofer Date: Fri, 10 Aug 2012 17:02:23 -0700 Subject: [PATCH] Added the ability to specify width by css --- src/servo/layout/block.rs | 2 +- src/servo/layout/box_builder.rs | 23 ++++++++++++++-------- src/servo/layout/inline.rs | 21 ++++++++++++++++---- src/servo/layout/style/apply.rs | 31 ++++++++++++++++++++++++++++++ src/test/compute_height_width.html | 13 +++++++++++++ src/test/height_width.css | 10 ++++++++++ 6 files changed, 87 insertions(+), 13 deletions(-) create mode 100644 src/test/compute_height_width.html create mode 100644 src/test/height_width.css diff --git a/src/servo/layout/block.rs b/src/servo/layout/block.rs index 7a59ba5d36cb..167ec519bd6a 100644 --- a/src/servo/layout/block.rs +++ b/src/servo/layout/block.rs @@ -46,7 +46,7 @@ impl @Box : BlockLayoutMethods { let width = match self.appearance.width { Px(p) => px_to_au(p.to_int()), Auto => self.bounds.size.width, // Do nothing here, width was set by top-down pass - _ => fail ~"inhereit_height failed, width is neither a Px or auto" + _ => fail ~"inhereit_width failed, width is neither a Px or auto" }; self.bounds.size = Size2D(width, height); diff --git a/src/servo/layout/box_builder.rs b/src/servo/layout/box_builder.rs index 1ecc84a0c05c..7dba8d0f8a48 100644 --- a/src/servo/layout/box_builder.rs +++ b/src/servo/layout/box_builder.rs @@ -2,7 +2,7 @@ import dom::base::{ElementData, HTMLDivElement, HTMLImageElement, Element, Text, Node}; import dom::style::{DisplayType, DisBlock, DisInline, DisNone}; -import gfx::geometry; +import gfx::geometry::zero_size_au; import layout::base::{Appearance, BTree, BlockBox, Box, BoxKind, InlineBox, IntrinsicBox, NTree}; import layout::base::{TextBoxKind}; import layout::text::TextBox; @@ -157,14 +157,21 @@ impl Node : PrivBoxBuilder { "] fn determine_box_kind() -> BoxKind { match self.read(|n| copy n.kind) { - ~Text(string) => TextBoxKind(@TextBox(copy string)), - ~Element(element) => { - match *element.kind { - HTMLDivElement => BlockBox, - HTMLImageElement({size}) => IntrinsicBox(@size), - UnknownElement => InlineBox + ~Text(string) => TextBoxKind(@TextBox(copy string)), + ~Element(element) => { + match (copy *element.kind, self.get_specified_style().display_type) { + (HTMLImageElement({size}), _) => IntrinsicBox(@size), + (_, some(DisBlock)) => BlockBox, + (_, some(DisInline)) => InlineBox, + (_, some(DisNone)) => { + // TODO: don't have a box here at all? + IntrinsicBox(@zero_size_au()) + } + (_, none) => { + fail ~"The specified display style should be a default instead of none" + } + } } - } } } } diff --git a/src/servo/layout/inline.rs b/src/servo/layout/inline.rs index 1df882d0cf80..f312a30c73f5 100644 --- a/src/servo/layout/inline.rs +++ b/src/servo/layout/inline.rs @@ -1,11 +1,13 @@ #[doc="Inline layout."] +import base::{Box, InlineBox, BTree}; import dom::rcu; +import dom::style::{Auto, Px}; import geom::point::Point2D; import geom::size::Size2D; -import gfx::geometry::au; +import gfx::geometry::{au, px_to_au}; +import num::num; import util::tree; -import base::{Box, InlineBox, BTree}; trait InlineLayout { fn reflow_inline(); @@ -31,9 +33,20 @@ impl @Box : InlineLayout { current_height = int::max(current_height, *kid.bounds.size.height); } + let height = match self.appearance.height { + Px(p) => px_to_au(p.to_int()), + Auto => au(current_height), + _ => fail ~"inhereit_height failed, height is neither a Px or auto" + }; + + let width = match self.appearance.width { + Px(p) => px_to_au(p.to_int()), + Auto => au(int::max(x, *self.bounds.size.width)), + _ => fail ~"inhereit_width failed, width is neither a Px or auto" + }; + // The maximum available width should have been set in the top-down pass - self.bounds.size = Size2D(au(int::max(x, *self.bounds.size.width)), - au(current_height)); + self.bounds.size = Size2D(width, height); #debug["reflow_inline size=%?", copy self.bounds]; } diff --git a/src/servo/layout/style/apply.rs b/src/servo/layout/style/apply.rs index 337951d1563d..d17ad86fbb66 100644 --- a/src/servo/layout/style/apply.rs +++ b/src/servo/layout/style/apply.rs @@ -18,6 +18,7 @@ trait ApplyStyleBoxMethods { fn inheritance_wrapper(box : @Box) { box.apply_style(); inhereit_height(box); + inhereit_width(box); } #[doc="Compute the specified height of a layout box based on it's css specification and its @@ -50,6 +51,36 @@ fn inhereit_height(box : @Box) { } } +#[doc="Compute the specified width of a layout box based on it's css specification and its + parent's width."] +fn inhereit_width(box : @Box) { + let style = box.node.get_specified_style(); + + box.appearance.width = match style.width { + none => Auto, + some(h) => match h { + Auto | Px(*) => h, + Pt(*) => PtToPx(h), + Mm(*) => MmToPx(h), + Percent(em) => { + match box.tree.parent { + none => Auto, + some(parent) => { + match parent.appearance.width { + //This is a poorly constrained case, so we ignore the percentage + Auto => Auto, + Px(f) => Px(em*f/100.0), + Percent(*) | Mm(*) | Pt(*) => { + fail ~"failed inheriting widths, parent should only be Px or Auto" + } + } + } + } + } + } + } +} + impl @Box : ApplyStyleBoxMethods { fn apply_css_style() { top_down_traversal(self, inheritance_wrapper); diff --git a/src/test/compute_height_width.html b/src/test/compute_height_width.html new file mode 100644 index 000000000000..0a34033eaa08 --- /dev/null +++ b/src/test/compute_height_width.html @@ -0,0 +1,13 @@ + + + + +
+
+
+
+
+
+
+
+ diff --git a/src/test/height_width.css b/src/test/height_width.css new file mode 100644 index 000000000000..8e5f58aca10e --- /dev/null +++ b/src/test/height_width.css @@ -0,0 +1,10 @@ +div {display : inline} +div div {width : 120px} +.start {background-color : gray; height : 500px} +.whole {background-color : red; height : 100%} +.half {background-color : rgb(250, 125, 0); height : 50%} +.quarter {background-color : yellow; height : 25%} +.eighth {background-color : green; height : 12.5%} +.sixteenth {background-color : blue; height : 6.25%} +.thirtysecond {background-color : purple; height : 3.125%} +