Coverage Report

Created: 2026-10-24 07:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/read-fonts-0.46.0/src/font_data.rs
Line
Count
Source
1
//! raw font bytes
2
3
#![deny(clippy::arithmetic_side_effects)]
4
use std::ops::{Range, RangeBounds};
5
6
use bytemuck::AnyBitPattern;
7
use types::{BigEndian, FixedSize, Scalar};
8
9
use crate::array::ComputedArray;
10
use crate::read::{ComputeSize, FontRead, FontReadAt, ReadArgs, ReadError};
11
12
/// A reference to raw binary font data.
13
///
14
/// This is a wrapper around a byte slice, that provides convenience methods
15
/// for parsing and validating that data.
16
#[derive(Debug, Default, Clone, Copy)]
17
pub struct FontData<'a> {
18
    bytes: &'a [u8],
19
}
20
21
/// A cursor for validating bytes during parsing.
22
///
23
/// This type improves the ergonomics of validation blah blah
24
///
25
/// # Note
26
///
27
/// call `finish` when you're done to ensure you're in bounds
28
#[derive(Debug, Default, Clone, Copy)]
29
pub struct Cursor<'a> {
30
    pos: usize,
31
    data: FontData<'a>,
32
}
33
34
// we reuse a single buffer for all tables, but it gets padded with a u16
35
// to accurately represent format-1 tables
36
const ARR_LEN: usize = FontData::NULL_POOL_SIZE + u16::RAW_BYTE_LEN;
37
38
/// This is [0, 1] ('1' in u16be) followed by NULL_POOL_SIZE zeros.
39
///
40
/// - this same array is reused both for format-1 tables (which need a leading 1)
41
///   as well as all other tables, which don't.
42
static EMPTY_TABLE_BYTES: [u8; ARR_LEN] = {
43
    let mut arr = [0u8; ARR_LEN];
44
    arr[1] = 1;
45
    arr
46
};
47
48
impl FontData<'static> {
49
    // https://github.com/harfbuzz/harfbuzz/blob/aba63bb5/src/hb-null.hh#L40
50
    /// The number of bytes required to represent the largest table we have.
51
    ///
52
    /// This is checked by an assert at compile time, and can be increased as needed.
53
    const NULL_POOL_SIZE: usize = 262;
54
55
    // this is only used in const eval contexts, which are not visible to the
56
    // dead_code lint https://github.com/rust-lang/rust/issues/101532
57
    #[allow(dead_code)]
58
    /// Return `true` if our default data can represent a table `n_bytes` long
59
0
    pub(crate) const fn default_data_long_enough(n_bytes: usize) -> bool {
60
0
        n_bytes <= Self::NULL_POOL_SIZE
61
0
    }
62
63
    /// Return all zeroes suitable for the default impl of a table.
64
0
    pub(crate) fn default_table_data() -> Self {
65
0
        FontData::new(&EMPTY_TABLE_BYTES[2..])
66
0
    }
67
68
    /// Return a [0x0, 0x01] byte pair (u16be) and then all zeros, to represent
69
    /// the default impl of a format 1 table with u16 format.
70
0
    pub(crate) fn default_format_1_u16_table_data() -> Self {
71
0
        FontData::new(&EMPTY_TABLE_BYTES)
72
0
    }
73
74
    /// Return a single 0x01 and then all zeros, to represent the default impl
75
    /// of a format 1 table with u8 format.
76
0
    pub(crate) fn default_format_1_u8_table_data() -> Self {
77
0
        FontData::new(&EMPTY_TABLE_BYTES[1..])
78
0
    }
79
}
80
81
impl<'a> FontData<'a> {
82
    /// Empty data, useful for some tests and examples
83
    pub const EMPTY: FontData<'static> = FontData { bytes: &[] };
84
85
    /// Create a new `FontData` with these bytes.
86
    ///
87
    /// You generally don't need to do this? It is handled for you when loading
88
    /// data from disk, but may be useful in tests.
89
174M
    pub const fn new(bytes: &'a [u8]) -> Self {
90
174M
        FontData { bytes }
91
174M
    }
92
93
    /// The length of the data, in bytes
94
88.8M
    pub fn len(&self) -> usize {
95
88.8M
        self.bytes.len()
96
88.8M
    }
97
98
    /// `true` if the data has a length of zero bytes.
99
66.6k
    pub fn is_empty(&self) -> bool {
100
66.6k
        self.bytes.is_empty()
101
66.6k
    }
102
103
    /// Returns self[pos..]
104
221M
    pub fn split_off(&self, pos: usize) -> Option<FontData<'a>> {
105
221M
        self.bytes.get(pos..).map(|bytes| FontData { bytes })
106
221M
    }
107
108
    /// returns self[..pos], and updates self to = self[pos..];
109
16.7k
    pub fn take_up_to(&mut self, pos: usize) -> Option<FontData<'a>> {
110
16.7k
        if pos > self.len() {
111
798
            return None;
112
15.9k
        }
113
15.9k
        let (head, tail) = self.bytes.split_at(pos);
114
15.9k
        self.bytes = tail;
115
15.9k
        Some(FontData { bytes: head })
116
16.7k
    }
117
118
133k
    pub fn slice(&self, range: impl RangeBounds<usize>) -> Option<FontData<'a>> {
119
133k
        let bounds = (range.start_bound().cloned(), range.end_bound().cloned());
120
133k
        self.bytes.get(bounds).map(|bytes| FontData { bytes })
<read_fonts::font_data::FontData>::slice::<core::ops::range::Range<usize>>::{closure#0}
Line
Count
Source
120
43.2k
        self.bytes.get(bounds).map(|bytes| FontData { bytes })
<read_fonts::font_data::FontData>::slice::<core::ops::range::RangeTo<usize>>::{closure#0}
Line
Count
Source
120
25.7k
        self.bytes.get(bounds).map(|bytes| FontData { bytes })
<read_fonts::font_data::FontData>::slice::<core::ops::range::RangeFrom<usize>>::{closure#0}
Line
Count
Source
120
13.7k
        self.bytes.get(bounds).map(|bytes| FontData { bytes })
121
133k
    }
<read_fonts::font_data::FontData>::slice::<core::ops::range::Range<usize>>
Line
Count
Source
118
44.9k
    pub fn slice(&self, range: impl RangeBounds<usize>) -> Option<FontData<'a>> {
119
44.9k
        let bounds = (range.start_bound().cloned(), range.end_bound().cloned());
120
44.9k
        self.bytes.get(bounds).map(|bytes| FontData { bytes })
121
44.9k
    }
<read_fonts::font_data::FontData>::slice::<core::ops::range::RangeTo<usize>>
Line
Count
Source
118
33.2k
    pub fn slice(&self, range: impl RangeBounds<usize>) -> Option<FontData<'a>> {
119
33.2k
        let bounds = (range.start_bound().cloned(), range.end_bound().cloned());
120
33.2k
        self.bytes.get(bounds).map(|bytes| FontData { bytes })
121
33.2k
    }
<read_fonts::font_data::FontData>::slice::<core::ops::range::RangeFrom<usize>>
Line
Count
Source
118
55.6k
    pub fn slice(&self, range: impl RangeBounds<usize>) -> Option<FontData<'a>> {
119
55.6k
        let bounds = (range.start_bound().cloned(), range.end_bound().cloned());
120
55.6k
        self.bytes.get(bounds).map(|bytes| FontData { bytes })
121
55.6k
    }
122
123
    /// Read a scalar at the provided location in the data.
124
272M
    pub fn read_at<T: Scalar>(&self, offset: usize) -> Result<T, ReadError> {
125
272M
        let end = offset
126
272M
            .checked_add(T::RAW_BYTE_LEN)
127
272M
            .ok_or(ReadError::OutOfBounds)?;
128
272M
        self.bytes
129
272M
            .get(offset..end)
130
272M
            .and_then(T::read)
131
272M
            .ok_or(ReadError::OutOfBounds)
132
272M
    }
<read_fonts::font_data::FontData>::read_at::<font_types::offset::Nullable<font_types::offset::Offset16>>
Line
Count
Source
124
161
    pub fn read_at<T: Scalar>(&self, offset: usize) -> Result<T, ReadError> {
125
161
        let end = offset
126
161
            .checked_add(T::RAW_BYTE_LEN)
127
161
            .ok_or(ReadError::OutOfBounds)?;
128
161
        self.bytes
129
161
            .get(offset..end)
130
161
            .and_then(T::read)
131
161
            .ok_or(ReadError::OutOfBounds)
132
161
    }
<read_fonts::font_data::FontData>::read_at::<font_types::offset::Nullable<font_types::offset::Offset32>>
Line
Count
Source
124
4.82k
    pub fn read_at<T: Scalar>(&self, offset: usize) -> Result<T, ReadError> {
125
4.82k
        let end = offset
126
4.82k
            .checked_add(T::RAW_BYTE_LEN)
127
4.82k
            .ok_or(ReadError::OutOfBounds)?;
128
4.82k
        self.bytes
129
4.82k
            .get(offset..end)
130
4.82k
            .and_then(T::read)
131
4.82k
            .ok_or(ReadError::OutOfBounds)
132
4.82k
    }
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_at::<font_types::tag::Tag>
<read_fonts::font_data::FontData>::read_at::<font_types::fixed::F2Dot14>
Line
Count
Source
124
289
    pub fn read_at<T: Scalar>(&self, offset: usize) -> Result<T, ReadError> {
125
289
        let end = offset
126
289
            .checked_add(T::RAW_BYTE_LEN)
127
289
            .ok_or(ReadError::OutOfBounds)?;
128
289
        self.bytes
129
289
            .get(offset..end)
130
289
            .and_then(T::read)
131
289
            .ok_or(ReadError::OutOfBounds)
132
289
    }
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_at::<font_types::fixed::F4Dot12>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_at::<font_types::fixed::F6Dot10>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_at::<font_types::fword::FWord>
<read_fonts::font_data::FontData>::read_at::<font_types::offset::Offset32>
Line
Count
Source
124
6.20k
    pub fn read_at<T: Scalar>(&self, offset: usize) -> Result<T, ReadError> {
125
6.20k
        let end = offset
126
6.20k
            .checked_add(T::RAW_BYTE_LEN)
127
6.20k
            .ok_or(ReadError::OutOfBounds)?;
128
6.20k
        self.bytes
129
6.20k
            .get(offset..end)
130
6.20k
            .and_then(T::read)
131
6.20k
            .ok_or(ReadError::OutOfBounds)
132
6.20k
    }
<read_fonts::font_data::FontData>::read_at::<font_types::uint24::Uint24>
Line
Count
Source
124
58.7k
    pub fn read_at<T: Scalar>(&self, offset: usize) -> Result<T, ReadError> {
125
58.7k
        let end = offset
126
58.7k
            .checked_add(T::RAW_BYTE_LEN)
127
58.7k
            .ok_or(ReadError::OutOfBounds)?;
128
58.7k
        self.bytes
129
58.7k
            .get(offset..end)
130
58.7k
            .and_then(T::read)
131
58.7k
            .ok_or(ReadError::OutOfBounds)
132
58.7k
    }
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_at::<font_types::name_id::NameId>
<read_fonts::font_data::FontData>::read_at::<font_types::glyph_id::GlyphId16>
Line
Count
Source
124
30.2k
    pub fn read_at<T: Scalar>(&self, offset: usize) -> Result<T, ReadError> {
125
30.2k
        let end = offset
126
30.2k
            .checked_add(T::RAW_BYTE_LEN)
127
30.2k
            .ok_or(ReadError::OutOfBounds)?;
128
30.2k
        self.bytes
129
30.2k
            .get(offset..end)
130
30.2k
            .and_then(T::read)
131
30.2k
            .ok_or(ReadError::OutOfBounds)
132
30.2k
    }
<read_fonts::font_data::FontData>::read_at::<read_fonts::tables::os2::SelectionFlags>
Line
Count
Source
124
945
    pub fn read_at<T: Scalar>(&self, offset: usize) -> Result<T, ReadError> {
125
945
        let end = offset
126
945
            .checked_add(T::RAW_BYTE_LEN)
127
945
            .ok_or(ReadError::OutOfBounds)?;
128
945
        self.bytes
129
945
            .get(offset..end)
130
945
            .and_then(T::read)
131
945
            .ok_or(ReadError::OutOfBounds)
132
945
    }
<read_fonts::font_data::FontData>::read_at::<read_fonts::tables::glyf::SimpleGlyphFlags>
Line
Count
Source
124
2.60k
    pub fn read_at<T: Scalar>(&self, offset: usize) -> Result<T, ReadError> {
125
2.60k
        let end = offset
126
2.60k
            .checked_add(T::RAW_BYTE_LEN)
127
2.60k
            .ok_or(ReadError::OutOfBounds)?;
128
2.60k
        self.bytes
129
2.60k
            .get(offset..end)
130
2.60k
            .and_then(T::read)
131
2.60k
            .ok_or(ReadError::OutOfBounds)
132
2.60k
    }
<read_fonts::font_data::FontData>::read_at::<read_fonts::tables::glyf::CompositeGlyphFlags>
Line
Count
Source
124
90.3k
    pub fn read_at<T: Scalar>(&self, offset: usize) -> Result<T, ReadError> {
125
90.3k
        let end = offset
126
90.3k
            .checked_add(T::RAW_BYTE_LEN)
127
90.3k
            .ok_or(ReadError::OutOfBounds)?;
128
90.3k
        self.bytes
129
90.3k
            .get(offset..end)
130
90.3k
            .and_then(T::read)
131
90.3k
            .ok_or(ReadError::OutOfBounds)
132
90.3k
    }
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_at::<read_fonts::tables::layout::DeltaFormat>
<read_fonts::font_data::FontData>::read_at::<i8>
Line
Count
Source
124
7.88k
    pub fn read_at<T: Scalar>(&self, offset: usize) -> Result<T, ReadError> {
125
7.88k
        let end = offset
126
7.88k
            .checked_add(T::RAW_BYTE_LEN)
127
7.88k
            .ok_or(ReadError::OutOfBounds)?;
128
7.88k
        self.bytes
129
7.88k
            .get(offset..end)
130
7.88k
            .and_then(T::read)
131
7.88k
            .ok_or(ReadError::OutOfBounds)
132
7.88k
    }
<read_fonts::font_data::FontData>::read_at::<u8>
Line
Count
Source
124
2.76M
    pub fn read_at<T: Scalar>(&self, offset: usize) -> Result<T, ReadError> {
125
2.76M
        let end = offset
126
2.76M
            .checked_add(T::RAW_BYTE_LEN)
127
2.76M
            .ok_or(ReadError::OutOfBounds)?;
128
2.76M
        self.bytes
129
2.76M
            .get(offset..end)
130
2.76M
            .and_then(T::read)
131
2.76M
            .ok_or(ReadError::OutOfBounds)
132
2.76M
    }
<read_fonts::font_data::FontData>::read_at::<i32>
Line
Count
Source
124
47.6k
    pub fn read_at<T: Scalar>(&self, offset: usize) -> Result<T, ReadError> {
125
47.6k
        let end = offset
126
47.6k
            .checked_add(T::RAW_BYTE_LEN)
127
47.6k
            .ok_or(ReadError::OutOfBounds)?;
128
47.6k
        self.bytes
129
47.6k
            .get(offset..end)
130
47.6k
            .and_then(T::read)
131
47.6k
            .ok_or(ReadError::OutOfBounds)
132
47.6k
    }
<read_fonts::font_data::FontData>::read_at::<u32>
Line
Count
Source
124
220k
    pub fn read_at<T: Scalar>(&self, offset: usize) -> Result<T, ReadError> {
125
220k
        let end = offset
126
220k
            .checked_add(T::RAW_BYTE_LEN)
127
220k
            .ok_or(ReadError::OutOfBounds)?;
128
220k
        self.bytes
129
220k
            .get(offset..end)
130
220k
            .and_then(T::read)
131
220k
            .ok_or(ReadError::OutOfBounds)
132
220k
    }
<read_fonts::font_data::FontData>::read_at::<i16>
Line
Count
Source
124
2.01M
    pub fn read_at<T: Scalar>(&self, offset: usize) -> Result<T, ReadError> {
125
2.01M
        let end = offset
126
2.01M
            .checked_add(T::RAW_BYTE_LEN)
127
2.01M
            .ok_or(ReadError::OutOfBounds)?;
128
2.01M
        self.bytes
129
2.01M
            .get(offset..end)
130
2.01M
            .and_then(T::read)
131
2.01M
            .ok_or(ReadError::OutOfBounds)
132
2.01M
    }
<read_fonts::font_data::FontData>::read_at::<u16>
Line
Count
Source
124
267M
    pub fn read_at<T: Scalar>(&self, offset: usize) -> Result<T, ReadError> {
125
267M
        let end = offset
126
267M
            .checked_add(T::RAW_BYTE_LEN)
127
267M
            .ok_or(ReadError::OutOfBounds)?;
128
267M
        self.bytes
129
267M
            .get(offset..end)
130
267M
            .and_then(T::read)
131
267M
            .ok_or(ReadError::OutOfBounds)
132
267M
    }
133
134
    /// Read a big-endian value at the provided location in the data.
135
0
    pub fn read_be_at<T: Scalar>(&self, offset: usize) -> Result<BigEndian<T>, ReadError> {
136
0
        let end = offset
137
0
            .checked_add(T::RAW_BYTE_LEN)
138
0
            .ok_or(ReadError::OutOfBounds)?;
139
0
        self.bytes
140
0
            .get(offset..end)
141
0
            .and_then(BigEndian::from_slice)
142
0
            .ok_or(ReadError::OutOfBounds)
143
0
    }
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_be_at::<font_types::glyph_id::GlyphId16>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_be_at::<font_types::glyph_id::GlyphId24>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_be_at::<u16>
144
145
0
    pub fn read_with_args<T>(&self, range: Range<usize>, args: T::Args) -> Result<T, ReadError>
146
0
    where
147
0
        T: FontRead<'a>,
148
    {
149
0
        self.slice(range)
150
0
            .ok_or(ReadError::OutOfBounds)
151
0
            .and_then(|data| T::read_with_args(data, args))
152
0
    }
153
154
369k
    fn check_in_bounds(&self, offset: usize) -> Result<(), ReadError> {
155
369k
        self.bytes
156
369k
            .get(..offset)
157
369k
            .ok_or(ReadError::OutOfBounds)
158
369k
            .map(|_| ())
159
369k
    }
160
161
    /// Interpret the bytes at the provided offset as a reference to `T`.
162
    ///
163
    /// Returns an error if the slice `offset..` is shorter than `T::RAW_BYTE_LEN`.
164
    ///
165
    /// This is a wrapper around [`read_ref_unchecked`][], which panics if
166
    /// the type does not uphold the required invariants.
167
    ///
168
    /// # Panics
169
    ///
170
    /// This function will panic if `T` is zero-sized, has an alignment
171
    /// other than one, or has any internal padding.
172
    ///
173
    /// [`read_ref_unchecked`]: [Self::read_ref_unchecked]
174
76.9M
    pub fn read_ref_at<T: AnyBitPattern + FixedSize>(
175
76.9M
        &self,
176
76.9M
        offset: usize,
177
76.9M
    ) -> Result<&'a T, ReadError> {
178
76.9M
        let end = offset
179
76.9M
            .checked_add(T::RAW_BYTE_LEN)
180
76.9M
            .ok_or(ReadError::OutOfBounds)?;
181
76.9M
        self.bytes
182
76.9M
            .get(offset..end)
183
76.9M
            .ok_or(ReadError::OutOfBounds)
184
76.9M
            .map(bytemuck::from_bytes)
185
76.9M
    }
<read_fonts::font_data::FontData>::read_ref_at::<font_types::raw::BigEndian<u16>>
Line
Count
Source
174
34.7M
    pub fn read_ref_at<T: AnyBitPattern + FixedSize>(
175
34.7M
        &self,
176
34.7M
        offset: usize,
177
34.7M
    ) -> Result<&'a T, ReadError> {
178
34.7M
        let end = offset
179
34.7M
            .checked_add(T::RAW_BYTE_LEN)
180
34.7M
            .ok_or(ReadError::OutOfBounds)?;
181
34.7M
        self.bytes
182
34.7M
            .get(offset..end)
183
34.7M
            .ok_or(ReadError::OutOfBounds)
184
34.7M
            .map(bytemuck::from_bytes)
185
34.7M
    }
<read_fonts::font_data::FontData>::read_ref_at::<read_fonts::tables::aat::NoPayload>
Line
Count
Source
174
22.6M
    pub fn read_ref_at<T: AnyBitPattern + FixedSize>(
175
22.6M
        &self,
176
22.6M
        offset: usize,
177
22.6M
    ) -> Result<&'a T, ReadError> {
178
22.6M
        let end = offset
179
22.6M
            .checked_add(T::RAW_BYTE_LEN)
180
22.6M
            .ok_or(ReadError::OutOfBounds)?;
181
22.6M
        self.bytes
182
22.6M
            .get(offset..end)
183
22.6M
            .ok_or(ReadError::OutOfBounds)
184
22.6M
            .map(bytemuck::from_bytes)
185
22.6M
    }
<read_fonts::font_data::FontData>::read_ref_at::<read_fonts::tables::mort::InsertionEntryData>
Line
Count
Source
174
2.00M
    pub fn read_ref_at<T: AnyBitPattern + FixedSize>(
175
2.00M
        &self,
176
2.00M
        offset: usize,
177
2.00M
    ) -> Result<&'a T, ReadError> {
178
2.00M
        let end = offset
179
2.00M
            .checked_add(T::RAW_BYTE_LEN)
180
2.00M
            .ok_or(ReadError::OutOfBounds)?;
181
2.00M
        self.bytes
182
2.00M
            .get(offset..end)
183
2.00M
            .ok_or(ReadError::OutOfBounds)
184
2.00M
            .map(bytemuck::from_bytes)
185
2.00M
    }
<read_fonts::font_data::FontData>::read_ref_at::<read_fonts::tables::mort::ContextualEntryData>
Line
Count
Source
174
944k
    pub fn read_ref_at<T: AnyBitPattern + FixedSize>(
175
944k
        &self,
176
944k
        offset: usize,
177
944k
    ) -> Result<&'a T, ReadError> {
178
944k
        let end = offset
179
944k
            .checked_add(T::RAW_BYTE_LEN)
180
944k
            .ok_or(ReadError::OutOfBounds)?;
181
944k
        self.bytes
182
944k
            .get(offset..end)
183
944k
            .ok_or(ReadError::OutOfBounds)
184
944k
            .map(bytemuck::from_bytes)
185
944k
    }
