aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Atkinson <eatkinson@mozilla.com>2013-06-24 09:37:09 -0700
committerEric Atkinson <eatkinson@mozilla.com>2013-06-24 16:07:02 -0700
commit0c63dda2904a77116218b07532d2f80cb159ae7d (patch)
tree000c22b26ecc114f360c62c820c7e08884929bb7
parent94e7a86b7efe8b8c8d8ede0f3104c3893ff9a37a (diff)
downloadservo-0c63dda2904a77116218b07532d2f80cb159ae7d.tar.gz
servo-0c63dda2904a77116218b07532d2f80cb159ae7d.zip
Allow floats to have specified heights
-rw-r--r--src/components/main/layout/block.rs2
-rw-r--r--src/components/main/layout/box_builder.rs16
-rw-r--r--src/components/main/layout/float.rs25
-rw-r--r--src/components/main/layout/float_context.rs22
-rw-r--r--src/components/main/layout/flow.rs8
-rw-r--r--src/components/main/layout/model.rs12
6 files changed, 73 insertions, 12 deletions
diff --git a/src/components/main/layout/block.rs b/src/components/main/layout/block.rs
index 175ee60073e..656d17530be 100644
--- a/src/components/main/layout/block.rs
+++ b/src/components/main/layout/block.rs
@@ -267,7 +267,7 @@ impl BlockFlowData {
// child[i-1].floats_out -> child[i].floats_in
// visit child[i]
// repeat until all children are visited.
- // last_child.floats_out -> self.floats_out (done at the end of this function)
+ // last_child.floats_out -> self.floats_out (done at the end of this method)
let mut float_ctx = self.common.floats_in.clone();
for BlockFlow(self).each_child |kid| {
do kid.with_mut_base |child_node| {
diff --git a/src/components/main/layout/box_builder.rs b/src/components/main/layout/box_builder.rs
index 6ec2092af99..0e478ba2654 100644
--- a/src/components/main/layout/box_builder.rs
+++ b/src/components/main/layout/box_builder.rs
@@ -161,6 +161,18 @@ impl BoxGenerator {
assert!(block.box.is_none());
block.box = Some(new_box);
},
+ FloatFlow(float) => {
+ debug!("BoxGenerator[f%d]: point b", float.common.id);
+ let new_box = self.make_box(ctx, box_type, node, self.flow, builder);
+
+ debug!("BoxGenerator[f%d]: attaching box[b%d] to float flow (node: %s)",
+ float.common.id,
+ new_box.id(),
+ node.debug_str());
+
+ assert!(float.box.is_none());
+ float.box = Some(new_box);
+ },
_ => warn!("push_node() not implemented for flow f%d", self.flow.id()),
}
}
@@ -384,7 +396,9 @@ pub impl LayoutTreeBuilder {
// Inlines that are children of blocks create new flows if their
// previous sibling was a block.
(CSSDisplayInline, BlockFlow(*), Some(BlockFlow(*))) |
- (CSSDisplayInlineBlock, BlockFlow(*), Some(BlockFlow(*))) => {
+ (CSSDisplayInlineBlock, BlockFlow(*), Some(BlockFlow(*))) |
+ (CSSDisplayInline, BlockFlow(*), Some(FloatFlow(*))) |
+ (CSSDisplayInlineBlock, BlockFlow(*), Some(FloatFlow(*))) => {
self.create_child_generator(node, parent_generator, Flow_Inline)
}
diff --git a/src/components/main/layout/float.rs b/src/components/main/layout/float.rs
index 5bd25784424..c63c21dbf25 100644
--- a/src/components/main/layout/float.rs
+++ b/src/components/main/layout/float.rs
@@ -85,7 +85,7 @@ impl FloatFlowData {
}
pub fn assign_widths_float(@mut self, _: &LayoutContext) {
- debug!("assign_widths_block: assigning width for flow %?", self.common.id);
+ debug!("assign_widths_float: assigning width for flow %?", self.common.id);
// position.size.width is set by parent even though we don't know
// position.origin yet.
let mut remaining_width = self.common.position.size.width;
@@ -117,13 +117,13 @@ impl FloatFlowData {
let width = MaybeAuto::from_width(style.width(),
remaining_width).spec_or_default(shrink_to_fit);
+ debug!("assign_widths_float -- width: %?", width);
model.margin.top = margin_top;
model.margin.right = margin_right;
model.margin.bottom = margin_bottom;
model.margin.left = margin_left;
- self.common.position.size.width = width;
x_offset = model.offset();
remaining_width = width;
}
@@ -138,6 +138,8 @@ impl FloatFlowData {
}
}
+ self.common.position.size.width = remaining_width;
+
for FloatFlow(self).each_child |kid| {
//assert!(kid.starts_block_flow() || kid.starts_inline_flow());
@@ -170,7 +172,7 @@ impl FloatFlowData {
}
}
- let height = cur_y - top_offset;
+ let mut height = cur_y - top_offset;
let mut noncontent_height = Au(0);
self.box.map(|&box| {
@@ -186,12 +188,23 @@ impl FloatFlowData {
}
});
- //TODO(eatkinson): compute heights using the 'height' property.
- self.common.position.size.height = height + noncontent_height;
+
+ //TODO(eatkinson): compute heights properly using the 'height' property.
+ for self.box.each |&box| {
+
+ let height_prop =
+ MaybeAuto::from_height(box.style().height(), Au(0)).spec_or_default(Au(0));
+
+ height = geometry::max(height, height_prop) + noncontent_height;
+ debug!("assign_height_float -- height: %?", height);
+ do box.with_mut_base |base| {
+ base.position.size.height = height;
+ }
+ }
let info = PlacementInfo {
width: self.common.position.size.width,
- height: self.common.position.size.height,
+ height: height,
ceiling: Au(0),
max_width: self.containing_width,
f_type: FloatLeft,
diff --git a/src/components/main/layout/float_context.rs b/src/components/main/layout/float_context.rs
index dd35b4f91cb..0d026ecc942 100644
--- a/src/components/main/layout/float_context.rs
+++ b/src/components/main/layout/float_context.rs
@@ -55,7 +55,7 @@ impl FloatContext {
}
#[inline(always)]
- fn with_base<R>(&mut self, callback: &fn(&mut FloatContextBase) -> R) -> R {
+ fn with_mut_base<R>(&mut self, callback: &fn(&mut FloatContextBase) -> R) -> R {
match *self {
Invalid => fail!("Float context no longer available"),
Valid(ref mut base) => callback(base)
@@ -72,7 +72,7 @@ impl FloatContext {
#[inline(always)]
pub fn translate(&mut self, trans: Point2D<Au>) -> FloatContext {
- do self.with_base |base| {
+ do self.with_mut_base |base| {
base.translate(trans);
}
replace(self, Invalid)
@@ -87,11 +87,18 @@ impl FloatContext {
#[inline(always)]
pub fn add_float(&mut self, info: &PlacementInfo) -> FloatContext{
- do self.with_base |base| {
+ do self.with_mut_base |base| {
base.add_float(info);
}
replace(self, Invalid)
}
+
+ #[inline(always)]
+ pub fn last_float_pos(&mut self) -> Point2D<Au> {
+ do self.with_base |base| {
+ base.last_float_pos()
+ }
+ }
}
impl FloatContextBase{
@@ -110,6 +117,15 @@ impl FloatContextBase{
self.offset += trans;
}
+ fn last_float_pos(&self) -> Point2D<Au> {
+ assert!(self.floats_used > 0, "Error: tried to access FloatContext with no floats in it");
+
+ match self.float_data[self.floats_used - 1] {
+ None => fail!("FloatContext error: floats should never be None here"),
+ Some(float) => float.bounds.origin
+ }
+ }
+
/// Returns a rectangle that encloses the region from top to top + height,
/// with width small enough that it doesn't collide with any floats. max_x
/// is the x-coordinate beyond which floats have no effect (generally
diff --git a/src/components/main/layout/flow.rs b/src/components/main/layout/flow.rs
index 0d60eb117a6..e2c14ce22e9 100644
--- a/src/components/main/layout/flow.rs
+++ b/src/components/main/layout/flow.rs
@@ -420,11 +420,17 @@ impl<'self> FlowContext {
None => ~"BlockFlow",
}
},
+ FloatFlow(float) => {
+ match float.box {
+ Some(box) => fmt!("FloatFlow(box=b%d)", box.id()),
+ None => ~"FloatFlow",
+ }
+ },
_ => ~"(Unknown flow)"
};
do self.with_base |base| {
- fmt!("f%? %? floats %?", base.id, repr, base.num_floats)
+ fmt!("f%? %? floats %? size %?", base.id, repr, base.num_floats, base.position)
}
}
}
diff --git a/src/components/main/layout/model.rs b/src/components/main/layout/model.rs
index 44bf3417a89..bd465db83b9 100644
--- a/src/components/main/layout/model.rs
+++ b/src/components/main/layout/model.rs
@@ -20,6 +20,7 @@ use newcss::units::{Em, Pt, Px};
use newcss::values::{CSSBorderWidth, CSSBorderWidthLength, CSSBorderWidthMedium};
use newcss::values::{CSSBorderWidthThick, CSSBorderWidthThin};
use newcss::values::{CSSWidth, CSSWidthLength, CSSWidthPercentage, CSSWidthAuto};
+use newcss::values::{CSSHeight, CSSHeightLength, CSSHeightPercentage, CSSHeightAuto};
use newcss::values::{CSSMargin, CSSMarginLength, CSSMarginPercentage, CSSMarginAuto};
use newcss::values::{CSSPadding, CSSPaddingLength, CSSPaddingPercentage};
/// Encapsulates the borders, padding, and margins, which we collectively call the "box model".
@@ -61,6 +62,17 @@ impl MaybeAuto{
}
}
+ pub fn from_height(height: CSSHeight, cb_height: Au) -> 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)),
+ }
+ }
+
pub fn spec_or_default(&self, default: Au) -> Au{
match *self{
Auto => default,