зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
a7785fcd55
Коммит
f501d497d2
|
@ -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)
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче