opentype/
font.rs

1use truetype::tables::offsets::Offsets;
2
3use crate::tape::Read;
4use crate::{Result, Table};
5
6/// A font.
7pub struct Font {
8    /// The offset table.
9    pub offsets: Offsets,
10}
11
12impl Font {
13    /// Read a file.
14    #[inline]
15    pub fn read<T>(tape: &mut T) -> Result<Self>
16    where
17        T: crate::tape::Read,
18    {
19        Read::take(tape)
20    }
21
22    /// Check if the table exists.
23    #[inline]
24    pub fn exists<T: Table>(&self) -> bool {
25        let tag = T::tag();
26        self.offsets.records.iter().any(|record| record.tag == tag)
27    }
28
29    /// Jump to the position of the table.
30    pub fn position<T, U>(&self, tape: &mut T) -> Result<Option<()>>
31    where
32        T: crate::tape::Read,
33        U: Table,
34    {
35        let tag = U::tag();
36        for record in &self.offsets.records {
37            if record.tag == tag {
38                #[cfg(not(feature = "ignore-invalid-checksums"))]
39                if record.checksum != record.checksum(tape)? {
40                    raise!("found a malformed font table with {:?}", record.tag);
41                }
42                Read::jump(tape, record.offset as u64)?;
43                return Ok(Some(()));
44            }
45        }
46        Ok(None)
47    }
48
49    /// Read a table.
50    #[inline]
51    pub fn take<T, U>(&self, tape: &mut T) -> Result<Option<U>>
52    where
53        T: crate::tape::Read,
54        U: Table + crate::value::Read,
55    {
56        self.position::<T, U>(tape)?
57            .map(|_| tape.take::<U>())
58            .transpose()
59    }
60
61    /// Read a table given a parameter.
62    pub fn take_given<'l, T, U>(&self, tape: &mut T, parameter: U::Parameter) -> Result<Option<U>>
63    where
64        T: crate::tape::Read,
65        U: Table + crate::walue::Read<'l>,
66    {
67        self.position::<T, U>(tape)?
68            .map(|_| tape.take_given::<U>(parameter))
69            .transpose()
70    }
71}
72
73impl crate::value::Read for Font {
74    #[inline]
75    fn read<T: crate::tape::Read>(tape: &mut T) -> Result<Self> {
76        Ok(Self {
77            offsets: tape.take()?,
78        })
79    }
80}