From 0d16a040388d5b5ec1d062eeec0b07021fc31055 Mon Sep 17 00:00:00 2001 From: Hamza Date: Wed, 28 Oct 2026 15:53:44 +0500 Subject: [PATCH] Fonts: the word "serif" outranks every sans indicator My own previous commit introduced this: moving the bare "serif" needle after the sans list to let "Microsoft Sans Serif" read as sans also let "gothic" win in "Sweet Gothic Serif", a real serif family, which review caught. The rule is narrower than either ordering. A name holding "serif" is serif, and that outranks the sans indicators; the only exception is the phrase it ends: "sans serif" and "sans-serif" are the name of a sans face. So the phrase is removed before the word is looked for, which keeps both spellings sans and gives every explicitly serif name back. Korean serif names stay ahead of all of it, so "Noto Sans Myungjo" and "Myungjo Gothic" are unchanged. --- crates/fonts/src/fontdb/fallback.rs | 11 ++++++----- crates/fonts/src/fontdb/tests/fallback.rs | 5 +++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/crates/fonts/src/fontdb/fallback.rs b/crates/fonts/src/fontdb/fallback.rs index 13afffd07..0b68f9c7c 100644 --- a/crates/fonts/src/fontdb/fallback.rs +++ b/crates/fonts/src/fontdb/fallback.rs @@ -123,6 +123,12 @@ pub fn sans_by_name(family: &str) -> Option { if has(&["batang", "myungjo", "myeongjo", "gungsuh", "\u{BC14}\u{D5D5}", "\u{BA85}\u{C870}", "\u{AD81}\u{C11C}"]) { return Some(false); } + // Then the word itself, which outranks every sans indicator: "Sweet Gothic Serif" is a serif + // family whatever "Gothic" suggests. "Sans serif" and "sans-serif" end with the word and do + // not mean it, so the phrase goes before the word is looked for (both noted in review). + if lower.replace("sans-serif", "sans").replace("sans serif", "sans").contains("serif") { + return Some(false); + } if has(&[ "dotum", "gothic", @@ -138,11 +144,6 @@ pub fn sans_by_name(family: &str) -> Option { ]) { return Some(true); } - // Only now the bare word, which "sans serif" and "sans-serif" end with and do not mean - // (noted in review): "Microsoft Sans Serif" is a sans face, and so is the CSS generic. - if lower.contains("serif") { - return Some(false); - } None } diff --git a/crates/fonts/src/fontdb/tests/fallback.rs b/crates/fonts/src/fontdb/tests/fallback.rs index d9a5ee71c..798443524 100644 --- a/crates/fonts/src/fontdb/tests/fallback.rs +++ b/crates/fonts/src/fontdb/tests/fallback.rs @@ -191,6 +191,11 @@ fn a_sans_serif_name_is_not_read_as_serif() { // And a Korean serif name still outranks "Sans", which is why it is tested first of all. assert_eq!(sans_by_name("Noto Sans Myungjo"), Some(false)); assert_eq!(sans_by_name("Myungjo Gothic"), Some(false)); + // And the word outranks every sans indicator: Sweet Gothic Serif is a serif family + // whatever "Gothic" suggests (noted in review). + for serif in ["Sweet Gothic Serif", "Gothic Serif", "Sans Forgetica Serif"] { + assert_eq!(sans_by_name(serif), Some(false), "{serif} names itself serif"); + } // Neither word present, so the caller still decides. assert_eq!(sans_by_name("monospace"), None); assert_eq!(sans_by_name("system-ui"), None);