auto merge of #2497 : bjz/servo/rename-box-type, r=pcwalton

I tried to make sure to keep 'box' where it made sense, and alter comments so they still make sense.

r? @pcwalton
This commit is contained in:
bors-servo 2014-05-28 20:34:06 -04:00
commit 547ad2dc48
16 changed files with 1159 additions and 1158 deletions

View file

@ -12,13 +12,13 @@
//! //!
//! CB: Containing Block of the current flow. //! CB: Containing Block of the current flow.
use layout::box_::{Box, ImageBox, ScannedTextBox};
use layout::construct::FlowConstructor; use layout::construct::FlowConstructor;
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::floats::{ClearBoth, ClearLeft, ClearRight, FloatKind, Floats, PlacementInfo}; use layout::floats::{ClearBoth, ClearLeft, ClearRight, FloatKind, Floats, PlacementInfo};
use layout::flow::{BaseFlow, BlockFlowClass, FlowClass, Flow, ImmutableFlowUtils}; use layout::flow::{BaseFlow, BlockFlowClass, FlowClass, Flow, ImmutableFlowUtils};
use layout::flow::{MutableFlowUtils, PreorderFlowTraversal, PostorderFlowTraversal, mut_base}; use layout::flow::{MutableFlowUtils, PreorderFlowTraversal, PostorderFlowTraversal, mut_base};
use layout::flow; use layout::flow;
use layout::fragment::{Fragment, ImageFragment, ScannedTextFragment};
use layout::model::{Auto, IntrinsicWidths, MarginCollapseInfo, MarginsCollapse}; use layout::model::{Auto, IntrinsicWidths, MarginCollapseInfo, MarginsCollapse};
use layout::model::{MarginsCollapseThrough, MaybeAuto, NoCollapsibleMargins, Specified, specified}; use layout::model::{MarginsCollapseThrough, MaybeAuto, NoCollapsibleMargins, Specified, specified};
use layout::model::{specified_or_none}; use layout::model::{specified_or_none};
@ -41,7 +41,6 @@ use servo_util::geometry;
use std::fmt; use std::fmt;
use std::mem; use std::mem;
use std::num::Zero; use std::num::Zero;
use std::owned;
use style::computed_values::{LPA_Auto, LPA_Length, LPA_Percentage, LPN_Length, LPN_None}; use style::computed_values::{LPA_Auto, LPA_Length, LPA_Percentage, LPN_Length, LPN_None};
use style::computed_values::{LPN_Percentage, LP_Length, LP_Percentage, display, float, overflow}; use style::computed_values::{LPN_Percentage, LP_Length, LP_Percentage, display, float, overflow};
use sync::Arc; use sync::Arc;
@ -53,7 +52,7 @@ pub struct FloatedBlockInfo {
/// Offset relative to where the parent tried to position this flow /// Offset relative to where the parent tried to position this flow
pub rel_pos: Point2D<Au>, pub rel_pos: Point2D<Au>,
/// Index into the box list for inline floats /// Index into the fragment list for inline floats
pub index: Option<uint>, pub index: Option<uint>,
/// Left or right? /// Left or right?
@ -489,8 +488,8 @@ pub struct BlockFlow {
/// Data common to all flows. /// Data common to all flows.
pub base: BaseFlow, pub base: BaseFlow,
/// The associated box. /// The associated fragment.
pub box_: Box, pub fragment: Fragment,
/// TODO: is_root should be a bit field to conserve memory. /// TODO: is_root should be a bit field to conserve memory.
/// Whether this block flow is the root flow. /// Whether this block flow is the root flow.
@ -504,14 +503,14 @@ pub struct BlockFlow {
previous_float_width: Option<Au>, previous_float_width: Option<Au>,
/// Additional floating flow members. /// Additional floating flow members.
pub float: Option<owned::Box<FloatedBlockInfo>> pub float: Option<Box<FloatedBlockInfo>>
} }
impl BlockFlow { impl BlockFlow {
pub fn from_node(constructor: &mut FlowConstructor, node: &ThreadSafeLayoutNode) -> BlockFlow { pub fn from_node(constructor: &mut FlowConstructor, node: &ThreadSafeLayoutNode) -> BlockFlow {
BlockFlow { BlockFlow {
base: BaseFlow::new((*node).clone()), base: BaseFlow::new((*node).clone()),
box_: Box::new(constructor, node), fragment: Fragment::new(constructor, node),
is_root: false, is_root: false,
static_y_offset: Au::new(0), static_y_offset: Au::new(0),
previous_float_width: None, previous_float_width: None,
@ -519,10 +518,10 @@ impl BlockFlow {
} }
} }
pub fn from_node_and_box(node: &ThreadSafeLayoutNode, box_: Box) -> BlockFlow { pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode, fragment: Fragment) -> BlockFlow {
BlockFlow { BlockFlow {
base: BaseFlow::new((*node).clone()), base: BaseFlow::new((*node).clone()),
box_: box_, fragment: fragment,
is_root: false, is_root: false,
static_y_offset: Au::new(0), static_y_offset: Au::new(0),
previous_float_width: None, previous_float_width: None,
@ -536,7 +535,7 @@ impl BlockFlow {
-> BlockFlow { -> BlockFlow {
BlockFlow { BlockFlow {
base: BaseFlow::new((*node).clone()), base: BaseFlow::new((*node).clone()),
box_: Box::new(constructor, node), fragment: Fragment::new(constructor, node),
is_root: false, is_root: false,
static_y_offset: Au::new(0), static_y_offset: Au::new(0),
previous_float_width: None, previous_float_width: None,
@ -601,9 +600,9 @@ impl BlockFlow {
} }
} }
/// Return this flow's box. /// Return this flow's fragment.
pub fn box_<'a>(&'a mut self) -> &'a mut Box { pub fn fragment<'a>(&'a mut self) -> &'a mut Fragment {
&mut self.box_ &mut self.fragment
} }
/// Return the static x offset from the appropriate Containing Block for this flow. /// Return the static x offset from the appropriate Containing Block for this flow.
@ -699,13 +698,13 @@ impl BlockFlow {
traversal.process(flow) traversal.process(flow)
} }
/// Return true if this has a replaced box. /// Return true if this has a replaced fragment.
/// ///
/// The only two types of replaced boxes currently are text boxes and /// The only two types of replaced fragments currently are text fragments
/// image boxes. /// and image fragments.
fn is_replaced_content(&self) -> bool { fn is_replaced_content(&self) -> bool {
match self.box_.specific { match self.fragment.specific {
ScannedTextBox(_) | ImageBox(_) => true, ScannedTextFragment(_) | ImageFragment(_) => true,
_ => false, _ => false,
} }
} }
@ -766,7 +765,7 @@ impl BlockFlow {
/// ///
/// TODO(#2017, pcwalton): This is somewhat inefficient (traverses kids twice); can we do /// TODO(#2017, pcwalton): This is somewhat inefficient (traverses kids twice); can we do
/// better? /// better?
fn adjust_boxes_for_collapsed_margins_if_root(&mut self) { fn adjust_fragments_for_collapsed_margins_if_root(&mut self) {
if !self.is_root() { if !self.is_root() {
return return
} }
@ -789,7 +788,7 @@ impl BlockFlow {
self.base.position.size.height = self.base.position.size.height + top_margin_value + self.base.position.size.height = self.base.position.size.height + top_margin_value +
bottom_margin_value; bottom_margin_value;
self.box_.border_box.size.height = self.box_.border_box.size.height + top_margin_value + self.fragment.border_box.size.height = self.fragment.border_box.size.height + top_margin_value +
bottom_margin_value; bottom_margin_value;
} }
@ -823,17 +822,17 @@ impl BlockFlow {
} }
let mut margin_collapse_info = MarginCollapseInfo::new(); let mut margin_collapse_info = MarginCollapseInfo::new();
self.base.floats.translate(Point2D(-self.box_.left_offset(), Au(0))); self.base.floats.translate(Point2D(-self.fragment.left_offset(), Au(0)));
// The sum of our top border and top padding. // The sum of our top border and top padding.
let top_offset = self.box_.border_padding.top; let top_offset = self.fragment.border_padding.top;
translate_including_floats(&mut cur_y, top_offset, &mut self.base.floats); translate_including_floats(&mut cur_y, top_offset, &mut self.base.floats);
let can_collapse_top_margin_with_kids = let can_collapse_top_margin_with_kids =
margins_may_collapse == MarginsMayCollapse && margins_may_collapse == MarginsMayCollapse &&
!self.is_absolutely_positioned() && !self.is_absolutely_positioned() &&
self.box_.border_padding.top == Au(0); self.fragment.border_padding.top == Au(0);
margin_collapse_info.initialize_top_margin(&self.box_, margin_collapse_info.initialize_top_margin(&self.fragment,
can_collapse_top_margin_with_kids); can_collapse_top_margin_with_kids);
// At this point, `cur_y` is at the content edge of our box. Now iterate over children. // At this point, `cur_y` is at the content edge of our box. Now iterate over children.
@ -935,10 +934,10 @@ impl BlockFlow {
let can_collapse_bottom_margin_with_kids = let can_collapse_bottom_margin_with_kids =
margins_may_collapse == MarginsMayCollapse && margins_may_collapse == MarginsMayCollapse &&
!self.is_absolutely_positioned() && !self.is_absolutely_positioned() &&
self.box_.border_padding.bottom == Au(0); self.fragment.border_padding.bottom == Au(0);
let (collapsible_margins, delta) = let (collapsible_margins, delta) =
margin_collapse_info.finish_and_compute_collapsible_margins( margin_collapse_info.finish_and_compute_collapsible_margins(
&self.box_, &self.fragment,
can_collapse_bottom_margin_with_kids); can_collapse_bottom_margin_with_kids);
self.base.collapsible_margins = collapsible_margins; self.base.collapsible_margins = collapsible_margins;
translate_including_floats(&mut cur_y, delta, &mut floats); translate_including_floats(&mut cur_y, delta, &mut floats);
@ -964,11 +963,11 @@ impl BlockFlow {
// Store the content height for use in calculating the absolute flow's dimensions // Store the content height for use in calculating the absolute flow's dimensions
// later. // later.
self.box_.border_box.size.height = height; self.fragment.border_box.size.height = height;
return return
} }
let mut candidate_height_iterator = CandidateHeightIterator::new(self.box_.style(), let mut candidate_height_iterator = CandidateHeightIterator::new(self.fragment.style(),
None); None);
for (candidate_height, new_candidate_height) in candidate_height_iterator { for (candidate_height, new_candidate_height) in candidate_height_iterator {
*new_candidate_height = match candidate_height { *new_candidate_height = match candidate_height {
@ -983,17 +982,17 @@ impl BlockFlow {
translate_including_floats(&mut cur_y, delta, &mut floats); translate_including_floats(&mut cur_y, delta, &mut floats);
// Compute content height and noncontent height. // Compute content height and noncontent height.
let bottom_offset = self.box_.border_padding.bottom; let bottom_offset = self.fragment.border_padding.bottom;
translate_including_floats(&mut cur_y, bottom_offset, &mut floats); translate_including_floats(&mut cur_y, bottom_offset, &mut floats);
// Now that `cur_y` is at the bottom of the border box, compute the final border box // Now that `cur_y` is at the bottom of the border box, compute the final border box
// position. // position.
self.box_.border_box.size.height = cur_y; self.fragment.border_box.size.height = cur_y;
self.box_.border_box.origin.y = Au(0); self.fragment.border_box.origin.y = Au(0);
self.base.position.size.height = cur_y; self.base.position.size.height = cur_y;
self.base.floats = floats.clone(); self.base.floats = floats.clone();
self.adjust_boxes_for_collapsed_margins_if_root(); self.adjust_fragments_for_collapsed_margins_if_root();
if self.is_root_of_absolute_flow_tree() { if self.is_root_of_absolute_flow_tree() {
// Assign heights for all flows in this Absolute flow tree. // Assign heights for all flows in this Absolute flow tree.
@ -1019,16 +1018,16 @@ impl BlockFlow {
/// already called on this kid flow by the traversal function. So, the values used are /// already called on this kid flow by the traversal function. So, the values used are
/// well-defined. /// well-defined.
pub fn place_float(&mut self) { pub fn place_float(&mut self) {
let height = self.box_.border_box.size.height; let height = self.fragment.border_box.size.height;
let clearance = match self.box_.clear() { let clearance = match self.fragment.clear() {
None => Au(0), None => Au(0),
Some(clear) => self.base.floats.clearance(clear), Some(clear) => self.base.floats.clearance(clear),
}; };
let margin_height = self.box_.margin.vertical(); let margin_height = self.fragment.margin.vertical();
let info = PlacementInfo { let info = PlacementInfo {
size: Size2D(self.base.position.size.width + self.box_.margin.horizontal() + size: Size2D(self.base.position.size.width + self.fragment.margin.horizontal() +
self.box_.border_padding.horizontal(), self.fragment.border_padding.horizontal(),
height + margin_height), height + margin_height),
ceiling: clearance + self.base.position.origin.y, ceiling: clearance + self.base.position.origin.y,
max_width: self.float.get_ref().containing_width, max_width: self.float.get_ref().containing_width,
@ -1061,7 +1060,7 @@ impl BlockFlow {
// Floats establish a block formatting context, so we discard the output floats here. // Floats establish a block formatting context, so we discard the output floats here.
drop(floats); drop(floats);
let top_offset = self.box_.margin.top + self.box_.border_padding.top; let top_offset = self.fragment.margin.top + self.fragment.border_padding.top;
let mut cur_y = top_offset; let mut cur_y = top_offset;
// cur_y is now at the top content edge // cur_y is now at the top content edge
@ -1075,11 +1074,11 @@ impl BlockFlow {
let content_height = cur_y - top_offset; let content_height = cur_y - top_offset;
// The associated box is the border box of this flow. // The associated fragment has the border box of this flow.
self.box_.border_box.origin.y = self.box_.margin.top; self.fragment.border_box.origin.y = self.fragment.margin.top;
// Calculate content height, taking `min-height` and `max-height` into account. // Calculate content height, taking `min-height` and `max-height` into account.
let mut candidate_height_iterator = CandidateHeightIterator::new(self.box_.style(), None); let mut candidate_height_iterator = CandidateHeightIterator::new(self.fragment.style(), None);
for (candidate_height, new_candidate_height) in candidate_height_iterator { for (candidate_height, new_candidate_height) in candidate_height_iterator {
*new_candidate_height = match candidate_height { *new_candidate_height = match candidate_height {
Auto => content_height, Auto => content_height,
@ -1088,9 +1087,9 @@ impl BlockFlow {
} }
let content_height = candidate_height_iterator.candidate_value; let content_height = candidate_height_iterator.candidate_value;
let noncontent_height = self.box_.border_padding.vertical(); let noncontent_height = self.fragment.border_padding.vertical();
debug!("assign_height_float -- height: {}", content_height + noncontent_height); debug!("assign_height_float -- height: {}", content_height + noncontent_height);
self.box_.border_box.size.height = content_height + noncontent_height; self.fragment.border_box.size.height = content_height + noncontent_height;
} }
fn build_display_list_block_common(&mut self, fn build_display_list_block_common(&mut self,
@ -1098,7 +1097,7 @@ impl BlockFlow {
offset: Point2D<Au>, offset: Point2D<Au>,
background_border_level: BackgroundAndBorderLevel) { background_border_level: BackgroundAndBorderLevel) {
let rel_offset = let rel_offset =
self.box_.relative_position(&self.base self.fragment.relative_position(&self.base
.absolute_position_info .absolute_position_info
.relative_containing_block_size, .relative_containing_block_size,
None); None);
@ -1106,11 +1105,11 @@ impl BlockFlow {
// Add the box that starts the block context. // Add the box that starts the block context.
let mut display_list = DisplayList::new(); let mut display_list = DisplayList::new();
let mut accumulator = let mut accumulator =
self.box_.build_display_list(&mut display_list, self.fragment.build_display_list(&mut display_list,
layout_context, layout_context,
self.base.abs_position + rel_offset + offset, self.base.abs_position + rel_offset + offset,
background_border_level, background_border_level,
None); None);
let mut child_layers = DList::new(); let mut child_layers = DList::new();
for kid in self.base.child_iter() { for kid in self.base.child_iter() {
@ -1177,39 +1176,39 @@ impl BlockFlow {
let static_y_offset = self.static_y_offset; let static_y_offset = self.static_y_offset;
// This is the stored content height value from assign-height // This is the stored content height value from assign-height
let content_height = self.box_.content_box().size.height; let content_height = self.fragment.content_box().size.height;
let mut solution = None; let mut solution = None;
{ {
// Non-auto margin-top and margin-bottom values have already been // Non-auto margin-top and margin-bottom values have already been
// calculated during assign-width. // calculated during assign-width.
let margin_top = match self.box_.style().get_margin().margin_top { let margin_top = match self.fragment.style().get_margin().margin_top {
LPA_Auto => Auto, LPA_Auto => Auto,
_ => Specified(self.box_.margin.top) _ => Specified(self.fragment.margin.top)
}; };
let margin_bottom = match self.box_.style().get_margin().margin_bottom { let margin_bottom = match self.fragment.style().get_margin().margin_bottom {
LPA_Auto => Auto, LPA_Auto => Auto,
_ => Specified(self.box_.margin.bottom) _ => Specified(self.fragment.margin.bottom)
}; };
let top; let top;
let bottom; let bottom;
{ {
let position_style = self.box_.style().get_positionoffsets(); let position_style = self.fragment.style().get_positionoffsets();
top = MaybeAuto::from_style(position_style.top, containing_block_height); top = MaybeAuto::from_style(position_style.top, containing_block_height);
bottom = MaybeAuto::from_style(position_style.bottom, containing_block_height); bottom = MaybeAuto::from_style(position_style.bottom, containing_block_height);
} }
let available_height = containing_block_height - self.box_.border_padding.vertical(); let available_height = containing_block_height - self.fragment.border_padding.vertical();
if self.is_replaced_content() { if self.is_replaced_content() {
// Calculate used value of height just like we do for inline replaced elements. // Calculate used value of height just like we do for inline replaced elements.
// TODO: Pass in the containing block height when Box's // TODO: Pass in the containing block height when Fragment's
// assign-height can handle it correctly. // assign-height can handle it correctly.
self.box_.assign_replaced_height_if_necessary(); self.fragment.assign_replaced_height_if_necessary();
// TODO: Right now, this content height value includes the // TODO: Right now, this content height value includes the
// margin because of erroneous height calculation in Box_. // margin because of erroneous height calculation in fragment.
// Check this when that has been fixed. // Check this when that has been fixed.
let height_used_val = self.box_.border_box.size.height; let height_used_val = self.fragment.border_box.size.height;
solution = Some(HeightConstraintSolution::solve_vertical_constraints_abs_replaced( solution = Some(HeightConstraintSolution::solve_vertical_constraints_abs_replaced(
height_used_val, height_used_val,
margin_top, margin_top,
@ -1220,7 +1219,7 @@ impl BlockFlow {
available_height, available_height,
static_y_offset)); static_y_offset));
} else { } else {
let style = self.box_.style(); let style = self.fragment.style();
let mut candidate_height_iterator = let mut candidate_height_iterator =
CandidateHeightIterator::new(style, Some(containing_block_height)); CandidateHeightIterator::new(style, Some(containing_block_height));
@ -1242,13 +1241,13 @@ impl BlockFlow {
} }
let solution = solution.unwrap(); let solution = solution.unwrap();
self.box_.margin.top = solution.margin_top; self.fragment.margin.top = solution.margin_top;
self.box_.margin.bottom = solution.margin_bottom; self.fragment.margin.bottom = solution.margin_bottom;
self.box_.border_box.origin.y = Au(0); self.fragment.border_box.origin.y = Au(0);
self.box_.border_box.size.height = solution.height + self.box_.border_padding.vertical(); self.fragment.border_box.size.height = solution.height + self.fragment.border_padding.vertical();
self.base.position.origin.y = solution.top + self.box_.margin.top; self.base.position.origin.y = solution.top + self.fragment.margin.top;
self.base.position.size.height = solution.height + self.box_.border_padding.vertical(); self.base.position.size.height = solution.height + self.fragment.border_padding.vertical();
} }
/// Add display items for Absolutely Positioned flow. /// Add display items for Absolutely Positioned flow.
@ -1289,7 +1288,7 @@ impl BlockFlow {
self.base.layers.push_back(new_layer) self.base.layers.push_back(new_layer)
} }
/// Return the top outer edge of the Hypothetical Box for an absolute flow. /// Return the top outer edge of the hypothetical box for an absolute flow.
/// ///
/// This is wrt its parent flow box. /// This is wrt its parent flow box.
/// ///
@ -1317,7 +1316,7 @@ impl BlockFlow {
let absolute_static_x_offset = if self.is_positioned() { let absolute_static_x_offset = if self.is_positioned() {
// This flow is the containing block. The static X offset will be the left padding // This flow is the containing block. The static X offset will be the left padding
// edge. // edge.
self.box_.border_padding.left - model::border_from_style(self.box_.style()).left self.fragment.border_padding.left - model::border_from_style(self.fragment.style()).left
} else { } else {
// For kids, the left margin edge will be at our left content edge. The current static // For kids, the left margin edge will be at our left content edge. The current static
// offset is at our left margin edge. So move in to the left content edge. // offset is at our left margin edge. So move in to the left content edge.
@ -1396,7 +1395,7 @@ impl BlockFlow {
/// Determines the type of formatting context this is. See the definition of /// Determines the type of formatting context this is. See the definition of
/// `FormattingContextType`. /// `FormattingContextType`.
fn formatting_context_type(&self) -> FormattingContextType { fn formatting_context_type(&self) -> FormattingContextType {
let style = self.box_.style(); let style = self.fragment.style();
if style.get_box().float != float::none { if style.get_box().float != float::none {
return OtherFormattingContext return OtherFormattingContext
} }
@ -1424,7 +1423,7 @@ impl Flow for BlockFlow {
/// Returns the direction that this flow clears floats in, if any. /// Returns the direction that this flow clears floats in, if any.
fn float_clearance(&self) -> clear::T { fn float_clearance(&self) -> clear::T {
self.box_.style().get_box().clear self.fragment.style().get_box().clear
} }
/// Pass 1 of reflow: computes minimum and preferred widths. /// Pass 1 of reflow: computes minimum and preferred widths.
@ -1432,7 +1431,7 @@ impl Flow for BlockFlow {
/// Recursively (bottom-up) determine the flow's minimum and preferred widths. When called on /// Recursively (bottom-up) determine the flow's minimum and preferred widths. When called on
/// this flow, all child flows have had their minimum and preferred widths set. This function /// this flow, all child flows have had their minimum and preferred widths set. This function
/// must decide minimum/preferred widths based on its children's widths and the dimensions of /// must decide minimum/preferred widths based on its children's widths and the dimensions of
/// any boxes it is responsible for flowing. /// any fragments it is responsible for flowing.
/// ///
/// TODO(pcwalton): Inline blocks. /// TODO(pcwalton): Inline blocks.
fn bubble_widths(&mut self, _: &mut LayoutContext) { fn bubble_widths(&mut self, _: &mut LayoutContext) {
@ -1458,15 +1457,15 @@ impl Flow for BlockFlow {
flags.union_floated_descendants_flags(child_base.flags); flags.union_floated_descendants_flags(child_base.flags);
} }
let box_intrinsic_widths = self.box_.intrinsic_widths(None); let fragment_intrinsic_widths = self.fragment.intrinsic_widths(None);
intrinsic_widths.minimum_width = geometry::max(intrinsic_widths.minimum_width, intrinsic_widths.minimum_width = geometry::max(intrinsic_widths.minimum_width,
box_intrinsic_widths.minimum_width); fragment_intrinsic_widths.minimum_width);
intrinsic_widths.preferred_width = geometry::max(intrinsic_widths.preferred_width, intrinsic_widths.preferred_width = geometry::max(intrinsic_widths.preferred_width,
box_intrinsic_widths.preferred_width); fragment_intrinsic_widths.preferred_width);
intrinsic_widths.surround_width = box_intrinsic_widths.surround_width; intrinsic_widths.surround_width = fragment_intrinsic_widths.surround_width;
self.base.intrinsic_widths = intrinsic_widths; self.base.intrinsic_widths = intrinsic_widths;
match self.box_.style().get_box().float { match self.fragment.style().get_box().float {
float::none => {} float::none => {}
float::left => flags.set_has_left_floated_descendants(true), float::left => flags.set_has_left_floated_descendants(true),
float::right => flags.set_has_right_floated_descendants(true), float::right => flags.set_has_right_floated_descendants(true),
@ -1474,10 +1473,10 @@ impl Flow for BlockFlow {
self.base.flags = flags self.base.flags = flags
} }
/// Recursively (top-down) determines the actual width of child contexts and boxes. When called /// Recursively (top-down) determines the actual width of child contexts and fragments. When
/// on this context, the context has had its width set by the parent context. /// 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) /// Dual fragments consume some width first, and the remainder is assigned to all child (block)
/// contexts. /// contexts.
fn assign_widths(&mut self, layout_context: &mut LayoutContext) { fn assign_widths(&mut self, layout_context: &mut LayoutContext) {
debug!("assign_widths({}): assigning width for flow", debug!("assign_widths({}): assigning width for flow",
@ -1519,8 +1518,8 @@ impl Flow for BlockFlow {
match self.previous_float_width { match self.previous_float_width {
None => {} None => {}
Some(previous_float_width) => { Some(previous_float_width) => {
self.box_.border_box.size.width = self.fragment.border_box.size.width =
self.box_.border_box.size.width - previous_float_width self.fragment.border_box.size.width - previous_float_width
} }
} }
} }
@ -1531,9 +1530,9 @@ impl Flow for BlockFlow {
} }
// Move in from the left border edge // Move in from the left border edge
let left_content_edge = self.box_.border_box.origin.x + self.box_.border_padding.left; let left_content_edge = self.fragment.border_box.origin.x + self.fragment.border_padding.left;
let padding_and_borders = self.box_.border_padding.horizontal(); let padding_and_borders = self.fragment.border_padding.horizontal();
let content_width = self.box_.border_box.size.width - padding_and_borders; let content_width = self.fragment.border_box.size.width - padding_and_borders;
if self.is_float() { if self.is_float() {
self.base.position.size.width = content_width; self.base.position.size.width = content_width;
@ -1563,8 +1562,8 @@ impl Flow for BlockFlow {
} }
fn assign_height(&mut self, ctx: &mut LayoutContext) { fn assign_height(&mut self, ctx: &mut LayoutContext) {
// Assign height for box if it is an image box. // Assign height for fragment if it is an image fragment.
self.box_.assign_replaced_height_if_necessary(); self.fragment.assign_replaced_height_if_necessary();
if self.is_float() { if self.is_float() {
debug!("assign_height_float: assigning height for float"); debug!("assign_height_float: assigning height for float");
@ -1599,10 +1598,10 @@ impl Flow for BlockFlow {
// the content box. The containing block for absolutely-positioned descendants, on the // the content box. The containing block for absolutely-positioned descendants, on the
// other hand, is only established if we are positioned. // other hand, is only established if we are positioned.
let relative_offset = let relative_offset =
self.box_.relative_position(&self.base self.fragment.relative_position(&self.base
.absolute_position_info .absolute_position_info
.relative_containing_block_size, .relative_containing_block_size,
None); None);
if self.is_positioned() { if self.is_positioned() {
self.base.absolute_position_info.absolute_containing_block_position = self.base.absolute_position_info.absolute_containing_block_position =
self.base.abs_position + self.base.abs_position +
@ -1618,7 +1617,7 @@ impl Flow for BlockFlow {
// Compute absolute position info for children. // Compute absolute position info for children.
let mut absolute_position_info = self.base.absolute_position_info; let mut absolute_position_info = self.base.absolute_position_info;
absolute_position_info.relative_containing_block_size = self.box_.content_box().size; absolute_position_info.relative_containing_block_size = self.fragment.content_box().size;
absolute_position_info.layers_needed_for_positioned_flows = absolute_position_info.layers_needed_for_positioned_flows =
self.base.flags.layers_needed_for_descendants(); self.base.flags.layers_needed_for_descendants();
@ -1666,7 +1665,7 @@ impl Flow for BlockFlow {
/// The 'position' property of this flow. /// The 'position' property of this flow.
fn positioning(&self) -> position::T { fn positioning(&self) -> position::T {
self.box_.style.get_box().position self.fragment.style.get_box().position
} }
/// Return true if this is the root of an Absolute flow tree. /// Return true if this is the root of an Absolute flow tree.
@ -1679,17 +1678,17 @@ impl Flow for BlockFlow {
/// Return the dimensions of the containing block generated by this flow for absolutely- /// Return the dimensions of the containing block generated by this flow for absolutely-
/// positioned descendants. For block flows, this is the padding box. /// positioned descendants. For block flows, this is the padding box.
fn generated_containing_block_rect(&self) -> Rect<Au> { fn generated_containing_block_rect(&self) -> Rect<Au> {
let border = model::border_from_style(self.box_.style()); let border = model::border_from_style(self.fragment.style());
Rect(self.box_.border_box.origin + Point2D(border.left, border.top), Rect(self.fragment.border_box.origin + Point2D(border.left, border.top),
Size2D(self.box_.border_box.size.width - border.horizontal(), Size2D(self.fragment.border_box.size.width - border.horizontal(),
self.box_.border_box.size.height - border.vertical())) self.fragment.border_box.size.height - border.vertical()))
} }
fn layer_id(&self, fragment_index: uint) -> LayerId { fn layer_id(&self, fragment_index: uint) -> LayerId {
// FIXME(#2010, pcwalton): This is a hack and is totally bogus in the presence of pseudo- // FIXME(#2010, pcwalton): This is a hack and is totally bogus in the presence of pseudo-
// elements. But until we have incremental reflow we can't do better--we recreate the flow // elements. But until we have incremental reflow we can't do better--we recreate the flow
// for every DOM node so otherwise we nuke layers on every reflow. // for every DOM node so otherwise we nuke layers on every reflow.
LayerId(self.box_.node.id(), fragment_index) LayerId(self.fragment.node.id(), fragment_index)
} }
fn is_absolute_containing_block(&self) -> bool { fn is_absolute_containing_block(&self) -> bool {
@ -1700,11 +1699,11 @@ impl Flow for BlockFlow {
impl fmt::Show for BlockFlow { impl fmt::Show for BlockFlow {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.is_float() { if self.is_float() {
write!(f.buf, "FloatFlow: {}", self.box_) write!(f.buf, "FloatFlow: {}", self.fragment)
} else if self.is_root() { } else if self.is_root() {
write!(f.buf, "RootFlow: {}", self.box_) write!(f.buf, "RootFlow: {}", self.fragment)
} else { } else {
write!(f.buf, "BlockFlow: {}", self.box_) write!(f.buf, "BlockFlow: {}", self.fragment)
} }
} }
} }
@ -1794,9 +1793,9 @@ pub trait WidthAndMarginsComputer {
let containing_block_width = self.containing_block_width(block, parent_flow_width, ctx); let containing_block_width = self.containing_block_width(block, parent_flow_width, ctx);
let computed_width = self.initial_computed_width(block, parent_flow_width, ctx); let computed_width = self.initial_computed_width(block, parent_flow_width, ctx);
block.box_.compute_border_padding_margins(containing_block_width, None); block.fragment.compute_border_padding_margins(containing_block_width, None);
let style = block.box_.style(); let style = block.fragment.style();
// The text alignment of a block flow is the text alignment of its box's style. // The text alignment of a block flow is the text alignment of its box's style.
block.base.flags.set_text_align(style.get_inheritedtext().text_align); block.base.flags.set_text_align(style.get_inheritedtext().text_align);
@ -1808,7 +1807,7 @@ pub trait WidthAndMarginsComputer {
let (left, right) = let (left, right) =
(MaybeAuto::from_style(style.get_positionoffsets().left, containing_block_width), (MaybeAuto::from_style(style.get_positionoffsets().left, containing_block_width),
MaybeAuto::from_style(style.get_positionoffsets().right, containing_block_width)); MaybeAuto::from_style(style.get_positionoffsets().right, containing_block_width));
let available_width = containing_block_width - block.box_.border_padding.horizontal(); let available_width = containing_block_width - block.fragment.border_padding.horizontal();
return WidthConstraintInput::new(computed_width, return WidthConstraintInput::new(computed_width,
margin_left, margin_left,
margin_right, margin_right,
@ -1829,15 +1828,15 @@ pub trait WidthAndMarginsComputer {
fn set_width_constraint_solutions(&self, fn set_width_constraint_solutions(&self,
block: &mut BlockFlow, block: &mut BlockFlow,
solution: WidthConstraintSolution) { solution: WidthConstraintSolution) {
let box_ = block.box_(); let fragment = block.fragment();
box_.margin.left = solution.margin_left; fragment.margin.left = solution.margin_left;
box_.margin.right = solution.margin_right; fragment.margin.right = solution.margin_right;
// The associated box is the border box of this flow. // The associated fragment has the border box of this flow.
// Left border edge. // Left border edge.
box_.border_box.origin.x = box_.margin.left; fragment.border_box.origin.x = fragment.margin.left;
// Border box width. // Border box width.
box_.border_box.size.width = solution.width + box_.border_padding.horizontal(); fragment.border_box.size.width = solution.width + fragment.border_padding.horizontal();
} }
/// Set the x coordinate of the given flow if it is absolutely positioned. /// Set the x coordinate of the given flow if it is absolutely positioned.
@ -1854,7 +1853,7 @@ pub trait WidthAndMarginsComputer {
parent_flow_width: Au, parent_flow_width: Au,
ctx: &mut LayoutContext) ctx: &mut LayoutContext)
-> MaybeAuto { -> MaybeAuto {
MaybeAuto::from_style(block.box_().style().get_box().width, MaybeAuto::from_style(block.fragment().style().get_box().width,
self.containing_block_width(block, parent_flow_width, ctx)) self.containing_block_width(block, parent_flow_width, ctx))
} }
@ -1881,7 +1880,7 @@ pub trait WidthAndMarginsComputer {
// If the tentative used width is greater than 'max-width', width should be recalculated, // 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'. // but this time using the computed value of 'max-width' as the computed value for 'width'.
match specified_or_none(block.box_().style().get_box().max_width, containing_block_width) { match specified_or_none(block.fragment().style().get_box().max_width, containing_block_width) {
Some(max_width) if max_width < solution.width => { Some(max_width) if max_width < solution.width => {
input.computed_width = Specified(max_width); input.computed_width = Specified(max_width);
solution = self.solve_width_constraints(block, &input); solution = self.solve_width_constraints(block, &input);
@ -1891,7 +1890,7 @@ pub trait WidthAndMarginsComputer {
// If the resulting width is smaller than 'min-width', width should be recalculated, // 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'. // but this time using the value of 'min-width' as the computed value for 'width'.
let computed_min_width = specified(block.box_().style().get_box().min_width, let computed_min_width = specified(block.fragment().style().get_box().min_width,
containing_block_width); containing_block_width);
if computed_min_width > solution.width { if computed_min_width > solution.width {
input.computed_width = Specified(computed_min_width); input.computed_width = Specified(computed_min_width);
@ -2234,11 +2233,11 @@ impl WidthAndMarginsComputer for AbsoluteReplaced {
ctx: &mut LayoutContext) ctx: &mut LayoutContext)
-> MaybeAuto { -> MaybeAuto {
let containing_block_width = block.containing_block_size(ctx.screen_size).width; let containing_block_width = block.containing_block_size(ctx.screen_size).width;
let box_ = block.box_(); let fragment = block.fragment();
box_.assign_replaced_width_if_necessary(containing_block_width, None); fragment.assign_replaced_width_if_necessary(containing_block_width, None);
// For replaced absolute flow, the rest of the constraint solving will // For replaced absolute flow, the rest of the constraint solving will
// take width to be specified as the value computed here. // take width to be specified as the value computed here.
Specified(box_.content_width()) Specified(fragment.content_width())
} }
fn containing_block_width(&self, block: &mut BlockFlow, _: Au, ctx: &mut LayoutContext) -> Au { fn containing_block_width(&self, block: &mut BlockFlow, _: Au, ctx: &mut LayoutContext) -> Au {
@ -2283,11 +2282,11 @@ impl WidthAndMarginsComputer for BlockReplaced {
parent_flow_width: Au, parent_flow_width: Au,
_: &mut LayoutContext) _: &mut LayoutContext)
-> MaybeAuto { -> MaybeAuto {
let box_ = block.box_(); let fragment = block.fragment();
box_.assign_replaced_width_if_necessary(parent_flow_width, None); fragment.assign_replaced_width_if_necessary(parent_flow_width, None);
// For replaced block flow, the rest of the constraint solving will // For replaced block flow, the rest of the constraint solving will
// take width to be specified as the value computed here. // take width to be specified as the value computed here.
Specified(box_.content_width()) Specified(fragment.content_width())
} }
} }
@ -2339,11 +2338,11 @@ impl WidthAndMarginsComputer for FloatReplaced {
parent_flow_width: Au, parent_flow_width: Au,
_: &mut LayoutContext) _: &mut LayoutContext)
-> MaybeAuto { -> MaybeAuto {
let box_ = block.box_(); let fragment = block.fragment();
box_.assign_replaced_width_if_necessary(parent_flow_width, None); fragment.assign_replaced_width_if_necessary(parent_flow_width, None);
// For replaced block flow, the rest of the constraint solving will // For replaced block flow, the rest of the constraint solving will
// take width to be specified as the value computed here. // take width to be specified as the value computed here.
Specified(box_.content_width()) Specified(fragment.content_width())
} }
} }

View file

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//! Creates flows and boxes from a DOM tree via a bottom-up, incremental traversal of the DOM. //! Creates flows and fragments from a DOM tree via a bottom-up, incremental traversal of the DOM.
//! //!
//! Each step of the traversal considers the node and existing flow, if there is one. If a node is //! Each step of the traversal considers the node and existing flow, if there is one. If a node is
//! not dirty and an existing flow exists, then the traversal reuses that flow. Otherwise, it //! not dirty and an existing flow exists, then the traversal reuses that flow. Otherwise, it
@ -22,15 +22,15 @@
use css::node_style::StyledNode; use css::node_style::StyledNode;
use layout::block::BlockFlow; use layout::block::BlockFlow;
use layout::box_::{Box, GenericBox, IframeBox, IframeBoxInfo, ImageBox, ImageBoxInfo};
use layout::box_::{SpecificBoxInfo, TableBox, TableCellBox, TableColumnBox, TableColumnBoxInfo};
use layout::box_::{TableRowBox, TableWrapperBox, UnscannedTextBox, UnscannedTextBoxInfo};
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::floats::FloatKind; use layout::floats::FloatKind;
use layout::flow::{Flow, ImmutableFlowUtils, MutableOwnedFlowUtils}; use layout::flow::{Flow, ImmutableFlowUtils, MutableOwnedFlowUtils};
use layout::flow::{Descendants, AbsDescendants}; use layout::flow::{Descendants, AbsDescendants};
use layout::flow_list::{Rawlink}; use layout::flow_list::{Rawlink};
use layout::inline::{FragmentIndex, InlineBoxes, InlineFlow}; use layout::fragment::{Fragment, GenericFragment, IframeFragment, IframeFragmentInfo, ImageFragment, ImageFragmentInfo};
use layout::fragment::{SpecificFragmentInfo, TableFragment, TableCellFragment, TableColumnFragment, TableColumnFragmentInfo};
use layout::fragment::{TableRowFragment, TableWrapperFragment, UnscannedTextFragment, UnscannedTextFragmentInfo};
use layout::inline::{FragmentIndex, InlineFragments, InlineFlow};
use layout::table_wrapper::TableWrapperFlow; use layout::table_wrapper::TableWrapperFlow;
use layout::table::TableFlow; use layout::table::TableFlow;
use layout::table_caption::TableCaptionFlow; use layout::table_caption::TableCaptionFlow;
@ -60,7 +60,6 @@ use servo_util::range::Range;
use servo_util::str::is_whitespace; use servo_util::str::is_whitespace;
use servo_util::url::{is_image_data, parse_url}; use servo_util::url::{is_image_data, parse_url};
use std::mem; use std::mem;
use std::owned;
use style::ComputedValues; use style::ComputedValues;
use style::computed_values::{display, position, float, white_space}; use style::computed_values::{display, position, float, white_space};
use sync::Arc; use sync::Arc;
@ -75,7 +74,7 @@ pub enum ConstructionResult {
/// This node contributed a flow at the proper position in the tree. /// This node contributed a flow at the proper position in the tree.
/// Nothing more needs to be done for this node. It has bubbled up fixed /// Nothing more needs to be done for this node. It has bubbled up fixed
/// and absolute descendant flows that have a CB above it. /// and absolute descendant flows that have a CB above it.
FlowConstructionResult(owned::Box<Flow:Share>, AbsDescendants), FlowConstructionResult(Box<Flow:Share>, AbsDescendants),
/// This node contributed some object or objects that will be needed to construct a proper flow /// This node contributed some object or objects that will be needed to construct a proper flow
/// later up the tree, but these objects have not yet found their home. /// later up the tree, but these objects have not yet found their home.
@ -96,35 +95,35 @@ impl ConstructionResult {
/// complete flow. Construction items bubble up the tree until they find a `Flow` to be /// complete flow. Construction items bubble up the tree until they find a `Flow` to be
/// attached to. /// attached to.
pub enum ConstructionItem { pub enum ConstructionItem {
/// Inline boxes and associated {ib} splits that have not yet found flows. /// Inline fragments and associated {ib} splits that have not yet found flows.
InlineBoxesConstructionItem(InlineBoxesConstructionResult), InlineFragmentsConstructionItem(InlineFragmentsConstructionResult),
/// Potentially ignorable whitespace. /// Potentially ignorable whitespace.
WhitespaceConstructionItem(OpaqueNode, Arc<ComputedValues>), WhitespaceConstructionItem(OpaqueNode, Arc<ComputedValues>),
/// TableColumn Box /// TableColumn Fragment
TableColumnBoxConstructionItem(Box), TableColumnFragmentConstructionItem(Fragment),
} }
impl ConstructionItem { impl ConstructionItem {
fn destroy(&mut self) { fn destroy(&mut self) {
match *self { match *self {
InlineBoxesConstructionItem(ref mut result) => { InlineFragmentsConstructionItem(ref mut result) => {
for split in result.splits.mut_iter() { for split in result.splits.mut_iter() {
split.destroy() split.destroy()
} }
} }
WhitespaceConstructionItem(..) => {} WhitespaceConstructionItem(..) => {}
TableColumnBoxConstructionItem(_) => {} TableColumnFragmentConstructionItem(_) => {}
} }
} }
} }
/// Represents inline boxes and {ib} splits that are bubbling up from an inline. /// Represents inline fragments and {ib} splits that are bubbling up from an inline.
pub struct InlineBoxesConstructionResult { pub struct InlineFragmentsConstructionResult {
/// Any {ib} splits that we're bubbling up. /// Any {ib} splits that we're bubbling up.
pub splits: Vec<InlineBlockSplit>, pub splits: Vec<InlineBlockSplit>,
/// Any boxes that succeed the {ib} splits. /// Any fragments that succeed the {ib} splits.
pub boxes: InlineBoxes, pub fragments: InlineFragments,
/// Any absolute descendants that we're bubbling up. /// Any absolute descendants that we're bubbling up.
pub abs_descendants: AbsDescendants, pub abs_descendants: AbsDescendants,
@ -141,9 +140,9 @@ pub struct InlineBoxesConstructionResult {
/// ///
/// The resulting `ConstructionItem` for the outer `span` will be: /// The resulting `ConstructionItem` for the outer `span` will be:
/// ///
/// InlineBoxesConstructionItem(Some(~[ /// InlineFragmentsConstructionItem(Some(~[
/// InlineBlockSplit { /// InlineBlockSplit {
/// predecessor_boxes: ~[ /// predecessor_fragments: ~[
/// A /// A
/// ], /// ],
/// block: ~BlockFlow { /// block: ~BlockFlow {
@ -153,11 +152,11 @@ pub struct InlineBoxesConstructionResult {
/// C /// C
/// ]) /// ])
pub struct InlineBlockSplit { pub struct InlineBlockSplit {
/// The inline boxes that precede the flow. /// The inline fragments that precede the flow.
pub predecessors: InlineBoxes, pub predecessors: InlineFragments,
/// The flow that caused this {ib} split. /// The flow that caused this {ib} split.
pub flow: owned::Box<Flow:Share>, pub flow: Box<Flow:Share>,
} }
impl InlineBlockSplit { impl InlineBlockSplit {
@ -166,44 +165,44 @@ impl InlineBlockSplit {
} }
} }
/// Holds inline boxes that we're gathering for children of an inline node. /// Holds inline fragments that we're gathering for children of an inline node.
struct InlineBoxAccumulator { struct InlineFragmentsAccumulator {
/// The list of boxes. /// The list of fragments.
boxes: InlineBoxes, fragments: InlineFragments,
/// Whether we've created a range to enclose all the boxes. This will be true if the outer node /// Whether we've created a range to enclose all the fragments. This will be true if the outer node
/// is an inline and false otherwise. /// is an inline and false otherwise.
has_enclosing_range: bool, has_enclosing_range: bool,
} }
impl InlineBoxAccumulator { impl InlineFragmentsAccumulator {
fn new() -> InlineBoxAccumulator { fn new() -> InlineFragmentsAccumulator {
InlineBoxAccumulator { InlineFragmentsAccumulator {
boxes: InlineBoxes::new(), fragments: InlineFragments::new(),
has_enclosing_range: false, has_enclosing_range: false,
} }
} }
fn from_inline_node(node: &ThreadSafeLayoutNode) -> InlineBoxAccumulator { fn from_inline_node(node: &ThreadSafeLayoutNode) -> InlineFragmentsAccumulator {
let mut boxes = InlineBoxes::new(); let mut fragments = InlineFragments::new();
boxes.map.push(node.style().clone(), Range::empty()); fragments.map.push(node.style().clone(), Range::empty());
InlineBoxAccumulator { InlineFragmentsAccumulator {
boxes: boxes, fragments: fragments,
has_enclosing_range: true, has_enclosing_range: true,
} }
} }
fn finish(self) -> InlineBoxes { fn finish(self) -> InlineFragments {
let InlineBoxAccumulator { let InlineFragmentsAccumulator {
boxes: mut boxes, fragments: mut fragments,
has_enclosing_range has_enclosing_range
} = self; } = self;
if has_enclosing_range { if has_enclosing_range {
let len = FragmentIndex(boxes.len() as int); let len = FragmentIndex(fragments.len() as int);
boxes.map.get_mut(FragmentIndex(0)).range.extend_to(len); fragments.map.get_mut(FragmentIndex(0)).range.extend_to(len);
} }
boxes fragments
} }
} }
@ -223,12 +222,12 @@ pub struct FlowConstructor<'a> {
/// ///
/// FIXME(pcwalton): This is pretty bogus and is basically just a workaround for libgreen /// FIXME(pcwalton): This is pretty bogus and is basically just a workaround for libgreen
/// having slow TLS. /// having slow TLS.
pub font_context: Option<owned::Box<FontContext>>, pub font_context: Option<Box<FontContext>>,
} }
impl<'a> FlowConstructor<'a> { impl<'a> FlowConstructor<'a> {
/// Creates a new flow constructor. /// Creates a new flow constructor.
pub fn new(layout_context: &'a mut LayoutContext, font_context: Option<owned::Box<FontContext>>) pub fn new(layout_context: &'a mut LayoutContext, font_context: Option<Box<FontContext>>)
-> FlowConstructor<'a> { -> FlowConstructor<'a> {
FlowConstructor { FlowConstructor {
layout_context: layout_context, layout_context: layout_context,
@ -247,7 +246,7 @@ impl<'a> FlowConstructor<'a> {
} }
/// Destroys this flow constructor and retrieves the font context. /// Destroys this flow constructor and retrieves the font context.
pub fn unwrap_font_context(self) -> Option<owned::Box<FontContext>> { pub fn unwrap_font_context(self) -> Option<Box<FontContext>> {
let FlowConstructor { let FlowConstructor {
font_context, font_context,
.. ..
@ -255,82 +254,82 @@ impl<'a> FlowConstructor<'a> {
font_context font_context
} }
/// Builds the `ImageBoxInfo` for the given image. This is out of line to guide inlining. /// Builds the `ImageFragmentInfo` for the given image. This is out of line to guide inlining.
fn build_box_info_for_image(&mut self, node: &ThreadSafeLayoutNode, url: Option<Url>) fn build_fragment_info_for_image(&mut self, node: &ThreadSafeLayoutNode, url: Option<Url>)
-> SpecificBoxInfo { -> SpecificFragmentInfo {
match url { match url {
None => GenericBox, None => GenericFragment,
Some(url) => { Some(url) => {
// FIXME(pcwalton): The fact that image boxes store the cache within them makes // FIXME(pcwalton): The fact that image fragments store the cache within them makes
// little sense to me. // little sense to me.
ImageBox(ImageBoxInfo::new(node, url, self.layout_context.image_cache.clone())) ImageFragment(ImageFragmentInfo::new(node, url, self.layout_context.image_cache.clone()))
} }
} }
} }
/// Builds specific `Box` info for the given node. /// Builds specific `Fragment` info for the given node.
pub fn build_specific_box_info_for_node(&mut self, node: &ThreadSafeLayoutNode) pub fn build_specific_fragment_info_for_node(&mut self, node: &ThreadSafeLayoutNode)
-> SpecificBoxInfo { -> SpecificFragmentInfo {
match node.type_id() { match node.type_id() {
Some(ElementNodeTypeId(HTMLImageElementTypeId)) => { Some(ElementNodeTypeId(HTMLImageElementTypeId)) => {
self.build_box_info_for_image(node, node.image_url()) self.build_fragment_info_for_image(node, node.image_url())
} }
Some(ElementNodeTypeId(HTMLIFrameElementTypeId)) => { Some(ElementNodeTypeId(HTMLIFrameElementTypeId)) => {
IframeBox(IframeBoxInfo::new(node)) IframeFragment(IframeFragmentInfo::new(node))
} }
Some(ElementNodeTypeId(HTMLObjectElementTypeId)) => { Some(ElementNodeTypeId(HTMLObjectElementTypeId)) => {
let data = node.get_object_data(&self.layout_context.url); let data = node.get_object_data(&self.layout_context.url);
self.build_box_info_for_image(node, data) self.build_fragment_info_for_image(node, data)
} }
Some(ElementNodeTypeId(HTMLTableElementTypeId)) => TableWrapperBox, Some(ElementNodeTypeId(HTMLTableElementTypeId)) => TableWrapperFragment,
Some(ElementNodeTypeId(HTMLTableColElementTypeId)) => { Some(ElementNodeTypeId(HTMLTableColElementTypeId)) => {
TableColumnBox(TableColumnBoxInfo::new(node)) TableColumnFragment(TableColumnFragmentInfo::new(node))
} }
Some(ElementNodeTypeId(HTMLTableDataCellElementTypeId)) | Some(ElementNodeTypeId(HTMLTableDataCellElementTypeId)) |
Some(ElementNodeTypeId(HTMLTableHeaderCellElementTypeId)) => TableCellBox, Some(ElementNodeTypeId(HTMLTableHeaderCellElementTypeId)) => TableCellFragment,
Some(ElementNodeTypeId(HTMLTableRowElementTypeId)) | Some(ElementNodeTypeId(HTMLTableRowElementTypeId)) |
Some(ElementNodeTypeId(HTMLTableSectionElementTypeId)) => TableRowBox, Some(ElementNodeTypeId(HTMLTableSectionElementTypeId)) => TableRowFragment,
None | Some(TextNodeTypeId) => UnscannedTextBox(UnscannedTextBoxInfo::new(node)), None | Some(TextNodeTypeId) => UnscannedTextFragment(UnscannedTextFragmentInfo::new(node)),
_ => GenericBox, _ => GenericFragment,
} }
} }
/// Creates an inline flow from a set of inline boxes, then adds it as a child of the given flow /// Creates an inline flow from a set of inline fragments, then adds it as a child of the given flow
/// or pushes it onto the given flow list. /// or pushes it onto the given flow list.
/// ///
/// `#[inline(always)]` because this is performance critical and LLVM will not inline it /// `#[inline(always)]` because this is performance critical and LLVM will not inline it
/// otherwise. /// otherwise.
#[inline(always)] #[inline(always)]
fn flush_inline_boxes_to_flow_or_list(&mut self, fn flush_inline_fragments_to_flow_or_list(&mut self,
box_accumulator: InlineBoxAccumulator, fragment_accumulator: InlineFragmentsAccumulator,
flow: &mut owned::Box<Flow:Share>, flow: &mut Box<Flow:Share>,
flow_list: &mut Vec<owned::Box<Flow:Share>>, flow_list: &mut Vec<Box<Flow:Share>>,
whitespace_stripping: WhitespaceStrippingMode, whitespace_stripping: WhitespaceStrippingMode,
node: &ThreadSafeLayoutNode) { node: &ThreadSafeLayoutNode) {
let mut boxes = box_accumulator.finish(); let mut fragments = fragment_accumulator.finish();
if boxes.len() == 0 { if fragments.len() == 0 {
return return
} }
match whitespace_stripping { match whitespace_stripping {
NoWhitespaceStripping => {} NoWhitespaceStripping => {}
StripWhitespaceFromStart => { StripWhitespaceFromStart => {
strip_ignorable_whitespace_from_start(&mut boxes); strip_ignorable_whitespace_from_start(&mut fragments);
if boxes.len() == 0 { if fragments.len() == 0 {
return return
} }
} }
StripWhitespaceFromEnd => { StripWhitespaceFromEnd => {
strip_ignorable_whitespace_from_end(&mut boxes); strip_ignorable_whitespace_from_end(&mut fragments);
if boxes.len() == 0 { if fragments.len() == 0 {
return return
} }
} }
} }
let mut inline_flow = box InlineFlow::from_boxes((*node).clone(), boxes); let mut inline_flow = box InlineFlow::from_fragments((*node).clone(), fragments);
inline_flow.compute_minimum_ascent_and_descent(self.font_context(), &**node.style()); inline_flow.compute_minimum_ascent_and_descent(self.font_context(), &**node.style());
let mut inline_flow = inline_flow as owned::Box<Flow:Share>; let mut inline_flow = inline_flow as Box<Flow:Share>;
TextRunScanner::new().scan_for_runs(self.font_context(), inline_flow); TextRunScanner::new().scan_for_runs(self.font_context(), inline_flow);
inline_flow.finish(self.layout_context); inline_flow.finish(self.layout_context);
@ -342,15 +341,15 @@ impl<'a> FlowConstructor<'a> {
} }
fn build_block_flow_using_children_construction_result(&mut self, fn build_block_flow_using_children_construction_result(&mut self,
flow: &mut owned::Box<Flow:Share>, flow: &mut Box<Flow:Share>,
consecutive_siblings: consecutive_siblings:
&mut Vec<owned::Box<Flow:Share>>, &mut Vec<Box<Flow:Share>>,
node: &ThreadSafeLayoutNode, node: &ThreadSafeLayoutNode,
kid: ThreadSafeLayoutNode, kid: ThreadSafeLayoutNode,
inline_box_accumulator: inline_fragment_accumulator:
&mut InlineBoxAccumulator, &mut InlineFragmentsAccumulator,
abs_descendants: &mut Descendants, abs_descendants: &mut Descendants,
first_box: &mut bool) { first_fragment: &mut bool) {
match kid.swap_out_construction_result() { match kid.swap_out_construction_result() {
NoConstructionResult => {} NoConstructionResult => {}
FlowConstructionResult(kid_flow, kid_abs_descendants) => { FlowConstructionResult(kid_flow, kid_abs_descendants) => {
@ -365,19 +364,19 @@ impl<'a> FlowConstructor<'a> {
} else { } else {
// Strip ignorable whitespace from the start of this flow per CSS 2.1 § // Strip ignorable whitespace from the start of this flow per CSS 2.1 §
// 9.2.1.1. // 9.2.1.1.
let whitespace_stripping = if flow.is_table_kind() || *first_box { let whitespace_stripping = if flow.is_table_kind() || *first_fragment {
*first_box = false; *first_fragment = false;
StripWhitespaceFromStart StripWhitespaceFromStart
} else { } else {
NoWhitespaceStripping NoWhitespaceStripping
}; };
// Flush any inline boxes that we were gathering up. This allows us to handle // Flush any inline fragments that we were gathering up. This allows us to handle
// {ib} splits. // {ib} splits.
debug!("flushing {} inline box(es) to flow A", debug!("flushing {} inline box(es) to flow A",
inline_box_accumulator.boxes.len()); inline_fragment_accumulator.fragments.len());
self.flush_inline_boxes_to_flow_or_list( self.flush_inline_fragments_to_flow_or_list(
mem::replace(inline_box_accumulator, InlineBoxAccumulator::new()), mem::replace(inline_fragment_accumulator, InlineFragmentsAccumulator::new()),
flow, flow,
consecutive_siblings, consecutive_siblings,
whitespace_stripping, whitespace_stripping,
@ -392,37 +391,37 @@ impl<'a> FlowConstructor<'a> {
} }
abs_descendants.push_descendants(kid_abs_descendants); abs_descendants.push_descendants(kid_abs_descendants);
} }
ConstructionItemConstructionResult(InlineBoxesConstructionItem( ConstructionItemConstructionResult(InlineFragmentsConstructionItem(
InlineBoxesConstructionResult { InlineFragmentsConstructionResult {
splits: splits, splits: splits,
boxes: successor_boxes, fragments: successor_fragments,
abs_descendants: kid_abs_descendants, abs_descendants: kid_abs_descendants,
})) => { })) => {
// Add any {ib} splits. // Add any {ib} splits.
for split in splits.move_iter() { for split in splits.move_iter() {
// Pull apart the {ib} split object and push its predecessor boxes // Pull apart the {ib} split object and push its predecessor fragments
// onto the list. // onto the list.
let InlineBlockSplit { let InlineBlockSplit {
predecessors: predecessors, predecessors: predecessors,
flow: kid_flow flow: kid_flow
} = split; } = split;
inline_box_accumulator.boxes.push_all(predecessors); inline_fragment_accumulator.fragments.push_all(predecessors);
// If this is the first box in flow, then strip ignorable // If this is the first fragment in flow, then strip ignorable
// whitespace per CSS 2.1 § 9.2.1.1. // whitespace per CSS 2.1 § 9.2.1.1.
let whitespace_stripping = if *first_box { let whitespace_stripping = if *first_fragment {
*first_box = false; *first_fragment = false;
StripWhitespaceFromStart StripWhitespaceFromStart
} else { } else {
NoWhitespaceStripping NoWhitespaceStripping
}; };
// Flush any inline boxes that we were gathering up. // Flush any inline fragments that we were gathering up.
debug!("flushing {} inline box(es) to flow A", debug!("flushing {} inline box(es) to flow A",
inline_box_accumulator.boxes.len()); inline_fragment_accumulator.fragments.len());
self.flush_inline_boxes_to_flow_or_list( self.flush_inline_fragments_to_flow_or_list(
mem::replace(inline_box_accumulator, mem::replace(inline_fragment_accumulator,
InlineBoxAccumulator::new()), InlineFragmentsAccumulator::new()),
flow, flow,
consecutive_siblings, consecutive_siblings,
whitespace_stripping, whitespace_stripping,
@ -437,14 +436,14 @@ impl<'a> FlowConstructor<'a> {
} }
} }
// Add the boxes to the list we're maintaining. // Add the fragments to the list we're maintaining.
inline_box_accumulator.boxes.push_all(successor_boxes); inline_fragment_accumulator.fragments.push_all(successor_fragments);
abs_descendants.push_descendants(kid_abs_descendants); abs_descendants.push_descendants(kid_abs_descendants);
} }
ConstructionItemConstructionResult(WhitespaceConstructionItem(..)) => { ConstructionItemConstructionResult(WhitespaceConstructionItem(..)) => {
// Nothing to do here. // Nothing to do here.
} }
ConstructionItemConstructionResult(TableColumnBoxConstructionItem(_)) => { ConstructionItemConstructionResult(TableColumnFragmentConstructionItem(_)) => {
// TODO: Implement anonymous table objects for missing parents // TODO: Implement anonymous table objects for missing parents
// CSS 2.1 § 17.2.1, step 3-2 // CSS 2.1 § 17.2.1, step 3-2
} }
@ -459,13 +458,13 @@ impl<'a> FlowConstructor<'a> {
/// Also, deal with the absolute and fixed descendants bubbled up by /// Also, deal with the absolute and fixed descendants bubbled up by
/// children nodes. /// children nodes.
fn build_flow_using_children(&mut self, fn build_flow_using_children(&mut self,
mut flow: owned::Box<Flow:Share>, mut flow: Box<Flow:Share>,
node: &ThreadSafeLayoutNode) node: &ThreadSafeLayoutNode)
-> ConstructionResult { -> ConstructionResult {
// Gather up boxes for the inline flows we might need to create. // Gather up fragments for the inline flows we might need to create.
let mut inline_box_accumulator = InlineBoxAccumulator::new(); let mut inline_fragment_accumulator = InlineFragmentsAccumulator::new();
let mut consecutive_siblings = vec!(); let mut consecutive_siblings = vec!();
let mut first_box = true; let mut first_fragment = true;
// List of absolute descendants, in tree order. // List of absolute descendants, in tree order.
let mut abs_descendants = Descendants::new(); let mut abs_descendants = Descendants::new();
@ -478,14 +477,14 @@ impl<'a> FlowConstructor<'a> {
&mut consecutive_siblings, &mut consecutive_siblings,
node, node,
kid, kid,
&mut inline_box_accumulator, &mut inline_fragment_accumulator,
&mut abs_descendants, &mut abs_descendants,
&mut first_box); &mut first_fragment);
} }
// Perform a final flush of any inline boxes that we were gathering up to handle {ib} // Perform a final flush of any inline fragments that we were gathering up to handle {ib}
// splits, after stripping ignorable whitespace. // splits, after stripping ignorable whitespace.
self.flush_inline_boxes_to_flow_or_list(inline_box_accumulator, self.flush_inline_fragments_to_flow_or_list(inline_fragment_accumulator,
&mut flow, &mut flow,
&mut consecutive_siblings, &mut consecutive_siblings,
StripWhitespaceFromEnd, StripWhitespaceFromEnd,
@ -517,7 +516,7 @@ impl<'a> FlowConstructor<'a> {
/// other `BlockFlow`s or `InlineFlow`s underneath it, depending on whether {ib} splits needed /// other `BlockFlow`s or `InlineFlow`s underneath it, depending on whether {ib} splits needed
/// to happen. /// to happen.
fn build_flow_for_block(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult { fn build_flow_for_block(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult {
let flow = box BlockFlow::from_node(self, node) as owned::Box<Flow:Share>; let flow = box BlockFlow::from_node(self, node) as Box<Flow:Share>;
self.build_flow_using_children(flow, node) self.build_flow_using_children(flow, node)
} }
@ -525,20 +524,20 @@ impl<'a> FlowConstructor<'a> {
/// a `BlockFlow` underneath it. /// a `BlockFlow` underneath it.
fn build_flow_for_floated_block(&mut self, node: &ThreadSafeLayoutNode, float_kind: FloatKind) fn build_flow_for_floated_block(&mut self, node: &ThreadSafeLayoutNode, float_kind: FloatKind)
-> ConstructionResult { -> ConstructionResult {
let flow = box BlockFlow::float_from_node(self, node, float_kind) as owned::Box<Flow:Share>; let flow = box BlockFlow::float_from_node(self, node, float_kind) as Box<Flow:Share>;
self.build_flow_using_children(flow, node) self.build_flow_using_children(flow, node)
} }
/// Concatenates the boxes of kids, adding in our own borders/padding/margins if necessary. /// Concatenates the fragments of kids, adding in our own borders/padding/margins if necessary.
/// Returns the `InlineBoxesConstructionResult`, if any. There will be no /// Returns the `InlineFragmentsConstructionResult`, if any. There will be no
/// `InlineBoxesConstructionResult` if this node consisted entirely of ignorable whitespace. /// `InlineFragmentsConstructionResult` if this node consisted entirely of ignorable whitespace.
fn build_boxes_for_nonreplaced_inline_content(&mut self, node: &ThreadSafeLayoutNode) fn build_fragments_for_nonreplaced_inline_content(&mut self, node: &ThreadSafeLayoutNode)
-> ConstructionResult { -> ConstructionResult {
let mut opt_inline_block_splits: Vec<InlineBlockSplit> = Vec::new(); let mut opt_inline_block_splits: Vec<InlineBlockSplit> = Vec::new();
let mut box_accumulator = InlineBoxAccumulator::from_inline_node(node); let mut fragment_accumulator = InlineFragmentsAccumulator::from_inline_node(node);
let mut abs_descendants = Descendants::new(); let mut abs_descendants = Descendants::new();
// Concatenate all the boxes of our kids, creating {ib} splits as necessary. // Concatenate all the fragments of our kids, creating {ib} splits as necessary.
for kid in node.children() { for kid in node.children() {
if kid.get_pseudo_element_type() != Normal { if kid.get_pseudo_element_type() != Normal {
self.process(&kid); self.process(&kid);
@ -547,20 +546,20 @@ impl<'a> FlowConstructor<'a> {
NoConstructionResult => {} NoConstructionResult => {}
FlowConstructionResult(flow, kid_abs_descendants) => { FlowConstructionResult(flow, kid_abs_descendants) => {
// {ib} split. Flush the accumulator to our new split and make a new // {ib} split. Flush the accumulator to our new split and make a new
// accumulator to hold any subsequent boxes we come across. // accumulator to hold any subsequent fragments we come across.
let split = InlineBlockSplit { let split = InlineBlockSplit {
predecessors: predecessors:
mem::replace(&mut box_accumulator, mem::replace(&mut fragment_accumulator,
InlineBoxAccumulator::from_inline_node(node)).finish(), InlineFragmentsAccumulator::from_inline_node(node)).finish(),
flow: flow, flow: flow,
}; };
opt_inline_block_splits.push(split); opt_inline_block_splits.push(split);
abs_descendants.push_descendants(kid_abs_descendants); abs_descendants.push_descendants(kid_abs_descendants);
} }
ConstructionItemConstructionResult(InlineBoxesConstructionItem( ConstructionItemConstructionResult(InlineFragmentsConstructionItem(
InlineBoxesConstructionResult { InlineFragmentsConstructionResult {
splits: splits, splits: splits,
boxes: successors, fragments: successors,
abs_descendants: kid_abs_descendants, abs_descendants: kid_abs_descendants,
})) => { })) => {
@ -570,33 +569,33 @@ impl<'a> FlowConstructor<'a> {
predecessors: predecessors, predecessors: predecessors,
flow: kid_flow flow: kid_flow
} = split; } = split;
box_accumulator.boxes.push_all(predecessors); fragment_accumulator.fragments.push_all(predecessors);
let split = InlineBlockSplit { let split = InlineBlockSplit {
predecessors: predecessors:
mem::replace(&mut box_accumulator, mem::replace(&mut fragment_accumulator,
InlineBoxAccumulator::from_inline_node(node)) InlineFragmentsAccumulator::from_inline_node(node))
.finish(), .finish(),
flow: kid_flow, flow: kid_flow,
}; };
opt_inline_block_splits.push(split) opt_inline_block_splits.push(split)
} }
// Push residual boxes. // Push residual fragments.
box_accumulator.boxes.push_all(successors); fragment_accumulator.fragments.push_all(successors);
abs_descendants.push_descendants(kid_abs_descendants); abs_descendants.push_descendants(kid_abs_descendants);
} }
ConstructionItemConstructionResult(WhitespaceConstructionItem(whitespace_node, ConstructionItemConstructionResult(WhitespaceConstructionItem(whitespace_node,
whitespace_style)) whitespace_style))
=> { => {
// Instantiate the whitespace box. // Instantiate the whitespace fragment.
let box_info = UnscannedTextBox(UnscannedTextBoxInfo::from_text(" ".to_owned())); let fragment_info = UnscannedTextFragment(UnscannedTextFragmentInfo::from_text(" ".to_owned()));
let fragment = Box::from_opaque_node_and_style(whitespace_node, let fragment = Fragment::from_opaque_node_and_style(whitespace_node,
whitespace_style.clone(), whitespace_style.clone(),
box_info); fragment_info);
box_accumulator.boxes.push(fragment, whitespace_style) fragment_accumulator.fragments.push(fragment, whitespace_style)
} }
ConstructionItemConstructionResult(TableColumnBoxConstructionItem(_)) => { ConstructionItemConstructionResult(TableColumnFragmentConstructionItem(_)) => {
// TODO: Implement anonymous table objects for missing parents // TODO: Implement anonymous table objects for missing parents
// CSS 2.1 § 17.2.1, step 3-2 // CSS 2.1 § 17.2.1, step 3-2
} }
@ -604,11 +603,11 @@ impl<'a> FlowConstructor<'a> {
} }
// Finally, make a new construction result. // Finally, make a new construction result.
if opt_inline_block_splits.len() > 0 || box_accumulator.boxes.len() > 0 if opt_inline_block_splits.len() > 0 || fragment_accumulator.fragments.len() > 0
|| abs_descendants.len() > 0 { || abs_descendants.len() > 0 {
let construction_item = InlineBoxesConstructionItem(InlineBoxesConstructionResult { let construction_item = InlineFragmentsConstructionItem(InlineFragmentsConstructionResult {
splits: opt_inline_block_splits, splits: opt_inline_block_splits,
boxes: box_accumulator.finish(), fragments: fragment_accumulator.finish(),
abs_descendants: abs_descendants, abs_descendants: abs_descendants,
}); });
ConstructionItemConstructionResult(construction_item) ConstructionItemConstructionResult(construction_item)
@ -617,9 +616,9 @@ impl<'a> FlowConstructor<'a> {
} }
} }
/// Creates an `InlineBoxesConstructionResult` for replaced content. Replaced content doesn't /// Creates an `InlineFragmentsConstructionResult` for replaced content. Replaced content doesn't
/// render its children, so this just nukes a child's boxes and creates a `Box`. /// render its children, so this just nukes a child's fragments and creates a `Fragment`.
fn build_boxes_for_replaced_inline_content(&mut self, node: &ThreadSafeLayoutNode) fn build_fragments_for_replaced_inline_content(&mut self, node: &ThreadSafeLayoutNode)
-> ConstructionResult { -> ConstructionResult {
for kid in node.children() { for kid in node.children() {
kid.set_flow_construction_result(NoConstructionResult) kid.set_flow_construction_result(NoConstructionResult)
@ -635,33 +634,34 @@ impl<'a> FlowConstructor<'a> {
node.style().clone())) node.style().clone()))
} }
let mut boxes = InlineBoxes::new(); let mut fragments = InlineFragments::new();
boxes.push(Box::new(self, node), node.style().clone()); fragments.push(Fragment::new(self, node), node.style().clone());
let construction_item = InlineBoxesConstructionItem(InlineBoxesConstructionResult { let construction_item = InlineFragmentsConstructionItem(InlineFragmentsConstructionResult {
splits: Vec::new(), splits: Vec::new(),
boxes: boxes, fragments: fragments,
abs_descendants: Descendants::new(), abs_descendants: Descendants::new(),
}); });
ConstructionItemConstructionResult(construction_item) ConstructionItemConstructionResult(construction_item)
} }
/// Builds one or more boxes for a node with `display: inline`. This yields an /// Builds one or more fragments for a node with `display: inline`. This yields an
/// `InlineBoxesConstructionResult`. /// `InlineFragmentsConstructionResult`.
fn build_boxes_for_inline(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult { fn build_fragments_for_inline(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult {
// Is this node replaced content? // Is this node replaced content?
if !node.is_replaced_content() { if !node.is_replaced_content() {
// Go to a path that concatenates our kids' boxes. // Go to a path that concatenates our kids' fragments.
self.build_boxes_for_nonreplaced_inline_content(node) self.build_fragments_for_nonreplaced_inline_content(node)
} else { } else {
// Otherwise, just nuke our kids' boxes, create our box if any, and be done with it. // Otherwise, just nuke our kids' fragments, create our fragment if any, and be done
self.build_boxes_for_replaced_inline_content(node) // with it.
self.build_fragments_for_replaced_inline_content(node)
} }
} }
/// TableCaptionFlow is populated underneath TableWrapperFlow /// TableCaptionFlow is populated underneath TableWrapperFlow
fn place_table_caption_under_table_wrapper(&mut self, fn place_table_caption_under_table_wrapper(&mut self,
table_wrapper_flow: &mut owned::Box<Flow:Share>, table_wrapper_flow: &mut Box<Flow:Share>,
node: &ThreadSafeLayoutNode) { node: &ThreadSafeLayoutNode) {
for kid in node.children() { for kid in node.children() {
match kid.swap_out_construction_result() { match kid.swap_out_construction_result() {
@ -678,8 +678,8 @@ impl<'a> FlowConstructor<'a> {
/// Generates an anonymous table flow according to CSS 2.1 § 17.2.1, step 2. /// Generates an anonymous table flow according to CSS 2.1 § 17.2.1, step 2.
/// If necessary, generate recursively another anonymous table flow. /// If necessary, generate recursively another anonymous table flow.
fn generate_anonymous_missing_child(&mut self, fn generate_anonymous_missing_child(&mut self,
child_flows: Vec<owned::Box<Flow:Share>>, child_flows: Vec<Box<Flow:Share>>,
flow: &mut owned::Box<Flow:Share>, flow: &mut Box<Flow:Share>,
node: &ThreadSafeLayoutNode) { node: &ThreadSafeLayoutNode) {
let mut anonymous_flow = flow.generate_missing_child_flow(node); let mut anonymous_flow = flow.generate_missing_child_flow(node);
let mut consecutive_siblings = vec!(); let mut consecutive_siblings = vec!();
@ -705,11 +705,11 @@ impl<'a> FlowConstructor<'a> {
/// Builds a flow for a node with `display: table`. This yields a `TableWrapperFlow` with possibly /// Builds a flow for a node with `display: table`. This yields a `TableWrapperFlow` with possibly
/// other `TableCaptionFlow`s or `TableFlow`s underneath it. /// other `TableCaptionFlow`s or `TableFlow`s underneath it.
fn build_flow_for_table_wrapper(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult { fn build_flow_for_table_wrapper(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult {
let box_ = Box::new_from_specific_info(node, TableWrapperBox); let fragment = Fragment::new_from_specific_info(node, TableWrapperFragment);
let mut wrapper_flow = box TableWrapperFlow::from_node_and_box(node, box_) as owned::Box<Flow:Share>; let mut wrapper_flow = box TableWrapperFlow::from_node_and_fragment(node, fragment) as Box<Flow:Share>;
let table_box_ = Box::new_from_specific_info(node, TableBox); let table_fragment = Fragment::new_from_specific_info(node, TableFragment);
let table_flow = box TableFlow::from_node_and_box(node, table_box_) as owned::Box<Flow:Share>; let table_flow = box TableFlow::from_node_and_fragment(node, table_fragment) as Box<Flow:Share>;
// We first populate the TableFlow with other flows than TableCaptionFlow. // We first populate the TableFlow with other flows than TableCaptionFlow.
// We then populate the TableWrapperFlow with TableCaptionFlow, and attach // We then populate the TableWrapperFlow with TableCaptionFlow, and attach
@ -755,44 +755,44 @@ impl<'a> FlowConstructor<'a> {
/// Builds a flow for a node with `display: table-caption`. This yields a `TableCaptionFlow` /// Builds a flow for a node with `display: table-caption`. This yields a `TableCaptionFlow`
/// with possibly other `BlockFlow`s or `InlineFlow`s underneath it. /// with possibly other `BlockFlow`s or `InlineFlow`s underneath it.
fn build_flow_for_table_caption(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult { fn build_flow_for_table_caption(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult {
let flow = box TableCaptionFlow::from_node(self, node) as owned::Box<Flow:Share>; let flow = box TableCaptionFlow::from_node(self, node) as Box<Flow:Share>;
self.build_flow_using_children(flow, node) self.build_flow_using_children(flow, node)
} }
/// Builds a flow for a node with `display: table-row-group`. This yields a `TableRowGroupFlow` /// Builds a flow for a node with `display: table-row-group`. This yields a `TableRowGroupFlow`
/// with possibly other `TableRowFlow`s underneath it. /// with possibly other `TableRowFlow`s underneath it.
fn build_flow_for_table_rowgroup(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult { fn build_flow_for_table_rowgroup(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult {
let box_ = Box::new_from_specific_info(node, TableRowBox); let fragment = Fragment::new_from_specific_info(node, TableRowFragment);
let flow = box TableRowGroupFlow::from_node_and_box(node, box_) as owned::Box<Flow:Share>; let flow = box TableRowGroupFlow::from_node_and_fragment(node, fragment) as Box<Flow:Share>;
self.build_flow_using_children(flow, node) self.build_flow_using_children(flow, node)
} }
/// Builds a flow for a node with `display: table-row`. This yields a `TableRowFlow` with /// Builds a flow for a node with `display: table-row`. This yields a `TableRowFlow` with
/// possibly other `TableCellFlow`s underneath it. /// possibly other `TableCellFlow`s underneath it.
fn build_flow_for_table_row(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult { fn build_flow_for_table_row(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult {
let box_ = Box::new_from_specific_info(node, TableRowBox); let fragment = Fragment::new_from_specific_info(node, TableRowFragment);
let flow = box TableRowFlow::from_node_and_box(node, box_) as owned::Box<Flow:Share>; let flow = box TableRowFlow::from_node_and_fragment(node, fragment) as Box<Flow:Share>;
self.build_flow_using_children(flow, node) self.build_flow_using_children(flow, node)
} }
/// Builds a flow for a node with `display: table-cell`. This yields a `TableCellFlow` with /// Builds a flow for a node with `display: table-cell`. This yields a `TableCellFlow` with
/// possibly other `BlockFlow`s or `InlineFlow`s underneath it. /// possibly other `BlockFlow`s or `InlineFlow`s underneath it.
fn build_flow_for_table_cell(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult { fn build_flow_for_table_cell(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult {
let box_ = Box::new_from_specific_info(node, TableCellBox); let fragment = Fragment::new_from_specific_info(node, TableCellFragment);
let flow = box TableCellFlow::from_node_and_box(node, box_) as owned::Box<Flow:Share>; let flow = box TableCellFlow::from_node_and_fragment(node, fragment) as Box<Flow:Share>;
self.build_flow_using_children(flow, node) self.build_flow_using_children(flow, node)
} }
/// Creates a box for a node with `display: table-column`. /// Creates a fragment for a node with `display: table-column`.
fn build_boxes_for_table_column(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult { fn build_fragments_for_table_column(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult {
// CSS 2.1 § 17.2.1. Treat all child boxes of a `table-column` as `display: none`. // CSS 2.1 § 17.2.1. Treat all child fragments of a `table-column` as `display: none`.
for kid in node.children() { for kid in node.children() {
kid.set_flow_construction_result(NoConstructionResult) kid.set_flow_construction_result(NoConstructionResult)
} }
let specific = TableColumnBox(TableColumnBoxInfo::new(node)); let specific = TableColumnFragment(TableColumnFragmentInfo::new(node));
let construction_item = TableColumnBoxConstructionItem( let construction_item = TableColumnFragmentConstructionItem(
Box::new_from_specific_info(node, specific) Fragment::new_from_specific_info(node, specific)
); );
ConstructionItemConstructionResult(construction_item) ConstructionItemConstructionResult(construction_item)
} }
@ -800,26 +800,25 @@ impl<'a> FlowConstructor<'a> {
/// Builds a flow for a node with `display: table-column-group`. /// Builds a flow for a node with `display: table-column-group`.
/// This yields a `TableColGroupFlow`. /// This yields a `TableColGroupFlow`.
fn build_flow_for_table_colgroup(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult { fn build_flow_for_table_colgroup(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult {
let box_ = Box::new_from_specific_info(node, let fragment = Fragment::new_from_specific_info(node,
TableColumnBox(TableColumnBoxInfo::new(node))); TableColumnFragment(TableColumnFragmentInfo::new(node)));
let mut col_boxes = vec!(); let mut col_fragments = vec!();
for kid in node.children() { for kid in node.children() {
// CSS 2.1 § 17.2.1. Treat all non-column child boxes of `table-column-group` // CSS 2.1 § 17.2.1. Treat all non-column child fragments of `table-column-group`
// as `display: none`. // as `display: none`.
match kid.swap_out_construction_result() { match kid.swap_out_construction_result() {
ConstructionItemConstructionResult(TableColumnBoxConstructionItem(box_)) => { ConstructionItemConstructionResult(TableColumnFragmentConstructionItem(fragment)) => {
col_boxes.push(box_); col_fragments.push(fragment);
} }
_ => {} _ => {}
} }
} }
if col_boxes.is_empty() { if col_fragments.is_empty() {
debug!("add TableColumnBox for empty colgroup"); debug!("add TableColumnFragment for empty colgroup");
let specific = TableColumnBox(TableColumnBoxInfo::new(node)); let specific = TableColumnFragment(TableColumnFragmentInfo::new(node));
col_boxes.push( Box::new_from_specific_info(node, specific) ); col_fragments.push(Fragment::new_from_specific_info(node, specific));
} }
let mut flow = box TableColGroupFlow::from_node_and_boxes(node, box_, col_boxes) as let mut flow = box TableColGroupFlow::from_node_and_fragments(node, fragment, col_fragments) as Box<Flow:Share>;
owned::Box<Flow:Share>;
flow.finish(self.layout_context); flow.finish(self.layout_context);
FlowConstructionResult(flow, Descendants::new()) FlowConstructionResult(flow, Descendants::new())
@ -888,9 +887,9 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
node.set_flow_construction_result(self.build_flow_for_block(node)) node.set_flow_construction_result(self.build_flow_for_block(node))
} }
// Inline items contribute inline box construction results. // Inline items contribute inline fragment construction results.
(display::inline, float::none, _) => { (display::inline, float::none, _) => {
let construction_result = self.build_boxes_for_inline(node); let construction_result = self.build_fragments_for_inline(node);
node.set_flow_construction_result(construction_result) node.set_flow_construction_result(construction_result)
} }
@ -908,7 +907,7 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
// Table items contribute table flow construction results. // Table items contribute table flow construction results.
(display::table_column, _, _) => { (display::table_column, _, _) => {
let construction_result = self.build_boxes_for_table_column(node); let construction_result = self.build_fragments_for_table_column(node);
node.set_flow_construction_result(construction_result) node.set_flow_construction_result(construction_result)
} }
@ -1086,57 +1085,57 @@ impl<'ln> ObjectElement for ThreadSafeLayoutNode<'ln> {
} }
} }
/// Strips ignorable whitespace from the start of a list of boxes. /// Strips ignorable whitespace from the start of a list of fragments.
fn strip_ignorable_whitespace_from_start(boxes: &mut InlineBoxes) { fn strip_ignorable_whitespace_from_start(fragments: &mut InlineFragments) {
if boxes.len() == 0 { if fragments.len() == 0 {
return return
} }
let InlineBoxes { let InlineFragments {
boxes: old_boxes, fragments: old_fragments,
map: mut map map: mut map
} = mem::replace(boxes, InlineBoxes::new()); } = mem::replace(fragments, InlineFragments::new());
// FIXME(#2264, pcwalton): This is slow because vector shift is broken. :( // FIXME(#2264, pcwalton): This is slow because vector shift is broken. :(
let mut found_nonwhitespace = false; let mut found_nonwhitespace = false;
let mut new_boxes = Vec::new(); let mut new_fragments = Vec::new();
for fragment in old_boxes.iter() { for fragment in old_fragments.iter() {
if !found_nonwhitespace && fragment.is_whitespace_only() { if !found_nonwhitespace && fragment.is_whitespace_only() {
debug!("stripping ignorable whitespace from start"); debug!("stripping ignorable whitespace from start");
continue continue
} }
found_nonwhitespace = true; found_nonwhitespace = true;
new_boxes.push(fragment.clone()) new_fragments.push(fragment.clone())
} }
map.fixup(old_boxes.as_slice(), new_boxes.as_slice()); map.fixup(old_fragments.as_slice(), new_fragments.as_slice());
*boxes = InlineBoxes { *fragments = InlineFragments {
boxes: new_boxes, fragments: new_fragments,
map: map, map: map,
} }
} }
/// Strips ignorable whitespace from the end of a list of boxes. /// Strips ignorable whitespace from the end of a list of fragments.
fn strip_ignorable_whitespace_from_end(boxes: &mut InlineBoxes) { fn strip_ignorable_whitespace_from_end(fragments: &mut InlineFragments) {
if boxes.len() == 0 { if fragments.len() == 0 {
return return
} }
let InlineBoxes { let InlineFragments {
boxes: old_boxes, fragments: old_fragments,
map: mut map map: mut map
} = mem::replace(boxes, InlineBoxes::new()); } = mem::replace(fragments, InlineFragments::new());
let mut new_boxes = old_boxes.clone(); let mut new_fragments = old_fragments.clone();
while new_boxes.len() > 0 && new_boxes.as_slice().last().get_ref().is_whitespace_only() { while new_fragments.len() > 0 && new_fragments.as_slice().last().get_ref().is_whitespace_only() {
debug!("stripping ignorable whitespace from end"); debug!("stripping ignorable whitespace from end");
drop(new_boxes.pop()); drop(new_fragments.pop());
} }
map.fixup(old_boxes.as_slice(), new_boxes.as_slice()); map.fixup(old_fragments.as_slice(), new_fragments.as_slice());
*boxes = InlineBoxes { *fragments = InlineFragments {
boxes: new_boxes, fragments: new_fragments,
map: map, map: map,
} }
} }

View file

@ -18,7 +18,7 @@ pub trait LayoutAuxMethods {
impl<'ln> LayoutAuxMethods for LayoutNode<'ln> { impl<'ln> LayoutAuxMethods for LayoutNode<'ln> {
/// Resets layout data and styles for the node. /// Resets layout data and styles for the node.
/// ///
/// FIXME(pcwalton): Do this as part of box building instead of in a traversal. /// FIXME(pcwalton): Do this as part of fragment building instead of in a traversal.
fn initialize_layout_data(&self, chan: LayoutChan) { fn initialize_layout_data(&self, chan: LayoutChan) {
let mut layout_data_ref = self.mutate_layout_data(); let mut layout_data_ref = self.mutate_layout_data();
match *layout_data_ref { match *layout_data_ref {
@ -35,7 +35,7 @@ impl<'ln> LayoutAuxMethods for LayoutNode<'ln> {
/// Resets layout data and styles for a Node tree. /// Resets layout data and styles for a Node tree.
/// ///
/// FIXME(pcwalton): Do this as part of box building instead of in a traversal. /// FIXME(pcwalton): Do this as part of fragment building instead of in a traversal.
fn initialize_style_for_subtree(&self, chan: LayoutChan) { fn initialize_style_for_subtree(&self, chan: LayoutChan) {
for n in self.traverse_preorder() { for n in self.traverse_preorder() {
n.initialize_layout_data(chan.clone()); n.initialize_layout_data(chan.clone());

View file

@ -320,7 +320,7 @@ impl Floats {
max_height.map(|h| h + self.offset.y) max_height.map(|h| h + self.offset.y)
} }
/// Given placement information, finds the closest place a box can be positioned without /// Given placement information, finds the closest place a fragment can be positioned without
/// colliding with any floats. /// colliding with any floats.
pub fn place_between_floats(&self, info: &PlacementInfo) -> Rect<Au> { pub fn place_between_floats(&self, info: &PlacementInfo) -> Rect<Au> {
debug!("place_between_floats: Placing object with width {} and height {}", debug!("place_between_floats: Placing object with width {} and height {}",

View file

@ -2,14 +2,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//! Servo's experimental layout system builds a tree of `Flow` and `Box` objects and solves //! Servo's experimental layout system builds a tree of `Flow` and `Fragment` objects and solves
//! layout constraints to obtain positions and display attributes of tree nodes. Positions are //! layout constraints to obtain positions and display attributes of tree nodes. Positions are
//! computed in several tree traversals driven by the fundamental data dependencies required by //! computed in several tree traversals driven by the fundamental data dependencies required by
/// inline and block layout. /// inline and block layout.
/// ///
/// Flows are interior nodes in the layout tree and correspond closely to *flow contexts* in the /// Flows are interior nodes in the layout tree and correspond closely to *flow contexts* in the
/// CSS specification. Flows are responsible for positioning their child flow contexts and boxes. /// CSS specification. Flows are responsible for positioning their child flow contexts and fragments.
/// Flows have purpose-specific fields, such as auxiliary line box structs, out-of-flow child /// Flows have purpose-specific fields, such as auxiliary line structs, out-of-flow child
/// lists, and so on. /// lists, and so on.
/// ///
/// Currently, the important types of flows are: /// Currently, the important types of flows are:
@ -21,16 +21,16 @@
/// the viewport. /// the viewport.
/// ///
/// * `InlineFlow`: A flow that establishes an inline context. It has a flat list of child /// * `InlineFlow`: A flow that establishes an inline context. It has a flat list of child
/// boxes/flows that are subject to inline layout and line breaking and structs to represent /// fragments/flows that are subject to inline layout and line breaking and structs to represent
/// line breaks and mapping to CSS boxes, for the purpose of handling `getClientRects()` and /// line breaks and mapping to CSS boxes, for the purpose of handling `getClientRects()` and
/// similar methods. /// similar methods.
use css::node_style::StyledNode; use css::node_style::StyledNode;
use layout::block::BlockFlow; use layout::block::BlockFlow;
use layout::box_::{Box, TableRowBox, TableCellBox};
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::floats::Floats; use layout::floats::Floats;
use layout::flow_list::{FlowList, Link, Rawlink, FlowListIterator, MutFlowListIterator}; use layout::flow_list::{FlowList, Link, Rawlink, FlowListIterator, MutFlowListIterator};
use layout::fragment::{Fragment, TableRowFragment, TableCellFragment};
use layout::incremental::RestyleDamage; use layout::incremental::RestyleDamage;
use layout::inline::InlineFlow; use layout::inline::InlineFlow;
use layout::model::{CollapsibleMargins, IntrinsicWidths, MarginCollapseInfo}; use layout::model::{CollapsibleMargins, IntrinsicWidths, MarginCollapseInfo};
@ -58,7 +58,6 @@ use std::cast;
use std::fmt; use std::fmt;
use std::iter::Zip; use std::iter::Zip;
use std::num::Zero; use std::num::Zero;
use std::owned;
use std::sync::atomics::Relaxed; use std::sync::atomics::Relaxed;
use std::slice::MutItems; use std::slice::MutItems;
use style::computed_values::{clear, position, text_align}; use style::computed_values::{clear, position, text_align};
@ -338,7 +337,7 @@ pub trait ImmutableFlowUtils {
fn need_anonymous_flow(self, child: &Flow) -> bool; fn need_anonymous_flow(self, child: &Flow) -> bool;
/// Generates missing child flow of this flow. /// Generates missing child flow of this flow.
fn generate_missing_child_flow(self, node: &ThreadSafeLayoutNode) -> owned::Box<Flow:Share>; fn generate_missing_child_flow(self, node: &ThreadSafeLayoutNode) -> Box<Flow:Share>;
/// Returns true if this flow has no children. /// Returns true if this flow has no children.
fn is_leaf(self) -> bool; fn is_leaf(self) -> bool;
@ -392,7 +391,7 @@ pub trait MutableFlowUtils {
pub trait MutableOwnedFlowUtils { pub trait MutableOwnedFlowUtils {
/// Adds a new flow as a child of this flow. Removes the flow from the given leaf set if /// Adds a new flow as a child of this flow. Removes the flow from the given leaf set if
/// it's present. /// it's present.
fn add_new_child(&mut self, new_child: owned::Box<Flow:Share>); fn add_new_child(&mut self, new_child: Box<Flow:Share>);
/// Finishes a flow. Once a flow is finished, no more child flows or boxes may be added to it. /// Finishes a flow. Once a flow is finished, no more child flows or boxes may be added to it.
/// This will normally run the bubble-widths (minimum and preferred -- i.e. intrinsic -- width) /// This will normally run the bubble-widths (minimum and preferred -- i.e. intrinsic -- width)
@ -842,15 +841,15 @@ impl<'a> ImmutableFlowUtils for &'a Flow {
} }
/// Generates missing child flow of this flow. /// Generates missing child flow of this flow.
fn generate_missing_child_flow(self, node: &ThreadSafeLayoutNode) -> owned::Box<Flow:Share> { fn generate_missing_child_flow(self, node: &ThreadSafeLayoutNode) -> Box<Flow:Share> {
match self.class() { match self.class() {
TableFlowClass | TableRowGroupFlowClass => { TableFlowClass | TableRowGroupFlowClass => {
let box_ = Box::new_anonymous_table_box(node, TableRowBox); let fragment = Fragment::new_anonymous_table_fragment(node, TableRowFragment);
box TableRowFlow::from_node_and_box(node, box_) as owned::Box<Flow:Share> box TableRowFlow::from_node_and_fragment(node, fragment) as Box<Flow:Share>
}, },
TableRowFlowClass => { TableRowFlowClass => {
let box_ = Box::new_anonymous_table_box(node, TableCellBox); let fragment = Fragment::new_anonymous_table_fragment(node, TableCellFragment);
box TableCellFlow::from_node_and_box(node, box_) as owned::Box<Flow:Share> box TableCellFlow::from_node_and_fragment(node, fragment) as Box<Flow:Share>
}, },
_ => { _ => {
fail!("no need to generate a missing child") fail!("no need to generate a missing child")
@ -870,8 +869,8 @@ impl<'a> ImmutableFlowUtils for &'a Flow {
/// Return true if this flow is a Block Container. /// Return true if this flow is a Block Container.
/// ///
/// Except for table boxes and replaced elements, block-level boxes (`BlockFlow`) are /// Except for table fragments and replaced elements, block-level fragments (`BlockFlow`) are
/// also block container boxes. /// also block container fragments.
/// Non-replaced inline blocks and non-replaced table cells are also block /// Non-replaced inline blocks and non-replaced table cells are also block
/// containers. /// containers.
fn is_block_container(self) -> bool { fn is_block_container(self) -> bool {
@ -1052,9 +1051,9 @@ impl<'a> MutableFlowUtils for &'a mut Flow {
} }
} }
impl MutableOwnedFlowUtils for owned::Box<Flow:Share> { impl MutableOwnedFlowUtils for Box<Flow:Share> {
/// Adds a new flow as a child of this flow. Fails if this flow is marked as a leaf. /// Adds a new flow as a child of this flow. Fails if this flow is marked as a leaf.
fn add_new_child(&mut self, mut new_child: owned::Box<Flow:Share>) { fn add_new_child(&mut self, mut new_child: Box<Flow:Share>) {
{ {
let kid_base = mut_base(new_child); let kid_base = mut_base(new_child);
kid_base.parallel.parent = parallel::mut_owned_flow_to_unsafe_flow(self); kid_base.parallel.parent = parallel::mut_owned_flow_to_unsafe_flow(self);
@ -1066,7 +1065,7 @@ impl MutableOwnedFlowUtils for owned::Box<Flow:Share> {
let _ = base.parallel.children_and_absolute_descendant_count.fetch_add(1, Relaxed); let _ = base.parallel.children_and_absolute_descendant_count.fetch_add(1, Relaxed);
} }
/// Finishes a flow. Once a flow is finished, no more child flows or boxes may be added to it. /// Finishes a flow. Once a flow is finished, no more child flows or fragments may be added to it.
/// This will normally run the bubble-widths (minimum and preferred -- i.e. intrinsic -- width) /// This will normally run the bubble-widths (minimum and preferred -- i.e. intrinsic -- width)
/// calculation, unless the global `bubble_widths_separately` flag is on. /// calculation, unless the global `bubble_widths_separately` flag is on.
/// ///

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,7 @@
//! Borders, padding, and margins. //! Borders, padding, and margins.
use layout::box_::Box; use layout::fragment::Fragment;
use computed = style::computed_values; use computed = style::computed_values;
use geom::SideOffsets2D; use geom::SideOffsets2D;
@ -88,7 +88,7 @@ pub struct MarginCollapseInfo {
} }
impl MarginCollapseInfo { impl MarginCollapseInfo {
/// TODO(#2012, pcwalton): Remove this method once `box_` is not an `Option`. /// TODO(#2012, pcwalton): Remove this method once `fragment` is not an `Option`.
pub fn new() -> MarginCollapseInfo { pub fn new() -> MarginCollapseInfo {
MarginCollapseInfo { MarginCollapseInfo {
state: AccumulatingCollapsibleTopMargin, state: AccumulatingCollapsibleTopMargin,
@ -98,7 +98,7 @@ impl MarginCollapseInfo {
} }
pub fn initialize_top_margin(&mut self, pub fn initialize_top_margin(&mut self,
fragment: &Box, fragment: &Fragment,
can_collapse_top_margin_with_kids: bool) { can_collapse_top_margin_with_kids: bool) {
if !can_collapse_top_margin_with_kids { if !can_collapse_top_margin_with_kids {
self.state = AccumulatingMarginIn self.state = AccumulatingMarginIn
@ -108,7 +108,7 @@ impl MarginCollapseInfo {
} }
pub fn finish_and_compute_collapsible_margins(mut self, pub fn finish_and_compute_collapsible_margins(mut self,
fragment: &Box, fragment: &Fragment,
can_collapse_bottom_margin_with_kids: bool) can_collapse_bottom_margin_with_kids: bool)
-> (CollapsibleMargins, Au) { -> (CollapsibleMargins, Au) {
let state = match self.state { let state = match self.state {
@ -120,15 +120,15 @@ impl MarginCollapseInfo {
MarginsCollapseThroughFinalMarginState MarginsCollapseThroughFinalMarginState
}, },
_ => { _ => {
// If the box has non-zero min-height, margins may not collapse // If the fragment has non-zero min-height, margins may not
// through it. // collapse through it.
BottomMarginCollapsesFinalMarginState BottomMarginCollapsesFinalMarginState
} }
} }
}, },
_ => { _ => {
// If the box has an explicitly specified height, margins may not collapse // If the fragment has an explicitly specified height, margins may not
// through it. // collapse through it.
BottomMarginCollapsesFinalMarginState BottomMarginCollapsesFinalMarginState
} }
} }

View file

@ -4,13 +4,13 @@
//! CSS table formatting contexts. //! CSS table formatting contexts.
use layout::box_::Box;
use layout::block::{BlockFlow, MarginsMayNotCollapse, WidthAndMarginsComputer}; use layout::block::{BlockFlow, MarginsMayNotCollapse, WidthAndMarginsComputer};
use layout::block::{WidthConstraintInput, WidthConstraintSolution}; use layout::block::{WidthConstraintInput, WidthConstraintSolution};
use layout::construct::FlowConstructor; use layout::construct::FlowConstructor;
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::floats::FloatKind; use layout::floats::FloatKind;
use layout::flow::{TableFlowClass, FlowClass, Flow, ImmutableFlowUtils}; use layout::flow::{TableFlowClass, FlowClass, Flow, ImmutableFlowUtils};
use layout::fragment::Fragment;
use layout::table_wrapper::{TableLayout, FixedLayout, AutoLayout}; use layout::table_wrapper::{TableLayout, FixedLayout, AutoLayout};
use layout::wrapper::ThreadSafeLayoutNode; use layout::wrapper::ThreadSafeLayoutNode;
@ -19,9 +19,9 @@ use servo_util::geometry;
use std::fmt; use std::fmt;
use style::computed_values::table_layout; use style::computed_values::table_layout;
/// A table flow corresponded to the table's internal table box under a table wrapper flow. /// A table flow corresponded to the table's internal table fragment under a table wrapper flow.
/// The properties `position`, `float`, and `margin-*` are used on the table wrapper box, /// The properties `position`, `float`, and `margin-*` are used on the table wrapper fragment,
/// not table box per CSS 2.1 § 10.5. /// not table fragment per CSS 2.1 § 10.5.
pub struct TableFlow { pub struct TableFlow {
pub block_flow: BlockFlow, pub block_flow: BlockFlow,
@ -39,11 +39,11 @@ pub struct TableFlow {
} }
impl TableFlow { impl TableFlow {
pub fn from_node_and_box(node: &ThreadSafeLayoutNode, pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode,
box_: Box) fragment: Fragment)
-> TableFlow { -> TableFlow {
let mut block_flow = BlockFlow::from_node_and_box(node, box_); let mut block_flow = BlockFlow::from_node_and_fragment(node, fragment);
let table_layout = if block_flow.box_().style().get_table().table_layout == let table_layout = if block_flow.fragment().style().get_table().table_layout ==
table_layout::fixed { table_layout::fixed {
FixedLayout FixedLayout
} else { } else {
@ -62,7 +62,7 @@ impl TableFlow {
node: &ThreadSafeLayoutNode) node: &ThreadSafeLayoutNode)
-> TableFlow { -> TableFlow {
let mut block_flow = BlockFlow::from_node(constructor, node); let mut block_flow = BlockFlow::from_node(constructor, node);
let table_layout = if block_flow.box_().style().get_table().table_layout == let table_layout = if block_flow.fragment().style().get_table().table_layout ==
table_layout::fixed { table_layout::fixed {
FixedLayout FixedLayout
} else { } else {
@ -82,7 +82,7 @@ impl TableFlow {
float_kind: FloatKind) float_kind: FloatKind)
-> TableFlow { -> TableFlow {
let mut block_flow = BlockFlow::float_from_node(constructor, node, float_kind); let mut block_flow = BlockFlow::float_from_node(constructor, node, float_kind);
let table_layout = if block_flow.box_().style().get_table().table_layout == let table_layout = if block_flow.fragment().style().get_table().table_layout ==
table_layout::fixed { table_layout::fixed {
FixedLayout FixedLayout
} else { } else {
@ -231,8 +231,8 @@ impl Flow for TableFlow {
geometry::max(min_width, pref_width); geometry::max(min_width, pref_width);
} }
/// Recursively (top-down) determines the actual width of child contexts and boxes. When called /// Recursively (top-down) determines the actual width of child contexts and fragments. When
/// on this context, the context has had its width set by the parent context. /// called on this context, the context has had its width set by the parent context.
fn assign_widths(&mut self, ctx: &mut LayoutContext) { fn assign_widths(&mut self, ctx: &mut LayoutContext) {
debug!("assign_widths({}): assigning width for flow", "table"); debug!("assign_widths({}): assigning width for flow", "table");
@ -252,9 +252,9 @@ impl Flow for TableFlow {
let width_computer = InternalTable; let width_computer = InternalTable;
width_computer.compute_used_width(&mut self.block_flow, ctx, containing_block_width); width_computer.compute_used_width(&mut self.block_flow, ctx, containing_block_width);
let left_content_edge = self.block_flow.box_.border_padding.left; let left_content_edge = self.block_flow.fragment.border_padding.left;
let padding_and_borders = self.block_flow.box_.border_padding.horizontal(); let padding_and_borders = self.block_flow.fragment.border_padding.horizontal();
let content_width = self.block_flow.box_.border_box.size.width - padding_and_borders; let content_width = self.block_flow.fragment.border_box.size.width - padding_and_borders;
match self.table_layout { match self.table_layout {
FixedLayout => { FixedLayout => {

View file

@ -4,10 +4,10 @@
//! CSS table formatting contexts. //! CSS table formatting contexts.
use layout::box_::Box;
use layout::block::{BlockFlow, MarginsMayNotCollapse, WidthAndMarginsComputer}; use layout::block::{BlockFlow, MarginsMayNotCollapse, WidthAndMarginsComputer};
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::flow::{TableCellFlowClass, FlowClass, Flow}; use layout::flow::{TableCellFlowClass, FlowClass, Flow};
use layout::fragment::Fragment;
use layout::model::{MaybeAuto}; use layout::model::{MaybeAuto};
use layout::table::InternalTable; use layout::table::InternalTable;
use layout::wrapper::ThreadSafeLayoutNode; use layout::wrapper::ThreadSafeLayoutNode;
@ -22,18 +22,18 @@ pub struct TableCellFlow {
} }
impl TableCellFlow { impl TableCellFlow {
pub fn from_node_and_box(node: &ThreadSafeLayoutNode, box_: Box) -> TableCellFlow { pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode, fragment: Fragment) -> TableCellFlow {
TableCellFlow { TableCellFlow {
block_flow: BlockFlow::from_node_and_box(node, box_) block_flow: BlockFlow::from_node_and_fragment(node, fragment)
} }
} }
pub fn box_<'a>(&'a mut self) -> &'a Box { pub fn fragment<'a>(&'a mut self) -> &'a Fragment {
&self.block_flow.box_ &self.block_flow.fragment
} }
pub fn mut_box<'a>(&'a mut self) -> &'a mut Box { pub fn mut_fragment<'a>(&'a mut self) -> &'a mut Fragment {
&mut self.block_flow.box_ &mut self.block_flow.fragment
} }
/// Assign height for table-cell flow. /// Assign height for table-cell flow.
@ -69,7 +69,7 @@ impl Flow for TableCellFlow {
/// Minimum/preferred widths set by this function are used in automatic table layout calculation. /// Minimum/preferred widths set by this function are used in automatic table layout calculation.
fn bubble_widths(&mut self, ctx: &mut LayoutContext) { fn bubble_widths(&mut self, ctx: &mut LayoutContext) {
self.block_flow.bubble_widths(ctx); self.block_flow.bubble_widths(ctx);
let specified_width = MaybeAuto::from_style(self.block_flow.box_.style().get_box().width, let specified_width = MaybeAuto::from_style(self.block_flow.fragment.style().get_box().width,
Au::new(0)).specified_or_zero(); Au::new(0)).specified_or_zero();
if self.block_flow.base.intrinsic_widths.minimum_width < specified_width { if self.block_flow.base.intrinsic_widths.minimum_width < specified_width {
self.block_flow.base.intrinsic_widths.minimum_width = specified_width; self.block_flow.base.intrinsic_widths.minimum_width = specified_width;
@ -81,8 +81,8 @@ impl Flow for TableCellFlow {
} }
} }
/// Recursively (top-down) determines the actual width of child contexts and boxes. When called /// Recursively (top-down) determines the actual width of child contexts and fragments. When
/// on this context, the context has had its width set by the parent table row. /// called on this context, the context has had its width set by the parent table row.
fn assign_widths(&mut self, ctx: &mut LayoutContext) { fn assign_widths(&mut self, ctx: &mut LayoutContext) {
debug!("assign_widths({}): assigning width for flow", "table_cell"); debug!("assign_widths({}): assigning width for flow", "table_cell");
@ -92,10 +92,10 @@ impl Flow for TableCellFlow {
let width_computer = InternalTable; let width_computer = InternalTable;
width_computer.compute_used_width(&mut self.block_flow, ctx, containing_block_width); width_computer.compute_used_width(&mut self.block_flow, ctx, containing_block_width);
let left_content_edge = self.block_flow.box_.border_box.origin.x + let left_content_edge = self.block_flow.fragment.border_box.origin.x +
self.block_flow.box_.border_padding.left; self.block_flow.fragment.border_padding.left;
let padding_and_borders = self.block_flow.box_.border_padding.horizontal(); let padding_and_borders = self.block_flow.fragment.border_padding.horizontal();
let content_width = self.block_flow.box_.border_box.size.width - padding_and_borders; let content_width = self.block_flow.fragment.border_box.size.width - padding_and_borders;
self.block_flow.propagate_assigned_width_to_children(left_content_edge, self.block_flow.propagate_assigned_width_to_children(left_content_edge,
content_width, content_width,

View file

@ -4,9 +4,9 @@
//! CSS table formatting contexts. //! CSS table formatting contexts.
use layout::box_::{Box, TableColumnBox};
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::flow::{BaseFlow, TableColGroupFlowClass, FlowClass, Flow}; use layout::flow::{BaseFlow, TableColGroupFlowClass, FlowClass, Flow};
use layout::fragment::{Fragment, TableColumnFragment};
use layout::model::{MaybeAuto}; use layout::model::{MaybeAuto};
use layout::wrapper::ThreadSafeLayoutNode; use layout::wrapper::ThreadSafeLayoutNode;
@ -18,24 +18,24 @@ pub struct TableColGroupFlow {
/// Data common to all flows. /// Data common to all flows.
pub base: BaseFlow, pub base: BaseFlow,
/// The associated box. /// The associated fragment.
pub box_: Option<Box>, pub fragment: Option<Fragment>,
/// The table column boxes /// The table column fragments
pub cols: Vec<Box>, pub cols: Vec<Fragment>,
/// The specified widths of table columns /// The specified widths of table columns
pub widths: Vec<Au>, pub widths: Vec<Au>,
} }
impl TableColGroupFlow { impl TableColGroupFlow {
pub fn from_node_and_boxes(node: &ThreadSafeLayoutNode, pub fn from_node_and_fragments(node: &ThreadSafeLayoutNode,
box_: Box, fragment: Fragment,
boxes: Vec<Box>) -> TableColGroupFlow { fragments: Vec<Fragment>) -> TableColGroupFlow {
TableColGroupFlow { TableColGroupFlow {
base: BaseFlow::new((*node).clone()), base: BaseFlow::new((*node).clone()),
box_: Some(box_), fragment: Some(fragment),
cols: boxes, cols: fragments,
widths: vec!(), widths: vec!(),
} }
} }
@ -51,14 +51,14 @@ impl Flow for TableColGroupFlow {
} }
fn bubble_widths(&mut self, _: &mut LayoutContext) { fn bubble_widths(&mut self, _: &mut LayoutContext) {
for box_ in self.cols.iter() { for fragment in self.cols.iter() {
// get the specified value from width property // get the specified value from width property
let width = MaybeAuto::from_style(box_.style().get_box().width, let width = MaybeAuto::from_style(fragment.style().get_box().width,
Au::new(0)).specified_or_zero(); Au::new(0)).specified_or_zero();
let span: int = match box_.specific { let span: int = match fragment.specific {
TableColumnBox(col_box) => col_box.span.unwrap_or(1), TableColumnFragment(col_fragment) => col_fragment.span.unwrap_or(1),
_ => fail!("Other box come out in TableColGroupFlow. {:?}", box_.specific) _ => fail!("Other fragment come out in TableColGroupFlow. {:?}", fragment.specific)
}; };
for _ in range(0, span) { for _ in range(0, span) {
self.widths.push(width); self.widths.push(width);
@ -78,7 +78,7 @@ impl Flow for TableColGroupFlow {
impl fmt::Show for TableColGroupFlow { impl fmt::Show for TableColGroupFlow {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.box_ { match self.fragment {
Some(ref rb) => write!(f.buf, "TableColGroupFlow: {}", rb), Some(ref rb) => write!(f.buf, "TableColGroupFlow: {}", rb),
None => write!(f.buf, "TableColGroupFlow"), None => write!(f.buf, "TableColGroupFlow"),
} }

View file

@ -4,13 +4,13 @@
//! CSS table formatting contexts. //! CSS table formatting contexts.
use layout::box_::Box;
use layout::block::BlockFlow; use layout::block::BlockFlow;
use layout::block::WidthAndMarginsComputer; use layout::block::WidthAndMarginsComputer;
use layout::construct::FlowConstructor; use layout::construct::FlowConstructor;
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::flow::{TableRowFlowClass, FlowClass, Flow, ImmutableFlowUtils}; use layout::flow::{TableRowFlowClass, FlowClass, Flow, ImmutableFlowUtils};
use layout::flow; use layout::flow;
use layout::fragment::Fragment;
use layout::table::InternalTable; use layout::table::InternalTable;
use layout::model::{MaybeAuto, Specified, Auto}; use layout::model::{MaybeAuto, Specified, Auto};
use layout::wrapper::ThreadSafeLayoutNode; use layout::wrapper::ThreadSafeLayoutNode;
@ -34,11 +34,11 @@ pub struct TableRowFlow {
} }
impl TableRowFlow { impl TableRowFlow {
pub fn from_node_and_box(node: &ThreadSafeLayoutNode, pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode,
box_: Box) fragment: Fragment)
-> TableRowFlow { -> TableRowFlow {
TableRowFlow { TableRowFlow {
block_flow: BlockFlow::from_node_and_box(node, box_), block_flow: BlockFlow::from_node_and_fragment(node, fragment),
col_widths: vec!(), col_widths: vec!(),
col_min_widths: vec!(), col_min_widths: vec!(),
col_pref_widths: vec!(), col_pref_widths: vec!(),
@ -56,8 +56,8 @@ impl TableRowFlow {
} }
} }
pub fn box_<'a>(&'a mut self) -> &'a Box { pub fn fragment<'a>(&'a mut self) -> &'a Fragment {
&self.block_flow.box_ &self.block_flow.fragment
} }
fn initialize_offsets(&mut self) -> (Au, Au, Au) { fn initialize_offsets(&mut self) -> (Au, Au, Au) {
@ -84,13 +84,13 @@ impl TableRowFlow {
kid.assign_height_for_inorder_child_if_necessary(layout_context); kid.assign_height_for_inorder_child_if_necessary(layout_context);
{ {
let child_box = kid.as_table_cell().box_(); let child_fragment = kid.as_table_cell().fragment();
// TODO: Percentage height // TODO: Percentage height
let child_specified_height = MaybeAuto::from_style(child_box.style().get_box().height, let child_specified_height = MaybeAuto::from_style(child_fragment.style().get_box().height,
Au::new(0)).specified_or_zero(); Au::new(0)).specified_or_zero();
max_y = max_y =
geometry::max(max_y, geometry::max(max_y,
child_specified_height + child_box.border_padding.vertical()); child_specified_height + child_fragment.border_padding.vertical());
} }
let child_node = flow::mut_base(kid); let child_node = flow::mut_base(kid);
child_node.position.origin.y = cur_y; child_node.position.origin.y = cur_y;
@ -99,27 +99,27 @@ impl TableRowFlow {
let mut height = max_y; let mut height = max_y;
// TODO: Percentage height // TODO: Percentage height
height = match MaybeAuto::from_style(self.block_flow.box_.style().get_box().height, Au(0)) { height = match MaybeAuto::from_style(self.block_flow.fragment.style().get_box().height, Au(0)) {
Auto => height, Auto => height,
Specified(value) => geometry::max(value, height) Specified(value) => geometry::max(value, height)
}; };
// cur_y = cur_y + height; // cur_y = cur_y + height;
// Assign the height of own box // Assign the height of own fragment
// //
// FIXME(pcwalton): Take `cur_y` into account. // FIXME(pcwalton): Take `cur_y` into account.
let mut position = self.block_flow.box_.border_box; let mut position = self.block_flow.fragment.border_box;
position.size.height = height; position.size.height = height;
self.block_flow.box_.border_box = position; self.block_flow.fragment.border_box = position;
self.block_flow.base.position.size.height = height; self.block_flow.base.position.size.height = height;
// Assign the height of kid boxes, which is the same value as own height. // Assign the height of kid fragments, which is the same value as own height.
for kid in self.block_flow.base.child_iter() { for kid in self.block_flow.base.child_iter() {
{ {
let kid_box_ = kid.as_table_cell().mut_box(); let kid_fragment = kid.as_table_cell().mut_fragment();
let mut position = kid_box_.border_box; let mut position = kid_fragment.border_box;
position.size.height = height; position.size.height = height;
kid_box_.border_box = position; kid_fragment.border_box = position;
} }
let child_node = flow::mut_base(kid); let child_node = flow::mut_base(kid);
child_node.position.size.height = height; child_node.position.size.height = height;
@ -159,7 +159,7 @@ impl Flow for TableRowFlow {
/// Recursively (bottom-up) determines the context's preferred and minimum widths. When called /// Recursively (bottom-up) determines the context's preferred and minimum widths. When called
/// on this context, all child contexts have had their min/pref widths set. This function must /// on this context, all child contexts have had their min/pref widths set. This function must
/// decide min/pref widths based on child context widths and dimensions of any boxes it is /// decide min/pref widths based on child context widths and dimensions of any fragments it is
/// responsible for flowing. /// responsible for flowing.
/// Min/pref widths set by this function are used in automatic table layout calculation. /// Min/pref widths set by this function are used in automatic table layout calculation.
/// The specified column widths of children cells are used in fixed table layout calculation. /// The specified column widths of children cells are used in fixed table layout calculation.
@ -172,8 +172,8 @@ impl Flow for TableRowFlow {
// collect the specified column widths of cells. These are used in fixed table layout calculation. // collect the specified column widths of cells. These are used in fixed table layout calculation.
{ {
let child_box = kid.as_table_cell().box_(); let child_fragment = kid.as_table_cell().fragment();
let child_specified_width = MaybeAuto::from_style(child_box.style().get_box().width, let child_specified_width = MaybeAuto::from_style(child_fragment.style().get_box().width,
Au::new(0)).specified_or_zero(); Au::new(0)).specified_or_zero();
self.col_widths.push(child_specified_width); self.col_widths.push(child_specified_width);
} }
@ -190,7 +190,7 @@ impl Flow for TableRowFlow {
pref_width); pref_width);
} }
/// Recursively (top-down) determines the actual width of child contexts and boxes. When called /// Recursively (top-down) determines the actual width of child contexts and fragments. When called
/// on this context, the context has had its width set by the parent context. /// on this context, the context has had its width set by the parent context.
fn assign_widths(&mut self, ctx: &mut LayoutContext) { fn assign_widths(&mut self, ctx: &mut LayoutContext) {
debug!("assign_widths({}): assigning width for flow", "table_row"); debug!("assign_widths({}): assigning width for flow", "table_row");
@ -218,6 +218,6 @@ impl Flow for TableRowFlow {
impl fmt::Show for TableRowFlow { impl fmt::Show for TableRowFlow {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f.buf, "TableRowFlow: {}", self.block_flow.box_) write!(f.buf, "TableRowFlow: {}", self.block_flow.fragment)
} }
} }

View file

@ -4,13 +4,13 @@
//! CSS table formatting contexts. //! CSS table formatting contexts.
use layout::box_::Box;
use layout::block::BlockFlow; use layout::block::BlockFlow;
use layout::block::WidthAndMarginsComputer; use layout::block::WidthAndMarginsComputer;
use layout::construct::FlowConstructor; use layout::construct::FlowConstructor;
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::flow::{TableRowGroupFlowClass, FlowClass, Flow, ImmutableFlowUtils}; use layout::flow::{TableRowGroupFlowClass, FlowClass, Flow, ImmutableFlowUtils};
use layout::flow; use layout::flow;
use layout::fragment::Fragment;
use layout::table::{InternalTable, TableFlow}; use layout::table::{InternalTable, TableFlow};
use layout::wrapper::ThreadSafeLayoutNode; use layout::wrapper::ThreadSafeLayoutNode;
@ -33,11 +33,11 @@ pub struct TableRowGroupFlow {
} }
impl TableRowGroupFlow { impl TableRowGroupFlow {
pub fn from_node_and_box(node: &ThreadSafeLayoutNode, pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode,
box_: Box) fragment: Fragment)
-> TableRowGroupFlow { -> TableRowGroupFlow {
TableRowGroupFlow { TableRowGroupFlow {
block_flow: BlockFlow::from_node_and_box(node, box_), block_flow: BlockFlow::from_node_and_fragment(node, fragment),
col_widths: vec!(), col_widths: vec!(),
col_min_widths: vec!(), col_min_widths: vec!(),
col_pref_widths: vec!(), col_pref_widths: vec!(),
@ -55,8 +55,8 @@ impl TableRowGroupFlow {
} }
} }
pub fn box_<'a>(&'a mut self) -> &'a Box { pub fn fragment<'a>(&'a mut self) -> &'a Fragment {
&self.block_flow.box_ &self.block_flow.fragment
} }
fn initialize_offsets(&mut self) -> (Au, Au, Au) { fn initialize_offsets(&mut self) -> (Au, Au, Au) {
@ -87,9 +87,9 @@ impl TableRowGroupFlow {
let height = cur_y - top_offset; let height = cur_y - top_offset;
let mut position = self.block_flow.box_.border_box; let mut position = self.block_flow.fragment.border_box;
position.size.height = height; position.size.height = height;
self.block_flow.box_.border_box = position; self.block_flow.fragment.border_box = position;
self.block_flow.base.position.size.height = height; self.block_flow.base.position.size.height = height;
} }
@ -126,7 +126,7 @@ impl Flow for TableRowGroupFlow {
/// Recursively (bottom-up) determines the context's preferred and minimum widths. When called /// Recursively (bottom-up) determines the context's preferred and minimum widths. When called
/// on this context, all child contexts have had their min/pref widths set. This function must /// on this context, all child contexts have had their min/pref widths set. This function must
/// decide min/pref widths based on child context widths and dimensions of any boxes it is /// decide min/pref widths based on child context widths and dimensions of any fragments it is
/// responsible for flowing. /// responsible for flowing.
/// Min/pref widths set by this function are used in automatic table layout calculation. /// Min/pref widths set by this function are used in automatic table layout calculation.
/// Also, this function finds the specified column widths from the first row. /// Also, this function finds the specified column widths from the first row.
@ -171,8 +171,8 @@ impl Flow for TableRowGroupFlow {
pref_width); pref_width);
} }
/// Recursively (top-down) determines the actual width of child contexts and boxes. When called /// Recursively (top-down) determines the actual width of child contexts and fragments. When
/// on this context, the context has had its width set by the parent context. /// called on this context, the context has had its width set by the parent context.
fn assign_widths(&mut self, ctx: &mut LayoutContext) { fn assign_widths(&mut self, ctx: &mut LayoutContext) {
debug!("assign_widths({}): assigning width for flow", "table_rowgroup"); debug!("assign_widths({}): assigning width for flow", "table_rowgroup");
@ -200,6 +200,6 @@ impl Flow for TableRowGroupFlow {
impl fmt::Show for TableRowGroupFlow { impl fmt::Show for TableRowGroupFlow {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f.buf, "TableRowGroupFlow: {}", self.block_flow.box_) write!(f.buf, "TableRowGroupFlow: {}", self.block_flow.fragment)
} }
} }

View file

@ -4,13 +4,13 @@
//! CSS table formatting contexts. //! CSS table formatting contexts.
use layout::box_::Box;
use layout::block::{BlockFlow, MarginsMayNotCollapse, WidthAndMarginsComputer}; use layout::block::{BlockFlow, MarginsMayNotCollapse, WidthAndMarginsComputer};
use layout::block::{WidthConstraintInput, WidthConstraintSolution}; use layout::block::{WidthConstraintInput, WidthConstraintSolution};
use layout::construct::FlowConstructor; use layout::construct::FlowConstructor;
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::floats::FloatKind; use layout::floats::FloatKind;
use layout::flow::{TableWrapperFlowClass, FlowClass, Flow, ImmutableFlowUtils}; use layout::flow::{TableWrapperFlowClass, FlowClass, Flow, ImmutableFlowUtils};
use layout::fragment::Fragment;
use layout::model::{Specified, Auto, specified}; use layout::model::{Specified, Auto, specified};
use layout::wrapper::ThreadSafeLayoutNode; use layout::wrapper::ThreadSafeLayoutNode;
@ -36,11 +36,11 @@ pub struct TableWrapperFlow {
} }
impl TableWrapperFlow { impl TableWrapperFlow {
pub fn from_node_and_box(node: &ThreadSafeLayoutNode, pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode,
box_: Box) fragment: Fragment)
-> TableWrapperFlow { -> TableWrapperFlow {
let mut block_flow = BlockFlow::from_node_and_box(node, box_); let mut block_flow = BlockFlow::from_node_and_fragment(node, fragment);
let table_layout = if block_flow.box_().style().get_table().table_layout == let table_layout = if block_flow.fragment().style().get_table().table_layout ==
table_layout::fixed { table_layout::fixed {
FixedLayout FixedLayout
} else { } else {
@ -57,7 +57,7 @@ impl TableWrapperFlow {
node: &ThreadSafeLayoutNode) node: &ThreadSafeLayoutNode)
-> TableWrapperFlow { -> TableWrapperFlow {
let mut block_flow = BlockFlow::from_node(constructor, node); let mut block_flow = BlockFlow::from_node(constructor, node);
let table_layout = if block_flow.box_().style().get_table().table_layout == let table_layout = if block_flow.fragment().style().get_table().table_layout ==
table_layout::fixed { table_layout::fixed {
FixedLayout FixedLayout
} else { } else {
@ -75,7 +75,7 @@ impl TableWrapperFlow {
float_kind: FloatKind) float_kind: FloatKind)
-> TableWrapperFlow { -> TableWrapperFlow {
let mut block_flow = BlockFlow::float_from_node(constructor, node, float_kind); let mut block_flow = BlockFlow::float_from_node(constructor, node, float_kind);
let table_layout = if block_flow.box_().style().get_table().table_layout == let table_layout = if block_flow.fragment().style().get_table().table_layout ==
table_layout::fixed { table_layout::fixed {
FixedLayout FixedLayout
} else { } else {
@ -125,7 +125,7 @@ impl Flow for TableWrapperFlow {
minimum widths. When called on this context, all child contexts minimum widths. When called on this context, all child contexts
have had their min/pref widths set. This function must decide have had their min/pref widths set. This function must decide
min/pref widths based on child context widths and dimensions of min/pref widths based on child context widths and dimensions of
any boxes it is responsible for flowing. */ any fragments it is responsible for flowing. */
fn bubble_widths(&mut self, ctx: &mut LayoutContext) { fn bubble_widths(&mut self, ctx: &mut LayoutContext) {
// get column widths info from table flow // get column widths info from table flow
@ -140,10 +140,10 @@ impl Flow for TableWrapperFlow {
self.block_flow.bubble_widths(ctx); self.block_flow.bubble_widths(ctx);
} }
/// Recursively (top-down) determines the actual width of child contexts and boxes. When called /// Recursively (top-down) determines the actual width of child contexts and fragments. When
/// on this context, the context has had its width set by the parent context. /// 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) /// Dual fragments consume some width first, and the remainder is assigned to all child (block)
/// contexts. /// contexts.
fn assign_widths(&mut self, ctx: &mut LayoutContext) { fn assign_widths(&mut self, ctx: &mut LayoutContext) {
debug!("assign_widths({}): assigning width for flow", debug!("assign_widths({}): assigning width for flow",
@ -159,8 +159,8 @@ impl Flow for TableWrapperFlow {
let width_computer = TableWrapper; let width_computer = TableWrapper;
width_computer.compute_used_width_table_wrapper(self, ctx, containing_block_width); width_computer.compute_used_width_table_wrapper(self, ctx, containing_block_width);
let left_content_edge = self.block_flow.box_.border_box.origin.x; let left_content_edge = self.block_flow.fragment.border_box.origin.x;
let content_width = self.block_flow.box_.border_box.size.width; let content_width = self.block_flow.fragment.border_box.size.width;
match self.table_layout { match self.table_layout {
FixedLayout | _ if self.is_float() => FixedLayout | _ if self.is_float() =>
@ -194,9 +194,9 @@ impl Flow for TableWrapperFlow {
impl fmt::Show for TableWrapperFlow { impl fmt::Show for TableWrapperFlow {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.is_float() { if self.is_float() {
write!(f.buf, "TableWrapperFlow(Float): {}", self.block_flow.box_) write!(f.buf, "TableWrapperFlow(Float): {}", self.block_flow.fragment)
} else { } else {
write!(f.buf, "TableWrapperFlow: {}", self.block_flow.box_) write!(f.buf, "TableWrapperFlow: {}", self.block_flow.fragment)
} }
} }
} }
@ -232,10 +232,10 @@ impl TableWrapper {
|sum, width| sum.add(width)); |sum, width| sum.add(width));
let mut computed_width = input.computed_width.specified_or_zero(); let mut computed_width = input.computed_width.specified_or_zero();
let style = table_wrapper.block_flow.box_.style(); let style = table_wrapper.block_flow.fragment.style();
// Get left and right paddings, borders for table. // Get left and right paddings, borders for table.
// We get these values from the box's style since table_wrapper doesn't have it's own border or padding. // We get these values from the fragment's style since table_wrapper doesn't have it's own border or padding.
// input.available_width is same as containing_block_width in table_wrapper. // input.available_width is same as containing_block_width in table_wrapper.
let padding_left = specified(style.get_padding().padding_left, let padding_left = specified(style.get_padding().padding_left,
input.available_width); input.available_width);

View file

@ -4,9 +4,9 @@
//! Text layout. //! Text layout.
use layout::box_::{Box, ScannedTextBox, ScannedTextBoxInfo, UnscannedTextBox};
use layout::flow::Flow; use layout::flow::Flow;
use layout::inline::InlineBoxes; use layout::fragment::{Fragment, ScannedTextFragment, ScannedTextFragmentInfo, UnscannedTextFragment};
use layout::inline::InlineFragments;
use gfx::font::{FontMetrics, FontStyle}; use gfx::font::{FontMetrics, FontStyle};
use gfx::font_context::FontContext; use gfx::font_context::FontContext;
@ -25,12 +25,12 @@ struct NewLinePositions {
} }
// A helper function. // A helper function.
fn can_coalesce_text_nodes(boxes: &[Box], left_i: uint, right_i: uint) -> bool { fn can_coalesce_text_nodes(fragments: &[Fragment], left_i: uint, right_i: uint) -> bool {
assert!(left_i != right_i); assert!(left_i != right_i);
boxes[left_i].can_merge_with_box(&boxes[right_i]) fragments[left_i].can_merge_with_fragment(&fragments[right_i])
} }
/// A stack-allocated object for scanning an inline flow into `TextRun`-containing `TextBox`es. /// A stack-allocated object for scanning an inline flow into `TextRun`-containing `TextFragment`s.
pub struct TextRunScanner { pub struct TextRunScanner {
pub clump: Range<CharIndex>, pub clump: Range<CharIndex>,
} }
@ -45,22 +45,22 @@ impl TextRunScanner {
pub fn scan_for_runs(&mut self, font_context: &mut FontContext, flow: &mut Flow) { pub fn scan_for_runs(&mut self, font_context: &mut FontContext, flow: &mut Flow) {
{ {
let inline = flow.as_immutable_inline(); let inline = flow.as_immutable_inline();
debug!("TextRunScanner: scanning {:u} boxes for text runs...", inline.boxes.len()); debug!("TextRunScanner: scanning {:u} fragments for text runs...", inline.fragments.len());
} }
let InlineBoxes { let InlineFragments {
boxes: old_boxes, fragments: old_fragments,
map: mut map map: mut map
} = mem::replace(&mut flow.as_inline().boxes, InlineBoxes::new()); } = mem::replace(&mut flow.as_inline().fragments, InlineFragments::new());
let mut last_whitespace = true; let mut last_whitespace = true;
let mut new_boxes = Vec::new(); let mut new_fragments = Vec::new();
for box_i in range(0, old_boxes.len()) { for fragment_i in range(0, old_fragments.len()) {
debug!("TextRunScanner: considering box: {:u}", box_i); debug!("TextRunScanner: considering fragment: {:u}", fragment_i);
if box_i > 0 && !can_coalesce_text_nodes(old_boxes.as_slice(), box_i - 1, box_i) { if fragment_i > 0 && !can_coalesce_text_nodes(old_fragments.as_slice(), fragment_i - 1, fragment_i) {
last_whitespace = self.flush_clump_to_list(font_context, last_whitespace = self.flush_clump_to_list(font_context,
old_boxes.as_slice(), old_fragments.as_slice(),
&mut new_boxes, &mut new_fragments,
last_whitespace); last_whitespace);
} }
@ -70,43 +70,43 @@ impl TextRunScanner {
// Handle remaining clumps. // Handle remaining clumps.
if self.clump.length() > CharIndex(0) { if self.clump.length() > CharIndex(0) {
drop(self.flush_clump_to_list(font_context, drop(self.flush_clump_to_list(font_context,
old_boxes.as_slice(), old_fragments.as_slice(),
&mut new_boxes, &mut new_fragments,
last_whitespace)) last_whitespace))
} }
debug!("TextRunScanner: swapping out boxes."); debug!("TextRunScanner: swapping out fragments.");
// Swap out the old and new box list of the flow. // Swap out the old and new fragment list of the flow.
map.fixup(old_boxes.as_slice(), new_boxes.as_slice()); map.fixup(old_fragments.as_slice(), new_fragments.as_slice());
flow.as_inline().boxes = InlineBoxes { flow.as_inline().fragments = InlineFragments {
boxes: new_boxes, fragments: new_fragments,
map: map, map: map,
} }
} }
/// A "clump" is a range of inline flow leaves that can be merged together into a single box. /// A "clump" is a range of inline flow leaves that can be merged together into a single
/// Adjacent text with the same style can be merged, and nothing else can. /// fragment. Adjacent text with the same style can be merged, and nothing else can.
/// ///
/// The flow keeps track of the boxes contained by all non-leaf DOM nodes. This is necessary /// The flow keeps track of the fragments contained by all non-leaf DOM nodes. This is necessary
/// for correct painting order. Since we compress several leaf boxes here, the mapping must be /// for correct painting order. Since we compress several leaf fragments here, the mapping must
/// adjusted. /// be adjusted.
/// ///
/// FIXME(#2267, pcwalton): Stop cloning boxes. Instead we will need to replace each `in_box` /// FIXME(#2267, pcwalton): Stop cloning fragments. Instead we will need to replace each
/// with some smaller stub. /// `in_fragment` with some smaller stub.
pub fn flush_clump_to_list(&mut self, pub fn flush_clump_to_list(&mut self,
font_context: &mut FontContext, font_context: &mut FontContext,
in_boxes: &[Box], in_fragments: &[Fragment],
out_boxes: &mut Vec<Box>, out_fragments: &mut Vec<Fragment>,
last_whitespace: bool) last_whitespace: bool)
-> bool { -> bool {
assert!(self.clump.length() > CharIndex(0)); assert!(self.clump.length() > CharIndex(0));
debug!("TextRunScanner: flushing boxes in range={}", self.clump); debug!("TextRunScanner: flushing fragments in range={}", self.clump);
let is_singleton = self.clump.length() == CharIndex(1); let is_singleton = self.clump.length() == CharIndex(1);
let is_text_clump = match in_boxes[self.clump.begin().to_uint()].specific { let is_text_clump = match in_fragments[self.clump.begin().to_uint()].specific {
UnscannedTextBox(_) => true, UnscannedTextFragment(_) => true,
_ => false, _ => false,
}; };
@ -116,23 +116,23 @@ impl TextRunScanner {
fail!("WAT: can't coalesce non-text nodes in flush_clump_to_list()!") fail!("WAT: can't coalesce non-text nodes in flush_clump_to_list()!")
} }
(true, false) => { (true, false) => {
// FIXME(pcwalton): Stop cloning boxes, as above. // FIXME(pcwalton): Stop cloning fragments, as above.
debug!("TextRunScanner: pushing single non-text box in range: {}", self.clump); debug!("TextRunScanner: pushing single non-text fragment in range: {}", self.clump);
let new_box = in_boxes[self.clump.begin().to_uint()].clone(); let new_fragment = in_fragments[self.clump.begin().to_uint()].clone();
out_boxes.push(new_box) out_fragments.push(new_fragment)
}, },
(true, true) => { (true, true) => {
let old_box = &in_boxes[self.clump.begin().to_uint()]; let old_fragment = &in_fragments[self.clump.begin().to_uint()];
let text = match old_box.specific { let text = match old_fragment.specific {
UnscannedTextBox(ref text_box_info) => &text_box_info.text, UnscannedTextFragment(ref text_fragment_info) => &text_fragment_info.text,
_ => fail!("Expected an unscanned text box!"), _ => fail!("Expected an unscanned text fragment!"),
}; };
let font_style = old_box.font_style(); let font_style = old_fragment.font_style();
let decoration = old_box.text_decoration(); let decoration = old_fragment.text_decoration();
// TODO(#115): Use the actual CSS `white-space` property of the relevant style. // TODO(#115): Use the actual CSS `white-space` property of the relevant style.
let compression = match old_box.white_space() { let compression = match old_fragment.white_space() {
white_space::normal => CompressWhitespaceNewline, white_space::normal => CompressWhitespaceNewline,
white_space::pre => CompressNone, white_space::pre => CompressNone,
}; };
@ -154,29 +154,29 @@ impl TextRunScanner {
let run = box fontgroup.borrow().create_textrun( let run = box fontgroup.borrow().create_textrun(
transformed_text.clone(), decoration); transformed_text.clone(), decoration);
debug!("TextRunScanner: pushing single text box in range: {} ({})", debug!("TextRunScanner: pushing single text fragment in range: {} ({})",
self.clump, self.clump,
*text); *text);
let range = Range::new(CharIndex(0), run.char_len()); let range = Range::new(CharIndex(0), run.char_len());
let new_metrics = run.metrics_for_range(&range); let new_metrics = run.metrics_for_range(&range);
let new_text_box_info = ScannedTextBoxInfo::new(Arc::new(run), range); let new_text_fragment_info = ScannedTextFragmentInfo::new(Arc::new(run), range);
let mut new_box = old_box.transform(new_metrics.bounding_box.size, let mut new_fragment = old_fragment.transform(new_metrics.bounding_box.size,
ScannedTextBox(new_text_box_info)); ScannedTextFragment(new_text_fragment_info));
new_box.new_line_pos = new_line_pos; new_fragment.new_line_pos = new_line_pos;
out_boxes.push(new_box) out_fragments.push(new_fragment)
} }
}, },
(false, true) => { (false, true) => {
// TODO(#177): Text run creation must account for the renderability of text by // TODO(#177): Text run creation must account for the renderability of text by
// font group fonts. This is probably achieved by creating the font group above // font group fonts. This is probably achieved by creating the font group above
// and then letting `FontGroup` decide which `Font` to stick into the text run. // and then letting `FontGroup` decide which `Font` to stick into the text run.
let in_box = &in_boxes[self.clump.begin().to_uint()]; let in_fragment = &in_fragments[self.clump.begin().to_uint()];
let font_style = in_box.font_style(); let font_style = in_fragment.font_style();
let fontgroup = font_context.get_resolved_font_for_style(&font_style); let fontgroup = font_context.get_resolved_font_for_style(&font_style);
let decoration = in_box.text_decoration(); let decoration = in_fragment.text_decoration();
// TODO(#115): Use the actual CSS `white-space` property of the relevant style. // TODO(#115): Use the actual CSS `white-space` property of the relevant style.
let compression = match in_box.white_space() { let compression = match in_fragment.white_space() {
white_space::normal => CompressWhitespaceNewline, white_space::normal => CompressWhitespaceNewline,
white_space::pre => CompressNone, white_space::pre => CompressNone,
}; };
@ -187,17 +187,17 @@ impl TextRunScanner {
let mut last_whitespace_in_clump = new_whitespace; let mut last_whitespace_in_clump = new_whitespace;
let transformed_strs: Vec<~str> = Vec::from_fn(self.clump.length().to_uint(), |i| { let transformed_strs: Vec<~str> = Vec::from_fn(self.clump.length().to_uint(), |i| {
// TODO(#113): We should be passing the compression context between calls to // TODO(#113): We should be passing the compression context between calls to
// `transform_text`, so that boxes starting and/or ending with whitespace can // `transform_text`, so that fragments starting and/or ending with whitespace can
// be compressed correctly with respect to the text run. // be compressed correctly with respect to the text run.
let idx = CharIndex(i as int) + self.clump.begin(); let idx = CharIndex(i as int) + self.clump.begin();
let in_box = match in_boxes[idx.to_uint()].specific { let in_fragment = match in_fragments[idx.to_uint()].specific {
UnscannedTextBox(ref text_box_info) => &text_box_info.text, UnscannedTextFragment(ref text_fragment_info) => &text_fragment_info.text,
_ => fail!("Expected an unscanned text box!"), _ => fail!("Expected an unscanned text fragment!"),
}; };
let mut new_line_pos = vec![]; let mut new_line_pos = vec![];
let (new_str, new_whitespace) = transform_text(*in_box, let (new_str, new_whitespace) = transform_text(*in_fragment,
compression, compression,
last_whitespace_in_clump, last_whitespace_in_clump,
&mut new_line_pos); &mut new_line_pos);
@ -232,23 +232,23 @@ impl TextRunScanner {
None None
}; };
// Make new boxes with the run and adjusted text indices. // Make new fragments with the run and adjusted text indices.
debug!("TextRunScanner: pushing box(es) in range: {}", self.clump); debug!("TextRunScanner: pushing fragment(s) in range: {}", self.clump);
for i in clump.each_index() { for i in clump.each_index() {
let logical_offset = i - self.clump.begin(); let logical_offset = i - self.clump.begin();
let range = new_ranges.get(logical_offset.to_uint()); let range = new_ranges.get(logical_offset.to_uint());
if range.length() == CharIndex(0) { if range.length() == CharIndex(0) {
debug!("Elided an `UnscannedTextbox` because it was zero-length after \ debug!("Elided an `UnscannedTextFragment` because it was zero-length after \
compression; {}", in_boxes[i.to_uint()]); compression; {}", in_fragments[i.to_uint()]);
continue continue
} }
let new_text_box_info = ScannedTextBoxInfo::new(run.get_ref().clone(), *range); let new_text_fragment_info = ScannedTextFragmentInfo::new(run.get_ref().clone(), *range);
let new_metrics = new_text_box_info.run.metrics_for_range(range); let new_metrics = new_text_fragment_info.run.metrics_for_range(range);
let mut new_box = in_boxes[i.to_uint()].transform(new_metrics.bounding_box.size, let mut new_fragment = in_fragments[i.to_uint()].transform(new_metrics.bounding_box.size,
ScannedTextBox(new_text_box_info)); ScannedTextFragment(new_text_fragment_info));
new_box.new_line_pos = new_line_positions.get(logical_offset.to_uint()).new_line_pos.clone(); new_fragment.new_line_pos = new_line_positions.get(logical_offset.to_uint()).new_line_pos.clone();
out_boxes.push(new_box) out_fragments.push(new_fragment)
} }
} }
} // End of match. } // End of match.

View file

@ -95,12 +95,12 @@ pub mod pipeline;
pub mod layout { pub mod layout {
pub mod block; pub mod block;
pub mod box_;
pub mod construct; pub mod construct;
pub mod context; pub mod context;
pub mod floats; pub mod floats;
pub mod flow; pub mod flow;
pub mod flow_list; pub mod flow_list;
pub mod fragment;
pub mod layout_task; pub mod layout_task;
pub mod inline; pub mod inline;
pub mod model; pub mod model;