<read_fonts::font_data::FontData>::read_ref_at::<read_fonts::tables::morx::InsertionEntryData>
Line
Count
Source
174
4.19M
    pub fn read_ref_at<T: AnyBitPattern + FixedSize>(
175
4.19M
        &self,
176
4.19M
        offset: usize,
177
4.19M
    ) -> Result<&'a T, ReadError> {
178
4.19M
        let end = offset
179
4.19M
            .checked_add(T::RAW_BYTE_LEN)
180
4.19M
            .ok_or(ReadError::OutOfBounds)?;
181
4.19M
        self.bytes
182
4.19M
            .get(offset..end)
183
4.19M
            .ok_or(ReadError::OutOfBounds)
184
4.19M
            .map(bytemuck::from_bytes)
185
4.19M
    }
<read_fonts::font_data::FontData>::read_ref_at::<read_fonts::tables::morx::ContextualEntryData>
Line
Count
Source
174
12.4M
    pub fn read_ref_at<T: AnyBitPattern + FixedSize>(
175
12.4M
        &self,
176
12.4M
        offset: usize,
177
12.4M
    ) -> Result<&'a T, ReadError> {
178
12.4M
        let end = offset
179
12.4M
            .checked_add(T::RAW_BYTE_LEN)
180
12.4M
            .ok_or(ReadError::OutOfBounds)?;
181
12.4M
        self.bytes
182
12.4M
            .get(offset..end)
183
12.4M
            .ok_or(ReadError::OutOfBounds)
184
12.4M
            .map(bytemuck::from_bytes)
185
12.4M
    }
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_ref_at::<_>
186
187
    /// Interpret the bytes at the provided offset as a slice of `T`.
188
    ///
189
    /// Returns an error if `range` is out of bounds for the underlying data,
190
    /// or if the length of the range is not a multiple of `T::RAW_BYTE_LEN`.
191
    ///
192
    /// This is a wrapper around [`read_array_unchecked`][], which panics if
193
    /// the type does not uphold the required invariants.
194
    ///
195
    /// # Panics
196
    ///
197
    /// This function will panic if `T` is zero-sized, has an alignment
198
    /// other than one, or has any internal padding.
199
    ///
200
    /// [`read_array_unchecked`]: [Self::read_array_unchecked]
201
49.4M
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
49.4M
        &self,
203
49.4M
        range: Range<usize>,
204
49.4M
    ) -> Result<&'a [T], ReadError> {
205
49.4M
        let bytes = self
206
49.4M
            .bytes
207
49.4M
            .get(range.clone())
208
49.4M
            .ok_or(ReadError::OutOfBounds)?;
209
45.8M
        if bytes
210
45.8M
            .len()
211
45.8M
            .checked_rem(std::mem::size_of::<T>())
212
45.8M
            .unwrap_or(1) // definitely != 0
213
45.8M
            != 0
214
        {
215
4
            return Err(ReadError::InvalidArrayLen);
216
45.8M
        };
217
45.8M
        Ok(bytemuck::cast_slice(bytes))
218
49.4M
    }
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<font_types::raw::BigEndian<font_types::offset::Nullable<font_types::offset::Offset16>>>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<font_types::raw::BigEndian<font_types::offset::Nullable<font_types::offset::Offset24>>>
<read_fonts::font_data::FontData>::read_array::<font_types::raw::BigEndian<font_types::offset::Nullable<font_types::offset::Offset32>>>
Line
Count
Source
201
1.15k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
1.15k
        &self,
203
1.15k
        range: Range<usize>,
204
1.15k
    ) -> Result<&'a [T], ReadError> {
205
1.15k
        let bytes = self
206
1.15k
            .bytes
207
1.15k
            .get(range.clone())
208
1.15k
            .ok_or(ReadError::OutOfBounds)?;
209
492
        if bytes
210
492
            .len()
211
492
            .checked_rem(std::mem::size_of::<T>())
212
492
            .unwrap_or(1) // definitely != 0
213
492
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
492
        };
217
492
        Ok(bytemuck::cast_slice(bytes))
218
1.15k
    }
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<font_types::raw::BigEndian<font_types::tag::Tag>>
<read_fonts::font_data::FontData>::read_array::<font_types::raw::BigEndian<font_types::fixed::Fixed>>
Line
Count
Source
201
42
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
42
        &self,
203
42
        range: Range<usize>,
204
42
    ) -> Result<&'a [T], ReadError> {
205
42
        let bytes = self
206
42
            .bytes
207
42
            .get(range.clone())
208
42
            .ok_or(ReadError::OutOfBounds)?;
209
40
        if bytes
210
40
            .len()
211
40
            .checked_rem(std::mem::size_of::<T>())
212
40
            .unwrap_or(1) // definitely != 0
213
40
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
40
        };
217
40
        Ok(bytemuck::cast_slice(bytes))
218
42
    }
<read_fonts::font_data::FontData>::read_array::<font_types::raw::BigEndian<font_types::fixed::F2Dot14>>
Line
Count
Source
201
25.6k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
25.6k
        &self,
203
25.6k
        range: Range<usize>,
204
25.6k
    ) -> Result<&'a [T], ReadError> {
205
25.6k
        let bytes = self
206
25.6k
            .bytes
207
25.6k
            .get(range.clone())
208
25.6k
            .ok_or(ReadError::OutOfBounds)?;
209
25.6k
        if bytes
210
25.6k
            .len()
211
25.6k
            .checked_rem(std::mem::size_of::<T>())
212
25.6k
            .unwrap_or(1) // definitely != 0
213
25.6k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
25.6k
        };
217
25.6k
        Ok(bytemuck::cast_slice(bytes))
218
25.6k
    }
<read_fonts::font_data::FontData>::read_array::<font_types::raw::BigEndian<font_types::offset::Offset16>>
Line
Count
Source
201
359k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
359k
        &self,
203
359k
        range: Range<usize>,
204
359k
    ) -> Result<&'a [T], ReadError> {
205
359k
        let bytes = self
206
359k
            .bytes
207
359k
            .get(range.clone())
208
359k
            .ok_or(ReadError::OutOfBounds)?;
209
319k
        if bytes
210
319k
            .len()
211
319k
            .checked_rem(std::mem::size_of::<T>())
212
319k
            .unwrap_or(1) // definitely != 0
213
319k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
319k
        };
217
319k
        Ok(bytemuck::cast_slice(bytes))
218
359k
    }
<read_fonts::font_data::FontData>::read_array::<font_types::raw::BigEndian<font_types::offset::Offset24>>
Line
Count
Source
201
6.41k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
6.41k
        &self,
203
6.41k
        range: Range<usize>,
204
6.41k
    ) -> Result<&'a [T], ReadError> {
205
6.41k
        let bytes = self
206
6.41k
            .bytes
207
6.41k
            .get(range.clone())
208
6.41k
            .ok_or(ReadError::OutOfBounds)?;
209
4.36k
        if bytes
210
4.36k
            .len()
211
4.36k
            .checked_rem(std::mem::size_of::<T>())
212
4.36k
            .unwrap_or(1) // definitely != 0
213
4.36k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
4.36k
        };
217
4.36k
        Ok(bytemuck::cast_slice(bytes))
218
6.41k
    }
<read_fonts::font_data::FontData>::read_array::<font_types::raw::BigEndian<font_types::offset::Offset32>>
Line
Count
Source
201
33.3k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
33.3k
        &self,
203
33.3k
        range: Range<usize>,
204
33.3k
    ) -> Result<&'a [T], ReadError> {
205
33.3k
        let bytes = self
206
33.3k
            .bytes
207
33.3k
            .get(range.clone())
208
33.3k
            .ok_or(ReadError::OutOfBounds)?;
209
33.1k
        if bytes
210
33.1k
            .len()
211
33.1k
            .checked_rem(std::mem::size_of::<T>())
212
33.1k
            .unwrap_or(1) // definitely != 0
213
33.1k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
33.1k
        };
217
33.1k
        Ok(bytemuck::cast_slice(bytes))
218
33.3k
    }
<read_fonts::font_data::FontData>::read_array::<font_types::raw::BigEndian<font_types::uint24::Uint24>>
Line
Count
Source
201
6.34k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
6.34k
        &self,
203
6.34k
        range: Range<usize>,
204
6.34k
    ) -> Result<&'a [T], ReadError> {
205
6.34k
        let bytes = self
206
6.34k
            .bytes
207
6.34k
            .get(range.clone())
208
6.34k
            .ok_or(ReadError::OutOfBounds)?;
209
2.88k
        if bytes
210
2.88k
            .len()
211
2.88k
            .checked_rem(std::mem::size_of::<T>())
212
2.88k
            .unwrap_or(1) // definitely != 0
213
2.88k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
2.88k
        };
217
2.88k
        Ok(bytemuck::cast_slice(bytes))
218
6.34k
    }
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<font_types::raw::BigEndian<font_types::name_id::NameId>>
<read_fonts::font_data::FontData>::read_array::<font_types::raw::BigEndian<font_types::glyph_id::GlyphId16>>
Line
Count
Source
201
66.0k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
66.0k
        &self,
203
66.0k
        range: Range<usize>,
204
66.0k
    ) -> Result<&'a [T], ReadError> {
205
66.0k
        let bytes = self
206
66.0k
            .bytes
207
66.0k
            .get(range.clone())
208
66.0k
            .ok_or(ReadError::OutOfBounds)?;
209
60.8k
        if bytes
210
60.8k
            .len()
211
60.8k
            .checked_rem(std::mem::size_of::<T>())
212
60.8k
            .unwrap_or(1) // definitely != 0
213
60.8k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
60.8k
        };
217
60.8k
        Ok(bytemuck::cast_slice(bytes))
218
66.0k
    }
<read_fonts::font_data::FontData>::read_array::<font_types::raw::BigEndian<font_types::glyph_id::GlyphId24>>
Line
Count
Source
201
8.25k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
8.25k
        &self,
203
8.25k
        range: Range<usize>,
204
8.25k
    ) -> Result<&'a [T], ReadError> {
205
8.25k
        let bytes = self
206
8.25k
            .bytes
207
8.25k
            .get(range.clone())
208
8.25k
            .ok_or(ReadError::OutOfBounds)?;
209
3.32k
        if bytes
210
3.32k
            .len()
211
3.32k
            .checked_rem(std::mem::size_of::<T>())
212
3.32k
            .unwrap_or(1) // definitely != 0
213
3.32k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
3.32k
        };
217
3.32k
        Ok(bytemuck::cast_slice(bytes))
218
8.25k
    }
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<font_types::raw::BigEndian<read_fonts::tables::cpal::PaletteType>>
<read_fonts::font_data::FontData>::read_array::<font_types::raw::BigEndian<i32>>
Line
Count
Source
201
499
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
499
        &self,
203
499
        range: Range<usize>,
204
499
    ) -> Result<&'a [T], ReadError> {
205
499
        let bytes = self
206
499
            .bytes
207
499
            .get(range.clone())
208
499
            .ok_or(ReadError::OutOfBounds)?;
209
387
        if bytes
210
387
            .len()
211
387
            .checked_rem(std::mem::size_of::<T>())
212
387
            .unwrap_or(1) // definitely != 0
213
387
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
387
        };
217
387
        Ok(bytemuck::cast_slice(bytes))
218
499
    }
<read_fonts::font_data::FontData>::read_array::<font_types::raw::BigEndian<u32>>
Line
Count
Source
201
6.71k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
6.71k
        &self,
203
6.71k
        range: Range<usize>,
204
6.71k
    ) -> Result<&'a [T], ReadError> {
205
6.71k
        let bytes = self
206
6.71k
            .bytes
207
6.71k
            .get(range.clone())
208
6.71k
            .ok_or(ReadError::OutOfBounds)?;
209
6.17k
        if bytes
210
6.17k
            .len()
211
6.17k
            .checked_rem(std::mem::size_of::<T>())
212
6.17k
            .unwrap_or(1) // definitely != 0
213
6.17k
            != 0
214
        {
215
2
            return Err(ReadError::InvalidArrayLen);
216
6.16k
        };
217
6.16k
        Ok(bytemuck::cast_slice(bytes))
218
6.71k
    }
<read_fonts::font_data::FontData>::read_array::<font_types::raw::BigEndian<i16>>
Line
Count
Source
201
53.0k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
53.0k
        &self,
203
53.0k
        range: Range<usize>,
204
53.0k
    ) -> Result<&'a [T], ReadError> {
205
53.0k
        let bytes = self
206
53.0k
            .bytes
207
53.0k
            .get(range.clone())
208
53.0k
            .ok_or(ReadError::OutOfBounds)?;
209
50.2k
        if bytes
210
50.2k
            .len()
211
50.2k
            .checked_rem(std::mem::size_of::<T>())
212
50.2k
            .unwrap_or(1) // definitely != 0
213
50.2k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
50.2k
        };
217
50.2k
        Ok(bytemuck::cast_slice(bytes))
218
53.0k
    }
<read_fonts::font_data::FontData>::read_array::<font_types::raw::BigEndian<u16>>
Line
Count
Source
201
3.12M
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
3.12M
        &self,
203
3.12M
        range: Range<usize>,
204
3.12M
    ) -> Result<&'a [T], ReadError> {
205
3.12M
        let bytes = self
206
3.12M
            .bytes
207
3.12M
            .get(range.clone())
208
3.12M
            .ok_or(ReadError::OutOfBounds)?;
209
2.82M
        if bytes
210
2.82M
            .len()
211
2.82M
            .checked_rem(std::mem::size_of::<T>())
212
2.82M
            .unwrap_or(1) // definitely != 0
213
2.82M
            != 0
214
        {
215
2
            return Err(ReadError::InvalidArrayLen);
216
2.82M
        };
217
2.82M
        Ok(bytemuck::cast_slice(bytes))
218
3.12M
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::aat::LookupSingle<u32>>
Line
Count
Source
201
336
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
336
        &self,
203
336
        range: Range<usize>,
204
336
    ) -> Result<&'a [T], ReadError> {
205
336
        let bytes = self
206
336
            .bytes
207
336
            .get(range.clone())
208
336
            .ok_or(ReadError::OutOfBounds)?;
209
326
        if bytes
210
326
            .len()
211
326
            .checked_rem(std::mem::size_of::<T>())
212
326
            .unwrap_or(1) // definitely != 0
213
326
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
326
        };
217
326
        Ok(bytemuck::cast_slice(bytes))
218
336
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::aat::LookupSingle<u16>>
Line
Count
Source
201
1.14M
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
1.14M
        &self,
203
1.14M
        range: Range<usize>,
204
1.14M
    ) -> Result<&'a [T], ReadError> {
205
1.14M
        let bytes = self
206
1.14M
            .bytes
207
1.14M
            .get(range.clone())
208
1.14M
            .ok_or(ReadError::OutOfBounds)?;
209
718k
        if bytes
210
718k
            .len()
211
718k
            .checked_rem(std::mem::size_of::<T>())
212
718k
            .unwrap_or(1) // definitely != 0
213
718k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
718k
        };
217
718k
        Ok(bytemuck::cast_slice(bytes))
218
1.14M
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::aat::LookupSegment2<u32>>
Line
Count
Source
201
403
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
403
        &self,
203
403
        range: Range<usize>,
204
403
    ) -> Result<&'a [T], ReadError> {
205
403
        let bytes = self
206
403
            .bytes
207
403
            .get(range.clone())
208
403
            .ok_or(ReadError::OutOfBounds)?;
209
398
        if bytes
210
398
            .len()
211
398
            .checked_rem(std::mem::size_of::<T>())
212
398
            .unwrap_or(1) // definitely != 0
213
398
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
398
        };
217
398
        Ok(bytemuck::cast_slice(bytes))
218
403
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::aat::LookupSegment2<u16>>
Line
Count
Source
201
1.57M
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
1.57M
        &self,
203
1.57M
        range: Range<usize>,
204
1.57M
    ) -> Result<&'a [T], ReadError> {
205
1.57M
        let bytes = self
206
1.57M
            .bytes
207
1.57M
            .get(range.clone())
208
1.57M
            .ok_or(ReadError::OutOfBounds)?;
209
1.14M
        if bytes
210
1.14M
            .len()
211
1.14M
            .checked_rem(std::mem::size_of::<T>())
212
1.14M
            .unwrap_or(1) // definitely != 0
213
1.14M
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
1.14M
        };
217
1.14M
        Ok(bytemuck::cast_slice(bytes))
218
1.57M
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::TableRecord>
Line
Count
Source
201
164k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
164k
        &self,
203
164k
        range: Range<usize>,
204
164k
    ) -> Result<&'a [T], ReadError> {
205
164k
        let bytes = self
206
164k
            .bytes
207
164k
            .get(range.clone())
208
164k
            .ok_or(ReadError::OutOfBounds)?;
209
138k
        if bytes
210
138k
            .len()
211
138k
            .checked_rem(std::mem::size_of::<T>())
212
138k
            .unwrap_or(1) // definitely != 0
213
138k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
138k
        };
217
138k
        Ok(bytemuck::cast_slice(bytes))
218
164k
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::variations::RegionAxisCoordinates>
Line
Count
Source
201
12
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
12
        &self,
203
12
        range: Range<usize>,
204
12
    ) -> Result<&'a [T], ReadError> {
205
12
        let bytes = self
206
12
            .bytes
207
12
            .get(range.clone())
208
12
            .ok_or(ReadError::OutOfBounds)?;
209
12
        if bytes
210
12
            .len()
211
12
            .checked_rem(std::mem::size_of::<T>())
212
12
            .unwrap_or(1) // definitely != 0
213
12
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
12
        };
217
12
        Ok(bytemuck::cast_slice(bytes))
218
12
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::aat::LookupSegment4>
Line
Count
Source
201
729k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
729k
        &self,
203
729k
        range: Range<usize>,
204
729k
    ) -> Result<&'a [T], ReadError> {
205
729k
        let bytes = self
206
729k
            .bytes
207
729k
            .get(range.clone())
208
729k
            .ok_or(ReadError::OutOfBounds)?;
209
156k
        if bytes
210
156k
            .len()
211
156k
            .checked_rem(std::mem::size_of::<T>())
212
156k
            .unwrap_or(1) // definitely != 0
213
156k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
156k
        };
217
156k
        Ok(bytemuck::cast_slice(bytes))
218
729k
    }
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::svg::SVGDocumentRecord>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::ankr::AnchorPoint>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::avar::AxisValueMap>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::base::BaseScriptRecord>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::base::FeatMinMaxRecord>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::base::BaseLangSysRecord>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::cmap::UvsMapping>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::cmap::UnicodeRange>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::cmap::UvsMapping24>
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::cmap::EncodingRecord>
Line
Count
Source
201
4.33k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
4.33k
        &self,
203
4.33k
        range: Range<usize>,
204
4.33k
    ) -> Result<&'a [T], ReadError> {
205
4.33k
        let bytes = self
206
4.33k
            .bytes
207
4.33k
            .get(range.clone())
208
4.33k
            .ok_or(ReadError::OutOfBounds)?;
209
3.21k
        if bytes
210
3.21k
            .len()
211
3.21k
            .checked_rem(std::mem::size_of::<T>())
212
3.21k
            .unwrap_or(1) // definitely != 0
213
3.21k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
3.21k
        };
217
3.21k
        Ok(bytemuck::cast_slice(bytes))
218
4.33k
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::cmap::ConstantMapGroup>
Line
Count
Source
201
82.7k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
82.7k
        &self,
203
82.7k
        range: Range<usize>,
204
82.7k
    ) -> Result<&'a [T], ReadError> {
205
82.7k
        let bytes = self
206
82.7k
            .bytes
207
82.7k
            .get(range.clone())
208
82.7k
            .ok_or(ReadError::OutOfBounds)?;
209
81.0k
        if bytes
210
81.0k
            .len()
211
81.0k
            .checked_rem(std::mem::size_of::<T>())
212
81.0k
            .unwrap_or(1) // definitely != 0
213
81.0k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
81.0k
        };
217
81.0k
        Ok(bytemuck::cast_slice(bytes))
218
82.7k
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::cmap::VariationSelector>
Line
Count
Source
201
1
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
1
        &self,
203
1
        range: Range<usize>,
204
1
    ) -> Result<&'a [T], ReadError> {
205
1
        let bytes = self
206
1
            .bytes
207
1
            .get(range.clone())
208
1
            .ok_or(ReadError::OutOfBounds)?;
209
0
        if bytes
210
0
            .len()
211
0
            .checked_rem(std::mem::size_of::<T>())
212
0
            .unwrap_or(1) // definitely != 0
213
0
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
0
        };
217
0
        Ok(bytemuck::cast_slice(bytes))
218
1
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::cmap::SequentialMapGroup>
Line
Count
Source
201
38.8k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
38.8k
        &self,
203
38.8k
        range: Range<usize>,
204
38.8k
    ) -> Result<&'a [T], ReadError> {
205
38.8k
        let bytes = self
206
38.8k
            .bytes
207
38.8k
            .get(range.clone())
208
38.8k
            .ok_or(ReadError::OutOfBounds)?;
209
37.7k
        if bytes
210
37.7k
            .len()
211
37.7k
            .checked_rem(std::mem::size_of::<T>())
212
37.7k
            .unwrap_or(1) // definitely != 0
213
37.7k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
37.7k
        };
217
37.7k
        Ok(bytemuck::cast_slice(bytes))
218
38.8k
    }
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::cmap::VariationSelector15>
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::colr::VarColorStop>
Line
Count
Source
201
7
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
7
        &self,
203
7
        range: Range<usize>,
204
7
    ) -> Result<&'a [T], ReadError> {
205
7
        let bytes = self
206
7
            .bytes
207
7
            .get(range.clone())
208
7
            .ok_or(ReadError::OutOfBounds)?;
209
5
        if bytes
210
5
            .len()
211
5
            .checked_rem(std::mem::size_of::<T>())
212
5
            .unwrap_or(1) // definitely != 0
213
5
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
5
        };
217
5
        Ok(bytemuck::cast_slice(bytes))
218
7
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::colr::BaseGlyphPaint>
Line
Count
Source
201
536
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
536
        &self,
203
536
        range: Range<usize>,
204
536
    ) -> Result<&'a [T], ReadError> {
205
536
        let bytes = self
206
536
            .bytes
207
536
            .get(range.clone())
208
536
            .ok_or(ReadError::OutOfBounds)?;
209
435
        if bytes
210
435
            .len()
211
435
            .checked_rem(std::mem::size_of::<T>())
212
435
            .unwrap_or(1) // definitely != 0
213
435
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
435
        };
217
435
        Ok(bytemuck::cast_slice(bytes))
218
536
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::colr::Clip>
Line
Count
Source
201
174
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
174
        &self,
203
174
        range: Range<usize>,
204
174
    ) -> Result<&'a [T], ReadError> {
205
174
        let bytes = self
206
174
            .bytes
207
174
            .get(range.clone())
208
174
            .ok_or(ReadError::OutOfBounds)?;
209
137
        if bytes
210
137
            .len()
211
137
            .checked_rem(std::mem::size_of::<T>())
212
137
            .unwrap_or(1) // definitely != 0
213
137
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
137
        };
217
137
        Ok(bytemuck::cast_slice(bytes))
218
174
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::colr::Layer>
Line
Count
Source
201
463
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
463
        &self,
203
463
        range: Range<usize>,
204
463
    ) -> Result<&'a [T], ReadError> {
205
463
        let bytes = self
206
463
            .bytes
207
463
            .get(range.clone())
208
463
            .ok_or(ReadError::OutOfBounds)?;
209
458
        if bytes
210
458
            .len()
211
458
            .checked_rem(std::mem::size_of::<T>())
212
458
            .unwrap_or(1) // definitely != 0
213
458
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
458
        };
217
458
        Ok(bytemuck::cast_slice(bytes))
218
463
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::colr::BaseGlyph>
Line
Count
Source
201
563
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
563
        &self,
203
563
        range: Range<usize>,
204
563
    ) -> Result<&'a [T], ReadError> {
205
563
        let bytes = self
206
563
            .bytes
207
563
            .get(range.clone())
208
563
            .ok_or(ReadError::OutOfBounds)?;
209
525
        if bytes
210
525
            .len()
211
525
            .checked_rem(std::mem::size_of::<T>())
212
525
            .unwrap_or(1) // definitely != 0
213
525
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
525
        };
217
525
        Ok(bytemuck::cast_slice(bytes))
218
563
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::colr::ColorStop>
Line
Count
Source
201
8
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
8
        &self,
203
8
        range: Range<usize>,
204
8
    ) -> Result<&'a [T], ReadError> {
205
8
        let bytes = self
206
8
            .bytes
207
8
            .get(range.clone())
208
8
            .ok_or(ReadError::OutOfBounds)?;
209
0
        if bytes
210
0
            .len()
211
0
            .checked_rem(std::mem::size_of::<T>())
212
0
            .unwrap_or(1) // definitely != 0
213
0
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
0
        };
217
0
        Ok(bytemuck::cast_slice(bytes))
218
8
    }
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::cpal::ColorRecord>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::dsig::SignatureRecord>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::feat::FeatureName>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::feat::SettingName>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::fvar::VariationAxisRecord>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::gasp::GaspRange>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::gpos::MarkRecord>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::gpos::MarkRecord2>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::gpos::EntryExitRecord>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::gpos::EntryExitRecord2>
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::hmtx::LongMetric>
Line
Count
Source
201
549
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
549
        &self,
203
549
        range: Range<usize>,
204
549
    ) -> Result<&'a [T], ReadError> {
205
549
        let bytes = self
206
549
            .bytes
207
549
            .get(range.clone())
208
549
            .ok_or(ReadError::OutOfBounds)?;
209
391
        if bytes
210
391
            .len()
211
391
            .checked_rem(std::mem::size_of::<T>())
212
391
            .unwrap_or(1) // definitely != 0
213
391
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
391
        };
217
391
        Ok(bytemuck::cast_slice(bytes))
218
549
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::kerx::Subtable0Pair>
Line
Count
Source
201
4.36k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
4.36k
        &self,
203
4.36k
        range: Range<usize>,
204
4.36k
    ) -> Result<&'a [T], ReadError> {
205
4.36k
        let bytes = self
206
4.36k
            .bytes
207
4.36k
            .get(range.clone())
208
4.36k
            .ok_or(ReadError::OutOfBounds)?;
209
4.23k
        if bytes
210
4.23k
            .len()
211
4.23k
            .checked_rem(std::mem::size_of::<T>())
212
4.23k
            .unwrap_or(1) // definitely != 0
213
4.23k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
4.23k
        };
217
4.23k
        Ok(bytemuck::cast_slice(bytes))
218
4.36k
    }
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::ltag::FTStringRange>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::math::GlyphPartRecord>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::math::MathValueRecord>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::math::MathKernInfoRecord>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::math::MathGlyphVariantRecord>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::meta::DataMapRecord>
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::mort::Feature>
Line
Count
Source
201
2.60k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
2.60k
        &self,
203
2.60k
        range: Range<usize>,
204
2.60k
    ) -> Result<&'a [T], ReadError> {
205
2.60k
        let bytes = self
206
2.60k
            .bytes
207
2.60k
            .get(range.clone())
208
2.60k
            .ok_or(ReadError::OutOfBounds)?;
209
2.49k
        if bytes
210
2.49k
            .len()
211
2.49k
            .checked_rem(std::mem::size_of::<T>())
212
2.49k
            .unwrap_or(1) // definitely != 0
213
2.49k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
2.49k
        };
217
2.49k
        Ok(bytemuck::cast_slice(bytes))
218
2.60k
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::morx::Feature>
Line
Count
Source
201
4.62k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
4.62k
        &self,
203
4.62k
        range: Range<usize>,
204
4.62k
    ) -> Result<&'a [T], ReadError> {
205
4.62k
        let bytes = self
206
4.62k
            .bytes
207
4.62k
            .get(range.clone())
208
4.62k
            .ok_or(ReadError::OutOfBounds)?;
209
4.45k
        if bytes
210
4.45k
            .len()
211
4.45k
            .checked_rem(std::mem::size_of::<T>())
212
4.45k
            .unwrap_or(1) // definitely != 0
213
4.45k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
4.45k
        };
217
4.45k
        Ok(bytemuck::cast_slice(bytes))
218
4.62k
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::mvar::ValueRecord>
Line
Count
Source
201
1.40k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
1.40k
        &self,
203
1.40k
        range: Range<usize>,
204
1.40k
    ) -> Result<&'a [T], ReadError> {
205
1.40k
        let bytes = self
206
1.40k
            .bytes
207
1.40k
            .get(range.clone())
208
1.40k
            .ok_or(ReadError::OutOfBounds)?;
209
239
        if bytes
210
239
            .len()
211
239
            .checked_rem(std::mem::size_of::<T>())
212
239
            .unwrap_or(1) // definitely != 0
213
239
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
239
        };
217
239
        Ok(bytemuck::cast_slice(bytes))
218
1.40k
    }
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::name::NameRecord>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::name::LangTagRecord>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::stat::AxisRecord>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::stat::AxisValueRecord>
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::trak::TrackTableEntry>
Line
Count
Source
201
37
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
37
        &self,
203
37
        range: Range<usize>,
204
37
    ) -> Result<&'a [T], ReadError> {
205
37
        let bytes = self
206
37
            .bytes
207
37
            .get(range.clone())
208
37
            .ok_or(ReadError::OutOfBounds)?;
209
36
        if bytes
210
36
            .len()
211
36
            .checked_rem(std::mem::size_of::<T>())
212
36
            .unwrap_or(1) // definitely != 0
213
36
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
36
        };
217
36
        Ok(bytemuck::cast_slice(bytes))
218
37
    }
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::vorg::VertOriginYMetrics>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::bitmap::BitmapSize>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::bitmap::BdtComponent>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::bitmap::BigGlyphMetrics>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::bitmap::GlyphIdOffsetPair>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::bitmap::SmallGlyphMetrics>
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::bitmap::IndexSubtableRecord>
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::layout::RangeRecord>
Line
Count
Source
201
328k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
328k
        &self,
203
328k
        range: Range<usize>,
204
328k
    ) -> Result<&'a [T], ReadError> {
205
328k
        let bytes = self
206
328k
            .bytes
207
328k
            .get(range.clone())
208
328k
            .ok_or(ReadError::OutOfBounds)?;
209
312k
        if bytes
210
312k
            .len()
211
312k
            .checked_rem(std::mem::size_of::<T>())
212
312k
            .unwrap_or(1) // definitely != 0
213
312k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
312k
        };
217
312k
        Ok(bytemuck::cast_slice(bytes))
218
328k
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::layout::RangeRecord2>
Line
Count
Source
201
11.4k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
11.4k
        &self,
203
11.4k
        range: Range<usize>,
204
11.4k
    ) -> Result<&'a [T], ReadError> {
205
11.4k
        let bytes = self
206
11.4k
            .bytes
207
11.4k
            .get(range.clone())
208
11.4k
            .ok_or(ReadError::OutOfBounds)?;
209
5.74k
        if bytes
210
5.74k
            .len()
211
5.74k
            .checked_rem(std::mem::size_of::<T>())
212
5.74k
            .unwrap_or(1) // definitely != 0
213
5.74k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
5.74k
        };
217
5.74k
        Ok(bytemuck::cast_slice(bytes))
218
11.4k
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::layout::ScriptRecord>
Line
Count
Source
201
727k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
727k
        &self,
203
727k
        range: Range<usize>,
204
727k
    ) -> Result<&'a [T], ReadError> {
205
727k
        let bytes = self
206
727k
            .bytes
207
727k
            .get(range.clone())
208
727k
            .ok_or(ReadError::OutOfBounds)?;
209
726k
        if bytes
210
726k
            .len()
211
726k
            .checked_rem(std::mem::size_of::<T>())
212
726k
            .unwrap_or(1) // definitely != 0
213
726k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
726k
        };
217
726k
        Ok(bytemuck::cast_slice(bytes))
218
727k
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::layout::FeatureRecord>
Line
Count
Source
201
664k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
664k
        &self,
203
664k
        range: Range<usize>,
204
664k
    ) -> Result<&'a [T], ReadError> {
205
664k
        let bytes = self
206
664k
            .bytes
207
664k
            .get(range.clone())
208
664k
            .ok_or(ReadError::OutOfBounds)?;
209
661k
        if bytes
210
661k
            .len()
211
661k
            .checked_rem(std::mem::size_of::<T>())
212
661k
            .unwrap_or(1) // definitely != 0
213
661k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
661k
        };
217
661k
        Ok(bytemuck::cast_slice(bytes))
218
664k
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::layout::LangSysRecord>
Line
Count
Source
201
22.6k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
22.6k
        &self,
203
22.6k
        range: Range<usize>,
204
22.6k
    ) -> Result<&'a [T], ReadError> {
205
22.6k
        let bytes = self
206
22.6k
            .bytes
207
22.6k
            .get(range.clone())
208
22.6k
            .ok_or(ReadError::OutOfBounds)?;
209
2.17k
        if bytes
210
2.17k
            .len()
211
2.17k
            .checked_rem(std::mem::size_of::<T>())
212
2.17k
            .unwrap_or(1) // definitely != 0
213
2.17k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
2.17k
        };
217
2.17k
        Ok(bytemuck::cast_slice(bytes))
218
22.6k
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::layout::ClassRangeRecord>
Line
Count
Source
201
24.0k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
24.0k
        &self,
203
24.0k
        range: Range<usize>,
204
24.0k
    ) -> Result<&'a [T], ReadError> {
205
24.0k
        let bytes = self
206
24.0k
            .bytes
207
24.0k
            .get(range.clone())
208
24.0k
            .ok_or(ReadError::OutOfBounds)?;
209
18.8k
        if bytes
210
18.8k
            .len()
211
18.8k
            .checked_rem(std::mem::size_of::<T>())
212
18.8k
            .unwrap_or(1) // definitely != 0
213
18.8k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
18.8k
        };
217
18.8k
        Ok(bytemuck::cast_slice(bytes))
218
24.0k
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::layout::ClassRangeRecord2>
Line
Count
Source
201
6.44k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
6.44k
        &self,
203
6.44k
        range: Range<usize>,
