Korean fallback: spell 바탕 right, and choose the label's fallback style once

This commit is contained in:
Hamza committed 2026-11-04 12:55:57 +05:00
1 parent 5792d32bdf
commit 39ea3513a4
3 files changed
+11 -5

No files matched your search

+2 -1
View File
@@ -1169,8 +1169,9 @@ fn shape_segment(
if let Some(label) = replacement.filter(|_| auto_leading.glyph_fallback) {
let lang = designcraft_doc::language_tag(&p.language);
let mut segments: Vec<(usize, usize, Arc<FontFace>)> = Vec::new();
// The same for every character of the label: worked out once, not per character.
let prefer_sans = designcraft_fonts::sans_by_name(&p.font_family).or_else(|| style_of_substitute(&face.family));
for (at, c) in label.char_indices() {
let prefer_sans = designcraft_fonts::sans_by_name(&p.font_family).or_else(|| style_of_substitute(&face.family));
let selected =
if face.covers(c) { face.clone() } else { db.fallback_for_styled(c, face.id(), lang, prefer_sans).unwrap_or_else(|| face.clone()) };
if let Some((_, end, previous)) = segments.last_mut().filter(|(_, _, previous)| previous.id() == selected.id()) {
+2 -2
View File
@@ -120,12 +120,12 @@ pub fn sans_by_name(family: &str) -> Option<bool> {
let has = |needles: &[&str]| needles.iter().any(|n| lower.contains(n));
// A Korean serif name comes first: "Myungjo Gothic" does not exist, but a name holding both
// reads as the serif it names, and "Sans" inside "Noto Sans Myungjo" would otherwise win.
if has(&["batang", "myungjo", "myeongjo", "gungsuh", "\u{BC14}\u{D5D5}", "\u{BA85}\u{C870}", "\u{AD81}\u{C11C}"]) {
if has(&["batang", "myungjo", "myeongjo", "gungsuh", "\u{BC14}\u{D0D5}", "\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).
// not mean it, so the phrase goes before the word is looked for.
if lower.replace("sans-serif", "sans").replace("sans serif", "sans").contains("serif") {
return Some(false);
}
+7 -2
View File
@@ -178,7 +178,7 @@ fn a_korean_family_name_says_sans_or_serif() {
/// "sans serif" ends with the word it is not. The bare "serif" needle matched first, so
/// "Microsoft Sans Serif" -- and the CSS generic -- classified as serif and a missing Hangul
/// glyph took the serif-first chain (noted in review of #1692).
/// glyph took the serif-first chain (#1692).
#[test]
fn a_sans_serif_name_is_not_read_as_serif() {
for sans in ["sans-serif", "Microsoft Sans Serif", "MS Sans Serif", "Lucida Sans Serif"] {
@@ -192,10 +192,15 @@ fn a_sans_serif_name_is_not_read_as_serif() {
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).
// whatever "Gothic" suggests.
for serif in ["Sweet Gothic Serif", "Gothic Serif", "Sans Forgetica Serif"] {
assert_eq!(sans_by_name(serif), Some(false), "{serif} names itself serif");
}
// Korean serif names written in Hangul: 바탕 (Batang), 명조 (Myungjo), 궁서 (Gungsuh). 바탕 was
// spelled with the wrong second syllable, so a Hangul Batang name was not recognised.
for serif in ["\u{BC14}\u{D0D5}\u{CCB4}", "HCR \u{BC14}\u{D0D5}", "\u{D55C}\u{CEF4} \u{BA85}\u{C870}", "\u{AD81}\u{C11C}\u{CCB4}"] {
assert_eq!(sans_by_name(serif), Some(false), "{serif} is serif");
}
// Neither word present, so the caller still decides.
assert_eq!(sans_by_name("monospace"), None);
assert_eq!(sans_by_name("system-ui"), None);