aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout
diff options
context:
space:
mode:
Diffstat (limited to 'components/layout')
-rw-r--r--components/layout/block.rs84
-rw-r--r--components/layout/construct.rs63
-rw-r--r--components/layout/display_list_builder.rs461
-rw-r--r--components/layout/flow.rs27
-rw-r--r--components/layout/fragment.rs115
-rw-r--r--components/layout/inline.rs106
-rw-r--r--components/layout/layout_task.rs42
-rw-r--r--components/layout/list_item.rs10
-rw-r--r--components/layout/sequential.rs33
-rw-r--r--components/layout/table.rs10
-rw-r--r--components/layout/table_caption.rs10
-rw-r--r--components/layout/table_cell.rs10
-rw-r--r--components/layout/table_colgroup.rs9
-rw-r--r--components/layout/table_row.rs10
-rw-r--r--components/layout/table_rowgroup.rs10
-rw-r--r--components/layout/table_wrapper.rs10
16 files changed, 561 insertions, 449 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs
index eec1f945d1c..3f7fd4be823 100644
--- a/components/layout/block.rs
+++ b/components/layout/block.rs
@@ -32,7 +32,7 @@ use context::LayoutContext;
use css::node_style::StyledNode;
use display_list_builder::{BlockFlowDisplayListBuilding, FragmentDisplayListBuilding};
use floats::{ClearType, FloatKind, Floats, PlacementInfo};
-use flow::{AbsolutePositionInfo, BaseFlow, ForceNonfloatedFlag, FlowClass, Flow};
+use flow::{mod, AbsolutePositionInfo, BaseFlow, ForceNonfloatedFlag, FlowClass, Flow};
use flow::{ImmutableFlowUtils, MutableFlowUtils, PreorderFlowTraversal};
use flow::{PostorderFlowTraversal, mut_base};
use flow::{HAS_LEFT_FLOATED_DESCENDANTS, HAS_RIGHT_FLOATED_DESCENDANTS};
@@ -40,8 +40,7 @@ use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS};
use flow::{LAYERS_NEEDED_FOR_DESCENDANTS, NEEDS_LAYER};
use flow::{IS_ABSOLUTELY_POSITIONED};
use flow::{CLEARS_LEFT, CLEARS_RIGHT};
-use flow;
-use fragment::{Fragment, FragmentOverflowIterator, SpecificFragmentInfo};
+use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo};
use incremental::{REFLOW, REFLOW_OUT_OF_FLOW};
use layout_debug;
use model::{IntrinsicISizes, MarginCollapseInfo};
@@ -49,11 +48,11 @@ use model::{MaybeAuto, CollapsibleMargins, specified, specified_or_none};
use table::ColumnComputedInlineSize;
use wrapper::ThreadSafeLayoutNode;
-use geom::{Rect, Size2D};
+use geom::{Point2D, Rect, Size2D};
use gfx::display_list::{ClippingRegion, DisplayList};
use serialize::{Encoder, Encodable};
use servo_msg::compositor_msg::LayerId;
-use servo_util::geometry::{Au, MAX_AU, ZERO_POINT};
+use servo_util::geometry::{Au, MAX_AU};
use servo_util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize};
use servo_util::opts;
use std::cmp::{max, min};
@@ -1769,23 +1768,40 @@ impl Flow for BlockFlow {
};
// Compute the origin and clipping rectangle for children.
- let origin_for_children = if self.fragment.establishes_stacking_context() {
- ZERO_POINT
+ let relative_offset = relative_offset.to_physical(self.base.writing_mode);
+ let origin_for_children;
+ let clip_in_child_coordinate_system;
+ if self.fragment.establishes_stacking_context() {
+ // We establish a stacking context, so the position of our children is vertically
+ // correct, but has to be adjusted to accommodate horizontal margins. (Note the
+ // calculation involving `position` below and recall that inline-direction flow
+ // positions are relative to the edges of the margin box.)
+ //
+ // FIXME(pcwalton): Is this vertical-writing-direction-safe?
+ let margin = self.fragment.margin.to_physical(self.base.writing_mode);
+ origin_for_children = Point2D(-margin.left, Au(0)) + relative_offset;
+ clip_in_child_coordinate_system =
+ self.base.clip.translate(&-self.base.stacking_relative_position)
} else {
- self.base.stacking_relative_position
- };
- let clip = self.fragment.clipping_region_for_children(&self.base.clip,
- &origin_for_children);
+ origin_for_children = self.base.stacking_relative_position + relative_offset;
+ clip_in_child_coordinate_system = self.base.clip.clone()
+ }
+ let stacking_relative_border_box =
+ self.fragment
+ .stacking_relative_border_box(&self.base.stacking_relative_position,
+ &self.base
+ .absolute_position_info
+ .relative_containing_block_size,
+ CoordinateSystem::Self);
+ let clip = self.fragment.clipping_region_for_children(&clip_in_child_coordinate_system,
+ &stacking_relative_border_box);
// Process children.
- let writing_mode = self.base.writing_mode;
for kid in self.base.child_iter() {
if !flow::base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) {
let kid_base = flow::mut_base(kid);
- kid_base.stacking_relative_position =
- origin_for_children
- + kid_base.position.start.to_physical(kid_base.writing_mode, container_size)
- + relative_offset.to_physical(writing_mode);
+ kid_base.stacking_relative_position = origin_for_children +
+ kid_base.position.start.to_physical(kid_base.writing_mode, container_size);
}
flow::mut_base(kid).absolute_position_info = absolute_position_info_for_children;
@@ -1832,16 +1848,20 @@ impl Flow for BlockFlow {
fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) {
if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
- self.fragment.style().logical_position().inline_start == LengthOrPercentageOrAuto::Auto &&
- self.fragment.style().logical_position().inline_end == LengthOrPercentageOrAuto::Auto {
+ self.fragment.style().logical_position().inline_start ==
+ LengthOrPercentageOrAuto::Auto &&
+ self.fragment.style().logical_position().inline_end ==
+ LengthOrPercentageOrAuto::Auto {
self.base.position.start.i = inline_position
}
}
fn update_late_computed_block_position_if_necessary(&mut self, block_position: Au) {
if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
- self.fragment.style().logical_position().block_start == LengthOrPercentageOrAuto::Auto &&
- self.fragment.style().logical_position().block_end == LengthOrPercentageOrAuto::Auto {
+ self.fragment.style().logical_position().block_start ==
+ LengthOrPercentageOrAuto::Auto &&
+ self.fragment.style().logical_position().block_end ==
+ LengthOrPercentageOrAuto::Auto {
self.base.position.start.b = block_position
}
}
@@ -1861,16 +1881,32 @@ impl Flow for BlockFlow {
self.fragment.compute_overflow()
}
- fn iterate_through_fragment_overflow(&self, iterator: &mut FragmentOverflowIterator) {
- if iterator.should_process(&self.fragment) {
- iterator.process(&self.fragment, self.fragment.compute_overflow());
+ fn iterate_through_fragment_border_boxes(&self,
+ iterator: &mut FragmentBorderBoxIterator,
+ stacking_context_position: &Point2D<Au>) {
+ if !iterator.should_process(&self.fragment) {
+ return
}
+
+ iterator.process(&self.fragment,
+ &self.fragment
+ .stacking_relative_border_box(&self.base.stacking_relative_position,
+ &self.base
+ .absolute_position_info
+ .relative_containing_block_size,
+ CoordinateSystem::Parent)
+ .translate(stacking_context_position));
}
}
impl fmt::Show for BlockFlow {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{} - {:x}: frag={} ({})", self.class(), self.base.debug_id(), self.fragment, self.base)
+ write!(f,
+ "{} - {:x}: frag={} ({})",
+ self.class(),
+ self.base.debug_id(),
+ self.fragment,
+ self.base)
}
}
diff --git a/components/layout/construct.rs b/components/layout/construct.rs
index 94605e103ec..c2911b13640 100644
--- a/components/layout/construct.rs
+++ b/components/layout/construct.rs
@@ -52,9 +52,9 @@ use servo_util::opts;
use std::collections::DList;
use std::mem;
use std::sync::atomic::Relaxed;
-use style::ComputedValues;
use style::computed_values::{caption_side, display, empty_cells, float, list_style_position};
use style::computed_values::{position};
+use style::{mod, ComputedValues};
use sync::Arc;
use url::Url;
@@ -681,7 +681,7 @@ impl<'a> FlowConstructor<'a> {
/// doesn't render its children, so this just nukes a child's fragments and creates a
/// `Fragment`.
fn build_fragments_for_replaced_inline_content(&mut self, node: &ThreadSafeLayoutNode)
- -> ConstructionResult {
+ -> ConstructionResult {
for kid in node.children() {
kid.set_flow_construction_result(ConstructionResult::None)
}
@@ -697,24 +697,42 @@ impl<'a> FlowConstructor<'a> {
node.restyle_damage()))
}
+ // If the value of `display` property is not `inline`, then we have a situation like
+ // `<div style="position:absolute">foo bar baz</div>`. The fragments for `foo`, `bar`, and
+ // `baz` had better not be absolutely positioned!
+ let mut style = (*node.style()).clone();
+ if style.get_box().display != display::inline {
+ style = Arc::new(style::make_inline(&*style))
+ }
+
// If this is generated content, then we need to initialize the accumulator with the
// fragment corresponding to that content. Otherwise, just initialize with the ordinary
// fragment that needs to be generated for this inline node.
let fragment = if node.get_pseudo_element_type() != PseudoElementType::Normal {
- let fragment_info = SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::new(node));
- Fragment::new_from_specific_info(node, fragment_info)
+ let fragment_info =
+ SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::new(node));
+ Fragment::from_opaque_node_and_style(
+ OpaqueNodeMethods::from_thread_safe_layout_node(node),
+ style,
+ node.restyle_damage(),
+ fragment_info)
} else {
- Fragment::new(self, node)
+ Fragment::from_opaque_node_and_style(
+ OpaqueNodeMethods::from_thread_safe_layout_node(node),
+ style,
+ node.restyle_damage(),
+ self.build_specific_fragment_info_for_node(node))
};
let mut fragments = DList::new();
fragments.push_back(fragment);
- let construction_item = ConstructionItem::InlineFragments(InlineFragmentsConstructionResult {
- splits: DList::new(),
- fragments: fragments,
- abs_descendants: Descendants::new(),
- });
+ let construction_item =
+ ConstructionItem::InlineFragments(InlineFragmentsConstructionResult {
+ splits: DList::new(),
+ fragments: fragments,
+ abs_descendants: Descendants::new(),
+ });
ConstructionResult::ConstructionItem(construction_item)
}
@@ -726,17 +744,19 @@ impl<'a> FlowConstructor<'a> {
_ => unreachable!()
};
- let fragment_info = SpecificFragmentInfo::InlineBlock(InlineBlockFragmentInfo::new(block_flow));
+ let fragment_info = SpecificFragmentInfo::InlineBlock(InlineBlockFragmentInfo::new(
+ block_flow));
let fragment = Fragment::new_from_specific_info(node, fragment_info);
let mut fragment_accumulator = InlineFragmentsAccumulator::from_inline_node(node);
fragment_accumulator.fragments.push_back(fragment);
- let construction_item = ConstructionItem::InlineFragments(InlineFragmentsConstructionResult {
- splits: DList::new(),
- fragments: fragment_accumulator.to_dlist(),
- abs_descendants: abs_descendants,
- });
+ let construction_item =
+ ConstructionItem::InlineFragments(InlineFragmentsConstructionResult {
+ splits: DList::new(),
+ fragments: fragment_accumulator.to_dlist(),
+ abs_descendants: abs_descendants,
+ });
ConstructionResult::ConstructionItem(construction_item)
}
@@ -757,11 +777,12 @@ impl<'a> FlowConstructor<'a> {
let mut fragment_accumulator = InlineFragmentsAccumulator::from_inline_node(node);
fragment_accumulator.fragments.push_back(fragment);
- let construction_item = ConstructionItem::InlineFragments(InlineFragmentsConstructionResult {
- splits: DList::new(),
- fragments: fragment_accumulator.to_dlist(),
- abs_descendants: abs_descendants,
- });
+ let construction_item =
+ ConstructionItem::InlineFragments(InlineFragmentsConstructionResult {
+ splits: DList::new(),
+ fragments: fragment_accumulator.to_dlist(),
+ abs_descendants: abs_descendants,
+ });
ConstructionResult::ConstructionItem(construction_item)
}
diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs
index 2696bcc3dc5..80877ffaaf9 100644
--- a/components/layout/display_list_builder.rs
+++ b/components/layout/display_list_builder.rs
@@ -13,8 +13,9 @@
use block::BlockFlow;
use context::LayoutContext;
use flow::{mod, Flow, IS_ABSOLUTELY_POSITIONED, NEEDS_LAYER};
-use fragment::{Fragment, SpecificFragmentInfo, IframeFragmentInfo, ImageFragmentInfo};
-use fragment::ScannedTextFragmentInfo;
+use fragment::{CoordinateSystem, Fragment, IframeFragmentInfo, ImageFragmentInfo};
+use fragment::{ScannedTextFragmentInfo, SpecificFragmentInfo};
+use inline::InlineFlow;
use list_item::ListItemFlow;
use model;
use util::{OpaqueNodeMethods, ToGfxColor};
@@ -36,8 +37,8 @@ use servo_msg::constellation_msg::Msg as ConstellationMsg;
use servo_msg::constellation_msg::ConstellationChan;
use servo_net::image::holder::ImageHolder;
use servo_util::cursor::{DefaultCursor, TextCursor, VerticalTextCursor};
-use servo_util::geometry::{mod, Au, ZERO_POINT};
-use servo_util::logical_geometry::{LogicalRect, WritingMode};
+use servo_util::geometry::{mod, Au};
+use servo_util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize};
use servo_util::opts;
use std::default::Default;
use std::num::FloatMath;
@@ -133,16 +134,19 @@ pub trait FragmentDisplayListBuilding {
absolute_bounds: &Rect<Au>,
clip: &ClippingRegion);
+ /// Adds display items necessary to draw debug boxes around a scanned text fragment.
fn build_debug_borders_around_text_fragments(&self,
style: &ComputedValues,
display_list: &mut DisplayList,
- flow_origin: Point2D<Au>,
+ stacking_relative_border_box: &Rect<Au>,
+ stacking_relative_content_box: &Rect<Au>,
text_fragment: &ScannedTextFragmentInfo,
clip: &ClippingRegion);
+ /// Adds display items necessary to draw debug boxes around this fragment.
fn build_debug_borders_around_fragment(&self,
display_list: &mut DisplayList,
- flow_origin: Point2D<Au>,
+ stacking_relative_border_box: &Rect<Au>,
clip: &ClippingRegion);
/// Adds the display items for this fragment to the given display list.
@@ -152,12 +156,16 @@ pub trait FragmentDisplayListBuilding {
/// * `display_list`: The display list to add display items to.
/// * `layout_context`: The layout context.
/// * `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.
+ /// * `stacking_relative_flow_origin`: Position of the origin of the owning flow with respect
+ /// to its nearest ancestor stacking context.
+ /// * `relative_containing_block_size`: The size of the containing block that
+ /// `position: relative` makes use of.
/// * `clip`: The region to clip the display items to.
fn build_display_list(&mut self,
display_list: &mut DisplayList,
layout_context: &LayoutContext,
- flow_origin: Point2D<Au>,
+ stacking_relative_flow_origin: &Point2D<Au>,
+ relative_containing_block_size: &LogicalSize<Au>,
background_and_border_level: BackgroundAndBorderLevel,
clip: &ClippingRegion);
@@ -168,12 +176,17 @@ pub trait FragmentDisplayListBuilding {
offset: Point2D<Au>,
layout_context: &LayoutContext);
- fn clipping_region_for_children(&self, current_clip: &ClippingRegion, flow_origin: &Point2D<Au>)
+ /// Returns the appropriate clipping region for descendants of this flow.
+ fn clipping_region_for_children(&self,
+ current_clip: &ClippingRegion,
+ stacking_relative_border_box: &Rect<Au>)
-> ClippingRegion;
/// Calculates the clipping rectangle for a fragment, taking the `clip` property into account
/// per CSS 2.1 § 11.1.2.
- fn calculate_style_specified_clip(&self, parent_clip: &ClippingRegion, origin: &Point2D<Au>)
+ fn calculate_style_specified_clip(&self,
+ parent_clip: &ClippingRegion,
+ stacking_relative_border_box: &Rect<Au>)
-> ClippingRegion;
/// Creates the text display item for one text fragment.
@@ -181,23 +194,20 @@ pub trait FragmentDisplayListBuilding {
display_list: &mut DisplayList,
text_fragment: &ScannedTextFragmentInfo,
text_color: RGBA,
- offset: &Point2D<Au>,
- flow_origin: &Point2D<Au>,
+ stacking_relative_content_box: &Rect<Au>,
clip: &ClippingRegion);
/// Creates the display item for a text decoration: underline, overline, or line-through.
fn build_display_list_for_text_decoration(&self,
display_list: &mut DisplayList,
- color: RGBA,
- flow_origin: &Point2D<Au>,
- clip: &ClippingRegion,
- logical_bounds: &LogicalRect<Au>,
- offset: &Point2D<Au>);
+ color: &RGBA,
+ stacking_relative_box: &LogicalRect<Au>,
+ clip: &ClippingRegion);
/// A helper method that `build_display_list` calls to create per-fragment-type display items.
fn build_fragment_type_specific_display_items(&mut self,
display_list: &mut DisplayList,
- flow_origin: Point2D<Au>,
+ stacking_relative_border_box: &Rect<Au>,
clip: &ClippingRegion);
}
@@ -580,20 +590,16 @@ impl FragmentDisplayListBuilding for Fragment {
fn build_debug_borders_around_text_fragments(&self,
style: &ComputedValues,
display_list: &mut DisplayList,
- flow_origin: Point2D<Au>,
+ stacking_relative_border_box: &Rect<Au>,
+ stacking_relative_content_box: &Rect<Au>,
text_fragment: &ScannedTextFragmentInfo,
clip: &ClippingRegion) {
- // FIXME(#2795): Get the real container size
+ // FIXME(pcwalton, #2795): Get the real container size.
let container_size = Size2D::zero();
- // Fragment position wrt to the owning flow.
- let fragment_bounds = self.border_box.to_physical(self.style.writing_mode, container_size);
- let absolute_fragment_bounds = Rect(
- fragment_bounds.origin + flow_origin,
- fragment_bounds.size);
// Compute the text fragment bounds and draw a border surrounding them.
display_list.content.push_back(DisplayItem::BorderClass(box BorderDisplayItem {
- base: BaseDisplayItem::new(absolute_fragment_bounds,
+ base: BaseDisplayItem::new(*stacking_relative_border_box,
DisplayItemMetadata::new(self.node, style, DefaultCursor),
(*clip).clone()),
border_widths: SideOffsets2D::new_all_same(Au::from_px(1)),
@@ -603,12 +609,12 @@ impl FragmentDisplayListBuilding for Fragment {
}));
// Draw a rectangle representing the baselines.
- let ascent = text_fragment.run.ascent();
- let mut baseline = self.border_box.clone();
- baseline.start.b = baseline.start.b + ascent;
+ let mut baseline = LogicalRect::from_physical(self.style.writing_mode,
+ *stacking_relative_content_box,
+ container_size);
+ baseline.start.b = baseline.start.b + text_fragment.run.ascent();
baseline.size.block = Au(0);
- let mut baseline = baseline.to_physical(self.style.writing_mode, container_size);
- baseline.origin = baseline.origin + flow_origin;
+ let baseline = baseline.to_physical(self.style.writing_mode, container_size);
let line_display_item = box LineDisplayItem {
base: BaseDisplayItem::new(baseline,
@@ -622,19 +628,11 @@ impl FragmentDisplayListBuilding for Fragment {
fn build_debug_borders_around_fragment(&self,
display_list: &mut DisplayList,
- flow_origin: Point2D<Au>,
+ stacking_relative_border_box: &Rect<Au>,
clip: &ClippingRegion) {
- // FIXME(#2795): Get the real container size
- let container_size = Size2D::zero();
- // Fragment position wrt to the owning flow.
- let fragment_bounds = self.border_box.to_physical(self.style.writing_mode, container_size);
- let absolute_fragment_bounds = Rect(
- fragment_bounds.origin + flow_origin,
- fragment_bounds.size);
-
// This prints a debug border around the border of this fragment.
display_list.content.push_back(DisplayItem::BorderClass(box BorderDisplayItem {
- base: BaseDisplayItem::new(absolute_fragment_bounds,
+ base: BaseDisplayItem::new(*stacking_relative_border_box,
DisplayItemMetadata::new(self.node,
&*self.style,
DefaultCursor),
@@ -646,7 +644,9 @@ impl FragmentDisplayListBuilding for Fragment {
}));
}
- fn calculate_style_specified_clip(&self, parent_clip: &ClippingRegion, origin: &Point2D<Au>)
+ fn calculate_style_specified_clip(&self,
+ parent_clip: &ClippingRegion,
+ stacking_relative_border_box: &Rect<Au>)
-> ClippingRegion {
// Account for `clip` per CSS 2.1 § 11.1.2.
let style_clip_rect = match (self.style().get_box().position,
@@ -656,54 +656,49 @@ impl FragmentDisplayListBuilding for Fragment {
};
// FIXME(pcwalton, #2795): Get the real container size.
- let border_box = self.border_box.to_physical(self.style.writing_mode, Size2D::zero());
- let clip_origin = Point2D(border_box.origin.x + style_clip_rect.left,
- border_box.origin.y + style_clip_rect.top);
- let new_clip_rect =
- Rect(clip_origin + *origin,
- Size2D(style_clip_rect.right.unwrap_or(border_box.size.width) - clip_origin.x,
- style_clip_rect.bottom.unwrap_or(border_box.size.height) - clip_origin.y));
- (*parent_clip).clone().intersect_rect(&new_clip_rect)
+ let clip_origin = Point2D(stacking_relative_border_box.origin.x + style_clip_rect.left,
+ stacking_relative_border_box.origin.y + style_clip_rect.top);
+ let right = style_clip_rect.right.unwrap_or(stacking_relative_border_box.size.width);
+ let bottom = style_clip_rect.bottom.unwrap_or(stacking_relative_border_box.size.height);
+ let clip_size = Size2D(right - clip_origin.x, bottom - clip_origin.y);
+ (*parent_clip).clone().intersect_rect(&Rect(clip_origin, clip_size))
}
fn build_display_list(&mut self,
display_list: &mut DisplayList,
layout_context: &LayoutContext,
- flow_origin: Point2D<Au>,
+ stacking_relative_flow_origin: &Point2D<Au>,
+ relative_containing_block_size: &LogicalSize<Au>,
background_and_border_level: BackgroundAndBorderLevel,
clip: &ClippingRegion) {
// Compute the fragment position relative to the parent stacking context. If the fragment
// itself establishes a stacking context, then the origin of its position will be (0, 0)
// for the purposes of this computation.
- let stacking_relative_flow_origin = if self.establishes_stacking_context() {
- ZERO_POINT
- } else {
- flow_origin
- };
- let absolute_fragment_bounds =
- self.stacking_relative_bounds(&stacking_relative_flow_origin);
+ let stacking_relative_border_box =
+ self.stacking_relative_border_box(stacking_relative_flow_origin,
+ relative_containing_block_size,
+ CoordinateSystem::Self);
- debug!("Fragment::build_display_list at rel={}, abs={}: {}",
+ debug!("Fragment::build_display_list at rel={}, abs={}, dirty={}, flow origin={}: {}",
self.border_box,
- absolute_fragment_bounds,
- self);
- debug!("Fragment::build_display_list: dirty={}, flow_origin={}",
+ stacking_relative_border_box,
layout_context.shared.dirty,
- flow_origin);
+ stacking_relative_flow_origin,
+ self);
if self.style().get_inheritedbox().visibility != visibility::visible {
return
}
- if !absolute_fragment_bounds.intersects(&layout_context.shared.dirty) {
+ if !stacking_relative_border_box.intersects(&layout_context.shared.dirty) {
debug!("Fragment::build_display_list: Did not intersect...");
return
}
// Calculate the clip rect. If there's nothing to render at all, don't even construct
// display list items.
- let clip = self.calculate_style_specified_clip(clip, &absolute_fragment_bounds.origin);
- if !clip.might_intersect_rect(&absolute_fragment_bounds) {
+ let clip = self.calculate_style_specified_clip(clip, &stacking_relative_border_box);
+ if !clip.might_intersect_rect(&stacking_relative_border_box) {
return;
}
@@ -713,15 +708,34 @@ impl FragmentDisplayListBuilding for Fragment {
let level =
StackingLevel::from_background_and_border_level(background_and_border_level);
- // Add a shadow to the list, if applicable.
+ // Add shadows, background, borders, and outlines, if applicable.
if let Some(ref inline_context) = self.inline_context {
for style in inline_context.styles.iter().rev() {
- self.build_display_list_for_box_shadow_if_applicable(&**style,
- display_list,
- layout_context,
- level,
- &absolute_fragment_bounds,
- &clip);
+ self.build_display_list_for_box_shadow_if_applicable(
+ &**style,
+ display_list,
+ layout_context,
+ level,
+ &stacking_relative_border_box,
+ &clip);
+ self.build_display_list_for_background_if_applicable(
+ &**style,
+ display_list,
+ layout_context,
+ level,
+ &stacking_relative_border_box,
+ &clip);
+ self.build_display_list_for_borders_if_applicable(
+ &**style,
+ display_list,
+ &stacking_relative_border_box,
+ level,
+ &clip);
+ self.build_display_list_for_outline_if_applicable(
+ &**style,
+ display_list,
+ &stacking_relative_border_box,
+ &clip);
}
}
if !self.is_scanned_text_fragment() {
@@ -729,62 +743,35 @@ impl FragmentDisplayListBuilding for Fragment {
display_list,
layout_context,
level,
- &absolute_fragment_bounds,
+ &stacking_relative_border_box,
&clip);
- }
-
- // Add the background to the list, if applicable.
- if let Some(ref inline_context) = self.inline_context {
- for style in inline_context.styles.iter().rev() {
- self.build_display_list_for_background_if_applicable(&**style,
- display_list,
- layout_context,
- level,
- &absolute_fragment_bounds,
- &clip);
- }
- }
- if !self.is_scanned_text_fragment() {
self.build_display_list_for_background_if_applicable(&*self.style,
display_list,
layout_context,
level,
- &absolute_fragment_bounds,
+ &stacking_relative_border_box,
&clip);
- }
-
- // Add a border and outlines, if applicable.
- if let Some(ref inline_context) = self.inline_context {
- for style in inline_context.styles.iter().rev() {
- self.build_display_list_for_borders_if_applicable(&**style,
- display_list,
- &absolute_fragment_bounds,
- level,
- &clip);
- self.build_display_list_for_outline_if_applicable(&**style,
- display_list,
- &absolute_fragment_bounds,
- &clip);
- }
- }
- if !self.is_scanned_text_fragment() {
self.build_display_list_for_borders_if_applicable(&*self.style,
display_list,
- &absolute_fragment_bounds,
+ &stacking_relative_border_box,
level,
&clip);
self.build_display_list_for_outline_if_applicable(&*self.style,
display_list,
- &absolute_fragment_bounds,
+ &stacking_relative_border_box,
&clip);
}
}
// Create special per-fragment-type display items.
- self.build_fragment_type_specific_display_items(display_list, flow_origin, &clip);
+ self.build_fragment_type_specific_display_items(display_list,
+ &stacking_relative_border_box,
+ &clip);
if opts::get().show_debug_fragment_borders {
- self.build_debug_borders_around_fragment(display_list, flow_origin, &clip)
+ self.build_debug_borders_around_fragment(display_list,
+ &stacking_relative_border_box,
+ &clip)
}
// If this is an iframe, then send its position and size up to the constellation.
@@ -799,31 +786,18 @@ impl FragmentDisplayListBuilding for Fragment {
// the iframe is actually going to be displayed.
if let SpecificFragmentInfo::Iframe(ref iframe_fragment) = self.specific {
self.finalize_position_and_size_of_iframe(&**iframe_fragment,
- absolute_fragment_bounds.origin,
+ stacking_relative_border_box.origin,
layout_context)
}
}
fn build_fragment_type_specific_display_items(&mut self,
display_list: &mut DisplayList,
- flow_origin: Point2D<Au>,
+ stacking_relative_border_box: &Rect<Au>,
clip: &ClippingRegion) {
- // Compute the fragment position relative to the parent stacking context. If the fragment
- // itself establishes a stacking context, then the origin of its position will be (0, 0)
- // for the purposes of this computation.
- let stacking_relative_flow_origin = if self.establishes_stacking_context() {
- ZERO_POINT
- } else {
- flow_origin
- };
-
- // FIXME(#2795): Get the real container size.
- let content_box = self.content_box();
- let container_size = Size2D::zero();
- let rect_to_absolute = |writing_mode: WritingMode, logical_rect: LogicalRect<Au>| {
- let physical_rect = logical_rect.to_physical(writing_mode, container_size);
- Rect(physical_rect.origin + stacking_relative_flow_origin, physical_rect.size)
- };
+ // Compute the context box position relative to the parent stacking context.
+ let stacking_relative_content_box =
+ self.stacking_relative_content_box(stacking_relative_border_box);
match self.specific {
SpecificFragmentInfo::UnscannedText(_) => {
@@ -838,16 +812,16 @@ impl FragmentDisplayListBuilding for Fragment {
self.build_display_list_for_text_fragment(display_list,
&**text_fragment,
text_color,
- &flow_origin,
- &Point2D(Au(0), Au(0)),
+ &stacking_relative_content_box,
clip);
if opts::get().show_debug_fragment_borders {
self.build_debug_borders_around_text_fragments(self.style(),
display_list,
- flow_origin,
+ stacking_relative_border_box,
+ &stacking_relative_content_box,
&**text_fragment,
- clip);
+ clip)
}
}
SpecificFragmentInfo::Generic |
@@ -859,25 +833,25 @@ impl FragmentDisplayListBuilding for Fragment {
SpecificFragmentInfo::InlineBlock(_) |
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {
if opts::get().show_debug_fragment_borders {
- self.build_debug_borders_around_fragment(display_list, flow_origin, clip);
+ self.build_debug_borders_around_fragment(display_list,
+ stacking_relative_border_box,
+ clip);
}
}
SpecificFragmentInfo::Image(ref mut image_fragment) => {
let image_ref = &mut image_fragment.image;
if let Some(image) = image_ref.get_image(self.node.to_untrusted_node_address()) {
debug!("(building display list) building image fragment");
- let absolute_content_box = rect_to_absolute(self.style.writing_mode,
- content_box);
// Place the image into the display list.
display_list.content.push_back(DisplayItem::ImageClass(box ImageDisplayItem {
- base: BaseDisplayItem::new(absolute_content_box,
+ base: BaseDisplayItem::new(stacking_relative_content_box,
DisplayItemMetadata::new(self.node,
&*self.style,
DefaultCursor),
(*clip).clone()),
image: image.clone(),
- stretch_size: absolute_content_box.size,
+ stretch_size: stacking_relative_content_box.size,
}));
} else {
// No image data at all? Do nothing.
@@ -910,7 +884,9 @@ impl FragmentDisplayListBuilding for Fragment {
iframe_rect));
}
- fn clipping_region_for_children(&self, current_clip: &ClippingRegion, flow_origin: &Point2D<Au>)
+ fn clipping_region_for_children(&self,
+ current_clip: &ClippingRegion,
+ stacking_relative_border_box: &Rect<Au>)
-> ClippingRegion {
// Don't clip if we're text.
if self.is_scanned_text_fragment() {
@@ -918,27 +894,24 @@ impl FragmentDisplayListBuilding for Fragment {
}
// Account for style-specified `clip`.
- let current_clip = self.calculate_style_specified_clip(current_clip, flow_origin);
+ let current_clip = self.calculate_style_specified_clip(current_clip,
+ stacking_relative_border_box);
// Only clip if `overflow` tells us to.
match self.style.get_box().overflow {
- overflow::hidden | overflow::auto | overflow::scroll => {}
- _ => return current_clip,
+ overflow::hidden | overflow::auto | overflow::scroll => {
+ // Create a new clip rect.
+ current_clip.intersect_rect(stacking_relative_border_box)
+ }
+ _ => current_clip,
}
-
- // Create a new clip rect.
- //
- // FIXME(#2795): Get the real container size.
- let physical_rect = self.border_box.to_physical(self.style.writing_mode, Size2D::zero());
- current_clip.intersect_rect(&Rect(physical_rect.origin + *flow_origin, physical_rect.size))
}
fn build_display_list_for_text_fragment(&self,
display_list: &mut DisplayList,
text_fragment: &ScannedTextFragmentInfo,
text_color: RGBA,
- flow_origin: &Point2D<Au>,
- offset: &Point2D<Au>,
+ stacking_relative_content_box: &Rect<Au>,
clip: &ClippingRegion) {
// Determine the orientation and cursor to use.
let (orientation, cursor) = if self.style.writing_mode.is_vertical() {
@@ -955,29 +928,16 @@ impl FragmentDisplayListBuilding for Fragment {
//
// FIXME(pcwalton): Get the real container size.
let container_size = Size2D::zero();
- let content_box = self.content_box();
let metrics = &text_fragment.run.font_metrics;
- let baseline_origin = {
- let mut content_box_start = content_box.start;
- content_box_start.b = content_box_start.b + metrics.ascent;
- content_box_start.to_physical(self.style.writing_mode, container_size) + *flow_origin +
- *offset
- };
- let stacking_relative_flow_origin = if self.establishes_stacking_context() {
- ZERO_POINT
- } else {
- *flow_origin
- };
- let rect_to_absolute = |writing_mode: WritingMode, logical_rect: LogicalRect<Au>| {
- let physical_rect = logical_rect.to_physical(writing_mode, container_size);
- Rect(physical_rect.origin + stacking_relative_flow_origin, physical_rect.size)
- };
- let content_rect = rect_to_absolute(self.style.writing_mode,
- content_box).translate(offset);
+ let baseline_origin = stacking_relative_content_box.origin +
+ LogicalPoint::new(self.style.writing_mode,
+ Au(0),
+ metrics.ascent).to_physical(self.style.writing_mode,
+ container_size);
// Create the text display item.
display_list.content.push_back(DisplayItem::TextClass(box TextDisplayItem {
- base: BaseDisplayItem::new(content_rect,
+ base: BaseDisplayItem::new(*stacking_relative_content_box,
DisplayItemMetadata::new(self.node, self.style(), cursor),
(*clip).clone()),
text_run: text_fragment.run.clone(),
@@ -989,63 +949,55 @@ impl FragmentDisplayListBuilding for Fragment {
// Create display items for text decorations.
let text_decorations = self.style().get_inheritedtext()._servo_text_decorations_in_effect;
- if let Some(underline_color) = text_decorations.underline {
- let mut rect = content_box.clone();
- rect.start.b = rect.start.b + metrics.ascent - metrics.underline_offset;
- rect.size.block = metrics.underline_size;
+ let stacking_relative_content_box =
+ LogicalRect::from_physical(self.style.writing_mode,
+ *stacking_relative_content_box,
+ container_size);
+ if let Some(ref underline_color) = text_decorations.underline {
+ let mut stacking_relative_box = stacking_relative_content_box;
+ stacking_relative_box.start.b = stacking_relative_content_box.start.b +
+ metrics.ascent - metrics.underline_offset;
+ stacking_relative_box.size.block = metrics.underline_size;
self.build_display_list_for_text_decoration(display_list,
underline_color,
- flow_origin,
- clip,
- &rect,
- offset)
+ &stacking_relative_box,
+ clip)
}
- if let Some(overline_color) = text_decorations.overline {
- let mut rect = content_box.clone();
- rect.size.block = metrics.underline_size;
+ if let Some(ref overline_color) = text_decorations.overline {
+ let mut stacking_relative_box = stacking_relative_content_box;
+ stacking_relative_box.size.block = metrics.underline_size;
self.build_display_list_for_text_decoration(display_list,
overline_color,
- flow_origin,
- clip,
- &rect,
- offset)
+ &stacking_relative_box,
+ clip)
}
- if let Some(line_through_color) = text_decorations.line_through {
- let mut rect = content_box.clone();
- rect.start.b = rect.start.b + metrics.ascent - metrics.strikeout_offset;
- rect.size.block = metrics.strikeout_size;
+ if let Some(ref line_through_color) = text_decorations.line_through {
+ let mut stacking_relative_box = stacking_relative_content_box;
+ stacking_relative_box.start.b = stacking_relative_box.start.b + metrics.ascent -
+ metrics.strikeout_offset;
+ stacking_relative_box.size.block = metrics.strikeout_size;
self.build_display_list_for_text_decoration(display_list,
line_through_color,
- flow_origin,
- clip,
- &rect,
- offset)
+ &stacking_relative_box,
+ clip)
}
}
fn build_display_list_for_text_decoration(&self,
display_list: &mut DisplayList,
- color: RGBA,
- flow_origin: &Point2D<Au>,
- clip: &ClippingRegion,
- logical_bounds: &LogicalRect<Au>,
- offset: &Point2D<Au>) {
- // FIXME(pcwalton): Get the real container size.
+ color: &RGBA,
+ stacking_relative_box: &LogicalRect<Au>,
+ clip: &ClippingRegion) {
+ // FIXME(pcwalton, #2795): Get the real container size.
let container_size = Size2D::zero();
- let stacking_relative_flow_origin = if self.establishes_stacking_context() {
- ZERO_POINT
- } else {
- *flow_origin
- };
- let physical_rect = logical_bounds.to_physical(self.style.writing_mode, container_size);
+ let stacking_relative_box = stacking_relative_box.to_physical(self.style.writing_mode,
+ container_size);
- let bounds = Rect(physical_rect.origin + stacking_relative_flow_origin,
- physical_rect.size).translate(offset);
let metadata = DisplayItemMetadata::new(self.node, &*self.style, DefaultCursor);
display_list.content.push_back(DisplayItem::SolidColorClass(box SolidColorDisplayItem {
- base: BaseDisplayItem::new(bounds, metadata, (*clip).clone()),
+ base: BaseDisplayItem::new(stacking_relative_box, metadata, (*clip).clone()),
color: color.to_gfx_color(),
}))
}
@@ -1081,14 +1033,16 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
layout_context: &LayoutContext,
background_border_level: BackgroundAndBorderLevel) {
// Add the box that starts the block context.
- let stacking_relative_fragment_origin =
- self.base.stacking_relative_position_of_child_fragment(&self.fragment);
self.fragment.build_display_list(display_list,
layout_context,
- stacking_relative_fragment_origin,
+ &self.base.stacking_relative_position,
+ &self.base
+ .absolute_position_info
+ .relative_containing_block_size,
background_border_level,
&self.base.clip);
+ // Add children.
for kid in self.base.children.iter_mut() {
flow::mut_base(kid).display_list_building_result.add_to(display_list);
}
@@ -1180,19 +1134,70 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
display_list: Box<DisplayList>,
layer: Option<Arc<PaintLayer>>)
-> Arc<StackingContext> {
- let size = self.base.position.size.to_physical(self.base.writing_mode);
- let bounds = Rect(self.base.stacking_relative_position, size);
- let z_index = self.fragment.style().get_box().z_index.number_or_zero();
- let opacity = self.fragment.style().get_effects().opacity as f32;
+ debug_assert!(self.fragment.establishes_stacking_context());
+ let border_box = self.fragment
+ .stacking_relative_border_box(&self.base.stacking_relative_position,
+ &self.base
+ .absolute_position_info
+ .relative_containing_block_size,
+ CoordinateSystem::Parent);
+
+ // FIXME(pcwalton): Is this vertical-writing-direction-safe?
+ let margin = self.fragment.margin.to_physical(self.base.writing_mode);
+ let overflow = self.base.overflow.translate(&-Point2D(margin.left, Au(0)));
+
Arc::new(StackingContext::new(display_list,
- &bounds,
- &self.base.overflow,
- z_index,
- opacity,
+ &border_box,
+ &overflow,
+ self.fragment.style().get_box().z_index.number_or_zero(),
+ self.fragment.style().get_effects().opacity as f32,
layer))
}
}
+pub trait InlineFlowDisplayListBuilding {
+ fn build_display_list_for_inline(&mut self, layout_context: &LayoutContext);
+}
+
+impl InlineFlowDisplayListBuilding for InlineFlow {
+ fn build_display_list_for_inline(&mut self, layout_context: &LayoutContext) {
+ // TODO(#228): Once we form lines and have their cached bounds, we can be smarter and
+ // not recurse on a line if nothing in it can intersect the dirty region.
+ debug!("Flow: building display list for {:u} inline fragments", self.fragments.len());
+
+ let mut display_list = box DisplayList::new();
+ for fragment in self.fragments.fragments.iter_mut() {
+ fragment.build_display_list(&mut *display_list,
+ layout_context,
+ &self.base.stacking_relative_position,
+ &self.base
+ .absolute_position_info
+ .relative_containing_block_size,
+ BackgroundAndBorderLevel::Content,
+ &self.base.clip);
+ match fragment.specific {
+ SpecificFragmentInfo::InlineBlock(ref mut block_flow) => {
+ let block_flow = block_flow.flow_ref.deref_mut();
+ flow::mut_base(block_flow).display_list_building_result
+ .add_to(&mut *display_list)
+ }
+ SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut block_flow) => {
+ let block_flow = block_flow.flow_ref.deref_mut();
+ flow::mut_base(block_flow).display_list_building_result
+ .add_to(&mut *display_list)
+ }
+ _ => {}
+ }
+ }
+
+ self.base.display_list_building_result = DisplayListBuildingResult::Normal(display_list);
+
+ if opts::get().validate_display_list_geometry {
+ self.base.validate_display_list_geometry();
+ }
+ }
+}
+
pub trait ListItemFlowDisplayListBuilding {
fn build_display_list_for_list_item(&mut self,
display_list: Box<DisplayList>,
@@ -1204,17 +1209,16 @@ impl ListItemFlowDisplayListBuilding for ListItemFlow {
mut display_list: Box<DisplayList>,
layout_context: &LayoutContext) {
// Draw the marker, if applicable.
- match self.marker {
- None => {}
- Some(ref mut marker) => {
- let stacking_relative_fragment_origin =
- self.block_flow.base.stacking_relative_position_of_child_fragment(marker);
- marker.build_display_list(&mut *display_list,
- layout_context,
- stacking_relative_fragment_origin,
- BackgroundAndBorderLevel::Content,
- &self.block_flow.base.clip);
- }
+ if let Some(ref mut marker) = self.marker {
+ marker.build_display_list(&mut *display_list,
+ layout_context,
+ &self.block_flow.base.stacking_relative_position,
+ &self.block_flow
+ .base
+ .absolute_position_info
+ .relative_containing_block_size,
+ BackgroundAndBorderLevel::Content,
+ &self.block_flow.base.clip);
}
// Draw the rest of the block.
@@ -1292,3 +1296,4 @@ impl StackingContextConstruction for DisplayList {
}
}
}
+
diff --git a/components/layout/flow.rs b/components/layout/flow.rs
index f20d5a0c128..d252a93269b 100644
--- a/components/layout/flow.rs
+++ b/components/layout/flow.rs
@@ -32,7 +32,7 @@ use display_list_builder::DisplayListBuildingResult;
use floats::Floats;
use flow_list::{FlowList, FlowListIterator, MutFlowListIterator};
use flow_ref::FlowRef;
-use fragment::{Fragment, FragmentOverflowIterator, SpecificFragmentInfo};
+use fragment::{Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo};
use incremental::{RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW, RestyleDamage};
use inline::InlineFlow;
use model::{CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo};
@@ -223,8 +223,10 @@ pub trait Flow: fmt::Show + ToString + Sync {
/// Returns the union of all overflow rects of all of this flow's fragments.
fn compute_overflow(&self) -> Rect<Au>;
- /// Iterates through overflow rects of all of this flow's fragments.
- fn iterate_through_fragment_overflow(&self, iterator: &mut FragmentOverflowIterator);
+ /// Iterates through border boxes of all of this flow's fragments.
+ fn iterate_through_fragment_border_boxes(&self,
+ iterator: &mut FragmentBorderBoxIterator,
+ stacking_context_position: &Point2D<Au>);
fn compute_collapsible_block_start_margin(&mut self,
_layout_context: &mut LayoutContext,
@@ -958,17 +960,6 @@ impl BaseFlow {
}
}
}
-
- /// Returns the position of the given fragment relative to the start of the nearest ancestor
- /// stacking context. The fragment must be a child fragment of this flow.
- pub fn stacking_relative_position_of_child_fragment(&self, fragment: &Fragment)
- -> Point2D<Au> {
- let relative_offset =
- fragment.relative_position(&self
- .absolute_position_info
- .relative_containing_block_size);
- self.stacking_relative_position.add_size(&relative_offset.to_physical(self.writing_mode))
- }
}
impl<'a> ImmutableFlowUtils for &'a Flow + 'a {
@@ -1065,14 +1056,14 @@ impl<'a> ImmutableFlowUtils for &'a Flow + 'a {
let flow = match self.class() {
FlowClass::Table | FlowClass::TableRowGroup => {
let fragment =
- Fragment::new_anonymous_table_fragment(node,
- SpecificFragmentInfo::TableRow);
+ Fragment::new_anonymous_from_specific_info(node,
+ SpecificFragmentInfo::TableRow);
box TableRowFlow::from_node_and_fragment(node, fragment) as Box<Flow>
},
FlowClass::TableRow => {
let fragment =
- Fragment::new_anonymous_table_fragment(node,
- SpecificFragmentInfo::TableCell);
+ Fragment::new_anonymous_from_specific_info(node,
+ SpecificFragmentInfo::TableCell);
let hide = node.style().get_inheritedtable().empty_cells == empty_cells::hide;
box TableCellFlow::from_node_fragment_and_visibility_flag(node, fragment, !hide) as
Box<Flow>
diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs
index c66087364ed..cfc2ab8b1a5 100644
--- a/components/layout/fragment.rs
+++ b/components/layout/fragment.rs
@@ -31,8 +31,7 @@ use serialize::{Encodable, Encoder};
use servo_msg::constellation_msg::{PipelineId, SubpageId};
use servo_net::image::holder::ImageHolder;
use servo_net::local_image_cache::LocalImageCache;
-use servo_util::geometry::Au;
-use servo_util::geometry;
+use servo_util::geometry::{mod, Au, ZERO_POINT};
use servo_util::logical_geometry::{LogicalRect, LogicalSize, LogicalMargin};
use servo_util::range::*;
use servo_util::smallvec::SmallVec;
@@ -62,8 +61,8 @@ use url::Url;
/// positioned as if it were a block fragment, but its children are positioned according to
/// inline flow.
///
-/// A `SpecificFragmentInfo::Generic` is an empty fragment that contributes only borders, margins, padding, and
-/// backgrounds. It is analogous to a CSS nonreplaced content box.
+/// A `SpecificFragmentInfo::Generic` is an empty fragment that contributes only borders, margins,
+/// padding, and backgrounds. It is analogous to a CSS nonreplaced content box.
///
/// 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.
@@ -83,8 +82,10 @@ pub struct Fragment {
/// The CSS style of this fragment.
pub style: Arc<ComputedValues>,
- /// The position of this fragment relative to its owning flow.
- /// The size includes padding and border, but not margin.
+ /// The position of this fragment relative to its owning flow. The size includes padding and
+ /// border, but not margin.
+ ///
+ /// NB: This does not account for relative positioning.
pub border_box: LogicalRect<Au>,
/// The sum of border and padding; i.e. the distance from the edge of the border box to the
@@ -520,10 +521,28 @@ impl Fragment {
}
}
+ /// Constructs a new `Fragment` instance for an anonymous object.
+ pub fn new_anonymous(constructor: &mut FlowConstructor, node: &ThreadSafeLayoutNode)
+ -> Fragment {
+ let node_style = cascade_anonymous(&**node.style());
+ let writing_mode = node_style.writing_mode;
+ Fragment {
+ node: OpaqueNodeMethods::from_thread_safe_layout_node(node),
+ style: Arc::new(node_style),
+ restyle_damage: node.restyle_damage(),
+ border_box: LogicalRect::zero(writing_mode),
+ border_padding: LogicalMargin::zero(writing_mode),
+ margin: LogicalMargin::zero(writing_mode),
+ specific: constructor.build_specific_fragment_info_for_node(node),
+ inline_context: None,
+ debug_id: layout_debug::generate_unique_debug_id(),
+ }
+ }
+
/// Constructs a new `Fragment` instance for an anonymous table object.
- pub fn new_anonymous_table_fragment(node: &ThreadSafeLayoutNode,
- specific: SpecificFragmentInfo)
- -> Fragment {
+ pub fn new_anonymous_from_specific_info(node: &ThreadSafeLayoutNode,
+ specific: SpecificFragmentInfo)
+ -> Fragment {
// CSS 2.1 § 17.2.1 This is for non-inherited properties on anonymous table fragments
// example:
//
@@ -1508,10 +1527,17 @@ impl Fragment {
/// because the corresponding table flow is the primary fragment.
pub fn is_primary_fragment(&self) -> bool {
match self.specific {
- SpecificFragmentInfo::InlineBlock(_) | SpecificFragmentInfo::InlineAbsoluteHypothetical(_) |
+ SpecificFragmentInfo::InlineBlock(_) |
+ SpecificFragmentInfo::InlineAbsoluteHypothetical(_) |
SpecificFragmentInfo::TableWrapper => false,
- SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::ScannedText(_) |
- SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell | SpecificFragmentInfo::TableColumn(_) | SpecificFragmentInfo::TableRow |
+ SpecificFragmentInfo::Generic |
+ SpecificFragmentInfo::Iframe(_) |
+ SpecificFragmentInfo::Image(_) |
+ SpecificFragmentInfo::ScannedText(_) |
+ SpecificFragmentInfo::Table |
+ SpecificFragmentInfo::TableCell |
+ SpecificFragmentInfo::TableColumn(_) |
+ SpecificFragmentInfo::TableRow |
SpecificFragmentInfo::UnscannedText(_) => true,
}
}
@@ -1540,15 +1566,48 @@ impl Fragment {
self.style = (*new_style).clone()
}
- /// Given the stacking-context-relative position of the containing flow, returns the boundaries
- /// of this fragment relative to the parent stacking context.
- pub fn stacking_relative_bounds(&self, stacking_relative_flow_origin: &Point2D<Au>)
- -> Rect<Au> {
- // FIXME(#2795): Get the real container size
+ /// Given the stacking-context-relative position of the containing flow, returns the border box
+ /// of this fragment relative to the parent stacking context. This takes `position: relative`
+ /// into account.
+ ///
+ /// If `coordinate_system` is `Parent`, this returns the border box in the parent stacking
+ /// context's coordinate system. Otherwise, if `coordinate_system` is `Self` and this fragment
+ /// establishes a stacking context itself, this returns a border box anchored at (0, 0). (If
+ /// this fragment does not establish a stacking context, then it always belongs to its parent
+ /// stacking context and thus `coordinate_system` is ignored.)
+ ///
+ /// This is the method you should use for display list construction as well as
+ /// `getBoundingClientRect()` and so forth.
+ pub fn stacking_relative_border_box(&self,
+ stacking_relative_flow_origin: &Point2D<Au>,
+ relative_containing_block_size: &LogicalSize<Au>,
+ coordinate_system: CoordinateSystem)
+ -> Rect<Au> {
+ // FIXME(pcwalton, #2795): Get the real container size.
let container_size = Size2D::zero();
- self.border_box
- .to_physical(self.style.writing_mode, container_size)
- .translate(stacking_relative_flow_origin)
+ let border_box = self.border_box.to_physical(self.style.writing_mode, container_size);
+ if coordinate_system == CoordinateSystem::Self && self.establishes_stacking_context() {
+ return Rect(ZERO_POINT, border_box.size)
+ }
+
+ // FIXME(pcwalton): This can double-count relative position sometimes for inlines (e.g.
+ // `<div style="position:relative">x</div>`, because the `position:relative` trickles down
+ // to the inline flow. Possibly we should extend the notion of "primary fragment" to fix
+ // this.
+ let relative_position = self.relative_position(relative_containing_block_size);
+ border_box.translate_by_size(&relative_position.to_physical(self.style.writing_mode))
+ .translate(stacking_relative_flow_origin)
+ }
+
+ /// Given the stacking-context-relative border box, returns the stacking-context-relative
+ /// content box.
+ pub fn stacking_relative_content_box(&self, stacking_relative_border_box: &Rect<Au>)
+ -> Rect<Au> {
+ let border_padding = self.border_padding.to_physical(self.style.writing_mode);
+ Rect(Point2D(stacking_relative_border_box.origin.x + border_padding.left,
+ stacking_relative_border_box.origin.y + border_padding.top),
+ Size2D(stacking_relative_border_box.size.width - border_padding.horizontal(),
+ stacking_relative_border_box.size.height - border_padding.vertical()))
}
/// Returns true if this fragment establishes a new stacking context and false otherwise.
@@ -1637,13 +1696,23 @@ bitflags! {
}
}
-/// A top-down fragment overflow region iteration handler.
-pub trait FragmentOverflowIterator {
+/// A top-down fragment border box iteration handler.
+pub trait FragmentBorderBoxIterator {
/// The operation to perform.
- fn process(&mut self, fragment: &Fragment, overflow: Rect<Au>);
+ fn process(&mut self, fragment: &Fragment, overflow: &Rect<Au>);
/// Returns true if this fragment must be processed in-order. If this returns false,
/// we skip the operation for this fragment, but continue processing siblings.
fn should_process(&mut self, fragment: &Fragment) -> bool;
}
+/// The coordinate system used in `stacking_relative_border_box()`. See the documentation of that
+/// method for details.
+#[deriving(Clone, PartialEq, Show)]
+pub enum CoordinateSystem {
+ /// The border box returned is relative to the fragment's parent stacking context.
+ Parent,
+ /// The border box returned is relative to the fragment's own stacking context, if applicable.
+ Self,
+}
+
diff --git a/components/layout/inline.rs b/components/layout/inline.rs
index f8a19708d1e..0a2234bfa8b 100644
--- a/components/layout/inline.rs
+++ b/components/layout/inline.rs
@@ -6,13 +6,13 @@
use css::node_style::StyledNode;
use context::LayoutContext;
-use display_list_builder::{BackgroundAndBorderLevel, DisplayListBuildingResult, FragmentDisplayListBuilding};
+use display_list_builder::{FragmentDisplayListBuilding, InlineFlowDisplayListBuilding};
use floats::{FloatKind, Floats, PlacementInfo};
use flow::{BaseFlow, FlowClass, Flow, MutableFlowUtils, ForceNonfloatedFlag};
use flow::{IS_ABSOLUTELY_POSITIONED};
use flow;
-use fragment::{Fragment, SpecificFragmentInfo};
-use fragment::{FragmentOverflowIterator, ScannedTextFragmentInfo};
+use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, ScannedTextFragmentInfo};
+use fragment::{SpecificFragmentInfo};
use fragment::SplitInfo;
use incremental::{REFLOW, REFLOW_OUT_OF_FLOW};
use layout_debug;
@@ -20,16 +20,14 @@ use model::IntrinsicISizesContribution;
use text;
use collections::{RingBuf};
-use geom::{Rect, Size2D};
-use gfx::display_list::DisplayList;
+use geom::{Point2D, Rect};
use gfx::font::FontMetrics;
use gfx::font_context::FontContext;
use gfx::text::glyph::CharIndex;
+use servo_util::arc_ptr_eq;
use servo_util::geometry::{Au, ZERO_RECT};
use servo_util::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
-use servo_util::opts;
use servo_util::range::{Range, RangeIndex};
-use servo_util::arc_ptr_eq;
use std::cmp::max;
use std::fmt;
use std::mem;
@@ -1186,44 +1184,29 @@ impl Flow for InlineFlow {
fn compute_absolute_position(&mut self) {
for fragment in self.fragments.fragments.iter_mut() {
- let stacking_relative_position = match fragment.specific {
+ let stacking_relative_border_box =
+ fragment.stacking_relative_border_box(&self.base.stacking_relative_position,
+ &self.base
+ .absolute_position_info
+ .relative_containing_block_size,
+ CoordinateSystem::Self);
+ let clip = fragment.clipping_region_for_children(&self.base.clip,
+ &stacking_relative_border_box);
+ match fragment.specific {
SpecificFragmentInfo::InlineBlock(ref mut info) => {
+ flow::mut_base(info.flow_ref.deref_mut()).clip = clip;
let block_flow = info.flow_ref.as_block();
block_flow.base.absolute_position_info = self.base.absolute_position_info;
-
- // FIXME(#2795): Get the real container size
- let container_size = Size2D::zero();
block_flow.base.stacking_relative_position =
- self.base.stacking_relative_position +
- fragment.border_box.start.to_physical(self.base.writing_mode,
- container_size);
- block_flow.base.stacking_relative_position
+ stacking_relative_border_box.origin;
}
SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut info) => {
+ flow::mut_base(info.flow_ref.deref_mut()).clip = clip;
let block_flow = info.flow_ref.as_block();
block_flow.base.absolute_position_info = self.base.absolute_position_info;
-
- // FIXME(#2795): Get the real container size
- let container_size = Size2D::zero();
block_flow.base.stacking_relative_position =
- self.base.stacking_relative_position +
- fragment.border_box.start.to_physical(self.base.writing_mode,
- container_size);
- block_flow.base.stacking_relative_position
-
- }
- _ => continue,
- };
-
- let clip = fragment.clipping_region_for_children(&self.base.clip,
- &stacking_relative_position);
+ stacking_relative_border_box.origin
- match fragment.specific {
- SpecificFragmentInfo::InlineBlock(ref mut info) => {
- flow::mut_base(info.flow_ref.deref_mut()).clip = clip
- }
- SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut info) => {
- flow::mut_base(info.flow_ref.deref_mut()).clip = clip
}
_ => {}
}
@@ -1235,38 +1218,7 @@ impl Flow for InlineFlow {
fn update_late_computed_block_position_if_necessary(&mut self, _: Au) {}
fn build_display_list(&mut self, layout_context: &LayoutContext) {
- // TODO(#228): Once we form lines and have their cached bounds, we can be smarter and
- // not recurse on a line if nothing in it can intersect the dirty region.
- debug!("Flow: building display list for {} inline fragments", self.fragments.len());
-
- let mut display_list = box DisplayList::new();
- for fragment in self.fragments.fragments.iter_mut() {
- let fragment_origin = self.base.stacking_relative_position_of_child_fragment(fragment);
- fragment.build_display_list(&mut *display_list,
- layout_context,
- fragment_origin,
- BackgroundAndBorderLevel::Content,
- &self.base.clip);
- match fragment.specific {
- SpecificFragmentInfo::InlineBlock(ref mut block_flow) => {
- let block_flow = block_flow.flow_ref.deref_mut();
- flow::mut_base(block_flow).display_list_building_result
- .add_to(&mut *display_list)
- }
- SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut block_flow) => {
- let block_flow = block_flow.flow_ref.deref_mut();
- flow::mut_base(block_flow).display_list_building_result
- .add_to(&mut *display_list)
- }
- _ => {}
- }
- }
-
- self.base.display_list_building_result = DisplayListBuildingResult::Normal(display_list);
-
- if opts::get().validate_display_list_geometry {
- self.base.validate_display_list_geometry();
- }
+ self.build_display_list_for_inline(layout_context)
}
fn repair_style(&mut self, _: &Arc<ComputedValues>) {}
@@ -1279,13 +1231,23 @@ impl Flow for InlineFlow {
overflow
}
- fn iterate_through_fragment_overflow(&self, iterator: &mut FragmentOverflowIterator) {
+ fn iterate_through_fragment_border_boxes(&self,
+ iterator: &mut FragmentBorderBoxIterator,
+ stacking_context_position: &Point2D<Au>) {
+ // FIXME(#2795): Get the real container size.
for fragment in self.fragments.fragments.iter() {
- if iterator.should_process(fragment) {
- let fragment_origin =
- self.base.stacking_relative_position_of_child_fragment(fragment);
- iterator.process(fragment, fragment.stacking_relative_bounds(&fragment_origin));
+ if !iterator.should_process(fragment) {
+ continue
}
+
+ let stacking_relative_position = &self.base.stacking_relative_position;
+ let relative_containing_block_size =
+ &self.base.absolute_position_info.relative_containing_block_size;
+ iterator.process(fragment,
+ &fragment.stacking_relative_border_box(stacking_relative_position,
+ relative_containing_block_size,
+ CoordinateSystem::Parent)
+ .translate(stacking_context_position))
}
}
}
diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs
index 22e00904c75..3309ff9c28b 100644
--- a/components/layout/layout_task.rs
+++ b/components/layout/layout_task.rs
@@ -10,7 +10,7 @@ use construct::ConstructionResult;
use context::SharedLayoutContext;
use flow::{mod, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils};
use flow_ref::FlowRef;
-use fragment::{Fragment, FragmentOverflowIterator};
+use fragment::{Fragment, FragmentBorderBoxIterator};
use incremental::{LayoutDamageComputation, REFLOW, REFLOW_ENTIRE_DOCUMENT, REPAINT};
use layout_debug;
use parallel::{mod, UnsafeFlow};
@@ -604,8 +604,8 @@ impl LayoutTask {
// FIXME(pcwalton): This has not been updated to handle the stacking context relative
// stuff. So the position is wrong in most cases.
let requested_node: OpaqueNode = OpaqueNodeMethods::from_script_node(requested_node);
- let mut iterator = UnioningFragmentOverflowIterator::new(requested_node);
- sequential::iterate_through_flow_tree_fragment_bounds(layout_root, &mut iterator);
+ let mut iterator = UnioningFragmentBorderBoxIterator::new(requested_node);
+ sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root, &mut iterator);
rw_data.content_box_response = iterator.rect;
}
@@ -616,8 +616,8 @@ impl LayoutTask {
// FIXME(pcwalton): This has not been updated to handle the stacking context relative
// stuff. So the position is wrong in most cases.
let requested_node: OpaqueNode = OpaqueNodeMethods::from_script_node(requested_node);
- let mut iterator = CollectingFragmentOverflowIterator::new(requested_node);
- sequential::iterate_through_flow_tree_fragment_bounds(layout_root, &mut iterator);
+ let mut iterator = CollectingFragmentBorderBoxIterator::new(requested_node);
+ sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root, &mut iterator);
rw_data.content_boxes_response = iterator.rects;
}
@@ -1017,26 +1017,26 @@ impl LayoutRPC for LayoutRPCImpl {
}
}
-struct UnioningFragmentOverflowIterator {
+struct UnioningFragmentBorderBoxIterator {
node_address: OpaqueNode,
rect: Rect<Au>,
}
-impl UnioningFragmentOverflowIterator {
- fn new(node_address: OpaqueNode) -> UnioningFragmentOverflowIterator {
- UnioningFragmentOverflowIterator {
+impl UnioningFragmentBorderBoxIterator {
+ fn new(node_address: OpaqueNode) -> UnioningFragmentBorderBoxIterator {
+ UnioningFragmentBorderBoxIterator {
node_address: node_address,
rect: Rect::zero(),
}
}
}
-impl FragmentOverflowIterator for UnioningFragmentOverflowIterator {
- fn process(&mut self, _: &Fragment, bounds: Rect<Au>) {
- if self.rect.is_empty() {
- self.rect = bounds;
+impl FragmentBorderBoxIterator for UnioningFragmentBorderBoxIterator {
+ fn process(&mut self, _: &Fragment, border_box: &Rect<Au>) {
+ self.rect = if self.rect.is_empty() {
+ *border_box
} else {
- self.rect = self.rect.union(&bounds);
+ self.rect.union(border_box)
}
}
@@ -1045,23 +1045,23 @@ impl FragmentOverflowIterator for UnioningFragmentOverflowIterator {
}
}
-struct CollectingFragmentOverflowIterator {
+struct CollectingFragmentBorderBoxIterator {
node_address: OpaqueNode,
rects: Vec<Rect<Au>>,
}
-impl CollectingFragmentOverflowIterator {
- fn new(node_address: OpaqueNode) -> CollectingFragmentOverflowIterator {
- CollectingFragmentOverflowIterator {
+impl CollectingFragmentBorderBoxIterator {
+ fn new(node_address: OpaqueNode) -> CollectingFragmentBorderBoxIterator {
+ CollectingFragmentBorderBoxIterator {
node_address: node_address,
rects: Vec::new(),
}
}
}
-impl FragmentOverflowIterator for CollectingFragmentOverflowIterator {
- fn process(&mut self, _: &Fragment, bounds: Rect<Au>) {
- self.rects.push(bounds);
+impl FragmentBorderBoxIterator for CollectingFragmentBorderBoxIterator {
+ fn process(&mut self, _: &Fragment, border_box: &Rect<Au>) {
+ self.rects.push(*border_box);
}
fn should_process(&mut self, fragment: &Fragment) -> bool {
diff --git a/components/layout/list_item.rs b/components/layout/list_item.rs
index 0d0c71d526c..b13630496c5 100644
--- a/components/layout/list_item.rs
+++ b/components/layout/list_item.rs
@@ -12,10 +12,10 @@ use construct::FlowConstructor;
use context::LayoutContext;
use display_list_builder::ListItemFlowDisplayListBuilding;
use flow::{Flow, FlowClass};
-use fragment::{Fragment, FragmentOverflowIterator};
+use fragment::{Fragment, FragmentBorderBoxIterator};
use wrapper::ThreadSafeLayoutNode;
-use geom::Rect;
+use geom::{Point2D, Rect};
use gfx::display_list::DisplayList;
use servo_util::geometry::Au;
use servo_util::opts;
@@ -116,8 +116,10 @@ impl Flow for ListItemFlow {
self.block_flow.compute_overflow()
}
- fn iterate_through_fragment_overflow(&self, iterator: &mut FragmentOverflowIterator) {
- self.block_flow.iterate_through_fragment_overflow(iterator);
+ fn iterate_through_fragment_border_boxes(&self,
+ iterator: &mut FragmentBorderBoxIterator,
+ stacking_context_position: &Point2D<Au>) {
+ self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position)
}
}
diff --git a/components/layout/sequential.rs b/components/layout/sequential.rs
index 01ba0c098ed..1be77041113 100644
--- a/components/layout/sequential.rs
+++ b/components/layout/sequential.rs
@@ -5,11 +5,10 @@
//! Implements sequential traversals over the DOM and flow trees.
use context::{LayoutContext, SharedLayoutContext};
-use flow::{Flow, MutableFlowUtils, PreorderFlowTraversal, PostorderFlowTraversal};
-use flow;
+use flow::{mod, Flow, ImmutableFlowUtils, MutableFlowUtils, PostorderFlowTraversal};
+use flow::{PreorderFlowTraversal};
use flow_ref::FlowRef;
-use fragment::FragmentOverflowIterator;
-use servo_util::opts;
+use fragment::FragmentBorderBoxIterator;
use traversal::{BubbleISizes, RecalcStyleForNode, ConstructFlows};
use traversal::{AssignBSizesAndStoreOverflow, AssignISizes};
use traversal::{ComputeAbsolutePositions, BuildDisplayList};
@@ -17,6 +16,10 @@ use wrapper::LayoutNode;
use wrapper::{PostorderNodeMutTraversal};
use wrapper::{PreorderDomTraversal, PostorderDomTraversal};
+use geom::point::Point2D;
+use servo_util::geometry::{Au, ZERO_POINT};
+use servo_util::opts;
+
pub fn traverse_dom_preorder(root: LayoutNode,
shared_layout_context: &SharedLayoutContext) {
fn doit(node: LayoutNode, recalc_style: RecalcStyleForNode, construct_flows: ConstructFlows) {
@@ -94,15 +97,25 @@ pub fn build_display_list_for_subtree(root: &mut FlowRef,
doit(root.deref_mut(), compute_absolute_positions, build_display_list);
}
-pub fn iterate_through_flow_tree_fragment_bounds(root: &mut FlowRef,
- iterator: &mut FragmentOverflowIterator) {
- fn doit(flow: &mut Flow, iterator: &mut FragmentOverflowIterator) {
- flow.iterate_through_fragment_overflow(iterator);
+pub fn iterate_through_flow_tree_fragment_border_boxes(root: &mut FlowRef,
+ iterator: &mut FragmentBorderBoxIterator) {
+ fn doit(flow: &mut Flow,
+ iterator: &mut FragmentBorderBoxIterator,
+ stacking_context_position: &Point2D<Au>) {
+ flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position);
for kid in flow::mut_base(flow).child_iter() {
- doit(kid, iterator);
+ let stacking_context_position =
+ if kid.is_block_flow() && kid.as_block().fragment.establishes_stacking_context() {
+ *stacking_context_position + flow::base(kid).stacking_relative_position
+ } else {
+ *stacking_context_position
+ };
+
+ // FIXME(#2795): Get the real container size.
+ doit(kid, iterator, &stacking_context_position);
}
}
- doit(root.deref_mut(), iterator);
+ doit(root.deref_mut(), iterator, &ZERO_POINT);
}
diff --git a/components/layout/table.rs b/components/layout/table.rs
index 81c9f40d43d..e05abd4d67e 100644
--- a/components/layout/table.rs
+++ b/components/layout/table.rs
@@ -13,14 +13,14 @@ use context::LayoutContext;
use floats::FloatKind;
use flow::{mod, Flow, FlowClass, IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS};
use flow::ImmutableFlowUtils;
-use fragment::{Fragment, FragmentOverflowIterator};
+use fragment::{Fragment, FragmentBorderBoxIterator};
use layout_debug;
use model::{IntrinsicISizes, IntrinsicISizesContribution};
use table_row::CellIntrinsicInlineSize;
use table_wrapper::TableLayout;
use wrapper::ThreadSafeLayoutNode;
-use geom::Rect;
+use geom::{Point2D, Rect};
use servo_util::geometry::Au;
use servo_util::logical_geometry::LogicalRect;
use std::cmp::max;
@@ -389,8 +389,10 @@ impl Flow for TableFlow {
self.block_flow.compute_overflow()
}
- fn iterate_through_fragment_overflow(&self, iterator: &mut FragmentOverflowIterator) {
- self.block_flow.iterate_through_fragment_overflow(iterator);
+ fn iterate_through_fragment_border_boxes(&self,
+ iterator: &mut FragmentBorderBoxIterator,
+ stacking_context_position: &Point2D<Au>) {
+ self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position)
}
}
diff --git a/components/layout/table_caption.rs b/components/layout/table_caption.rs
index 4864e49096a..1a77cde7092 100644
--- a/components/layout/table_caption.rs
+++ b/components/layout/table_caption.rs
@@ -10,10 +10,10 @@ use block::BlockFlow;
use construct::FlowConstructor;
use context::LayoutContext;
use flow::{FlowClass, Flow};
-use fragment::FragmentOverflowIterator;
+use fragment::FragmentBorderBoxIterator;
use wrapper::ThreadSafeLayoutNode;
-use geom::Rect;
+use geom::{Point2D, Rect};
use servo_util::geometry::Au;
use std::fmt;
use style::ComputedValues;
@@ -86,8 +86,10 @@ impl Flow for TableCaptionFlow {
self.block_flow.compute_overflow()
}
- fn iterate_through_fragment_overflow(&self, iterator: &mut FragmentOverflowIterator) {
- self.block_flow.iterate_through_fragment_overflow(iterator);
+ fn iterate_through_fragment_border_boxes(&self,
+ iterator: &mut FragmentBorderBoxIterator,
+ stacking_context_position: &Point2D<Au>) {
+ self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position)
}
}
diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs
index 583c328f315..b97a12e143d 100644
--- a/components/layout/table_cell.rs
+++ b/components/layout/table_cell.rs
@@ -9,13 +9,13 @@
use block::{BlockFlow, ISizeAndMarginsComputer, MarginsMayCollapseFlag};
use context::LayoutContext;
use flow::{Flow, FlowClass};
-use fragment::{Fragment, FragmentOverflowIterator};
+use fragment::{Fragment, FragmentBorderBoxIterator};
use model::{MaybeAuto};
use layout_debug;
use table::InternalTable;
use wrapper::ThreadSafeLayoutNode;
-use geom::Rect;
+use geom::{Point2D, Rect};
use servo_util::geometry::Au;
use std::fmt;
use style::{UnsignedIntegerAttribute, ComputedValues};
@@ -167,8 +167,10 @@ impl Flow for TableCellFlow {
self.block_flow.compute_overflow()
}
- fn iterate_through_fragment_overflow(&self, iterator: &mut FragmentOverflowIterator) {
- self.block_flow.iterate_through_fragment_overflow(iterator);
+ fn iterate_through_fragment_border_boxes(&self,
+ iterator: &mut FragmentBorderBoxIterator,
+ stacking_context_position: &Point2D<Au>) {
+ self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position)
}
}
diff --git a/components/layout/table_colgroup.rs b/components/layout/table_colgroup.rs
index 4eb1cae8022..5e7b066d206 100644
--- a/components/layout/table_colgroup.rs
+++ b/components/layout/table_colgroup.rs
@@ -9,11 +9,11 @@
use context::LayoutContext;
use css::node_style::StyledNode;
use flow::{BaseFlow, FlowClass, Flow, ForceNonfloatedFlag};
-use fragment::{Fragment, FragmentOverflowIterator, SpecificFragmentInfo};
+use fragment::{Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo};
use layout_debug;
use wrapper::ThreadSafeLayoutNode;
-use geom::Rect;
+use geom::{Point2D, Rect};
use servo_util::geometry::{Au, ZERO_RECT};
use std::cmp::max;
use std::fmt;
@@ -101,8 +101,9 @@ impl Flow for TableColGroupFlow {
ZERO_RECT
}
- fn iterate_through_fragment_overflow(&self, _: &mut FragmentOverflowIterator) {
- }
+ fn iterate_through_fragment_border_boxes(&self,
+ _: &mut FragmentBorderBoxIterator,
+ _: &Point2D<Au>) {}
}
impl fmt::Show for TableColGroupFlow {
diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs
index d27d7d1ffb4..b3e9e1ae7f6 100644
--- a/components/layout/table_row.rs
+++ b/components/layout/table_row.rs
@@ -12,13 +12,13 @@ use construct::FlowConstructor;
use context::LayoutContext;
use flow::{FlowClass, Flow, ImmutableFlowUtils};
use flow;
-use fragment::{Fragment, FragmentOverflowIterator};
+use fragment::{Fragment, FragmentBorderBoxIterator};
use layout_debug;
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable};
use model::MaybeAuto;
use wrapper::ThreadSafeLayoutNode;
-use geom::Rect;
+use geom::{Point2D, Rect};
use servo_util::geometry::Au;
use std::cmp::max;
use std::fmt;
@@ -320,8 +320,10 @@ impl Flow for TableRowFlow {
self.block_flow.compute_overflow()
}
- fn iterate_through_fragment_overflow(&self, iterator: &mut FragmentOverflowIterator) {
- self.block_flow.iterate_through_fragment_overflow(iterator);
+ fn iterate_through_fragment_border_boxes(&self,
+ iterator: &mut FragmentBorderBoxIterator,
+ stacking_context_position: &Point2D<Au>) {
+ self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position)
}
}
diff --git a/components/layout/table_rowgroup.rs b/components/layout/table_rowgroup.rs
index 5d3673c1612..2c2847565c7 100644
--- a/components/layout/table_rowgroup.rs
+++ b/components/layout/table_rowgroup.rs
@@ -10,12 +10,12 @@ use block::{BlockFlow, ISizeAndMarginsComputer, MarginsMayCollapseFlag};
use construct::FlowConstructor;
use context::LayoutContext;
use flow::{FlowClass, Flow};
-use fragment::{Fragment, FragmentOverflowIterator};
+use fragment::{Fragment, FragmentBorderBoxIterator};
use layout_debug;
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable};
use wrapper::ThreadSafeLayoutNode;
-use geom::Rect;
+use geom::{Point2D, Rect};
use servo_util::geometry::Au;
use std::fmt;
use style::ComputedValues;
@@ -155,8 +155,10 @@ impl Flow for TableRowGroupFlow {
self.block_flow.compute_overflow()
}
- fn iterate_through_fragment_overflow(&self, iterator: &mut FragmentOverflowIterator) {
- self.block_flow.iterate_through_fragment_overflow(iterator);
+ fn iterate_through_fragment_border_boxes(&self,
+ iterator: &mut FragmentBorderBoxIterator,
+ stacking_context_position: &Point2D<Au>) {
+ self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position)
}
}
diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs
index fa8497c46d7..1c68b7fa924 100644
--- a/components/layout/table_wrapper.rs
+++ b/components/layout/table_wrapper.rs
@@ -19,11 +19,11 @@ use context::LayoutContext;
use floats::FloatKind;
use flow::{FlowClass, Flow, ImmutableFlowUtils};
use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS};
-use fragment::{Fragment, FragmentOverflowIterator};
+use fragment::{Fragment, FragmentBorderBoxIterator};
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize};
use wrapper::ThreadSafeLayoutNode;
-use geom::Rect;
+use geom::{Point2D, Rect};
use servo_util::geometry::Au;
use std::cmp::{max, min};
use std::fmt;
@@ -363,8 +363,10 @@ impl Flow for TableWrapperFlow {
self.block_flow.compute_overflow()
}
- fn iterate_through_fragment_overflow(&self, iterator: &mut FragmentOverflowIterator) {
- self.block_flow.iterate_through_fragment_overflow(iterator);
+ fn iterate_through_fragment_border_boxes(&self,
+ iterator: &mut FragmentBorderBoxIterator,
+ stacking_context_position: &Point2D<Au>) {
+ self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position)
}
}