204
6.44k
    ) -> Result<&'a [T], ReadError> {
205
6.44k
        let bytes = self
206
6.44k
            .bytes
207
6.44k
            .get(range.clone())
208
6.44k
            .ok_or(ReadError::OutOfBounds)?;
209
1.85k
        if bytes
210
1.85k
            .len()
211
1.85k
            .checked_rem(std::mem::size_of::<T>())
212
1.85k
            .unwrap_or(1) // definitely != 0
213
1.85k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
1.85k
        };
217
1.85k
        Ok(bytemuck::cast_slice(bytes))
218
6.44k
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::layout::SequenceLookupRecord>
Line
Count
Source
201
6.73M
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
6.73M
        &self,
203
6.73M
        range: Range<usize>,
204
6.73M
    ) -> Result<&'a [T], ReadError> {
205
6.73M
        let bytes = self
206
6.73M
            .bytes
207
6.73M
            .get(range.clone())
208
6.73M
            .ok_or(ReadError::OutOfBounds)?;
209
6.25M
        if bytes
210
6.25M
            .len()
211
6.25M
            .checked_rem(std::mem::size_of::<T>())
212
6.25M
            .unwrap_or(1) // definitely != 0
213
6.25M
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
6.25M
        };
217
6.25M
        Ok(bytemuck::cast_slice(bytes))
218
6.73M
    }
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::layout::LookupConditionRecord>
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::layout::LookupVariationRecord>
Line
Count
Source
201
9
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
9
        &self,
203
9
        range: Range<usize>,
204
9
    ) -> Result<&'a [T], ReadError> {
205
9
        let bytes = self
206
9
            .bytes
207
9
            .get(range.clone())
208
9
            .ok_or(ReadError::OutOfBounds)?;
209
7
        if bytes
210
7
            .len()
211
7
            .checked_rem(std::mem::size_of::<T>())
212
7
            .unwrap_or(1) // definitely != 0
213
7
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
7
        };
217
7
        Ok(bytemuck::cast_slice(bytes))
218
9
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::tables::layout::FeatureVariationRecord>
Line
Count
Source
201
15
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
15
        &self,
203
15
        range: Range<usize>,
204
15
    ) -> Result<&'a [T], ReadError> {
205
15
        let bytes = self
206
15
            .bytes
207
15
            .get(range.clone())
208
15
            .ok_or(ReadError::OutOfBounds)?;
209
6
        if bytes
210
6
            .len()
211
6
            .checked_rem(std::mem::size_of::<T>())
212
6
            .unwrap_or(1) // definitely != 0
213
6
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
6
        };
217
6
        Ok(bytemuck::cast_slice(bytes))
218
15
    }
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::tables::layout::FeatureTableSubstitutionRecord>
<read_fonts::font_data::FontData>::read_array::<read_fonts::ps::cff::v1::CharsetRange1>
Line
Count
Source
201
136
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
136
        &self,
203
136
        range: Range<usize>,
204
136
    ) -> Result<&'a [T], ReadError> {
205
136
        let bytes = self
206
136
            .bytes
207
136
            .get(range.clone())
208
136
            .ok_or(ReadError::OutOfBounds)?;
209
136
        if bytes
210
136
            .len()
211
136
            .checked_rem(std::mem::size_of::<T>())
212
136
            .unwrap_or(1) // definitely != 0
213
136
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
136
        };
217
136
        Ok(bytemuck::cast_slice(bytes))
218
136
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::ps::cff::v1::CharsetRange2>
Line
Count
Source
201
93
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
93
        &self,
203
93
        range: Range<usize>,
204
93
    ) -> Result<&'a [T], ReadError> {
205
93
        let bytes = self
206
93
            .bytes
207
93
            .get(range.clone())
208
93
            .ok_or(ReadError::OutOfBounds)?;
209
93
        if bytes
210
93
            .len()
211
93
            .checked_rem(std::mem::size_of::<T>())
212
93
            .unwrap_or(1) // definitely != 0
213
93
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
93
        };
217
93
        Ok(bytemuck::cast_slice(bytes))
218
93
    }
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::ps::cff::v1::EncodingRange1>
<read_fonts::font_data::FontData>::read_array::<read_fonts::ps::cff::v1::FdSelectRange3>
Line
Count
Source
201
45
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
45
        &self,
203
45
        range: Range<usize>,
204
45
    ) -> Result<&'a [T], ReadError> {
205
45
        let bytes = self
206
45
            .bytes
207
45
            .get(range.clone())
208
45
            .ok_or(ReadError::OutOfBounds)?;
209
34
        if bytes
210
34
            .len()
211
34
            .checked_rem(std::mem::size_of::<T>())
212
34
            .unwrap_or(1) // definitely != 0
213
34
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
34
        };
217
34
        Ok(bytemuck::cast_slice(bytes))
218
45
    }
<read_fonts::font_data::FontData>::read_array::<read_fonts::ps::cff::v1::FdSelectRange4>
Line
Count
Source
201
89
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
89
        &self,
203
89
        range: Range<usize>,
204
89
    ) -> Result<&'a [T], ReadError> {
205
89
        let bytes = self
206
89
            .bytes
207
89
            .get(range.clone())
208
89
            .ok_or(ReadError::OutOfBounds)?;
209
68
        if bytes
210
68
            .len()
211
68
            .checked_rem(std::mem::size_of::<T>())
212
68
            .unwrap_or(1) // definitely != 0
213
68
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
68
        };
217
68
        Ok(bytemuck::cast_slice(bytes))
218
89
    }
Unexecuted instantiation: <read_fonts::font_data::FontData>::read_array::<read_fonts::ps::cff::v1::EncodingSupplement>
<read_fonts::font_data::FontData>::read_array::<i8>
Line
Count
Source
201
4.35k
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
4.35k
        &self,
203
4.35k
        range: Range<usize>,
204
4.35k
    ) -> Result<&'a [T], ReadError> {
205
4.35k
        let bytes = self
206
4.35k
            .bytes
207
4.35k
            .get(range.clone())
208
4.35k
            .ok_or(ReadError::OutOfBounds)?;
209
4.19k
        if bytes
210
4.19k
            .len()
211
4.19k
            .checked_rem(std::mem::size_of::<T>())
212
4.19k
            .unwrap_or(1) // definitely != 0
213
4.19k
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
4.19k
        };
217
4.19k
        Ok(bytemuck::cast_slice(bytes))
218
4.35k
    }
<read_fonts::font_data::FontData>::read_array::<u8>
Line
Count
Source
201
33.4M
    pub fn read_array<T: AnyBitPattern + FixedSize>(
202
33.4M
        &self,
203
33.4M
        range: Range<usize>,
204
33.4M
    ) -> Result<&'a [T], ReadError> {
205
33.4M
        let bytes = self
206
33.4M
            .bytes
207
33.4M
            .get(range.clone())
208
33.4M
            .ok_or(ReadError::OutOfBounds)?;
209
32.2M
        if bytes
210
32.2M
            .len()
211
32.2M
            .checked_rem(std::mem::size_of::<T>())
212
32.2M
            .unwrap_or(1) // definitely != 0
213
32.2M
            != 0
214
        {
215
0
            return Err(ReadError::InvalidArrayLen);
216
32.2M
        };
217
32.2M
        Ok(bytemuck::cast_slice(bytes))
218
33.4M
    }
219
220
84.1M
    pub(crate) fn cursor(&self) -> Cursor<'a> {
221
84.1M
        Cursor {
222
84.1M
            pos: 0,
223
84.1M
            data: *self,
224
84.1M
        }
225
84.1M
    }
226
227
    /// Return the data as a byte slice
228
109M
    pub fn as_bytes(&self) -> &'a [u8] {
229
109M
        self.bytes
230
109M
    }
