mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
style: Simplify language-dependent font fallback code
.fallback is always the default font for the lang group unless we're a system font (in which case it's "none"). The only reason we need that is because we need to react to language changes (which affect the initial font). Simplify the model a bit doing the language lookup in gfxTextRun (this should avoid allocating a few nsStyleFont structs too. Depends on D130732 Differential Revision: https://phabricator.services.mozilla.com/D131312
This commit is contained in:
parent
f911fb4f0f
commit
19aa8842c2
3 changed files with 57 additions and 55 deletions
|
@ -874,33 +874,23 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The default font type (which is stored in FontFamilyList's
|
/// The initial font depends on the current lang group so we may need to
|
||||||
/// `mDefaultFontType`) depends on the current lang group and generic font
|
/// recompute it if the language changed.
|
||||||
/// family, so we may need to recompute it if or the family changed.
|
|
||||||
///
|
|
||||||
/// Also, we prioritize non-document fonts here if we need to (see the pref
|
|
||||||
/// `browser.display.use_document_fonts`).
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
fn recompute_default_font_family_type_if_needed(&mut self) {
|
fn recompute_initial_font_family_if_needed(&mut self) {
|
||||||
use crate::gecko_bindings::bindings;
|
use crate::gecko_bindings::bindings;
|
||||||
use crate::values::computed::font::GenericFontFamily;
|
use crate::values::computed::font::FontFamily;
|
||||||
|
|
||||||
if !self.seen.contains(LonghandId::XLang) && !self.seen.contains(LonghandId::FontFamily) {
|
if !self.seen.contains(LonghandId::XLang) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let builder = &mut self.context.builder;
|
let builder = &mut self.context.builder;
|
||||||
let (default_font_type, prioritize_user_fonts) = {
|
let default_font_type = {
|
||||||
let font = builder.get_font().gecko();
|
let font = builder.get_font().gecko();
|
||||||
|
|
||||||
// System fonts are all right, and should have the default font type
|
if !font.mFont.family.is_initial {
|
||||||
// set to none already, so bail out early.
|
|
||||||
if font.mFont.family.is_system_font {
|
|
||||||
debug_assert_eq!(
|
|
||||||
font.mFont.family.families.fallback,
|
|
||||||
GenericFontFamily::None
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -911,29 +901,52 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let use_document_fonts = static_prefs::pref!("browser.display.use_document_fonts") != 0;
|
let initial_generic = font.mFont.family.families.single_generic();
|
||||||
|
debug_assert!(initial_generic.is_some(), "Initial font should be just one generic font");
|
||||||
// We prioritize user fonts over document fonts if the pref is set,
|
if initial_generic == Some(default_font_type) {
|
||||||
// and we don't have a generic family already (or we're using
|
|
||||||
// cursive or fantasy, since they're ignored, see bug 789788), and
|
|
||||||
// we have a generic family to actually replace it with.
|
|
||||||
let prioritize_user_fonts =
|
|
||||||
!use_document_fonts &&
|
|
||||||
default_font_type != GenericFontFamily::None &&
|
|
||||||
font.mFont.family.families.needs_user_font_prioritization();
|
|
||||||
|
|
||||||
if !prioritize_user_fonts && default_font_type == font.mFont.family.families.fallback {
|
|
||||||
// Nothing to do.
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
(default_font_type, prioritize_user_fonts)
|
|
||||||
|
default_font_type
|
||||||
};
|
};
|
||||||
|
|
||||||
let font = builder.mutate_font().gecko_mut();
|
let font = builder.mutate_font().gecko_mut();
|
||||||
font.mFont.family.families.fallback = default_font_type;
|
// NOTE: Leaves is_initial untouched.
|
||||||
if prioritize_user_fonts {
|
font.mFont.family.families = FontFamily::generic(default_font_type).families.clone();
|
||||||
font.mFont.family.families.prioritize_first_generic_or_prepend(default_font_type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Prioritize user fonts if needed by pref.
|
||||||
|
#[inline]
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
fn prioritize_user_fonts_if_needed(&mut self) {
|
||||||
|
use crate::gecko_bindings::bindings;
|
||||||
|
|
||||||
|
if !self.seen.contains(LonghandId::FontFamily) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if static_prefs::pref!("browser.display.use_document_fonts") != 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let builder = &mut self.context.builder;
|
||||||
|
let default_font_type = {
|
||||||
|
let font = builder.get_font().gecko();
|
||||||
|
|
||||||
|
if !font.mFont.family.families.needs_user_font_prioritization() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
bindings::Gecko_nsStyleFont_ComputeFallbackFontTypeForLanguage(
|
||||||
|
builder.device.document(),
|
||||||
|
font.mLanguage.mRawPtr,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let font = builder.mutate_font().gecko_mut();
|
||||||
|
font.mFont.family.families.prioritize_first_generic_or_prepend(default_font_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Some keyword sizes depend on the font family and language.
|
/// Some keyword sizes depend on the font family and language.
|
||||||
|
@ -1107,7 +1120,8 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
{
|
{
|
||||||
self.unzoom_fonts_if_needed();
|
self.unzoom_fonts_if_needed();
|
||||||
self.recompute_default_font_family_type_if_needed();
|
self.recompute_initial_font_family_if_needed();
|
||||||
|
self.prioritize_user_fonts_if_needed();
|
||||||
self.recompute_keyword_font_size_if_needed();
|
self.recompute_keyword_font_size_if_needed();
|
||||||
self.handle_mathml_scriptlevel_if_needed();
|
self.handle_mathml_scriptlevel_if_needed();
|
||||||
self.constrain_font_size_if_needed()
|
self.constrain_font_size_if_needed()
|
||||||
|
|
|
@ -182,6 +182,9 @@ pub struct FontFamily {
|
||||||
pub families: FontFamilyList,
|
pub families: FontFamilyList,
|
||||||
/// Whether this font-family came from a specified system-font.
|
/// Whether this font-family came from a specified system-font.
|
||||||
pub is_system_font: bool,
|
pub is_system_font: bool,
|
||||||
|
/// Whether this is the initial font-family that might react to language
|
||||||
|
/// changes.
|
||||||
|
pub is_initial: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! static_font_family {
|
macro_rules! static_font_family {
|
||||||
|
@ -193,10 +196,9 @@ macro_rules! static_font_family {
|
||||||
list: crate::ArcSlice::from_iter_leaked(std::iter::once($family)),
|
list: crate::ArcSlice::from_iter_leaked(std::iter::once($family)),
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
list: Box::new([$family]),
|
list: Box::new([$family]),
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
fallback: GenericFontFamily::None,
|
|
||||||
},
|
},
|
||||||
is_system_font: false,
|
is_system_font: false,
|
||||||
|
is_initial: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -234,9 +236,9 @@ impl FontFamily {
|
||||||
syntax: FontFamilyNameSyntax::Identifiers,
|
syntax: FontFamilyNameSyntax::Identifiers,
|
||||||
},
|
},
|
||||||
))),
|
))),
|
||||||
fallback: GenericFontFamily::None,
|
|
||||||
},
|
},
|
||||||
is_system_font: true,
|
is_system_font: true,
|
||||||
|
is_initial: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +305,7 @@ impl ToCss for FontFamily {
|
||||||
Some(f) => f.to_css(dest)?,
|
Some(f) => f.to_css(dest)?,
|
||||||
None => {
|
None => {
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
return self.families.fallback.to_css(dest);
|
return return Ok(());
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
unreachable!();
|
unreachable!();
|
||||||
},
|
},
|
||||||
|
@ -562,8 +564,6 @@ impl SingleFontFamily {
|
||||||
pub struct FontFamilyList {
|
pub struct FontFamilyList {
|
||||||
/// The actual list of font families specified.
|
/// The actual list of font families specified.
|
||||||
pub list: crate::ArcSlice<SingleFontFamily>,
|
pub list: crate::ArcSlice<SingleFontFamily>,
|
||||||
/// A fallback font type (none, serif, or sans-serif, generally).
|
|
||||||
pub fallback: GenericFontFamily,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A list of font families.
|
/// A list of font families.
|
||||||
|
@ -592,17 +592,6 @@ impl FontFamilyList {
|
||||||
self.list.iter()
|
self.list.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Puts the fallback in the list if needed.
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
pub fn normalize(&mut self) {
|
|
||||||
if self.fallback == GenericFontFamily::None {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let mut new_list = self.list.iter().cloned().collect::<Vec<_>>();
|
|
||||||
new_list.push(SingleFontFamily::Generic(self.fallback));
|
|
||||||
self.list = crate::ArcSlice::from_iter(new_list.into_iter());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If there's a generic font family on the list which is suitable for user
|
/// If there's a generic font family on the list which is suitable for user
|
||||||
/// font prioritization, then move it to the front of the list. Otherwise,
|
/// font prioritization, then move it to the front of the list. Otherwise,
|
||||||
/// prepend the default generic.
|
/// prepend the default generic.
|
||||||
|
|
|
@ -697,6 +697,7 @@ impl ToComputedValue for FontFamily {
|
||||||
FontFamily::Values(ref list) => computed::FontFamily {
|
FontFamily::Values(ref list) => computed::FontFamily {
|
||||||
families: list.clone(),
|
families: list.clone(),
|
||||||
is_system_font: false,
|
is_system_font: false,
|
||||||
|
is_initial: false,
|
||||||
},
|
},
|
||||||
FontFamily::System(_) => self.compute_system(context),
|
FontFamily::System(_) => self.compute_system(context),
|
||||||
}
|
}
|
||||||
|
@ -736,8 +737,6 @@ impl Parse for FontFamily {
|
||||||
list: crate::ArcSlice::from_iter(values.into_iter()),
|
list: crate::ArcSlice::from_iter(values.into_iter()),
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
list: values.into_boxed_slice(),
|
list: values.into_boxed_slice(),
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
fallback: computed::GenericFontFamily::None,
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue