diff options
author | Bruno de Oliveira Abinader <bruno.d@partner.samsung.com> | 2013-11-29 10:47:30 -0400 |
---|---|---|
committer | Bruno de Oliveira Abinader <bruno.d@partner.samsung.com> | 2013-12-03 14:36:31 -0400 |
commit | ac45d70a4ace71380358fdec918e1c4438ae2e43 (patch) | |
tree | dbe38879889fd0e53886b87c26b9c69d66cb1a27 /src | |
parent | a0c6075b4d766da8f0414405f9e1f76c8c90acc4 (diff) | |
download | servo-ac45d70a4ace71380358fdec918e1c4438ae2e43.tar.gz servo-ac45d70a4ace71380358fdec918e1c4438ae2e43.zip |
Remove 'FloatFlow'
Removes 'FloatFlow' in favor of FloatBlockFlow, which is cointained
inside BlockFlow in a 'has-a' relationship. This avoids a bunch of
duplicated code.
This patch is for:
https://github.com/mozilla/servo/issues/1281
Diffstat (limited to 'src')
-rw-r--r-- | src/components/main/layout/block.rs | 378 | ||||
-rw-r--r-- | src/components/main/layout/construct.rs | 7 | ||||
-rw-r--r-- | src/components/main/layout/float.rs | 333 | ||||
-rw-r--r-- | src/components/main/layout/flow.rs | 14 | ||||
-rwxr-xr-x | src/components/main/servo.rc | 1 |
5 files changed, 321 insertions, 412 deletions
diff --git a/src/components/main/layout/block.rs b/src/components/main/layout/block.rs index 995c35397d4..9890666a924 100644 --- a/src/components/main/layout/block.rs +++ b/src/components/main/layout/block.rs @@ -10,7 +10,7 @@ use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData}; use layout::flow::{BlockFlowClass, FlowClass, Flow, FlowData, ImmutableFlowUtils}; use layout::flow; use layout::model::{MaybeAuto, Specified, Auto, specified_or_none, specified}; -use layout::float_context::{FloatContext, Invalid}; +use layout::float_context::{FloatContext, PlacementInfo, Invalid, FloatType}; use std::cell::Cell; use geom::point::Point2D; @@ -20,6 +20,34 @@ use gfx::display_list::DisplayList; use servo_util::geometry::{Au, to_frac_px}; use servo_util::geometry; +pub struct FloatedBlockInfo { + containing_width: Au, + + /// Offset relative to where the parent tried to position this flow + rel_pos: Point2D<Au>, + + /// Index into the box list for inline floats + index: Option<uint>, + + /// Number of floated children + floated_children: uint, + + /// Left or right? + float_type: FloatType +} + +impl FloatedBlockInfo { + pub fn new(float_type: FloatType) -> FloatedBlockInfo { + FloatedBlockInfo { + containing_width: Au(0), + rel_pos: Point2D(Au(0), Au(0)), + index: None, + floated_children: 0, + float_type: float_type + } + } +} + pub struct BlockFlow { /// Data common to all flows. base: FlowData, @@ -28,7 +56,10 @@ pub struct BlockFlow { box: Option<@RenderBox>, /// Whether this block flow is the root flow. - is_root: bool + is_root: bool, + + // Additional floating flow members. + float: Option<~FloatedBlockInfo> } impl BlockFlow { @@ -36,7 +67,8 @@ impl BlockFlow { BlockFlow { base: base, box: None, - is_root: false + is_root: false, + float: None } } @@ -44,7 +76,17 @@ impl BlockFlow { BlockFlow { base: base, box: Some(box), - is_root: false + is_root: false, + float: None + } + } + + pub fn float_from_box(base: FlowData, float_type: FloatType, box: @RenderBox) -> BlockFlow { + BlockFlow { + base: base, + box: Some(box), + is_root: false, + float: Some(~FloatedBlockInfo::new(float_type)) } } @@ -52,15 +94,30 @@ impl BlockFlow { BlockFlow { base: base, box: None, - is_root: true + is_root: true, + float: None + } + } + + pub fn new_float(base: FlowData, float_type: FloatType) -> BlockFlow { + BlockFlow { + base: base, + box: None, + is_root: false, + float: Some(~FloatedBlockInfo::new(float_type)) } } + pub fn is_float(&self) -> bool { + self.float.is_some() + } + pub fn teardown(&mut self) { for box in self.box.iter() { box.teardown(); } self.box = None; + self.float = None; } /// Computes left and right margins and width based on CSS 2.1 section 10.3.3. @@ -115,6 +172,63 @@ impl BlockFlow { (width_Au, left_margin_Au, right_margin_Au) } + fn compute_block_margins(&self, box: @RenderBox, remaining_width: Au, available_width: Au) -> (Au, Au, Au) { + let base = box.base(); + let style = base.style(); + + let (width, maybe_margin_left, maybe_margin_right) = + (MaybeAuto::from_style(style.Box.width, remaining_width), + MaybeAuto::from_style(style.Margin.margin_left, remaining_width), + MaybeAuto::from_style(style.Margin.margin_right, remaining_width)); + + let (width, margin_left, margin_right) = self.compute_horiz(width, + maybe_margin_left, + maybe_margin_right, + available_width); + + // If the tentative used width is greater than 'max-width', width should be recalculated, + // but this time using the computed value of 'max-width' as the computed value for 'width'. + let (width, margin_left, margin_right) = { + match specified_or_none(style.Box.max_width, remaining_width) { + Some(value) if value < width => self.compute_horiz(Specified(value), + maybe_margin_left, + maybe_margin_right, + available_width), + _ => (width, margin_left, margin_right) + } + }; + + // If the resulting width is smaller than 'min-width', width should be recalculated, + // but this time using the value of 'min-width' as the computed value for 'width'. + let (width, margin_left, margin_right) = { + let computed_min_width = specified(style.Box.min_width, remaining_width); + if computed_min_width > width { + self.compute_horiz(Specified(computed_min_width), + maybe_margin_left, + maybe_margin_right, + available_width) + } else { + (width, margin_left, margin_right) + } + }; + + return (width, margin_left, margin_right); + } + + fn compute_float_margins(&self, box: @RenderBox, remaining_width: Au) -> (Au, Au, Au) { + let style = box.base().style(); + let margin_left = MaybeAuto::from_style(style.Margin.margin_left, + remaining_width).specified_or_zero(); + let margin_right = MaybeAuto::from_style(style.Margin.margin_right, + remaining_width).specified_or_zero(); + let shrink_to_fit = geometry::min(self.base.pref_width, + geometry::max(self.base.min_width, remaining_width)); + let width = MaybeAuto::from_style(style.Box.width, + remaining_width).specified_or_default(shrink_to_fit); + debug!("assign_widths_float -- width: {}", width); + return (width, margin_left, margin_right); + } + // inline(always) because this is only ever called by in-order or non-in-order top-level // methods #[inline(always)] @@ -252,12 +366,104 @@ impl BlockFlow { } } + fn assign_height_float_inorder(&mut self) { + // assign_height_float was already called by the traversal function + // so this is well-defined + + let mut height = Au(0); + let mut clearance = Au(0); + let mut full_noncontent_width = Au(0); + let mut margin_height = Au(0); + + for box in self.box.iter() { + let base = box.base(); + height = base.position.borrow().ptr.size.height; + clearance = match base.clear() { + None => Au(0), + Some(clear) => self.base.floats_in.clearance(clear), + }; + + let noncontent_width = base.padding.left + base.padding.right + base.border.left + + base.border.right; + + full_noncontent_width = noncontent_width + base.margin.left + base.margin.right; + margin_height = base.margin.top + base.margin.bottom; + } + + let info = PlacementInfo { + width: self.base.position.size.width + full_noncontent_width, + height: height + margin_height, + ceiling: clearance, + max_width: self.float.get_ref().containing_width, + f_type: self.float.get_ref().float_type, + }; + + // Place the float and return the FloatContext back to the parent flow. + // After, grab the position and use that to set our position. + self.base.floats_out = self.base.floats_in.add_float(&info); + self.float.get_mut_ref().rel_pos = self.base.floats_out.last_float_pos(); + } + + fn assign_height_float(&mut self, ctx: &mut LayoutContext) { + // Now that we've determined our height, propagate that out. + let has_inorder_children = self.base.num_floats > 0; + if has_inorder_children { + let mut float_ctx = FloatContext::new(self.float.get_ref().floated_children); + for kid in self.base.child_iter() { + flow::mut_base(*kid).floats_in = float_ctx.clone(); + kid.assign_height_inorder(ctx); + float_ctx = flow::mut_base(*kid).floats_out.clone(); + } + } + let mut cur_y = Au(0); + let mut top_offset = Au(0); + + for &box in self.box.iter() { + let base = box.base(); + top_offset = base.margin.top + base.border.top + base.padding.top; + cur_y = cur_y + top_offset; + } + + for kid in self.base.child_iter() { + let child_base = flow::mut_base(*kid); + child_base.position.origin.y = cur_y; + cur_y = cur_y + child_base.position.size.height; + } + + let mut height = cur_y - top_offset; + + let mut noncontent_height; + let box = self.box.as_ref().unwrap(); + let base = box.base(); + let mut position_ref = base.position.mutate(); + let position = &mut position_ref.ptr; + + // The associated box is the border box of this flow. + position.origin.y = base.margin.top; + + noncontent_height = base.padding.top + base.padding.bottom + base.border.top + + base.border.bottom; + + //TODO(eatkinson): compute heights properly using the 'height' property. + let height_prop = MaybeAuto::from_style(base.style().Box.height, + Au::new(0)).specified_or_zero(); + + height = geometry::max(height, height_prop) + noncontent_height; + debug!("assign_height_float -- height: {}", height); + + position.size.height = height; + } + pub fn build_display_list_block<E:ExtraDisplayListData>( &mut self, builder: &DisplayListBuilder, dirty: &Rect<Au>, list: &Cell<DisplayList<E>>) -> bool { + if self.is_float() { + return self.build_display_list_float(builder, dirty, list); + } + if self.base.node.is_iframe_element() { let x = self.base.abs_position.x + do self.box.map_default(Au::new(0)) |box| { let base = box.base(); @@ -302,6 +508,39 @@ impl BlockFlow { false } + + pub fn build_display_list_float<E:ExtraDisplayListData>(&mut self, + builder: &DisplayListBuilder, + dirty: &Rect<Au>, + list: &Cell<DisplayList<E>>) + -> bool { + //TODO: implement iframe size messaging + if self.base.node.is_iframe_element() { + error!("float iframe size messaging not implemented yet"); + } + let abs_rect = Rect(self.base.abs_position, self.base.position.size); + if !abs_rect.intersects(dirty) { + return true; + } + + + let offset = self.base.abs_position + self.float.get_ref().rel_pos; + // add box that starts block context + for box in self.box.iter() { + box.build_display_list(builder, dirty, &offset, list) + } + + + // TODO: handle any out-of-flow elements + + // go deeper into the flow tree + for child in self.base.child_iter() { + let child_base = flow::mut_base(*child); + child_base.abs_position = offset + child_base.position.origin; + } + + false + } } impl Flow for BlockFlow { @@ -334,10 +573,16 @@ impl Flow for BlockFlow { let child_base = flow::mut_base(*child_ctx); min_width = geometry::max(min_width, child_base.min_width); pref_width = geometry::max(pref_width, child_base.pref_width); - num_floats = num_floats + child_base.num_floats; } + if self.is_float() { + self.base.num_floats = 1; + self.float.get_mut_ref().floated_children = num_floats; + } else { + self.base.num_floats = num_floats; + } + /* if not an anonymous block context, add in block box's widths. these widths will not include child elements, just padding etc. */ for box in self.box.iter() { @@ -355,16 +600,20 @@ impl Flow for BlockFlow { self.base.min_width = min_width; self.base.pref_width = pref_width; - self.base.num_floats = num_floats; } - + /// Recursively (top-down) determines the actual width of child contexts and boxes. When called /// on this context, the context has had its width set by the parent context. /// /// Dual boxes consume some width first, and the remainder is assigned to all child (block) /// contexts. - fn assign_widths(&mut self, ctx: &mut LayoutContext) { - debug!("assign_widths_block: assigning width for flow {}", self.base.id); + fn assign_widths(&mut self, ctx: &mut LayoutContext) { + if self.is_float() { + debug!("assign_widths_float: assigning width for flow {}", self.base.id); + } else { + debug!("assign_widths_block: assigning width for flow {}", self.base.id); + } + if self.is_root { debug!("Setting root position"); self.base.position.origin = Au::zero_point(); @@ -377,12 +626,19 @@ impl Flow for BlockFlow { let mut remaining_width = self.base.position.size.width; let mut x_offset = Au::new(0); + if self.is_float() { + // Parent usually sets this, but floats are never inorder + self.base.is_inorder = false; + } + for &box in self.box.iter() { - let base = box.mut_base(); + let base = box.base(); + let mut_base = box.mut_base(); let style = base.style(); + let mut_position = &mut base.position.mutate().ptr; // Can compute padding here since we know containing block width. - base.compute_padding(style, remaining_width); + mut_base.compute_padding(style, remaining_width); // Margins are 0 right now so base.noncontent_width() is just borders + padding. let available_width = remaining_width - base.noncontent_width(); @@ -393,58 +649,38 @@ impl Flow for BlockFlow { let margin_bottom = MaybeAuto::from_style(style.Margin.margin_bottom, remaining_width).specified_or_zero(); - let (width, maybe_margin_left, maybe_margin_right) = - (MaybeAuto::from_style(style.Box.width, remaining_width), - MaybeAuto::from_style(style.Margin.margin_left, remaining_width), - MaybeAuto::from_style(style.Margin.margin_right, remaining_width)); - - let (width, margin_left, margin_right) = self.compute_horiz(width, - maybe_margin_left, - maybe_margin_right, - available_width); - - // If the tentative used width is greater than 'max-width', width should be recalculated, - // but this time using the computed value of 'max-width' as the computed value for 'width'. - let (width, margin_left, margin_right) = { - match specified_or_none(style.Box.max_width, remaining_width) { - Some(value) if value < width => self.compute_horiz(Specified(value), - maybe_margin_left, - maybe_margin_right, - available_width), - _ => (width, margin_left, margin_right) - } - }; - // If the resulting width is smaller than 'min-width', width should be recalculated, - // but this time using the value of 'min-width' as the computed value for 'width'. - let (width, margin_left, margin_right) = { - let computed_min_width = specified(style.Box.min_width, remaining_width); - if computed_min_width > width { - self.compute_horiz(Specified(computed_min_width), - maybe_margin_left, - maybe_margin_right, - available_width) - } else { - (width, margin_left, margin_right) - } + let (width, margin_left, margin_right) = if self.is_float() { + self.compute_float_margins(box, remaining_width) + } else { + self.compute_block_margins(box, remaining_width, available_width) }; - base.margin.top = margin_top; - base.margin.right = margin_right; - base.margin.bottom = margin_bottom; - base.margin.left = margin_left; + mut_base.margin.top = margin_top; + mut_base.margin.right = margin_right; + mut_base.margin.bottom = margin_bottom; + mut_base.margin.left = margin_left; x_offset = base.offset(); remaining_width = width; //The associated box is the border box of this flow - let position_ref = base.position.mutate(); - position_ref.ptr.origin.x = base.margin.left; + mut_position.origin.x = base.margin.left; + let padding_and_borders = base.padding.left + base.padding.right + base.border.left + base.border.right; - position_ref.ptr.size.width = remaining_width + padding_and_borders; + mut_position.size.width = remaining_width + padding_and_borders; } - let has_inorder_children = self.base.is_inorder || self.base.num_floats > 0; + if self.is_float() { + self.base.position.size.width = remaining_width; + } + + let has_inorder_children = if self.is_float() { + self.base.num_floats > 0 + } else { + self.base.is_inorder || self.base.num_floats > 0 + }; + for kid in self.base.child_iter() { assert!(kid.starts_block_flow() || kid.starts_inline_flow()); @@ -460,19 +696,29 @@ impl Flow for BlockFlow { } fn assign_height_inorder(&mut self, ctx: &mut LayoutContext) { - debug!("assign_height_inorder: assigning height for block {}", self.base.id); - self.assign_height_block_base(ctx, true); + if self.is_float() { + debug!("assign_height_inorder_float: assigning height for float {}", self.base.id); + self.assign_height_float_inorder(); + } else { + debug!("assign_height_inorder: assigning height for block {}", self.base.id); + self.assign_height_block_base(ctx, true); + } } fn assign_height(&mut self, ctx: &mut LayoutContext) { - debug!("assign_height: assigning height for block {}", self.base.id); - // This is the only case in which a block flow can start an inorder - // subtraversal. - if self.is_root && self.base.num_floats > 0 { - self.assign_height_inorder(ctx); - return; + if self.is_float() { + debug!("assign_height_float: assigning height for float {}", self.base.id); + self.assign_height_float(ctx); + } else { + debug!("assign_height: assigning height for block {}", self.base.id); + // This is the only case in which a block flow can start an inorder + // subtraversal. + if self.is_root && self.base.num_floats > 0 { + self.assign_height_inorder(ctx); + return; + } + self.assign_height_block_base(ctx, false); } - self.assign_height_block_base(ctx, false); } fn collapse_margins(&mut self, @@ -482,6 +728,12 @@ impl Flow for BlockFlow { top_offset: &mut Au, collapsing: &mut Au, collapsible: &mut Au) { + if self.is_float() { + // Margins between a floated box and any other box do not collapse. + *collapsing = Au::new(0); + return; + } + for &box in self.box.iter() { let base = box.base(); @@ -515,7 +767,7 @@ impl Flow for BlockFlow { if self.is_root { ~"BlockFlow(root)" } else { - let txt = ~"BlockFlow: "; + let txt = if self.is_float() { ~"FloatFlow: " } else { ~"BlockFlow: " }; txt.append(match self.box { Some(rb) => { rb.debug_str() diff --git a/src/components/main/layout/construct.rs b/src/components/main/layout/construct.rs index ea4f70af101..9341727e227 100644 --- a/src/components/main/layout/construct.rs +++ b/src/components/main/layout/construct.rs @@ -25,7 +25,6 @@ use layout::block::BlockFlow; use layout::box::{GenericRenderBox, ImageRenderBox, RenderBox, RenderBoxBase}; use layout::box::{UnscannedTextRenderBox}; use layout::context::LayoutContext; -use layout::float::FloatFlow; use layout::float_context::FloatType; use layout::flow::{Flow, FlowData, MutableFlowUtils}; use layout::inline::InlineFlow; @@ -360,13 +359,13 @@ impl<'self> FlowConstructor<'self> { flow } - /// Builds the flow for a node with `float: {left|right}`. This yields a `FloatFlow` with a - /// `BlockFlow` underneath it. + /// Builds the flow for a node with `float: {left|right}`. This yields a float `BlockFlow` with + /// a `BlockFlow` underneath it. fn build_flow_for_floated_block(&self, node: AbstractNode<LayoutView>, float_type: FloatType) -> ~Flow: { let base = FlowData::new(self.next_flow_id(), node); let box = self.build_box_for_node(node); - let mut flow = ~FloatFlow::from_box(base, float_type, box) as ~Flow:; + let mut flow = ~BlockFlow::float_from_box(base, float_type, box) as ~Flow:; self.build_children_of_block_flow(&mut flow, node); flow } diff --git a/src/components/main/layout/float.rs b/src/components/main/layout/float.rs deleted file mode 100644 index b6d123844b1..00000000000 --- a/src/components/main/layout/float.rs +++ /dev/null @@ -1,333 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -use layout::box::{RenderBox, RenderBoxUtils}; -use layout::context::LayoutContext; -use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData}; -use layout::flow::{FloatFlowClass, FlowClass, Flow, FlowData}; -use layout::flow; -use layout::model::{MaybeAuto}; -use layout::float_context::{FloatContext, PlacementInfo, FloatType}; - -use std::cell::Cell; -use geom::point::Point2D; -use geom::rect::Rect; -use gfx::display_list::DisplayList; -use servo_util::geometry::Au; -use servo_util::geometry; - -pub struct FloatFlow { - /// Data common to all flows. - base: FlowData, - - /// The associated render box. - box: Option<@RenderBox>, - - containing_width: Au, - - /// Offset relative to where the parent tried to position this flow - rel_pos: Point2D<Au>, - - /// Left or right? - float_type: FloatType, - - /// Index into the box list for inline floats - index: Option<uint>, - - /// Number of floated children - floated_children: uint, - -} - -impl FloatFlow { - pub fn new(base: FlowData, float_type: FloatType) -> FloatFlow { - FloatFlow { - base: base, - containing_width: Au(0), - box: None, - index: None, - float_type: float_type, - rel_pos: Point2D(Au(0), Au(0)), - floated_children: 0, - } - } - - pub fn from_box(base: FlowData, float_type: FloatType, box: @RenderBox) -> FloatFlow { - FloatFlow { - base: base, - containing_width: Au(0), - box: Some(box), - index: None, - float_type: float_type, - rel_pos: Point2D(Au(0), Au(0)), - floated_children: 0, - } - } - - pub fn teardown(&mut self) { - for box in self.box.iter() { - box.teardown(); - } - self.box = None; - self.index = None; - } - - pub fn build_display_list_float<E:ExtraDisplayListData>(&mut self, - builder: &DisplayListBuilder, - dirty: &Rect<Au>, - list: &Cell<DisplayList<E>>) - -> bool { - //TODO: implement iframe size messaging - if self.base.node.is_iframe_element() { - error!("float iframe size messaging not implemented yet"); - } - let abs_rect = Rect(self.base.abs_position, self.base.position.size); - if !abs_rect.intersects(dirty) { - return true; - } - - - let offset = self.base.abs_position + self.rel_pos; - // add box that starts block context - for box in self.box.iter() { - box.build_display_list(builder, dirty, &offset, list) - } - - - // TODO: handle any out-of-flow elements - - // go deeper into the flow tree - for child in self.base.child_iter() { - let child_base = flow::mut_base(*child); - child_base.abs_position = offset + child_base.position.origin; - } - - false - } - - fn debug_str(&self) -> ~str { - ~"FloatFlow" - } -} - -impl Flow for FloatFlow { - fn class(&self) -> FlowClass { - FloatFlowClass - } - - fn as_float<'a>(&'a mut self) -> &'a mut FloatFlow { - self - } - - fn bubble_widths(&mut self, _: &mut LayoutContext) { - let mut min_width = Au(0); - let mut pref_width = Au(0); - let mut num_floats = 0; - - for child_ctx in self.base.child_iter() { - //assert!(child_ctx.starts_block_flow() || child_ctx.starts_inline_flow()); - - let child_base = flow::mut_base(*child_ctx); - min_width = geometry::max(min_width, child_base.min_width); - pref_width = geometry::max(pref_width, child_base.pref_width); - num_floats = num_floats + child_base.num_floats; - } - - self.base.num_floats = 1; - self.floated_children = num_floats; - - for box in self.box.iter() { - { - box.mut_base().compute_borders(box.base().style()); - } - - let (this_minimum_width, this_preferred_width) = box.minimum_and_preferred_widths(); - min_width = min_width + this_minimum_width; - pref_width = pref_width + this_preferred_width; - } - - self.base.min_width = min_width; - self.base.pref_width = pref_width; - } - - fn assign_widths(&mut self, _: &mut LayoutContext) { - debug!("assign_widths_float: assigning width for flow {}", self.base.id); - // position.size.width is set by parent even though we don't know - // position.origin yet. - let mut remaining_width = self.base.position.size.width; - self.containing_width = remaining_width; - let mut x_offset = Au(0); - - // Parent usually sets this, but floats are never inorder - self.base.is_inorder = false; - - for &box in self.box.iter() { - let base = box.base(); - let mut_base = box.mut_base(); - let style = base.style(); - let mut position_ref = base.position.mutate(); - let position = &mut position_ref.ptr; - - // Can compute padding here since we know containing block width. - mut_base.compute_padding(style, remaining_width); - - // Margins for floats are 0 if auto. - let margin_top = MaybeAuto::from_style(style.Margin.margin_top, - remaining_width).specified_or_zero(); - let margin_bottom = MaybeAuto::from_style(style.Margin.margin_bottom, - remaining_width).specified_or_zero(); - let margin_left = MaybeAuto::from_style(style.Margin.margin_left, - remaining_width).specified_or_zero(); - let margin_right = MaybeAuto::from_style(style.Margin.margin_right, - remaining_width).specified_or_zero(); - - - let shrink_to_fit = geometry::min(self.base.pref_width, - geometry::max(self.base.min_width, remaining_width)); - - - let width = MaybeAuto::from_style(style.Box.width, - remaining_width).specified_or_default(shrink_to_fit); - debug!("assign_widths_float -- width: {}", width); - - mut_base.margin.top = margin_top; - mut_base.margin.right = margin_right; - mut_base.margin.bottom = margin_bottom; - mut_base.margin.left = margin_left; - - x_offset = base.offset(); - remaining_width = width; - - // The associated box is the border box of this flow. - position.origin.x = base.margin.left; - - let padding_and_borders = base.padding.left + base.padding.right + - base.border.left + base.border.right; - position.size.width = remaining_width + padding_and_borders; - } - - self.base.position.size.width = remaining_width; - - let has_inorder_children = self.base.num_floats > 0; - for kid in self.base.child_iter() { - //assert!(kid.starts_block_flow() || kid.starts_inline_flow()); - - let child_base = flow::mut_base(*kid); - child_base.position.origin.x = x_offset; - child_base.position.size.width = remaining_width; - child_base.is_inorder = has_inorder_children; - - if !child_base.is_inorder { - child_base.floats_in = FloatContext::new(0); - } - } - } - - fn assign_height_inorder(&mut self, _: &mut LayoutContext) { - debug!("assign_height_inorder_float: assigning height for float {}", self.base.id); - // assign_height_float was already called by the traversal function - // so this is well-defined - - let mut height = Au(0); - let mut clearance = Au(0); - let mut full_noncontent_width = Au(0); - let mut margin_height = Au(0); - - for box in self.box.iter() { - let base = box.base(); - height = base.position.borrow().ptr.size.height; - clearance = match base.clear() { - None => Au(0), - Some(clear) => self.base.floats_in.clearance(clear), - }; - - let noncontent_width = base.padding.left + base.padding.right + base.border.left + - base.border.right; - - full_noncontent_width = noncontent_width + base.margin.left + base.margin.right; - margin_height = base.margin.top + base.margin.bottom; - } - - let info = PlacementInfo { - width: self.base.position.size.width + full_noncontent_width, - height: height + margin_height, - ceiling: clearance, - max_width: self.containing_width, - f_type: self.float_type, - }; - - // Place the float and return the FloatContext back to the parent flow. - // After, grab the position and use that to set our position. - self.base.floats_out = self.base.floats_in.add_float(&info); - self.rel_pos = self.base.floats_out.last_float_pos(); - } - - fn assign_height(&mut self, ctx: &mut LayoutContext) { - // Now that we've determined our height, propagate that out. - let has_inorder_children = self.base.num_floats > 0; - if has_inorder_children { - let mut float_ctx = FloatContext::new(self.floated_children); - for kid in self.base.child_iter() { - flow::mut_base(*kid).floats_in = float_ctx.clone(); - kid.assign_height_inorder(ctx); - float_ctx = flow::mut_base(*kid).floats_out.clone(); - } - } - debug!("assign_height_float: assigning height for float {}", self.base.id); - let mut cur_y = Au(0); - let mut top_offset = Au(0); - - for &box in self.box.iter() { - let base = box.base(); - top_offset = base.margin.top + base.border.top + base.padding.top; - cur_y = cur_y + top_offset; - } - - for kid in self.base.child_iter() { - let child_base = flow::mut_base(*kid); - child_base.position.origin.y = cur_y; - cur_y = cur_y + child_base.position.size.height; - } - - let mut height = cur_y - top_offset; - - let mut noncontent_height; - let box = self.box.as_ref().unwrap(); - let base = box.base(); - let mut position_ref = base.position.mutate(); - let position = &mut position_ref.ptr; - - // The associated box is the border box of this flow. - position.origin.y = base.margin.top; - - noncontent_height = base.padding.top + base.padding.bottom + base.border.top + - base.border.bottom; - - //TODO(eatkinson): compute heights properly using the 'height' property. - let height_prop = MaybeAuto::from_style(base.style().Box.height, - Au::new(0)).specified_or_zero(); - - height = geometry::max(height, height_prop) + noncontent_height; - debug!("assign_height_float -- height: {}", height); - - position.size.height = height; - - } - - fn collapse_margins(&mut self, - _: bool, - _: &mut bool, - _: &mut Au, - _: &mut Au, - collapsing: &mut Au, - _: &mut Au) { - // Margins between a floated box and any other box do not collapse. - *collapsing = Au::new(0); - } - - fn debug_str(&self) -> ~str { - ~"FloatFlow" - } -} - diff --git a/src/components/main/layout/flow.rs b/src/components/main/layout/flow.rs index 2ad37fa0d82..ecf6d34e47d 100644 --- a/src/components/main/layout/flow.rs +++ b/src/components/main/layout/flow.rs @@ -29,7 +29,6 @@ use css::node_style::StyledNode; use layout::block::BlockFlow; use layout::box::RenderBox; use layout::context::LayoutContext; -use layout::float::FloatFlow; use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData}; use layout::float_context::{FloatContext, Invalid}; use layout::incremental::RestyleDamage; @@ -74,11 +73,6 @@ pub trait Flow { fail!("called as_inline() on a non-inline flow") } - /// If this is a float flow, returns the underlying object. Fails otherwise. - fn as_float<'a>(&'a mut self) -> &'a mut FloatFlow { - fail!("called as_float() on a non-float flow") - } - // Main methods /// Pass 1 of reflow: computes minimum and preferred widths. @@ -217,7 +211,6 @@ pub trait MutableFlowUtils { pub enum FlowClass { AbsoluteFlowClass, BlockFlowClass, - FloatFlowClass, InlineBlockFlowClass, InlineFlowClass, TableFlowClass, @@ -395,7 +388,7 @@ impl<'self> ImmutableFlowUtils for &'self Flow { /// Returns true if this flow is a block or a float flow. fn is_block_like(self) -> bool { match self.class() { - BlockFlowClass | FloatFlowClass => true, + BlockFlowClass => true, AbsoluteFlowClass | InlineBlockFlowClass | InlineFlowClass | TableFlowClass => false, } } @@ -408,7 +401,7 @@ impl<'self> ImmutableFlowUtils for &'self Flow { /// Returns true if this flow is a block flow, an inline-block flow, or a float flow. fn starts_block_flow(self) -> bool { match self.class() { - BlockFlowClass | InlineBlockFlowClass | FloatFlowClass => true, + BlockFlowClass | InlineBlockFlowClass => true, AbsoluteFlowClass | InlineFlowClass | TableFlowClass => false, } } @@ -417,7 +410,7 @@ impl<'self> ImmutableFlowUtils for &'self Flow { fn starts_inline_flow(self) -> bool { match self.class() { InlineFlowClass => true, - AbsoluteFlowClass | BlockFlowClass | FloatFlowClass | InlineBlockFlowClass | + AbsoluteFlowClass | BlockFlowClass | InlineBlockFlowClass | TableFlowClass => false, } } @@ -525,7 +518,6 @@ impl<'self> MutableFlowUtils for &'self mut Flow { match self.class() { BlockFlowClass => self.as_block().build_display_list_block(builder, dirty, list), InlineFlowClass => self.as_inline().build_display_list_inline(builder, dirty, list), - FloatFlowClass => self.as_float().build_display_list_float(builder, dirty, list), _ => fail!("Tried to build_display_list_recurse of flow: {:?}", self), }; diff --git a/src/components/main/servo.rc b/src/components/main/servo.rc index 227bae8ab2a..f286368b332 100755 --- a/src/components/main/servo.rc +++ b/src/components/main/servo.rc @@ -81,7 +81,6 @@ pub mod layout { pub mod context; pub mod display_list_builder; pub mod float_context; - pub mod float; pub mod flow; pub mod layout_task; pub mod inline; |