231
}
232
233
impl<'a> Cursor<'a> {
234
158M
    pub(crate) fn advance<T: Scalar>(&mut self) {
235
158M
        self.pos = self.pos.saturating_add(T::RAW_BYTE_LEN);
236
158M
    }
<read_fonts::font_data::Cursor>::advance::<font_types::fixed::F2Dot14>
Line
Count
Source
234
289
    pub(crate) fn advance<T: Scalar>(&mut self) {
235
289
        self.pos = self.pos.saturating_add(T::RAW_BYTE_LEN);
236
289
    }
Unexecuted instantiation: <read_fonts::font_data::Cursor>::advance::<font_types::fixed::F4Dot12>
Unexecuted instantiation: <read_fonts::font_data::Cursor>::advance::<font_types::fixed::F6Dot10>
Unexecuted instantiation: <read_fonts::font_data::Cursor>::advance::<font_types::fword::FWord>
<read_fonts::font_data::Cursor>::advance::<font_types::uint24::Uint24>
Line
Count
Source
234
54.6k
    pub(crate) fn advance<T: Scalar>(&mut self) {
235
54.6k
        self.pos = self.pos.saturating_add(T::RAW_BYTE_LEN);
236
54.6k
    }
Unexecuted instantiation: <read_fonts::font_data::Cursor>::advance::<font_types::name_id::NameId>
<read_fonts::font_data::Cursor>::advance::<font_types::glyph_id::GlyphId16>
Line
Count
Source
234
30.2k
    pub(crate) fn advance<T: Scalar>(&mut self) {
235
30.2k
        self.pos = self.pos.saturating_add(T::RAW_BYTE_LEN);
236
30.2k
    }
Unexecuted instantiation: <read_fonts::font_data::Cursor>::advance::<font_types::glyph_id::GlyphId24>
Unexecuted instantiation: <read_fonts::font_data::Cursor>::advance::<read_fonts::tables::glyf::SimpleGlyphFlags>
<read_fonts::font_data::Cursor>::advance::<read_fonts::tables::glyf::CompositeGlyphFlags>
Line
Count
Source
234
90.3k
    pub(crate) fn advance<T: Scalar>(&mut self) {
235
90.3k
        self.pos = self.pos.saturating_add(T::RAW_BYTE_LEN);
236
90.3k
    }
<read_fonts::font_data::Cursor>::advance::<i8>
Line
Count
Source
234
7.88k
    pub(crate) fn advance<T: Scalar>(&mut self) {
235
7.88k
        self.pos = self.pos.saturating_add(T::RAW_BYTE_LEN);
236
7.88k
    }
<read_fonts::font_data::Cursor>::advance::<u8>
Line
Count
Source
234
2.67M
    pub(crate) fn advance<T: Scalar>(&mut self) {
235
2.67M
        self.pos = self.pos.saturating_add(T::RAW_BYTE_LEN);
236
2.67M
    }
<read_fonts::font_data::Cursor>::advance::<i32>
Line
Count
Source
234
47.6k
    pub(crate) fn advance<T: Scalar>(&mut self) {
235
47.6k
        self.pos = self.pos.saturating_add(T::RAW_BYTE_LEN);
236
47.6k
    }
<read_fonts::font_data::Cursor>::advance::<u32>
Line
Count
Source
234
139k
    pub(crate) fn advance<T: Scalar>(&mut self) {
235
139k
        self.pos = self.pos.saturating_add(T::RAW_BYTE_LEN);
236
139k
    }
<read_fonts::font_data::Cursor>::advance::<i16>
Line
Count
Source
234
10.7k
    pub(crate) fn advance<T: Scalar>(&mut self) {
235
10.7k
        self.pos = self.pos.saturating_add(T::RAW_BYTE_LEN);
236
10.7k
    }
<read_fonts::font_data::Cursor>::advance::<u16>
Line
Count
Source
234
155M
    pub(crate) fn advance<T: Scalar>(&mut self) {
235
155M
        self.pos = self.pos.saturating_add(T::RAW_BYTE_LEN);
236
155M
    }
237
238
6.06M
    pub(crate) fn advance_by(&mut self, n_bytes: usize) {
239
6.06M
        self.pos = self.pos.saturating_add(n_bytes);
240
6.06M
    }
241
242
    /// Read a variable length u32 and advance the cursor
243
0
    pub(crate) fn read_u32_var(&mut self) -> Result<u32, ReadError> {
244
0
        let mut next = || self.read::<u8>().map(|v| v as u32);
245
0
        let b0 = next()?;
246
        // TODO this feels possible to simplify, e.g. compute length, loop taking one and shifting and or'ing
247
        #[allow(clippy::arithmetic_side_effects)] // these are all checked
248
0
        let result = match b0 {
249
0
            _ if b0 < 0x80 => b0,
250
0
            _ if b0 < 0xC0 => ((b0 - 0x80) << 8) | next()?,
251
0
            _ if b0 < 0xE0 => ((b0 - 0xC0) << 16) | (next()? << 8) | next()?,
252
0
            _ if b0 < 0xF0 => ((b0 - 0xE0) << 24) | (next()? << 16) | (next()? << 8) | next()?,
253
            _ => {
254
                // 0xF0 is a dedicated 5-byte prefix; high bits are carried entirely
255
                // by the following 4 bytes.
256
0
                (next()? << 24) | (next()? << 16) | (next()? << 8) | next()?
257
            }
258
        };
259
260
0
        Ok(result)
261
0
    }
262
263
    /// Read a scalar and advance the cursor.
264
158M
    pub(crate) fn read<T: Scalar>(&mut self) -> Result<T, ReadError> {
265
158M
        let temp = self.data.read_at(self.pos);
266
158M
        self.advance::<T>();
267
158M
        temp
268
158M
    }
<read_fonts::font_data::Cursor>::read::<font_types::fixed::F2Dot14>
Line
Count
Source
264
289
    pub(crate) fn read<T: Scalar>(&mut self) -> Result<T, ReadError> {
265
289
        let temp = self.data.read_at(self.pos);
266
289
        self.advance::<T>();
267
289
        temp
268
289
    }
Unexecuted instantiation: <read_fonts::font_data::Cursor>::read::<font_types::fixed::F4Dot12>
Unexecuted instantiation: <read_fonts::font_data::Cursor>::read::<font_types::fixed::F6Dot10>
Unexecuted instantiation: <read_fonts::font_data::Cursor>::read::<font_types::fword::FWord>
<read_fonts::font_data::Cursor>::read::<font_types::uint24::Uint24>
Line
Count
Source
264
54.6k
    pub(crate) fn read<T: Scalar>(&mut self) -> Result<T, ReadError> {
265
54.6k
        let temp = self.data.read_at(self.pos);
266
54.6k
        self.advance::<T>();
267
54.6k
        temp
268
54.6k
    }
Unexecuted instantiation: <read_fonts::font_data::Cursor>::read::<font_types::name_id::NameId>
<read_fonts::font_data::Cursor>::read::<font_types::glyph_id::GlyphId16>
Line
Count
Source
264
30.2k
    pub(crate) fn read<T: Scalar>(&mut self) -> Result<T, ReadError> {
265
30.2k
        let temp = self.data.read_at(self.pos);
266
30.2k
        self.advance::<T>();
267
30.2k
        temp
268
30.2k
    }
Unexecuted instantiation: <read_fonts::font_data::Cursor>::read::<read_fonts::tables::glyf::SimpleGlyphFlags>
<read_fonts::font_data::Cursor>::read::<read_fonts::tables::glyf::CompositeGlyphFlags>
Line
Count
Source
264
90.3k
    pub(crate) fn read<T: Scalar>(&mut self) -> Result<T, ReadError> {
265
90.3k
        let temp = self.data.read_at(self.pos);
266
90.3k
        self.advance::<T>();
267
90.3k
        temp
268
90.3k
    }
<read_fonts::font_data::Cursor>::read::<i8>
Line
Count
Source
264
7.88k
    pub(crate) fn read<T: Scalar>(&mut self) -> Result<T, ReadError> {
265
7.88k
        let temp = self.data.read_at(self.pos);
266
7.88k
        self.advance::<T>();
267
7.88k
        temp
268
7.88k
    }
<read_fonts::font_data::Cursor>::read::<u8>
Line
Count
Source
264
2.67M
    pub(crate) fn read<T: Scalar>(&mut self) -> Result<T, ReadError> {
265
2.67M
        let temp = self.data.read_at(self.pos);
266
2.67M
        self.advance::<T>();
267
2.67M
        temp
268
2.67M
    }
<read_fonts::font_data::Cursor>::read::<i32>
Line
Count
Source
264
47.6k
    pub(crate) fn read<T: Scalar>(&mut self) -> Result<T, ReadError> {
265
47.6k
        let temp = self.data.read_at(self.pos);
266
47.6k
        self.advance::<T>();
267
47.6k
        temp
268
47.6k
    }
<read_fonts::font_data::Cursor>::read::<u32>
Line
Count
Source
264
139k
    pub(crate) fn read<T: Scalar>(&mut self) -> Result<T, ReadError> {
265
139k
        let temp = self.data.read_at(self.pos);
266
139k
        self.advance::<T>();
267
139k
        temp
268
139k
    }
<read_fonts::font_data::Cursor>::read::<i16>
Line
Count
Source
264
10.7k
    pub(crate) fn read<T: Scalar>(&mut self) -> Result<T, ReadError> {
265
10.7k
        let temp = self.data.read_at(self.pos);
266
10.7k
        self.advance::<T>();
267
10.7k
        temp
268
10.7k
    }
<read_fonts::font_data::Cursor>::read::<u16>
Line
Count
Source
264
155M
    pub(crate) fn read<T: Scalar>(&mut self) -> Result<T, ReadError> {
265
155M
        let temp = self.data.read_at(self.pos);
266
155M
        self.advance::<T>();
267
155M
        temp
268
155M
    }
269
270
    /// Read a big-endian value and advance the cursor.
271
0
    pub(crate) fn read_be<T: Scalar>(&mut self) -> Result<BigEndian<T>, ReadError> {
272
0
        let temp = self.data.read_be_at(self.pos);
273
0
        self.advance::<T>();
274
0
        temp
275
0
    }
Unexecuted instantiation: <read_fonts::font_data::Cursor>::read_be::<font_types::glyph_id::GlyphId16>
Unexecuted instantiation: <read_fonts::font_data::Cursor>::read_be::<font_types::glyph_id::GlyphId24>
Unexecuted instantiation: <read_fonts::font_data::Cursor>::read_be::<u16>
276
277
    /// Read an item positioned at the cursor and advance past it.
278
    ///
279
    /// The item is given the cursor's whole data plus its position,
280
    /// rather than data sliced to it, so it can resolve offsets
281
    /// relative to the enclosing table.
282
0
    pub(crate) fn read_at_with_args<T>(&mut self, args: T::Args) -> Result<T, ReadError>
283
0
    where
284
0
        T: FontReadAt<'a> + ComputeSize,
285
    {
286
0
        let len = T::compute_size(args)?;
287
        // check the item actually fits before handing out a handle to it
288
0
        let range_end = self.pos.checked_add(len).ok_or(ReadError::OutOfBounds)?;
289
0
        self.data.check_in_bounds(range_end)?;
290
0
        let temp = T::read_at(self.data, self.pos, args);
291
0
        self.advance_by(len);
292
0
        temp
293
0
    }
294
295
    // only used in records that contain arrays :/
296
0
    pub(crate) fn read_computed_array<T>(
297
0
        &mut self,
298
0
        len: usize,
299
0
        args: T::Args,
300
0
    ) -> Result<ComputedArray<'a, T>, ReadError>
301
0
    where
302
0
        T: FontReadAt<'a> + ComputeSize,
303
    {
304
0
        let byte_len = len
305
0
            .checked_mul(T::compute_size(args)?)
306
0
            .ok_or(ReadError::OutOfBounds)?;
307
0
        let range_end = self
308
0
            .pos
309
0
            .checked_add(byte_len)
310
0
            .ok_or(ReadError::OutOfBounds)?;
311
0
        let temp = ComputedArray::new(self.data, self.pos..range_end, args);
312
0
        self.advance_by(byte_len);
313
0
        temp
314
0
    }
315
4.99M
    pub(crate) fn read_array<T: AnyBitPattern + FixedSize>(
316
4.99M
        &mut self,
317
4.99M
        n_elem: usize,
318
4.99M
    ) -> Result<&'a [T], ReadError> {
319
4.99M
        let len = n_elem
320
4.99M
            .checked_mul(T::RAW_BYTE_LEN)
321
4.99M
            .ok_or(ReadError::OutOfBounds)?;
322
4.99M
        let end = self.pos.checked_add(len).ok_or(ReadError::OutOfBounds)?;
323
4.99M
        let temp = self.data.read_array(self.pos..end);
324
4.99M
        self.advance_by(len);
325
4.99M
        temp
326
4.99M
    }
Unexecuted instantiation: <read_fonts::font_data::Cursor>::read_array::<font_types::raw::BigEndian<font_types::offset::Nullable<font_types::offset::Offset16>>>
Unexecuted instantiation: <read_fonts::font_data::Cursor>::read_array::<font_types::raw::BigEndian<font_types::offset::Nullable<font_types::offset::Offset24>>>
<read_fonts::font_data::Cursor>::read_array::<font_types::raw::BigEndian<font_types::fixed::Fixed>>
Line
Count
Source
315
42
    pub(crate) fn read_array<T: AnyBitPattern + FixedSize>(
316
42
        &mut self,
317
42
        n_elem: usize,
318
42
    ) -> Result<&'a [T], ReadError> {
319
42
        let len = n_elem
320
42
            .checked_mul(T::RAW_BYTE_LEN)
321
42
            .ok_or(ReadError::OutOfBounds)?;
322
42
        let end = self.pos.checked_add(len).ok_or(ReadError::OutOfBounds)?;
323
42
        let temp = self.data.read_array(self.pos..end);
324
42
        self.advance_by(len);
325
42
        temp
326
42
    }
<read_fonts::font_data::Cursor>::read_array::<font_types::raw::BigEndian<font_types::fixed::F2Dot14>>
Line
Count
Source
315
3.87k
    pub(crate) fn read_array<T: AnyBitPattern + FixedSize>(
316
3.87k
        &mut self,
317
3.87k
        n_elem: usize,
318
3.87k
    ) -> Result<&'a [T], ReadError> {
319
3.87k
        let len = n_elem
320
3.87k
            .checked_mul(T::RAW_BYTE_LEN)
321
3.87k
            .ok_or(ReadError::OutOfBounds)?;
322
3.87k
        let end = self.pos.checked_add(len).ok_or(ReadError::OutOfBounds)?;
323
3.87k
        let temp = self.data.read_array(self.pos..end);
324
3.87k
        self.advance_by(len);
325
3.87k
        temp
326
3.87k
    }
<read_fonts::font_data::Cursor>::read_array::<font_types::raw::BigEndian<i32>>
Line
Count
Source
315
287
    pub(crate) fn read_array<T: AnyBitPattern + FixedSize>(
316
287
        &mut self,
317
287
        n_elem: usize,
318
287
    ) -> Result<&'a [T], ReadError> {
319
287
        let len = n_elem
