mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Allow floats to have specified heights
This commit is contained in:
parent
94e7a86b7e
commit
0c63dda290
6 changed files with 73 additions and 12 deletions
|
@ -267,7 +267,7 @@ impl BlockFlowData {
|
||||||
// child[i-1].floats_out -> child[i].floats_in
|
// child[i-1].floats_out -> child[i].floats_in
|
||||||
// visit child[i]
|
// visit child[i]
|
||||||
// repeat until all children are visited.
|
// 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();
|
let mut float_ctx = self.common.floats_in.clone();
|
||||||
for BlockFlow(self).each_child |kid| {
|
for BlockFlow(self).each_child |kid| {
|
||||||
do kid.with_mut_base |child_node| {
|
do kid.with_mut_base |child_node| {
|
||||||
|
|
|
@ -161,6 +161,18 @@ impl BoxGenerator {
|
||||||
assert!(block.box.is_none());
|
assert!(block.box.is_none());
|
||||||
block.box = Some(new_box);
|
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()),
|
_ => 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
|
// Inlines that are children of blocks create new flows if their
|
||||||
// previous sibling was a block.
|
// previous sibling was a block.
|
||||||
(CSSDisplayInline, BlockFlow(*), Some(BlockFlow(*))) |
|
(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)
|
self.create_child_generator(node, parent_generator, Flow_Inline)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ impl FloatFlowData {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assign_widths_float(@mut self, _: &LayoutContext) {
|
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.size.width is set by parent even though we don't know
|
||||||
// position.origin yet.
|
// position.origin yet.
|
||||||
let mut remaining_width = self.common.position.size.width;
|
let mut remaining_width = self.common.position.size.width;
|
||||||
|
@ -117,13 +117,13 @@ impl FloatFlowData {
|
||||||
|
|
||||||
let width = MaybeAuto::from_width(style.width(),
|
let width = MaybeAuto::from_width(style.width(),
|
||||||
remaining_width).spec_or_default(shrink_to_fit);
|
remaining_width).spec_or_default(shrink_to_fit);
|
||||||
|
debug!("assign_widths_float -- width: %?", width);
|
||||||
|
|
||||||
model.margin.top = margin_top;
|
model.margin.top = margin_top;
|
||||||
model.margin.right = margin_right;
|
model.margin.right = margin_right;
|
||||||
model.margin.bottom = margin_bottom;
|
model.margin.bottom = margin_bottom;
|
||||||
model.margin.left = margin_left;
|
model.margin.left = margin_left;
|
||||||
|
|
||||||
self.common.position.size.width = width;
|
|
||||||
x_offset = model.offset();
|
x_offset = model.offset();
|
||||||
remaining_width = width;
|
remaining_width = width;
|
||||||
}
|
}
|
||||||
|
@ -138,6 +138,8 @@ impl FloatFlowData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.common.position.size.width = remaining_width;
|
||||||
|
|
||||||
for FloatFlow(self).each_child |kid| {
|
for FloatFlow(self).each_child |kid| {
|
||||||
//assert!(kid.starts_block_flow() || kid.starts_inline_flow());
|
//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);
|
let mut noncontent_height = Au(0);
|
||||||
self.box.map(|&box| {
|
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 {
|
let info = PlacementInfo {
|
||||||
width: self.common.position.size.width,
|
width: self.common.position.size.width,
|
||||||
height: self.common.position.size.height,
|
height: height,
|
||||||
ceiling: Au(0),
|
ceiling: Au(0),
|
||||||
max_width: self.containing_width,
|
max_width: self.containing_width,
|
||||||
f_type: FloatLeft,
|
f_type: FloatLeft,
|
||||||
|
|
|
@ -55,7 +55,7 @@ impl FloatContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[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 {
|
match *self {
|
||||||
Invalid => fail!("Float context no longer available"),
|
Invalid => fail!("Float context no longer available"),
|
||||||
Valid(ref mut base) => callback(base)
|
Valid(ref mut base) => callback(base)
|
||||||
|
@ -72,7 +72,7 @@ impl FloatContext {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn translate(&mut self, trans: Point2D<Au>) -> FloatContext {
|
pub fn translate(&mut self, trans: Point2D<Au>) -> FloatContext {
|
||||||
do self.with_base |base| {
|
do self.with_mut_base |base| {
|
||||||
base.translate(trans);
|
base.translate(trans);
|
||||||
}
|
}
|
||||||
replace(self, Invalid)
|
replace(self, Invalid)
|
||||||
|
@ -87,11 +87,18 @@ impl FloatContext {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn add_float(&mut self, info: &PlacementInfo) -> FloatContext{
|
pub fn add_float(&mut self, info: &PlacementInfo) -> FloatContext{
|
||||||
do self.with_base |base| {
|
do self.with_mut_base |base| {
|
||||||
base.add_float(info);
|
base.add_float(info);
|
||||||
}
|
}
|
||||||
replace(self, Invalid)
|
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{
|
impl FloatContextBase{
|
||||||
|
@ -110,6 +117,15 @@ impl FloatContextBase{
|
||||||
self.offset += trans;
|
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,
|
/// 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
|
/// 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
|
/// is the x-coordinate beyond which floats have no effect (generally
|
||||||
|
|
|
@ -420,11 +420,17 @@ impl<'self> FlowContext {
|
||||||
None => ~"BlockFlow",
|
None => ~"BlockFlow",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
FloatFlow(float) => {
|
||||||
|
match float.box {
|
||||||
|
Some(box) => fmt!("FloatFlow(box=b%d)", box.id()),
|
||||||
|
None => ~"FloatFlow",
|
||||||
|
}
|
||||||
|
},
|
||||||
_ => ~"(Unknown flow)"
|
_ => ~"(Unknown flow)"
|
||||||
};
|
};
|
||||||
|
|
||||||
do self.with_base |base| {
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ use newcss::units::{Em, Pt, Px};
|
||||||
use newcss::values::{CSSBorderWidth, CSSBorderWidthLength, CSSBorderWidthMedium};
|
use newcss::values::{CSSBorderWidth, CSSBorderWidthLength, CSSBorderWidthMedium};
|
||||||
use newcss::values::{CSSBorderWidthThick, CSSBorderWidthThin};
|
use newcss::values::{CSSBorderWidthThick, CSSBorderWidthThin};
|
||||||
use newcss::values::{CSSWidth, CSSWidthLength, CSSWidthPercentage, CSSWidthAuto};
|
use newcss::values::{CSSWidth, CSSWidthLength, CSSWidthPercentage, CSSWidthAuto};
|
||||||
|
use newcss::values::{CSSHeight, CSSHeightLength, CSSHeightPercentage, CSSHeightAuto};
|
||||||
use newcss::values::{CSSMargin, CSSMarginLength, CSSMarginPercentage, CSSMarginAuto};
|
use newcss::values::{CSSMargin, CSSMarginLength, CSSMarginPercentage, CSSMarginAuto};
|
||||||
use newcss::values::{CSSPadding, CSSPaddingLength, CSSPaddingPercentage};
|
use newcss::values::{CSSPadding, CSSPaddingLength, CSSPaddingPercentage};
|
||||||
/// Encapsulates the borders, padding, and margins, which we collectively call the "box model".
|
/// 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{
|
pub fn spec_or_default(&self, default: Au) -> Au{
|
||||||
match *self{
|
match *self{
|
||||||
Auto => default,
|
Auto => default,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue