tinymist_world/font/
memory.rsuse std::sync::Arc;
use rayon::iter::ParallelIterator;
use typst::foundations::Bytes;
use typst::text::{FontBook, FontInfo};
use crate::debug_loc::{DataSource, MemoryDataSource};
use crate::font::{BufferFontLoader, FontResolverImpl, FontSlot};
#[derive(Debug)]
pub struct MemoryFontSearcher {
pub fonts: Vec<(FontInfo, FontSlot)>,
}
impl Default for MemoryFontSearcher {
fn default() -> Self {
Self::new()
}
}
impl MemoryFontSearcher {
pub fn new() -> Self {
Self { fonts: vec![] }
}
pub fn add_memory_font(&mut self, data: Bytes) {
self.add_memory_fonts(rayon::iter::once(data));
}
pub fn add_memory_fonts(&mut self, data: impl ParallelIterator<Item = Bytes>) {
let source = DataSource::Memory(MemoryDataSource {
name: "<memory>".to_owned(),
});
self.extend_bytes(data.map(|data| (data, Some(source.clone()))));
}
pub fn extend(&mut self, items: impl IntoIterator<Item = (FontInfo, FontSlot)>) {
self.fonts.extend(items);
}
pub fn extend_bytes(
&mut self,
items: impl ParallelIterator<Item = (Bytes, Option<DataSource>)>,
) {
let loaded = items.flat_map(|(data, desc)| {
let count = ttf_parser::fonts_in_collection(&data).unwrap_or(1);
let desc = desc.map(Arc::new);
(0..count)
.flat_map(|index| {
let info = FontInfo::new(&data, index)?;
let mut slot = FontSlot::new(BufferFontLoader {
buffer: Some(data.clone()),
index,
});
if let Some(desc) = desc.clone() {
slot = slot.with_describe_arc(desc);
}
Some((info, slot))
})
.collect::<Vec<_>>()
});
self.extend(loaded.collect::<Vec<_>>());
}
pub fn build(self) -> FontResolverImpl {
let slots = self.fonts.iter().map(|(_, slot)| slot.clone()).collect();
let book = FontBook::from_infos(self.fonts.into_iter().map(|(info, _)| info));
FontResolverImpl::new(Vec::new(), book, slots)
}
}
#[deprecated(note = "use [`MemoryFontSearcher`] instead")]
pub type MemoryFontBuilder = MemoryFontSearcher;