320
287
            .checked_mul(T::RAW_BYTE_LEN)
321
287
            .ok_or(ReadError::OutOfBounds)?;
322
287
        let end = self.pos.checked_add(len).ok_or(ReadError::OutOfBounds)?;
323
287
        let temp = self.data.read_array(self.pos..end);
324
287
        self.advance_by(len);
325
287
        temp
326
287
    }
<read_fonts::font_data::Cursor>::read_array::<font_types::raw::BigEndian<u32>>
Line
Count
Source
315
3.05k
    pub(crate) fn read_array<T: AnyBitPattern + FixedSize>(
316
3.05k
        &mut self,
317
3.05k
        n_elem: usize,
318
3.05k
    ) -> Result<&'a [T], ReadError> {
319
3.05k
        let len = n_elem
320
3.05k
            .checked_mul(T::RAW_BYTE_LEN)
321
3.05k
            .ok_or(ReadError::OutOfBounds)?;
322
3.05k
        let end = self.pos.checked_add(len).ok_or(ReadError::OutOfBounds)?;
323
3.05k
        let temp = self.data.read_array(self.pos..end);
324
3.05k
        self.advance_by(len);
325
3.05k
        temp
326
3.05k
    }
<read_fonts::font_data::Cursor>::read_array::<font_types::raw::BigEndian<i16>>
Line
Count
Source
315
534
    pub(crate) fn read_array<T: AnyBitPattern + FixedSize>(
316
534
        &mut self,
317
534
        n_elem: usize,
318
534
    ) -> Result<&'a [T], ReadError> {
319
534
        let len = n_elem
320
534
            .checked_mul(T::RAW_BYTE_LEN)
321
534
            .ok_or(ReadError::OutOfBounds)?;
322
534
        let end = self.pos.checked_add(len).ok_or(ReadError::OutOfBounds)?;
323
534
        let temp = self.data.read_array(self.pos..end);
324
534
        self.advance_by(len);
325
534
        temp
326
534
    }
<read_fonts::font_data::Cursor>::read_array::<font_types::raw::BigEndian<u16>>
Line
Count
Source
315
2.23M
    pub(crate) fn read_array<T: AnyBitPattern + FixedSize>(
316
2.23M
        &mut self,
317
2.23M
        n_elem: usize,
318
2.23M
    ) -> Result<&'a [T], ReadError> {
319
2.23M
        let len = n_elem
320
2.23M
            .checked_mul(T::RAW_BYTE_LEN)
321
2.23M
            .ok_or(ReadError::OutOfBounds)?;
322
2.23M
        let end = self.pos.checked_add(len).ok_or(ReadError::OutOfBounds)?;
323
2.23M
        let temp = self.data.read_array(self.pos..end);
324
2.23M
        self.advance_by(len);
325
2.23M
        temp
326
2.23M
    }
<read_fonts::font_data::Cursor>::read_array::<read_fonts::tables::aat::LookupSingle<u32>>
Line
Count
Source
315
336
    pub(crate) fn read_array<T: AnyBitPattern + FixedSize>(
316
336
        &mut self,
317
336
        n_elem: usize,
318
336
    ) -> Result<&'a [T], ReadError> {
319
336
        let len = n_elem
320
336
            .checked_mul(T::RAW_BYTE_LEN)
321
336
            .ok_or(ReadError::OutOfBounds)?;
322
336
        let end = self.pos.checked_add(len).ok_or(ReadError::OutOfBounds)?;
323
336
        let temp = self.data.read_array(self.pos..end);
324
336
        self.advance_by(len);
325
336
        temp
326
336
    }
<read_fonts::font_data::Cursor>::read_array::<read_fonts::tables::aat::LookupSingle<u16>>
Line
Count
Source
315
1.14M
    pub(crate) fn read_array<T: AnyBitPattern + FixedSize>(
316
1.14M
        &mut self,
317
1.14M
        n_elem: usize,
318
1.14M
    ) -> Result<&'a [T], ReadError> {
319
1.14M
        let len = n_elem
320
1.14M
            .checked_mul(T::RAW_BYTE_LEN)
321
1.14M
            .ok_or(ReadError::OutOfBounds)?;
322
1.14M
        let end = self.pos.checked_add(len).ok_or(ReadError::OutOfBounds)?;
323
1.14M
        let temp = self.data.read_array(self.pos..end);
324
1.14M
        self.advance_by(len);
325
1.14M
        temp
326
1.14M
    }
<read_fonts::font_data::Cursor>::read_array::<read_fonts::tables::aat::LookupSegment2<u32>>
Line
Count
Source
315
403
    pub(crate) fn read_array<T: AnyBitPattern + FixedSize>(
316
403
        &mut self,
317
403
        n_elem: usize,
318
403
    ) -> Result<&'a [T], ReadError> {
319
403
        let len = n_elem
320
403
            .checked_mul(T::RAW_BYTE_LEN)
321
403
            .ok_or(ReadError::OutOfBounds)?;
322
403
        let end = self.pos.checked_add(len).ok_or(ReadError::OutOfBounds)?;
323
403
        let temp = self.data.read_array(self.pos..end);
324
403
        self.advance_by(len);
325
403
        temp
326
403
    }
<read_fonts::font_data::Cursor>::read_array::<read_fonts::tables::aat::LookupSegment2<u16>>
Line
Count
Source
315
1.57M
    pub(crate) fn read_array<T: AnyBitPattern + FixedSize>(
316
1.57M
        &mut self,
317
1.57M
        n_elem: usize,
318
1.57M
    ) -> Result<&'a [T], ReadError> {
319
1.57M
        let len = n_elem
320
1.57M
            .checked_mul(T::RAW_BYTE_LEN)
321
1.57M
            .ok_or(ReadError::OutOfBounds)?;
322
1.57M
        let end = self.pos.checked_add(len).ok_or(ReadError::OutOfBounds)?;
323
1.57M
        let temp = self.data.read_array(self.pos..end);
324
1.57M
        self.advance_by(len);
325
1.57M
        temp
326
1.57M
    }
<read_fonts::font_data::Cursor>::read_array::<read_fonts::tables::variations::RegionAxisCoordinates>
Line
Count
Source
315
12
    pub(crate) fn read_array<T: AnyBitPattern + FixedSize>(
316
12
        &mut self,
317
12
        n_elem: usize,
318
12
    ) -> Result<&'a [T], ReadError> {
319
12
        let len = n_elem
320
12
            .checked_mul(T::RAW_BYTE_LEN)
321
12
            .ok_or(ReadError::OutOfBounds)?;
322
12
        let end = self.pos.checked_add(len).ok_or(ReadError::OutOfBounds)?;
323
12
        let temp = self.data.read_array(self.pos..end);
324
12
        self.advance_by(len);
325
12
        temp
326
12
    }
Unexecuted instantiation: <read_fonts::font_data::Cursor>::read_array::<read_fonts::tables::avar::AxisValueMap>
Unexecuted instantiation: <read_fonts::font_data::Cursor>::read_array::<read_fonts::tables::bitmap::BdtComponent>
Unexecuted instantiation: <read_fonts::font_data::Cursor>::read_array::<read_fonts::tables::bitmap::BigGlyphMetrics>
Unexecuted instantiation: <read_fonts::font_data::Cursor>::read_array::<read_fonts::tables::bitmap::SmallGlyphMetrics>
Unexecuted instantiation: <read_fonts::font_data::Cursor>::read_array::<read_fonts::ps::cff::v1::EncodingRange1>
Unexecuted instantiation: <read_fonts::font_data::Cursor>::read_array::<read_fonts::ps::cff::v1::EncodingSupplement>
<read_fonts::font_data::Cursor>::read_array::<i8>
Line
Count
Source
315
4.35k
    pub(crate) fn read_array<T: AnyBitPattern + FixedSize>(
316
4.35k
        &mut self,
317
4.35k
        n_elem: usize,
318
4.35k
    ) -> Result<&'a [T], ReadError> {
319
4.35k
        let len = n_elem
320
4.35k
            .checked_mul(T::RAW_BYTE_LEN)
321
4.35k
            .ok_or(ReadError::OutOfBounds)?;
322
4.35k
        let end = self.pos.checked_add(len).ok_or(ReadError::OutOfBounds)?;
323
4.35k
        let temp = self.data.read_array(self.pos..end);
324
4.35k
        self.advance_by(len);
325
4.35k
        temp
326
4.35k
    }
<read_fonts::font_data::Cursor>::read_array::<u8>
Line
Count
Source
315
14.1k
    pub(crate) fn read_array<T: AnyBitPattern + FixedSize>(
316
14.1k
        &mut self,
317
14.1k
        n_elem: usize,
318
14.1k
    ) -> Result<&'a [T], ReadError> {
319
14.1k
        let len = n_elem
320
14.1k
            .checked_mul(T::RAW_BYTE_LEN)
321
14.1k
            .ok_or(ReadError::OutOfBounds)?;
322
14.1k
        let end = self.pos.checked_add(len).ok_or(ReadError::OutOfBounds)?;
323
14.1k
        let temp = self.data.read_array(self.pos..end);
324
14.1k
        self.advance_by(len);
325
14.1k
        temp
326
14.1k
    }
327
328
    /// return the current position, or an error if we are out of bounds
329
369k
    pub(crate) fn position(&self) -> Result<usize, ReadError> {
330
369k
        self.data.check_in_bounds(self.pos).map(|_| self.pos)
331
369k
    }
332
333
    // used when handling fields with an implicit length, which must be at the
334
    // end of a table.
335
2.26M
    pub(crate) fn remaining_bytes(&self) -> usize {
336
2.26M
        self.data.len().saturating_sub(self.pos)
337
2.26M
    }
338
339
76.9M
    pub(crate) fn remaining(self) -> Option<FontData<'a>> {
340
76.9M
        self.data.split_off(self.pos)
341
76.9M
    }
342
343
0
    pub fn is_empty(&self) -> bool {
344
0
        self.pos >= self.data.len()
345
0
    }
346
}
347
348
// useful so we can have offsets that are just to data
349
impl ReadArgs for FontData<'_> {
350
    type Args = ();
351
}
352
353
impl<'a> FontRead<'a> for FontData<'a> {
354
2.51k
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
355
2.51k
        Ok(data)
356
2.51k
    }
357
}
358
359
impl AsRef<[u8]> for FontData<'_> {
360
406
    fn as_ref(&self) -> &[u8] {
361
406
        self.bytes
362
406
    }
363
}
364
365
impl<'a> From<&'a [u8]> for FontData<'a> {
366
307k
    fn from(src: &'a [u8]) -> FontData<'a> {
367
307k
        FontData::new(src)
368
307k
    }
369
}
370
371
//kind of ugly, but makes FontData work with FontBuilder. If FontBuilder stops using
372
//Cow in its API, we can probably get rid of this?
373
#[cfg(feature = "std")]
374
impl<'a> From<FontData<'a>> for std::borrow::Cow<'a, [u8]> {
375
0
    fn from(src: FontData<'a>) -> Self {
376
0
        src.bytes.into()
377
0
    }
378
}
379
380
#[cfg(test)]
381
mod tests {
382
    use super::*;
383
    #[test]
384
    fn how_does_big_endian_work_again() {
385
        let data = FontData::default_format_1_u16_table_data();
386
        assert_eq!(data.read_at(0), Ok(1u16));
387
388
        assert_eq!(
389
            FontData::default_format_1_u8_table_data().read_at(0),
390
            Ok(1u8)
391
        );
392
    }
393
}