diff options
-rw-r--r-- | components/style/font_metrics.rs | 13 | ||||
-rw-r--r-- | components/style/gecko/wrapper.rs | 9 | ||||
-rw-r--r-- | components/style/values/specified/length.rs | 28 |
3 files changed, 42 insertions, 8 deletions
diff --git a/components/style/font_metrics.rs b/components/style/font_metrics.rs index c1707d1fbc1..15b5fd453e8 100644 --- a/components/style/font_metrics.rs +++ b/components/style/font_metrics.rs @@ -20,6 +20,16 @@ pub struct FontMetrics { pub zero_advance_measure: Option<Au>, } +/// Type of font metrics to retrieve. +#[derive(Clone, Debug, PartialEq)] +pub enum FontMetricsOrientation { + /// Get metrics for horizontal or vertical according to the Context's + /// writing mode. + MatchContext, + /// Force getting horizontal metrics. + Horizontal, +} + /// A trait used to represent something capable of providing us font metrics. pub trait FontMetricsProvider { /// Obtain the metrics for given font family. @@ -27,7 +37,8 @@ pub trait FontMetricsProvider { &self, _context: &crate::values::computed::Context, _base_size: crate::values::specified::length::FontBaseSize, - ) -> FontMetricsQueryResult { + _orientation: FontMetricsOrientation, + ) -> FontMetrics { Default::default() } diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 8055cd316ea..ee3dcced3e4 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -20,7 +20,7 @@ use crate::context::{PostAnimationTasks, QuirksMode, SharedStyleContext, UpdateA use crate::data::ElementData; use crate::dom::{LayoutIterator, NodeInfo, OpaqueNode, TDocument, TElement, TNode, TShadowRoot}; use crate::element_state::{DocumentState, ElementState}; -use crate::font_metrics::{FontMetrics, FontMetricsProvider}; +use crate::font_metrics::{FontMetrics, FontMetricsOrientation, FontMetricsProvider}; use crate::gecko::data::GeckoStyleSheet; use crate::gecko::selector_parser::{NonTSPseudoClass, PseudoElement, SelectorImpl}; use crate::gecko::snapshot_helpers; @@ -1035,6 +1035,7 @@ impl FontMetricsProvider for GeckoFontMetricsProvider { &self, context: &crate::values::computed::Context, base_size: FontBaseSize, + orientation: FontMetricsOrientation, ) -> FontMetrics { let pc = match context.device().pres_context() { Some(pc) => pc, @@ -1056,10 +1057,14 @@ impl FontMetricsProvider for GeckoFontMetricsProvider { }, }; + let vertical_metrics = match orientation { + FontMetricsOrientation::MatchContext => wm.is_vertical() && wm.is_upright(), + FontMetricsOrientation::Horizontal => false, + }; let gecko_metrics = unsafe { bindings::Gecko_GetFontMetrics( pc, - wm.is_vertical() && !wm.is_sideways(), + vertical_metrics, font.gecko(), size.0, // we don't use the user font set in a media query diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index 38cf272c795..750378682bb 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -7,7 +7,7 @@ //! [length]: https://drafts.csswg.org/css-values/#lengths use super::{AllowQuirks, Number, Percentage, ToComputedValue}; -use crate::font_metrics::FontMetrics; +use crate::font_metrics::{FontMetrics, FontMetricsOrientation}; use crate::parser::{Parse, ParserContext}; use crate::properties::computed_value_flags::ComputedValueFlags; use crate::values::computed::{self, CSSPixelLength, Context}; @@ -133,8 +133,9 @@ impl FontRelativeLength { fn query_font_metrics( context: &Context, base_size: FontBaseSize, + orientation: FontMetricsOrientation, ) -> FontMetrics { - context.font_metrics_provider.query(context, base_size) + context.font_metrics_provider.query(context, base_size, orientation) } let reference_font_size = base_size.resolve(context); @@ -160,7 +161,12 @@ impl FontRelativeLength { context.rule_cache_conditions.borrow_mut().set_uncacheable(); } context.builder.add_flags(ComputedValueFlags::DEPENDS_ON_FONT_METRICS); - let metrics = query_font_metrics(context, base_size); + // The x-height is an intrinsically horizontal metric. + let metrics = query_font_metrics( + context, + base_size, + FontMetricsOrientation::Horizontal + ); let reference_size = metrics.x_height.unwrap_or_else(|| { // https://drafts.csswg.org/css-values/#ex // @@ -177,7 +183,18 @@ impl FontRelativeLength { context.rule_cache_conditions.borrow_mut().set_uncacheable(); } context.builder.add_flags(ComputedValueFlags::DEPENDS_ON_FONT_METRICS); - let metrics = query_font_metrics(context, base_size); + // https://drafts.csswg.org/css-values/#ch: + // + // Equal to the used advance measure of the “0” (ZERO, + // U+0030) glyph in the font used to render it. (The advance + // measure of a glyph is its advance width or height, + // whichever is in the inline axis of the element.) + // + let metrics = query_font_metrics( + context, + base_size, + FontMetricsOrientation::MatchContext, + ); let reference_size = metrics.zero_advance_measure.unwrap_or_else(|| { // https://drafts.csswg.org/css-values/#ch // @@ -189,7 +206,8 @@ impl FontRelativeLength { // writing-mode is vertical-rl or vertical-lr and // text-orientation is upright). // - if context.style().writing_mode.is_vertical() { + let wm = context.style().writing_mode; + if wm.is_vertical() && wm.is_upright() { reference_font_size } else { reference_font_size.scale_by(0.5) |