mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
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. -->
This commit is contained in:
commit
feaa66b597
5 changed files with 68 additions and 8 deletions
|
@ -12,20 +12,38 @@ use crate::Atom;
|
||||||
|
|
||||||
/// 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, Default, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct FontMetrics {
|
pub struct FontMetrics {
|
||||||
/// The x-height of the font.
|
/// The x-height of the font.
|
||||||
pub x_height: Option<Length>,
|
pub x_height: Option<Length>,
|
||||||
/// The zero advance. This is usually writing mode dependent
|
/// The zero advance. This is usually writing mode dependent
|
||||||
pub zero_advance_measure: Option<Length>,
|
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.
|
/// Type of font metrics to retrieve.
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum FontMetricsOrientation {
|
pub enum FontMetricsOrientation {
|
||||||
/// Get metrics for horizontal or vertical according to the Context's
|
/// Get metrics for horizontal or vertical according to the Context's
|
||||||
/// writing mode.
|
/// writing mode, using horizontal metrics for vertical/mixed
|
||||||
MatchContext,
|
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.
|
/// Force getting horizontal metrics.
|
||||||
Horizontal,
|
Horizontal,
|
||||||
}
|
}
|
||||||
|
|
|
@ -979,7 +979,12 @@ impl FontMetricsProvider for GeckoFontMetricsProvider {
|
||||||
};
|
};
|
||||||
|
|
||||||
let vertical_metrics = match orientation {
|
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,
|
FontMetricsOrientation::Horizontal => false,
|
||||||
};
|
};
|
||||||
let gecko_metrics = unsafe {
|
let gecko_metrics = unsafe {
|
||||||
|
@ -999,6 +1004,12 @@ impl FontMetricsProvider for GeckoFontMetricsProvider {
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
|
cap_height: if gecko_metrics.mCapHeight.px() >= 0. {
|
||||||
|
Some(gecko_metrics.mCapHeight)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
ascent: gecko_metrics.mAscent,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ pub enum MinMaxOp {
|
||||||
pub enum SortKey {
|
pub enum SortKey {
|
||||||
Number,
|
Number,
|
||||||
Percentage,
|
Percentage,
|
||||||
|
Cap,
|
||||||
Ch,
|
Ch,
|
||||||
Deg,
|
Deg,
|
||||||
Em,
|
Em,
|
||||||
|
|
|
@ -168,6 +168,7 @@ impl generic::CalcNodeLeaf for Leaf {
|
||||||
FontRelativeLength::Ch(..) => SortKey::Ch,
|
FontRelativeLength::Ch(..) => SortKey::Ch,
|
||||||
FontRelativeLength::Em(..) => SortKey::Em,
|
FontRelativeLength::Em(..) => SortKey::Em,
|
||||||
FontRelativeLength::Ex(..) => SortKey::Ex,
|
FontRelativeLength::Ex(..) => SortKey::Ex,
|
||||||
|
FontRelativeLength::Cap(..) => SortKey::Cap,
|
||||||
FontRelativeLength::Rem(..) => SortKey::Rem,
|
FontRelativeLength::Rem(..) => SortKey::Rem,
|
||||||
},
|
},
|
||||||
NoCalcLength::ViewportPercentage(ref vp) => match *vp {
|
NoCalcLength::ViewportPercentage(ref vp) => match *vp {
|
||||||
|
|
|
@ -57,6 +57,9 @@ pub enum FontRelativeLength {
|
||||||
/// A "ch" value: https://drafts.csswg.org/css-values/#ch
|
/// A "ch" value: https://drafts.csswg.org/css-values/#ch
|
||||||
#[css(dimension)]
|
#[css(dimension)]
|
||||||
Ch(CSSFloat),
|
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
|
/// A "rem" value: https://drafts.csswg.org/css-values/#rem
|
||||||
#[css(dimension)]
|
#[css(dimension)]
|
||||||
Rem(CSSFloat),
|
Rem(CSSFloat),
|
||||||
|
@ -90,6 +93,7 @@ impl FontRelativeLength {
|
||||||
FontRelativeLength::Em(v) |
|
FontRelativeLength::Em(v) |
|
||||||
FontRelativeLength::Ex(v) |
|
FontRelativeLength::Ex(v) |
|
||||||
FontRelativeLength::Ch(v) |
|
FontRelativeLength::Ch(v) |
|
||||||
|
FontRelativeLength::Cap(v) |
|
||||||
FontRelativeLength::Rem(v) => v == 0.,
|
FontRelativeLength::Rem(v) => v == 0.,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,6 +103,7 @@ impl FontRelativeLength {
|
||||||
FontRelativeLength::Em(v) |
|
FontRelativeLength::Em(v) |
|
||||||
FontRelativeLength::Ex(v) |
|
FontRelativeLength::Ex(v) |
|
||||||
FontRelativeLength::Ch(v) |
|
FontRelativeLength::Ch(v) |
|
||||||
|
FontRelativeLength::Cap(v) |
|
||||||
FontRelativeLength::Rem(v) => v < 0.,
|
FontRelativeLength::Rem(v) => v < 0.,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,12 +119,13 @@ impl FontRelativeLength {
|
||||||
(&Em(one), &Em(other)) => Em(one + other),
|
(&Em(one), &Em(other)) => Em(one + other),
|
||||||
(&Ex(one), &Ex(other)) => Ex(one + other),
|
(&Ex(one), &Ex(other)) => Ex(one + other),
|
||||||
(&Ch(one), &Ch(other)) => Ch(one + other),
|
(&Ch(one), &Ch(other)) => Ch(one + other),
|
||||||
|
(&Cap(one), &Cap(other)) => Cap(one + other),
|
||||||
(&Rem(one), &Rem(other)) => Rem(one + other),
|
(&Rem(one), &Rem(other)) => Rem(one + other),
|
||||||
// See https://github.com/rust-lang/rust/issues/68867. rustc isn't
|
// See https://github.com/rust-lang/rust/issues/68867. rustc isn't
|
||||||
// able to figure it own on its own so we help.
|
// able to figure it own on its own so we help.
|
||||||
_ => unsafe {
|
_ => unsafe {
|
||||||
match *self {
|
match *self {
|
||||||
Em(..) | Ex(..) | Ch(..) | Rem(..) => {},
|
Em(..) | Ex(..) | Ch(..) | Cap(..) | Rem(..) => {},
|
||||||
}
|
}
|
||||||
debug_unreachable!("Forgot to handle unit in try_sum()")
|
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,
|
// measure of a glyph is its advance width or height,
|
||||||
// whichever is in the inline axis of the element.)
|
// whichever is in the inline axis of the element.)
|
||||||
//
|
//
|
||||||
let metrics =
|
let metrics = query_font_metrics(
|
||||||
query_font_metrics(context, base_size, FontMetricsOrientation::MatchContext);
|
context,
|
||||||
|
base_size,
|
||||||
|
FontMetricsOrientation::MatchContextPreferHorizontal,
|
||||||
|
);
|
||||||
let reference_size = metrics.zero_advance_measure.unwrap_or_else(|| {
|
let reference_size = metrics.zero_advance_measure.unwrap_or_else(|| {
|
||||||
// https://drafts.csswg.org/css-values/#ch
|
// https://drafts.csswg.org/css-values/#ch
|
||||||
//
|
//
|
||||||
|
@ -229,6 +238,23 @@ impl FontRelativeLength {
|
||||||
});
|
});
|
||||||
(reference_size, length)
|
(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) => {
|
FontRelativeLength::Rem(length) => {
|
||||||
// https://drafts.csswg.org/css-values/#rem:
|
// https://drafts.csswg.org/css-values/#rem:
|
||||||
//
|
//
|
||||||
|
@ -540,6 +566,7 @@ impl NoCalcLength {
|
||||||
"em" => NoCalcLength::FontRelative(FontRelativeLength::Em(value)),
|
"em" => NoCalcLength::FontRelative(FontRelativeLength::Em(value)),
|
||||||
"ex" => NoCalcLength::FontRelative(FontRelativeLength::Ex(value)),
|
"ex" => NoCalcLength::FontRelative(FontRelativeLength::Ex(value)),
|
||||||
"ch" => NoCalcLength::FontRelative(FontRelativeLength::Ch(value)),
|
"ch" => NoCalcLength::FontRelative(FontRelativeLength::Ch(value)),
|
||||||
|
"cap" => NoCalcLength::FontRelative(FontRelativeLength::Cap(value)),
|
||||||
"rem" => NoCalcLength::FontRelative(FontRelativeLength::Rem(value)),
|
"rem" => NoCalcLength::FontRelative(FontRelativeLength::Rem(value)),
|
||||||
// viewport percentages
|
// viewport percentages
|
||||||
"vw" if !context.in_page_rule() => {
|
"vw" if !context.in_page_rule() => {
|
||||||
|
@ -699,12 +726,13 @@ impl PartialOrd for FontRelativeLength {
|
||||||
(&Em(ref one), &Em(ref other)) => one.partial_cmp(other),
|
(&Em(ref one), &Em(ref other)) => one.partial_cmp(other),
|
||||||
(&Ex(ref one), &Ex(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),
|
(&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),
|
(&Rem(ref one), &Rem(ref other)) => one.partial_cmp(other),
|
||||||
// See https://github.com/rust-lang/rust/issues/68867. rustc isn't
|
// See https://github.com/rust-lang/rust/issues/68867. rustc isn't
|
||||||
// able to figure it own on its own so we help.
|
// able to figure it own on its own so we help.
|
||||||
_ => unsafe {
|
_ => unsafe {
|
||||||
match *self {
|
match *self {
|
||||||
Em(..) | Ex(..) | Ch(..) | Rem(..) => {},
|
Em(..) | Ex(..) | Ch(..) | Cap(..) | Rem(..) => {},
|
||||||
}
|
}
|
||||||
debug_unreachable!("Forgot an arm in partial_cmp?")
|
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::Em(v) => FontRelativeLength::Em(v * scalar),
|
||||||
FontRelativeLength::Ex(v) => FontRelativeLength::Ex(v * scalar),
|
FontRelativeLength::Ex(v) => FontRelativeLength::Ex(v * scalar),
|
||||||
FontRelativeLength::Ch(v) => FontRelativeLength::Ch(v * scalar),
|
FontRelativeLength::Ch(v) => FontRelativeLength::Ch(v * scalar),
|
||||||
|
FontRelativeLength::Cap(v) => FontRelativeLength::Cap(v * scalar),
|
||||||
FontRelativeLength::Rem(v) => FontRelativeLength::Rem(v * scalar),
|
FontRelativeLength::Rem(v) => FontRelativeLength::Rem(v * scalar),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue