diff --git a/components/style/font_face.rs b/components/style/font_face.rs index f0728f00ae6..2a039a80474 100644 --- a/components/style/font_face.rs +++ b/components/style/font_face.rs @@ -102,6 +102,25 @@ bitflags! { } } +impl FontFaceSourceTechFlags { + /// Parse a single font-technology keyword and return its flag. + pub fn parse_one<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { + Ok(try_match_ident_ignore_ascii_case! { input, + "feature-opentype" => Self::FEATURE_OPENTYPE, + "feature-aat" => Self::FEATURE_AAT, + "feature-graphite" => Self::FEATURE_GRAPHITE, + "color-colrv0" => Self::COLOR_COLRV0, + "color-colrv1" => Self::COLOR_COLRV1, + "color-svg" => Self::COLOR_SVG, + "color-sbix" => Self::COLOR_SBIX, + "color-cbdt" => Self::COLOR_CBDT, + "variations" => Self::VARIATIONS, + "palettes" => Self::PALETTES, + "incremental" => Self::INCREMENTAL, + }) + } +} + impl Parse for FontFaceSourceTechFlags { fn parse<'i, 't>( _context: &ParserContext, @@ -112,22 +131,7 @@ impl Parse for FontFaceSourceTechFlags { // because we insert the flags into result as we go. let mut result = Self::empty(); input.parse_comma_separated(|input| { - let location = input.current_source_location(); - let ident = input.expect_ident()?; - let flag = match_ignore_ascii_case! { ident, - "feature-opentype" => Self::FEATURE_OPENTYPE, - "feature-aat" => Self::FEATURE_AAT, - "feature-graphite" => Self::FEATURE_GRAPHITE, - "color-colrv0" => Self::COLOR_COLRV0, - "color-colrv1" => Self::COLOR_COLRV1, - "color-svg" => Self::COLOR_SVG, - "color-sbix" => Self::COLOR_SBIX, - "color-cbdt" => Self::COLOR_CBDT, - "variations" => Self::VARIATIONS, - "palettes" => Self::PALETTES, - "incremental" => Self::INCREMENTAL, - _ => return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)), - }; + let flag = Self::parse_one(input)?; result.insert(flag); Ok(()) })?; diff --git a/components/style/stylesheets/supports_rule.rs b/components/style/stylesheets/supports_rule.rs index 23d79fd1cc2..09092a2080e 100644 --- a/components/style/stylesheets/supports_rule.rs +++ b/components/style/stylesheets/supports_rule.rs @@ -11,6 +11,7 @@ use crate::shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked}; use crate::shared_lock::{SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; use crate::str::CssStringWriter; use crate::stylesheets::{CssRuleType, CssRules, Namespaces}; +use crate::font_face::{FontFaceSourceFormatKeyword, FontFaceSourceTechFlags}; use cssparser::parse_important; use cssparser::{Delimiter, Parser, SourceLocation, Token}; use cssparser::{ParseError as CssParseError, ParserInput}; @@ -94,6 +95,10 @@ pub enum SupportsCondition { /// Since we need to pass it through FFI to get the pref value, /// we store it as CString directly. MozBoolPref(CString), + /// `font-format()` + FontFormat(FontFaceSourceFormatKeyword), + /// `font-tech()` + FontTech(FontFaceSourceTechFlags), /// `(any tokens)` or `func(any tokens)` FutureSyntax(String), } @@ -165,6 +170,14 @@ impl SupportsCondition { input.slice_from(pos).to_owned() ))) }, + "font-format" if static_prefs::pref!("layout.css.font-tech.enabled") => { + let kw = FontFaceSourceFormatKeyword::parse(input)?; + Ok(SupportsCondition::FontFormat(kw)) + }, + "font-tech" if static_prefs::pref!("layout.css.font-tech.enabled") => { + let flag = FontFaceSourceTechFlags::parse_one(input)?; + Ok(SupportsCondition::FontTech(flag)) + }, _ => { Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) }, @@ -215,6 +228,8 @@ impl SupportsCondition { SupportsCondition::Declaration(ref decl) => decl.eval(cx), SupportsCondition::MozBoolPref(ref name) => eval_moz_bool_pref(name, cx), SupportsCondition::Selector(ref selector) => selector.eval(cx, namespaces), + SupportsCondition::FontFormat(ref format) => eval_font_format(format), + SupportsCondition::FontTech(ref tech) => eval_font_tech(tech), SupportsCondition::FutureSyntax(_) => false, } } @@ -229,6 +244,16 @@ fn eval_moz_bool_pref(name: &CStr, cx: &ParserContext) -> bool { unsafe { bindings::Gecko_GetBoolPrefValue(name.as_ptr()) } } +fn eval_font_format(kw: &FontFaceSourceFormatKeyword) -> bool { + use crate::gecko_bindings::bindings; + unsafe { bindings::Gecko_IsFontFormatSupported(*kw) } +} + +fn eval_font_tech(flag: &FontFaceSourceTechFlags) -> bool { + use crate::gecko_bindings::bindings; + unsafe { bindings::Gecko_IsFontTechSupported(*flag) } +} + #[cfg(feature = "servo")] fn eval_moz_bool_pref(_: &CStr, _: &ParserContext) -> bool { false @@ -300,6 +325,16 @@ impl ToCss for SupportsCondition { name.to_css(dest)?; dest.write_str(")") }, + SupportsCondition::FontFormat(ref kw) => { + dest.write_str("font-format(")?; + kw.to_css(dest)?; + dest.write_str(")") + }, + SupportsCondition::FontTech(ref flag) => { + dest.write_str("font-tech(")?; + flag.to_css(dest)?; + dest.write_str(")") + }, SupportsCondition::FutureSyntax(ref s) => dest.write_str(&s), } }