aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorAnthony Ramine <nox@nox.paris>2019-11-12 12:30:03 +0100
committerAnthony Ramine <nox@nox.paris>2019-11-25 10:54:46 +0100
commit144675677495b9c63c942f4458bc7965908deb94 (patch)
treec7422b1c7b87a1153024001f0c0352685112f92c /components
parentea3249550467bd9f5a1de8271ed4fcaa70a7cdda (diff)
downloadservo-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.rs17
-rw-r--r--components/layout_2020/flow/inline.rs6
-rw-r--r--components/layout_2020/flow/mod.rs25
-rw-r--r--components/layout_2020/flow/root.rs10
-rw-r--r--components/layout_2020/lib.rs19
-rw-r--r--components/layout_2020/positioned.rs12
-rw-r--r--components/layout_thread_2020/lib.rs28
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();