mirror of
https://github.com/servo/servo.git
synced 2025-06-19 14:48:59 +01:00
layout: Refactor flow construction to move around large structs less.
5% perf win, and a net loss in lines of code.
This commit is contained in:
parent
48e9b8f752
commit
d34ebf521d
4 changed files with 34 additions and 52 deletions
|
@ -5,12 +5,14 @@
|
||||||
//! CSS block formatting contexts.
|
//! CSS block formatting contexts.
|
||||||
|
|
||||||
use layout::box_::Box;
|
use layout::box_::Box;
|
||||||
|
use layout::construct::FlowConstructor;
|
||||||
use layout::context::LayoutContext;
|
use layout::context::LayoutContext;
|
||||||
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
|
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
|
||||||
|
use layout::float_context::{FloatContext, PlacementInfo, Invalid, FloatType};
|
||||||
use layout::flow::{BaseFlow, BlockFlowClass, FlowClass, Flow, ImmutableFlowUtils};
|
use layout::flow::{BaseFlow, BlockFlowClass, FlowClass, Flow, ImmutableFlowUtils};
|
||||||
use layout::flow;
|
use layout::flow;
|
||||||
use layout::model::{MaybeAuto, Specified, Auto, specified_or_none, specified};
|
use layout::model::{MaybeAuto, Specified, Auto, specified_or_none, specified};
|
||||||
use layout::float_context::{FloatContext, PlacementInfo, Invalid, FloatType};
|
use layout::wrapper::ThreadSafeLayoutNode;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use geom::{Point2D, Rect, SideOffsets2D, Size2D};
|
use geom::{Point2D, Rect, SideOffsets2D, Size2D};
|
||||||
|
@ -66,30 +68,24 @@ pub struct BlockFlow {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockFlow {
|
impl BlockFlow {
|
||||||
pub fn new(base: BaseFlow) -> BlockFlow {
|
pub fn from_node(constructor: &mut FlowConstructor, node: ThreadSafeLayoutNode, is_fixed: bool)
|
||||||
|
-> BlockFlow {
|
||||||
BlockFlow {
|
BlockFlow {
|
||||||
base: base,
|
base: BaseFlow::new(constructor.next_flow_id(), node),
|
||||||
box_: None,
|
box_: Some(Box::new(constructor, node)),
|
||||||
is_root: false,
|
|
||||||
is_fixed: false,
|
|
||||||
float: None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_box(base: BaseFlow, box_: Box, is_fixed: bool) -> BlockFlow {
|
|
||||||
BlockFlow {
|
|
||||||
base: base,
|
|
||||||
box_: Some(box_),
|
|
||||||
is_root: false,
|
is_root: false,
|
||||||
is_fixed: is_fixed,
|
is_fixed: is_fixed,
|
||||||
float: None
|
float: None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn float_from_box(base: BaseFlow, float_type: FloatType, box_: Box) -> BlockFlow {
|
pub fn float_from_node(constructor: &mut FlowConstructor,
|
||||||
|
node: ThreadSafeLayoutNode,
|
||||||
|
float_type: FloatType)
|
||||||
|
-> BlockFlow {
|
||||||
BlockFlow {
|
BlockFlow {
|
||||||
base: base,
|
base: BaseFlow::new(constructor.next_flow_id(), node),
|
||||||
box_: Some(box_),
|
box_: Some(Box::new(constructor, node)),
|
||||||
is_root: false,
|
is_root: false,
|
||||||
is_fixed: false,
|
is_fixed: false,
|
||||||
float: Some(~FloatedBlockInfo::new(float_type))
|
float: Some(~FloatedBlockInfo::new(float_type))
|
||||||
|
|
|
@ -14,7 +14,6 @@ use gfx::display_list::{SolidColorDisplayItem, SolidColorDisplayItemClass, TextD
|
||||||
use gfx::display_list::{TextDisplayItemClass, TextDisplayItemFlags, ClipDisplayItem};
|
use gfx::display_list::{TextDisplayItemClass, TextDisplayItemFlags, ClipDisplayItem};
|
||||||
use gfx::display_list::{ClipDisplayItemClass, DisplayListCollection};
|
use gfx::display_list::{ClipDisplayItemClass, DisplayListCollection};
|
||||||
use gfx::font::FontStyle;
|
use gfx::font::FontStyle;
|
||||||
|
|
||||||
use gfx::text::text_run::TextRun;
|
use gfx::text::text_run::TextRun;
|
||||||
use servo_msg::constellation_msg::{FrameRectMsg, PipelineId, SubpageId};
|
use servo_msg::constellation_msg::{FrameRectMsg, PipelineId, SubpageId};
|
||||||
use servo_net::image::holder::ImageHolder;
|
use servo_net::image::holder::ImageHolder;
|
||||||
|
@ -33,6 +32,7 @@ use style::computed_values::{border_style, clear, font_family, line_height, posi
|
||||||
use style::computed_values::{text_align, text_decoration, vertical_align, visibility, white_space};
|
use style::computed_values::{text_align, text_decoration, vertical_align, visibility, white_space};
|
||||||
|
|
||||||
use css::node_style::StyledNode;
|
use css::node_style::StyledNode;
|
||||||
|
use layout::construct::FlowConstructor;
|
||||||
use layout::context::LayoutContext;
|
use layout::context::LayoutContext;
|
||||||
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData, ToGfxColor};
|
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData, ToGfxColor};
|
||||||
use layout::float_context::{ClearType, ClearLeft, ClearRight, ClearBoth};
|
use layout::float_context::{ClearType, ClearLeft, ClearRight, ClearBoth};
|
||||||
|
@ -298,7 +298,7 @@ pub struct InlineParentInfo {
|
||||||
|
|
||||||
impl Box {
|
impl Box {
|
||||||
/// Constructs a new `Box` instance.
|
/// Constructs a new `Box` instance.
|
||||||
pub fn new(node: ThreadSafeLayoutNode, specific: SpecificBoxInfo) -> Box {
|
pub fn new(constructor: &mut FlowConstructor, node: ThreadSafeLayoutNode) -> Box {
|
||||||
Box {
|
Box {
|
||||||
node: OpaqueNode::from_thread_safe_layout_node(&node),
|
node: OpaqueNode::from_thread_safe_layout_node(&node),
|
||||||
style: node.style().clone(),
|
style: node.style().clone(),
|
||||||
|
@ -306,7 +306,7 @@ impl Box {
|
||||||
border: RefCell::new(Zero::zero()),
|
border: RefCell::new(Zero::zero()),
|
||||||
padding: RefCell::new(Zero::zero()),
|
padding: RefCell::new(Zero::zero()),
|
||||||
margin: RefCell::new(Zero::zero()),
|
margin: RefCell::new(Zero::zero()),
|
||||||
specific: specific,
|
specific: constructor.build_specific_box_info_for_node(node),
|
||||||
position_offsets: RefCell::new(Zero::zero()),
|
position_offsets: RefCell::new(Zero::zero()),
|
||||||
inline_info: RefCell::new(None),
|
inline_info: RefCell::new(None),
|
||||||
new_line_pos: ~[],
|
new_line_pos: ~[],
|
||||||
|
|
|
@ -23,10 +23,11 @@
|
||||||
use css::node_style::StyledNode;
|
use css::node_style::StyledNode;
|
||||||
use layout::block::BlockFlow;
|
use layout::block::BlockFlow;
|
||||||
use layout::box_::{Box, GenericBox, IframeBox, IframeBoxInfo, ImageBox, ImageBoxInfo};
|
use layout::box_::{Box, GenericBox, IframeBox, IframeBoxInfo, ImageBox, ImageBoxInfo};
|
||||||
use layout::box_::{UnscannedTextBox, UnscannedTextBoxInfo, InlineInfo, InlineParentInfo};
|
use layout::box_::{InlineInfo, InlineParentInfo, SpecificBoxInfo, UnscannedTextBox};
|
||||||
|
use layout::box_::{UnscannedTextBoxInfo};
|
||||||
use layout::context::LayoutContext;
|
use layout::context::LayoutContext;
|
||||||
use layout::float_context::FloatType;
|
use layout::float_context::FloatType;
|
||||||
use layout::flow::{BaseFlow, Flow, FlowLeafSet, ImmutableFlowUtils, MutableOwnedFlowUtils};
|
use layout::flow::{Flow, FlowLeafSet, ImmutableFlowUtils, MutableOwnedFlowUtils};
|
||||||
use layout::inline::InlineFlow;
|
use layout::inline::InlineFlow;
|
||||||
use layout::text::TextRunScanner;
|
use layout::text::TextRunScanner;
|
||||||
use layout::util::{LayoutDataAccess, OpaqueNode};
|
use layout::util::{LayoutDataAccess, OpaqueNode};
|
||||||
|
@ -227,7 +228,7 @@ impl<'fc> FlowConstructor<'fc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the next flow ID and bumps the internal counter.
|
/// Returns the next flow ID and bumps the internal counter.
|
||||||
fn next_flow_id(&self) -> int {
|
pub fn next_flow_id(&self) -> int {
|
||||||
let id = self.next_flow_id.get();
|
let id = self.next_flow_id.get();
|
||||||
self.next_flow_id.set(id + 1);
|
self.next_flow_id.set(id + 1);
|
||||||
id
|
id
|
||||||
|
@ -246,9 +247,10 @@ impl<'fc> FlowConstructor<'fc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a `Box` for the given node.
|
/// Builds specific `Box` info for the given node.
|
||||||
fn build_box_for_node(&mut self, node: ThreadSafeLayoutNode) -> Box {
|
pub fn build_specific_box_info_for_node(&mut self, node: ThreadSafeLayoutNode)
|
||||||
let specific = match node.type_id() {
|
-> SpecificBoxInfo {
|
||||||
|
match node.type_id() {
|
||||||
ElementNodeTypeId(HTMLImageElementTypeId) => {
|
ElementNodeTypeId(HTMLImageElementTypeId) => {
|
||||||
match self.build_box_info_for_image(node) {
|
match self.build_box_info_for_image(node) {
|
||||||
None => GenericBox,
|
None => GenericBox,
|
||||||
|
@ -258,8 +260,7 @@ impl<'fc> FlowConstructor<'fc> {
|
||||||
ElementNodeTypeId(HTMLIframeElementTypeId) => IframeBox(IframeBoxInfo::new(&node)),
|
ElementNodeTypeId(HTMLIframeElementTypeId) => IframeBox(IframeBoxInfo::new(&node)),
|
||||||
TextNodeTypeId => UnscannedTextBox(UnscannedTextBoxInfo::new(&node)),
|
TextNodeTypeId => UnscannedTextBox(UnscannedTextBoxInfo::new(&node)),
|
||||||
_ => GenericBox,
|
_ => GenericBox,
|
||||||
};
|
}
|
||||||
Box::new(node, specific)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an inline flow from a set of inline boxes and adds it as a child of the given flow.
|
/// Creates an inline flow from a set of inline boxes and adds it as a child of the given flow.
|
||||||
|
@ -275,8 +276,7 @@ impl<'fc> FlowConstructor<'fc> {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let inline_base = BaseFlow::new(self.next_flow_id(), node);
|
let mut inline_flow = ~InlineFlow::from_boxes(self.next_flow_id(), node, boxes) as ~Flow;
|
||||||
let mut inline_flow = ~InlineFlow::from_boxes(inline_base, boxes) as ~Flow;
|
|
||||||
inline_flow.mark_as_leaf(self.layout_context.flow_leaf_set.get());
|
inline_flow.mark_as_leaf(self.layout_context.flow_leaf_set.get());
|
||||||
TextRunScanner::new().scan_for_runs(self.font_context, inline_flow);
|
TextRunScanner::new().scan_for_runs(self.font_context, inline_flow);
|
||||||
|
|
||||||
|
@ -391,9 +391,7 @@ impl<'fc> FlowConstructor<'fc> {
|
||||||
/// other `BlockFlow`s or `InlineFlow`s underneath it, depending on whether {ib} splits needed
|
/// other `BlockFlow`s or `InlineFlow`s underneath it, depending on whether {ib} splits needed
|
||||||
/// to happen.
|
/// to happen.
|
||||||
fn build_flow_for_block(&mut self, node: ThreadSafeLayoutNode, is_fixed: bool) -> ~Flow {
|
fn build_flow_for_block(&mut self, node: ThreadSafeLayoutNode, is_fixed: bool) -> ~Flow {
|
||||||
let base = BaseFlow::new(self.next_flow_id(), node);
|
let mut flow = ~BlockFlow::from_node(self, node, is_fixed) as ~Flow;
|
||||||
let box_ = self.build_box_for_node(node);
|
|
||||||
let mut flow = ~BlockFlow::from_box(base, box_, is_fixed) as ~Flow;
|
|
||||||
self.build_children_of_block_flow(&mut flow, node);
|
self.build_children_of_block_flow(&mut flow, node);
|
||||||
flow
|
flow
|
||||||
}
|
}
|
||||||
|
@ -402,10 +400,7 @@ impl<'fc> FlowConstructor<'fc> {
|
||||||
/// a `BlockFlow` underneath it.
|
/// a `BlockFlow` underneath it.
|
||||||
fn build_flow_for_floated_block(&mut self, node: ThreadSafeLayoutNode, float_type: FloatType)
|
fn build_flow_for_floated_block(&mut self, node: ThreadSafeLayoutNode, float_type: FloatType)
|
||||||
-> ~Flow {
|
-> ~Flow {
|
||||||
let base = BaseFlow::new(self.next_flow_id(), node);
|
let mut flow = ~BlockFlow::float_from_node(self, node, float_type) as ~Flow;
|
||||||
let box_ = self.build_box_for_node(node);
|
|
||||||
|
|
||||||
let mut flow = ~BlockFlow::float_from_box(base, float_type, box_) as ~Flow;
|
|
||||||
self.build_children_of_block_flow(&mut flow, node);
|
self.build_children_of_block_flow(&mut flow, node);
|
||||||
flow
|
flow
|
||||||
}
|
}
|
||||||
|
@ -523,7 +518,7 @@ impl<'fc> FlowConstructor<'fc> {
|
||||||
fn set_inline_info_for_inline_child(&mut self,
|
fn set_inline_info_for_inline_child(&mut self,
|
||||||
boxes: &~[&Box],
|
boxes: &~[&Box],
|
||||||
parent_node: ThreadSafeLayoutNode) {
|
parent_node: ThreadSafeLayoutNode) {
|
||||||
let parent_box = self.build_box_for_node(parent_node);
|
let parent_box = Box::new(self, parent_node);
|
||||||
let font_style = parent_box.font_style();
|
let font_style = parent_box.font_style();
|
||||||
let font_group = self.font_context.get_resolved_font_for_style(&font_style);
|
let font_group = self.font_context.get_resolved_font_for_style(&font_style);
|
||||||
let (font_ascent,font_descent) = font_group.borrow().with_mut( |fg| {
|
let (font_ascent,font_descent) = font_group.borrow().with_mut( |fg| {
|
||||||
|
@ -578,7 +573,7 @@ impl<'fc> FlowConstructor<'fc> {
|
||||||
let construction_item = InlineBoxesConstructionItem(InlineBoxesConstructionResult {
|
let construction_item = InlineBoxesConstructionItem(InlineBoxesConstructionResult {
|
||||||
splits: None,
|
splits: None,
|
||||||
boxes: ~[
|
boxes: ~[
|
||||||
self.build_box_for_node(node)
|
Box::new(self, node)
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
ConstructionItemConstructionResult(construction_item)
|
ConstructionItemConstructionResult(construction_item)
|
||||||
|
|
|
@ -9,9 +9,9 @@ use layout::context::LayoutContext;
|
||||||
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
|
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
|
||||||
use layout::flow::{BaseFlow, FlowClass, Flow, InlineFlowClass};
|
use layout::flow::{BaseFlow, FlowClass, Flow, InlineFlowClass};
|
||||||
use layout::flow;
|
use layout::flow;
|
||||||
use layout::float_context::FloatContext;
|
use layout::float_context::{FloatContext, FloatLeft, PlacementInfo};
|
||||||
use layout::util::ElementMapping;
|
use layout::util::ElementMapping;
|
||||||
use layout::float_context::{PlacementInfo, FloatLeft};
|
use layout::wrapper::ThreadSafeLayoutNode;
|
||||||
|
|
||||||
use extra::container::Deque;
|
use extra::container::Deque;
|
||||||
use extra::ringbuf::RingBuf;
|
use extra::ringbuf::RingBuf;
|
||||||
|
@ -466,18 +466,9 @@ pub struct InlineFlow {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InlineFlow {
|
impl InlineFlow {
|
||||||
pub fn new(base: BaseFlow) -> InlineFlow {
|
pub fn from_boxes(id: int, node: ThreadSafeLayoutNode, boxes: ~[Box]) -> InlineFlow {
|
||||||
InlineFlow {
|
InlineFlow {
|
||||||
base: base,
|
base: BaseFlow::new(id, node),
|
||||||
boxes: ~[],
|
|
||||||
lines: ~[],
|
|
||||||
elems: ElementMapping::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_boxes(base: BaseFlow, boxes: ~[Box]) -> InlineFlow {
|
|
||||||
InlineFlow {
|
|
||||||
base: base,
|
|
||||||
boxes: boxes,
|
boxes: boxes,
|
||||||
lines: ~[],
|
lines: ~[],
|
||||||
elems: ElementMapping::new(),
|
elems: ElementMapping::new(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue