mirror of
https://github.com/servo/servo.git
synced 2025-08-07 14:35:33 +01:00
style: Allow FontMetricsProvider to produce ex height and zero width independently.
We are always able to produce an x height, but depending on whether the glyph exists, we sometimes can't produce a zero glyph width. Differential Revision: https://phabricator.services.mozilla.com/D23424
This commit is contained in:
parent
39df092bce
commit
d5f208e18c
3 changed files with 29 additions and 38 deletions
|
@ -12,22 +12,12 @@ use app_units::Au;
|
||||||
|
|
||||||
/// Represents the font metrics that style needs from a font to compute the
|
/// Represents the font metrics that style needs from a font to compute the
|
||||||
/// value of certain CSS units like `ex`.
|
/// value of certain CSS units like `ex`.
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, Default, PartialEq)]
|
||||||
pub struct FontMetrics {
|
pub struct FontMetrics {
|
||||||
/// The x-height of the font.
|
/// The x-height of the font.
|
||||||
pub x_height: Au,
|
pub x_height: Option<Au>,
|
||||||
/// The zero advance. This is usually writing mode dependent
|
/// The zero advance. This is usually writing mode dependent
|
||||||
pub zero_advance_measure: Au,
|
pub zero_advance_measure: Option<Au>,
|
||||||
}
|
|
||||||
|
|
||||||
/// The result for querying font metrics for a given font family.
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub enum FontMetricsQueryResult {
|
|
||||||
/// The font is available, but we may or may not have found any font metrics
|
|
||||||
/// for it.
|
|
||||||
Available(FontMetrics),
|
|
||||||
/// The font is not available.
|
|
||||||
NotAvailable,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A trait used to represent something capable of providing us font metrics.
|
/// A trait used to represent something capable of providing us font metrics.
|
||||||
|
@ -38,7 +28,7 @@ pub trait FontMetricsProvider {
|
||||||
_context: &crate::values::computed::Context,
|
_context: &crate::values::computed::Context,
|
||||||
_base_size: crate::values::specified::length::FontBaseSize,
|
_base_size: crate::values::specified::length::FontBaseSize,
|
||||||
) -> FontMetricsQueryResult {
|
) -> FontMetricsQueryResult {
|
||||||
FontMetricsQueryResult::NotAvailable
|
Default::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get default size of a given language and generic family.
|
/// Get default size of a given language and generic family.
|
||||||
|
|
|
@ -20,7 +20,7 @@ use crate::context::{PostAnimationTasks, QuirksMode, SharedStyleContext, UpdateA
|
||||||
use crate::data::ElementData;
|
use crate::data::ElementData;
|
||||||
use crate::dom::{LayoutIterator, NodeInfo, OpaqueNode, TDocument, TElement, TNode, TShadowRoot};
|
use crate::dom::{LayoutIterator, NodeInfo, OpaqueNode, TDocument, TElement, TNode, TShadowRoot};
|
||||||
use crate::element_state::{DocumentState, ElementState};
|
use crate::element_state::{DocumentState, ElementState};
|
||||||
use crate::font_metrics::{FontMetrics, FontMetricsProvider, FontMetricsQueryResult};
|
use crate::font_metrics::{FontMetrics, FontMetricsProvider};
|
||||||
use crate::gecko::data::GeckoStyleSheet;
|
use crate::gecko::data::GeckoStyleSheet;
|
||||||
use crate::gecko::selector_parser::{NonTSPseudoClass, PseudoElement, SelectorImpl};
|
use crate::gecko::selector_parser::{NonTSPseudoClass, PseudoElement, SelectorImpl};
|
||||||
use crate::gecko::snapshot_helpers;
|
use crate::gecko::snapshot_helpers;
|
||||||
|
@ -1035,10 +1035,10 @@ impl FontMetricsProvider for GeckoFontMetricsProvider {
|
||||||
&self,
|
&self,
|
||||||
context: &crate::values::computed::Context,
|
context: &crate::values::computed::Context,
|
||||||
base_size: FontBaseSize,
|
base_size: FontBaseSize,
|
||||||
) -> FontMetricsQueryResult {
|
) -> FontMetrics {
|
||||||
let pc = match context.device().pres_context() {
|
let pc = match context.device().pres_context() {
|
||||||
Some(pc) => pc,
|
Some(pc) => pc,
|
||||||
None => return FontMetricsQueryResult::NotAvailable,
|
None => return Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let size = base_size.resolve(context);
|
let size = base_size.resolve(context);
|
||||||
|
@ -1066,11 +1066,14 @@ impl FontMetricsProvider for GeckoFontMetricsProvider {
|
||||||
!context.in_media_query,
|
!context.in_media_query,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
let metrics = FontMetrics {
|
FontMetrics {
|
||||||
x_height: Au(gecko_metrics.mXSize),
|
x_height: Some(Au(gecko_metrics.mXSize)),
|
||||||
zero_advance_measure: Au(gecko_metrics.mChSize),
|
zero_advance_measure: if gecko_metrics.mChSize >= 0 {
|
||||||
};
|
Some(Au(gecko_metrics.mChSize))
|
||||||
FontMetricsQueryResult::Available(metrics)
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
//! [length]: https://drafts.csswg.org/css-values/#lengths
|
//! [length]: https://drafts.csswg.org/css-values/#lengths
|
||||||
|
|
||||||
use super::{AllowQuirks, Number, Percentage, ToComputedValue};
|
use super::{AllowQuirks, Number, Percentage, ToComputedValue};
|
||||||
use crate::font_metrics::FontMetricsQueryResult;
|
use crate::font_metrics::FontMetrics;
|
||||||
use crate::parser::{Parse, ParserContext};
|
use crate::parser::{Parse, ParserContext};
|
||||||
use crate::properties::computed_value_flags::ComputedValueFlags;
|
use crate::properties::computed_value_flags::ComputedValueFlags;
|
||||||
use crate::values::computed::{self, CSSPixelLength, Context};
|
use crate::values::computed::{self, CSSPixelLength, Context};
|
||||||
|
@ -133,7 +133,7 @@ impl FontRelativeLength {
|
||||||
fn query_font_metrics(
|
fn query_font_metrics(
|
||||||
context: &Context,
|
context: &Context,
|
||||||
base_size: FontBaseSize,
|
base_size: FontBaseSize,
|
||||||
) -> FontMetricsQueryResult {
|
) -> FontMetrics {
|
||||||
context.font_metrics_provider.query(context, base_size)
|
context.font_metrics_provider.query(context, base_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,16 +160,16 @@ impl FontRelativeLength {
|
||||||
context.rule_cache_conditions.borrow_mut().set_uncacheable();
|
context.rule_cache_conditions.borrow_mut().set_uncacheable();
|
||||||
}
|
}
|
||||||
context.builder.add_flags(ComputedValueFlags::DEPENDS_ON_FONT_METRICS);
|
context.builder.add_flags(ComputedValueFlags::DEPENDS_ON_FONT_METRICS);
|
||||||
let reference_size = match query_font_metrics(context, base_size) {
|
let metrics = query_font_metrics(context, base_size);
|
||||||
FontMetricsQueryResult::Available(metrics) => metrics.x_height,
|
let reference_size = metrics.x_height.unwrap_or_else(|| {
|
||||||
// https://drafts.csswg.org/css-values/#ex
|
// https://drafts.csswg.org/css-values/#ex
|
||||||
//
|
//
|
||||||
// In the cases where it is impossible or impractical to
|
// In the cases where it is impossible or impractical to
|
||||||
// determine the x-height, a value of 0.5em must be
|
// determine the x-height, a value of 0.5em must be
|
||||||
// assumed.
|
// assumed.
|
||||||
//
|
//
|
||||||
FontMetricsQueryResult::NotAvailable => reference_font_size.scale_by(0.5),
|
reference_font_size.scale_by(0.5)
|
||||||
};
|
});
|
||||||
(reference_size, length)
|
(reference_size, length)
|
||||||
},
|
},
|
||||||
FontRelativeLength::Ch(length) => {
|
FontRelativeLength::Ch(length) => {
|
||||||
|
@ -177,8 +177,8 @@ impl FontRelativeLength {
|
||||||
context.rule_cache_conditions.borrow_mut().set_uncacheable();
|
context.rule_cache_conditions.borrow_mut().set_uncacheable();
|
||||||
}
|
}
|
||||||
context.builder.add_flags(ComputedValueFlags::DEPENDS_ON_FONT_METRICS);
|
context.builder.add_flags(ComputedValueFlags::DEPENDS_ON_FONT_METRICS);
|
||||||
let reference_size = match query_font_metrics(context, base_size) {
|
let metrics = query_font_metrics(context, base_size);
|
||||||
FontMetricsQueryResult::Available(metrics) => metrics.zero_advance_measure,
|
let reference_size = metrics.zero_advance_measure.unwrap_or_else(|| {
|
||||||
// https://drafts.csswg.org/css-values/#ch
|
// https://drafts.csswg.org/css-values/#ch
|
||||||
//
|
//
|
||||||
// In the cases where it is impossible or impractical to
|
// In the cases where it is impossible or impractical to
|
||||||
|
@ -189,14 +189,12 @@ impl FontRelativeLength {
|
||||||
// writing-mode is vertical-rl or vertical-lr and
|
// writing-mode is vertical-rl or vertical-lr and
|
||||||
// text-orientation is upright).
|
// text-orientation is upright).
|
||||||
//
|
//
|
||||||
FontMetricsQueryResult::NotAvailable => {
|
if context.style().writing_mode.is_vertical() {
|
||||||
if context.style().writing_mode.is_vertical() {
|
reference_font_size
|
||||||
reference_font_size
|
} else {
|
||||||
} else {
|
reference_font_size.scale_by(0.5)
|
||||||
reference_font_size.scale_by(0.5)
|
}
|
||||||
}
|
});
|
||||||
},
|
|
||||||
};
|
|
||||||
(reference_size, length)
|
(reference_size, length)
|
||||||
},
|
},
|
||||||
FontRelativeLength::Rem(length) => {
|
FontRelativeLength::Rem(length) => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue