diff options
author | bors-servo <infra@servo.org> | 2023-05-11 18:41:09 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-11 18:41:09 +0200 |
commit | feaa66b5972c3e31d77c2acce7d626c455320535 (patch) | |
tree | 0599544c17bd29578ccdb6d03272bf843dc4e406 | |
parent | 425b0fe641e16083507c459041ff5dd19256ed7c (diff) | |
parent | 6785c57c788dd08fc128f0c72758d60c9b8bcfc4 (diff) | |
download | servo-feaa66b5972c3e31d77c2acce7d626c455320535.tar.gz servo-feaa66b5972c3e31d77c2acce7d626c455320535.zip |
Auto merge of #29729 - Loirooriol:sync-cap-D133101, r=mrobinson
Add support for the 'cap' font-relative unit
This is a backport of https://phabricator.services.mozilla.com/D133101, by Jonathan Kew.
Note that Servo isn't using font metrics yet, so the unit still won't really work.
<!-- Please describe your changes on the following line: -->
---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [ ] These changes fix #___ (GitHub issue number if applicable)
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because ___
<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->
<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
-rw-r--r-- | components/style/font_metrics.rs | 24 | ||||
-rw-r--r-- | components/style/gecko/wrapper.rs | 13 | ||||
-rw-r--r-- | components/style/values/generics/calc.rs | 1 | ||||
-rw-r--r-- | components/style/values/specified/calc.rs | 1 | ||||
-rw-r--r-- | components/style/values/specified/length.rs | 37 |
5 files changed, 68 insertions, 8 deletions
diff --git a/components/style/font_metrics.rs b/components/style/font_metrics.rs index b521fdf76c9..db435539735 100644 --- a/components/style/font_metrics.rs +++ b/components/style/font_metrics.rs @@ -12,20 +12,38 @@ use crate::Atom; /// Represents the font metrics that style needs from a font to compute the /// value of certain CSS units like `ex`. -#[derive(Clone, Debug, Default, PartialEq)] +#[derive(Clone, Debug, PartialEq)] pub struct FontMetrics { /// The x-height of the font. pub x_height: Option<Length>, /// The zero advance. This is usually writing mode dependent pub zero_advance_measure: Option<Length>, + /// The cap-height of the font. + pub cap_height: Option<Length>, + /// The ascent of the font (a value is always available for this). + pub ascent: Length, +} + +impl Default for FontMetrics { + fn default() -> Self { + FontMetrics { + x_height: None, + zero_advance_measure: None, + cap_height: None, + ascent: Length::new(0.0), + } + } } /// 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, + /// writing mode, using horizontal metrics for vertical/mixed + MatchContextPreferHorizontal, + /// Get metrics for horizontal or vertical according to the Context's + /// writing mode, using vertical metrics for vertical/mixed + MatchContextPreferVertical, /// Force getting horizontal metrics. Horizontal, } diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 1813c225c57..78e41cf767f 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -979,7 +979,12 @@ impl FontMetricsProvider for GeckoFontMetricsProvider { }; let vertical_metrics = match orientation { - FontMetricsOrientation::MatchContext => wm.is_vertical() && wm.is_upright(), + FontMetricsOrientation::MatchContextPreferHorizontal => { + wm.is_vertical() && wm.is_upright() + }, + FontMetricsOrientation::MatchContextPreferVertical => { + wm.is_vertical() && !wm.is_sideways() + }, FontMetricsOrientation::Horizontal => false, }; let gecko_metrics = unsafe { @@ -999,6 +1004,12 @@ impl FontMetricsProvider for GeckoFontMetricsProvider { } else { None }, + cap_height: if gecko_metrics.mCapHeight.px() >= 0. { + Some(gecko_metrics.mCapHeight) + } else { + None + }, + ascent: gecko_metrics.mAscent, } } } diff --git a/components/style/values/generics/calc.rs b/components/style/values/generics/calc.rs index 0d791e5d00d..d2bc2a85523 100644 --- a/components/style/values/generics/calc.rs +++ b/components/style/values/generics/calc.rs @@ -42,6 +42,7 @@ pub enum MinMaxOp { pub enum SortKey { Number, Percentage, + Cap, Ch, Deg, Em, diff --git a/components/style/values/specified/calc.rs b/components/style/values/specified/calc.rs index eb8b2fe4217..c42683bce1f 100644 --- a/components/style/values/specified/calc.rs +++ b/components/style/values/specified/calc.rs @@ -168,6 +168,7 @@ impl generic::CalcNodeLeaf for Leaf { FontRelativeLength::Ch(..) => SortKey::Ch, FontRelativeLength::Em(..) => SortKey::Em, FontRelativeLength::Ex(..) => SortKey::Ex, + FontRelativeLength::Cap(..) => SortKey::Cap, FontRelativeLength::Rem(..) => SortKey::Rem, }, NoCalcLength::ViewportPercentage(ref vp) => match *vp { diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index 7c03e8dce42..62f070893a6 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -57,6 +57,9 @@ pub enum FontRelativeLength { /// A "ch" value: https://drafts.csswg.org/css-values/#ch #[css(dimension)] Ch(CSSFloat), + /// A "cap" value: https://drafts.csswg.org/css-values/#cap + #[css(dimension)] + Cap(CSSFloat), /// A "rem" value: https://drafts.csswg.org/css-values/#rem #[css(dimension)] Rem(CSSFloat), @@ -90,6 +93,7 @@ impl FontRelativeLength { FontRelativeLength::Em(v) | FontRelativeLength::Ex(v) | FontRelativeLength::Ch(v) | + FontRelativeLength::Cap(v) | FontRelativeLength::Rem(v) => v == 0., } } @@ -99,6 +103,7 @@ impl FontRelativeLength { FontRelativeLength::Em(v) | FontRelativeLength::Ex(v) | FontRelativeLength::Ch(v) | + FontRelativeLength::Cap(v) | FontRelativeLength::Rem(v) => v < 0., } } @@ -114,12 +119,13 @@ impl FontRelativeLength { (&Em(one), &Em(other)) => Em(one + other), (&Ex(one), &Ex(other)) => Ex(one + other), (&Ch(one), &Ch(other)) => Ch(one + other), + (&Cap(one), &Cap(other)) => Cap(one + other), (&Rem(one), &Rem(other)) => Rem(one + other), // See https://github.com/rust-lang/rust/issues/68867. rustc isn't // able to figure it own on its own so we help. _ => unsafe { match *self { - Em(..) | Ex(..) | Ch(..) | Rem(..) => {}, + Em(..) | Ex(..) | Ch(..) | Cap(..) | Rem(..) => {}, } debug_unreachable!("Forgot to handle unit in try_sum()") }, @@ -207,8 +213,11 @@ impl FontRelativeLength { // 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 metrics = query_font_metrics( + context, + base_size, + FontMetricsOrientation::MatchContextPreferHorizontal, + ); let reference_size = metrics.zero_advance_measure.unwrap_or_else(|| { // https://drafts.csswg.org/css-values/#ch // @@ -229,6 +238,23 @@ impl FontRelativeLength { }); (reference_size, length) }, + FontRelativeLength::Cap(length) => { + if context.for_non_inherited_property.is_some() { + context.rule_cache_conditions.borrow_mut().set_uncacheable(); + } + context.builder.add_flags(font_metrics_flag); + let metrics = + query_font_metrics(context, base_size, FontMetricsOrientation::Horizontal); + let reference_size = metrics.cap_height.unwrap_or_else(|| { + // https://drafts.csswg.org/css-values/#cap + // + // In the cases where it is impossible or impractical to + // determine the cap-height, the font’s ascent must be used. + // + metrics.ascent + }); + (reference_size, length) + }, FontRelativeLength::Rem(length) => { // https://drafts.csswg.org/css-values/#rem: // @@ -540,6 +566,7 @@ impl NoCalcLength { "em" => NoCalcLength::FontRelative(FontRelativeLength::Em(value)), "ex" => NoCalcLength::FontRelative(FontRelativeLength::Ex(value)), "ch" => NoCalcLength::FontRelative(FontRelativeLength::Ch(value)), + "cap" => NoCalcLength::FontRelative(FontRelativeLength::Cap(value)), "rem" => NoCalcLength::FontRelative(FontRelativeLength::Rem(value)), // viewport percentages "vw" if !context.in_page_rule() => { @@ -699,12 +726,13 @@ impl PartialOrd for FontRelativeLength { (&Em(ref one), &Em(ref other)) => one.partial_cmp(other), (&Ex(ref one), &Ex(ref other)) => one.partial_cmp(other), (&Ch(ref one), &Ch(ref other)) => one.partial_cmp(other), + (&Cap(ref one), &Cap(ref other)) => one.partial_cmp(other), (&Rem(ref one), &Rem(ref other)) => one.partial_cmp(other), // See https://github.com/rust-lang/rust/issues/68867. rustc isn't // able to figure it own on its own so we help. _ => unsafe { match *self { - Em(..) | Ex(..) | Ch(..) | Rem(..) => {}, + Em(..) | Ex(..) | Ch(..) | Cap(..) | Rem(..) => {}, } debug_unreachable!("Forgot an arm in partial_cmp?") }, @@ -721,6 +749,7 @@ impl Mul<CSSFloat> for FontRelativeLength { FontRelativeLength::Em(v) => FontRelativeLength::Em(v * scalar), FontRelativeLength::Ex(v) => FontRelativeLength::Ex(v * scalar), FontRelativeLength::Ch(v) => FontRelativeLength::Ch(v * scalar), + FontRelativeLength::Cap(v) => FontRelativeLength::Cap(v * scalar), FontRelativeLength::Rem(v) => FontRelativeLength::Rem(v * scalar), } } |