mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
layout: Largely move display list building out to a separate file.
`layout::fragment` and `layout::block` were getting too big.
This commit is contained in:
parent
691e42f7ef
commit
821793351e
13 changed files with 843 additions and 785 deletions
|
@ -29,6 +29,7 @@
|
|||
|
||||
use construct::FlowConstructor;
|
||||
use context::LayoutContext;
|
||||
use display_list_builder::{BlockFlowDisplayListBuilding, FragmentDisplayListBuilding};
|
||||
use floats::{ClearBoth, ClearLeft, ClearRight, FloatKind, FloatLeft, Floats, PlacementInfo};
|
||||
use flow::{BaseFlow, BlockFlowClass, FlowClass, Flow, ImmutableFlowUtils};
|
||||
use flow::{MutableFlowUtils, PreorderFlowTraversal, PostorderFlowTraversal, mut_base};
|
||||
|
@ -40,24 +41,18 @@ use model::{MaybeAuto, NoCollapsibleMargins, Specified, specified, specified_or_
|
|||
use table::ColumnInlineSize;
|
||||
use wrapper::ThreadSafeLayoutNode;
|
||||
|
||||
use collections::dlist::DList;
|
||||
use geom::{Size2D, Point2D, Rect};
|
||||
use gfx::color;
|
||||
use gfx::display_list::{BackgroundAndBorderLevel, BlockLevel, ContentStackingLevel, DisplayList};
|
||||
use gfx::display_list::{FloatStackingLevel, PositionedDescendantStackingLevel};
|
||||
use gfx::display_list::{RootOfStackingContextLevel};
|
||||
use gfx::render_task::RenderLayer;
|
||||
use geom::Size2D;
|
||||
use gfx::display_list::BlockLevel;
|
||||
use serialize::{Encoder, Encodable};
|
||||
use servo_msg::compositor_msg::{FixedPosition, LayerId, Scrollable};
|
||||
use servo_msg::compositor_msg::LayerId;
|
||||
use servo_util::geometry::{Au, MAX_AU, MAX_RECT};
|
||||
use servo_util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize};
|
||||
use servo_util::opts;
|
||||
use std::cmp::{max, min};
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
use style::computed_values::{LPA_Auto, LPA_Length, LPA_Percentage, LPN_Length, LPN_None};
|
||||
use style::computed_values::{LPN_Percentage, LP_Length, LP_Percentage, box_sizing, clear};
|
||||
use style::computed_values::{display, float, overflow, position};
|
||||
use sync::Arc;
|
||||
|
||||
/// Information specific to floated blocks.
|
||||
#[deriving(Clone, Encodable)]
|
||||
|
@ -1070,70 +1065,6 @@ impl BlockFlow {
|
|||
self.base.position = self.base.position.translate(&float_offset).translate(&margin_offset);
|
||||
}
|
||||
|
||||
fn build_display_list_block_common(&mut self,
|
||||
layout_context: &LayoutContext,
|
||||
background_border_level: BackgroundAndBorderLevel) {
|
||||
let relative_offset =
|
||||
self.fragment.relative_position(&self.base
|
||||
.absolute_position_info
|
||||
.relative_containing_block_size);
|
||||
|
||||
// Add the box that starts the block context.
|
||||
let mut display_list = DisplayList::new();
|
||||
self.fragment.build_display_list(&mut display_list,
|
||||
layout_context,
|
||||
self.base.abs_position.add_size(
|
||||
&relative_offset.to_physical(self.base.writing_mode)),
|
||||
background_border_level,
|
||||
&self.base.clip_rect);
|
||||
|
||||
let mut child_layers = DList::new();
|
||||
for kid in self.base.child_iter() {
|
||||
if kid.is_absolutely_positioned() {
|
||||
// All absolute flows will be handled by their containing block.
|
||||
continue
|
||||
}
|
||||
|
||||
display_list.push_all_move(mem::replace(&mut flow::mut_base(kid).display_list,
|
||||
DisplayList::new()));
|
||||
child_layers.append(mem::replace(&mut flow::mut_base(kid).layers, DList::new()))
|
||||
}
|
||||
|
||||
// Process absolute descendant links.
|
||||
for abs_descendant_link in self.base.abs_descendants.iter() {
|
||||
// TODO(pradeep): Send in our absolute position directly.
|
||||
display_list.push_all_move(mem::replace(
|
||||
&mut flow::mut_base(abs_descendant_link).display_list,
|
||||
DisplayList::new()));
|
||||
child_layers.append(mem::replace(&mut flow::mut_base(abs_descendant_link).layers,
|
||||
DList::new()));
|
||||
}
|
||||
|
||||
self.base.display_list = display_list;
|
||||
self.base.layers = child_layers
|
||||
}
|
||||
|
||||
/// Add display items for current block.
|
||||
///
|
||||
/// Set the absolute position for children after doing any offsetting for
|
||||
/// position: relative.
|
||||
pub fn build_display_list_block(&mut self, layout_context: &LayoutContext) {
|
||||
if self.is_float() {
|
||||
// TODO(#2009, pcwalton): This is a pseudo-stacking context. We need to merge `z-index:
|
||||
// auto` kids into the parent stacking context, when that is supported.
|
||||
self.build_display_list_float(layout_context)
|
||||
} else if self.is_absolutely_positioned() {
|
||||
self.build_display_list_abs(layout_context)
|
||||
} else {
|
||||
self.build_display_list_block_common(layout_context, BlockLevel)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_display_list_float(&mut self, layout_context: &LayoutContext) {
|
||||
self.build_display_list_block_common(layout_context, RootOfStackingContextLevel);
|
||||
self.base.display_list = mem::replace(&mut self.base.display_list,
|
||||
DisplayList::new()).flatten(FloatStackingLevel)
|
||||
}
|
||||
|
||||
/// Calculate and set the block-size, offsets, etc. for absolutely positioned flow.
|
||||
///
|
||||
|
@ -1232,43 +1163,6 @@ impl BlockFlow {
|
|||
self.base.position.size.block = block_size;
|
||||
}
|
||||
|
||||
/// Add display items for Absolutely Positioned flow.
|
||||
fn build_display_list_abs(&mut self, layout_context: &LayoutContext) {
|
||||
self.build_display_list_block_common(layout_context, RootOfStackingContextLevel);
|
||||
|
||||
if !self.base.absolute_position_info.layers_needed_for_positioned_flows &&
|
||||
!self.base.flags.needs_layer() {
|
||||
// We didn't need a layer.
|
||||
let z_index = self.fragment.style().get_box().z_index.number_or_zero();
|
||||
let level = PositionedDescendantStackingLevel(z_index);
|
||||
self.base.display_list = mem::replace(&mut self.base.display_list,
|
||||
DisplayList::new()).flatten(level);
|
||||
return
|
||||
}
|
||||
|
||||
// If we got here, then we need a new layer.
|
||||
let layer_rect = self.base.position.union(&self.base.overflow);
|
||||
let size = Size2D(layer_rect.size.inline.to_nearest_px() as uint,
|
||||
layer_rect.size.block.to_nearest_px() as uint);
|
||||
let origin = Point2D(self.base.abs_position.x.to_nearest_px() as uint,
|
||||
self.base.abs_position.y.to_nearest_px() as uint);
|
||||
|
||||
let scroll_policy = if self.is_fixed() {
|
||||
FixedPosition
|
||||
} else {
|
||||
Scrollable
|
||||
};
|
||||
let display_list = mem::replace(&mut self.base.display_list, DisplayList::new());
|
||||
let new_layer = RenderLayer {
|
||||
id: self.layer_id(0),
|
||||
display_list: Arc::new(display_list.flatten(ContentStackingLevel)),
|
||||
position: Rect(origin, size),
|
||||
background_color: color::rgba(1.0, 1.0, 1.0, 0.0),
|
||||
scroll_policy: scroll_policy,
|
||||
};
|
||||
self.base.layers.push(new_layer)
|
||||
}
|
||||
|
||||
/// Return the block-start outer edge of the hypothetical box for an absolute flow.
|
||||
///
|
||||
/// This is wrt its parent flow box.
|
||||
|
@ -1839,6 +1733,22 @@ impl Flow for BlockFlow {
|
|||
self.base.position.start.b = block_position
|
||||
}
|
||||
}
|
||||
|
||||
fn build_display_list(&mut self, layout_context: &LayoutContext) {
|
||||
if self.is_float() {
|
||||
// TODO(#2009, pcwalton): This is a pseudo-stacking context. We need to merge `z-index:
|
||||
// auto` kids into the parent stacking context, when that is supported.
|
||||
self.build_display_list_for_floating_block(layout_context)
|
||||
} else if self.is_absolutely_positioned() {
|
||||
self.build_display_list_for_absolutely_positioned_block(layout_context)
|
||||
} else {
|
||||
self.build_display_list_for_block(layout_context, BlockLevel)
|
||||
}
|
||||
|
||||
if opts::get().validate_display_list_geometry {
|
||||
self.base.validate_display_list_geometry();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for BlockFlow {
|
||||
|
@ -2562,3 +2472,4 @@ fn propagate_column_inline_sizes_to_child(kid: &mut Flow,
|
|||
*inline_start_margin_edge = *inline_start_margin_edge + inline_size
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue