use oxifont::db::{FontDatabase, Query, Source};
pub fn build_system_db() -> Option<FontDatabase> {
FontDatabase::system().ok()
}
pub fn load_font_for_family(family: &str) -> Option<Vec<u8>> {
let db = build_system_db()?;
load_font_for_family_from(&db, family)
}
pub fn load_font_for_family_from(db: &FontDatabase, family: &str) -> Option<Vec<u8>> {
let face = Query::new(db).family(family).match_best()?;
load_face_bytes(&face.source)
}
pub fn load_best_font_for_text(text: &str) -> Option<Vec<u8>> {
if text.is_empty() {
return None;
}
let db = build_system_db()?;
load_best_font_for_text_from(&db, text)
}
pub fn load_best_font_for_text_from(db: &FontDatabase, text: &str) -> Option<Vec<u8>> {
if text.is_empty() {
return None;
}
let faces = Query::new(db).match_with_fallback(text);
for face in faces {
if let Some(bytes) = load_face_bytes(&face.source) {
return Some(bytes);
}
}
None
}
fn load_face_bytes(source: &Source) -> Option<Vec<u8>> {
match source {
Source::File(path) => std::fs::read(path).ok(),
Source::Memory(data) => Some(data.clone()),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn load_font_for_family_sans_serif() {
if let Some(bytes) = load_font_for_family("sans-serif") {
assert!(bytes.len() > 100, "font data should be non-trivial in size");
let magic_ok = matches!(
bytes[..4],
[0x00, 0x01, 0x00, 0x00]
| [0x4F, 0x54, 0x54, 0x4F]
| [0x74, 0x72, 0x75, 0x65]
| [0x74, 0x74, 0x63, 0x66]
);
assert!(magic_ok, "font data must begin with valid font magic bytes");
}
}
#[test]
fn load_best_font_for_ascii_text() {
if let Some(bytes) = load_best_font_for_text("Hello World") {
assert!(bytes.len() > 100, "font data should be non-trivial in size");
}
}
#[test]
fn load_best_font_for_empty_text_returns_none() {
let result = load_best_font_for_text("");
assert!(result.is_none(), "empty text must return None");
}
#[test]
fn from_variants_accept_pre_built_db() {
let db = match build_system_db() {
Some(db) => db,
None => return, };
let _family = load_font_for_family_from(&db, "sans-serif");
let _text = load_best_font_for_text_from(&db, "abc");
}
#[test]
fn from_variant_empty_text_returns_none() {
let db = match build_system_db() {
Some(db) => db,
None => return,
};
assert!(load_best_font_for_text_from(&db, "").is_none());
}
}