Text library moved from libcosmic
This commit is contained in:
commit
410d4ee674
37 changed files with 12909 additions and 0 deletions
85
src/font/fallback/macos.rs
Normal file
85
src/font/fallback/macos.rs
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
use unicode_script::Script;
|
||||
|
||||
// Fallbacks to use after any script specific fallbacks
|
||||
pub fn common_fallback() -> &'static [&'static str] {
|
||||
&[
|
||||
".SF NS",
|
||||
"Apple Color Emoji",
|
||||
"Geneva",
|
||||
"Arial Unicode MS",
|
||||
]
|
||||
}
|
||||
|
||||
// Fallbacks to never use
|
||||
pub fn forbidden_fallback() -> &'static [&'static str] {
|
||||
&[
|
||||
".LastResort",
|
||||
]
|
||||
}
|
||||
|
||||
fn han_unification(locale: &str) -> &'static [&'static str] {
|
||||
match locale {
|
||||
// Japan
|
||||
"ja" => &["Hiragino Sans"],
|
||||
// Korea
|
||||
"ko" => &["Apple SD Gothic Neo"],
|
||||
// Hong Kong
|
||||
"zh-HK" => &["PingFang HK"],
|
||||
// Taiwan
|
||||
"zh-TW" => &["PingFang TC"],
|
||||
// Simplified Chinese is the default (also catches "zh-CN" for China)
|
||||
_ => &["PingFang SC"],
|
||||
}
|
||||
}
|
||||
|
||||
// Fallbacks to use per script
|
||||
pub fn script_fallback(script: &Script, locale: &str) -> &'static [&'static str] {
|
||||
//TODO: abstract style (sans/serif/monospaced)
|
||||
//TODO: pull more data from about:config font.name-list.sans-serif in Firefox
|
||||
match script {
|
||||
Script::Adlam => &["Noto Sans Adlam"],
|
||||
Script::Arabic => &["Geeza Pro"],
|
||||
Script::Armenian => &["Noto Sans Armenian"],
|
||||
Script::Bengali => &["Bangla Sangam MN"],
|
||||
Script::Buhid => &["Noto Sans Buhid"],
|
||||
Script::Canadian_Aboriginal => &["Euphemia UCAS"],
|
||||
Script::Chakma => &["Noto Sans Chakma"],
|
||||
Script::Devanagari => &["Devanagari Sangam MN"],
|
||||
Script::Ethiopic => &["Kefa"],
|
||||
Script::Gothic => &["Noto Sans Gothic"],
|
||||
Script::Grantha => &["Grantha Sangam MN"],
|
||||
Script::Gujarati => &["Gujarati Sangam MN"],
|
||||
Script::Gurmukhi => &["Gurmukhi Sangam MN"],
|
||||
Script::Han => han_unification(locale),
|
||||
Script::Hangul => han_unification("ko"),
|
||||
Script::Hanunoo => &["Noto Sans Hanunoo"],
|
||||
Script::Hebrew => &["Arial"],
|
||||
Script::Hiragana => han_unification("ja"),
|
||||
Script::Javanese => &["Noto Sans Javanese"],
|
||||
Script::Kannada => &["Noto Sans Kannada"],
|
||||
Script::Katakana => han_unification("ja"),
|
||||
Script::Khmer => &["Khmer Sangam MN"],
|
||||
Script::Lao => &["Lao Sangam MN"],
|
||||
Script::Malayalam => &["Malayalam Sangam MN"],
|
||||
Script::Mongolian => &["Noto Sans Mongolian"],
|
||||
Script::Myanmar => &["Noto Sans Myanmar"],
|
||||
Script::Oriya => &["Noto Sans Oriya"],
|
||||
Script::Sinhala => &["Sinhala Sangam MN"],
|
||||
Script::Syriac => &["Noto Sans Syriac"],
|
||||
Script::Tagalog => &["Noto Sans Tagalog"],
|
||||
Script::Tagbanwa => &["Noto Sans Tagbanwa"],
|
||||
Script::Tai_Le => &["Noto Sans Tai Le"],
|
||||
Script::Tai_Tham => &["Noto Sans Tai Tham"],
|
||||
Script::Tai_Viet => &["Noto Sans Tai Viet"],
|
||||
Script::Tamil => &["InaiMathi"],
|
||||
Script::Telugu => &["Telugu Sangam MN"],
|
||||
Script::Thaana => &["Noto Sans Thaana"],
|
||||
Script::Thai => &["Ayuthaya"],
|
||||
Script::Tibetan => &["Kailasa"],
|
||||
Script::Tifinagh => &["Noto Sans Tifinagh"],
|
||||
Script::Vai => &["Noto Sans Vai"],
|
||||
//TODO: Use han_unification?
|
||||
Script::Yi => &["Noto Sans Yi", "PingFang SC"],
|
||||
_ => &[],
|
||||
}
|
||||
}
|
||||
138
src/font/fallback/mod.rs
Normal file
138
src/font/fallback/mod.rs
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
use unicode_script::Script;
|
||||
|
||||
use super::Font;
|
||||
|
||||
use self::platform::*;
|
||||
|
||||
#[cfg(not(any(
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "windows",
|
||||
)))]
|
||||
#[path = "other.rs"]
|
||||
mod platform;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[path = "macos.rs"]
|
||||
mod platform;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[path = "unix.rs"]
|
||||
mod platform;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
#[path = "windows.rs"]
|
||||
mod platform;
|
||||
|
||||
pub struct FontFallbackIter<'a> {
|
||||
fonts: &'a [Font<'a>],
|
||||
default_family_opt: Option<&'a str>,
|
||||
scripts: Vec<Script>,
|
||||
locale: &'a str,
|
||||
script_i: (usize, usize),
|
||||
common_i: usize,
|
||||
other_i: usize,
|
||||
end: bool,
|
||||
}
|
||||
|
||||
impl<'a> FontFallbackIter<'a> {
|
||||
pub fn new(fonts: &'a [Font<'a>], default_family_opt: Option<&'a str>, scripts: Vec<Script>, locale: &'a str) -> Self {
|
||||
Self {
|
||||
fonts,
|
||||
default_family_opt,
|
||||
scripts,
|
||||
locale,
|
||||
script_i: (0, 0),
|
||||
common_i: 0,
|
||||
other_i: 0,
|
||||
end: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_missing(&self, word: &str) {
|
||||
if self.end {
|
||||
log::warn!(
|
||||
"Failed to find any fallback for {:?} locale '{}': '{}'",
|
||||
self.scripts,
|
||||
self.locale,
|
||||
word
|
||||
);
|
||||
} else if self.other_i > 0 {
|
||||
let font = &self.fonts[self.other_i - 1];
|
||||
log::warn!(
|
||||
"Failed to find preset fallback for {:?} locale '{}', used '{}': '{}'",
|
||||
self.scripts,
|
||||
self.locale,
|
||||
font.info.family,
|
||||
word
|
||||
);
|
||||
} else if ! self.scripts.is_empty() && self.common_i > 0 {
|
||||
let family = common_fallback()[self.common_i - 1];
|
||||
log::debug!(
|
||||
"Failed to find script fallback for {:?} locale '{}', used '{}': '{}'",
|
||||
self.scripts,
|
||||
self.locale,
|
||||
family,
|
||||
word
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for FontFallbackIter<'a> {
|
||||
type Item = &'a Font<'a>;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if let Some(default_family) = self.default_family_opt.take() {
|
||||
for font in self.fonts.iter() {
|
||||
if font.info.family == default_family {
|
||||
return Some(font);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while self.script_i.0 < self.scripts.len() {
|
||||
let script = self.scripts[self.script_i.0];
|
||||
|
||||
let script_families = script_fallback(&script, self.locale);
|
||||
while self.script_i.1 < script_families.len() {
|
||||
let script_family = script_families[self.script_i.1];
|
||||
self.script_i.1 += 1;
|
||||
for font in self.fonts.iter() {
|
||||
if font.info.family == script_family {
|
||||
return Some(font);
|
||||
}
|
||||
}
|
||||
log::warn!("failed to find family '{}' for script {:?} and locale '{}'", script_family, script, self.locale);
|
||||
}
|
||||
|
||||
self.script_i.0 += 1;
|
||||
self.script_i.1 = 0;
|
||||
}
|
||||
|
||||
let common_families = common_fallback();
|
||||
while self.common_i < common_families.len() {
|
||||
let common_family = common_families[self.common_i];
|
||||
self.common_i += 1;
|
||||
for font in self.fonts.iter() {
|
||||
if font.info.family == common_family {
|
||||
return Some(font);
|
||||
}
|
||||
}
|
||||
log::warn!("failed to find family '{}'", common_family)
|
||||
}
|
||||
|
||||
//TODO: do we need to do this?
|
||||
//TODO: do not evaluate fonts more than once!
|
||||
let forbidden_families = forbidden_fallback();
|
||||
while self.other_i < self.fonts.len() {
|
||||
let font = &self.fonts[self.other_i];
|
||||
self.other_i += 1;
|
||||
if ! forbidden_families.contains(&font.info.family.as_str()) {
|
||||
return Some(font);
|
||||
}
|
||||
}
|
||||
|
||||
self.end = true;
|
||||
None
|
||||
}
|
||||
}
|
||||
16
src/font/fallback/other.rs
Normal file
16
src/font/fallback/other.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
use unicode_script::Script;
|
||||
|
||||
// Fallbacks to use after any script specific fallbacks
|
||||
pub fn common_fallback() -> &'static [&'static str] {
|
||||
&[]
|
||||
}
|
||||
|
||||
// Fallbacks to never use
|
||||
pub fn forbidden_fallback() -> &'static [&'static str] {
|
||||
&[]
|
||||
}
|
||||
|
||||
// Fallbacks to use per script
|
||||
pub fn script_fallback(script: &Script, locale: &str) -> &'static [&'static str] {
|
||||
&[]
|
||||
}
|
||||
90
src/font/fallback/unix.rs
Normal file
90
src/font/fallback/unix.rs
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
use unicode_script::Script;
|
||||
|
||||
// Fallbacks to use after any script specific fallbacks
|
||||
pub fn common_fallback() -> &'static [&'static str] {
|
||||
//TODO: abstract style (sans/serif/monospaced)
|
||||
&[
|
||||
"DejaVu Sans",
|
||||
"FreeSans",
|
||||
"Noto Sans Symbols",
|
||||
"Noto Sans Symbols2",
|
||||
"Noto Color Emoji",
|
||||
//TODO: Add CJK script here for doublewides?
|
||||
]
|
||||
}
|
||||
|
||||
// Fallbacks to never use
|
||||
pub fn forbidden_fallback() -> &'static [&'static str] {
|
||||
&[]
|
||||
}
|
||||
|
||||
fn han_unification(locale: &str) -> &'static [&'static str] {
|
||||
match locale {
|
||||
// Japan
|
||||
"ja" => &["Noto Sans CJK JA"],
|
||||
// Korea
|
||||
"ko" => &["Noto Sans CJK KR"],
|
||||
// Hong Kong
|
||||
"zh-HK" => &["Noto Sans CJK HK"],
|
||||
// Taiwan
|
||||
"zh-TW" => &["Noto Sans CJK TC"],
|
||||
// Simplified Chinese is the default (also catches "zh-CN" for China)
|
||||
_ => &["Noto Sans CJK SC"],
|
||||
}
|
||||
}
|
||||
|
||||
// Fallbacks to use per script
|
||||
pub fn script_fallback(script: &Script, locale: &str) -> &'static [&'static str] {
|
||||
//TODO: abstract style (sans/serif/monospaced)
|
||||
match script {
|
||||
Script::Adlam => &["Noto Sans Adlam", "Noto Sans Adlam Unjoined"],
|
||||
Script::Arabic => &["Noto Sans Arabic"],
|
||||
Script::Armenian => &["Noto Sans Armenian"],
|
||||
Script::Bengali => &["Noto Sans Bengali"],
|
||||
Script::Bopomofo => han_unification(locale),
|
||||
Script::Buhid => &["Noto Sans Buhid"],
|
||||
Script::Chakma => &["Noto Sans Chakma"],
|
||||
Script::Cherokee => &["Noto Sans Cherokee"],
|
||||
Script::Deseret => &["Noto Sans Deseret"],
|
||||
Script::Devanagari => &["Noto Sans Devanagari"],
|
||||
Script::Ethiopic => &["Noto Sans Ethiopic"],
|
||||
Script::Georgian => &["Noto Sans Georgian"],
|
||||
Script::Gothic => &["Noto Sans Gothic"],
|
||||
Script::Grantha => &["Noto Sans Grantha"],
|
||||
Script::Gujarati => &["Noto Sans Gujarati"],
|
||||
Script::Gurmukhi => &["Noto Sans Gurmukhi"],
|
||||
Script::Han => han_unification(locale),
|
||||
Script::Hangul => han_unification("ko"),
|
||||
Script::Hanunoo => &["Noto Sans Hanunoo"],
|
||||
Script::Hebrew => &["Noto Sans Hebrew"],
|
||||
Script::Hiragana => han_unification("ja"),
|
||||
Script::Javanese => &["Noto Sans Javanese"],
|
||||
Script::Kannada => &["Noto Sans Kannada"],
|
||||
Script::Katakana => han_unification("ja"),
|
||||
Script::Khmer => &["Noto Sans Khmer"],
|
||||
Script::Lao => &["Noto Sans Lao"],
|
||||
Script::Malayalam => &["Noto Sans Malayalam"],
|
||||
Script::Mongolian => &["Noto Sans Mongolian"],
|
||||
Script::Myanmar => &["Noto Sans Myanmar"],
|
||||
Script::Oriya => &["Noto Sans Oriya"],
|
||||
Script::Runic => &["Noto Sans Runic"],
|
||||
Script::Sinhala => &["Noto Sans Sinhala"],
|
||||
Script::Syriac => &["Noto Sans Syriac"],
|
||||
Script::Tagalog => &["Noto Sans Tagalog"],
|
||||
Script::Tagbanwa => &["Noto Sans Tagbanwa"],
|
||||
Script::Tai_Le => &["Noto Sans Tai Le"],
|
||||
Script::Tai_Tham => &["Noto Sans Tai Tham"],
|
||||
Script::Tai_Viet => &["Noto Sans Tai Viet"],
|
||||
Script::Tamil => &["Noto Sans Tamil"],
|
||||
Script::Telugu => &["Noto Sans Telugu"],
|
||||
Script::Thaana => &["Noto Sans Thaana"],
|
||||
Script::Thai => &["Noto Sans Thai"],
|
||||
//TODO: no sans script?
|
||||
Script::Tibetan => &["Noto Serif Tibetan"],
|
||||
Script::Tifinagh => &["Noto Sans Tifinagh"],
|
||||
Script::Vai => &["Noto Sans Vai"],
|
||||
//TODO: Use han_unification?
|
||||
Script::Yi => &["Noto Sans Yi", "Noto Sans CJK SC"],
|
||||
_ => &[],
|
||||
}
|
||||
}
|
||||
72
src/font/fallback/windows.rs
Normal file
72
src/font/fallback/windows.rs
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
use unicode_script::Script;
|
||||
|
||||
// Fallbacks to use after any script specific fallbacks
|
||||
pub fn common_fallback() -> &'static [&'static str] {
|
||||
//TODO: abstract style (sans/serif/monospaced)
|
||||
&[
|
||||
"Segoe UI",
|
||||
"Segoe UI Emoji",
|
||||
"Segoe UI Symbol",
|
||||
"Segoe UI Historic",
|
||||
//TODO: Add CJK script here for doublewides?
|
||||
]
|
||||
}
|
||||
|
||||
// Fallbacks to never use
|
||||
pub fn forbidden_fallback() -> &'static [&'static str] {
|
||||
&[]
|
||||
}
|
||||
|
||||
fn han_unification(locale: &str) -> &'static [&'static str] {
|
||||
//TODO!
|
||||
match locale {
|
||||
// Japan
|
||||
"ja" => &["Yu Gothic"],
|
||||
// Korea
|
||||
"ko" => &["Malgun Gothic"],
|
||||
// Hong Kong"
|
||||
"zh-HK" => &["MingLiU_HKSCS"],
|
||||
// Taiwan
|
||||
"zh-TW" => &["Microsoft JhengHei UI"],
|
||||
// Simplified Chinese is the default (also catches "zh-CN" for China)
|
||||
_ => &["Microsoft YaHei UI"]
|
||||
}
|
||||
}
|
||||
|
||||
// Fallbacks to use per script
|
||||
pub fn script_fallback(script: &Script, locale: &str) -> &'static [&'static str] {
|
||||
//TODO: better match https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc#L99
|
||||
match script {
|
||||
Script::Adlam => &["Ebrima"],
|
||||
Script::Bengali => &["Nirmala UI"],
|
||||
Script::Canadian_Aboriginal => &["Gadugi"],
|
||||
Script::Chakma => &["Nirmala UI"],
|
||||
Script::Cherokee => &["Gadugi"],
|
||||
Script::Devanagari => &["Nirmala UI"],
|
||||
Script::Ethiopic => &["Ebrima"],
|
||||
Script::Gujarati => &["Nirmala UI"],
|
||||
Script::Gurmukhi => &["Nirmala UI"],
|
||||
Script::Han => han_unification(locale),
|
||||
Script::Hangul => han_unification("ko"),
|
||||
Script::Hiragana => han_unification("ja"),
|
||||
Script::Javanese => &["Javanese Text"],
|
||||
Script::Kannada => &["Nirmala UI"],
|
||||
Script::Katakana => han_unification("ja"),
|
||||
Script::Khmer => &["Leelawadee UI"],
|
||||
Script::Lao => &["Leelawadee UI"],
|
||||
Script::Malayalam => &["Nirmala UI"],
|
||||
Script::Mongolian => &["Mongolian Baiti"],
|
||||
Script::Myanmar => &["Myanmar Text"],
|
||||
Script::Oriya => &["Nirmala UI"],
|
||||
Script::Sinhala => &["Nirmala UI"],
|
||||
Script::Tamil => &["Nirmala UI"],
|
||||
Script::Telugu => &["Nirmala UI"],
|
||||
Script::Thaana => &["MV Boli"],
|
||||
Script::Thai => &["Leelawadee UI"],
|
||||
Script::Tibetan => &["Microsoft Himalaya"],
|
||||
Script::Tifinagh => &["Ebrima"],
|
||||
Script::Vai => &["Ebrima"],
|
||||
Script::Yi => &["Microsoft Yi Baiti"],
|
||||
_ => &[],
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue