From 8ded1072ceda45e8f8b7716f5779c63996d7e653 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Wed, 6 Dec 2023 10:52:23 +0100 Subject: [PATCH] Re-use the TextMetrics data structure in the Layout 2020 fragment tree (#30823) This data structure has all of the metrics needed to render a font and is in `Au`. We'll need more of these metrics for implementing `vertical-align` and its use doesn't increase the size of the Fragment tree (as the BoxFragment is still larger). In addition, this will be helpful when switching layout to `Au`. --- components/layout_2020/display_list/mod.rs | 18 ++++++------- components/layout_2020/flow/inline.rs | 21 ++++++++-------- .../layout_2020/fragment_tree/fragment.rs | 25 +------------------ ...on-thickness-from-zero-sized-font.html.ini | 2 -- 4 files changed, 20 insertions(+), 46 deletions(-) delete mode 100644 tests/wpt/meta/css/css-text-decor/text-decoration-thickness-from-zero-sized-font.html.ini diff --git a/components/layout_2020/display_list/mod.rs b/components/layout_2020/display_list/mod.rs index 6b01f327b18..4807d54d923 100644 --- a/components/layout_2020/display_list/mod.rs +++ b/components/layout_2020/display_list/mod.rs @@ -281,7 +281,7 @@ impl Fragment { .to_physical(fragment.parent_style.writing_mode, containing_block) .translate(containing_block.origin.to_vector()); let mut baseline_origin = rect.origin.clone(); - baseline_origin.y += fragment.font_metrics.ascent; + baseline_origin.y += Length::from(fragment.font_metrics.ascent); let glyphs = glyphs(&fragment.glyphs, baseline_origin); if glyphs.is_empty() { return; @@ -306,10 +306,6 @@ impl Fragment { let color = fragment.parent_style.clone_color(); let font_metrics = &fragment.font_metrics; let dppx = builder.context.style_context.device_pixel_ratio().get(); - let round_to_nearest_device_pixel = |value: Length| -> Length { - // Round to the nearest integer device pixel, ensuring at least one device pixel. - Length::new((value.px() * dppx).round().max(1.0) / dppx) - }; // Underline. if fragment @@ -317,8 +313,9 @@ impl Fragment { .contains(TextDecorationLine::UNDERLINE) { let mut rect = rect; - rect.origin.y = rect.origin.y + font_metrics.ascent - font_metrics.underline_offset; - rect.size.height = round_to_nearest_device_pixel(font_metrics.underline_size); + rect.origin.y = + rect.origin.y + Length::from(font_metrics.ascent - font_metrics.underline_offset); + rect.size.height = Length::new(font_metrics.underline_size.to_nearest_pixel(dppx)); self.build_display_list_for_text_decoration(fragment, builder, &rect, &color); } @@ -328,7 +325,7 @@ impl Fragment { .contains(TextDecorationLine::OVERLINE) { let mut rect = rect; - rect.size.height = round_to_nearest_device_pixel(font_metrics.underline_size); + rect.size.height = Length::new(font_metrics.underline_size.to_nearest_pixel(dppx)); self.build_display_list_for_text_decoration(fragment, builder, &rect, &color); } @@ -349,9 +346,10 @@ impl Fragment { .contains(TextDecorationLine::LINE_THROUGH) { let mut rect = rect; - rect.origin.y = rect.origin.y + font_metrics.ascent - font_metrics.strikeout_offset; + rect.origin.y = + rect.origin.y + Length::from(font_metrics.ascent - font_metrics.strikeout_offset); // XXX(ferjm) This does not work on MacOS #942 - rect.size.height = round_to_nearest_device_pixel(font_metrics.strikeout_size); + rect.size.height = Length::new(font_metrics.strikeout_size.to_nearest_pixel(dppx)); self.build_display_list_for_text_decoration(fragment, builder, &rect, &color); } } diff --git a/components/layout_2020/flow/inline.rs b/components/layout_2020/flow/inline.rs index e247c1d37ee..7d950807da4 100644 --- a/components/layout_2020/flow/inline.rs +++ b/components/layout_2020/flow/inline.rs @@ -8,6 +8,7 @@ use std::vec::IntoIter; use app_units::Au; use atomic_refcell::AtomicRef; +use gfx::font::FontMetrics; use gfx::text::glyph::GlyphStore; use gfx::text::text_run::GlyphRun; use log::warn; @@ -32,7 +33,7 @@ use crate::flow::FlowLayout; use crate::formatting_contexts::IndependentFormattingContext; use crate::fragment_tree::{ AnonymousFragment, BaseFragmentInfo, BoxFragment, CollapsedBlockMargins, CollapsedMargin, - FontMetrics, Fragment, HoistedSharedFragment, TextFragment, + Fragment, HoistedSharedFragment, TextFragment, }; use crate::geom::{LogicalRect, LogicalVec2}; use crate::positioned::{ @@ -893,7 +894,7 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> { glyph_store: std::sync::Arc, base_fragment_info: BaseFragmentInfo, parent_style: &Arc, - font_metrics: FontMetrics, + font_metrics: &FontMetrics, font_key: FontInstanceKey, ) { let inline_advance = Length::from(glyph_store.total_advance()); @@ -926,7 +927,7 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> { text: vec![glyph_store], base_fragment_info: base_fragment_info.into(), parent_style: parent_style.clone(), - font_metrics, + font_metrics: font_metrics.clone(), font_key, text_decoration_line: self.current_inline_container_state().text_decoration_line, }), @@ -1644,7 +1645,7 @@ impl TextRun { ); Ok(BreakAndShapeResult { - font_metrics: (&font.metrics).into(), + font_metrics: font.metrics.clone(), font_key: font.font_key, runs, break_at_start, @@ -1729,7 +1730,7 @@ impl TextRun { run.glyph_store, self.base_fragment_info, &self.parent_style, - font_metrics, + &font_metrics, font_key, ); } @@ -1930,7 +1931,7 @@ struct TextRunLineItem { fn line_height(parent_style: &ComputedValues, font_metrics: &FontMetrics) -> Length { let font_size = parent_style.get_font().font_size.computed_size(); match parent_style.get_inherited_text().line_height { - LineHeight::Normal => font_metrics.line_gap, + LineHeight::Normal => Length::from(font_metrics.line_gap), LineHeight::Number(number) => font_size * number.0, LineHeight::Length(length) => length.0, } @@ -1946,8 +1947,8 @@ fn line_gap_from_style(layout_context: &LayoutContext, style: &ComputedValues) - return Length::zero(); }, }; - let font_metrics: FontMetrics = (&font.borrow().metrics).into(); - font_metrics.line_gap + let font = font.borrow(); + Length::from(font.metrics.line_gap) }) } @@ -1961,8 +1962,8 @@ fn line_height_from_style(layout_context: &LayoutContext, style: &ComputedValues return Length::zero(); }, }; - let font_metrics: FontMetrics = (&font.borrow().metrics).into(); - line_height(style, &font_metrics) + let font = font.borrow(); + line_height(style, &font.metrics) }) } diff --git a/components/layout_2020/fragment_tree/fragment.rs b/components/layout_2020/fragment_tree/fragment.rs index fda4636e9e7..c8456ba6bbc 100644 --- a/components/layout_2020/fragment_tree/fragment.rs +++ b/components/layout_2020/fragment_tree/fragment.rs @@ -4,7 +4,7 @@ use std::sync::Arc; -use gfx::font::FontMetrics as GfxFontMetrics; +use gfx::font::FontMetrics; use gfx::text::glyph::GlyphStore; use gfx_traits::print_tree::PrintTree; use msg::constellation_msg::{BrowsingContextId, PipelineId}; @@ -75,29 +75,6 @@ pub(crate) struct AnonymousFragment { pub scrollable_overflow: PhysicalRect, } -#[derive(Clone, Copy, Serialize)] -pub(crate) struct FontMetrics { - pub ascent: Length, - pub line_gap: Length, - pub underline_offset: Length, - pub underline_size: Length, - pub strikeout_offset: Length, - pub strikeout_size: Length, -} - -impl From<&GfxFontMetrics> for FontMetrics { - fn from(metrics: &GfxFontMetrics) -> FontMetrics { - FontMetrics { - ascent: metrics.ascent.into(), - line_gap: metrics.line_gap.into(), - underline_offset: metrics.underline_offset.into(), - underline_size: metrics.underline_size.into(), - strikeout_offset: metrics.strikeout_offset.into(), - strikeout_size: metrics.strikeout_size.into(), - } - } -} - #[derive(Serialize)] pub(crate) struct TextFragment { pub base: BaseFragment, diff --git a/tests/wpt/meta/css/css-text-decor/text-decoration-thickness-from-zero-sized-font.html.ini b/tests/wpt/meta/css/css-text-decor/text-decoration-thickness-from-zero-sized-font.html.ini deleted file mode 100644 index ba4be2d12c7..00000000000 --- a/tests/wpt/meta/css/css-text-decor/text-decoration-thickness-from-zero-sized-font.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[text-decoration-thickness-from-zero-sized-font.html] - expected: FAIL