Rename functions, fields and adjust comments to use fragment instead of box

I tried to make sure to keep 'box' where it made sense, and alter comments so they still make sense.
This commit is contained in:
Brendan Zabarauskas 2014-05-28 10:35:35 -07:00
parent c5fced4390
commit 3ffce02b88
15 changed files with 847 additions and 849 deletions

View file

@ -52,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?
@ -488,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_: Fragment, 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.
@ -510,7 +510,7 @@ 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_: Fragment::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,
@ -518,10 +518,10 @@ impl BlockFlow {
} }
} }
pub fn from_node_and_box(node: &ThreadSafeLayoutNode, box_: Fragment) -> 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,
@ -535,7 +535,7 @@ impl BlockFlow {
-> BlockFlow { -> BlockFlow {
BlockFlow { BlockFlow {
base: BaseFlow::new((*node).clone()), base: BaseFlow::new((*node).clone()),
box_: Fragment::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,
@ -600,9 +600,9 @@ impl BlockFlow {
} }
} }
/// Return this flow's box. /// Return this flow's fragment.
pub fn box_<'a>(&'a mut self) -> &'a mut Fragment { 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.
@ -698,12 +698,12 @@ 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 {
ScannedTextFragment(_) | ImageFragment(_) => true, ScannedTextFragment(_) | ImageFragment(_) => true,
_ => false, _ => false,
} }
@ -765,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
} }
@ -788,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;
} }
@ -822,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.
@ -934,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);
@ -963,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 {
@ -982,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.
@ -1018,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,
@ -1060,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
@ -1074,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,
@ -1087,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,
@ -1097,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);
@ -1105,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() {
@ -1176,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 Fragment'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,
@ -1219,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));
@ -1241,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.
@ -1288,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 Fragment 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.
/// ///
@ -1316,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.
@ -1395,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
} }
@ -1423,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.
@ -1431,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) {
@ -1457,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),
@ -1473,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",
@ -1518,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
} }
} }
} }
@ -1530,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;
@ -1562,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");
@ -1598,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 +
@ -1617,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();
@ -1665,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.
@ -1678,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 {
@ -1699,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)
} }
} }
} }
@ -1793,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);
@ -1807,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,
@ -1828,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.
@ -1853,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))
} }
@ -1880,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);
@ -1890,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);
@ -2233,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 {
@ -2282,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())
} }
} }
@ -2338,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

