1
use crate::binary::read::{ReadBinary, ReadCtxt};
2
use crate::error::ParseError;
3
use crate::woff2::{PackedU16, TableDirectoryEntry, Woff2Font};
4

            
5
#[derive(Clone, Eq, PartialEq, Debug)]
6
pub struct Directory {
7
    #[allow(unused)]
8
    version: u32,
9
    entries: Vec<FontEntry>,
10
}
11

            
12
#[derive(Clone, Eq, PartialEq, Debug)]
13
pub struct FontEntry {
14
    #[allow(unused)]
15
    flavor: u32,
16
    table_indices: Vec<u16>,
17
}
18

            
19
impl ReadBinary for FontEntry {
20
    type HostType<'a> = Self;
21

            
22
    fn read(ctxt: &mut ReadCtxt<'_>) -> Result<Self, ParseError> {
23
        let num_tables = ctxt.read::<PackedU16>()?;
24
        let flavor = ctxt.read_u32be()?;
25
        let table_indices = (0..num_tables)
26
            .map(|_| ctxt.read::<PackedU16>())
27
            .collect::<Result<Vec<_>, _>>()?;
28

            
29
        Ok(FontEntry {
30
            flavor,
31
            table_indices,
32
        })
33
    }
34
}
35

            
36
impl ReadBinary for Directory {
37
    type HostType<'a> = Self;
38

            
39
    fn read(ctxt: &mut ReadCtxt<'_>) -> Result<Self, ParseError> {
40
        let ttc_version = ctxt.read_u32be()?;
41
        let num_fonts = ctxt.read::<PackedU16>()?;
42
        let entries = (0..num_fonts)
43
            .map(|_| ctxt.read::<FontEntry>())
44
            .collect::<Result<Vec<_>, _>>()?;
45

            
46
        Ok(Directory {
47
            version: ttc_version,
48
            entries,
49
        })
50
    }
51
}
52

            
53
impl Directory {
54
    pub fn fonts(&self) -> impl Iterator<Item = &FontEntry> + '_ {
55
        self.entries.iter()
56
    }
57

            
58
    pub fn get(&self, index: usize) -> Option<&FontEntry> {
59
        self.entries.get(index)
60
    }
61
}
62

            
63
impl FontEntry {
64
    pub fn table_entries<'a>(
65
        &'a self,
66
        file: &'a Woff2Font<'_>,
67
    ) -> impl Iterator<Item = &'a TableDirectoryEntry> + 'a {
68
        self.table_indices
69
            .iter()
70
            .flat_map(move |&index| file.table_directory.get(usize::from(index)))
71
    }
72
}