Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Start implementing text in layout 2020 #24822

Merged
merged 6 commits into from Nov 25, 2019
Next

Pass a LayoutContext to TextRun::layout in 2020

  • Loading branch information
nox committed Nov 25, 2019
commit 144675677495b9c63c942f4458bc7965908deb94
@@ -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())
}))
})
}
@@ -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
}
}
@@ -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,21 +109,26 @@ impl BlockContainer {
) -> FlowChildren {
match self {
BlockContainer::BlockLevelBoxes(child_boxes) => layout_block_level_children(
layout_context,
child_boxes,
containing_block,
tree_rank,
absolutely_positioned_fragments,
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,
@@ -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)
}
@@ -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,28 +88,38 @@ 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,
),
}
}
}

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,
),
}
}
}
@@ -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,
@@ -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();
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.