tinymist_world/font/
memory.rs1use std::sync::Arc;
5
6use rayon::iter::{IntoParallelIterator, ParallelIterator};
7use typst::foundations::Bytes;
8use typst::text::{FontBook, FontInfo};
9
10use crate::debug_loc::{DataSource, MemoryDataSource};
11use crate::font::{BufferFontLoader, FontResolverImpl, FontSlot};
12
13#[derive(Debug)]
15pub struct MemoryFontSearcher {
16 pub fonts: Vec<(FontInfo, FontSlot)>,
18}
19
20impl Default for MemoryFontSearcher {
21 fn default() -> Self {
22 Self::new()
23 }
24}
25
26impl MemoryFontSearcher {
27 pub fn new() -> Self {
29 Self { fonts: vec![] }
30 }
31
32 pub fn from_resolver(resolver: FontResolverImpl) -> Self {
34 let fonts = resolver
35 .slots
36 .into_iter()
37 .enumerate()
38 .map(|(idx, slot)| {
39 (
40 resolver
41 .book
42 .info(idx)
43 .expect("font should be in font book")
44 .clone(),
45 slot,
46 )
47 })
48 .collect();
49
50 Self { fonts }
51 }
52
53 pub fn add_memory_font(&mut self, data: Bytes) {
55 self.add_memory_fonts(rayon::iter::once(data));
56 }
57
58 pub fn add_memory_fonts(&mut self, data: impl IntoParallelIterator<Item = Bytes>) {
60 let source = DataSource::Memory(MemoryDataSource {
61 name: "<memory>".to_owned(),
62 });
63 self.extend_bytes(
64 data.into_par_iter()
65 .map(|data| (data, Some(source.clone()))),
66 );
67 }
68
69 pub fn extend(&mut self, items: impl IntoIterator<Item = (FontInfo, FontSlot)>) {
74 self.fonts.extend(items);
75 }
76
77 pub fn extend_bytes(
80 &mut self,
81 items: impl ParallelIterator<Item = (Bytes, Option<DataSource>)>,
82 ) {
83 let loaded = items.flat_map(|(data, desc)| {
84 let count = ttf_parser::fonts_in_collection(&data).unwrap_or(1);
85
86 let desc = desc.map(Arc::new);
87
88 (0..count)
89 .flat_map(|index| {
90 let info = FontInfo::new(&data, index)?;
91 let mut slot = FontSlot::new(BufferFontLoader {
92 buffer: Some(data.clone()),
93 index,
94 });
95 if let Some(desc) = desc.clone() {
96 slot = slot.with_describe_arc(desc);
97 }
98
99 Some((info, slot))
100 })
101 .collect::<Vec<_>>()
102 });
103
104 self.extend(loaded.collect::<Vec<_>>());
105 }
106
107 pub fn build(self) -> FontResolverImpl {
109 let slots = self.fonts.iter().map(|(_, slot)| slot.clone()).collect();
110 let book = FontBook::from_infos(self.fonts.into_iter().map(|(info, _)| info));
111 FontResolverImpl::new(Vec::new(), book, slots)
112 }
113}
114
115#[deprecated(note = "use [`MemoryFontSearcher`] instead")]
117pub type MemoryFontBuilder = MemoryFontSearcher;