@ -51,24 +51,24 @@ use style::computed_values::{text_decoration, vertical_align, visibility, white_
use sync::Arc; use sync::Arc;
use url::Url; use url::Url;
/// Boxes (`struct Box`) are the leaves of the layout tree. They cannot position themselves. In /// Fragments (`struct Fragment`) are the leaves of the layout tree. They cannot position themselves. In
/// general, boxes do not have a simple correspondence with CSS boxes in the specification: /// general, fragments do not have a simple correspondence with CSS fragments in the specification:
/// ///
/// * Several boxes may correspond to the same CSS box or DOM node. For example, a CSS text box /// * Several fragments may correspond to the same CSS box or DOM node. For example, a CSS text box
/// broken across two lines is represented by two boxes. /// broken across two lines is represented by two fragments.
/// ///
/// * Some CSS boxes are not created at all, such as some anonymous block boxes induced by inline /// * Some CSS fragments are not created at all, such as some anonymous block fragments induced by inline
/// boxes with block-level sibling boxes. In that case, Servo uses an `InlineFlow` with /// fragments with block-level sibling fragments. In that case, Servo uses an `InlineFlow` with
/// `BlockFlow` siblings; the `InlineFlow` is block-level, but not a block container. It is /// `BlockFlow` siblings; the `InlineFlow` is block-level, but not a block container. It is
/// positioned as if it were a block box, but its children are positioned according to inline /// positioned as if it were a block fragment, but its children are positioned according to inline
/// flow. /// flow.
/// ///
/// A `GenericFragment` is an empty box that contributes only borders, margins, padding, and /// A `GenericFragment` is an empty fragment that contributes only borders, margins, padding, and
/// backgrounds. It is analogous to a CSS nonreplaced content box. /// backgrounds. It is analogous to a CSS nonreplaced content box.
/// ///
/// A box's type influences how its styles are interpreted during layout. For example, replaced /// A fragment's type influences how its styles are interpreted during layout. For example, replaced
/// content such as images are resized differently from tables, text, or other content. Different /// content such as images are resized differently from tables, text, or other content. Different
/// types of boxes may also contain custom data; for example, text boxes contain text. /// types of fragments may also contain custom data; for example, text fragments contain text.
/// ///
/// FIXME(#2260, pcwalton): This can be slimmed down some. /// FIXME(#2260, pcwalton): This can be slimmed down some.
#[deriving(Clone)] #[deriving(Clone)]
@ -76,21 +76,21 @@ pub struct Fragment {
/// An opaque reference to the DOM node that this `Fragment` originates from. /// An opaque reference to the DOM node that this `Fragment` originates from.
pub node: OpaqueNode, pub node: OpaqueNode,
/// The CSS style of this box. /// The CSS style of this fragment.
pub style: Arc<ComputedValues>, pub style: Arc<ComputedValues>,
/// The position of this box relative to its owning flow. /// The position of this fragment relative to its owning flow.
/// The size includes padding and border, but not margin. /// The size includes padding and border, but not margin.
pub border_box: Rect<Au>, pub border_box: Rect<Au>,
/// The sum of border and padding; i.e. the distance from the edge of the border box to the /// The sum of border and padding; i.e. the distance from the edge of the border box to the
/// content edge of the box. /// content edge of the fragment.
pub border_padding: SideOffsets2D<Au>, pub border_padding: SideOffsets2D<Au>,
/// The margin of the content box. /// The margin of the content box.
pub margin: SideOffsets2D<Au>, pub margin: SideOffsets2D<Au>,
/// Info specific to the kind of box. Keep this enum small. /// Info specific to the kind of fragment. Keep this enum small.
pub specific: SpecificFragmentInfo, pub specific: SpecificFragmentInfo,
/// New-line chracter(\n)'s positions(relative, not absolute) /// New-line chracter(\n)'s positions(relative, not absolute)
@ -99,7 +99,7 @@ pub struct Fragment {
pub new_line_pos: Vec<CharIndex>, pub new_line_pos: Vec<CharIndex>,
} }
/// Info specific to the kind of box. Keep this enum small. /// Info specific to the kind of fragment. Keep this enum small.
#[deriving(Clone)] #[deriving(Clone)]
pub enum SpecificFragmentInfo { pub enum SpecificFragmentInfo {
GenericFragment, GenericFragment,
@ -114,10 +114,10 @@ pub enum SpecificFragmentInfo {
UnscannedTextFragment(UnscannedTextFragmentInfo), UnscannedTextFragment(UnscannedTextFragmentInfo),
} }
/// A box that represents a replaced content image and its accompanying borders, shadows, etc. /// A fragment that represents a replaced content image and its accompanying borders, shadows, etc.
#[deriving(Clone)] #[deriving(Clone)]
pub struct ImageFragmentInfo { pub struct ImageFragmentInfo {
/// The image held within this box. /// The image held within this fragment.
pub image: ImageHolder, pub image: ImageHolder,
pub computed_width: Option<Au>, pub computed_width: Option<Au>,
pub computed_height: Option<Au>, pub computed_height: Option<Au>,
@ -126,9 +126,9 @@ pub struct ImageFragmentInfo {
} }
impl ImageFragmentInfo { impl ImageFragmentInfo {
/// Creates a new image box from the given URL and local image cache. /// Creates a new image fragment from the given URL and local image cache.
/// ///
/// FIXME(pcwalton): The fact that image boxes store the cache in the box makes little sense to /// FIXME(pcwalton): The fact that image fragments store the cache in the fragment makes little sense to
/// me. /// me.
pub fn new(node: &ThreadSafeLayoutNode, pub fn new(node: &ThreadSafeLayoutNode,
image_url: Url, image_url: Url,
@ -196,7 +196,7 @@ impl ImageFragmentInfo {
} }
} }
/// A box that represents an inline frame (iframe). This stores the pipeline ID so that the size /// A fragment that represents an inline frame (iframe). This stores the pipeline ID so that the size
/// of this iframe can be communicated via the constellation to the iframe's own layout task. /// of this iframe can be communicated via the constellation to the iframe's own layout task.
#[deriving(Clone)] #[deriving(Clone)]
pub struct IframeFragmentInfo { pub struct IframeFragmentInfo {
@ -207,7 +207,7 @@ pub struct IframeFragmentInfo {
} }
impl IframeFragmentInfo { impl IframeFragmentInfo {
/// Creates the information specific to an iframe box. /// Creates the information specific to an iframe fragment.
pub fn new(node: &ThreadSafeLayoutNode) -> IframeFragmentInfo { pub fn new(node: &ThreadSafeLayoutNode) -> IframeFragmentInfo {
let (pipeline_id, subpage_id) = node.iframe_pipeline_and_subpage_ids(); let (pipeline_id, subpage_id) = node.iframe_pipeline_and_subpage_ids();
IframeFragmentInfo { IframeFragmentInfo {
@ -217,10 +217,10 @@ impl IframeFragmentInfo {
} }
} }
/// A scanned text box represents a single run of text with a distinct style. A `TextBox` may be /// A scanned text fragment represents a single run of text with a distinct style. A `TextFragment`
/// split into two or more boxes across line breaks. Several `TextBox`es may correspond to a single /// may be split into two or more fragments across line breaks. Several `TextFragment`s may
/// DOM text node. Split text boxes are implemented by referring to subsets of a single `TextRun` /// correspond to a single DOM text node. Split text fragments are implemented by referring to
/// object. /// subsets of a single `TextRun` object.
#[deriving(Clone)] #[deriving(Clone)]
pub struct ScannedTextFragmentInfo { pub struct ScannedTextFragmentInfo {
/// The text run that this represents. /// The text run that this represents.
@ -231,7 +231,7 @@ pub struct ScannedTextFragmentInfo {
} }
impl ScannedTextFragmentInfo { impl ScannedTextFragmentInfo {
/// Creates the information specific to a scanned text box from a range and a text run. /// Creates the information specific to a scanned text fragment from a range and a text run.
pub fn new(run: Arc<Box<TextRun>>, range: Range<CharIndex>) -> ScannedTextFragmentInfo { pub fn new(run: Arc<Box<TextRun>>, range: Range<CharIndex>) -> ScannedTextFragmentInfo {
ScannedTextFragmentInfo { ScannedTextFragmentInfo {
run: run, run: run,
@ -257,11 +257,11 @@ impl SplitInfo {
} }
} }
/// Data for an unscanned text box. Unscanned text boxes are the results of flow construction that /// Data for an unscanned text fragment. Unscanned text fragments are the results of flow construction that
/// have not yet had their width determined. /// have not yet had their width determined.
#[deriving(Clone)] #[deriving(Clone)]
pub struct UnscannedTextFragmentInfo { pub struct UnscannedTextFragmentInfo {
/// The text inside the box. /// The text inside the fragment.
pub text: ~str, pub text: ~str,
} }
@ -283,7 +283,7 @@ impl UnscannedTextFragmentInfo {
} }
} }
/// A box that represents a table column. /// A fragment that represents a table column.
#[deriving(Clone)] #[deriving(Clone)]
pub struct TableColumnFragmentInfo { pub struct TableColumnFragmentInfo {
/// the number of columns a <col> element should span /// the number of columns a <col> element should span
@ -291,7 +291,7 @@ pub struct TableColumnFragmentInfo {
} }
impl TableColumnFragmentInfo { impl TableColumnFragmentInfo {
/// Create the information specific to an table column box. /// Create the information specific to an table column fragment.
pub fn new(node: &ThreadSafeLayoutNode) -> TableColumnFragmentInfo { pub fn new(node: &ThreadSafeLayoutNode) -> TableColumnFragmentInfo {
let span = { let span = {
let element = node.as_element(); let element = node.as_element();
@ -313,7 +313,7 @@ impl Fragment {
/// ///
/// * `constructor`: The flow constructor. /// * `constructor`: The flow constructor.
/// ///
/// * `node`: The node to create a box for. /// * `node`: The node to create a fragment for.
pub fn new(constructor: &mut FlowConstructor, node: &ThreadSafeLayoutNode) -> Fragment { pub fn new(constructor: &mut FlowConstructor, node: &ThreadSafeLayoutNode) -> Fragment {
Fragment { Fragment {
node: OpaqueNodeMethods::from_thread_safe_layout_node(node), node: OpaqueNodeMethods::from_thread_safe_layout_node(node),
@ -321,7 +321,7 @@ impl Fragment {
border_box: Rect::zero(), border_box: Rect::zero(),
border_padding: Zero::zero(), border_padding: Zero::zero(),
margin: Zero::zero(), margin: Zero::zero(),
specific: constructor.build_specific_box_info_for_node(node), specific: constructor.build_specific_fragment_info_for_node(node),
new_line_pos: vec!(), new_line_pos: vec!(),
} }
} }
@ -340,15 +340,15 @@ impl Fragment {
} }
/// Constructs a new `Fragment` instance for an anonymous table object. /// Constructs a new `Fragment` instance for an anonymous table object.
pub fn new_anonymous_table_box(node: &ThreadSafeLayoutNode, specific: SpecificFragmentInfo) -> Fragment { pub fn new_anonymous_table_fragment(node: &ThreadSafeLayoutNode, specific: SpecificFragmentInfo) -> Fragment {
// CSS 2.1 § 17.2.1 This is for non-inherited properties on anonymous table boxes // CSS 2.1 § 17.2.1 This is for non-inherited properties on anonymous table fragments
// example: // example:
// //
// <div style="display: table"> // <div style="display: table">
// Foo // Foo
// </div> // </div>
// //
// Anonymous table boxes, TableRowFragment and TableCellFragment, are generated around `Foo`, but it shouldn't inherit the border. // Anonymous table fragments, TableRowFragment and TableCellFragment, are generated around `Foo`, but it shouldn't inherit the border.
let node_style = cascade_anonymous(&**node.style()); let node_style = cascade_anonymous(&**node.style());
Fragment { Fragment {
@ -378,15 +378,15 @@ impl Fragment {
} }
} }
/// Returns a debug ID of this box. This ID should not be considered stable across multiple /// Returns a debug ID of this fragment. This ID should not be considered stable across multiple
/// layouts or box manipulations. /// layouts or fragment manipulations.
pub fn debug_id(&self) -> uint { pub fn debug_id(&self) -> uint {
unsafe { unsafe {
cast::transmute(self) cast::transmute(self)
} }
} }
/// Transforms this box into another box of the given type, with the given size, preserving all /// Transforms this fragment into another fragment of the given type, with the given size, preserving all
/// the other data. /// the other data.
pub fn transform(&self, size: Size2D<Au>, specific: SpecificFragmentInfo) -> Fragment { pub fn transform(&self, size: Size2D<Au>, specific: SpecificFragmentInfo) -> Fragment {
Fragment { Fragment {
@ -409,7 +409,7 @@ impl Fragment {
TableWrapperFragment => (true, false), TableWrapperFragment => (true, false),
TableRowFragment => (false, false), TableRowFragment => (false, false),
ScannedTextFragment(_) | TableColumnFragment(_) | UnscannedTextFragment(_) => { ScannedTextFragment(_) | TableColumnFragment(_) | UnscannedTextFragment(_) => {
// Styles are irrelevant for these kinds of boxes. // Styles are irrelevant for these kinds of fragments.
return IntrinsicWidths::new() return IntrinsicWidths::new()
} }
}; };
@ -541,7 +541,7 @@ impl Fragment {
} }
} }
// Go over the ancestor boxes and add all relative offsets (if any). // Go over the ancestor fragments and add all relative offsets (if any).
let mut rel_pos: Point2D<Au> = Zero::zero(); let mut rel_pos: Point2D<Au> = Zero::zero();
match inline_fragment_context { match inline_fragment_context {
None => { None => {
@ -603,7 +603,7 @@ impl Fragment {
self.style().get_inheritedtext().white_space self.style().get_inheritedtext().white_space
} }
/// Returns the text decoration of this box, according to the style of the nearest ancestor /// Returns the text decoration of this fragment, according to the style of the nearest ancestor
/// element. /// element.
/// ///
/// NB: This may not be the actual text decoration, because of the override rules specified in /// NB: This may not be the actual text decoration, because of the override rules specified in
@ -627,7 +627,7 @@ impl Fragment {
} }
} }
/// Returns true if this element can be split. This is true for text boxes. /// Returns true if this element can be split. This is true for text fragments.
pub fn can_split(&self) -> bool { pub fn can_split(&self) -> bool {
match self.specific { match self.specific {
ScannedTextFragment(..) => true, ScannedTextFragment(..) => true,
@ -635,8 +635,8 @@ impl Fragment {
} }
} }
/// Adds the display items necessary to paint the background of this box to the display list if /// Adds the display items necessary to paint the background of this fragment to the display
/// necessary. /// list if necessary.
pub fn build_display_list_for_background_if_applicable(&self, pub fn build_display_list_for_background_if_applicable(&self,
list: &mut DisplayList, list: &mut DisplayList,
layout_context: &LayoutContext, layout_context: &LayoutContext,
@ -645,7 +645,7 @@ impl Fragment {
// FIXME: This causes a lot of background colors to be displayed when they are clearly not // FIXME: This causes a lot of background colors to be displayed when they are clearly not
// needed. We could use display list optimization to clean this up, but it still seems // needed. We could use display list optimization to clean this up, but it still seems
// inefficient. What we really want is something like "nearest ancestor element that // inefficient. What we really want is something like "nearest ancestor element that
// doesn't have a box". // doesn't have a fragment".
let style = self.style(); let style = self.style();
let background_color = style.resolve_color(style.get_background().background_color); let background_color = style.resolve_color(style.get_background().background_color);
if !background_color.alpha.approx_eq(&0.0) { if !background_color.alpha.approx_eq(&0.0) {
@ -741,7 +741,7 @@ impl Fragment {
} }
} }
/// Adds the display items necessary to paint the borders of this box to a display list if /// Adds the display items necessary to paint the borders of this fragment to a display list if
/// necessary. /// necessary.
pub fn build_display_list_for_borders_if_applicable(&self, pub fn build_display_list_for_borders_if_applicable(&self,
list: &mut DisplayList, list: &mut DisplayList,
@ -778,18 +778,18 @@ impl Fragment {
list.push(BorderDisplayItemClass(border_display_item)) list.push(BorderDisplayItemClass(border_display_item))
} }
fn build_debug_borders_around_text_boxes(&self, fn build_debug_borders_around_text_fragments(&self,
display_list: &mut DisplayList, display_list: &mut DisplayList,
flow_origin: Point2D<Au>, flow_origin: Point2D<Au>,
text_box: &ScannedTextFragmentInfo) { text_fragment: &ScannedTextFragmentInfo) {
let box_bounds = self.border_box; let fragment_bounds = self.border_box;
let absolute_box_bounds = box_bounds.translate(&flow_origin); let absolute_fragment_bounds = fragment_bounds.translate(&flow_origin);
// Compute the text box bounds and draw a border surrounding them. // Compute the text fragment bounds and draw a border surrounding them.
let debug_border = SideOffsets2D::new_all_same(Au::from_px(1)); let debug_border = SideOffsets2D::new_all_same(Au::from_px(1));
let border_display_item = box BorderDisplayItem { let border_display_item = box BorderDisplayItem {
base: BaseDisplayItem::new(absolute_box_bounds, self.node, ContentStackingLevel), base: BaseDisplayItem::new(absolute_fragment_bounds, self.node, ContentStackingLevel),
border: debug_border, border: debug_border,
color: SideOffsets2D::new_all_same(rgb(0, 0, 200)), color: SideOffsets2D::new_all_same(rgb(0, 0, 200)),
style: SideOffsets2D::new_all_same(border_style::solid) style: SideOffsets2D::new_all_same(border_style::solid)
@ -797,9 +797,9 @@ impl Fragment {
display_list.push(BorderDisplayItemClass(border_display_item)); display_list.push(BorderDisplayItemClass(border_display_item));
// Draw a rectangle representing the baselines. // Draw a rectangle representing the baselines.
let ascent = text_box.run.ascent(); let ascent = text_fragment.run.ascent();
let baseline = Rect(absolute_box_bounds.origin + Point2D(Au(0), ascent), let baseline = Rect(absolute_fragment_bounds.origin + Point2D(Au(0), ascent),
Size2D(absolute_box_bounds.size.width, Au(0))); Size2D(absolute_fragment_bounds.size.width, Au(0)));
let line_display_item = box LineDisplayItem { let line_display_item = box LineDisplayItem {
base: BaseDisplayItem::new(baseline, self.node, ContentStackingLevel), base: BaseDisplayItem::new(baseline, self.node, ContentStackingLevel),
@ -809,17 +809,17 @@ impl Fragment {
display_list.push(LineDisplayItemClass(line_display_item)); display_list.push(LineDisplayItemClass(line_display_item));
} }
fn build_debug_borders_around_box(&self, fn build_debug_borders_around_fragment(&self,
display_list: &mut DisplayList, display_list: &mut DisplayList,
flow_origin: Point2D<Au>) { flow_origin: Point2D<Au>) {
let box_bounds = self.border_box; let fragment_bounds = self.border_box;
let absolute_box_bounds = box_bounds.translate(&flow_origin); let absolute_fragment_bounds = fragment_bounds.translate(&flow_origin);
// This prints a debug border around the border of this box. // This prints a debug border around the border of this fragment.
let debug_border = SideOffsets2D::new_all_same(Au::from_px(1)); let debug_border = SideOffsets2D::new_all_same(Au::from_px(1));
let border_display_item = box BorderDisplayItem { let border_display_item = box BorderDisplayItem {
base: BaseDisplayItem::new(absolute_box_bounds, self.node, ContentStackingLevel), base: BaseDisplayItem::new(absolute_fragment_bounds, self.node, ContentStackingLevel),
border: debug_border, border: debug_border,
color: SideOffsets2D::new_all_same(rgb(0, 0, 200)), color: SideOffsets2D::new_all_same(rgb(0, 0, 200)),
style: SideOffsets2D::new_all_same(border_style::solid) style: SideOffsets2D::new_all_same(border_style::solid)
@ -827,7 +827,7 @@ impl Fragment {
display_list.push(BorderDisplayItemClass(border_display_item)) display_list.push(BorderDisplayItemClass(border_display_item))
} }
/// Adds the display items for this box to the given stacking context. /// Adds the display items for this fragment to the given stacking context.
/// ///
/// Arguments: /// Arguments:
/// ///
@ -835,7 +835,6 @@ impl Fragment {
/// * `layout_context`: The layout context. /// * `layout_context`: The layout context.
/// * `dirty`: The dirty rectangle in the coordinate system of the owning flow. /// * `dirty`: The dirty rectangle in the coordinate system of the owning flow.
/// * `flow_origin`: Position of the origin of the owning flow wrt the display list root flow. /// * `flow_origin`: Position of the origin of the owning flow wrt the display list root flow.
/// box.
pub fn build_display_list(&self, pub fn build_display_list(&self,
display_list: &mut DisplayList, display_list: &mut DisplayList,
layout_context: &LayoutContext, layout_context: &LayoutContext,
@ -844,25 +843,25 @@ impl Fragment {
inline_fragment_context: Option<InlineFragmentContext>) inline_fragment_context: Option<InlineFragmentContext>)
-> ChildDisplayListAccumulator { -> ChildDisplayListAccumulator {
// Fragment position wrt to the owning flow. // Fragment position wrt to the owning flow.
let box_bounds = self.border_box; let fragment_bounds = self.border_box;
let absolute_box_bounds = box_bounds.translate(&flow_origin); let absolute_fragment_bounds = fragment_bounds.translate(&flow_origin);
debug!("Fragment::build_display_list at rel={}, abs={}: {}", debug!("Fragment::build_display_list at rel={}, abs={}: {}",
box_bounds, fragment_bounds,
absolute_box_bounds, absolute_fragment_bounds,
self); self);
debug!("Fragment::build_display_list: dirty={}, flow_origin={}", debug!("Fragment::build_display_list: dirty={}, flow_origin={}",
layout_context.dirty, layout_context.dirty,
flow_origin); flow_origin);
let mut accumulator = ChildDisplayListAccumulator::new(self.style(), let mut accumulator = ChildDisplayListAccumulator::new(self.style(),
absolute_box_bounds, absolute_fragment_bounds,
self.node, self.node,
ContentStackingLevel); ContentStackingLevel);
if self.style().get_inheritedbox().visibility != visibility::visible { if self.style().get_inheritedbox().visibility != visibility::visible {
return accumulator return accumulator
} }
if !absolute_box_bounds.intersects(&layout_context.dirty) { if !absolute_fragment_bounds.intersects(&layout_context.dirty) {
debug!("Fragment::build_display_list: Did not intersect..."); debug!("Fragment::build_display_list: Did not intersect...");
return accumulator return accumulator
} }
@ -874,29 +873,29 @@ impl Fragment {
StackingLevel::from_background_and_border_level(background_and_border_level); StackingLevel::from_background_and_border_level(background_and_border_level);
// Add a pseudo-display item for content box queries. This is a very bogus thing to do. // Add a pseudo-display item for content box queries. This is a very bogus thing to do.
let base_display_item = box BaseDisplayItem::new(absolute_box_bounds, self.node, level); let base_display_item = box BaseDisplayItem::new(absolute_fragment_bounds, self.node, level);
display_list.push(PseudoDisplayItemClass(base_display_item)); display_list.push(PseudoDisplayItemClass(base_display_item));
// Add the background to the list, if applicable. // Add the background to the list, if applicable.
self.build_display_list_for_background_if_applicable(display_list, self.build_display_list_for_background_if_applicable(display_list,
layout_context, layout_context,
level, level,
&absolute_box_bounds); &absolute_fragment_bounds);
// Add a border, if applicable. // Add a border, if applicable.
// //
// TODO: Outlines. // TODO: Outlines.
self.build_display_list_for_borders_if_applicable(display_list, self.build_display_list_for_borders_if_applicable(display_list,
&absolute_box_bounds, &absolute_fragment_bounds,
level, level,
inline_fragment_context); inline_fragment_context);
} }
// Add a clip, if applicable. // Add a clip, if applicable.
match self.specific { match self.specific {
UnscannedTextFragment(_) => fail!("Shouldn't see unscanned boxes here."), UnscannedTextFragment(_) => fail!("Shouldn't see unscanned fragments here."),
TableColumnFragment(_) => fail!("Shouldn't see table column boxes here."), TableColumnFragment(_) => fail!("Shouldn't see table column fragments here."),
ScannedTextFragment(ref text_box) => { ScannedTextFragment(ref text_fragment) => {
// Compute text color. // Compute text color.
let text_color = self.style().get_color().color.to_gfx_color(); let text_color = self.style().get_color().color.to_gfx_color();
@ -911,15 +910,15 @@ impl Fragment {
.map(|c| c.to_gfx_color()), .map(|c| c.to_gfx_color()),
}; };
let mut bounds = absolute_box_bounds.clone(); let mut bounds = absolute_fragment_bounds.clone();
bounds.origin.x = bounds.origin.x + self.border_padding.left; bounds.origin.x = bounds.origin.x + self.border_padding.left;
bounds.size.width = bounds.size.width - self.border_padding.horizontal(); bounds.size.width = bounds.size.width - self.border_padding.horizontal();
// Create the text box. // Create the text fragment.
let text_display_item = box TextDisplayItem { let text_display_item = box TextDisplayItem {
base: BaseDisplayItem::new(bounds, self.node, ContentStackingLevel), base: BaseDisplayItem::new(bounds, self.node, ContentStackingLevel),
text_run: text_box.run.clone(), text_run: text_fragment.run.clone(),
range: text_box.range, range: text_fragment.range,
text_color: text_color, text_color: text_color,
text_decorations: text_decorations, text_decorations: text_decorations,
}; };
@ -929,29 +928,29 @@ impl Fragment {
// //
// FIXME(#2263, pcwalton): This is a bit of an abuse of the logging infrastructure. // FIXME(#2263, pcwalton): This is a bit of an abuse of the logging infrastructure.
// We should have a real `SERVO_DEBUG` system. // We should have a real `SERVO_DEBUG` system.
debug!("{:?}", self.build_debug_borders_around_text_boxes(display_list, debug!("{:?}", self.build_debug_borders_around_text_fragments(display_list,
flow_origin, flow_origin,
text_box)) text_fragment))
}, },
GenericFragment | IframeFragment(..) | TableFragment | TableCellFragment | TableRowFragment | GenericFragment | IframeFragment(..) | TableFragment | TableCellFragment | TableRowFragment |
TableWrapperFragment => { TableWrapperFragment => {
// FIXME(pcwalton): This is a bit of an abuse of the logging infrastructure. We // FIXME(pcwalton): This is a bit of an abuse of the logging infrastructure. We
// should have a real `SERVO_DEBUG` system. // should have a real `SERVO_DEBUG` system.
debug!("{:?}", self.build_debug_borders_around_box(display_list, flow_origin)) debug!("{:?}", self.build_debug_borders_around_fragment(display_list, flow_origin))
}, },
ImageFragment(_) => { ImageFragment(_) => {
let mut bounds = absolute_box_bounds.clone(); let mut bounds = absolute_fragment_bounds.clone();
bounds.origin.x = bounds.origin.x + self.border_padding.left; bounds.origin.x = bounds.origin.x + self.border_padding.left;
bounds.origin.y = bounds.origin.y + self.border_padding.top; bounds.origin.y = bounds.origin.y + self.border_padding.top;
bounds.size.width = bounds.size.width - self.border_padding.horizontal(); bounds.size.width = bounds.size.width - self.border_padding.horizontal();
bounds.size.height = bounds.size.height - self.border_padding.vertical(); bounds.size.height = bounds.size.height - self.border_padding.vertical();
match self.specific { match self.specific {
ImageFragment(ref image_box) => { ImageFragment(ref image_fragment) => {
let image_ref = &image_box.image; let image_ref = &image_fragment.image;
match image_ref.get_image_if_present() { match image_ref.get_image_if_present() {
Some(image) => { Some(image) => {
debug!("(building display list) building image box"); debug!("(building display list) building image fragment");
// Place the image into the display list. // Place the image into the display list.
let image_display_item = box ImageDisplayItem { let image_display_item = box ImageDisplayItem {
@ -977,7 +976,7 @@ impl Fragment {
// FIXME(pcwalton): This is a bit of an abuse of the logging // FIXME(pcwalton): This is a bit of an abuse of the logging
// infrastructure. We should have a real `SERVO_DEBUG` system. // infrastructure. We should have a real `SERVO_DEBUG` system.
debug!("{:?}", self.build_debug_borders_around_box(display_list, flow_origin)) debug!("{:?}", self.build_debug_borders_around_fragment(display_list, flow_origin))
} }
} }
@ -992,8 +991,8 @@ impl Fragment {
// layout for the iframe only needs to know size, and origin is only relevant if the // layout for the iframe only needs to know size, and origin is only relevant if the
// iframe is actually going to be displayed. // iframe is actually going to be displayed.
match self.specific { match self.specific {
IframeFragment(ref iframe_box) => { IframeFragment(ref iframe_fragment) => {
self.finalize_position_and_size_of_iframe(iframe_box, flow_origin, layout_context) self.finalize_position_and_size_of_iframe(iframe_fragment, flow_origin, layout_context)
} }
_ => {} _ => {}
} }
@ -1009,28 +1008,28 @@ impl Fragment {
match self.specific { match self.specific {
GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment | TableColumnFragment(_) | TableRowFragment | GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment | TableColumnFragment(_) | TableRowFragment |
TableWrapperFragment => {} TableWrapperFragment => {}
ImageFragment(ref mut image_box_info) => { ImageFragment(ref mut image_fragment_info) => {
let image_width = image_box_info.image_width(); let image_width = image_fragment_info.image_width();
result.minimum_width = geometry::max(result.minimum_width, image_width); result.minimum_width = geometry::max(result.minimum_width, image_width);
result.preferred_width = geometry::max(result.preferred_width, image_width); result.preferred_width = geometry::max(result.preferred_width, image_width);
} }
ScannedTextFragment(ref text_box_info) => { ScannedTextFragment(ref text_fragment_info) => {
let range = &text_box_info.range; let range = &text_fragment_info.range;
let min_line_width = text_box_info.run.min_width_for_range(range); let min_line_width = text_fragment_info.run.min_width_for_range(range);
let mut max_line_width = Au::new(0); let mut max_line_width = Au::new(0);
for line_range in text_box_info.run.iter_natural_lines_for_range(range) { for line_range in text_fragment_info.run.iter_natural_lines_for_range(range) {
let line_metrics = text_box_info.run.metrics_for_range(&line_range); let line_metrics = text_fragment_info.run.metrics_for_range(&line_range);
max_line_width = Au::max(max_line_width, line_metrics.advance_width); max_line_width = Au::max(max_line_width, line_metrics.advance_width);
} }
result.minimum_width = geometry::max(result.minimum_width, min_line_width); result.minimum_width = geometry::max(result.minimum_width, min_line_width);
result.preferred_width = geometry::max(result.preferred_width, max_line_width); result.preferred_width = geometry::max(result.preferred_width, max_line_width);
} }
UnscannedTextFragment(..) => fail!("Unscanned text boxes should have been scanned by now!"), UnscannedTextFragment(..) => fail!("Unscanned text fragments should have been scanned by now!"),
} }
// Take borders and padding for parent inline boxes into account, if necessary. // Take borders and padding for parent inline fragments into account, if necessary.
match inline_fragment_context { match inline_fragment_context {
None => {} None => {}
Some(context) => { Some(context) => {
@ -1052,39 +1051,39 @@ impl Fragment {
match self.specific { match self.specific {
GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment | TableRowFragment | GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment | TableRowFragment |
TableWrapperFragment => Au(0), TableWrapperFragment => Au(0),
ImageFragment(ref image_box_info) => { ImageFragment(ref image_fragment_info) => {
image_box_info.computed_width() image_fragment_info.computed_width()
} }
ScannedTextFragment(ref text_box_info) => { ScannedTextFragment(ref text_fragment_info) => {
let (range, run) = (&text_box_info.range, &text_box_info.run); let (range, run) = (&text_fragment_info.range, &text_fragment_info.run);
let text_bounds = run.metrics_for_range(range).bounding_box; let text_bounds = run.metrics_for_range(range).bounding_box;
text_bounds.size.width text_bounds.size.width
} }
TableColumnFragment(_) => fail!("Table column boxes do not have width"), TableColumnFragment(_) => fail!("Table column fragments do not have width"),
UnscannedTextFragment(_) => fail!("Unscanned text boxes should have been scanned by now!"), UnscannedTextFragment(_) => fail!("Unscanned text fragments should have been scanned by now!"),
} }
} }
/// Returns, and computes, the height of this box. /// Returns, and computes, the height of this fragment.
pub fn content_height(&self) -> Au { pub fn content_height(&self) -> Au {
match self.specific { match self.specific {
GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment | TableRowFragment | GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment | TableRowFragment |
TableWrapperFragment => Au(0), TableWrapperFragment => Au(0),
ImageFragment(ref image_box_info) => { ImageFragment(ref image_fragment_info) => {
image_box_info.computed_height() image_fragment_info.computed_height()
} }
ScannedTextFragment(ref text_box_info) => { ScannedTextFragment(ref text_fragment_info) => {
// Compute the height based on the line-height and font size. // Compute the height based on the line-height and font size.
// //
// FIXME(pcwalton): Shouldn't we use the value of the `font-size` property below // FIXME(pcwalton): Shouldn't we use the value of the `font-size` property below
// instead of the bounding box of the text run? // instead of the bounding box of the text run?
let (range, run) = (&text_box_info.range, &text_box_info.run); let (range, run) = (&text_fragment_info.range, &text_fragment_info.run);
let text_bounds = run.metrics_for_range(range).bounding_box; let text_bounds = run.metrics_for_range(range).bounding_box;
let em_size = text_bounds.size.height; let em_size = text_bounds.size.height;
self.calculate_line_height(em_size) self.calculate_line_height(em_size)
} }
TableColumnFragment(_) => fail!("Table column boxes do not have height"), TableColumnFragment(_) => fail!("Table column fragments do not have height"),
UnscannedTextFragment(_) => fail!("Unscanned text boxes should have been scanned by now!"), UnscannedTextFragment(_) => fail!("Unscanned text fragments should have been scanned by now!"),
} }
} }
@ -1102,82 +1101,81 @@ impl Fragment {
} }
} }
/// Find the split of a box that includes a new-line character. /// Find the split of a fragment that includes a new-line character.
/// ///
/// A return value of `None` indicates that the box is not splittable. /// A return value of `None` indicates that the fragment is not splittable.
/// Otherwise the split information is returned. The right information is /// Otherwise the split information is returned. The right information is
/// optional due to the possibility of it being whitespace. /// optional due to the possibility of it being whitespace.
// //
// TODO(bjz): The text run should be removed in the future, but it is currently needed for // TODO(bjz): The text run should be removed in the future, but it is currently needed for
// the current method of box splitting in the `inline::try_append_*` functions. // the current method of fragment splitting in the `inline::try_append_*` functions.
pub fn find_split_info_by_new_line(&self) pub fn find_split_info_by_new_line(&self)
-> Option<(SplitInfo, Option<SplitInfo>, Arc<Box<TextRun>> /* TODO(bjz): remove */)> { -> Option<(SplitInfo, Option<SplitInfo>, Arc<Box<TextRun>> /* TODO(bjz): remove */)> {
match self.specific { match self.specific {
GenericFragment | IframeFragment(_) | ImageFragment(_) | TableFragment | TableCellFragment | GenericFragment | IframeFragment(_) | ImageFragment(_) | TableFragment | TableCellFragment |
TableRowFragment | TableWrapperFragment => None, TableRowFragment | TableWrapperFragment => None,
TableColumnFragment(_) => fail!("Table column boxes do not need to split"), TableColumnFragment(_) => fail!("Table column fragments do not need to split"),
UnscannedTextFragment(_) => fail!("Unscanned text boxes should have been scanned by now!"), UnscannedTextFragment(_) => fail!("Unscanned text fragments should have been scanned by now!"),
ScannedTextFragment(ref text_box_info) => { ScannedTextFragment(ref text_fragment_info) => {
let mut new_line_pos = self.new_line_pos.clone(); let mut new_line_pos = self.new_line_pos.clone();
let cur_new_line_pos = new_line_pos.shift().unwrap(); let cur_new_line_pos = new_line_pos.shift().unwrap();
let left_range = Range::new(text_box_info.range.begin(), cur_new_line_pos); let left_range = Range::new(text_fragment_info.range.begin(), cur_new_line_pos);
let right_range = Range::new(text_box_info.range.begin() + cur_new_line_pos + CharIndex(1), let right_range = Range::new(text_fragment_info.range.begin() + cur_new_line_pos + CharIndex(1),
text_box_info.range.length() - (cur_new_line_pos + CharIndex(1))); text_fragment_info.range.length() - (cur_new_line_pos + CharIndex(1)));
// Left box is for left text of first founded new-line character. // Left fragment is for left text of first founded new-line character.
let left_box = SplitInfo::new(left_range, text_box_info); let left_fragment = SplitInfo::new(left_range, text_fragment_info);
// Right box is for right text of first founded new-line character. // Right fragment is for right text of first founded new-line character.
let right_box = if right_range.length() > CharIndex(0) { let right_fragment = if right_range.length() > CharIndex(0) {
Some(SplitInfo::new(right_range, text_box_info)) Some(SplitInfo::new(right_range, text_fragment_info))
} else { } else {
None None
}; };
Some((left_box, right_box, text_box_info.run.clone())) Some((left_fragment, right_fragment, text_fragment_info.run.clone()))
} }
} }
} }
/// Attempts to find the split positions of a text box so that its width is /// Attempts to find the split positions of a text fragment so that its width is
/// no more than `max_width`. /// no more than `max_width`.
/// ///
/// A return value of `None` indicates that the box could not be split. /// A return value of `None` indicates that the fragment could not be split.
/// Otherwise the information pertaining to the split is returned. The left /// Otherwise the information pertaining to the split is returned. The left
/// and right split information are both optional due to the possibility of /// and right split information are both optional due to the possibility of
/// them being whitespace. /// them being whitespace.
// //
// TODO(bjz): The text run should be removed in the future, but it is currently needed for // TODO(bjz): The text run should be removed in the future, but it is currently needed for
// the current method of box splitting in the `inline::try_append_*` functions. // the current method of fragment splitting in the `inline::try_append_*` functions.
pub fn find_split_info_for_width(&self, start: CharIndex, max_width: Au, starts_line: bool) pub fn find_split_info_for_width(&self, start: CharIndex, max_width: Au, starts_line: bool)
-> Option<(Option<SplitInfo>, Option<SplitInfo>, Arc<Box<TextRun>> /* TODO(bjz): remove */)> { -> Option<(Option<SplitInfo>, Option<SplitInfo>, Arc<Box<TextRun>> /* TODO(bjz): remove */)> {
match self.specific { match self.specific {
GenericFragment | IframeFragment(_) | ImageFragment(_) | TableFragment | TableCellFragment | GenericFragment | IframeFragment(_) | ImageFragment(_) | TableFragment | TableCellFragment |
TableRowFragment | TableWrapperFragment => None, TableRowFragment | TableWrapperFragment => None,
TableColumnFragment(_) => fail!("Table column boxes do not have width"), TableColumnFragment(_) => fail!("Table column fragments do not have width"),
UnscannedTextFragment(_) => fail!("Unscanned text boxes should have been scanned by now!"), UnscannedTextFragment(_) => fail!("Unscanned text fragments should have been scanned by now!"),
ScannedTextFragment(ref text_box_info) => { ScannedTextFragment(ref text_fragment_info) => {
let mut pieces_processed_count: uint = 0; let mut pieces_processed_count: uint = 0;
let mut remaining_width: Au = max_width; let mut remaining_width: Au = max_width;
let mut left_range = Range::new(text_box_info.range.begin() + start, CharIndex(0)); let mut left_range = Range::new(text_fragment_info.range.begin() + start, CharIndex(0));
let mut right_range: Option<Range<CharIndex>> = None; let mut right_range: Option<Range<CharIndex>> = None;
debug!("split_to_width: splitting text box (strlen={:u}, range={}, \ debug!("split_to_width: splitting text fragment (strlen={}, range={}, avail_width={})",
avail_width={})", text_fragment_info.run.text.len(),
text_box_info.run.text.len(), text_fragment_info.range,
text_box_info.range,
max_width); max_width);
for (glyphs, offset, slice_range) in text_box_info.run.iter_slices_for_range( for (glyphs, offset, slice_range) in text_fragment_info.run.iter_slices_for_range(
&text_box_info.range) { &text_fragment_info.range) {
debug!("split_to_width: considering slice (offset={}, range={}, \ debug!("split_to_width: considering slice (offset={}, range={}, \
remain_width={})", remain_width={})",
offset, offset,
slice_range, slice_range,
remaining_width); remaining_width);
let metrics = text_box_info.run.metrics_for_slice(glyphs, &slice_range); let metrics = text_fragment_info.run.metrics_for_slice(glyphs, &slice_range);
let advance = metrics.advance_width; let advance = metrics.advance_width;
let should_continue; let should_continue;
@ -1201,19 +1199,19 @@ impl Fragment {
if glyphs.is_whitespace() { if glyphs.is_whitespace() {
// If there are still things after the trimmable whitespace, create the // If there are still things after the trimmable whitespace, create the
// right chunk. // right chunk.
if slice_end < text_box_info.range.end() { if slice_end < text_fragment_info.range.end() {
debug!("split_to_width: case=skipping trimmable trailing \ debug!("split_to_width: case=skipping trimmable trailing \
whitespace, then split remainder"); whitespace, then split remainder");
let right_range_end = text_box_info.range.end() - slice_end; let right_range_end = text_fragment_info.range.end() - slice_end;
right_range = Some(Range::new(slice_end, right_range_end)); right_range = Some(Range::new(slice_end, right_range_end));
} else { } else {
debug!("split_to_width: case=skipping trimmable trailing \ debug!("split_to_width: case=skipping trimmable trailing \
whitespace"); whitespace");
} }
} else if slice_begin < text_box_info.range.end() { } else if slice_begin < text_fragment_info.range.end() {
// There are still some things left over at the end of the line. Create // There are still some things left over at the end of the line. Create
// the right chunk. // the right chunk.
let right_range_end = text_box_info.range.end() - slice_begin; let right_range_end = text_fragment_info.range.end() - slice_begin;
right_range = Some(Range::new(slice_begin, right_range_end)); right_range = Some(Range::new(slice_begin, right_range_end));
debug!("split_to_width: case=splitting remainder with right range={:?}", debug!("split_to_width: case=splitting remainder with right range={:?}",
right_range); right_range);
@ -1233,28 +1231,28 @@ impl Fragment {
None None
} else { } else {
let left = if left_is_some { let left = if left_is_some {
Some(SplitInfo::new(left_range, text_box_info)) Some(SplitInfo::new(left_range, text_fragment_info))
} else { } else {
None None
}; };
let right = right_range.map(|right_range| SplitInfo::new(right_range, text_box_info)); let right = right_range.map(|right_range| SplitInfo::new(right_range, text_fragment_info));
Some((left, right, text_box_info.run.clone())) Some((left, right, text_fragment_info.run.clone()))
} }
} }
} }
} }
/// Returns true if this box is an unscanned text box that consists entirely of whitespace. /// Returns true if this fragment is an unscanned text fragment that consists entirely of whitespace.
pub fn is_whitespace_only(&self) -> bool { pub fn is_whitespace_only(&self) -> bool {
match self.specific { match self.specific {
UnscannedTextFragment(ref text_box_info) => is_whitespace(text_box_info.text), UnscannedTextFragment(ref text_fragment_info) => is_whitespace(text_fragment_info.text),
_ => false, _ => false,
} }
} }
/// Assigns replaced width, padding, and margins for this box only if it is replaced content /// Assigns replaced width, padding, and margins for this fragment only if it is replaced
/// per CSS 2.1 § 10.3.2. /// content per CSS 2.1 § 10.3.2.
pub fn assign_replaced_width_if_necessary(&mut self, pub fn assign_replaced_width_if_necessary(&mut self,
container_width: Au, container_width: Au,
inline_fragment_context: inline_fragment_context:
@ -1262,8 +1260,8 @@ impl Fragment {
match self.specific { match self.specific {
GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment | TableRowFragment | GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment | TableRowFragment |
TableWrapperFragment => return, TableWrapperFragment => return,
TableColumnFragment(_) => fail!("Table column boxes do not have width"), TableColumnFragment(_) => fail!("Table column fragments do not have width"),
UnscannedTextFragment(_) => fail!("Unscanned text boxes should have been scanned by now!"), UnscannedTextFragment(_) => fail!("Unscanned text fragments should have been scanned by now!"),
ImageFragment(_) | ScannedTextFragment(_) => {} ImageFragment(_) | ScannedTextFragment(_) => {}
}; };
@ -1275,37 +1273,37 @@ impl Fragment {
match self.specific { match self.specific {
ScannedTextFragment(_) => { ScannedTextFragment(_) => {
// Scanned text boxes will have already had their content widths assigned by this // Scanned text fragments will have already had their content widths assigned by this
// point. // point.
self.border_box.size.width = self.border_box.size.width + noncontent_width self.border_box.size.width = self.border_box.size.width + noncontent_width
} }
ImageFragment(ref mut image_box_info) => { ImageFragment(ref mut image_fragment_info) => {
// TODO(ksh8281): compute border,margin // TODO(ksh8281): compute border,margin
let width = ImageFragmentInfo::style_length(style_width, let width = ImageFragmentInfo::style_length(style_width,
image_box_info.dom_width, image_fragment_info.dom_width,
container_width); container_width);
let height = ImageFragmentInfo::style_length(style_height, let height = ImageFragmentInfo::style_length(style_height,
image_box_info.dom_height, image_fragment_info.dom_height,
Au(0)); Au(0));
let width = match (width,height) { let width = match (width,height) {
(Auto, Auto) => image_box_info.image_width(), (Auto, Auto) => image_fragment_info.image_width(),
(Auto,Specified(h)) => { (Auto,Specified(h)) => {
let scale = image_box_info. let scale = image_fragment_info.
image_height().to_f32().unwrap() / h.to_f32().unwrap(); image_height().to_f32().unwrap() / h.to_f32().unwrap();
Au::new((image_box_info.image_width().to_f32().unwrap() / scale) as i32) Au::new((image_fragment_info.image_width().to_f32().unwrap() / scale) as i32)
}, },
(Specified(w), _) => w, (Specified(w), _) => w,
}; };
self.border_box.size.width = width + noncontent_width; self.border_box.size.width = width + noncontent_width;
image_box_info.computed_width = Some(width); image_fragment_info.computed_width = Some(width);
} }
_ => fail!("this case should have been handled above"), _ => fail!("this case should have been handled above"),
} }
} }
/// Assign height for this box if it is replaced content. The width must have been assigned /// Assign height for this fragment if it is replaced content. The width must have been assigned
/// first. /// first.
/// ///
/// Ideally, this should follow CSS 2.1 § 10.6.2. /// Ideally, this should follow CSS 2.1 § 10.6.2.
@ -1313,8 +1311,8 @@ impl Fragment {
match self.specific { match self.specific {
GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment | TableRowFragment | GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment | TableRowFragment |
TableWrapperFragment => return, TableWrapperFragment => return,
TableColumnFragment(_) => fail!("Table column boxes do not have height"), TableColumnFragment(_) => fail!("Table column fragments do not have height"),
UnscannedTextFragment(_) => fail!("Unscanned text boxes should have been scanned by now!"), UnscannedTextFragment(_) => fail!("Unscanned text fragments should have been scanned by now!"),
ImageFragment(_) | ScannedTextFragment(_) => {} ImageFragment(_) | ScannedTextFragment(_) => {}
} }
@ -1323,34 +1321,34 @@ impl Fragment {
let noncontent_height = self.border_padding.vertical(); let noncontent_height = self.border_padding.vertical();
match self.specific { match self.specific {
ImageFragment(ref mut image_box_info) => { ImageFragment(ref mut image_fragment_info) => {
// TODO(ksh8281): compute border,margin,padding // TODO(ksh8281): compute border,margin,padding
let width = image_box_info.computed_width(); let width = image_fragment_info.computed_width();
// FIXME(ksh8281): we shouldn't assign height this way // FIXME(ksh8281): we shouldn't assign height this way
// we don't know about size of parent's height // we don't know about size of parent's height
let height = ImageFragmentInfo::style_length(style_height, let height = ImageFragmentInfo::style_length(style_height,
image_box_info.dom_height, image_fragment_info.dom_height,
Au(0)); Au(0));
let height = match (style_width, image_box_info.dom_width, height) { let height = match (style_width, image_fragment_info.dom_width, height) {
(LPA_Auto, None, Auto) => { (LPA_Auto, None, Auto) => {
image_box_info.image_height() image_fragment_info.image_height()
}, },
(_,_,Auto) => { (_,_,Auto) => {
let scale = image_box_info.image_width().to_f32().unwrap() let scale = image_fragment_info.image_width().to_f32().unwrap()
/ width.to_f32().unwrap(); / width.to_f32().unwrap();
Au::new((image_box_info.image_height().to_f32().unwrap() / scale) as i32) Au::new((image_fragment_info.image_height().to_f32().unwrap() / scale) as i32)
}, },
(_,_,Specified(h)) => { (_,_,Specified(h)) => {
h h
} }
}; };
image_box_info.computed_height = Some(height); image_fragment_info.computed_height = Some(height);
self.border_box.size.height = height + noncontent_height self.border_box.size.height = height + noncontent_height
} }
ScannedTextFragment(_) => { ScannedTextFragment(_) => {
// Scanned text boxes' content heights are calculated by the text run scanner // Scanned text fragments' content heights are calculated by the text run scanner
// during flow construction. // during flow construction.
self.border_box.size.height = self.border_box.size.height + noncontent_height self.border_box.size.height = self.border_box.size.height + noncontent_height
} }
@ -1362,19 +1360,19 @@ impl Fragment {
/// used in an inline formatting context. See CSS 2.1 § 10.8.1. /// used in an inline formatting context. See CSS 2.1 § 10.8.1.
pub fn inline_metrics(&self) -> InlineMetrics { pub fn inline_metrics(&self) -> InlineMetrics {
match self.specific { match self.specific {
ImageFragment(ref image_box_info) => { ImageFragment(ref image_fragment_info) => {
let computed_height = image_box_info.computed_height(); let computed_height = image_fragment_info.computed_height();
InlineMetrics { InlineMetrics {
height_above_baseline: computed_height + self.border_padding.vertical(), height_above_baseline: computed_height + self.border_padding.vertical(),
depth_below_baseline: Au(0), depth_below_baseline: Au(0),
ascent: computed_height + self.border_padding.bottom, ascent: computed_height + self.border_padding.bottom,
} }
} }
ScannedTextFragment(ref text_box) => { ScannedTextFragment(ref text_fragment) => {
// See CSS 2.1 § 10.8.1. // See CSS 2.1 § 10.8.1.
let font_size = self.style().get_font().font_size; let font_size = self.style().get_font().font_size;
let line_height = self.calculate_line_height(font_size); let line_height = self.calculate_line_height(font_size);
InlineMetrics::from_font_metrics(&text_box.run.font_metrics, line_height) InlineMetrics::from_font_metrics(&text_fragment.run.font_metrics, line_height)
} }
_ => { _ => {
InlineMetrics { InlineMetrics {
@ -1386,8 +1384,8 @@ impl Fragment {
} }
} }
/// Returns true if this box can merge with another adjacent box or false otherwise. /// Returns true if this fragment can merge with another adjacent fragment or false otherwise.
pub fn can_merge_with_box(&self, other: &Fragment) -> bool { pub fn can_merge_with_fragment(&self, other: &Fragment) -> bool {
match (&self.specific, &other.specific) { match (&self.specific, &other.specific) {
(&UnscannedTextFragment(_), &UnscannedTextFragment(_)) => { (&UnscannedTextFragment(_), &UnscannedTextFragment(_)) => {
self.font_style() == other.font_style() && self.font_style() == other.font_style() &&
@ -1419,11 +1417,11 @@ impl Fragment {
} }
} }
/// Sends the size and position of this iframe box to the constellation. This is out of line to /// Sends the size and position of this iframe fragment to the constellation. This is out of
/// guide inlining. /// line to guide inlining.
#[inline(never)] #[inline(never)]
fn finalize_position_and_size_of_iframe(&self, fn finalize_position_and_size_of_iframe(&self,
iframe_box: &IframeFragmentInfo, iframe_fragment: &IframeFragmentInfo,
offset: Point2D<Au>, offset: Point2D<Au>,
layout_context: &LayoutContext) { layout_context: &LayoutContext) {
let left = offset.x + self.margin.left + self.border_padding.left; let left = offset.x + self.margin.left + self.border_padding.left;
@ -1435,16 +1433,16 @@ impl Fragment {
let rect = Rect(origin, size); let rect = Rect(origin, size);
debug!("finalizing position and size of iframe for {:?},{:?}", debug!("finalizing position and size of iframe for {:?},{:?}",
iframe_box.pipeline_id, iframe_fragment.pipeline_id,
iframe_box.subpage_id); iframe_fragment.subpage_id);
let msg = FrameRectMsg(iframe_box.pipeline_id, iframe_box.subpage_id, rect); let msg = FrameRectMsg(iframe_fragment.pipeline_id, iframe_fragment.subpage_id, rect);
let ConstellationChan(ref chan) = layout_context.constellation_chan; let ConstellationChan(ref chan) = layout_context.constellation_chan;
chan.send(msg) chan.send(msg)
} }
} }
impl fmt::Show for Fragment { impl fmt::Show for Fragment {
/// Outputs a debugging string describing this box. /// Outputs a debugging string describing this fragment.
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f.buf, "({} ", try!(write!(f.buf, "({} ",
match self.specific { match self.specific {

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
@ -95,7 +95,7 @@ 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.
InlineFragmentsConstructionItem(InlineFragmentsConstructionResult), InlineFragmentsConstructionItem(InlineFragmentsConstructionResult),
/// Potentially ignorable whitespace. /// Potentially ignorable whitespace.
WhitespaceConstructionItem(OpaqueNode, Arc<ComputedValues>), WhitespaceConstructionItem(OpaqueNode, Arc<ComputedValues>),
@ -117,13 +117,13 @@ impl ConstructionItem {
} }
} }
/// 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 InlineFragmentsConstructionResult { 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: InlineFragments, 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,
@ -142,7 +142,7 @@ pub struct InlineFragmentsConstructionResult {
/// ///
/// InlineFragmentsConstructionItem(Some(~[ /// InlineFragmentsConstructionItem(Some(~[
/// InlineBlockSplit { /// InlineBlockSplit {
/// predecessor_boxes: ~[ /// predecessor_fragments: ~[
/// A /// A
/// ], /// ],
/// block: ~BlockFlow { /// block: ~BlockFlow {
@ -152,7 +152,7 @@ pub struct InlineFragmentsConstructionResult {
/// C /// C
/// ]) /// ])
pub struct InlineBlockSplit { pub struct InlineBlockSplit {
/// The inline boxes that precede the flow. /// The inline fragments that precede the flow.
pub predecessors: InlineFragments, pub predecessors: InlineFragments,
/// The flow that caused this {ib} split. /// The flow that caused this {ib} split.
@ -165,12 +165,12 @@ 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 InlineFragmentsAccumulator { struct InlineFragmentsAccumulator {
/// The list of boxes. /// The list of fragments.
boxes: InlineFragments, 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,
} }
@ -178,31 +178,31 @@ struct InlineFragmentsAccumulator {
impl InlineFragmentsAccumulator { impl InlineFragmentsAccumulator {
fn new() -> InlineFragmentsAccumulator { fn new() -> InlineFragmentsAccumulator {
InlineFragmentsAccumulator { InlineFragmentsAccumulator {
boxes: InlineFragments::new(), fragments: InlineFragments::new(),
has_enclosing_range: false, has_enclosing_range: false,
} }
} }
fn from_inline_node(node: &ThreadSafeLayoutNode) -> InlineFragmentsAccumulator { fn from_inline_node(node: &ThreadSafeLayoutNode) -> InlineFragmentsAccumulator {
let mut boxes = InlineFragments::new(); let mut fragments = InlineFragments::new();
boxes.map.push(node.style().clone(), Range::empty()); fragments.map.push(node.style().clone(), Range::empty());
InlineFragmentsAccumulator { InlineFragmentsAccumulator {
boxes: boxes, fragments: fragments,
has_enclosing_range: true, has_enclosing_range: true,
} }
} }
fn finish(self) -> InlineFragments { fn finish(self) -> InlineFragments {
let InlineFragmentsAccumulator { 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
} }
} }
@ -255,12 +255,12 @@ impl<'a> FlowConstructor<'a> {
} }
/// Builds the `ImageFragmentInfo` 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>)
-> SpecificFragmentInfo { -> SpecificFragmentInfo {
match url { match url {
None => GenericFragment, 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.
ImageFragment(ImageFragmentInfo::new(node, url, self.layout_context.image_cache.clone())) ImageFragment(ImageFragmentInfo::new(node, url, self.layout_context.image_cache.clone()))
} }
@ -268,18 +268,18 @@ impl<'a> FlowConstructor<'a> {
} }
/// Builds specific `Fragment` 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)
-> SpecificFragmentInfo { -> 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)) => {
IframeFragment(IframeFragmentInfo::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)) => TableWrapperFragment, Some(ElementNodeTypeId(HTMLTableElementTypeId)) => TableWrapperFragment,
Some(ElementNodeTypeId(HTMLTableColElementTypeId)) => { Some(ElementNodeTypeId(HTMLTableColElementTypeId)) => {
@ -294,40 +294,40 @@ impl<'a> FlowConstructor<'a> {
} }
} }
/// 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: InlineFragmentsAccumulator, fragment_accumulator: InlineFragmentsAccumulator,
flow: &mut Box<Flow:Share>, flow: &mut Box<Flow:Share>,
flow_list: &mut Vec<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 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);
@ -343,13 +343,13 @@ 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 Box<Flow:Share>, flow: &mut Box<Flow:Share>,
consecutive_siblings: consecutive_siblings:
&mut Vec<Box<Flow:Share>>, &mut Vec<Box<Flow:Share>>,
node: &ThreadSafeLayoutNode, node: &ThreadSafeLayoutNode,
kid: ThreadSafeLayoutNode, kid: ThreadSafeLayoutNode,
inline_box_accumulator: inline_fragment_accumulator:
&mut InlineFragmentsAccumulator, &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) => {
@ -364,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, InlineFragmentsAccumulator::new()), mem::replace(inline_fragment_accumulator, InlineFragmentsAccumulator::new()),
flow, flow,
consecutive_siblings, consecutive_siblings,
whitespace_stripping, whitespace_stripping,
@ -394,33 +394,33 @@ impl<'a> FlowConstructor<'a> {
ConstructionItemConstructionResult(InlineFragmentsConstructionItem( ConstructionItemConstructionResult(InlineFragmentsConstructionItem(
InlineFragmentsConstructionResult { 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,
InlineFragmentsAccumulator::new()), InlineFragmentsAccumulator::new()),
flow, flow,
consecutive_siblings, consecutive_siblings,
@ -436,8 +436,8 @@ 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(..)) => {
@ -461,10 +461,10 @@ impl<'a> FlowConstructor<'a> {
mut flow: 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 = InlineFragmentsAccumulator::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();
@ -477,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,
@ -528,16 +528,16 @@ impl<'a> FlowConstructor<'a> {
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 `InlineFragmentsConstructionResult`, if any. There will be no /// Returns the `InlineFragmentsConstructionResult`, if any. There will be no
/// `InlineFragmentsConstructionResult` 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 = InlineFragmentsAccumulator::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);
@ -546,10 +546,10 @@ 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,
InlineFragmentsAccumulator::from_inline_node(node)).finish(), InlineFragmentsAccumulator::from_inline_node(node)).finish(),
flow: flow, flow: flow,
}; };
@ -559,7 +559,7 @@ impl<'a> FlowConstructor<'a> {
ConstructionItemConstructionResult(InlineFragmentsConstructionItem( ConstructionItemConstructionResult(InlineFragmentsConstructionItem(
InlineFragmentsConstructionResult { InlineFragmentsConstructionResult {
splits: splits, splits: splits,
boxes: successors, fragments: successors,
abs_descendants: kid_abs_descendants, abs_descendants: kid_abs_descendants,
})) => { })) => {
@ -569,11 +569,11 @@ 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,
InlineFragmentsAccumulator::from_inline_node(node)) InlineFragmentsAccumulator::from_inline_node(node))
.finish(), .finish(),
flow: kid_flow, flow: kid_flow,
@ -581,19 +581,19 @@ impl<'a> FlowConstructor<'a> {
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 = UnscannedTextFragment(UnscannedTextFragmentInfo::from_text(" ".to_owned())); let fragment_info = UnscannedTextFragment(UnscannedTextFragmentInfo::from_text(" ".to_owned()));
let fragment = Fragment::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(TableColumnFragmentConstructionItem(_)) => { ConstructionItemConstructionResult(TableColumnFragmentConstructionItem(_)) => {
// TODO: Implement anonymous table objects for missing parents // TODO: Implement anonymous table objects for missing parents
@ -603,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 = InlineFragmentsConstructionItem(InlineFragmentsConstructionResult { 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,8 +617,8 @@ impl<'a> FlowConstructor<'a> {
} }
/// Creates an `InlineFragmentsConstructionResult` 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 `Fragment`. /// 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)
@ -634,27 +634,28 @@ impl<'a> FlowConstructor<'a> {
node.style().clone())) node.style().clone()))
} }
let mut boxes = InlineFragments::new(); let mut fragments = InlineFragments::new();
boxes.push(Fragment::new(self, node), node.style().clone()); fragments.push(Fragment::new(self, node), node.style().clone());
let construction_item = InlineFragmentsConstructionItem(InlineFragmentsConstructionResult { 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
/// `InlineFragmentsConstructionResult`. /// `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)
} }
} }
@ -704,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_ = Fragment::new_from_specific_info(node, TableWrapperFragment); let fragment = Fragment::new_from_specific_info(node, TableWrapperFragment);
let mut wrapper_flow = box TableWrapperFlow::from_node_and_box(node, box_) as Box<Flow:Share>; let mut wrapper_flow = box TableWrapperFlow::from_node_and_fragment(node, fragment) as Box<Flow:Share>;
let table_box_ = Fragment::new_from_specific_info(node, TableFragment); let table_fragment = Fragment::new_from_specific_info(node, TableFragment);
let table_flow = box TableFlow::from_node_and_box(node, table_box_) as 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
@ -761,30 +762,30 @@ impl<'a> FlowConstructor<'a> {
/// 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_ = Fragment::new_from_specific_info(node, TableRowFragment); let fragment = Fragment::new_from_specific_info(node, TableRowFragment);
let flow = box TableRowGroupFlow::from_node_and_box(node, box_) as 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_ = Fragment::new_from_specific_info(node, TableRowFragment); let fragment = Fragment::new_from_specific_info(node, TableRowFragment);
let flow = box TableRowFlow::from_node_and_box(node, box_) as 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_ = Fragment::new_from_specific_info(node, TableCellFragment); let fragment = Fragment::new_from_specific_info(node, TableCellFragment);
let flow = box TableCellFlow::from_node_and_box(node, box_) as 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)
} }
@ -799,25 +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_ = Fragment::new_from_specific_info(node, let fragment = Fragment::new_from_specific_info(node,
TableColumnFragment(TableColumnFragmentInfo::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(TableColumnFragmentConstructionItem(box_)) => { ConstructionItemConstructionResult(TableColumnFragmentConstructionItem(fragment)) => {
col_boxes.push(box_); col_fragments.push(fragment);
} }
_ => {} _ => {}
} }
} }
if col_boxes.is_empty() { if col_fragments.is_empty() {
debug!("add TableColumnFragment for empty colgroup"); debug!("add TableColumnFragment for empty colgroup");
let specific = TableColumnFragment(TableColumnFragmentInfo::new(node)); let specific = TableColumnFragment(TableColumnFragmentInfo::new(node));
col_boxes.push(Fragment::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 Box<Flow:Share>; let mut flow = box TableColGroupFlow::from_node_and_fragments(node, fragment, col_fragments) as Box<Flow:Share>;
flow.finish(self.layout_context); flow.finish(self.layout_context);
FlowConstructionResult(flow, Descendants::new()) FlowConstructionResult(flow, Descendants::new())
@ -886,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)
} }
@ -906,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)
} }
@ -1084,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 InlineFragments) { fn strip_ignorable_whitespace_from_start(fragments: &mut InlineFragments) {
if boxes.len() == 0 { if fragments.len() == 0 {
return return
} }
let InlineFragments { let InlineFragments {
boxes: old_boxes, fragments: old_fragments,
map: mut map map: mut map
} = mem::replace(boxes, InlineFragments::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 = InlineFragments { *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 InlineFragments) { fn strip_ignorable_whitespace_from_end(fragments: &mut InlineFragments) {
if boxes.len() == 0 { if fragments.len() == 0 {
return return
} }
let InlineFragments { let InlineFragments {
boxes: old_boxes, fragments: old_fragments,
map: mut map map: mut map
} = mem::replace(boxes, InlineFragments::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 = InlineFragments { *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

@ -8,8 +8,8 @@
/// 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 fragment 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,7 +21,7 @@
/// 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.
@ -844,12 +844,12 @@ impl<'a> ImmutableFlowUtils for &'a Flow {
fn generate_missing_child_flow(self, node: &ThreadSafeLayoutNode) -> 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_ = Fragment::new_anonymous_table_box(node, TableRowFragment); let fragment = Fragment::new_anonymous_table_fragment(node, TableRowFragment);
box TableRowFlow::from_node_and_box(node, box_) as Box<Flow:Share> box TableRowFlow::from_node_and_fragment(node, fragment) as Box<Flow:Share>
}, },
TableRowFlowClass => { TableRowFlowClass => {
let box_ = Fragment::new_anonymous_table_box(node, TableCellFragment); let fragment = Fragment::new_anonymous_table_fragment(node, TableCellFragment);
box TableCellFlow::from_node_and_box(node, box_) as 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")
@ -869,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 {
@ -1065,7 +1065,7 @@ impl MutableOwnedFlowUtils for 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.
/// ///

View file

@ -33,39 +33,39 @@ use style::computed_values::{text_align, vertical_align, white_space};
use style::ComputedValues; use style::ComputedValues;
use sync::Arc; use sync::Arc;
/// Lineboxes are represented as offsets into the child list, rather than /// `LineFragment`s are represented as offsets into the child list, rather than
/// as an object that "owns" boxes. Choosing a different set of line /// as an object that "owns" fragments. Choosing a different set of line
/// breaks requires a new list of offsets, and possibly some splitting and /// breaks requires a new list of offsets, and possibly some splitting and
/// merging of TextFragments. /// merging of TextFragments.
/// ///
/// A similar list will keep track of the mapping between CSS boxes and /// A similar list will keep track of the mapping between CSS fragments and
/// the corresponding boxes in the inline flow. /// the corresponding fragments in the inline flow.
/// ///
/// After line breaks are determined, render boxes in the inline flow may /// After line breaks are determined, render fragments in the inline flow may
/// overlap visually. For example, in the case of nested inline CSS boxes, /// overlap visually. For example, in the case of nested inline CSS fragments,
/// outer inlines must be at least as large as the inner inlines, for /// outer inlines must be at least as large as the inner inlines, for
/// purposes of drawing noninherited things like backgrounds, borders, /// purposes of drawing noninherited things like backgrounds, borders,
/// outlines. /// outlines.
/// ///
/// N.B. roc has an alternative design where the list instead consists of /// N.B. roc has an alternative design where the list instead consists of
/// things like "start outer box, text, start inner box, text, end inner /// things like "start outer fragment, text, start inner fragment, text, end inner
/// box, text, end outer box, text". This seems a little complicated to /// fragment, text, end outer fragment, text". This seems a little complicated to
/// serve as the starting point, but the current design doesn't make it /// serve as the starting point, but the current design doesn't make it
/// hard to try out that alternative. /// hard to try out that alternative.
/// ///
/// Line boxes also contain some metadata used during line breaking. The /// Line fragments also contain some metadata used during line breaking. The
/// green zone is the area that the line can expand to before it collides /// green zone is the area that the line can expand to before it collides
/// with a float or a horizontal wall of the containing block. The top /// with a float or a horizontal wall of the containing block. The top
/// left corner of the green zone is the same as that of the line, but /// left corner of the green zone is the same as that of the line, but
/// the green zone can be taller and wider than the line itself. /// the green zone can be taller and wider than the line itself.
pub struct LineBox { pub struct LineFragment {
pub range: Range<LineIndices>, pub range: Range<LineIndices>,
pub bounds: Rect<Au>, pub bounds: Rect<Au>,
pub green_zone: Size2D<Au> pub green_zone: Size2D<Au>
} }
int_range_index! { int_range_index! {
#[doc = "The index of a box fragment in a flattened vector of DOM elements."] #[doc = "The index of a fragment in a flattened vector of DOM elements."]
struct FragmentIndex(int) struct FragmentIndex(int)
} }
@ -97,8 +97,7 @@ int_range_index! {
/// ~~~ /// ~~~
#[deriving(Clone, Eq, Ord, TotalEq, TotalOrd, Zero)] #[deriving(Clone, Eq, Ord, TotalEq, TotalOrd, Zero)]
pub struct LineIndices { pub struct LineIndices {
/// The index of a box fragment into the flattened vector of DOM /// The index of a fragment into the flattened vector of DOM elements.
/// elements.
/// ///
/// For example, given the HTML below: /// For example, given the HTML below:
/// ///
@ -199,22 +198,22 @@ pub fn each_char_index(range: &Range<LineIndices>) -> EachIndex<int, CharIndex>
range::each_index(range.begin().char_index, range.end().char_index) range::each_index(range.begin().char_index, range.end().char_index)
} }
struct LineboxScanner { struct LineFragmentScanner {
pub floats: Floats, pub floats: Floats,
pub new_boxes: Vec<Fragment>, pub new_fragments: Vec<Fragment>,
pub work_list: RingBuf<Fragment>, pub work_list: RingBuf<Fragment>,
pub pending_line: LineBox, pub pending_line: LineFragment,
pub lines: Vec<LineBox>, pub lines: Vec<LineFragment>,
pub cur_y: Au, pub cur_y: Au,
} }
impl LineboxScanner { impl LineFragmentScanner {
pub fn new(float_ctx: Floats) -> LineboxScanner { pub fn new(float_ctx: Floats) -> LineFragmentScanner {
LineboxScanner { LineFragmentScanner {
floats: float_ctx, floats: float_ctx,
new_boxes: Vec::new(), new_fragments: Vec::new(),
work_list: RingBuf::new(), work_list: RingBuf::new(),
pending_line: LineBox { pending_line: LineFragment {
range: Range::empty(), range: Range::empty(),
bounds: Rect(Point2D(Au::new(0), Au::new(0)), Size2D(Au::new(0), Au::new(0))), bounds: Rect(Point2D(Au::new(0), Au::new(0)), Size2D(Au::new(0), Au::new(0))),
green_zone: Size2D(Au::new(0), Au::new(0)) green_zone: Size2D(Au::new(0), Au::new(0))
@ -229,14 +228,14 @@ impl LineboxScanner {
} }
fn reset_scanner(&mut self) { fn reset_scanner(&mut self) {
debug!("Resetting line box scanner's state for flow."); debug!("Resetting LineFragmentScanner's state for flow.");
self.lines = Vec::new(); self.lines = Vec::new();
self.new_boxes = Vec::new(); self.new_fragments = Vec::new();
self.cur_y = Au(0); self.cur_y = Au(0);
self.reset_linebox(); self.reset_line_fragment();
} }
fn reset_linebox(&mut self) { fn reset_line_fragment(&mut self) {
self.pending_line.range.reset(num::zero(), num::zero()); self.pending_line.range.reset(num::zero(), num::zero());
self.pending_line.bounds = Rect(Point2D(Au::new(0), self.cur_y), Size2D(Au::new(0), Au::new(0))); self.pending_line.bounds = Rect(Point2D(Au::new(0), self.cur_y), Size2D(Au::new(0), Au::new(0)));
self.pending_line.green_zone = Size2D(Au::new(0), Au::new(0)) self.pending_line.green_zone = Size2D(Au::new(0), Au::new(0))
@ -247,52 +246,52 @@ impl LineboxScanner {
// Swap out temporarily. // Swap out temporarily.
let InlineFragments { let InlineFragments {
boxes: old_boxes, fragments: old_fragments,
map: mut map map: mut map
} = mem::replace(&mut flow.boxes, InlineFragments::new()); } = mem::replace(&mut flow.fragments, InlineFragments::new());
let mut old_box_iter = old_boxes.iter(); let mut old_fragment_iter = old_fragments.iter();
loop { loop {
// acquire the next box to lay out from work list or box list // acquire the next fragment to lay out from work list or fragment list
let cur_box = if self.work_list.is_empty() { let cur_fragment = if self.work_list.is_empty() {
match old_box_iter.next() { match old_fragment_iter.next() {
None => break, None => break,
Some(fragment) => { Some(fragment) => {
debug!("LineboxScanner: Working with fragment from flow: b{}", debug!("LineFragmentScanner: Working with fragment from flow: b{}",
fragment.debug_id()); fragment.debug_id());
(*fragment).clone() (*fragment).clone()
} }
} }
} else { } else {
let fragment = self.work_list.pop_front().unwrap(); let fragment = self.work_list.pop_front().unwrap();
debug!("LineboxScanner: Working with box from work list: b{}", debug!("LineFragmentScanner: Working with fragment from work list: b{}",
fragment.debug_id()); fragment.debug_id());
fragment fragment
}; };
let box_was_appended = match cur_box.white_space() { let fragment_was_appended = match cur_fragment.white_space() {
white_space::normal => self.try_append_to_line(cur_box, flow), white_space::normal => self.try_append_to_line(cur_fragment, flow),
white_space::pre => self.try_append_to_line_by_new_line(cur_box), white_space::pre => self.try_append_to_line_by_new_line(cur_fragment),
}; };
if !box_was_appended { if !fragment_was_appended {
debug!("LineboxScanner: Fragment wasn't appended, because line {:u} was full.", debug!("LineFragmentScanner: Fragment wasn't appended, because line {:u} was full.",
self.lines.len()); self.lines.len());
self.flush_current_line(); self.flush_current_line();
} else { } else {
debug!("LineboxScanner: appended a box to line {:u}", self.lines.len()); debug!("LineFragmentScanner: appended a fragment to line {:u}", self.lines.len());
} }
} }
if self.pending_line.range.length() > num::zero() { if self.pending_line.range.length() > num::zero() {
debug!("LineboxScanner: Partially full linebox {:u} left at end of scanning.", debug!("LineFragmentScanner: Partially full line_fragment {:u} left at end of scanning.",
self.lines.len()); self.lines.len());
self.flush_current_line(); self.flush_current_line();
} }
map.fixup(old_boxes.as_slice(), self.new_boxes.as_slice()); map.fixup(old_fragments.as_slice(), self.new_fragments.as_slice());
flow.boxes = InlineFragments { flow.fragments = InlineFragments {
boxes: mem::replace(&mut self.new_boxes, Vec::new()), fragments: mem::replace(&mut self.new_fragments, Vec::new()),
map: map, map: map,
}; };
@ -300,49 +299,49 @@ impl LineboxScanner {
} }
fn flush_current_line(&mut self) { fn flush_current_line(&mut self) {
debug!("LineboxScanner: Flushing line {:u}: {:?}", debug!("LineFragmentScanner: Flushing line {:u}: {:?}",
self.lines.len(), self.pending_line); self.lines.len(), self.pending_line);
// clear line and add line mapping // clear line and add line mapping
debug!("LineboxScanner: Saving information for flushed line {:u}.", self.lines.len()); debug!("LineFragmentScanner: Saving information for flushed line {:u}.", self.lines.len());
self.lines.push(self.pending_line); self.lines.push(self.pending_line);
self.cur_y = self.pending_line.bounds.origin.y + self.pending_line.bounds.size.height; self.cur_y = self.pending_line.bounds.origin.y + self.pending_line.bounds.size.height;
self.reset_linebox(); self.reset_line_fragment();
} }
// FIXME(eatkinson): this assumes that the tallest box in the line determines the line height // FIXME(eatkinson): this assumes that the tallest fragment in the line determines the line height
// This might not be the case with some weird text fonts. // This might not be the case with some weird text fonts.
fn new_height_for_line(&self, new_box: &Fragment) -> Au { fn new_height_for_line(&self, new_fragment: &Fragment) -> Au {
let box_height = new_box.content_height(); let fragment_height = new_fragment.content_height();
if box_height > self.pending_line.bounds.size.height { if fragment_height > self.pending_line.bounds.size.height {
box_height fragment_height
} else { } else {
self.pending_line.bounds.size.height self.pending_line.bounds.size.height
} }
} }
/// Computes the position of a line that has only the provided box. Returns the bounding rect /// Computes the position of a line that has only the provided fragment. Returns the bounding
/// of the line's green zone (whose origin coincides with the line's origin) and the actual /// rect of the line's green zone (whose origin coincides with the line's origin) and the actual
/// width of the first box after splitting. /// width of the first fragment after splitting.
fn initial_line_placement(&self, first_box: &Fragment, ceiling: Au, flow: &mut InlineFlow) fn initial_line_placement(&self, first_fragment: &Fragment, ceiling: Au, flow: &mut InlineFlow)
-> (Rect<Au>, Au) { -> (Rect<Au>, Au) {
debug!("LineboxScanner: Trying to place first box of line {}", self.lines.len()); debug!("LineFragmentScanner: Trying to place first fragment of line {}", self.lines.len());
let first_box_size = first_box.border_box.size; let first_fragment_size = first_fragment.border_box.size;
let splittable = first_box.can_split(); let splittable = first_fragment.can_split();
debug!("LineboxScanner: box size: {}, splittable: {}", first_box_size, splittable); debug!("LineFragmentScanner: fragment size: {}, splittable: {}", first_fragment_size, splittable);
// Initally, pretend a splittable box has 0 width. // Initally, pretend a splittable fragment has 0 width.
// We will move it later if it has nonzero width // We will move it later if it has nonzero width
// and that causes problems. // and that causes problems.
let placement_width = if splittable { let placement_width = if splittable {
Au::new(0) Au::new(0)
} else { } else {
first_box_size.width first_fragment_size.width
}; };
let info = PlacementInfo { let info = PlacementInfo {
size: Size2D(placement_width, first_box_size.height), size: Size2D(placement_width, first_fragment_size.height),
ceiling: ceiling, ceiling: ceiling,
max_width: flow.base.position.size.width, max_width: flow.base.position.size.width,
kind: FloatLeft, kind: FloatLeft,
@ -350,33 +349,33 @@ impl LineboxScanner {
let line_bounds = self.floats.place_between_floats(&info); let line_bounds = self.floats.place_between_floats(&info);
debug!("LineboxScanner: found position for line: {} using placement_info: {:?}", debug!("LineFragmentScanner: found position for line: {} using placement_info: {:?}",
line_bounds, line_bounds,
info); info);
// Simple case: if the box fits, then we can stop here // Simple case: if the fragment fits, then we can stop here
if line_bounds.size.width > first_box_size.width { if line_bounds.size.width > first_fragment_size.width {
debug!("LineboxScanner: case=box fits"); debug!("LineFragmentScanner: case=fragment fits");
return (line_bounds, first_box_size.width); return (line_bounds, first_fragment_size.width);
} }
// If not, but we can't split the box, then we'll place // If not, but we can't split the fragment, then we'll place
// the line here and it will overflow. // the line here and it will overflow.
if !splittable { if !splittable {
debug!("LineboxScanner: case=line doesn't fit, but is unsplittable"); debug!("LineFragmentScanner: case=line doesn't fit, but is unsplittable");
return (line_bounds, first_box_size.width); return (line_bounds, first_fragment_size.width);
} }
debug!("LineboxScanner: used to call split_to_width here"); debug!("LineFragmentScanner: used to call split_to_width here");
return (line_bounds, first_box_size.width); return (line_bounds, first_fragment_size.width);
} }
/// Performs float collision avoidance. This is called when adding a box is going to increase /// Performs float collision avoidance. This is called when adding a fragment is going to increase
/// the height, and because of that we will collide with some floats. /// the height, and because of that we will collide with some floats.
/// ///
/// We have two options here: /// We have two options here:
/// 1) Move the entire line so that it doesn't collide any more. /// 1) Move the entire line so that it doesn't collide any more.
/// 2) Break the line and put the new box on the next line. /// 2) Break the line and put the new fragment on the next line.
/// ///
/// The problem with option 1 is that we might move the line and then wind up breaking anyway, /// The problem with option 1 is that we might move the line and then wind up breaking anyway,
/// which violates the standard. /// which violates the standard.
@ -386,93 +385,93 @@ impl LineboxScanner {
/// ///
/// Returns false if and only if we should break the line. /// Returns false if and only if we should break the line.
fn avoid_floats(&mut self, fn avoid_floats(&mut self,
in_box: Fragment, in_fragment: Fragment,
flow: &mut InlineFlow, flow: &mut InlineFlow,
new_height: Au, new_height: Au,
line_is_empty: bool) line_is_empty: bool)
-> bool { -> bool {
debug!("LineboxScanner: entering float collision avoider!"); debug!("LineFragmentScanner: entering float collision avoider!");
// First predict where the next line is going to be. // First predict where the next line is going to be.
let this_line_y = self.pending_line.bounds.origin.y; let this_line_y = self.pending_line.bounds.origin.y;
let (next_line, first_box_width) = self.initial_line_placement(&in_box, this_line_y, flow); let (next_line, first_fragment_width) = self.initial_line_placement(&in_fragment, this_line_y, flow);
let next_green_zone = next_line.size; let next_green_zone = next_line.size;
let new_width = self.pending_line.bounds.size.width + first_box_width; let new_width = self.pending_line.bounds.size.width + first_fragment_width;
// Now, see if everything can fit at the new location. // Now, see if everything can fit at the new location.
if next_green_zone.width >= new_width && next_green_zone.height >= new_height { if next_green_zone.width >= new_width && next_green_zone.height >= new_height {
debug!("LineboxScanner: case=adding box collides vertically with floats: moving line"); debug!("LineFragmentScanner: case=adding fragment collides vertically with floats: moving line");
self.pending_line.bounds.origin = next_line.origin; self.pending_line.bounds.origin = next_line.origin;
self.pending_line.green_zone = next_green_zone; self.pending_line.green_zone = next_green_zone;
assert!(!line_is_empty, "Non-terminating line breaking"); assert!(!line_is_empty, "Non-terminating line breaking");
self.work_list.push_front(in_box); self.work_list.push_front(in_fragment);
return true return true
} }
debug!("LineboxScanner: case=adding box collides vertically with floats: breaking line"); debug!("LineFragmentScanner: case=adding fragment collides vertically with floats: breaking line");
self.work_list.push_front(in_box); self.work_list.push_front(in_fragment);
false false
} }
fn try_append_to_line_by_new_line(&mut self, in_box: Fragment) -> bool { fn try_append_to_line_by_new_line(&mut self, in_fragment: Fragment) -> bool {
if in_box.new_line_pos.len() == 0 { if in_fragment.new_line_pos.len() == 0 {
debug!("LineboxScanner: Did not find a new-line character, so pushing the box to \ debug!("LineFragmentScanner: Did not find a new-line character, so pushing the fragment to \
the line without splitting."); the line without splitting.");
self.push_box_to_line(in_box); self.push_fragment_to_line(in_fragment);
true true
} else { } else {
debug!("LineboxScanner: Found a new-line character, so splitting theline."); debug!("LineFragmentScanner: Found a new-line character, so splitting theline.");
match in_box.find_split_info_by_new_line() { match in_fragment.find_split_info_by_new_line() {
Some((left, right, run)) => { Some((left, right, run)) => {
// TODO(bjz): Remove box splitting // TODO(bjz): Remove fragment splitting
let split_box = |split: SplitInfo| { let split_fragment = |split: SplitInfo| {
let info = ScannedTextFragmentInfo::new(run.clone(), split.range); let info = ScannedTextFragmentInfo::new(run.clone(), split.range);
let specific = ScannedTextFragment(info); let specific = ScannedTextFragment(info);
let size = Size2D(split.width, in_box.border_box.size.height); let size = Size2D(split.width, in_fragment.border_box.size.height);
in_box.transform(size, specific) in_fragment.transform(size, specific)
}; };
debug!("LineboxScanner: Pushing the box to the left of the new-line character \ debug!("LineFragmentScanner: Pushing the fragment to the left of the new-line character \
to the line."); to the line.");
let mut left = split_box(left); let mut left = split_fragment(left);
left.new_line_pos = vec!(); left.new_line_pos = vec!();
self.push_box_to_line(left); self.push_fragment_to_line(left);
for right in right.move_iter() { for right in right.move_iter() {
debug!("LineboxScanner: Deferring the box to the right of the new-line \ debug!("LineFragmentScanner: Deferring the fragment to the right of the new-line \
character to the line."); character to the line.");
let mut right = split_box(right); let mut right = split_fragment(right);
right.new_line_pos = in_box.new_line_pos.clone(); right.new_line_pos = in_fragment.new_line_pos.clone();
self.work_list.push_front(right); self.work_list.push_front(right);
} }
}, },
None => { None => {
error!("LineboxScanner: This split case makes no sense!") error!("LineFragmentScanner: This split case makes no sense!")
}, },
} }
false false
} }
} }
/// Tries to append the given box to the line, splitting it if necessary. Returns false only if /// Tries to append the given fragment to the line, splitting it if necessary. Returns false only if
/// we should break the line. /// we should break the line.
fn try_append_to_line(&mut self, in_box: Fragment, flow: &mut InlineFlow) -> bool { fn try_append_to_line(&mut self, in_fragment: Fragment, flow: &mut InlineFlow) -> bool {
let line_is_empty = self.pending_line.range.length() == num::zero(); let line_is_empty = self.pending_line.range.length() == num::zero();
if line_is_empty { if line_is_empty {
let (line_bounds, _) = self.initial_line_placement(&in_box, self.cur_y, flow); let (line_bounds, _) = self.initial_line_placement(&in_fragment, self.cur_y, flow);
self.pending_line.bounds.origin = line_bounds.origin; self.pending_line.bounds.origin = line_bounds.origin;
self.pending_line.green_zone = line_bounds.size; self.pending_line.green_zone = line_bounds.size;
} }
debug!("LineboxScanner: Trying to append box to line {:u} (box size: {}, green zone: \ debug!("LineFragmentScanner: Trying to append fragment to line {:u} (fragment size: {}, green zone: \
{}): {}", {}): {}",
self.lines.len(), self.lines.len(),
in_box.border_box.size, in_fragment.border_box.size,
self.pending_line.green_zone, self.pending_line.green_zone,
in_box); in_fragment);
let green_zone = self.pending_line.green_zone; let green_zone = self.pending_line.green_zone;
@ -480,87 +479,87 @@ impl LineboxScanner {
// `green_zone.height < self.pending_line.bounds.size.height`, then we committed a line // `green_zone.height < self.pending_line.bounds.size.height`, then we committed a line
// that overlaps with floats. // that overlaps with floats.
let new_height = self.new_height_for_line(&in_box); let new_height = self.new_height_for_line(&in_fragment);
if new_height > green_zone.height { if new_height > green_zone.height {
// Uh-oh. Float collision imminent. Enter the float collision avoider // Uh-oh. Float collision imminent. Enter the float collision avoider
return self.avoid_floats(in_box, flow, new_height, line_is_empty) return self.avoid_floats(in_fragment, flow, new_height, line_is_empty)
} }
// If we're not going to overflow the green zone vertically, we might still do so // If we're not going to overflow the green zone vertically, we might still do so
// horizontally. We'll try to place the whole box on this line and break somewhere if it // horizontally. We'll try to place the whole fragment on this line and break somewhere if it
// doesn't fit. // doesn't fit.
let new_width = self.pending_line.bounds.size.width + in_box.border_box.size.width; let new_width = self.pending_line.bounds.size.width + in_fragment.border_box.size.width;
if new_width <= green_zone.width { if new_width <= green_zone.width {
debug!("LineboxScanner: case=box fits without splitting"); debug!("LineFragmentScanner: case=fragment fits without splitting");
self.push_box_to_line(in_box); self.push_fragment_to_line(in_fragment);
return true return true
} }
if !in_box.can_split() { if !in_fragment.can_split() {
// TODO(eatkinson, issue #224): Signal that horizontal overflow happened? // TODO(eatkinson, issue #224): Signal that horizontal overflow happened?
if line_is_empty { if line_is_empty {
debug!("LineboxScanner: case=box can't split and line {:u} is empty, so \ debug!("LineFragmentScanner: case=fragment can't split and line {:u} is empty, so \
overflowing.", overflowing.",
self.lines.len()); self.lines.len());
self.push_box_to_line(in_box); self.push_fragment_to_line(in_fragment);
return true return true
} }
} }
let available_width = green_zone.width - self.pending_line.bounds.size.width; let available_width = green_zone.width - self.pending_line.bounds.size.width;
let split = in_box.find_split_info_for_width(CharIndex(0), available_width, line_is_empty); let split = in_fragment.find_split_info_for_width(CharIndex(0), available_width, line_is_empty);
match split.map(|(left, right, run)| { match split.map(|(left, right, run)| {
// TODO(bjz): Remove box splitting // TODO(bjz): Remove fragment splitting
let split_box = |split: SplitInfo| { let split_fragment = |split: SplitInfo| {
let info = ScannedTextFragmentInfo::new(run.clone(), split.range); let info = ScannedTextFragmentInfo::new(run.clone(), split.range);
let specific = ScannedTextFragment(info); let specific = ScannedTextFragment(info);
let size = Size2D(split.width, in_box.border_box.size.height); let size = Size2D(split.width, in_fragment.border_box.size.height);
in_box.transform(size, specific) in_fragment.transform(size, specific)
}; };
(left.map(|x| { debug!("LineboxScanner: Left split {}", x); split_box(x) }), (left.map(|x| { debug!("LineFragmentScanner: Left split {}", x); split_fragment(x) }),
right.map(|x| { debug!("LineboxScanner: Right split {}", x); split_box(x) })) right.map(|x| { debug!("LineFragmentScanner: Right split {}", x); split_fragment(x) }))
}) { }) {
None => { None => {
debug!("LineboxScanner: Tried to split unsplittable render box! Deferring to next \ debug!("LineFragmentScanner: Tried to split unsplittable render fragment! Deferring to next \
line. {}", in_box); line. {}", in_fragment);
self.work_list.push_front(in_box); self.work_list.push_front(in_fragment);
false false
}, },
Some((Some(left_box), Some(right_box))) => { Some((Some(left_fragment), Some(right_fragment))) => {
debug!("LineboxScanner: Line break found! Pushing left box to line and deferring \ debug!("LineFragmentScanner: Line break found! Pushing left fragment to line and deferring \
right box to next line."); right fragment to next line.");
self.push_box_to_line(left_box); self.push_fragment_to_line(left_fragment);
self.work_list.push_front(right_box); self.work_list.push_front(right_fragment);
true true
}, },
Some((Some(left_box), None)) => { Some((Some(left_fragment), None)) => {
debug!("LineboxScanner: Pushing left box to line."); debug!("LineFragmentScanner: Pushing left fragment to line.");
self.push_box_to_line(left_box); self.push_fragment_to_line(left_fragment);
true true
}, },
Some((None, Some(right_box))) => { Some((None, Some(right_fragment))) => {
debug!("LineboxScanner: Pushing right box to line."); debug!("LineFragmentScanner: Pushing right fragment to line.");
self.push_box_to_line(right_box); self.push_fragment_to_line(right_fragment);
true true
}, },
Some((None, None)) => { Some((None, None)) => {
error!("LineboxScanner: This split case makes no sense!"); error!("LineFragmentScanner: This split case makes no sense!");
true true
}, },
} }
} }
// An unconditional push // An unconditional push
fn push_box_to_line(&mut self, box_: Fragment) { fn push_fragment_to_line(&mut self, fragment: Fragment) {
debug!("LineboxScanner: Pushing box {} to line {:u}", box_.debug_id(), self.lines.len()); debug!("LineFragmentScanner: Pushing fragment {} to line {:u}", fragment.debug_id(), self.lines.len());
if self.pending_line.range.length() == num::zero() { if self.pending_line.range.length() == num::zero() {
assert!(self.new_boxes.len() <= (u16::MAX as uint)); assert!(self.new_fragments.len() <= (u16::MAX as uint));
self.pending_line.range.reset( self.pending_line.range.reset(
LineIndices { LineIndices {
fragment_index: FragmentIndex(self.new_boxes.len() as int), fragment_index: FragmentIndex(self.new_fragments.len() as int),
char_index: CharIndex(0) /* unused for now */, char_index: CharIndex(0) /* unused for now */,
}, },
num::zero() num::zero()
@ -571,14 +570,14 @@ impl LineboxScanner {
char_index: CharIndex(0) /* unused for now */ , char_index: CharIndex(0) /* unused for now */ ,
}); });
self.pending_line.bounds.size.width = self.pending_line.bounds.size.width + self.pending_line.bounds.size.width = self.pending_line.bounds.size.width +
box_.border_box.size.width; fragment.border_box.size.width;
self.pending_line.bounds.size.height = Au::max(self.pending_line.bounds.size.height, self.pending_line.bounds.size.height = Au::max(self.pending_line.bounds.size.height,
box_.border_box.size.height); fragment.border_box.size.height);
self.new_boxes.push(box_); self.new_fragments.push(fragment);
} }
} }
/// Iterator over boxes. /// Iterator over fragments.
pub struct FragmentIterator<'a> { pub struct FragmentIterator<'a> {
iter: Enumerate<Items<'a,Fragment>>, iter: Enumerate<Items<'a,Fragment>>,
map: &'a InlineFragmentMap, map: &'a InlineFragmentMap,
@ -597,7 +596,7 @@ impl<'a> Iterator<(&'a Fragment, InlineFragmentContext<'a>)> for FragmentIterato
} }
} }
/// Mutable iterator over boxes. /// Mutable iterator over fragments.
pub struct MutFragmentIterator<'a> { pub struct MutFragmentIterator<'a> {
iter: Enumerate<MutItems<'a,Fragment>>, iter: Enumerate<MutItems<'a,Fragment>>,
map: &'a InlineFragmentMap, map: &'a InlineFragmentMap,
@ -616,75 +615,75 @@ impl<'a> Iterator<(&'a mut Fragment, InlineFragmentContext<'a>)> for MutFragment
} }
} }
/// Represents a list of inline boxes, including element ranges. /// Represents a list of inline fragments, including element ranges.
pub struct InlineFragments { pub struct InlineFragments {
/// The boxes themselves. /// The fragments themselves.
pub boxes: Vec<Fragment>, pub fragments: Vec<Fragment>,
/// Tracks the elements that made up the boxes above. /// Tracks the elements that made up the fragments above.
pub map: InlineFragmentMap, pub map: InlineFragmentMap,
} }
impl InlineFragments { impl InlineFragments {
/// Creates an empty set of inline boxes. /// Creates an empty set of inline fragments.
pub fn new() -> InlineFragments { pub fn new() -> InlineFragments {
InlineFragments { InlineFragments {
boxes: Vec::new(), fragments: Vec::new(),
map: InlineFragmentMap::new(), map: InlineFragmentMap::new(),
} }
} }
/// Returns the number of inline boxes. /// Returns the number of inline fragments.
pub fn len(&self) -> uint { pub fn len(&self) -> uint {
self.boxes.len() self.fragments.len()
} }
/// Returns true if this list contains no boxes and false if it contains at least one box. /// Returns true if this list contains no fragments and false if it contains at least one fragment.
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.len() == 0 self.len() == 0
} }
/// Pushes a new inline box. /// Pushes a new inline fragment.
pub fn push(&mut self, fragment: Fragment, style: Arc<ComputedValues>) { pub fn push(&mut self, fragment: Fragment, style: Arc<ComputedValues>) {
self.map.push(style, Range::new(FragmentIndex(self.boxes.len() as int), FragmentIndex(1))); self.map.push(style, Range::new(FragmentIndex(self.fragments.len() as int), FragmentIndex(1)));
self.boxes.push(fragment) self.fragments.push(fragment)
} }
/// Merges another set of inline boxes with this one. /// Merges another set of inline fragments with this one.
pub fn push_all(&mut self, other: InlineFragments) { pub fn push_all(&mut self, other: InlineFragments) {
let InlineFragments { let InlineFragments {
boxes: other_boxes, fragments: other_fragments,
map: other_map map: other_map
} = other; } = other;
let adjustment = FragmentIndex(self.boxes.len() as int); let adjustment = FragmentIndex(self.fragments.len() as int);
self.map.push_all(other_map, adjustment); self.map.push_all(other_map, adjustment);
self.boxes.push_all_move(other_boxes); self.fragments.push_all_move(other_fragments);
} }
/// Returns an iterator that iterates over all boxes along with the appropriate context. /// Returns an iterator that iterates over all fragments along with the appropriate context.
pub fn iter<'a>(&'a self) -> FragmentIterator<'a> { pub fn iter<'a>(&'a self) -> FragmentIterator<'a> {
FragmentIterator { FragmentIterator {
iter: self.boxes.as_slice().iter().enumerate(), iter: self.fragments.as_slice().iter().enumerate(),
map: &self.map, map: &self.map,
} }
} }
/// Returns an iterator that iterates over all boxes along with the appropriate context and /// Returns an iterator that iterates over all fragments along with the appropriate context and
/// allows those boxes to be mutated. /// allows those fragments to be mutated.
pub fn mut_iter<'a>(&'a mut self) -> MutFragmentIterator<'a> { pub fn mut_iter<'a>(&'a mut self) -> MutFragmentIterator<'a> {
MutFragmentIterator { MutFragmentIterator {
iter: self.boxes.as_mut_slice().mut_iter().enumerate(), iter: self.fragments.as_mut_slice().mut_iter().enumerate(),
map: &self.map, map: &self.map,
} }
} }
/// A convenience function to return the box at a given index. /// A convenience function to return the fragment at a given index.
pub fn get<'a>(&'a self, index: uint) -> &'a Fragment { pub fn get<'a>(&'a self, index: uint) -> &'a Fragment {
self.boxes.get(index) self.fragments.get(index)
} }
/// A convenience function to return a mutable reference to the box at a given index. /// A convenience function to return a mutable reference to the fragment at a given index.
pub fn get_mut<'a>(&'a mut self, index: uint) -> &'a mut Fragment { pub fn get_mut<'a>(&'a mut self, index: uint) -> &'a mut Fragment {
self.boxes.get_mut(index) self.fragments.get_mut(index)
} }
} }
@ -694,12 +693,12 @@ pub struct InlineFlow {
pub base: BaseFlow, pub base: BaseFlow,
/// A vector of all inline fragments. Several fragments may correspond to one node/element. /// A vector of all inline fragments. Several fragments may correspond to one node/element.
pub boxes: InlineFragments, pub fragments: InlineFragments,
/// A vector of ranges into boxes that represents line positions. These ranges are disjoint and /// A vector of ranges into fragments that represents line positions. These ranges are disjoint and
/// are the result of inline layout. This also includes some metadata used for positioning /// are the result of inline layout. This also includes some metadata used for positioning
/// lines. /// lines.
pub lines: Vec<LineBox>, pub lines: Vec<LineFragment>,
/// The minimum height above the baseline for each line, as specified by the line height and /// The minimum height above the baseline for each line, as specified by the line height and
/// font style. /// font style.
@ -711,10 +710,10 @@ pub struct InlineFlow {
} }
impl InlineFlow { impl InlineFlow {
pub fn from_boxes(node: ThreadSafeLayoutNode, boxes: InlineFragments) -> InlineFlow { pub fn from_fragments(node: ThreadSafeLayoutNode, fragments: InlineFragments) -> InlineFlow {
InlineFlow { InlineFlow {
base: BaseFlow::new(node), base: BaseFlow::new(node),
boxes: boxes, fragments: fragments,
lines: Vec::new(), lines: Vec::new(),
minimum_height_above_baseline: Au(0), minimum_height_above_baseline: Au(0),
minimum_depth_below_baseline: Au(0), minimum_depth_below_baseline: Au(0),
@ -727,11 +726,11 @@ impl InlineFlow {
return return
} }
// TODO(#228): Once we form line boxes and have their cached bounds, we can be smarter and // TODO(#228): Once we form line fragments and have their cached bounds, we can be smarter and
// not recurse on a line if nothing in it can intersect the dirty region. // not recurse on a line if nothing in it can intersect the dirty region.
debug!("Flow: building display list for {:u} inline boxes", self.boxes.len()); debug!("Flow: building display list for {:u} inline fragments", self.fragments.len());
for (fragment, context) in self.boxes.mut_iter() { for (fragment, context) in self.fragments.mut_iter() {
let rel_offset = fragment.relative_position(&self.base let rel_offset = fragment.relative_position(&self.base
.absolute_position_info .absolute_position_info
.relative_containing_block_size, .relative_containing_block_size,
@ -744,7 +743,7 @@ impl InlineFlow {
} }
// TODO(#225): Should `inline-block` elements have flows as children of the inline flow or // TODO(#225): Should `inline-block` elements have flows as children of the inline flow or
// should the flow be nested inside the box somehow? // should the flow be nested inside the fragment somehow?
// For now, don't traverse the subtree rooted here. // For now, don't traverse the subtree rooted here.
} }
@ -784,17 +783,17 @@ impl InlineFlow {
(-super_offset - ascent, false) (-super_offset - ascent, false)
}, },
vertical_align::text_top => { vertical_align::text_top => {
let box_height = *height_above_baseline + *depth_below_baseline; let fragment_height = *height_above_baseline + *depth_below_baseline;
let prev_depth_below_baseline = *depth_below_baseline; let prev_depth_below_baseline = *depth_below_baseline;
*height_above_baseline = parent_text_top; *height_above_baseline = parent_text_top;
*depth_below_baseline = box_height - *height_above_baseline; *depth_below_baseline = fragment_height - *height_above_baseline;
(*depth_below_baseline - prev_depth_below_baseline - ascent, false) (*depth_below_baseline - prev_depth_below_baseline - ascent, false)
}, },
vertical_align::text_bottom => { vertical_align::text_bottom => {
let box_height = *height_above_baseline + *depth_below_baseline; let fragment_height = *height_above_baseline + *depth_below_baseline;
let prev_depth_below_baseline = *depth_below_baseline; let prev_depth_below_baseline = *depth_below_baseline;
*depth_below_baseline = parent_text_bottom; *depth_below_baseline = parent_text_bottom;
*height_above_baseline = box_height - *depth_below_baseline; *height_above_baseline = fragment_height - *depth_below_baseline;
(*depth_below_baseline - prev_depth_below_baseline - ascent, false) (*depth_below_baseline - prev_depth_below_baseline - ascent, false)
}, },
vertical_align::top => { vertical_align::top => {
@ -821,17 +820,17 @@ impl InlineFlow {
} }
} }
/// Sets box X positions based on alignment for one line. /// Sets fragment X positions based on alignment for one line.
fn set_horizontal_box_positions(boxes: &mut InlineFragments, fn set_horizontal_fragment_positions(fragments: &mut InlineFragments,
line: &LineBox, line: &LineFragment,
linebox_align: text_align::T) { line_fragment_align: text_align::T) {
// Figure out how much width we have. // Figure out how much width we have.
let slack_width = Au::max(Au(0), line.green_zone.width - line.bounds.size.width); let slack_width = Au::max(Au(0), line.green_zone.width - line.bounds.size.width);
// Set the box x positions based on that alignment. // Set the fragment x positions based on that alignment.
let mut offset_x = line.bounds.origin.x; let mut offset_x = line.bounds.origin.x;
offset_x = offset_x + match linebox_align { offset_x = offset_x + match line_fragment_align {
// So sorry, but justified text is more complicated than shuffling linebox // So sorry, but justified text is more complicated than shuffling line_fragment
// coordinates. // coordinates.
// //
// TODO(burg, issue #213): Implement `text-align: justify`. // TODO(burg, issue #213): Implement `text-align: justify`.
@ -841,9 +840,9 @@ impl InlineFlow {
}; };
for i in each_fragment_index(&line.range) { for i in each_fragment_index(&line.range) {
let box_ = boxes.get_mut(i.to_uint()); let fragment = fragments.get_mut(i.to_uint());
let size = box_.border_box.size; let size = fragment.border_box.size;
box_.border_box = Rect(Point2D(offset_x, box_.border_box.origin.y), size); fragment.border_box = Rect(Point2D(offset_x, fragment.border_box.origin.y), size);
offset_x = offset_x + size.width; offset_x = offset_x + size.width;
} }
} }
@ -883,31 +882,31 @@ impl Flow for InlineFlow {
} }
let mut intrinsic_widths = IntrinsicWidths::new(); let mut intrinsic_widths = IntrinsicWidths::new();
for (fragment, context) in self.boxes.mut_iter() { for (fragment, context) in self.fragments.mut_iter() {
debug!("Flow: measuring {}", *fragment); debug!("Flow: measuring {}", *fragment);
let box_intrinsic_widths = fragment.intrinsic_widths(Some(context)); let fragment_intrinsic_widths = fragment.intrinsic_widths(Some(context));
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);
} }
self.base.intrinsic_widths = intrinsic_widths; self.base.intrinsic_widths = intrinsic_widths;
} }
/// 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, _: &mut LayoutContext) { fn assign_widths(&mut self, _: &mut LayoutContext) {
// Initialize content box widths if they haven't been initialized already. // Initialize content fragment widths if they haven't been initialized already.
// //
// TODO: Combine this with `LineboxScanner`'s walk in the box list, or put this into `Fragment`. // TODO: Combine this with `LineFragmentScanner`'s walk in the fragment list, or put this into `Fragment`.
debug!("InlineFlow::assign_widths: floats in: {:?}", self.base.floats); debug!("InlineFlow::assign_widths: floats in: {:?}", self.base.floats);
{ {
let this = &mut *self; let this = &mut *self;
for (fragment, context) in this.boxes.mut_iter() { for (fragment, context) in this.fragments.mut_iter() {
fragment.assign_replaced_width_if_necessary(self.base.position.size.width, fragment.assign_replaced_width_if_necessary(self.base.position.size.width,
Some(context)) Some(context))
} }
@ -922,57 +921,57 @@ impl Flow for InlineFlow {
// true. In that case, set the InlineBlockFragment's width to the // true. In that case, set the InlineBlockFragment's width to the
// shrink-to-fit width, perform inline flow, and set the block // shrink-to-fit width, perform inline flow, and set the block
// flow context's width as the assigned width of the // flow context's width as the assigned width of the
// 'inline-block' box that created this flow before recursing. // 'inline-block' fragment that created this flow before recursing.
} }
/// Calculate and set the height of this flow. See CSS 2.1 § 10.6.1. /// Calculate and set the height of this flow. See CSS 2.1 § 10.6.1.
fn assign_height(&mut self, _: &mut LayoutContext) { fn assign_height(&mut self, _: &mut LayoutContext) {
debug!("assign_height_inline: assigning height for flow"); debug!("assign_height_inline: assigning height for flow");
// Divide the boxes into lines. // Divide the fragments into lines.
// //
// TODO(#226): Get the CSS `line-height` property from the containing block's style to // TODO(#226): Get the CSS `line-height` property from the containing block's style to
// determine minimum linebox height. // determine minimum line_fragment height.
// //
// TODO(#226): Get the CSS `line-height` property from each non-replaced inline element to // TODO(#226): Get the CSS `line-height` property from each non-replaced inline element to
// determine its height for computing linebox height. // determine its height for computing line_fragment height.
// //
// TODO(pcwalton): Cache the linebox scanner? // TODO(pcwalton): Cache the line_fragment scanner?
debug!("assign_height_inline: floats in: {:?}", self.base.floats); debug!("assign_height_inline: floats in: {:?}", self.base.floats);
// assign height for inline boxes // assign height for inline fragments
for (fragment, _) in self.boxes.mut_iter() { for (fragment, _) in self.fragments.mut_iter() {
fragment.assign_replaced_height_if_necessary(); fragment.assign_replaced_height_if_necessary();
} }
let scanner_floats = self.base.floats.clone(); let scanner_floats = self.base.floats.clone();
let mut scanner = LineboxScanner::new(scanner_floats); let mut scanner = LineFragmentScanner::new(scanner_floats);
scanner.scan_for_lines(self); scanner.scan_for_lines(self);
// All lines use text alignment of the flow. // All lines use text alignment of the flow.
let text_align = self.base.flags.text_align(); let text_align = self.base.flags.text_align();
// Now, go through each line and lay out the boxes inside. // Now, go through each line and lay out the fragments inside.
let mut line_distance_from_flow_top = Au(0); let mut line_distance_from_flow_top = Au(0);
for line in self.lines.mut_iter() { for line in self.lines.mut_iter() {
// Lay out boxes horizontally. // Lay out fragments horizontally.
InlineFlow::set_horizontal_box_positions(&mut self.boxes, line, text_align); InlineFlow::set_horizontal_fragment_positions(&mut self.fragments, line, text_align);
// Set the top y position of the current line box. // Set the top y position of the current line fragment.
// `line_height_offset` is updated at the end of the previous loop. // `line_height_offset` is updated at the end of the previous loop.
line.bounds.origin.y = line_distance_from_flow_top; line.bounds.origin.y = line_distance_from_flow_top;
// Calculate the distance from the baseline to the top and bottom of the line box. // Calculate the distance from the baseline to the top and bottom of the line fragment.
let mut largest_height_above_baseline = self.minimum_height_above_baseline; let mut largest_height_above_baseline = self.minimum_height_above_baseline;
let mut largest_depth_below_baseline = self.minimum_depth_below_baseline; let mut largest_depth_below_baseline = self.minimum_depth_below_baseline;
// Calculate the largest height among boxes with 'top' and 'bottom' values // Calculate the largest height among fragments with 'top' and 'bottom' values
// respectively. // respectively.
let (mut largest_height_for_top_fragments, mut largest_height_for_bottom_fragments) = let (mut largest_height_for_top_fragments, mut largest_height_for_bottom_fragments) =
(Au(0), Au(0)); (Au(0), Au(0));
for box_i in each_fragment_index(&line.range) { for fragment_i in each_fragment_index(&line.range) {
let fragment = self.boxes.boxes.get_mut(box_i.to_uint()); let fragment = self.fragments.fragments.get_mut(fragment_i.to_uint());
let InlineMetrics { let InlineMetrics {
height_above_baseline: mut height_above_baseline, height_above_baseline: mut height_above_baseline,
@ -981,7 +980,7 @@ impl Flow for InlineFlow {
} = fragment.inline_metrics(); } = fragment.inline_metrics();
// To calculate text-top and text-bottom value when `vertical-align` is involved, // To calculate text-top and text-bottom value when `vertical-align` is involved,
// we should find the top and bottom of the content area of the parent box. // we should find the top and bottom of the content area of the parent fragment.
// "Content area" is defined in CSS 2.1 § 10.6.1. // "Content area" is defined in CSS 2.1 § 10.6.1.
// //
// TODO: We should extract em-box info from the font size of the parent and // TODO: We should extract em-box info from the font size of the parent and
@ -999,7 +998,7 @@ impl Flow for InlineFlow {
// content area. But for now we assume it's zero. // content area. But for now we assume it's zero.
let parent_text_bottom = Au(0); let parent_text_bottom = Au(0);
// Calculate the final height above the baseline for this box. // Calculate the final height above the baseline for this fragment.
// //
// The no-update flag decides whether `largest_height_for_top_fragments` and // The no-update flag decides whether `largest_height_for_top_fragments` and
// `largest_height_for_bottom_fragments` are to be updated or not. This will be set // `largest_height_for_bottom_fragments` are to be updated or not. This will be set
@ -1029,26 +1028,26 @@ impl Flow for InlineFlow {
fragment.border_box.origin.y = distance_from_baseline fragment.border_box.origin.y = distance_from_baseline
} }
// Calculate the distance from the baseline to the top of the largest box with a // Calculate the distance from the baseline to the top of the largest fragment with a
// value for `bottom`. Then, if necessary, update `largest_height_above_baseline`. // value for `bottom`. Then, if necessary, update `largest_height_above_baseline`.
largest_height_above_baseline = largest_height_above_baseline =
Au::max(largest_height_above_baseline, Au::max(largest_height_above_baseline,
largest_height_for_bottom_fragments - largest_depth_below_baseline); largest_height_for_bottom_fragments - largest_depth_below_baseline);
// Calculate the distance from baseline to the bottom of the largest box with a value // Calculate the distance from baseline to the bottom of the largest fragment with a value
// for `top`. Then, if necessary, update `largest_depth_below_baseline`. // for `top`. Then, if necessary, update `largest_depth_below_baseline`.
largest_depth_below_baseline = largest_depth_below_baseline =
Au::max(largest_depth_below_baseline, Au::max(largest_depth_below_baseline,
largest_height_for_top_fragments - largest_height_above_baseline); largest_height_for_top_fragments - largest_height_above_baseline);
// Now, the distance from the logical top of the line box to the baseline can be // Now, the distance from the logical top of the line fragment to the baseline can be
// computed as `largest_height_above_baseline`. // computed as `largest_height_above_baseline`.
let baseline_distance_from_top = largest_height_above_baseline; let baseline_distance_from_top = largest_height_above_baseline;
// Compute the final positions in the block direction of each fragment. Recall that // Compute the final positions in the block direction of each fragment. Recall that
// `fragment.border_box.origin.y` was set to the distance from the baseline above. // `fragment.border_box.origin.y` was set to the distance from the baseline above.
for box_i in each_fragment_index(&line.range) { for fragment_i in each_fragment_index(&line.range) {
let fragment = self.boxes.get_mut(box_i.to_uint()); let fragment = self.fragments.get_mut(fragment_i.to_uint());
match fragment.vertical_align() { match fragment.vertical_align() {
vertical_align::top => { vertical_align::top => {
fragment.border_box.origin.y = fragment.border_box.origin.y + fragment.border_box.origin.y = fragment.border_box.origin.y +
@ -1066,7 +1065,7 @@ impl Flow for InlineFlow {
} }
} }
// This is used to set the top y position of the next line box in the next loop. // This is used to set the top y position of the next line fragment in the next loop.
line.bounds.size.height = largest_height_above_baseline + largest_depth_below_baseline; line.bounds.size.height = largest_height_above_baseline + largest_depth_below_baseline;
line_distance_from_flow_top = line_distance_from_flow_top + line.bounds.size.height; line_distance_from_flow_top = line_distance_from_flow_top + line.bounds.size.height;
} // End of `lines.each` loop. } // End of `lines.each` loop.
@ -1087,7 +1086,7 @@ impl Flow for InlineFlow {
impl fmt::Show for InlineFlow { impl fmt::Show for InlineFlow {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f.buf, "InlineFlow")); try!(write!(f.buf, "InlineFlow"));
for (i, (fragment, _)) in self.boxes.iter().enumerate() { for (i, (fragment, _)) in self.fragments.iter().enumerate() {
if i == 0 { if i == 0 {
try!(write!(f.buf, ": {}", fragment)) try!(write!(f.buf, ": {}", fragment))
} else { } else {
@ -1099,7 +1098,7 @@ impl fmt::Show for InlineFlow {
} }
/// Information that inline flows keep about a single nested element. This is used to recover the /// Information that inline flows keep about a single nested element. This is used to recover the
/// DOM structure from the flat box list when it's needed. /// DOM structure from the flat fragment list when it's needed.
pub struct InlineFragmentRange { pub struct InlineFragmentRange {
/// The style of the DOM node that this range refers to. /// The style of the DOM node that this range refers to.
pub style: Arc<ComputedValues>, pub style: Arc<ComputedValues>,
@ -1166,7 +1165,7 @@ impl<'a> Iterator<&'a InlineFragmentRange> for RangeIterator<'a> {
} }
/// Information that inline flows keep about nested elements. This is used to recover the DOM /// Information that inline flows keep about nested elements. This is used to recover the DOM
/// structure from the flat box list when it's needed. /// structure from the flat fragment list when it's needed.
pub struct InlineFragmentMap { pub struct InlineFragmentMap {
list: Vec<InlineFragmentRange>, list: Vec<InlineFragmentRange>,
} }
@ -1207,7 +1206,7 @@ impl InlineFragmentMap {
&mut self.list.as_mut_slice()[index.to_uint()] &mut self.list.as_mut_slice()[index.to_uint()]
} }
/// Iterates over all ranges that contain the box with the given index, outermost first. /// Iterates over all ranges that contain the fragment with the given index, outermost first.
#[inline(always)] #[inline(always)]
fn ranges_for_index<'a>(&'a self, index: FragmentIndex) -> RangeIterator<'a> { fn ranges_for_index<'a>(&'a self, index: FragmentIndex) -> RangeIterator<'a> {
RangeIterator { RangeIterator {
@ -1222,10 +1221,10 @@ impl InlineFragmentMap {
/// DOM has changed, then the flow constructor will need to do more complicated surgery than /// DOM has changed, then the flow constructor will need to do more complicated surgery than
/// this function can provide. /// this function can provide.
/// ///
/// FIXME(#2267, pcwalton): It would be more efficient to not have to clone boxes all the time; /// FIXME(#2267, pcwalton): It would be more efficient to not have to clone fragments all the time;
/// i.e. if `old_boxes` contained less info than the entire range of boxes. See /// i.e. if `old_fragments` contained less info than the entire range of fragments. See
/// `layout::construct::strip_ignorable_whitespace_from_start` for an example of some code that /// `layout::construct::strip_ignorable_whitespace_from_start` for an example of some code that
/// needlessly has to clone boxes. /// needlessly has to clone fragments.
pub fn fixup(&mut self, old_fragments: &[Fragment], new_fragments: &[Fragment]) { pub fn fixup(&mut self, old_fragments: &[Fragment], new_fragments: &[Fragment]) {
// TODO(pcwalton): Post Rust upgrade, use `with_capacity` here. // TODO(pcwalton): Post Rust upgrade, use `with_capacity` here.
let old_list = mem::replace(&mut self.list, Vec::new()); let old_list = mem::replace(&mut self.list, Vec::new());

View file

@ -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,
@ -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

@ -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_: Fragment) 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

@ -22,18 +22,18 @@ pub struct TableCellFlow {
} }
impl TableCellFlow { impl TableCellFlow {
pub fn from_node_and_box(node: &ThreadSafeLayoutNode, box_: Fragment) -> 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 Fragment { 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 Fragment { 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

@ -18,10 +18,10 @@ 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<Fragment>, pub fragment: Option<Fragment>,
/// The table column boxes /// The table column fragments
pub cols: Vec<Fragment>, pub cols: Vec<Fragment>,
/// The specified widths of table columns /// The specified widths of table columns
@ -29,13 +29,13 @@ pub struct TableColGroupFlow {
} }
impl TableColGroupFlow { impl TableColGroupFlow {
pub fn from_node_and_boxes(node: &ThreadSafeLayoutNode, pub fn from_node_and_fragments(node: &ThreadSafeLayoutNode,
box_: Fragment, fragment: Fragment,
boxes: Vec<Fragment>) -> 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 {
TableColumnFragment(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

@ -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_: Fragment) 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 Fragment { 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

@ -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_: Fragment) 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 Fragment { 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

@ -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_: Fragment) 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

@ -25,12 +25,12 @@ struct NewLinePositions {
} }
// A helper function. // A helper function.
fn can_coalesce_text_nodes(boxes: &[Fragment], 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 `TextFragment`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 InlineFragments { let InlineFragments {
boxes: old_boxes, fragments: old_fragments,
map: mut map map: mut map
} = mem::replace(&mut flow.as_inline().boxes, InlineFragments::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,42 +70,42 @@ 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 = InlineFragments { 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: &[Fragment], in_fragments: &[Fragment],
out_boxes: &mut Vec<Fragment>, 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 {
UnscannedTextFragment(_) => 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 {
UnscannedTextFragment(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 = ScannedTextFragmentInfo::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,
ScannedTextFragment(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 {
UnscannedTextFragment(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 = ScannedTextFragmentInfo::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,
ScannedTextFragment(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.