use crate::compat::{String, Vec};
use crate::platform::types::SystemFont;
use std::process::Command;
pub(crate) fn system_fonts() -> Vec<SystemFont> {
let output =
match Command::new("fc-list").args(["--format", "%{family}\t%{style}\t%{file}\n"]).output()
{
Ok(output) if output.status.success() => output,
Ok(_) | Err(_) => return Vec::new(),
};
let text = String::from_utf8_lossy(&output.stdout);
let mut fonts: Vec<SystemFont> = Vec::new();
for line in text.lines() {
let mut fields = line.split('\t');
let families = fields.next().unwrap_or("").trim();
let style = fields.next().unwrap_or("").trim();
let file = fields.next().unwrap_or("").trim();
let family = families.split(',').next().unwrap_or("").trim();
if family.is_empty() {
continue;
}
if fonts.iter().any(|known| known.family.eq_ignore_ascii_case(family)) {
continue;
}
fonts.push(SystemFont {
family: family.to_string(),
style: style.to_string(),
source: (!file.is_empty()).then(|| std::path::PathBuf::from(file)),
});
}
fonts
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_enumeration_is_well_formed() {
for font in system_fonts() {
assert!(!font.family.is_empty());
if let Some(source) = font.source {
assert!(source.is_absolute(), "fc-list reports an absolute font path");
}
}
}
}