mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
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`.
This commit is contained in:
parent
f0b4162328
commit
8ded1072ce
4 changed files with 20 additions and 46 deletions
|
@ -281,7 +281,7 @@ impl Fragment {
|
||||||
.to_physical(fragment.parent_style.writing_mode, containing_block)
|
.to_physical(fragment.parent_style.writing_mode, containing_block)
|
||||||
.translate(containing_block.origin.to_vector());
|
.translate(containing_block.origin.to_vector());
|
||||||
let mut baseline_origin = rect.origin.clone();
|
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);
|
let glyphs = glyphs(&fragment.glyphs, baseline_origin);
|
||||||
if glyphs.is_empty() {
|
if glyphs.is_empty() {
|
||||||
return;
|
return;
|
||||||
|
@ -306,10 +306,6 @@ impl Fragment {
|
||||||
let color = fragment.parent_style.clone_color();
|
let color = fragment.parent_style.clone_color();
|
||||||
let font_metrics = &fragment.font_metrics;
|
let font_metrics = &fragment.font_metrics;
|
||||||
let dppx = builder.context.style_context.device_pixel_ratio().get();
|
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.
|
// Underline.
|
||||||
if fragment
|
if fragment
|
||||||
|
@ -317,8 +313,9 @@ impl Fragment {
|
||||||
.contains(TextDecorationLine::UNDERLINE)
|
.contains(TextDecorationLine::UNDERLINE)
|
||||||
{
|
{
|
||||||
let mut rect = rect;
|
let mut rect = rect;
|
||||||
rect.origin.y = rect.origin.y + font_metrics.ascent - font_metrics.underline_offset;
|
rect.origin.y =
|
||||||
rect.size.height = round_to_nearest_device_pixel(font_metrics.underline_size);
|
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);
|
self.build_display_list_for_text_decoration(fragment, builder, &rect, &color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,7 +325,7 @@ impl Fragment {
|
||||||
.contains(TextDecorationLine::OVERLINE)
|
.contains(TextDecorationLine::OVERLINE)
|
||||||
{
|
{
|
||||||
let mut rect = rect;
|
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);
|
self.build_display_list_for_text_decoration(fragment, builder, &rect, &color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,9 +346,10 @@ impl Fragment {
|
||||||
.contains(TextDecorationLine::LINE_THROUGH)
|
.contains(TextDecorationLine::LINE_THROUGH)
|
||||||
{
|
{
|
||||||
let mut rect = rect;
|
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
|
// 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);
|
self.build_display_list_for_text_decoration(fragment, builder, &rect, &color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ use std::vec::IntoIter;
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use atomic_refcell::AtomicRef;
|
use atomic_refcell::AtomicRef;
|
||||||
|
use gfx::font::FontMetrics;
|
||||||
use gfx::text::glyph::GlyphStore;
|
use gfx::text::glyph::GlyphStore;
|
||||||
use gfx::text::text_run::GlyphRun;
|
use gfx::text::text_run::GlyphRun;
|
||||||
use log::warn;
|
use log::warn;
|
||||||
|
@ -32,7 +33,7 @@ use crate::flow::FlowLayout;
|
||||||
use crate::formatting_contexts::IndependentFormattingContext;
|
use crate::formatting_contexts::IndependentFormattingContext;
|
||||||
use crate::fragment_tree::{
|
use crate::fragment_tree::{
|
||||||
AnonymousFragment, BaseFragmentInfo, BoxFragment, CollapsedBlockMargins, CollapsedMargin,
|
AnonymousFragment, BaseFragmentInfo, BoxFragment, CollapsedBlockMargins, CollapsedMargin,
|
||||||
FontMetrics, Fragment, HoistedSharedFragment, TextFragment,
|
Fragment, HoistedSharedFragment, TextFragment,
|
||||||
};
|
};
|
||||||
use crate::geom::{LogicalRect, LogicalVec2};
|
use crate::geom::{LogicalRect, LogicalVec2};
|
||||||
use crate::positioned::{
|
use crate::positioned::{
|
||||||
|
@ -893,7 +894,7 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
|
||||||
glyph_store: std::sync::Arc<GlyphStore>,
|
glyph_store: std::sync::Arc<GlyphStore>,
|
||||||
base_fragment_info: BaseFragmentInfo,
|
base_fragment_info: BaseFragmentInfo,
|
||||||
parent_style: &Arc<ComputedValues>,
|
parent_style: &Arc<ComputedValues>,
|
||||||
font_metrics: FontMetrics,
|
font_metrics: &FontMetrics,
|
||||||
font_key: FontInstanceKey,
|
font_key: FontInstanceKey,
|
||||||
) {
|
) {
|
||||||
let inline_advance = Length::from(glyph_store.total_advance());
|
let inline_advance = Length::from(glyph_store.total_advance());
|
||||||
|
@ -926,7 +927,7 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
|
||||||
text: vec![glyph_store],
|
text: vec![glyph_store],
|
||||||
base_fragment_info: base_fragment_info.into(),
|
base_fragment_info: base_fragment_info.into(),
|
||||||
parent_style: parent_style.clone(),
|
parent_style: parent_style.clone(),
|
||||||
font_metrics,
|
font_metrics: font_metrics.clone(),
|
||||||
font_key,
|
font_key,
|
||||||
text_decoration_line: self.current_inline_container_state().text_decoration_line,
|
text_decoration_line: self.current_inline_container_state().text_decoration_line,
|
||||||
}),
|
}),
|
||||||
|
@ -1644,7 +1645,7 @@ impl TextRun {
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(BreakAndShapeResult {
|
Ok(BreakAndShapeResult {
|
||||||
font_metrics: (&font.metrics).into(),
|
font_metrics: font.metrics.clone(),
|
||||||
font_key: font.font_key,
|
font_key: font.font_key,
|
||||||
runs,
|
runs,
|
||||||
break_at_start,
|
break_at_start,
|
||||||
|
@ -1729,7 +1730,7 @@ impl TextRun {
|
||||||
run.glyph_store,
|
run.glyph_store,
|
||||||
self.base_fragment_info,
|
self.base_fragment_info,
|
||||||
&self.parent_style,
|
&self.parent_style,
|
||||||
font_metrics,
|
&font_metrics,
|
||||||
font_key,
|
font_key,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1930,7 +1931,7 @@ struct TextRunLineItem {
|
||||||
fn line_height(parent_style: &ComputedValues, font_metrics: &FontMetrics) -> Length {
|
fn line_height(parent_style: &ComputedValues, font_metrics: &FontMetrics) -> Length {
|
||||||
let font_size = parent_style.get_font().font_size.computed_size();
|
let font_size = parent_style.get_font().font_size.computed_size();
|
||||||
match parent_style.get_inherited_text().line_height {
|
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::Number(number) => font_size * number.0,
|
||||||
LineHeight::Length(length) => length.0,
|
LineHeight::Length(length) => length.0,
|
||||||
}
|
}
|
||||||
|
@ -1946,8 +1947,8 @@ fn line_gap_from_style(layout_context: &LayoutContext, style: &ComputedValues) -
|
||||||
return Length::zero();
|
return Length::zero();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let font_metrics: FontMetrics = (&font.borrow().metrics).into();
|
let font = font.borrow();
|
||||||
font_metrics.line_gap
|
Length::from(font.metrics.line_gap)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1961,8 +1962,8 @@ fn line_height_from_style(layout_context: &LayoutContext, style: &ComputedValues
|
||||||
return Length::zero();
|
return Length::zero();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let font_metrics: FontMetrics = (&font.borrow().metrics).into();
|
let font = font.borrow();
|
||||||
line_height(style, &font_metrics)
|
line_height(style, &font.metrics)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use gfx::font::FontMetrics as GfxFontMetrics;
|
use gfx::font::FontMetrics;
|
||||||
use gfx::text::glyph::GlyphStore;
|
use gfx::text::glyph::GlyphStore;
|
||||||
use gfx_traits::print_tree::PrintTree;
|
use gfx_traits::print_tree::PrintTree;
|
||||||
use msg::constellation_msg::{BrowsingContextId, PipelineId};
|
use msg::constellation_msg::{BrowsingContextId, PipelineId};
|
||||||
|
@ -75,29 +75,6 @@ pub(crate) struct AnonymousFragment {
|
||||||
pub scrollable_overflow: PhysicalRect<Length>,
|
pub scrollable_overflow: PhysicalRect<Length>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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)]
|
#[derive(Serialize)]
|
||||||
pub(crate) struct TextFragment {
|
pub(crate) struct TextFragment {
|
||||||
pub base: BaseFragment,
|
pub base: BaseFragment,
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[text-decoration-thickness-from-zero-sized-font.html]
|
|
||||||
expected: FAIL
|
|
Loading…
Add table
Add a link
Reference in a new issue