use valo::{Font, FontAttrs};
pub use valo::{FontCollection, FontDemand, FontId, FontSource};
use valo_system_fonts::SystemFonts;
pub use valo_system_fonts::fontmgr::{FontManager, Typeface};
use crate::TargetPlatform;
pub struct SystemFontSource {
fonts: SystemFonts,
}
const CUPERTINO_TEXT: &str = "CupertinoSystemText";
const CUPERTINO_DISPLAY: &str = "CupertinoSystemDisplay";
const TEXT_SIZE: f32 = 17.0;
const DISPLAY_SIZE: f32 = 29.0;
impl SystemFontSource {
pub fn new(manager: Box<dyn FontManager>) -> SystemFontSource {
SystemFontSource {
fonts: SystemFonts::with_manager(manager),
}
}
#[cfg(not(target_arch = "wasm32"))]
pub fn platform() -> SystemFontSource {
SystemFontSource {
fonts: SystemFonts::load(),
}
}
pub fn set_locales(&mut self, locales: Vec<String>) {
self.fonts.set_locales(locales);
}
}
impl FontSource for SystemFontSource {
fn family(&mut self, name: &str) -> Vec<Font> {
match name {
CUPERTINO_TEXT => self.fonts.system_family(TEXT_SIZE),
CUPERTINO_DISPLAY => self.fonts.system_family(DISPLAY_SIZE),
_ => self.fonts.family(name),
}
}
fn face_for_codepoint(&mut self, codepoint: char, attrs: FontAttrs) -> Option<Font> {
self.fonts.face_for_codepoint(codepoint, attrs)
}
}
pub fn default_font_families(os: TargetPlatform) -> Vec<String> {
let families: &[&str] = match os {
TargetPlatform::Android => &["sans-serif"],
TargetPlatform::Fuchsia => &["Roboto"],
TargetPlatform::IOS | TargetPlatform::MacOS => &[CUPERTINO_TEXT],
TargetPlatform::Linux => &[
"Ubuntu",
"Adwaita Sans",
"Cantarell",
"DejaVu Sans",
"Liberation Sans",
"Arial",
],
TargetPlatform::Windows => &["Segoe UI", "Arial"],
};
families.iter().map(|&family| family.to_owned()).collect()
}
pub fn set_default_font_manager(
fonts: &mut FontCollection,
mut source: Box<dyn FontSource>,
families: &[String],
) {
for name in families {
for mut font in source.family(name) {
font.add_alias(name);
let id = fonts.add(font);
fonts.add_fallback(id);
}
}
fonts.add_boxed_source(source);
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Platform;
#[test]
fn default_font_families_match_the_engine_on_this_os() {
let names = crate::InertPlatform.default_font_families();
assert!(!names.is_empty());
#[cfg(any(target_os = "macos", target_os = "ios"))]
assert_eq!(names, vec![CUPERTINO_TEXT]);
#[cfg(target_os = "android")]
assert_eq!(names, vec!["sans-serif"]);
}
}