Bug 1962602 - Give gfxFontGroup::GetMetricsForCSSUnits flags to control whether it should load extra font resources to measure the ZERO or WATER IDEOGRAPH characters. r=firefox-style-system-reviewers,emilio
This makes the style system pass flags down to GetMetricsForCSSUnits to specify whether it needs the 'ch' or 'ic' units, which may trigger downloading additional font resources. There should be no change in user-visible behavior, except by observing (e.g. in the devtools network panel) what resources end up being fetched in an example like the reporter's. Differential Revision: https://phabricator.services.mozilla.com/D246780
This commit is contained in:
@@ -29,6 +29,23 @@ use std::sync::atomic::{AtomicBool, AtomicU32, AtomicUsize, Ordering};
|
||||
use std::{cmp, fmt};
|
||||
use style_traits::{CSSPixel, DevicePixel};
|
||||
|
||||
/// Flags for the query_font_metrics() function.
|
||||
#[repr(C)]
|
||||
pub struct QueryFontMetricsFlags(u8);
|
||||
|
||||
bitflags! {
|
||||
impl QueryFontMetricsFlags: u8 {
|
||||
/// Should we use the user font set?
|
||||
const USE_USER_FONT_SET = 1 << 0;
|
||||
/// Does the caller need the `ch` unit (width of the ZERO glyph)?
|
||||
const NEEDS_CH = 1 << 1;
|
||||
/// Does the caller need the `ic` unit (width of the WATER ideograph)?
|
||||
const NEEDS_IC = 1 << 2;
|
||||
/// Does the caller need math scales to be retrieved?
|
||||
const NEEDS_MATH_SCALES = 1 << 3;
|
||||
}
|
||||
}
|
||||
|
||||
/// The `Device` in Gecko wraps a pres context, has a default values computed,
|
||||
/// and contains all the viewport rule state.
|
||||
pub struct Device {
|
||||
@@ -227,8 +244,7 @@ impl Device {
|
||||
vertical: bool,
|
||||
font: &crate::properties::style_structs::Font,
|
||||
base_size: Length,
|
||||
in_media_query: bool,
|
||||
retrieve_math_scales: bool,
|
||||
flags: QueryFontMetricsFlags,
|
||||
) -> FontMetrics {
|
||||
self.used_font_metrics.store(true, Ordering::Relaxed);
|
||||
let pc = match self.pres_context() {
|
||||
@@ -241,9 +257,7 @@ impl Device {
|
||||
vertical,
|
||||
&**font,
|
||||
base_size,
|
||||
// we don't use the user font set in a media query
|
||||
!in_media_query,
|
||||
retrieve_math_scales,
|
||||
flags,
|
||||
)
|
||||
};
|
||||
FontMetrics {
|
||||
|
||||
@@ -1355,6 +1355,8 @@ impl<'b> Cascade<'b> {
|
||||
}
|
||||
|
||||
let (new_size, new_unconstrained_size) = {
|
||||
use crate::gecko::media_queries::QueryFontMetricsFlags;
|
||||
|
||||
let builder = &context.builder;
|
||||
let font = builder.get_font();
|
||||
let parent_font = builder.get_parent_font();
|
||||
@@ -1376,7 +1378,7 @@ impl<'b> Cascade<'b> {
|
||||
let font_metrics = context.query_font_metrics(
|
||||
FontBaseSize::InheritedStyle,
|
||||
FontMetricsOrientation::Horizontal,
|
||||
/* retrieve_math_scales = */ true,
|
||||
QueryFontMetricsFlags::NEEDS_MATH_SCALES,
|
||||
);
|
||||
scale_factor_for_math_depth_change(
|
||||
parent_font.mMathDepth as i32,
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
//! Computed values for font properties
|
||||
|
||||
use crate::gecko::media_queries::QueryFontMetricsFlags;
|
||||
use crate::parser::{Parse, ParserContext};
|
||||
use crate::values::animated::ToAnimatedValue;
|
||||
use crate::values::computed::{
|
||||
@@ -802,13 +803,13 @@ impl ToComputedValue for specified::FontSizeAdjust {
|
||||
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||
use crate::font_metrics::FontMetricsOrientation;
|
||||
|
||||
let font_metrics = |vertical| {
|
||||
let font_metrics = |vertical, flags| {
|
||||
let orient = if vertical {
|
||||
FontMetricsOrientation::MatchContextPreferVertical
|
||||
} else {
|
||||
FontMetricsOrientation::Horizontal
|
||||
};
|
||||
let metrics = context.query_font_metrics(FontBaseSize::CurrentStyle, orient, false);
|
||||
let metrics = context.query_font_metrics(FontBaseSize::CurrentStyle, orient, flags);
|
||||
let font_size = context.style().get_font().clone_font_size().used_size.0;
|
||||
(metrics, font_size)
|
||||
};
|
||||
@@ -817,13 +818,13 @@ impl ToComputedValue for specified::FontSizeAdjust {
|
||||
// returns the fallback value, or if that is negative, resolves using ascent instead
|
||||
// of the missing field (this is the fallback for cap-height).
|
||||
macro_rules! resolve {
|
||||
($basis:ident, $value:expr, $vertical:expr, $field:ident, $fallback:expr) => {{
|
||||
($basis:ident, $value:expr, $vertical:expr, $field:ident, $fallback:expr, $flags:expr) => {{
|
||||
match $value {
|
||||
specified::FontSizeAdjustFactor::Number(f) => {
|
||||
FontSizeAdjust::$basis(f.to_computed_value(context))
|
||||
},
|
||||
specified::FontSizeAdjustFactor::FromFont => {
|
||||
let (metrics, font_size) = font_metrics($vertical);
|
||||
let (metrics, font_size) = font_metrics($vertical, $flags);
|
||||
let ratio = if let Some(metric) = metrics.$field {
|
||||
metric / font_size
|
||||
} else if $fallback >= 0.0 {
|
||||
@@ -843,13 +844,21 @@ impl ToComputedValue for specified::FontSizeAdjust {
|
||||
|
||||
match *self {
|
||||
Self::None => FontSizeAdjust::None,
|
||||
Self::ExHeight(val) => resolve!(ExHeight, val, false, x_height, 0.5),
|
||||
Self::CapHeight(val) => {
|
||||
resolve!(CapHeight, val, false, cap_height, -1.0 /* fall back to ascent */)
|
||||
Self::ExHeight(val) => {
|
||||
resolve!(ExHeight, val, false, x_height, 0.5, QueryFontMetricsFlags::empty())
|
||||
},
|
||||
Self::CapHeight(val) => {
|
||||
resolve!(CapHeight, val, false, cap_height, -1.0 /* fall back to ascent */, QueryFontMetricsFlags::empty())
|
||||
},
|
||||
Self::ChWidth(val) => {
|
||||
resolve!(ChWidth, val, false, zero_advance_measure, 0.5, QueryFontMetricsFlags::NEEDS_CH)
|
||||
},
|
||||
Self::IcWidth(val) => {
|
||||
resolve!(IcWidth, val, false, ic_width, 1.0, QueryFontMetricsFlags::NEEDS_IC)
|
||||
},
|
||||
Self::IcHeight(val) => {
|
||||
resolve!(IcHeight, val, true, ic_width, 1.0, QueryFontMetricsFlags::NEEDS_IC)
|
||||
},
|
||||
Self::ChWidth(val) => resolve!(ChWidth, val, false, zero_advance_measure, 0.5),
|
||||
Self::IcWidth(val) => resolve!(IcWidth, val, false, ic_width, 1.0),
|
||||
Self::IcHeight(val) => resolve!(IcHeight, val, true, ic_width, 1.0),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ use crate::computed_value_flags::ComputedValueFlags;
|
||||
use crate::context::QuirksMode;
|
||||
use crate::custom_properties::ComputedCustomProperties;
|
||||
use crate::font_metrics::{FontMetrics, FontMetricsOrientation};
|
||||
use crate::gecko::media_queries::QueryFontMetricsFlags;
|
||||
use crate::media_queries::Device;
|
||||
#[cfg(feature = "gecko")]
|
||||
use crate::properties;
|
||||
@@ -363,7 +364,7 @@ impl<'a> Context<'a> {
|
||||
&self,
|
||||
base_size: FontBaseSize,
|
||||
orientation: FontMetricsOrientation,
|
||||
retrieve_math_scales: bool,
|
||||
mut flags: QueryFontMetricsFlags,
|
||||
) -> FontMetrics {
|
||||
if self.for_non_inherited_property {
|
||||
self.rule_cache_conditions.borrow_mut().set_uncacheable();
|
||||
@@ -390,12 +391,14 @@ impl<'a> Context<'a> {
|
||||
FontMetricsOrientation::MatchContextPreferVertical => wm.is_text_vertical(),
|
||||
FontMetricsOrientation::Horizontal => false,
|
||||
};
|
||||
if !self.in_media_or_container_query() {
|
||||
flags |= QueryFontMetricsFlags::USE_USER_FONT_SET
|
||||
}
|
||||
self.device().query_font_metrics(
|
||||
vertical,
|
||||
font,
|
||||
size,
|
||||
self.in_media_or_container_query(),
|
||||
retrieve_math_scales,
|
||||
flags,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
use super::{AllowQuirks, Number, Percentage, ToComputedValue};
|
||||
use crate::computed_value_flags::ComputedValueFlags;
|
||||
use crate::font_metrics::{FontMetrics, FontMetricsOrientation};
|
||||
use crate::gecko::media_queries::QueryFontMetricsFlags;
|
||||
#[cfg(feature = "gecko")]
|
||||
use crate::gecko_bindings::structs::GeckoFontMetrics;
|
||||
use crate::parser::{Parse, ParserContext};
|
||||
@@ -249,9 +250,13 @@ impl FontRelativeLength {
|
||||
context: &Context,
|
||||
base_size: FontBaseSize,
|
||||
orientation: FontMetricsOrientation,
|
||||
flags: QueryFontMetricsFlags,
|
||||
) -> FontMetrics {
|
||||
let retrieve_math_scales = false;
|
||||
context.query_font_metrics(base_size, orientation, retrieve_math_scales)
|
||||
context.query_font_metrics(
|
||||
base_size,
|
||||
orientation,
|
||||
flags,
|
||||
)
|
||||
}
|
||||
|
||||
let reference_font_size = base_size.resolve(context);
|
||||
@@ -268,8 +273,12 @@ impl FontRelativeLength {
|
||||
},
|
||||
Self::Ex(length) => {
|
||||
// The x-height is an intrinsically horizontal metric.
|
||||
let metrics =
|
||||
query_font_metrics(context, base_size, FontMetricsOrientation::Horizontal);
|
||||
let metrics = query_font_metrics(
|
||||
context,
|
||||
base_size,
|
||||
FontMetricsOrientation::Horizontal,
|
||||
QueryFontMetricsFlags::empty(),
|
||||
);
|
||||
let reference_size = metrics.x_height.unwrap_or_else(|| {
|
||||
// https://drafts.csswg.org/css-values/#ex
|
||||
//
|
||||
@@ -295,6 +304,7 @@ impl FontRelativeLength {
|
||||
context,
|
||||
base_size,
|
||||
FontMetricsOrientation::MatchContextPreferHorizontal,
|
||||
QueryFontMetricsFlags::NEEDS_CH,
|
||||
);
|
||||
let reference_size = metrics.zero_advance_measure.unwrap_or_else(|| {
|
||||
// https://drafts.csswg.org/css-values/#ch
|
||||
@@ -319,8 +329,12 @@ impl FontRelativeLength {
|
||||
(reference_size, length)
|
||||
},
|
||||
Self::Cap(length) => {
|
||||
let metrics =
|
||||
query_font_metrics(context, base_size, FontMetricsOrientation::Horizontal);
|
||||
let metrics = query_font_metrics(
|
||||
context,
|
||||
base_size,
|
||||
FontMetricsOrientation::Horizontal,
|
||||
QueryFontMetricsFlags::empty(),
|
||||
);
|
||||
let reference_size = metrics.cap_height.unwrap_or_else(|| {
|
||||
// https://drafts.csswg.org/css-values/#cap
|
||||
//
|
||||
@@ -337,6 +351,7 @@ impl FontRelativeLength {
|
||||
context,
|
||||
base_size,
|
||||
FontMetricsOrientation::MatchContextPreferVertical,
|
||||
QueryFontMetricsFlags::NEEDS_IC,
|
||||
);
|
||||
let reference_size = metrics.ic_width.unwrap_or_else(|| {
|
||||
// https://drafts.csswg.org/css-values/#ic
|
||||
|
||||
Reference in New Issue
Block a user