use cosmic_text::fontdb::{Source, ID as FontId};
use cosmic_text::FontSystem;
use std::io::Error;
use std::mem;
use std::sync::Arc;
const FONT_DATA: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/font_data/font_data.bin"));
#[allow(clippy::needless_return)]
pub(super) fn load_embedded_font_data(system: &mut FontSystem) -> Result<Vec<FontId>, Error> {
#[cfg(not(feature = "compress_fonts"))]
{
return read_font_data(system, FONT_DATA);
}
#[cfg(feature = "compress_fonts")]
{
use std::io::prelude::*;
let mut decoder = {
let mut decoder = yazi::Decoder::boxed();
decoder.set_format(yazi::Format::Raw);
decoder
};
let mut decoded_data = Vec::new();
let mut stream = decoder.stream_into_vec(&mut decoded_data);
stream.write_all(FONT_DATA)?;
stream.finish().map_err(|_| {
Error::new(
std::io::ErrorKind::InvalidData,
"Failed to decode font data",
)
})?;
return read_font_data(system, &decoded_data);
}
}
fn read_font_data(system: &mut FontSystem, mut data: &[u8]) -> Result<Vec<FontId>, Error> {
let mut all_ids = vec![];
loop {
let font_len = if data.len() >= mem::size_of::<u64>() {
let (length, rest) = data.split_at(mem::size_of::<u64>());
data = rest;
u64::from_le_bytes(length.try_into().unwrap())
} else {
break;
};
let (font_data, rest) = data.split_at(font_len.try_into().unwrap());
data = rest;
let ids = system
.db_mut()
.load_font_source(Source::Binary(Arc::new(font_data.to_vec())));
assert!(!ids.is_empty());
for id in ids {
let font = system.db().face(id);
if let Some(font) = font {
for (_name, _) in &font.families {
#[cfg(feature = "tracing")]
tracing::debug!("Loaded default font: {}", _name);
}
}
all_ids.push(id);
}
}
set_default_fonts(system);
Ok(all_ids)
}
fn set_default_fonts(fs: &mut FontSystem) {
fs.db_mut().set_monospace_family("DejaVu Sans Mono");
fs.db_mut().set_sans_serif_family("DejaVu Sans");
fs.db_mut().set_serif_family("DejaVu Serif");
}