diff options
author | Anthony Ramine <nox@nox.paris> | 2019-11-12 12:30:03 +0100 |
---|---|---|
committer | Anthony Ramine <nox@nox.paris> | 2019-11-25 10:54:46 +0100 |
commit | 144675677495b9c63c942f4458bc7965908deb94 (patch) | |
tree | c7422b1c7b87a1153024001f0c0352685112f92c /components | |
parent | ea3249550467bd9f5a1de8271ed4fcaa70a7cdda (diff) | |
download | servo-144675677495b9c63c942f4458bc7965908deb94.tar.gz servo-144675677495b9c63c942f4458bc7965908deb94.zip |
Pass a LayoutContext to TextRun::layout in 2020
Diffstat (limited to 'components')
-rw-r--r-- | components/layout_2020/context.rs | 17 | ||||
-rw-r--r-- | components/layout_2020/flow/inline.rs | 6 | ||||
-rw-r--r-- | components/layout_2020/flow/mod.rs | 25 | ||||
-rw-r--r-- | components/layout_2020/flow/root.rs | 10 | ||||
-rw-r--r-- | components/layout_2020/lib.rs | 19 | ||||
-rw-r--r-- | components/layout_2020/positioned.rs | 12 | ||||
-rw-r--r-- | components/layout_thread_2020/lib.rs | 28 |
7 files changed, 94 insertions, 23 deletions
diff --git a/components/layout_2020/context.rs b/components/layout_2020/context.rs index 0e96797f4d7..5bde114ca57 100644 --- a/components/layout_2020/context.rs +++ b/components/layout_2020/context.rs @@ -3,7 +3,9 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use gfx::font_cache_thread::FontCacheThread; +use gfx::font_context::FontContext; use msg::constellation_msg::PipelineId; +use std::cell::{RefCell, RefMut}; use std::sync::Mutex; use style::context::SharedStyleContext; @@ -19,3 +21,18 @@ impl<'a> LayoutContext<'a> { &self.style_context } } + +pub(crate) type LayoutFontContext = FontContext<FontCacheThread>; + +thread_local!(static FONT_CONTEXT: RefCell<Option<LayoutFontContext>> = RefCell::new(None)); + +pub(crate) fn with_thread_local_font_context<F, R>(layout_context: &LayoutContext, f: F) -> R +where + F: FnOnce(&mut LayoutFontContext) -> R, +{ + FONT_CONTEXT.with(|font_context| { + f(font_context.borrow_mut().get_or_insert_with(|| { + FontContext::new(layout_context.font_cache_thread.lock().unwrap().clone()) + })) + }) +} diff --git a/components/layout_2020/flow/inline.rs b/components/layout_2020/flow/inline.rs index 133654f32b7..11bb82eef8e 100644 --- a/components/layout_2020/flow/inline.rs +++ b/components/layout_2020/flow/inline.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use crate::context::LayoutContext; use crate::flow::float::FloatBox; use crate::flow::FlowChildren; use crate::fragments::{AnonymousFragment, BoxFragment, CollapsedBlockMargins, Fragment}; @@ -81,6 +82,7 @@ struct LinesBoxes { impl InlineFormattingContext { pub(super) fn layout<'a>( &'a self, + layout_context: &LayoutContext, containing_block: &ContainingBlock, tree_rank: usize, absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>, @@ -107,7 +109,7 @@ impl InlineFormattingContext { let partial = inline.start_layout(&mut ifc); ifc.partial_inline_boxes_stack.push(partial) }, - InlineLevelBox::TextRun(run) => run.layout(&mut ifc), + InlineLevelBox::TextRun(run) => run.layout(layout_context, &mut ifc), InlineLevelBox::Atomic { style: _, contents } => { // FIXME match *contents {} @@ -284,7 +286,7 @@ impl<'box_tree> PartialInlineBoxFragment<'box_tree> { } impl TextRun { - fn layout(&self, _ifc: &mut InlineFormattingContextState) { + fn layout(&self, _layout_context: &LayoutContext, _ifc: &mut InlineFormattingContextState) { // TODO } } diff --git a/components/layout_2020/flow/mod.rs b/components/layout_2020/flow/mod.rs index 2395380c5eb..b690e447cd7 100644 --- a/components/layout_2020/flow/mod.rs +++ b/components/layout_2020/flow/mod.rs @@ -4,6 +4,7 @@ //! Flow layout, also known as block-and-inline layout. +use crate::context::LayoutContext; use crate::flow::float::{FloatBox, FloatContext}; use crate::flow::inline::InlineFormattingContext; use crate::fragments::{ @@ -67,6 +68,7 @@ struct CollapsibleWithParentStartMargin(bool); impl BlockFormattingContext { pub(super) fn layout<'a>( &'a self, + layout_context: &LayoutContext, containing_block: &ContainingBlock, tree_rank: usize, absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>, @@ -79,6 +81,7 @@ impl BlockFormattingContext { None }; let mut flow_children = self.contents.layout( + layout_context, containing_block, tree_rank, absolutely_positioned_fragments, @@ -97,6 +100,7 @@ impl BlockFormattingContext { impl BlockContainer { fn layout<'a>( &'a self, + layout_context: &LayoutContext, containing_block: &ContainingBlock, tree_rank: usize, absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>, @@ -105,6 +109,7 @@ impl BlockContainer { ) -> FlowChildren { match self { BlockContainer::BlockLevelBoxes(child_boxes) => layout_block_level_children( + layout_context, child_boxes, containing_block, tree_rank, @@ -112,14 +117,18 @@ impl BlockContainer { float_context, collapsible_with_parent_start_margin, ), - BlockContainer::InlineFormattingContext(ifc) => { - ifc.layout(containing_block, tree_rank, absolutely_positioned_fragments) - }, + BlockContainer::InlineFormattingContext(ifc) => ifc.layout( + layout_context, + containing_block, + tree_rank, + absolutely_positioned_fragments, + ), } } } fn layout_block_level_children<'a>( + layout_context: &LayoutContext, child_boxes: &'a [Arc<BlockLevelBox>], containing_block: &ContainingBlock, tree_rank: usize, @@ -201,6 +210,7 @@ fn layout_block_level_children<'a>( .enumerate() .map(|(tree_rank, box_)| { let mut fragment = box_.layout( + layout_context, containing_block, tree_rank, absolutely_positioned_fragments, @@ -218,6 +228,7 @@ fn layout_block_level_children<'a>( absolutely_positioned_fragments, |abspos_fragments, (tree_rank, box_)| { box_.layout( + layout_context, containing_block, tree_rank, abspos_fragments, @@ -255,6 +266,7 @@ fn layout_block_level_children<'a>( impl BlockLevelBox { fn layout<'a>( &'a self, + layout_context: &LayoutContext, containing_block: &ContainingBlock, tree_rank: usize, absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>, @@ -263,12 +275,14 @@ impl BlockLevelBox { match self { BlockLevelBox::SameFormattingContextBlock { style, contents } => { Fragment::Box(layout_in_flow_non_replaced_block_level( + layout_context, containing_block, absolutely_positioned_fragments, style, BlockLevelKind::SameFormattingContextBlock, |containing_block, nested_abspos, collapsible_with_parent_start_margin| { contents.layout( + layout_context, containing_block, tree_rank, nested_abspos, @@ -284,12 +298,13 @@ impl BlockLevelBox { match *replaced {} }, Err(contents) => Fragment::Box(layout_in_flow_non_replaced_block_level( + layout_context, containing_block, absolutely_positioned_fragments, style, BlockLevelKind::EstablishesAnIndependentFormattingContext, |containing_block, nested_abspos, _| { - contents.layout(containing_block, tree_rank, nested_abspos) + contents.layout(layout_context, containing_block, tree_rank, nested_abspos) }, )), }, @@ -314,6 +329,7 @@ enum BlockLevelKind { /// https://drafts.csswg.org/css2/visudet.html#blockwidth /// https://drafts.csswg.org/css2/visudet.html#normal-block fn layout_in_flow_non_replaced_block_level<'a>( + layout_context: &LayoutContext, containing_block: &ContainingBlock, absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>, style: &Arc<ComputedValues>, @@ -433,6 +449,7 @@ fn layout_in_flow_non_replaced_block_level<'a>( }; if style.get_box().position == Position::Relative { AbsolutelyPositionedFragment::in_positioned_containing_block( + layout_context, &nested_abspos, &mut flow_children.fragments, &content_rect.size, diff --git a/components/layout_2020/flow/root.rs b/components/layout_2020/flow/root.rs index 54cc1eef07f..a1831c6433a 100644 --- a/components/layout_2020/flow/root.rs +++ b/components/layout_2020/flow/root.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use crate::context::LayoutContext; use crate::display_list::IsContentful; use crate::dom_traversal::{Contents, NodeExt}; use crate::flow::construct::ContainsFloats; @@ -98,7 +99,11 @@ fn construct_for_root_element<'dom>( } impl BoxTreeRoot { - pub fn layout(&self, viewport: geom::Size<CSSPixel>) -> FragmentTreeRoot { + pub fn layout( + &self, + layout_context: &LayoutContext, + viewport: geom::Size<CSSPixel>, + ) -> FragmentTreeRoot { let initial_containing_block_size = Vec2 { inline: Length::new(viewport.width), block: Length::new(viewport.height), @@ -114,6 +119,7 @@ impl BoxTreeRoot { let dummy_tree_rank = 0; let mut absolutely_positioned_fragments = vec![]; let mut flow_children = self.0.layout( + layout_context, &initial_containing_block, dummy_tree_rank, &mut absolutely_positioned_fragments, @@ -126,7 +132,7 @@ impl BoxTreeRoot { flow_children.fragments.par_extend( absolutely_positioned_fragments .par_iter() - .map(|a| a.layout(&initial_containing_block)), + .map(|a| a.layout(layout_context, &initial_containing_block)), ); FragmentTreeRoot(flow_children.fragments) } diff --git a/components/layout_2020/lib.rs b/components/layout_2020/lib.rs index 052cb4b0540..b25d8837581 100644 --- a/components/layout_2020/lib.rs +++ b/components/layout_2020/lib.rs @@ -33,6 +33,7 @@ pub mod wrapper; pub use flow::{BoxTreeRoot, FragmentTreeRoot}; +use crate::context::LayoutContext; use crate::dom_traversal::{Contents, NodeExt}; use crate::flow::{BlockFormattingContext, FlowChildren}; use crate::geom::flow_relative::Vec2; @@ -87,13 +88,19 @@ impl IndependentFormattingContext { fn layout<'a>( &'a self, + layout_context: &LayoutContext, containing_block: &ContainingBlock, tree_rank: usize, absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>, ) -> FlowChildren { match self.as_replaced() { Ok(replaced) => match *replaced {}, - Err(ifc) => ifc.layout(containing_block, tree_rank, absolutely_positioned_fragments), + Err(ifc) => ifc.layout( + layout_context, + containing_block, + tree_rank, + absolutely_positioned_fragments, + ), } } } @@ -101,14 +108,18 @@ impl IndependentFormattingContext { impl<'a> NonReplacedIFC<'a> { fn layout( &self, + layout_context: &LayoutContext, containing_block: &ContainingBlock, tree_rank: usize, absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>, ) -> FlowChildren { match self { - NonReplacedIFC::Flow(bfc) => { - bfc.layout(containing_block, tree_rank, absolutely_positioned_fragments) - }, + NonReplacedIFC::Flow(bfc) => bfc.layout( + layout_context, + containing_block, + tree_rank, + absolutely_positioned_fragments, + ), } } } diff --git a/components/layout_2020/positioned.rs b/components/layout_2020/positioned.rs index 55888fb8842..b37a5ed4a70 100644 --- a/components/layout_2020/positioned.rs +++ b/components/layout_2020/positioned.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use crate::context::LayoutContext; use crate::fragments::{AnonymousFragment, BoxFragment, CollapsedBlockMargins, Fragment}; use crate::geom::flow_relative::{Rect, Sides, Vec2}; use crate::style_ext::{ComputedValuesExt, Direction, WritingMode}; @@ -94,6 +95,7 @@ impl AbsolutelyPositionedBox { impl<'a> AbsolutelyPositionedFragment<'a> { pub(crate) fn in_positioned_containing_block( + layout_context: &LayoutContext, absolute: &[Self], fragments: &mut Vec<Fragment>, content_rect_size: &Vec2<Length>, @@ -116,14 +118,18 @@ impl<'a> AbsolutelyPositionedFragment<'a> { fragments.push(Fragment::Anonymous(AnonymousFragment { children: absolute .par_iter() - .map(|a| a.layout(&containing_block)) + .map(|a| a.layout(layout_context, &containing_block)) .collect(), rect: padding_rect, mode, })) } - pub(crate) fn layout(&self, containing_block: &DefiniteContainingBlock) -> Fragment { + pub(crate) fn layout( + &self, + layout_context: &LayoutContext, + containing_block: &DefiniteContainingBlock, + ) -> Fragment { let style = &self.absolutely_positioned_box.style; let cbis = containing_block.size.inline; let cbbs = containing_block.size.block; @@ -269,6 +275,7 @@ impl<'a> AbsolutelyPositionedFragment<'a> { let dummy_tree_rank = 0; let mut absolutely_positioned_fragments = vec![]; let mut flow_children = self.absolutely_positioned_box.contents.layout( + layout_context, &containing_block_for_children, dummy_tree_rank, &mut absolutely_positioned_fragments, @@ -297,6 +304,7 @@ impl<'a> AbsolutelyPositionedFragment<'a> { }; AbsolutelyPositionedFragment::in_positioned_containing_block( + layout_context, &absolutely_positioned_fragments, &mut flow_children.fragments, &content_rect.size, diff --git a/components/layout_thread_2020/lib.rs b/components/layout_thread_2020/lib.rs index bf18c584231..67ae81ca0a7 100644 --- a/components/layout_thread_2020/lib.rs +++ b/components/layout_thread_2020/lib.rs @@ -1087,16 +1087,28 @@ impl LayoutThread { RecalcStyle::pre_traverse(element, shared) }; - if token.should_traverse() { + let box_tree = if token.should_traverse() { driver::traverse_dom(&traversal, token, None); let shared = DomTraversal::<ServoLayoutElement>::shared_context(&traversal); - let box_tree = - BoxTreeRoot::construct(shared, document.root_element().unwrap().as_node()); - let fragment_tree = box_tree.layout(Size2D::new( - self.viewport_size.width.to_f32_px(), - self.viewport_size.height.to_f32_px(), - )); + Some(BoxTreeRoot::construct( + shared, + document.root_element().unwrap().as_node(), + )) + } else { + None + }; + + layout_context = traversal.destroy(); + + if let Some(box_tree) = box_tree { + let fragment_tree = box_tree.layout( + &layout_context, + Size2D::new( + self.viewport_size.width.to_f32_px(), + self.viewport_size.height.to_f32_px(), + ), + ); *self.box_tree_root.borrow_mut() = Some(box_tree); *self.fragment_tree_root.borrow_mut() = Some(fragment_tree); } @@ -1105,8 +1117,6 @@ impl LayoutThread { unsafe { element.unset_snapshot_flags() } } - layout_context = traversal.destroy(); - // GC the rule tree if some heuristics are met. unsafe { layout_context.style_context.stylist.rule_tree().maybe_gc(); |