mirror of
https://github.com/servo/servo.git
synced 2025-07-22 14:53:49 +01:00
Code organization: Move all generic traversal code to layout::traversal
This commit is contained in:
parent
a08bc13df9
commit
d1a37f1ea3
8 changed files with 107 additions and 139 deletions
|
@ -36,9 +36,8 @@ use floats::{ClearType, FloatKind, Floats, PlacementInfo};
|
|||
use flow::{self, BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ForceNonfloatedFlag};
|
||||
use flow::{BLOCK_POSITION_IS_STATIC, CLEARS_LEFT, CLEARS_RIGHT};
|
||||
use flow::{CONTAINS_TEXT_OR_REPLACED_FRAGMENTS, INLINE_POSITION_IS_STATIC};
|
||||
use flow::{FragmentationContext, MARGINS_CANNOT_COLLAPSE, PreorderFlowTraversal};
|
||||
use flow::{ImmutableFlowUtils, LateAbsolutePositionInfo, MutableFlowUtils, OpaqueFlow};
|
||||
use flow::IS_ABSOLUTELY_POSITIONED;
|
||||
use flow::{IS_ABSOLUTELY_POSITIONED, FragmentationContext, MARGINS_CANNOT_COLLAPSE};
|
||||
use flow::{ImmutableFlowUtils, LateAbsolutePositionInfo, OpaqueFlow};
|
||||
use flow_list::FlowList;
|
||||
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow};
|
||||
use fragment::{IS_INLINE_FLEX_ITEM, IS_BLOCK_FLEX_ITEM};
|
||||
|
@ -60,6 +59,7 @@ use style::properties::ComputedValues;
|
|||
use style::servo::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPOSITION};
|
||||
use style::values::computed::{LengthOrPercentageOrNone, LengthOrPercentage};
|
||||
use style::values::computed::LengthOrPercentageOrAuto;
|
||||
use traversal::PreorderFlowTraversal;
|
||||
|
||||
/// Information specific to floated blocks.
|
||||
#[derive(Clone, Serialize)]
|
||||
|
@ -1065,8 +1065,8 @@ impl BlockFlow {
|
|||
// Assign block-sizes for all flows in this absolute flow tree.
|
||||
// This is preorder because the block-size of an absolute flow may depend on
|
||||
// the block-size of its containing block, which may also be an absolute flow.
|
||||
(&mut *self as &mut Flow).traverse_preorder_absolute_flows(
|
||||
&mut AbsoluteAssignBSizesTraversal(layout_context.shared_context()));
|
||||
let assign_abs_b_sizes = AbsoluteAssignBSizesTraversal(layout_context.shared_context());
|
||||
assign_abs_b_sizes.traverse_absolute_flows(&mut *self);
|
||||
}
|
||||
|
||||
// Don't remove the dirty bits yet if we're absolutely-positioned, since our final size
|
||||
|
|
|
@ -535,28 +535,6 @@ pub trait ImmutableFlowUtils {
|
|||
}
|
||||
|
||||
pub trait MutableFlowUtils {
|
||||
// Traversals
|
||||
|
||||
/// Traverses the tree in preorder.
|
||||
fn traverse_preorder<T: PreorderFlowTraversal>(self, traversal: &T);
|
||||
|
||||
/// Traverses the tree in postorder.
|
||||
fn traverse_postorder<T: PostorderFlowTraversal>(self, traversal: &T);
|
||||
|
||||
/// Traverses the tree in-order.
|
||||
fn traverse_inorder<T: InorderFlowTraversal>(self, traversal: &mut T, level: u32);
|
||||
|
||||
/// Traverse the Absolute flow tree in preorder.
|
||||
///
|
||||
/// Traverse all your direct absolute descendants, who will then traverse
|
||||
/// their direct absolute descendants.
|
||||
///
|
||||
/// Return true if the traversal is to continue or false to stop.
|
||||
fn traverse_preorder_absolute_flows<T>(&mut self, traversal: &mut T)
|
||||
where T: PreorderFlowTraversal;
|
||||
|
||||
// Mutators
|
||||
|
||||
/// Calls `repair_style` and `bubble_inline_sizes`. You should use this method instead of
|
||||
/// calling them individually, since there is no reason not to perform both operations.
|
||||
fn repair_style_and_bubble_inline_sizes(self, style: &::ServoArc<ComputedValues>);
|
||||
|
@ -608,42 +586,6 @@ impl FlowClass {
|
|||
}
|
||||
}
|
||||
|
||||
/// A top-down traversal.
|
||||
pub trait PreorderFlowTraversal {
|
||||
/// The operation to perform. Return true to continue or false to stop.
|
||||
fn process(&self, flow: &mut Flow);
|
||||
|
||||
/// Returns true if this node must be processed in-order. If this returns false,
|
||||
/// we skip the operation for this node, but continue processing the descendants.
|
||||
/// This is called *after* parent nodes are visited.
|
||||
fn should_process(&self, _flow: &mut Flow) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// A bottom-up traversal, with a optional in-order pass.
|
||||
pub trait PostorderFlowTraversal {
|
||||
/// The operation to perform. Return true to continue or false to stop.
|
||||
fn process(&self, flow: &mut Flow);
|
||||
|
||||
/// Returns false if this node must be processed in-order. If this returns false, we skip the
|
||||
/// operation for this node, but continue processing the ancestors. This is called *after*
|
||||
/// child nodes are visited.
|
||||
fn should_process(&self, _flow: &mut Flow) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// An in-order (sequential only) traversal.
|
||||
pub trait InorderFlowTraversal {
|
||||
/// The operation to perform. Returns the level of the tree we're at.
|
||||
fn process(&mut self, flow: &mut Flow, level: u32);
|
||||
|
||||
/// Returns true if this node should be processed and false if neither this node nor its
|
||||
/// descendants should be processed.
|
||||
fn should_process_subtree(&mut self, flow: &mut Flow) -> bool;
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
#[doc = "Flags used in flows."]
|
||||
pub flags FlowFlags: u32 {
|
||||
|
@ -1354,41 +1296,6 @@ impl<'a> ImmutableFlowUtils for &'a Flow {
|
|||
}
|
||||
|
||||
impl<'a> MutableFlowUtils for &'a mut Flow {
|
||||
/// Traverses the tree in preorder.
|
||||
fn traverse_preorder<T: PreorderFlowTraversal>(self, traversal: &T) {
|
||||
if traversal.should_process(self) {
|
||||
traversal.process(self);
|
||||
}
|
||||
|
||||
for kid in child_iter_mut(self) {
|
||||
kid.traverse_preorder(traversal);
|
||||
}
|
||||
}
|
||||
|
||||
/// Traverses the tree in postorder.
|
||||
fn traverse_postorder<T: PostorderFlowTraversal>(self, traversal: &T) {
|
||||
for kid in child_iter_mut(self) {
|
||||
kid.traverse_postorder(traversal);
|
||||
}
|
||||
|
||||
if traversal.should_process(self) {
|
||||
traversal.process(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Traverses the tree in-order.
|
||||
fn traverse_inorder<T: InorderFlowTraversal>(self, traversal: &mut T, level: u32) {
|
||||
if !traversal.should_process_subtree(self) {
|
||||
return;
|
||||
}
|
||||
|
||||
traversal.process(self, level);
|
||||
|
||||
for kid in child_iter_mut(self) {
|
||||
kid.traverse_inorder(traversal, level + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/// Calls `repair_style` and `bubble_inline_sizes`. You should use this method instead of
|
||||
/// calling them individually, since there is no reason not to perform both operations.
|
||||
fn repair_style_and_bubble_inline_sizes(self, style: &::ServoArc<ComputedValues>) {
|
||||
|
@ -1396,22 +1303,6 @@ impl<'a> MutableFlowUtils for &'a mut Flow {
|
|||
mut_base(self).update_flags_if_needed(style);
|
||||
self.bubble_inline_sizes();
|
||||
}
|
||||
|
||||
/// Traverse the Absolute flow tree in preorder.
|
||||
///
|
||||
/// Traverse all your direct absolute descendants, who will then traverse
|
||||
/// their direct absolute descendants.
|
||||
///
|
||||
/// Return true if the traversal is to continue or false to stop.
|
||||
fn traverse_preorder_absolute_flows<T>(&mut self, traversal: &mut T)
|
||||
where T: PreorderFlowTraversal {
|
||||
traversal.process(*self);
|
||||
|
||||
let descendant_offset_iter = mut_base(*self).abs_descendants.iter();
|
||||
for ref mut descendant_link in descendant_offset_iter {
|
||||
descendant_link.traverse_preorder_absolute_flows(traversal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MutableOwnedFlowUtils for FlowRef {
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
use context::{LayoutContext, with_thread_local_font_context};
|
||||
use flow::{self, AFFECTS_COUNTERS, Flow, HAS_COUNTER_AFFECTING_CHILDREN, ImmutableFlowUtils};
|
||||
use flow::InorderFlowTraversal;
|
||||
use fragment::{Fragment, GeneratedContentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
|
||||
use gfx::display_list::OpaqueNode;
|
||||
use script_layout_interface::wrapper_traits::PseudoElementType;
|
||||
|
@ -22,6 +21,7 @@ use style::properties::ComputedValues;
|
|||
use style::selector_parser::RestyleDamage;
|
||||
use style::servo::restyle_damage::RESOLVE_GENERATED_CONTENT;
|
||||
use text::TextRunScanner;
|
||||
use traversal::InorderFlowTraversal;
|
||||
|
||||
// Decimal styles per CSS-COUNTER-STYLES § 6.1:
|
||||
static DECIMAL: [char; 10] = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ];
|
||||
|
|
|
@ -12,8 +12,7 @@ use display_list_builder::{DisplayListBuildState, InlineFlowDisplayListBuilding}
|
|||
use euclid::{Point2D, Size2D};
|
||||
use floats::{FloatKind, Floats, PlacementInfo};
|
||||
use flow::{self, BaseFlow, Flow, FlowClass, ForceNonfloatedFlag};
|
||||
use flow::{CONTAINS_TEXT_OR_REPLACED_FRAGMENTS, EarlyAbsolutePositionInfo, MutableFlowUtils};
|
||||
use flow::OpaqueFlow;
|
||||
use flow::{CONTAINS_TEXT_OR_REPLACED_FRAGMENTS, EarlyAbsolutePositionInfo, OpaqueFlow};
|
||||
use flow_ref::FlowRef;
|
||||
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow};
|
||||
use fragment::IS_ELLIPSIS;
|
||||
|
@ -36,6 +35,7 @@ use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
|
|||
use style::properties::{longhands, ComputedValues};
|
||||
use style::servo::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPOSITION, RESOLVE_GENERATED_CONTENT};
|
||||
use text;
|
||||
use traversal::PreorderFlowTraversal;
|
||||
use unicode_bidi as bidi;
|
||||
|
||||
/// `Line`s are represented as offsets into the child list, rather than
|
||||
|
@ -1490,8 +1490,8 @@ impl Flow for InlineFlow {
|
|||
// Assign block-sizes for all flows in this absolute flow tree.
|
||||
// This is preorder because the block-size of an absolute flow may depend on
|
||||
// the block-size of its containing block, which may also be an absolute flow.
|
||||
(&mut *self as &mut Flow).traverse_preorder_absolute_flows(
|
||||
&mut AbsoluteAssignBSizesTraversal(layout_context.shared_context()));
|
||||
let assign_abs_b_sizes = AbsoluteAssignBSizesTraversal(layout_context.shared_context());
|
||||
assign_abs_b_sizes.traverse_absolute_flows(&mut *self);
|
||||
}
|
||||
|
||||
self.base.position.size.block = match self.last_line_containing_real_fragments() {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#![allow(unsafe_code)]
|
||||
|
||||
use context::LayoutContext;
|
||||
use flow::{self, Flow, MutableFlowUtils, PostorderFlowTraversal, PreorderFlowTraversal};
|
||||
use flow::{self, Flow};
|
||||
use flow_ref::FlowRef;
|
||||
use profile_traits::time::{self, TimerMetadata, profile};
|
||||
use rayon;
|
||||
|
@ -18,8 +18,8 @@ use smallvec::SmallVec;
|
|||
use std::mem;
|
||||
use std::sync::atomic::{AtomicIsize, Ordering};
|
||||
use style::dom::UnsafeNode;
|
||||
use traversal::{AssignISizes, BubbleISizes};
|
||||
use traversal::AssignBSizes;
|
||||
use traversal::{AssignBSizes, AssignISizes, BubbleISizes};
|
||||
use traversal::{PostorderFlowTraversal, PreorderFlowTraversal};
|
||||
|
||||
pub use style::parallel::traverse_dom;
|
||||
|
||||
|
@ -195,7 +195,7 @@ pub fn traverse_flow_tree_preorder(
|
|||
queue: &rayon::ThreadPool) {
|
||||
if opts::get().bubble_inline_sizes_separately {
|
||||
let bubble_inline_sizes = BubbleISizes { layout_context: &context };
|
||||
root.traverse_postorder(&bubble_inline_sizes);
|
||||
bubble_inline_sizes.traverse(root);
|
||||
}
|
||||
|
||||
let assign_isize_traversal = &AssignISizes { layout_context: &context };
|
||||
|
|
|
@ -9,21 +9,19 @@ use context::LayoutContext;
|
|||
use display_list_builder::DisplayListBuildState;
|
||||
use euclid::{Point2D, Vector2D};
|
||||
use floats::SpeculatedFloatPlacement;
|
||||
use flow::{self, Flow, ImmutableFlowUtils, MutableFlowUtils};
|
||||
use flow::{PostorderFlowTraversal, PreorderFlowTraversal};
|
||||
use flow::IS_ABSOLUTELY_POSITIONED;
|
||||
use flow::{self, Flow, ImmutableFlowUtils, IS_ABSOLUTELY_POSITIONED};
|
||||
use fragment::{FragmentBorderBoxIterator, CoordinateSystem};
|
||||
use generated_content::ResolveGeneratedContent;
|
||||
use incremental::RelayoutMode;
|
||||
use servo_config::opts;
|
||||
use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, STORE_OVERFLOW};
|
||||
use traversal::{AssignBSizes, AssignISizes, BubbleISizes, BuildDisplayList};
|
||||
use traversal::{InorderFlowTraversal, PostorderFlowTraversal, PreorderFlowTraversal};
|
||||
|
||||
pub use style::sequential::traverse_dom;
|
||||
|
||||
pub fn resolve_generated_content(root: &mut Flow, layout_context: &LayoutContext) {
|
||||
let mut traversal = ResolveGeneratedContent::new(&layout_context);
|
||||
root.traverse_inorder(&mut traversal, 0);
|
||||
ResolveGeneratedContent::new(&layout_context).traverse(root, 0);
|
||||
}
|
||||
|
||||
pub fn traverse_flow_tree_preorder(root: &mut Flow, layout_context: &LayoutContext, relayout_mode: RelayoutMode) {
|
||||
|
@ -56,10 +54,7 @@ pub fn traverse_flow_tree_preorder(root: &mut Flow, layout_context: &LayoutConte
|
|||
let bubble_inline_sizes = BubbleISizes {
|
||||
layout_context: &layout_context,
|
||||
};
|
||||
{
|
||||
let root: &mut Flow = root;
|
||||
root.traverse_postorder(&bubble_inline_sizes);
|
||||
}
|
||||
bubble_inline_sizes.traverse(root);
|
||||
}
|
||||
|
||||
let assign_inline_sizes = AssignISizes {
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
use construct::FlowConstructor;
|
||||
use context::LayoutContext;
|
||||
use display_list_builder::DisplayListBuildState;
|
||||
use flow::{self, PreorderFlowTraversal};
|
||||
use flow::{CAN_BE_FRAGMENTED, Flow, ImmutableFlowUtils, PostorderFlowTraversal};
|
||||
use flow::{self, CAN_BE_FRAGMENTED, Flow, ImmutableFlowUtils};
|
||||
use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode};
|
||||
use servo_config::opts;
|
||||
use style::context::{SharedStyleContext, StyleContext};
|
||||
|
@ -92,6 +91,90 @@ impl<'a, E> DomTraversal<E> for RecalcStyleAndConstructFlows<'a>
|
|||
}
|
||||
}
|
||||
|
||||
/// A top-down traversal.
|
||||
pub trait PreorderFlowTraversal {
|
||||
/// The operation to perform. Return true to continue or false to stop.
|
||||
fn process(&self, flow: &mut Flow);
|
||||
|
||||
/// Returns true if this node must be processed in-order. If this returns false,
|
||||
/// we skip the operation for this node, but continue processing the descendants.
|
||||
/// This is called *after* parent nodes are visited.
|
||||
fn should_process(&self, _flow: &mut Flow) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// Traverses the tree in preorder.
|
||||
fn traverse(&self, flow: &mut Flow) {
|
||||
if self.should_process(flow) {
|
||||
self.process(flow);
|
||||
}
|
||||
for kid in flow::child_iter_mut(flow) {
|
||||
self.traverse(kid);
|
||||
}
|
||||
}
|
||||
|
||||
/// Traverse the Absolute flow tree in preorder.
|
||||
///
|
||||
/// Traverse all your direct absolute descendants, who will then traverse
|
||||
/// their direct absolute descendants.
|
||||
///
|
||||
/// Return true if the traversal is to continue or false to stop.
|
||||
fn traverse_absolute_flows(&self, flow: &mut Flow) {
|
||||
if self.should_process(flow) {
|
||||
self.process(flow);
|
||||
}
|
||||
for descendant_link in flow::mut_base(flow).abs_descendants.iter() {
|
||||
self.traverse_absolute_flows(descendant_link)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A bottom-up traversal, with a optional in-order pass.
|
||||
pub trait PostorderFlowTraversal {
|
||||
/// The operation to perform. Return true to continue or false to stop.
|
||||
fn process(&self, flow: &mut Flow);
|
||||
|
||||
/// Returns false if this node must be processed in-order. If this returns false, we skip the
|
||||
/// operation for this node, but continue processing the ancestors. This is called *after*
|
||||
/// child nodes are visited.
|
||||
fn should_process(&self, _flow: &mut Flow) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// Traverses the tree in postorder.
|
||||
fn traverse(&self, flow: &mut Flow) {
|
||||
for kid in flow::child_iter_mut(flow) {
|
||||
self.traverse(kid);
|
||||
}
|
||||
if self.should_process(flow) {
|
||||
self.process(flow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An in-order (sequential only) traversal.
|
||||
pub trait InorderFlowTraversal {
|
||||
/// The operation to perform. Returns the level of the tree we're at.
|
||||
fn process(&mut self, flow: &mut Flow, level: u32);
|
||||
|
||||
/// Returns true if this node should be processed and false if neither this node nor its
|
||||
/// descendants should be processed.
|
||||
fn should_process_subtree(&mut self, _flow: &mut Flow) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// Traverses the tree in-order.
|
||||
fn traverse(&mut self, flow: &mut Flow, level: u32) {
|
||||
if !self.should_process_subtree(flow) {
|
||||
return;
|
||||
}
|
||||
self.process(flow, level);
|
||||
for kid in flow::child_iter_mut(flow) {
|
||||
self.traverse(kid, level + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A bottom-up, parallelizable traversal.
|
||||
pub trait PostorderNodeMutTraversal<ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> {
|
||||
/// The operation to perform. Return true to continue or false to stop.
|
||||
|
|
|
@ -71,7 +71,7 @@ use layout::context::RegisteredPainter;
|
|||
use layout::context::RegisteredPainters;
|
||||
use layout::context::heap_size_of_persistent_local_context;
|
||||
use layout::display_list_builder::ToGfxColor;
|
||||
use layout::flow::{self, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils};
|
||||
use layout::flow::{self, Flow, ImmutableFlowUtils, MutableOwnedFlowUtils};
|
||||
use layout::flow_ref::FlowRef;
|
||||
use layout::incremental::{LayoutDamageComputation, REFLOW_ENTIRE_DOCUMENT, RelayoutMode};
|
||||
use layout::layout_debug;
|
||||
|
@ -82,7 +82,7 @@ use layout::query::{process_margin_style_query, process_node_overflow_request, p
|
|||
use layout::query::{process_node_geometry_request, process_node_scroll_area_request};
|
||||
use layout::query::{process_node_scroll_root_id_request, process_offset_parent_query};
|
||||
use layout::sequential;
|
||||
use layout::traversal::{ComputeStackingRelativePositions, RecalcStyleAndConstructFlows};
|
||||
use layout::traversal::{ComputeStackingRelativePositions, PreorderFlowTraversal, RecalcStyleAndConstructFlows};
|
||||
use layout::webrender_helpers::WebRenderDisplayListConverter;
|
||||
use layout::wrapper::LayoutNodeLayoutData;
|
||||
use layout_traits::LayoutThreadFactory;
|
||||
|
@ -975,9 +975,8 @@ impl LayoutThread {
|
|||
flow::mut_base(layout_root).clip = data.page_clip_rect;
|
||||
|
||||
if flow::base(layout_root).restyle_damage.contains(REPOSITION) {
|
||||
layout_root.traverse_preorder(&ComputeStackingRelativePositions {
|
||||
layout_context: layout_context
|
||||
});
|
||||
let traversal = ComputeStackingRelativePositions { layout_context: layout_context };
|
||||
traversal.traverse(layout_root);
|
||||
}
|
||||
|
||||
if flow::base(layout_root).restyle_damage.contains(REPAINT) ||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue