Bug 1720710 - Add system-ui boilerplate. r=jfkthame

Alias -apple-system to it, and put it behind a pref for now. This is
pretty boring (read: uncontroversial hopefully) code. The follow-up work
is modifying StaticPresData to look up the fonts using system APIs,
probably. Maybe a bit more work if on macOS they can't be named.

Differential Revision: https://phabricator.services.mozilla.com/D119984
This commit is contained in:
Emilio Cobos Álvarez 2021-07-27 11:11:51 +00:00
Родитель a7785fcd55
Коммит f501d497d2
10 изменённых файлов: 89 добавлений и 42 удалений

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

@ -2357,6 +2357,8 @@ nsAtom* gfxPlatformFontList::GetLangGroup(nsAtom* aLanguage) {
return "cursive";
case StyleGenericFontFamily::Fantasy:
return "fantasy";
case StyleGenericFontFamily::SystemUi:
return "system-ui";
case StyleGenericFontFamily::MozEmoji:
return "-moz-emoji";
case StyleGenericFontFamily::None:

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

@ -46,19 +46,20 @@ static const char* const kGenericFont[] = {
".sans-serif.",
".monospace.",
".cursive.",
".fantasy."
".fantasy.",
".system-ui.",
};
// clang-format on
// These are private, use the list in nsFont.h if you want a public list.
enum {
eDefaultFont_Variable,
eDefaultFont_Serif,
eDefaultFont_SansSerif,
eDefaultFont_Monospace,
eDefaultFont_Cursive,
eDefaultFont_Fantasy,
eDefaultFont_COUNT
enum class DefaultFont {
Variable = 0,
Serif,
SansSerif,
Monospace,
Cursive,
Fantasy,
SystemUi,
COUNT
};
void LangGroupFontPrefs::Initialize(nsStaticAtom* aLangGroupAtom) {
@ -111,10 +112,11 @@ void LangGroupFontPrefs::Initialize(nsStaticAtom* aLangGroupAtom) {
&mDefaultSansSerifFont,
&mDefaultMonospaceFont,
&mDefaultCursiveFont,
&mDefaultFantasyFont
&mDefaultFantasyFont,
&mDefaultSystemUiFont,
};
// clang-format on
static_assert(MOZ_ARRAY_LENGTH(fontTypes) == eDefaultFont_COUNT,
static_assert(MOZ_ARRAY_LENGTH(fontTypes) == size_t(DefaultFont::COUNT),
"FontTypes array count is not correct");
// Get attributes specific to each generic font. We do not get the user's
@ -123,16 +125,16 @@ void LangGroupFontPrefs::Initialize(nsStaticAtom* aLangGroupAtom) {
// code to look up the font prefs to convert generic names to specific
// family names as necessary.
nsAutoCString generic_dot_langGroup;
for (uint32_t eType = 0; eType < ArrayLength(fontTypes); ++eType) {
generic_dot_langGroup.Assign(kGenericFont[eType]);
for (auto type : MakeEnumeratedRange(DefaultFont::COUNT)) {
generic_dot_langGroup.Assign(kGenericFont[size_t(type)]);
generic_dot_langGroup.Append(langGroup);
nsFont* font = fontTypes[eType];
nsFont* font = fontTypes[size_t(type)];
// Set the default variable font (the other fonts are seen as 'generic'
// fonts in GFX and will be queried there when hunting for alternative
// fonts)
if (eType == eDefaultFont_Variable) {
if (type == DefaultFont::Variable) {
// XXX "font.name.variable."? There is no such pref...
MAKE_FONT_PREF_KEY(pref, "font.name.variable.", langGroup);
@ -153,7 +155,7 @@ void LangGroupFontPrefs::Initialize(nsStaticAtom* aLangGroupAtom) {
mDefaultVariableFont.family.families.fallback = defaultType;
}
} else {
if (eType != eDefaultFont_Monospace) {
if (type != DefaultFont::Monospace) {
// all the other generic fonts are initialized with the size of the
// variable font, but their specific size can supersede later -- see
// below

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

@ -26,7 +26,8 @@ struct LangGroupFontPrefs {
mDefaultSansSerifFont(StyleGenericFontFamily::SansSerif, {0}),
mDefaultMonospaceFont(StyleGenericFontFamily::Monospace, {0}),
mDefaultCursiveFont(StyleGenericFontFamily::Cursive, {0}),
mDefaultFantasyFont(StyleGenericFontFamily::Fantasy, {0}) {
mDefaultFantasyFont(StyleGenericFontFamily::Fantasy, {0}),
mDefaultSystemUiFont(StyleGenericFontFamily::SystemUi, {0}) {
mDefaultVariableFont.family.families.fallback =
StyleGenericFontFamily::Serif;
// We create mDefaultVariableFont.family with defaultType as the
@ -72,6 +73,8 @@ struct LangGroupFontPrefs {
return &mDefaultCursiveFont;
case StyleGenericFontFamily::Fantasy:
return &mDefaultFantasyFont;
case StyleGenericFontFamily::SystemUi:
return &mDefaultSystemUiFont;
case StyleGenericFontFamily::MozEmoji:
// This shouldn't appear in font family names.
break;
@ -88,6 +91,7 @@ struct LangGroupFontPrefs {
nsFont mDefaultMonospaceFont;
nsFont mDefaultCursiveFont;
nsFont mDefaultFantasyFont;
nsFont mDefaultSystemUiFont;
UniquePtr<LangGroupFontPrefs> mNext;
};

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

@ -1364,7 +1364,8 @@ StyleDefaultFontSizes Gecko_GetBaseSize(nsAtom* aLanguage) {
prefs.Initialize(langGroupAtom);
return {prefs.mDefaultVariableFont.size, prefs.mDefaultSerifFont.size,
prefs.mDefaultSansSerifFont.size, prefs.mDefaultMonospaceFont.size,
prefs.mDefaultCursiveFont.size, prefs.mDefaultFantasyFont.size};
prefs.mDefaultCursiveFont.size, prefs.mDefaultFantasyFont.size,
prefs.mDefaultSystemUiFont.size};
}
static StaticRefPtr<UACacheReporter> gUACacheReporter;
@ -1792,6 +1793,8 @@ void StyleSingleFontFamily::AppendToString(nsACString& aName,
return aName.AppendLiteral("cursive");
case StyleGenericFontFamily::Fantasy:
return aName.AppendLiteral("fantasy");
case StyleGenericFontFamily::SystemUi:
return aName.AppendLiteral("system-ui");
}
MOZ_ASSERT_UNREACHABLE("Unknown generic font-family!");
return aName.AppendLiteral("serif");

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

@ -6852,6 +6852,13 @@
value: true
mirror: always
# Whether the system-ui generic family is enabled.
- name: layout.css.system-ui.enabled
type: RelaxedAtomicBool
value: false
mirror: always
rust: true
# Whether the bloom filter optimization is applied to attribute names too, not
# only classes / id / namespaces / etc.
- name: layout.css.bloom-filter-attribute-names.enabled

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

@ -1032,6 +1032,7 @@ pub struct DefaultFontSizes {
monospace: Length,
cursive: Length,
fantasy: Length,
system_ui: Length,
}
impl DefaultFontSizes {
@ -1043,6 +1044,7 @@ impl DefaultFontSizes {
GenericFontFamily::Monospace => self.monospace,
GenericFontFamily::Cursive => self.cursive,
GenericFontFamily::Fantasy => self.fantasy,
GenericFontFamily::SystemUi => self.system_ui,
GenericFontFamily::MozEmoji => unreachable!(
"Should never get here, since this doesn't (yet) appear on font family"
),

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

@ -137,7 +137,7 @@
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
}
let family = FontFamily::parse_specified(input)?;
let family = FontFamily::parse(context, input)?;
Ok(expanded! {
% for name in "style weight stretch variant_caps".split():
font_${name}: unwrap_or_initial!(font_${name}, ${name}),

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

@ -6,6 +6,7 @@
#[cfg(feature = "gecko")]
use crate::gecko_bindings::{bindings, structs};
use crate::parser::{Parse, ParserContext};
use crate::values::animated::ToAnimatedValue;
use crate::values::computed::{
Angle, Context, Integer, Length, NonNegativeLength, NonNegativeNumber, NonNegativePercentage,
@ -243,6 +244,7 @@ impl FontFamily {
generic_font_family!(CURSIVE, Cursive);
generic_font_family!(FANTASY, Fantasy);
generic_font_family!(MOZ_EMOJI, MozEmoji);
generic_font_family!(SYSTEM_UI, SystemUi);
match generic {
GenericFontFamily::None => {
@ -255,6 +257,7 @@ impl FontFamily {
GenericFontFamily::Cursive => &*CURSIVE,
GenericFontFamily::Fantasy => &*FANTASY,
GenericFontFamily::MozEmoji => &*MOZ_EMOJI,
GenericFontFamily::SystemUi => &*SYSTEM_UI,
}
}
}
@ -370,6 +373,10 @@ pub enum SingleFontFamily {
Generic(GenericFontFamily),
}
fn system_ui_enabled(_: &ParserContext) -> bool {
static_prefs::pref!("layout.css.system-ui.enabled")
}
/// A generic font-family name.
///
/// The order here is important, if you change it make sure that
@ -404,15 +411,17 @@ pub enum GenericFontFamily {
Monospace,
Cursive,
Fantasy,
#[parse(aliases = "-apple-system", condition = "system_ui_enabled")]
SystemUi,
/// An internal value for emoji font selection.
#[css(skip)]
#[cfg(feature = "gecko")]
MozEmoji,
}
impl SingleFontFamily {
impl Parse for SingleFontFamily {
/// Parse a font-family value.
pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
if let Ok(value) = input.try_parse(|i| i.expect_string_cloned()) {
return Ok(SingleFontFamily::FamilyName(FamilyName {
name: Atom::from(&*value),
@ -420,11 +429,11 @@ impl SingleFontFamily {
}));
}
let first_ident = input.expect_ident_cloned()?;
if let Ok(generic) = GenericFontFamily::from_ident(&first_ident) {
if let Ok(generic) = input.try_parse(|i| GenericFontFamily::parse(context, i)) {
return Ok(SingleFontFamily::Generic(generic));
}
let first_ident = input.expect_ident_cloned()?;
let reserved = match_ignore_ascii_case! { &first_ident,
// https://drafts.csswg.org/css-fonts/#propdef-font-family
// "Font family names that happen to be the same as a keyword value
@ -467,8 +476,10 @@ impl SingleFontFamily {
syntax,
}))
}
}
#[cfg(feature = "servo")]
#[cfg(feature = "servo")]
impl SingleFontFamily {
/// Get the corresponding font-family with Atom
pub fn from_atom(input: Atom) -> SingleFontFamily {
match input {

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

@ -658,15 +658,6 @@ pub enum FontFamily {
impl FontFamily {
system_font_methods!(FontFamily, font_family);
/// Parse a specified font-family value
pub fn parse_specified<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
let values = input.parse_comma_separated(SingleFontFamily::parse)?;
Ok(FontFamily::Values(FontFamilyList {
list: crate::ArcSlice::from_iter(values.into_iter()),
fallback: computed::GenericFontFamily::None,
}))
}
}
impl ToComputedValue for FontFamily {
@ -706,23 +697,27 @@ impl Parse for FontFamily {
/// <family-name> = <string> | [ <ident>+ ]
/// TODO: <generic-family>
fn parse<'i, 't>(
_: &ParserContext,
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<FontFamily, ParseError<'i>> {
FontFamily::parse_specified(input)
let values = input.parse_comma_separated(|input| SingleFontFamily::parse(context, input))?;
Ok(FontFamily::Values(FontFamilyList {
list: crate::ArcSlice::from_iter(values.into_iter()),
fallback: computed::GenericFontFamily::None,
}))
}
}
impl SpecifiedValueInfo for FontFamily {}
/// `FamilyName::parse` is based on `SingleFontFamily::parse` and not the other way around
/// because we want the former to exclude generic family keywords.
/// `FamilyName::parse` is based on `SingleFontFamily::parse` and not the other
/// way around because we want the former to exclude generic family keywords.
impl Parse for FamilyName {
fn parse<'i, 't>(
_: &ParserContext,
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
match SingleFontFamily::parse(input) {
match SingleFontFamily::parse(context, input) {
Ok(SingleFontFamily::FamilyName(name)) => Ok(name),
Ok(SingleFontFamily::Generic(_)) => {
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))

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

@ -5331,7 +5331,16 @@ pub unsafe extern "C" fn Servo_DeclarationBlock_SetFontFamily(
let string = value.as_str_unchecked();
let mut input = ParserInput::new(&string);
let mut parser = Parser::new(&mut input);
let result = FontFamily::parse_specified(&mut parser);
let context = ParserContext::new(
Origin::Author,
dummy_url_data(),
Some(CssRuleType::Style),
ParsingMode::DEFAULT,
QuirksMode::NoQuirks,
None,
None,
);
let result = FontFamily::parse(&context, &mut parser);
if let Ok(family) = result {
if parser.is_exhausted() {
let decl = PropertyDeclaration::FontFamily(family);
@ -7118,5 +7127,17 @@ pub extern "C" fn Servo_FontFamilyList_WithNames(names: &nsTArray<computed::font
#[no_mangle]
pub extern "C" fn Servo_GenericFontFamily_Parse(input: &nsACString) -> GenericFontFamily {
GenericFontFamily::from_ident(&*input.to_utf8()).unwrap_or(GenericFontFamily::None)
let context = ParserContext::new(
Origin::Author,
unsafe { dummy_url_data() },
Some(CssRuleType::Style),
ParsingMode::DEFAULT,
QuirksMode::NoQuirks,
None,
None,
);
let value = input.to_utf8();
let mut input = ParserInput::new(&value);
let mut input = Parser::new(&mut input);
GenericFontFamily::parse(&context, &mut input).unwrap_or(GenericFontFamily::None)
}