diff options
author | Martin Robinson <mrobinson@igalia.com> | 2024-01-25 15:33:47 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-25 14:33:47 +0000 |
commit | 094f7845b151a54d318b40711119d1b86be75076 (patch) | |
tree | dbcd1741a44b7eff1ae180dd461e640b38a2e1f4 /components/layout_2020/flow/construct.rs | |
parent | bb04c97f15728d14a146f29fa1bc4d23ee96ec49 (diff) | |
download | servo-094f7845b151a54d318b40711119d1b86be75076.tar.gz servo-094f7845b151a54d318b40711119d1b86be75076.zip |
layout: Shape text only once (#31146)
Shape text during InlineFormattingContext construction rather than doing
it twice during fragment tree construction. This is a step on the way
toward proper font fallback.
This also moves all `TextRun` related code into `text_run.rs` to try to
trim down the size of `inline.rs`.
<!-- Please describe your changes on the following line: -->
---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by
`[X]` when the step is complete, and replace `___` with appropriate
data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes do not require tests because this should only have
performance impacts.
<!-- Also, please make sure that "Allow edits from maintainers" checkbox
is checked, so that we can help you if you get stuck somewhere along the
way.-->
<!-- Pull requests that do not address these steps are welcome, but they
will require additional verification as part of the review process. -->
Diffstat (limited to 'components/layout_2020/flow/construct.rs')
-rw-r--r-- | components/layout_2020/flow/construct.rs | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/components/layout_2020/flow/construct.rs b/components/layout_2020/flow/construct.rs index 4c7b712fade..3155ff6e878 100644 --- a/components/layout_2020/flow/construct.rs +++ b/components/layout_2020/flow/construct.rs @@ -19,7 +19,8 @@ use crate::context::LayoutContext; use crate::dom::{BoxSlot, LayoutBox, NodeExt}; use crate::dom_traversal::{Contents, NodeAndStyleInfo, NonReplacedContents, TraversalHandler}; use crate::flow::float::FloatBox; -use crate::flow::inline::{InlineBox, InlineFormattingContext, InlineLevelBox, TextRun}; +use crate::flow::inline::{InlineBox, InlineFormattingContext, InlineLevelBox}; +use crate::flow::text_run::TextRun; use crate::flow::{BlockContainer, BlockFormattingContext, BlockLevelBox}; use crate::formatting_contexts::IndependentFormattingContext; use crate::positioned::AbsolutelyPositionedBox; @@ -56,6 +57,7 @@ impl BlockFormattingContext { pub fn construct_for_text_runs<'dom>( runs: impl Iterator<Item = TextRun>, + layout_context: &LayoutContext, text_decoration_line: TextDecorationLine, ) -> Self { // FIXME: do white space collapsing @@ -70,10 +72,8 @@ impl BlockFormattingContext { contains_floats: false, ends_with_whitespace: false, }; - let contents = BlockContainer::InlineFormattingContext(ifc); - Self { - contents, + contents: BlockContainer::construct_inline_formatting_context(layout_context, ifc), contains_floats: false, } } @@ -216,6 +216,16 @@ impl BlockContainer { contents.traverse(context, info, &mut builder); builder.finish() } + + pub(super) fn construct_inline_formatting_context( + layout_context: &LayoutContext, + mut ifc: InlineFormattingContext, + ) -> Self { + // TODO(mrobinson): Perhaps it would be better to iteratively break and shape the contents + // of the IFC, and not wait until it is completely built. + ifc.break_and_shape_text(layout_context); + BlockContainer::InlineFormattingContext(ifc) + } } impl<'dom, 'style, Node> BlockContainerBuilder<'dom, 'style, Node> @@ -251,7 +261,8 @@ where if !self.ongoing_inline_formatting_context.is_empty() { if self.block_level_boxes.is_empty() { - return BlockContainer::InlineFormattingContext( + return BlockContainer::construct_inline_formatting_context( + self.context, self.ongoing_inline_formatting_context, ); } @@ -427,6 +438,7 @@ where parent_style: Arc::clone(&info.style), text: output, has_uncollapsible_content, + shaped_text: None, }))); } } @@ -811,15 +823,15 @@ where /* ends_with_whitespace */ false, ); std::mem::swap(&mut self.ongoing_inline_formatting_context, &mut ifc); - let kind = BlockLevelCreator::SameFormattingContextBlock( - IntermediateBlockContainer::InlineFormattingContext(ifc), - ); + let info = self.info.new_replacing_style(anonymous_style.clone()); self.block_level_boxes.push(BlockLevelJob { info, // FIXME(nox): We should be storing this somewhere. box_slot: BoxSlot::dummy(), - kind, + kind: BlockLevelCreator::SameFormattingContextBlock( + IntermediateBlockContainer::InlineFormattingContext(ifc), + ), }); } @@ -919,7 +931,7 @@ impl IntermediateBlockContainer { is_list_item, ), IntermediateBlockContainer::InlineFormattingContext(ifc) => { - BlockContainer::InlineFormattingContext(ifc) + BlockContainer::construct_inline_formatting_context(context, ifc) }, } } |