mirror of
https://github.com/servo/servo.git
synced 2025-08-17 03:15:34 +01:00
fonts: Improve font fallback (#32286)
- Better detect situations where emoji is necessary by looking ahead one character while laying out. This allow processing Unicode presentation selectors. When detecting emoji, put emoji fonts at the front of fallback lists for all platforms. This enables monochrome emoji on Windows. Full-color emoji on Windows probably needs full support for processing the COLR table and drawing separate glyph color layers. - Improve the font fallback list on FreeType platforms. Ideally, Servo would be able to look through the entire font list to find the best font for a certain character, but until that time we can make sure the font list contains the "Noto Sans" fonts which cover most situations. Fixes #31664. Fixes #12944.
This commit is contained in:
parent
5f0866379a
commit
43a3c9c319
12 changed files with 610 additions and 292 deletions
|
@ -14,6 +14,7 @@ use ucd::{Codepoint, UnicodeBlock};
|
|||
|
||||
use crate::font_template::{FontTemplate, FontTemplateDescriptor};
|
||||
use crate::text::util::unicode_plane;
|
||||
use crate::text::FallbackFontSelectionOptions;
|
||||
|
||||
pub static SANS_SERIF_FONT_FAMILY: &str = "Arial";
|
||||
|
||||
|
@ -90,260 +91,263 @@ where
|
|||
}
|
||||
|
||||
// Based on gfxWindowsPlatform::GetCommonFallbackFonts() in Gecko
|
||||
pub fn fallback_font_families(codepoint: Option<char>) -> Vec<&'static str> {
|
||||
let mut families = vec!["Arial"];
|
||||
pub fn fallback_font_families(options: FallbackFontSelectionOptions) -> Vec<&'static str> {
|
||||
let mut families = Vec::new();
|
||||
|
||||
if let Some(codepoint) = codepoint {
|
||||
match unicode_plane(codepoint) {
|
||||
// https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane
|
||||
0 => {
|
||||
if let Some(block) = codepoint.block() {
|
||||
match block {
|
||||
UnicodeBlock::CyrillicSupplement |
|
||||
UnicodeBlock::Armenian |
|
||||
UnicodeBlock::Hebrew => {
|
||||
families.push("Estrangelo Edessa");
|
||||
families.push("Cambria");
|
||||
},
|
||||
if options.prefer_emoji_presentation {
|
||||
families.push("Segoe UI Emoji");
|
||||
}
|
||||
|
||||
UnicodeBlock::Arabic | UnicodeBlock::ArabicSupplement => {
|
||||
families.push("Microsoft Uighur");
|
||||
},
|
||||
families.push("Arial");
|
||||
match unicode_plane(options.character) {
|
||||
// https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane
|
||||
0 => {
|
||||
if let Some(block) = options.character.block() {
|
||||
match block {
|
||||
UnicodeBlock::CyrillicSupplement |
|
||||
UnicodeBlock::Armenian |
|
||||
UnicodeBlock::Hebrew => {
|
||||
families.push("Estrangelo Edessa");
|
||||
families.push("Cambria");
|
||||
},
|
||||
|
||||
UnicodeBlock::Syriac => {
|
||||
families.push("Estrangelo Edessa");
|
||||
},
|
||||
UnicodeBlock::Arabic | UnicodeBlock::ArabicSupplement => {
|
||||
families.push("Microsoft Uighur");
|
||||
},
|
||||
|
||||
UnicodeBlock::Thaana => {
|
||||
families.push("MV Boli");
|
||||
},
|
||||
UnicodeBlock::Syriac => {
|
||||
families.push("Estrangelo Edessa");
|
||||
},
|
||||
|
||||
UnicodeBlock::NKo => {
|
||||
families.push("Ebrima");
|
||||
},
|
||||
UnicodeBlock::Thaana => {
|
||||
families.push("MV Boli");
|
||||
},
|
||||
|
||||
UnicodeBlock::Devanagari | UnicodeBlock::Bengali => {
|
||||
families.push("Nirmala UI");
|
||||
families.push("Utsaah");
|
||||
families.push("Aparajita");
|
||||
},
|
||||
UnicodeBlock::NKo => {
|
||||
families.push("Ebrima");
|
||||
},
|
||||
|
||||
UnicodeBlock::Gurmukhi |
|
||||
UnicodeBlock::Gujarati |
|
||||
UnicodeBlock::Oriya |
|
||||
UnicodeBlock::Tamil |
|
||||
UnicodeBlock::Telugu |
|
||||
UnicodeBlock::Kannada |
|
||||
UnicodeBlock::Malayalam |
|
||||
UnicodeBlock::Sinhala |
|
||||
UnicodeBlock::Lepcha |
|
||||
UnicodeBlock::OlChiki |
|
||||
UnicodeBlock::CyrillicExtendedC |
|
||||
UnicodeBlock::SundaneseSupplement |
|
||||
UnicodeBlock::VedicExtensions => {
|
||||
families.push("Nirmala UI");
|
||||
},
|
||||
UnicodeBlock::Devanagari | UnicodeBlock::Bengali => {
|
||||
families.push("Nirmala UI");
|
||||
families.push("Utsaah");
|
||||
families.push("Aparajita");
|
||||
},
|
||||
|
||||
UnicodeBlock::Thai => {
|
||||
families.push("Leelawadee UI");
|
||||
},
|
||||
UnicodeBlock::Gurmukhi |
|
||||
UnicodeBlock::Gujarati |
|
||||
UnicodeBlock::Oriya |
|
||||
UnicodeBlock::Tamil |
|
||||
UnicodeBlock::Telugu |
|
||||
UnicodeBlock::Kannada |
|
||||
UnicodeBlock::Malayalam |
|
||||
UnicodeBlock::Sinhala |
|
||||
UnicodeBlock::Lepcha |
|
||||
UnicodeBlock::OlChiki |
|
||||
UnicodeBlock::CyrillicExtendedC |
|
||||
UnicodeBlock::SundaneseSupplement |
|
||||
UnicodeBlock::VedicExtensions => {
|
||||
families.push("Nirmala UI");
|
||||
},
|
||||
|
||||
UnicodeBlock::Lao => {
|
||||
families.push("Lao UI");
|
||||
},
|
||||
UnicodeBlock::Thai => {
|
||||
families.push("Leelawadee UI");
|
||||
},
|
||||
|
||||
UnicodeBlock::Myanmar |
|
||||
UnicodeBlock::MyanmarExtendedA |
|
||||
UnicodeBlock::MyanmarExtendedB => {
|
||||
families.push("Myanmar Text");
|
||||
},
|
||||
UnicodeBlock::Lao => {
|
||||
families.push("Lao UI");
|
||||
},
|
||||
|
||||
UnicodeBlock::HangulJamo |
|
||||
UnicodeBlock::HangulJamoExtendedA |
|
||||
UnicodeBlock::HangulSyllables |
|
||||
UnicodeBlock::HangulJamoExtendedB |
|
||||
UnicodeBlock::HangulCompatibilityJamo => {
|
||||
families.push("Malgun Gothic");
|
||||
},
|
||||
UnicodeBlock::Myanmar |
|
||||
UnicodeBlock::MyanmarExtendedA |
|
||||
UnicodeBlock::MyanmarExtendedB => {
|
||||
families.push("Myanmar Text");
|
||||
},
|
||||
|
||||
UnicodeBlock::Ethiopic |
|
||||
UnicodeBlock::EthiopicSupplement |
|
||||
UnicodeBlock::EthiopicExtended |
|
||||
UnicodeBlock::EthiopicExtendedA => {
|
||||
families.push("Nyala");
|
||||
},
|
||||
UnicodeBlock::HangulJamo |
|
||||
UnicodeBlock::HangulJamoExtendedA |
|
||||
UnicodeBlock::HangulSyllables |
|
||||
UnicodeBlock::HangulJamoExtendedB |
|
||||
UnicodeBlock::HangulCompatibilityJamo => {
|
||||
families.push("Malgun Gothic");
|
||||
},
|
||||
|
||||
UnicodeBlock::Cherokee => {
|
||||
families.push("Plantagenet Cherokee");
|
||||
},
|
||||
UnicodeBlock::Ethiopic |
|
||||
UnicodeBlock::EthiopicSupplement |
|
||||
UnicodeBlock::EthiopicExtended |
|
||||
UnicodeBlock::EthiopicExtendedA => {
|
||||
families.push("Nyala");
|
||||
},
|
||||
|
||||
UnicodeBlock::UnifiedCanadianAboriginalSyllabics |
|
||||
UnicodeBlock::UnifiedCanadianAboriginalSyllabicsExtended => {
|
||||
families.push("Euphemia");
|
||||
families.push("Segoe UI");
|
||||
},
|
||||
UnicodeBlock::Cherokee => {
|
||||
families.push("Plantagenet Cherokee");
|
||||
},
|
||||
|
||||
UnicodeBlock::Khmer | UnicodeBlock::KhmerSymbols => {
|
||||
families.push("Khmer UI");
|
||||
families.push("Leelawadee UI");
|
||||
},
|
||||
UnicodeBlock::UnifiedCanadianAboriginalSyllabics |
|
||||
UnicodeBlock::UnifiedCanadianAboriginalSyllabicsExtended => {
|
||||
families.push("Euphemia");
|
||||
families.push("Segoe UI");
|
||||
},
|
||||
|
||||
UnicodeBlock::Mongolian => {
|
||||
families.push("Mongolian Baiti");
|
||||
},
|
||||
UnicodeBlock::Khmer | UnicodeBlock::KhmerSymbols => {
|
||||
families.push("Khmer UI");
|
||||
families.push("Leelawadee UI");
|
||||
},
|
||||
|
||||
UnicodeBlock::TaiLe => {
|
||||
families.push("Microsoft Tai Le");
|
||||
},
|
||||
UnicodeBlock::Mongolian => {
|
||||
families.push("Mongolian Baiti");
|
||||
},
|
||||
|
||||
UnicodeBlock::NewTaiLue => {
|
||||
families.push("Microsoft New Tai Lue");
|
||||
},
|
||||
UnicodeBlock::TaiLe => {
|
||||
families.push("Microsoft Tai Le");
|
||||
},
|
||||
|
||||
UnicodeBlock::Buginese |
|
||||
UnicodeBlock::TaiTham |
|
||||
UnicodeBlock::CombiningDiacriticalMarksExtended => {
|
||||
families.push("Leelawadee UI");
|
||||
},
|
||||
UnicodeBlock::NewTaiLue => {
|
||||
families.push("Microsoft New Tai Lue");
|
||||
},
|
||||
|
||||
UnicodeBlock::GeneralPunctuation |
|
||||
UnicodeBlock::SuperscriptsandSubscripts |
|
||||
UnicodeBlock::CurrencySymbols |
|
||||
UnicodeBlock::CombiningDiacriticalMarksforSymbols |
|
||||
UnicodeBlock::LetterlikeSymbols |
|
||||
UnicodeBlock::NumberForms |
|
||||
UnicodeBlock::Arrows |
|
||||
UnicodeBlock::MathematicalOperators |
|
||||
UnicodeBlock::MiscellaneousTechnical |
|
||||
UnicodeBlock::ControlPictures |
|
||||
UnicodeBlock::OpticalCharacterRecognition |
|
||||
UnicodeBlock::EnclosedAlphanumerics |
|
||||
UnicodeBlock::BoxDrawing |
|
||||
UnicodeBlock::BlockElements |
|
||||
UnicodeBlock::GeometricShapes |
|
||||
UnicodeBlock::MiscellaneousSymbols |
|
||||
UnicodeBlock::Dingbats |
|
||||
UnicodeBlock::MiscellaneousMathematicalSymbolsA |
|
||||
UnicodeBlock::SupplementalArrowsA |
|
||||
UnicodeBlock::SupplementalArrowsB |
|
||||
UnicodeBlock::MiscellaneousMathematicalSymbolsB |
|
||||
UnicodeBlock::SupplementalMathematicalOperators |
|
||||
UnicodeBlock::MiscellaneousSymbolsandArrows |
|
||||
UnicodeBlock::Glagolitic |
|
||||
UnicodeBlock::LatinExtendedC |
|
||||
UnicodeBlock::Coptic => {
|
||||
families.push("Segoe UI");
|
||||
families.push("Segoe UI Symbol");
|
||||
families.push("Cambria");
|
||||
families.push("Meiryo");
|
||||
families.push("Lucida Sans Unicode");
|
||||
families.push("Ebrima");
|
||||
},
|
||||
UnicodeBlock::Buginese |
|
||||
UnicodeBlock::TaiTham |
|
||||
UnicodeBlock::CombiningDiacriticalMarksExtended => {
|
||||
families.push("Leelawadee UI");
|
||||
},
|
||||
|
||||
UnicodeBlock::GeorgianSupplement |
|
||||
UnicodeBlock::Tifinagh |
|
||||
UnicodeBlock::CyrillicExtendedA |
|
||||
UnicodeBlock::SupplementalPunctuation |
|
||||
UnicodeBlock::CJKRadicalsSupplement |
|
||||
UnicodeBlock::KangxiRadicals |
|
||||
UnicodeBlock::IdeographicDescriptionCharacters => {
|
||||
families.push("Segoe UI");
|
||||
families.push("Segoe UI Symbol");
|
||||
families.push("Meiryo");
|
||||
},
|
||||
UnicodeBlock::GeneralPunctuation |
|
||||
UnicodeBlock::SuperscriptsandSubscripts |
|
||||
UnicodeBlock::CurrencySymbols |
|
||||
UnicodeBlock::CombiningDiacriticalMarksforSymbols |
|
||||
UnicodeBlock::LetterlikeSymbols |
|
||||
UnicodeBlock::NumberForms |
|
||||
UnicodeBlock::Arrows |
|
||||
UnicodeBlock::MathematicalOperators |
|
||||
UnicodeBlock::MiscellaneousTechnical |
|
||||
UnicodeBlock::ControlPictures |
|
||||
UnicodeBlock::OpticalCharacterRecognition |
|
||||
UnicodeBlock::EnclosedAlphanumerics |
|
||||
UnicodeBlock::BoxDrawing |
|
||||
UnicodeBlock::BlockElements |
|
||||
UnicodeBlock::GeometricShapes |
|
||||
UnicodeBlock::MiscellaneousSymbols |
|
||||
UnicodeBlock::Dingbats |
|
||||
UnicodeBlock::MiscellaneousMathematicalSymbolsA |
|
||||
UnicodeBlock::SupplementalArrowsA |
|
||||
UnicodeBlock::SupplementalArrowsB |
|
||||
UnicodeBlock::MiscellaneousMathematicalSymbolsB |
|
||||
UnicodeBlock::SupplementalMathematicalOperators |
|
||||
UnicodeBlock::MiscellaneousSymbolsandArrows |
|
||||
UnicodeBlock::Glagolitic |
|
||||
UnicodeBlock::LatinExtendedC |
|
||||
UnicodeBlock::Coptic => {
|
||||
families.push("Segoe UI");
|
||||
families.push("Segoe UI Symbol");
|
||||
families.push("Cambria");
|
||||
families.push("Meiryo");
|
||||
families.push("Lucida Sans Unicode");
|
||||
families.push("Ebrima");
|
||||
},
|
||||
|
||||
UnicodeBlock::BraillePatterns => {
|
||||
families.push("Segoe UI Symbol");
|
||||
},
|
||||
UnicodeBlock::GeorgianSupplement |
|
||||
UnicodeBlock::Tifinagh |
|
||||
UnicodeBlock::CyrillicExtendedA |
|
||||
UnicodeBlock::SupplementalPunctuation |
|
||||
UnicodeBlock::CJKRadicalsSupplement |
|
||||
UnicodeBlock::KangxiRadicals |
|
||||
UnicodeBlock::IdeographicDescriptionCharacters => {
|
||||
families.push("Segoe UI");
|
||||
families.push("Segoe UI Symbol");
|
||||
families.push("Meiryo");
|
||||
},
|
||||
|
||||
UnicodeBlock::CJKSymbolsandPunctuation |
|
||||
UnicodeBlock::Hiragana |
|
||||
UnicodeBlock::Katakana |
|
||||
UnicodeBlock::Bopomofo |
|
||||
UnicodeBlock::Kanbun |
|
||||
UnicodeBlock::BopomofoExtended |
|
||||
UnicodeBlock::CJKStrokes |
|
||||
UnicodeBlock::KatakanaPhoneticExtensions |
|
||||
UnicodeBlock::CJKUnifiedIdeographs => {
|
||||
families.push("Microsoft YaHei");
|
||||
families.push("Yu Gothic");
|
||||
},
|
||||
UnicodeBlock::BraillePatterns => {
|
||||
families.push("Segoe UI Symbol");
|
||||
},
|
||||
|
||||
UnicodeBlock::EnclosedCJKLettersandMonths => {
|
||||
families.push("Malgun Gothic");
|
||||
},
|
||||
UnicodeBlock::CJKSymbolsandPunctuation |
|
||||
UnicodeBlock::Hiragana |
|
||||
UnicodeBlock::Katakana |
|
||||
UnicodeBlock::Bopomofo |
|
||||
UnicodeBlock::Kanbun |
|
||||
UnicodeBlock::BopomofoExtended |
|
||||
UnicodeBlock::CJKStrokes |
|
||||
UnicodeBlock::KatakanaPhoneticExtensions |
|
||||
UnicodeBlock::CJKUnifiedIdeographs => {
|
||||
families.push("Microsoft YaHei");
|
||||
families.push("Yu Gothic");
|
||||
},
|
||||
|
||||
UnicodeBlock::YijingHexagramSymbols => {
|
||||
families.push("Segoe UI Symbol");
|
||||
},
|
||||
UnicodeBlock::EnclosedCJKLettersandMonths => {
|
||||
families.push("Malgun Gothic");
|
||||
},
|
||||
|
||||
UnicodeBlock::YiSyllables | UnicodeBlock::YiRadicals => {
|
||||
families.push("Microsoft Yi Baiti");
|
||||
families.push("Segoe UI");
|
||||
},
|
||||
UnicodeBlock::YijingHexagramSymbols => {
|
||||
families.push("Segoe UI Symbol");
|
||||
},
|
||||
|
||||
UnicodeBlock::Vai |
|
||||
UnicodeBlock::CyrillicExtendedB |
|
||||
UnicodeBlock::Bamum |
|
||||
UnicodeBlock::ModifierToneLetters |
|
||||
UnicodeBlock::LatinExtendedD => {
|
||||
families.push("Ebrima");
|
||||
families.push("Segoe UI");
|
||||
families.push("Cambria Math");
|
||||
},
|
||||
UnicodeBlock::YiSyllables | UnicodeBlock::YiRadicals => {
|
||||
families.push("Microsoft Yi Baiti");
|
||||
families.push("Segoe UI");
|
||||
},
|
||||
|
||||
UnicodeBlock::SylotiNagri |
|
||||
UnicodeBlock::CommonIndicNumberForms |
|
||||
UnicodeBlock::Phagspa |
|
||||
UnicodeBlock::Saurashtra |
|
||||
UnicodeBlock::DevanagariExtended => {
|
||||
families.push("Microsoft PhagsPa");
|
||||
families.push("Nirmala UI");
|
||||
},
|
||||
UnicodeBlock::Vai |
|
||||
UnicodeBlock::CyrillicExtendedB |
|
||||
UnicodeBlock::Bamum |
|
||||
UnicodeBlock::ModifierToneLetters |
|
||||
UnicodeBlock::LatinExtendedD => {
|
||||
families.push("Ebrima");
|
||||
families.push("Segoe UI");
|
||||
families.push("Cambria Math");
|
||||
},
|
||||
|
||||
UnicodeBlock::KayahLi | UnicodeBlock::Rejang | UnicodeBlock::Javanese => {
|
||||
families.push("Malgun Gothic");
|
||||
families.push("Javanese Text");
|
||||
families.push("Leelawadee UI");
|
||||
},
|
||||
UnicodeBlock::SylotiNagri |
|
||||
UnicodeBlock::CommonIndicNumberForms |
|
||||
UnicodeBlock::Phagspa |
|
||||
UnicodeBlock::Saurashtra |
|
||||
UnicodeBlock::DevanagariExtended => {
|
||||
families.push("Microsoft PhagsPa");
|
||||
families.push("Nirmala UI");
|
||||
},
|
||||
|
||||
UnicodeBlock::AlphabeticPresentationForms => {
|
||||
families.push("Microsoft Uighur");
|
||||
families.push("Gabriola");
|
||||
families.push("Sylfaen");
|
||||
},
|
||||
UnicodeBlock::KayahLi | UnicodeBlock::Rejang | UnicodeBlock::Javanese => {
|
||||
families.push("Malgun Gothic");
|
||||
families.push("Javanese Text");
|
||||
families.push("Leelawadee UI");
|
||||
},
|
||||
|
||||
UnicodeBlock::ArabicPresentationFormsA |
|
||||
UnicodeBlock::ArabicPresentationFormsB => {
|
||||
families.push("Traditional Arabic");
|
||||
families.push("Arabic Typesetting");
|
||||
},
|
||||
UnicodeBlock::AlphabeticPresentationForms => {
|
||||
families.push("Microsoft Uighur");
|
||||
families.push("Gabriola");
|
||||
families.push("Sylfaen");
|
||||
},
|
||||
|
||||
UnicodeBlock::VariationSelectors |
|
||||
UnicodeBlock::VerticalForms |
|
||||
UnicodeBlock::CombiningHalfMarks |
|
||||
UnicodeBlock::CJKCompatibilityForms |
|
||||
UnicodeBlock::SmallFormVariants |
|
||||
UnicodeBlock::HalfwidthandFullwidthForms |
|
||||
UnicodeBlock::Specials => {
|
||||
families.push("Microsoft JhengHei");
|
||||
},
|
||||
UnicodeBlock::ArabicPresentationFormsA |
|
||||
UnicodeBlock::ArabicPresentationFormsB => {
|
||||
families.push("Traditional Arabic");
|
||||
families.push("Arabic Typesetting");
|
||||
},
|
||||
|
||||
_ => {},
|
||||
}
|
||||
UnicodeBlock::VariationSelectors |
|
||||
UnicodeBlock::VerticalForms |
|
||||
UnicodeBlock::CombiningHalfMarks |
|
||||
UnicodeBlock::CJKCompatibilityForms |
|
||||
UnicodeBlock::SmallFormVariants |
|
||||
UnicodeBlock::HalfwidthandFullwidthForms |
|
||||
UnicodeBlock::Specials => {
|
||||
families.push("Microsoft JhengHei");
|
||||
},
|
||||
|
||||
_ => {},
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
// https://en.wikipedia.org/wiki/Plane_(Unicode)#Supplementary_Multilingual_Plane
|
||||
1 => {
|
||||
families.push("Segoe UI Symbol");
|
||||
families.push("Ebrima");
|
||||
families.push("Nirmala UI");
|
||||
families.push("Cambria Math");
|
||||
},
|
||||
// https://en.wikipedia.org/wiki/Plane_(Unicode)#Supplementary_Multilingual_Plane
|
||||
1 => {
|
||||
families.push("Segoe UI Symbol");
|
||||
families.push("Ebrima");
|
||||
families.push("Nirmala UI");
|
||||
families.push("Cambria Math");
|
||||
},
|
||||
|
||||
_ => {},
|
||||
}
|
||||
_ => {},
|
||||
}
|
||||
|
||||
families.push("Arial Unicode MS");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue