Bug 1786493 - Implement CSS @supports font-format(...) and font-tech(...) functions. r=emilio

These are gated by the same layout.css.font-tech.enabled pref as the
closely-related `tech()` function for the @font-face src descriptor;
once the spec questions are settled, we should enable them all together.

Differential Revision: https://phabricator.services.mozilla.com/D155359
This commit is contained in:
Jonathan Kew 2022-08-25 12:19:21 +00:00
Родитель 4ce6d539fd
Коммит 5bcdc7cf69
5 изменённых файлов: 71 добавлений и 16 удалений

Просмотреть файл

@ -1632,6 +1632,16 @@ bool Gecko_GetBoolPrefValue(const char* aPrefName) {
return Preferences::GetBool(aPrefName);
}
bool Gecko_IsFontFormatSupported(StyleFontFaceSourceFormatKeyword aFormat) {
return gfxPlatform::GetPlatform()->IsFontFormatSupported(
aFormat, StyleFontFaceSourceTechFlags::Empty());
}
bool Gecko_IsFontTechSupported(StyleFontFaceSourceTechFlags aFlag) {
return gfxPlatform::GetPlatform()->IsFontFormatSupported(
StyleFontFaceSourceFormatKeyword::None, aFlag);
}
bool Gecko_IsInServoTraversal() { return ServoStyleSet::IsInServoTraversal(); }
bool Gecko_IsMainThread() { return NS_IsMainThread(); }

Просмотреть файл

@ -550,6 +550,11 @@ const nsTArray<mozilla::dom::Element*>* Gecko_ShadowRoot_GetElementsWithId(
// be null-terminated.
bool Gecko_GetBoolPrefValue(const char* pref_name);
// Check whether font format/tech is supported.
bool Gecko_IsFontFormatSupported(
mozilla::StyleFontFaceSourceFormatKeyword aFormat);
bool Gecko_IsFontTechSupported(mozilla::StyleFontFaceSourceTechFlags aFlag);
// Returns true if we're currently performing the servo traversal.
bool Gecko_IsInServoTraversal();

Просмотреть файл

@ -424,6 +424,7 @@ cbindgen-types = [
{ gecko = "StyleFillRule", servo = "crate::values::generics::basic_shape::FillRule" },
{ gecko = "StyleFontDisplay", servo = "crate::font_face::FontDisplay" },
{ gecko = "StyleFontFaceSourceListComponent", servo = "crate::font_face::FontFaceSourceListComponent" },
{ gecko = "StyleFontFaceSourceFormatKeyword", servo = "crate::font_face::FontFaceSourceFormatKeyword" },
{ gecko = "StyleFontFaceSourceTechFlags", servo = "crate::font_face::FontFaceSourceTechFlags" },
{ gecko = "StyleFontLanguageOverride", servo = "crate::values::computed::font::FontLanguageOverride" },
{ gecko = "StyleOffsetPath", servo = "crate::values::computed::motion::OffsetPath" },

Просмотреть файл

@ -96,6 +96,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<Self, ParseError<'i>> {
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,
@ -106,22 +125,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(())
})?;

Просмотреть файл

@ -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(<font-format>)`
FontFormat(FontFaceSourceFormatKeyword),
/// `font-tech(<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),
}
}