/rust/registry/src/index.crates.io-1949cf8c6b5b557f/read-fonts-0.46.0/generated/generated_kern.rs
Line | Count | Source |
1 | | // THIS FILE IS AUTOGENERATED. |
2 | | // Any changes to this file will be overwritten. |
3 | | // For more information about how codegen works, see font-codegen/README.md |
4 | | |
5 | | #[allow(unused_imports)] |
6 | | use crate::codegen_prelude::*; |
7 | | |
8 | | impl<'a> MinByteRange<'a> for OtKern<'a> { |
9 | 0 | fn min_byte_range(&self) -> Range<usize> { |
10 | 0 | 0..self.subtable_data_byte_range().end |
11 | 0 | } |
12 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
13 | 0 | let range = self.min_byte_range(); |
14 | 0 | self.offset_data().as_bytes().get(range).unwrap_or_default() |
15 | 0 | } |
16 | | } |
17 | | |
18 | | impl ReadArgs for OtKern<'_> { |
19 | | type Args = (); |
20 | | } |
21 | | |
22 | | impl<'a> FontRead<'a> for OtKern<'a> { |
23 | 1.15k | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
24 | | #[allow(clippy::absurd_extreme_comparisons)] |
25 | 1.15k | if data.len() < Self::MIN_SIZE { |
26 | 2 | return Err(ReadError::OutOfBounds); |
27 | 1.15k | } |
28 | 1.15k | let Some(data) = TableDataRef::new(data.as_bytes()) else { |
29 | 0 | return Err(ReadError::OutOfBounds); |
30 | | }; |
31 | 1.15k | Ok(Self { data }) |
32 | 1.15k | } |
33 | | } |
34 | | |
35 | | /// The fields at the start of the table, which are read directly. |
36 | | #[derive(Clone, Copy, bytemuck :: AnyBitPattern)] |
37 | | #[repr(C, packed)] |
38 | | #[doc(hidden)] |
39 | | pub struct OtKernFixedHeader { |
40 | | pub version: BigEndian<u16>, |
41 | | pub n_tables: BigEndian<u16>, |
42 | | } |
43 | | |
44 | | #[allow(clippy::absurd_extreme_comparisons)] |
45 | | const _: () = assert!(std::mem::size_of::<OtKernFixedHeader>() <= OtKern::MIN_SIZE); |
46 | | |
47 | | /// The OpenType [kerning](https://learn.microsoft.com/en-us/typography/opentype/spec/kern) table. |
48 | | #[derive(Clone)] |
49 | | pub struct OtKern<'a> { |
50 | | data: TableDataRef<'a, OtKernFixedHeader>, |
51 | | } |
52 | | |
53 | | #[allow(clippy::needless_lifetimes)] |
54 | | impl<'a> OtKern<'a> { |
55 | | pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN); |
56 | | basic_table_impls!(impl_the_methods); |
57 | | |
58 | | /// Table version number—set to 0. |
59 | 0 | pub fn version(&self) -> u16 { |
60 | 0 | self.data.header().version.get() |
61 | 0 | } |
62 | | |
63 | | /// Number of subtables in the kerning table. |
64 | 5.34k | pub fn n_tables(&self) -> u16 { |
65 | 5.34k | self.data.header().n_tables.get() |
66 | 5.34k | } |
67 | | |
68 | | /// Data for subtables, immediately following the header. |
69 | 5.34k | pub fn subtable_data(&self) -> &'a [u8] { |
70 | 5.34k | let range = self.subtable_data_byte_range(); |
71 | 5.34k | self.offset_data() |
72 | 5.34k | .read_array(range) |
73 | 5.34k | .ok() |
74 | 5.34k | .unwrap_or_default() |
75 | 5.34k | } |
76 | | |
77 | 5.34k | pub fn version_byte_range(&self) -> Range<usize> { |
78 | 5.34k | let start = 0; |
79 | 5.34k | let end = start + u16::RAW_BYTE_LEN; |
80 | 5.34k | start..end |
81 | 5.34k | } |
82 | | |
83 | 5.34k | pub fn n_tables_byte_range(&self) -> Range<usize> { |
84 | 5.34k | let start = self.version_byte_range().end; |
85 | 5.34k | let end = start + u16::RAW_BYTE_LEN; |
86 | 5.34k | start..end |
87 | 5.34k | } |
88 | | |
89 | 5.34k | pub fn subtable_data_byte_range(&self) -> Range<usize> { |
90 | 5.34k | let start = self.n_tables_byte_range().end; |
91 | 5.34k | let end = start |
92 | 5.34k | + self.offset_data().len().saturating_sub(start) / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN; |
93 | 5.34k | start..end |
94 | 5.34k | } |
95 | | } |
96 | | |
97 | | const _: () = assert!(FontData::default_data_long_enough(OtKern::MIN_SIZE)); |
98 | | |
99 | | impl Default for OtKern<'_> { |
100 | 0 | fn default() -> Self { |
101 | | Self { |
102 | 0 | data: TableDataRef::new(FontData::default_table_data().as_bytes()) |
103 | 0 | .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")), |
104 | | } |
105 | 0 | } |
106 | | } |
107 | | |
108 | | impl<'a> MinByteRange<'a> for AatKern<'a> { |
109 | 0 | fn min_byte_range(&self) -> Range<usize> { |
110 | 0 | 0..self.subtable_data_byte_range().end |
111 | 0 | } |
112 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
113 | 0 | let range = self.min_byte_range(); |
114 | 0 | self.offset_data().as_bytes().get(range).unwrap_or_default() |
115 | 0 | } |
116 | | } |
117 | | |
118 | | impl ReadArgs for AatKern<'_> { |
119 | | type Args = (); |
120 | | } |
121 | | |
122 | | impl<'a> FontRead<'a> for AatKern<'a> { |
123 | 135 | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
124 | | #[allow(clippy::absurd_extreme_comparisons)] |
125 | 135 | if data.len() < Self::MIN_SIZE { |
126 | 2 | return Err(ReadError::OutOfBounds); |
127 | 133 | } |
128 | 133 | let Some(data) = TableDataRef::new(data.as_bytes()) else { |
129 | 0 | return Err(ReadError::OutOfBounds); |
130 | | }; |
131 | 133 | Ok(Self { data }) |
132 | 135 | } |
133 | | } |
134 | | |
135 | | /// The fields at the start of the table, which are read directly. |
136 | | #[derive(Clone, Copy, bytemuck :: AnyBitPattern)] |
137 | | #[repr(C, packed)] |
138 | | #[doc(hidden)] |
139 | | pub struct AatKernFixedHeader { |
140 | | pub version: BigEndian<MajorMinor>, |
141 | | pub n_tables: BigEndian<u32>, |
142 | | } |
143 | | |
144 | | #[allow(clippy::absurd_extreme_comparisons)] |
145 | | const _: () = assert!(std::mem::size_of::<AatKernFixedHeader>() <= AatKern::MIN_SIZE); |
146 | | |
147 | | /// The Apple Advanced Typography [kerning](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kern.html) table. |
148 | | #[derive(Clone)] |
149 | | pub struct AatKern<'a> { |
150 | | data: TableDataRef<'a, AatKernFixedHeader>, |
151 | | } |
152 | | |
153 | | #[allow(clippy::needless_lifetimes)] |
154 | | impl<'a> AatKern<'a> { |
155 | | pub const MIN_SIZE: usize = (MajorMinor::RAW_BYTE_LEN + u32::RAW_BYTE_LEN); |
156 | | basic_table_impls!(impl_the_methods); |
157 | | |
158 | | /// The version number of the kerning table (0x00010000 for the current version). |
159 | 0 | pub fn version(&self) -> MajorMinor { |
160 | 0 | self.data.header().version.get() |
161 | 0 | } |
162 | | |
163 | | /// The number of subtables included in the kerning table. |
164 | 588 | pub fn n_tables(&self) -> u32 { |
165 | 588 | self.data.header().n_tables.get() |
166 | 588 | } |
167 | | |
168 | | /// Data for subtables, immediately following the header. |
169 | 588 | pub fn subtable_data(&self) -> &'a [u8] { |
170 | 588 | let range = self.subtable_data_byte_range(); |
171 | 588 | self.offset_data() |
172 | 588 | .read_array(range) |
173 | 588 | .ok() |
174 | 588 | .unwrap_or_default() |
175 | 588 | } |
176 | | |
177 | 588 | pub fn version_byte_range(&self) -> Range<usize> { |
178 | 588 | let start = 0; |
179 | 588 | let end = start + MajorMinor::RAW_BYTE_LEN; |
180 | 588 | start..end |
181 | 588 | } |
182 | | |
183 | 588 | pub fn n_tables_byte_range(&self) -> Range<usize> { |
184 | 588 | let start = self.version_byte_range().end; |
185 | 588 | let end = start + u32::RAW_BYTE_LEN; |
186 | 588 | start..end |
187 | 588 | } |
188 | | |
189 | 588 | pub fn subtable_data_byte_range(&self) -> Range<usize> { |
190 | 588 | let start = self.n_tables_byte_range().end; |
191 | 588 | let end = start |
192 | 588 | + self.offset_data().len().saturating_sub(start) / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN; |
193 | 588 | start..end |
194 | 588 | } |
195 | | } |
196 | | |
197 | | const _: () = assert!(FontData::default_data_long_enough(AatKern::MIN_SIZE)); |
198 | | |
199 | | impl Default for AatKern<'_> { |
200 | 0 | fn default() -> Self { |
201 | | Self { |
202 | 0 | data: TableDataRef::new(FontData::default_table_data().as_bytes()) |
203 | 0 | .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")), |
204 | | } |
205 | 0 | } |
206 | | } |
207 | | |
208 | | impl<'a> MinByteRange<'a> for OtSubtable<'a> { |
209 | 0 | fn min_byte_range(&self) -> Range<usize> { |
210 | 0 | 0..self.data_byte_range().end |
211 | 0 | } |
212 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
213 | 0 | let range = self.min_byte_range(); |
214 | 0 | self.offset_data().as_bytes().get(range).unwrap_or_default() |
215 | 0 | } |
216 | | } |
217 | | |
218 | | impl ReadArgs for OtSubtable<'_> { |
219 | | type Args = (); |
220 | | } |
221 | | |
222 | | impl<'a> FontRead<'a> for OtSubtable<'a> { |
223 | 14.5k | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
224 | | #[allow(clippy::absurd_extreme_comparisons)] |
225 | 14.5k | if data.len() < Self::MIN_SIZE { |
226 | 367 | return Err(ReadError::OutOfBounds); |
227 | 14.1k | } |
228 | 14.1k | let Some(data) = TableDataRef::new(data.as_bytes()) else { |
229 | 0 | return Err(ReadError::OutOfBounds); |
230 | | }; |
231 | 14.1k | Ok(Self { data }) |
232 | 14.5k | } |
233 | | } |
234 | | |
235 | | /// The fields at the start of the table, which are read directly. |
236 | | #[derive(Clone, Copy, bytemuck :: AnyBitPattern)] |
237 | | #[repr(C, packed)] |
238 | | #[doc(hidden)] |
239 | | pub struct OtSubtableFixedHeader { |
240 | | pub version: BigEndian<u16>, |
241 | | pub length: BigEndian<u16>, |
242 | | pub coverage: BigEndian<u16>, |
243 | | } |
244 | | |
245 | | #[allow(clippy::absurd_extreme_comparisons)] |
246 | | const _: () = assert!(std::mem::size_of::<OtSubtableFixedHeader>() <= OtSubtable::MIN_SIZE); |
247 | | |
248 | | /// A subtable in an OT `kern` table. |
249 | | #[derive(Clone)] |
250 | | pub struct OtSubtable<'a> { |
251 | | data: TableDataRef<'a, OtSubtableFixedHeader>, |
252 | | } |
253 | | |
254 | | #[allow(clippy::needless_lifetimes)] |
255 | | impl<'a> OtSubtable<'a> { |
256 | | pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN); |
257 | | basic_table_impls!(impl_the_methods); |
258 | | |
259 | | /// Kern subtable version number-- set to 0. |
260 | 0 | pub fn version(&self) -> u16 { |
261 | 0 | self.data.header().version.get() |
262 | 0 | } |
263 | | |
264 | | /// The length of this subtable in bytes, including this header. |
265 | 0 | pub fn length(&self) -> u16 { |
266 | 0 | self.data.header().length.get() |
267 | 0 | } |
268 | | |
269 | | /// Circumstances under which this table is used. |
270 | 23.1k | pub fn coverage(&self) -> u16 { |
271 | 23.1k | self.data.header().coverage.get() |
272 | 23.1k | } |
273 | | |
274 | | /// Subtable specific data. |
275 | 7.08k | pub fn data(&self) -> &'a [u8] { |
276 | 7.08k | let range = self.data_byte_range(); |
277 | 7.08k | self.offset_data() |
278 | 7.08k | .read_array(range) |
279 | 7.08k | .ok() |
280 | 7.08k | .unwrap_or_default() |
281 | 7.08k | } |
282 | | |
283 | 7.08k | pub fn version_byte_range(&self) -> Range<usize> { |
284 | 7.08k | let start = 0; |
285 | 7.08k | let end = start + u16::RAW_BYTE_LEN; |
286 | 7.08k | start..end |
287 | 7.08k | } |
288 | | |
289 | 7.08k | pub fn length_byte_range(&self) -> Range<usize> { |
290 | 7.08k | let start = self.version_byte_range().end; |
291 | 7.08k | let end = start + u16::RAW_BYTE_LEN; |
292 | 7.08k | start..end |
293 | 7.08k | } |
294 | | |
295 | 7.08k | pub fn coverage_byte_range(&self) -> Range<usize> { |
296 | 7.08k | let start = self.length_byte_range().end; |
297 | 7.08k | let end = start + u16::RAW_BYTE_LEN; |
298 | 7.08k | start..end |
299 | 7.08k | } |
300 | | |
301 | 7.08k | pub fn data_byte_range(&self) -> Range<usize> { |
302 | 7.08k | let start = self.coverage_byte_range().end; |
303 | 7.08k | let end = start |
304 | 7.08k | + self.offset_data().len().saturating_sub(start) / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN; |
305 | 7.08k | start..end |
306 | 7.08k | } |
307 | | } |
308 | | |
309 | | const _: () = assert!(FontData::default_data_long_enough(OtSubtable::MIN_SIZE)); |
310 | | |
311 | | impl Default for OtSubtable<'_> { |
312 | 0 | fn default() -> Self { |
313 | | Self { |
314 | 0 | data: TableDataRef::new(FontData::default_table_data().as_bytes()) |
315 | 0 | .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")), |
316 | | } |
317 | 0 | } |
318 | | } |
319 | | |
320 | | impl<'a> MinByteRange<'a> for AatSubtable<'a> { |
321 | 0 | fn min_byte_range(&self) -> Range<usize> { |
322 | 0 | 0..self.data_byte_range().end |
323 | 0 | } |
324 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
325 | 0 | let range = self.min_byte_range(); |
326 | 0 | self.offset_data().as_bytes().get(range).unwrap_or_default() |
327 | 0 | } |
328 | | } |
329 | | |
330 | | impl ReadArgs for AatSubtable<'_> { |
331 | | type Args = (); |
332 | | } |
333 | | |
334 | | impl<'a> FontRead<'a> for AatSubtable<'a> { |
335 | 1.40k | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
336 | | #[allow(clippy::absurd_extreme_comparisons)] |
337 | 1.40k | if data.len() < Self::MIN_SIZE { |
338 | 44 | return Err(ReadError::OutOfBounds); |
339 | 1.36k | } |
340 | 1.36k | let Some(data) = TableDataRef::new(data.as_bytes()) else { |
341 | 0 | return Err(ReadError::OutOfBounds); |
342 | | }; |
343 | 1.36k | Ok(Self { data }) |
344 | 1.40k | } |
345 | | } |
346 | | |
347 | | /// The fields at the start of the table, which are read directly. |
348 | | #[derive(Clone, Copy, bytemuck :: AnyBitPattern)] |
349 | | #[repr(C, packed)] |
350 | | #[doc(hidden)] |
351 | | pub struct AatSubtableFixedHeader { |
352 | | pub length: BigEndian<u32>, |
353 | | pub coverage: BigEndian<u16>, |
354 | | pub tuple_index: BigEndian<u16>, |
355 | | } |
356 | | |
357 | | #[allow(clippy::absurd_extreme_comparisons)] |
358 | | const _: () = assert!(std::mem::size_of::<AatSubtableFixedHeader>() <= AatSubtable::MIN_SIZE); |
359 | | |
360 | | /// A subtable in an AAT `kern` table. |
361 | | #[derive(Clone)] |
362 | | pub struct AatSubtable<'a> { |
363 | | data: TableDataRef<'a, AatSubtableFixedHeader>, |
364 | | } |
365 | | |
366 | | #[allow(clippy::needless_lifetimes)] |
367 | | impl<'a> AatSubtable<'a> { |
368 | | pub const MIN_SIZE: usize = (u32::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN); |
369 | | basic_table_impls!(impl_the_methods); |
370 | | |
371 | | /// The length of this subtable in bytes, including this header. |
372 | 0 | pub fn length(&self) -> u32 { |
373 | 0 | self.data.header().length.get() |
374 | 0 | } |
375 | | |
376 | | /// Circumstances under which this table is used. |
377 | 2.74k | pub fn coverage(&self) -> u16 { |
378 | 2.74k | self.data.header().coverage.get() |
379 | 2.74k | } |
380 | | |
381 | | /// The tuple index (used for variations fonts). This value specifies which tuple this subtable covers. |
382 | 0 | pub fn tuple_index(&self) -> u16 { |
383 | 0 | self.data.header().tuple_index.get() |
384 | 0 | } |
385 | | |
386 | | /// Subtable specific data. |
387 | 1.03k | pub fn data(&self) -> &'a [u8] { |
388 | 1.03k | let range = self.data_byte_range(); |
389 | 1.03k | self.offset_data() |
390 | 1.03k | .read_array(range) |
391 | 1.03k | .ok() |
392 | 1.03k | .unwrap_or_default() |
393 | 1.03k | } |
394 | | |
395 | 1.03k | pub fn length_byte_range(&self) -> Range<usize> { |
396 | 1.03k | let start = 0; |
397 | 1.03k | let end = start + u32::RAW_BYTE_LEN; |
398 | 1.03k | start..end |
399 | 1.03k | } |
400 | | |
401 | 1.03k | pub fn coverage_byte_range(&self) -> Range<usize> { |
402 | 1.03k | let start = self.length_byte_range().end; |
403 | 1.03k | let end = start + u16::RAW_BYTE_LEN; |
404 | 1.03k | start..end |
405 | 1.03k | } |
406 | | |
407 | 1.03k | pub fn tuple_index_byte_range(&self) -> Range<usize> { |
408 | 1.03k | let start = self.coverage_byte_range().end; |
409 | 1.03k | let end = start + u16::RAW_BYTE_LEN; |
410 | 1.03k | start..end |
411 | 1.03k | } |
412 | | |
413 | 1.03k | pub fn data_byte_range(&self) -> Range<usize> { |
414 | 1.03k | let start = self.tuple_index_byte_range().end; |
415 | 1.03k | let end = start |
416 | 1.03k | + self.offset_data().len().saturating_sub(start) / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN; |
417 | 1.03k | start..end |
418 | 1.03k | } |
419 | | } |
420 | | |
421 | | const _: () = assert!(FontData::default_data_long_enough(AatSubtable::MIN_SIZE)); |
422 | | |
423 | | impl Default for AatSubtable<'_> { |
424 | 0 | fn default() -> Self { |
425 | | Self { |
426 | 0 | data: TableDataRef::new(FontData::default_table_data().as_bytes()) |
427 | 0 | .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")), |
428 | | } |
429 | 0 | } |
430 | | } |
431 | | |
432 | | impl<'a> MinByteRange<'a> for Subtable0<'a> { |
433 | 0 | fn min_byte_range(&self) -> Range<usize> { |
434 | 0 | 0..self.pairs_byte_range().end |
435 | 0 | } |
436 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
437 | 0 | let range = self.min_byte_range(); |
438 | 0 | self.offset_data().as_bytes().get(range).unwrap_or_default() |
439 | 0 | } |
440 | | } |
441 | | |
442 | | impl ReadArgs for Subtable0<'_> { |
443 | | type Args = (); |
444 | | } |
445 | | |
446 | | impl<'a> FontRead<'a> for Subtable0<'a> { |
447 | 446 | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
448 | | #[allow(clippy::absurd_extreme_comparisons)] |
449 | 446 | if data.len() < Self::MIN_SIZE { |
450 | 184 | return Err(ReadError::OutOfBounds); |
451 | 262 | } |
452 | 262 | let Some(data) = TableDataRef::new(data.as_bytes()) else { |
453 | 0 | return Err(ReadError::OutOfBounds); |
454 | | }; |
455 | 262 | Ok(Self { data }) |
456 | 446 | } |
457 | | } |
458 | | |
459 | | /// The fields at the start of the table, which are read directly. |
460 | | #[derive(Clone, Copy, bytemuck :: AnyBitPattern)] |
461 | | #[repr(C, packed)] |
462 | | #[doc(hidden)] |
463 | | pub struct Subtable0FixedHeader { |
464 | | pub n_pairs: BigEndian<u16>, |
465 | | pub search_range: BigEndian<u16>, |
466 | | pub entry_selector: BigEndian<u16>, |
467 | | pub range_shift: BigEndian<u16>, |
468 | | } |
469 | | |
470 | | #[allow(clippy::absurd_extreme_comparisons)] |
471 | | const _: () = assert!(std::mem::size_of::<Subtable0FixedHeader>() <= Subtable0::MIN_SIZE); |
472 | | |
473 | | /// The type 0 `kern` subtable. |
474 | | #[derive(Clone)] |
475 | | pub struct Subtable0<'a> { |
476 | | data: TableDataRef<'a, Subtable0FixedHeader>, |
477 | | } |
478 | | |
479 | | #[allow(clippy::needless_lifetimes)] |
480 | | impl<'a> Subtable0<'a> { |
481 | | pub const MIN_SIZE: usize = |
482 | | (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN); |
483 | | basic_table_impls!(impl_the_methods); |
484 | | |
485 | | /// The number of kerning pairs in this subtable. |
486 | 2.15k | pub fn n_pairs(&self) -> u16 { |
487 | 2.15k | self.data.header().n_pairs.get() |
488 | 2.15k | } |
489 | | |
490 | | /// The largest power of two less than or equal to the value of nPairs, multiplied by the size in bytes of an entry in the subtable. |
491 | 0 | pub fn search_range(&self) -> u16 { |
492 | 0 | self.data.header().search_range.get() |
493 | 0 | } |
494 | | |
495 | | /// This is calculated as log2 of the largest power of two less than or equal to the value of nPairs. This value indicates how many iterations of the search loop have to be made. For example, in a list of eight items, there would be three iterations of the loop. |
496 | 0 | pub fn entry_selector(&self) -> u16 { |
497 | 0 | self.data.header().entry_selector.get() |
498 | 0 | } |
499 | | |
500 | | /// The value of nPairs minus the largest power of two less than or equal to nPairs. This is multiplied by the size in bytes of an entry in the table. |
501 | 0 | pub fn range_shift(&self) -> u16 { |
502 | 0 | self.data.header().range_shift.get() |
503 | 0 | } |
504 | | |
505 | | /// Kerning records. |
506 | 2.15k | pub fn pairs(&self) -> &'a [Subtable0Pair] { |
507 | 2.15k | let range = self.pairs_byte_range(); |
508 | 2.15k | self.offset_data() |
509 | 2.15k | .read_array(range) |
510 | 2.15k | .ok() |
511 | 2.15k | .unwrap_or_default() |
512 | 2.15k | } |
513 | | |
514 | 2.15k | pub fn n_pairs_byte_range(&self) -> Range<usize> { |
515 | 2.15k | let start = 0; |
516 | 2.15k | let end = start + u16::RAW_BYTE_LEN; |
517 | 2.15k | start..end |
518 | 2.15k | } |
519 | | |
520 | 2.15k | pub fn search_range_byte_range(&self) -> Range<usize> { |
521 | 2.15k | let start = self.n_pairs_byte_range().end; |
522 | 2.15k | let end = start + u16::RAW_BYTE_LEN; |
523 | 2.15k | start..end |
524 | 2.15k | } |
525 | | |
526 | 2.15k | pub fn entry_selector_byte_range(&self) -> Range<usize> { |
527 | 2.15k | let start = self.search_range_byte_range().end; |
528 | 2.15k | let end = start + u16::RAW_BYTE_LEN; |
529 | 2.15k | start..end |
530 | 2.15k | } |
531 | | |
532 | 2.15k | pub fn range_shift_byte_range(&self) -> Range<usize> { |
533 | 2.15k | let start = self.entry_selector_byte_range().end; |
534 | 2.15k | let end = start + u16::RAW_BYTE_LEN; |
535 | 2.15k | start..end |
536 | 2.15k | } |
537 | | |
538 | 2.15k | pub fn pairs_byte_range(&self) -> Range<usize> { |
539 | 2.15k | let n_pairs = self.n_pairs(); |
540 | 2.15k | let start = self.range_shift_byte_range().end; |
541 | 2.15k | let end = |
542 | 2.15k | start + (transforms::to_usize(n_pairs)).saturating_mul(Subtable0Pair::RAW_BYTE_LEN); |
543 | 2.15k | start..end |
544 | 2.15k | } |
545 | | } |
546 | | |
547 | | const _: () = assert!(FontData::default_data_long_enough(Subtable0::MIN_SIZE)); |
548 | | |
549 | | impl Default for Subtable0<'_> { |
550 | 0 | fn default() -> Self { |
551 | | Self { |
552 | 0 | data: TableDataRef::new(FontData::default_table_data().as_bytes()) |
553 | 0 | .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")), |
554 | | } |
555 | 0 | } |
556 | | } |
557 | | |
558 | | impl<'a> MinByteRange<'a> for Subtable2ClassTable<'a> { |
559 | 0 | fn min_byte_range(&self) -> Range<usize> { |
560 | 0 | 0..self.offsets_byte_range().end |
561 | 0 | } |
562 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
563 | 0 | let range = self.min_byte_range(); |
564 | 0 | self.offset_data().as_bytes().get(range).unwrap_or_default() |
565 | 0 | } |
566 | | } |
567 | | |
568 | | impl ReadArgs for Subtable2ClassTable<'_> { |
569 | | type Args = (); |
570 | | } |
571 | | |
572 | | impl<'a> FontRead<'a> for Subtable2ClassTable<'a> { |
573 | 163 | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
574 | | #[allow(clippy::absurd_extreme_comparisons)] |
575 | 163 | if data.len() < Self::MIN_SIZE { |
576 | 4 | return Err(ReadError::OutOfBounds); |
577 | 159 | } |
578 | 159 | let Some(data) = TableDataRef::new(data.as_bytes()) else { |
579 | 0 | return Err(ReadError::OutOfBounds); |
580 | | }; |
581 | 159 | Ok(Self { data }) |
582 | 163 | } |
583 | | } |
584 | | |
585 | | /// The fields at the start of the table, which are read directly. |
586 | | #[derive(Clone, Copy, bytemuck :: AnyBitPattern)] |
587 | | #[repr(C, packed)] |
588 | | #[doc(hidden)] |
589 | | pub struct Subtable2ClassTableFixedHeader { |
590 | | pub first_glyph: BigEndian<GlyphId16>, |
591 | | pub n_glyphs: BigEndian<u16>, |
592 | | } |
593 | | |
594 | | #[allow(clippy::absurd_extreme_comparisons)] |
595 | | const _: () = |
596 | | assert!(std::mem::size_of::<Subtable2ClassTableFixedHeader>() <= Subtable2ClassTable::MIN_SIZE); |
597 | | |
598 | | /// Class table for the type 2 `kern` subtable. |
599 | | #[derive(Clone)] |
600 | | pub struct Subtable2ClassTable<'a> { |
601 | | data: TableDataRef<'a, Subtable2ClassTableFixedHeader>, |
602 | | } |
603 | | |
604 | | #[allow(clippy::needless_lifetimes)] |
605 | | impl<'a> Subtable2ClassTable<'a> { |
606 | | pub const MIN_SIZE: usize = (GlyphId16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN); |
607 | | basic_table_impls!(impl_the_methods); |
608 | | |
609 | | /// First glyph in class range. |
610 | 1.54k | pub fn first_glyph(&self) -> GlyphId16 { |
611 | 1.54k | self.data.header().first_glyph.get() |
612 | 1.54k | } |
613 | | |
614 | | /// Number of glyph in class range. |
615 | 1.54k | pub fn n_glyphs(&self) -> u16 { |
616 | 1.54k | self.data.header().n_glyphs.get() |
617 | 1.54k | } |
618 | | |
619 | | /// The offsets array for all of the glyphs in the range. |
620 | 1.39k | pub fn offsets(&self) -> &'a [BigEndian<u16>] { |
621 | 1.39k | let range = self.offsets_byte_range(); |
622 | 1.39k | self.offset_data() |
623 | 1.39k | .read_array(range) |
624 | 1.39k | .ok() |
625 | 1.39k | .unwrap_or_default() |
626 | 1.39k | } |
627 | | |
628 | 1.39k | pub fn first_glyph_byte_range(&self) -> Range<usize> { |
629 | 1.39k | let start = 0; |
630 | 1.39k | let end = start + GlyphId16::RAW_BYTE_LEN; |
631 | 1.39k | start..end |
632 | 1.39k | } |
633 | | |
634 | 1.39k | pub fn n_glyphs_byte_range(&self) -> Range<usize> { |
635 | 1.39k | let start = self.first_glyph_byte_range().end; |
636 | 1.39k | let end = start + u16::RAW_BYTE_LEN; |
637 | 1.39k | start..end |
638 | 1.39k | } |
639 | | |
640 | 1.39k | pub fn offsets_byte_range(&self) -> Range<usize> { |
641 | 1.39k | let n_glyphs = self.n_glyphs(); |
642 | 1.39k | let start = self.n_glyphs_byte_range().end; |
643 | 1.39k | let end = start + (transforms::to_usize(n_glyphs)).saturating_mul(u16::RAW_BYTE_LEN); |
644 | 1.39k | start..end |
645 | 1.39k | } |
646 | | } |
647 | | |
648 | | const _: () = assert!(FontData::default_data_long_enough( |
649 | | Subtable2ClassTable::MIN_SIZE |
650 | | )); |
651 | | |
652 | | impl Default for Subtable2ClassTable<'_> { |
653 | 0 | fn default() -> Self { |
654 | | Self { |
655 | 0 | data: TableDataRef::new(FontData::default_table_data().as_bytes()) |
656 | 0 | .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")), |
657 | | } |
658 | 0 | } |
659 | | } |
660 | | |
661 | | impl<'a> MinByteRange<'a> for Subtable3<'a> { |
662 | 0 | fn min_byte_range(&self) -> Range<usize> { |
663 | 0 | 0..self.kern_index_byte_range().end |
664 | 0 | } |
665 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
666 | 0 | let range = self.min_byte_range(); |
667 | 0 | self.offset_data().as_bytes().get(range).unwrap_or_default() |
668 | 0 | } |
669 | | } |
670 | | |
671 | | impl ReadArgs for Subtable3<'_> { |
672 | | type Args = (); |
673 | | } |
674 | | |
675 | | impl<'a> FontRead<'a> for Subtable3<'a> { |
676 | 217 | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
677 | | #[allow(clippy::absurd_extreme_comparisons)] |
678 | 217 | if data.len() < Self::MIN_SIZE { |
679 | 9 | return Err(ReadError::OutOfBounds); |
680 | 208 | } |
681 | 208 | let Some(data) = TableDataRef::new(data.as_bytes()) else { |
682 | 0 | return Err(ReadError::OutOfBounds); |
683 | | }; |
684 | 208 | Ok(Self { data }) |
685 | 217 | } |
686 | | } |
687 | | |
688 | | /// The fields at the start of the table, which are read directly. |
689 | | #[derive(Clone, Copy, bytemuck :: AnyBitPattern)] |
690 | | #[repr(C, packed)] |
691 | | #[doc(hidden)] |
692 | | pub struct Subtable3FixedHeader { |
693 | | pub glyph_count: BigEndian<u16>, |
694 | | pub kern_value_count: u8, |
695 | | pub left_class_count: u8, |
696 | | pub right_class_count: u8, |
697 | | pub flags: u8, |
698 | | } |
699 | | |
700 | | #[allow(clippy::absurd_extreme_comparisons)] |
701 | | const _: () = assert!(std::mem::size_of::<Subtable3FixedHeader>() <= Subtable3::MIN_SIZE); |
702 | | |
703 | | /// The type 3 'kern' subtable. |
704 | | #[derive(Clone)] |
705 | | pub struct Subtable3<'a> { |
706 | | data: TableDataRef<'a, Subtable3FixedHeader>, |
707 | | } |
708 | | |
709 | | #[allow(clippy::needless_lifetimes)] |
710 | | impl<'a> Subtable3<'a> { |
711 | | pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN |
712 | | + u8::RAW_BYTE_LEN |
713 | | + u8::RAW_BYTE_LEN |
714 | | + u8::RAW_BYTE_LEN |
715 | | + u8::RAW_BYTE_LEN); |
716 | | basic_table_impls!(impl_the_methods); |
717 | | |
718 | | /// The number of glyphs in this font. |
719 | 7.53k | pub fn glyph_count(&self) -> u16 { |
720 | 7.53k | self.data.header().glyph_count.get() |
721 | 7.53k | } |
722 | | |
723 | | /// The number of kerning values. |
724 | 5.78k | pub fn kern_value_count(&self) -> u8 { |
725 | 5.78k | self.data.header().kern_value_count |
726 | 5.78k | } |
727 | | |
728 | | /// The number of left-hand classes. |
729 | 361 | pub fn left_class_count(&self) -> u8 { |
730 | 361 | self.data.header().left_class_count |
731 | 361 | } |
732 | | |
733 | | /// The number of right-hand classes. |
734 | 722 | pub fn right_class_count(&self) -> u8 { |
735 | 722 | self.data.header().right_class_count |
736 | 722 | } |
737 | | |
738 | | /// Set to zero (reserved for future use). |
739 | 0 | pub fn flags(&self) -> u8 { |
740 | 0 | self.data.header().flags |
741 | 0 | } |
742 | | |
743 | | /// The kerning values. |
744 | 170 | pub fn kern_value(&self) -> &'a [BigEndian<i16>] { |
745 | 170 | let range = self.kern_value_byte_range(); |
746 | 170 | self.offset_data() |
747 | 170 | .read_array(range) |
748 | 170 | .ok() |
749 | 170 | .unwrap_or_default() |
750 | 170 | } |
751 | | |
752 | | /// The left-hand classes. |
753 | 4.09k | pub fn left_class(&self) -> &'a [u8] { |
754 | 4.09k | let range = self.left_class_byte_range(); |
755 | 4.09k | self.offset_data() |
756 | 4.09k | .read_array(range) |
757 | 4.09k | .ok() |
758 | 4.09k | .unwrap_or_default() |
759 | 4.09k | } |
760 | | |
761 | | /// The right-hand classes. |
762 | 1.15k | pub fn right_class(&self) -> &'a [u8] { |
763 | 1.15k | let range = self.right_class_byte_range(); |
764 | 1.15k | self.offset_data() |
765 | 1.15k | .read_array(range) |
766 | 1.15k | .ok() |
767 | 1.15k | .unwrap_or_default() |
768 | 1.15k | } |
769 | | |
770 | | /// The indices into the kernValue array. |
771 | 361 | pub fn kern_index(&self) -> &'a [u8] { |
772 | 361 | let range = self.kern_index_byte_range(); |
773 | 361 | self.offset_data() |
774 | 361 | .read_array(range) |
775 | 361 | .ok() |
776 | 361 | .unwrap_or_default() |
777 | 361 | } |
778 | | |
779 | 5.78k | pub fn glyph_count_byte_range(&self) -> Range<usize> { |
780 | 5.78k | let start = 0; |
781 | 5.78k | let end = start + u16::RAW_BYTE_LEN; |
782 | 5.78k | start..end |
783 | 5.78k | } |
784 | | |
785 | 5.78k | pub fn kern_value_count_byte_range(&self) -> Range<usize> { |
786 | 5.78k | let start = self.glyph_count_byte_range().end; |
787 | 5.78k | let end = start + u8::RAW_BYTE_LEN; |
788 | 5.78k | start..end |
789 | 5.78k | } |
790 | | |
791 | 5.78k | pub fn left_class_count_byte_range(&self) -> Range<usize> { |
792 | 5.78k | let start = self.kern_value_count_byte_range().end; |
793 | 5.78k | let end = start + u8::RAW_BYTE_LEN; |
794 | 5.78k | start..end |
795 | 5.78k | } |
796 | | |
797 | 5.78k | pub fn right_class_count_byte_range(&self) -> Range<usize> { |
798 | 5.78k | let start = self.left_class_count_byte_range().end; |
799 | 5.78k | let end = start + u8::RAW_BYTE_LEN; |
800 | 5.78k | start..end |
801 | 5.78k | } |
802 | | |
803 | 5.78k | pub fn flags_byte_range(&self) -> Range<usize> { |
804 | 5.78k | let start = self.right_class_count_byte_range().end; |
805 | 5.78k | let end = start + u8::RAW_BYTE_LEN; |
806 | 5.78k | start..end |
807 | 5.78k | } |
808 | | |
809 | 5.78k | pub fn kern_value_byte_range(&self) -> Range<usize> { |
810 | 5.78k | let kern_value_count = self.kern_value_count(); |
811 | 5.78k | let start = self.flags_byte_range().end; |
812 | 5.78k | let end = |
813 | 5.78k | start + (transforms::to_usize(kern_value_count)).saturating_mul(i16::RAW_BYTE_LEN); |
814 | 5.78k | start..end |
815 | 5.78k | } |
816 | | |
817 | 5.61k | pub fn left_class_byte_range(&self) -> Range<usize> { |
818 | 5.61k | let glyph_count = self.glyph_count(); |
819 | 5.61k | let start = self.kern_value_byte_range().end; |
820 | 5.61k | let end = start + (transforms::to_usize(glyph_count)).saturating_mul(u8::RAW_BYTE_LEN); |
821 | 5.61k | start..end |
822 | 5.61k | } |
823 | | |
824 | 1.51k | pub fn right_class_byte_range(&self) -> Range<usize> { |
825 | 1.51k | let glyph_count = self.glyph_count(); |
826 | 1.51k | let start = self.left_class_byte_range().end; |
827 | 1.51k | let end = start + (transforms::to_usize(glyph_count)).saturating_mul(u8::RAW_BYTE_LEN); |
828 | 1.51k | start..end |
829 | 1.51k | } |
830 | | |
831 | 361 | pub fn kern_index_byte_range(&self) -> Range<usize> { |
832 | 361 | let left_class_count = self.left_class_count(); |
833 | 361 | let right_class_count = self.right_class_count(); |
834 | 361 | let start = self.right_class_byte_range().end; |
835 | 361 | let end = start |
836 | 361 | + (transforms::add_multiply(left_class_count, 0_usize, right_class_count)) |
837 | 361 | .saturating_mul(u8::RAW_BYTE_LEN); |
838 | 361 | start..end |
839 | 361 | } |
840 | | } |
841 | | |
842 | | const _: () = assert!(FontData::default_data_long_enough(Subtable3::MIN_SIZE)); |
843 | | |
844 | | impl Default for Subtable3<'_> { |
845 | 0 | fn default() -> Self { |
846 | | Self { |
847 | 0 | data: TableDataRef::new(FontData::default_table_data().as_bytes()) |
848 | 0 | .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")), |
849 | | } |
850 | 0 | } |
851 | | } |