diff --git a/layout/reftests/font-matching/reftest.list b/layout/reftests/font-matching/reftest.list
index 3d9274b8628c..4e7c763b389f 100644
--- a/layout/reftests/font-matching/reftest.list
+++ b/layout/reftests/font-matching/reftest.list
@@ -164,6 +164,7 @@ random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == descriptor-ranges.html d
skip-if(Android) == fallback-respects-generic-1.html fallback-respects-generic-1-ref.html # fonts present on Android are too unpredictable for easy testing
skip-if(Android) != system-ui-fallback.html system-ui-fallback-notref.html # Roboto supports the characters in the reftest, and that's better behavior.
+== system-ui-fallback-2.html system-ui-fallback-2-ref.html
# Japanese monospace font on macOS is Osaka-mono
# If Osaka is present then Osaka-mono should also be available.
diff --git a/layout/reftests/font-matching/system-ui-fallback-2-ref.html b/layout/reftests/font-matching/system-ui-fallback-2-ref.html
new file mode 100644
index 000000000000..6e60fefe18d8
--- /dev/null
+++ b/layout/reftests/font-matching/system-ui-fallback-2-ref.html
@@ -0,0 +1,2 @@
+
+
ب
diff --git a/layout/reftests/font-matching/system-ui-fallback-2.html b/layout/reftests/font-matching/system-ui-fallback-2.html
new file mode 100644
index 000000000000..a39c4e2a2db6
--- /dev/null
+++ b/layout/reftests/font-matching/system-ui-fallback-2.html
@@ -0,0 +1,2 @@
+
+ب
diff --git a/layout/style/GeckoBindings.cpp b/layout/style/GeckoBindings.cpp
index 0102a86bab4a..e9dc5c68b30e 100644
--- a/layout/style/GeckoBindings.cpp
+++ b/layout/style/GeckoBindings.cpp
@@ -90,15 +90,15 @@ ServoTraversalStatistics ServoTraversalStatistics::sSingleton;
static StaticAutoPtr sServoFFILock;
-static const nsFont* ThreadSafeGetDefaultFontHelper(
- const Document& aDocument, nsAtom* aLanguage,
- StyleGenericFontFamily aGenericId) {
+static const nsFont* ThreadSafeGetDefaultVariableFont(const Document& aDocument,
+ nsAtom* aLanguage) {
bool needsCache = false;
const nsFont* retval;
auto GetDefaultFont = [&](bool* aNeedsToCache) {
auto* prefs = aDocument.GetFontPrefsForLang(aLanguage, aNeedsToCache);
- return prefs ? prefs->GetDefaultFont(aGenericId) : nullptr;
+ return prefs ? prefs->GetDefaultFont(StyleGenericFontFamily::None)
+ : nullptr;
};
{
@@ -978,8 +978,8 @@ void Gecko_ReleaseAtom(nsAtom* aAtom) { NS_RELEASE(aAtom); }
void Gecko_nsFont_InitSystem(nsFont* aDest, StyleSystemFont aFontId,
const nsStyleFont* aFont,
const Document* aDocument) {
- const nsFont* defaultVariableFont = ThreadSafeGetDefaultFontHelper(
- *aDocument, aFont->mLanguage, StyleGenericFontFamily::None);
+ const nsFont* defaultVariableFont =
+ ThreadSafeGetDefaultVariableFont(*aDocument, aFont->mLanguage);
// We have passed uninitialized memory to this function,
// initialize it. We can't simply return an nsFont because then
@@ -994,11 +994,10 @@ void Gecko_nsFont_InitSystem(nsFont* aDest, StyleSystemFont aFontId,
void Gecko_nsFont_Destroy(nsFont* aDest) { aDest->~nsFont(); }
-StyleGenericFontFamily Gecko_nsStyleFont_ComputeDefaultFontType(
- const Document* aDoc, StyleGenericFontFamily aGenericId,
- nsAtom* aLanguage) {
+StyleGenericFontFamily Gecko_nsStyleFont_ComputeFallbackFontTypeForLanguage(
+ const Document* aDoc, nsAtom* aLanguage) {
const nsFont* defaultFont =
- ThreadSafeGetDefaultFontHelper(*aDoc, aLanguage, aGenericId);
+ ThreadSafeGetDefaultVariableFont(*aDoc, aLanguage);
return defaultFont->family.families.fallback;
}
diff --git a/layout/style/GeckoBindings.h b/layout/style/GeckoBindings.h
index 82cf31fb7b81..a235e29eee1a 100644
--- a/layout/style/GeckoBindings.h
+++ b/layout/style/GeckoBindings.h
@@ -474,10 +474,10 @@ void Gecko_nsStyleFont_CopyLangFrom(nsStyleFont* aFont,
mozilla::Length Gecko_nsStyleFont_ComputeMinSize(const nsStyleFont*,
const mozilla::dom::Document*);
-// Computes the default generic font for a generic family and language.
-mozilla::StyleGenericFontFamily Gecko_nsStyleFont_ComputeDefaultFontType(
- const mozilla::dom::Document*,
- mozilla::StyleGenericFontFamily generic_family, nsAtom* language);
+// Computes the default generic font for a language.
+mozilla::StyleGenericFontFamily
+Gecko_nsStyleFont_ComputeFallbackFontTypeForLanguage(
+ const mozilla::dom::Document*, nsAtom* language);
mozilla::StyleDefaultFontSizes Gecko_GetBaseSize(nsAtom* lang);
diff --git a/servo/components/style/properties/cascade.rs b/servo/components/style/properties/cascade.rs
index 81f09700b44d..7dadcbc709a5 100644
--- a/servo/components/style/properties/cascade.rs
+++ b/servo/components/style/properties/cascade.rs
@@ -897,7 +897,6 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
return;
}
- let use_document_fonts = static_prefs::pref!("browser.display.use_document_fonts") != 0;
let builder = &mut self.context.builder;
let (default_font_type, prioritize_user_fonts) = {
let font = builder.get_font().gecko();
@@ -912,22 +911,23 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
return;
}
- let generic = font.mFont.family.families.single_generic().unwrap_or(GenericFontFamily::None);
let default_font_type = unsafe {
- bindings::Gecko_nsStyleFont_ComputeDefaultFontType(
+ bindings::Gecko_nsStyleFont_ComputeFallbackFontTypeForLanguage(
builder.device.document(),
- generic,
font.mLanguage.mRawPtr,
)
};
+ let use_document_fonts = static_prefs::pref!("browser.display.use_document_fonts") != 0;
+
// We prioritize user fonts over document fonts if the pref is set,
// 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 &&
+ let prioritize_user_fonts =
+ !use_document_fonts &&
default_font_type != GenericFontFamily::None &&
- !generic.valid_for_user_font_prioritization();
+ font.mFont.family.families.needs_user_font_prioritization();
if !prioritize_user_fonts && default_font_type == font.mFont.family.families.fallback {
// Nothing to do.
diff --git a/servo/components/style/values/computed/font.rs b/servo/components/style/values/computed/font.rs
index 96c1cb6ba8d9..b41dce552503 100644
--- a/servo/components/style/values/computed/font.rs
+++ b/servo/components/style/values/computed/font.rs
@@ -585,12 +585,20 @@ impl FontFamilyList {
self.list = crate::ArcSlice::from_iter(new_list.into_iter());
}
+ /// Returns whether we need to prioritize user fonts.
+ pub (crate) fn needs_user_font_prioritization(&self) -> bool {
+ self.iter().next().map_or(true, |f| match f {
+ SingleFontFamily::Generic(f) => !f.valid_for_user_font_prioritization(),
+ _ => true,
+ })
+ }
+
/// Return the generic ID if it is a single generic font
pub fn single_generic(&self) -> Option {
let mut iter = self.iter();
if let Some(SingleFontFamily::Generic(f)) = iter.next() {
if iter.next().is_none() {
- return Some(f.clone());
+ return Some(*f);
}
}
None
diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs
index d5faac4a0495..1659ab376285 100644
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -4130,6 +4130,9 @@ pub extern "C" fn Servo_ComputedValues_EqualForCachedAnonymousContentStyle(
// rules in minimal-xul.css, but which makes no difference for the
// anonymous content subtrees we cache style for.
differing_properties.remove(LonghandId::XLang);
+ // Similarly, -x-lang can influence the font-family fallback we have for
+ // the initial font-family so remove it as well.
+ differing_properties.remove(LonghandId::FontFamily);
// Ignore any difference in pref-controlled, inherited properties. These
// properties may or may not be set by the 'all' declaration in the