diff options
author | Patrick Walton <pcwalton@mimiga.net> | 2014-12-24 21:40:06 -0600 |
---|---|---|
committer | Patrick Walton <pcwalton@mimiga.net> | 2015-01-04 17:43:05 -0800 |
commit | bf540d590a519cb07d70ee470050e2e4a37ccfc5 (patch) | |
tree | ddca8f26376087d4cd05f8396c3cc860ae776a76 /components/layout/inline.rs | |
parent | 5ea2c6dcfdfc24ce3730f736fcd045a13bcdc5b6 (diff) | |
download | servo-bf540d590a519cb07d70ee470050e2e4a37ccfc5.tar.gz servo-bf540d590a519cb07d70ee470050e2e4a37ccfc5.zip |
layout: Explicitly thread border box dimensions and relative offsets
through display list building.
The old `flow_origin` concept was ill-defined (sometimes the border box
plus the flow origin, sometimes including horizontal margins and
sometimes not, sometimes including relative position and sometimes not),
leading to brittleness and test failures. This commit reworks the logic
to always pass border box origins in during display list building.
Diffstat (limited to 'components/layout/inline.rs')
-rw-r--r-- | components/layout/inline.rs | 106 |
1 files changed, 34 insertions, 72 deletions
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)) } } } |