/rust/registry/src/index.crates.io-1949cf8c6b5b557f/read-fonts-0.46.0/generated/generated_bitmap.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 | | /// [BitmapSize](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#bitmapsize-record) record. |
9 | | #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] |
10 | | #[repr(C)] |
11 | | #[repr(packed)] |
12 | | pub struct BitmapSize { |
13 | | /// Offset to IndexSubtableList, from beginning of EBLC/CBLC. |
14 | | pub index_subtable_list_offset: BigEndian<u32>, |
15 | | /// Total size in bytes of the IndexSubtableList including its array of IndexSubtables. |
16 | | pub index_subtable_list_size: BigEndian<u32>, |
17 | | /// Number of IndexSubtables in the IndexSubtableList. |
18 | | pub number_of_index_subtables: BigEndian<u32>, |
19 | | /// Not used; set to 0. |
20 | | pub color_ref: BigEndian<u32>, |
21 | | /// Line metrics for text rendered horizontally. |
22 | | pub hori: SbitLineMetrics, |
23 | | /// Line metrics for text rendered vertically. |
24 | | pub vert: SbitLineMetrics, |
25 | | /// Lowest glyph index for this size. |
26 | | pub start_glyph_index: BigEndian<GlyphId16>, |
27 | | /// Highest glyph index for this size. |
28 | | pub end_glyph_index: BigEndian<GlyphId16>, |
29 | | /// Horizontal pixels per em. |
30 | | pub ppem_x: u8, |
31 | | /// Vertical pixels per em. |
32 | | pub ppem_y: u8, |
33 | | /// The Microsoft rasterizer v.1.7 or greater supports the following |
34 | | /// bitDepth values, as described below: 1, 2, 4, and 8 (and 32 for CBLC). |
35 | | pub bit_depth: u8, |
36 | | /// Vertical or horizontal. |
37 | | pub flags: BigEndian<BitmapFlags>, |
38 | | } |
39 | | |
40 | | impl BitmapSize { |
41 | | /// Offset to IndexSubtableList, from beginning of EBLC/CBLC. |
42 | 0 | pub fn index_subtable_list_offset(&self) -> u32 { |
43 | 0 | self.index_subtable_list_offset.get() |
44 | 0 | } |
45 | | |
46 | | /// Total size in bytes of the IndexSubtableList including its array of IndexSubtables. |
47 | 0 | pub fn index_subtable_list_size(&self) -> u32 { |
48 | 0 | self.index_subtable_list_size.get() |
49 | 0 | } |
50 | | |
51 | | /// Number of IndexSubtables in the IndexSubtableList. |
52 | 0 | pub fn number_of_index_subtables(&self) -> u32 { |
53 | 0 | self.number_of_index_subtables.get() |
54 | 0 | } |
55 | | |
56 | | /// Not used; set to 0. |
57 | 0 | pub fn color_ref(&self) -> u32 { |
58 | 0 | self.color_ref.get() |
59 | 0 | } |
60 | | |
61 | | /// Line metrics for text rendered horizontally. |
62 | 0 | pub fn hori(&self) -> &SbitLineMetrics { |
63 | 0 | &self.hori |
64 | 0 | } |
65 | | |
66 | | /// Line metrics for text rendered vertically. |
67 | 0 | pub fn vert(&self) -> &SbitLineMetrics { |
68 | 0 | &self.vert |
69 | 0 | } |
70 | | |
71 | | /// Lowest glyph index for this size. |
72 | 0 | pub fn start_glyph_index(&self) -> GlyphId16 { |
73 | 0 | self.start_glyph_index.get() |
74 | 0 | } |
75 | | |
76 | | /// Highest glyph index for this size. |
77 | 0 | pub fn end_glyph_index(&self) -> GlyphId16 { |
78 | 0 | self.end_glyph_index.get() |
79 | 0 | } |
80 | | |
81 | | /// Horizontal pixels per em. |
82 | 0 | pub fn ppem_x(&self) -> u8 { |
83 | 0 | self.ppem_x |
84 | 0 | } |
85 | | |
86 | | /// Vertical pixels per em. |
87 | 0 | pub fn ppem_y(&self) -> u8 { |
88 | 0 | self.ppem_y |
89 | 0 | } |
90 | | |
91 | | /// The Microsoft rasterizer v.1.7 or greater supports the following |
92 | | /// bitDepth values, as described below: 1, 2, 4, and 8 (and 32 for CBLC). |
93 | 0 | pub fn bit_depth(&self) -> u8 { |
94 | 0 | self.bit_depth |
95 | 0 | } |
96 | | |
97 | | /// Vertical or horizontal. |
98 | 0 | pub fn flags(&self) -> BitmapFlags { |
99 | 0 | self.flags.get() |
100 | 0 | } |
101 | | } |
102 | | |
103 | | impl FixedSize for BitmapSize { |
104 | | const RAW_BYTE_LEN: usize = u32::RAW_BYTE_LEN |
105 | | + u32::RAW_BYTE_LEN |
106 | | + u32::RAW_BYTE_LEN |
107 | | + u32::RAW_BYTE_LEN |
108 | | + SbitLineMetrics::RAW_BYTE_LEN |
109 | | + SbitLineMetrics::RAW_BYTE_LEN |
110 | | + GlyphId16::RAW_BYTE_LEN |
111 | | + GlyphId16::RAW_BYTE_LEN |
112 | | + u8::RAW_BYTE_LEN |
113 | | + u8::RAW_BYTE_LEN |
114 | | + u8::RAW_BYTE_LEN |
115 | | + BitmapFlags::RAW_BYTE_LEN; |
116 | | } |
117 | | |
118 | | /// [SbitLineMetrics](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#sbitlinemetrics-record) record. |
119 | | #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] |
120 | | #[repr(C)] |
121 | | #[repr(packed)] |
122 | | pub struct SbitLineMetrics { |
123 | | pub ascender: BigEndian<i8>, |
124 | | pub descender: BigEndian<i8>, |
125 | | pub width_max: u8, |
126 | | pub caret_slope_numerator: BigEndian<i8>, |
127 | | pub caret_slope_denominator: u8, |
128 | | pub caret_offset: BigEndian<i8>, |
129 | | pub min_origin_sb: BigEndian<i8>, |
130 | | pub min_advance_sb: BigEndian<i8>, |
131 | | pub max_before_bl: BigEndian<i8>, |
132 | | pub min_after_bl: BigEndian<i8>, |
133 | | pub pad1: BigEndian<i8>, |
134 | | pub pad2: BigEndian<i8>, |
135 | | } |
136 | | |
137 | | impl SbitLineMetrics { |
138 | 0 | pub fn ascender(&self) -> i8 { |
139 | 0 | self.ascender.get() |
140 | 0 | } |
141 | | |
142 | 0 | pub fn descender(&self) -> i8 { |
143 | 0 | self.descender.get() |
144 | 0 | } |
145 | | |
146 | 0 | pub fn width_max(&self) -> u8 { |
147 | 0 | self.width_max |
148 | 0 | } |
149 | | |
150 | 0 | pub fn caret_slope_numerator(&self) -> i8 { |
151 | 0 | self.caret_slope_numerator.get() |
152 | 0 | } |
153 | | |
154 | 0 | pub fn caret_slope_denominator(&self) -> u8 { |
155 | 0 | self.caret_slope_denominator |
156 | 0 | } |
157 | | |
158 | 0 | pub fn caret_offset(&self) -> i8 { |
159 | 0 | self.caret_offset.get() |
160 | 0 | } |
161 | | |
162 | 0 | pub fn min_origin_sb(&self) -> i8 { |
163 | 0 | self.min_origin_sb.get() |
164 | 0 | } |
165 | | |
166 | 0 | pub fn min_advance_sb(&self) -> i8 { |
167 | 0 | self.min_advance_sb.get() |
168 | 0 | } |
169 | | |
170 | 0 | pub fn max_before_bl(&self) -> i8 { |
171 | 0 | self.max_before_bl.get() |
172 | 0 | } |
173 | | |
174 | 0 | pub fn min_after_bl(&self) -> i8 { |
175 | 0 | self.min_after_bl.get() |
176 | 0 | } |
177 | | |
178 | 0 | pub fn pad1(&self) -> i8 { |
179 | 0 | self.pad1.get() |
180 | 0 | } |
181 | | |
182 | 0 | pub fn pad2(&self) -> i8 { |
183 | 0 | self.pad2.get() |
184 | 0 | } |
185 | | } |
186 | | |
187 | | impl FixedSize for SbitLineMetrics { |
188 | | const RAW_BYTE_LEN: usize = i8::RAW_BYTE_LEN |
189 | | + i8::RAW_BYTE_LEN |
190 | | + u8::RAW_BYTE_LEN |
191 | | + i8::RAW_BYTE_LEN |
192 | | + u8::RAW_BYTE_LEN |
193 | | + i8::RAW_BYTE_LEN |
194 | | + i8::RAW_BYTE_LEN |
195 | | + i8::RAW_BYTE_LEN |
196 | | + i8::RAW_BYTE_LEN |
197 | | + i8::RAW_BYTE_LEN |
198 | | + i8::RAW_BYTE_LEN |
199 | | + i8::RAW_BYTE_LEN; |
200 | | } |
201 | | |
202 | | /// [Bitmap flags](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#bitmap-flags). |
203 | | #[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck :: AnyBitPattern)] |
204 | | #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
205 | | #[repr(transparent)] |
206 | | pub struct BitmapFlags { |
207 | | bits: u8, |
208 | | } |
209 | | |
210 | | impl BitmapFlags { |
211 | | /// Horizontal |
212 | | pub const HORIZONTAL_METRICS: Self = Self { bits: 0x01 }; |
213 | | |
214 | | /// Vertical |
215 | | pub const VERTICAL_METRICS: Self = Self { bits: 0x02 }; |
216 | | } |
217 | | |
218 | | impl BitmapFlags { |
219 | | /// Returns an empty set of flags. |
220 | | #[inline] |
221 | 0 | pub const fn empty() -> Self { |
222 | 0 | Self { bits: 0 } |
223 | 0 | } |
224 | | |
225 | | /// Returns the set containing all flags. |
226 | | #[inline] |
227 | 0 | pub const fn all() -> Self { |
228 | 0 | Self { |
229 | 0 | bits: Self::HORIZONTAL_METRICS.bits | Self::VERTICAL_METRICS.bits, |
230 | 0 | } |
231 | 0 | } |
232 | | |
233 | | /// Returns the raw value of the flags currently stored. |
234 | | #[inline] |
235 | 0 | pub const fn bits(&self) -> u8 { |
236 | 0 | self.bits |
237 | 0 | } |
238 | | |
239 | | /// Convert from underlying bit representation, unless that |
240 | | /// representation contains bits that do not correspond to a flag. |
241 | | #[inline] |
242 | 0 | pub const fn from_bits(bits: u8) -> Option<Self> { |
243 | 0 | if (bits & !Self::all().bits()) == 0 { |
244 | 0 | Some(Self { bits }) |
245 | | } else { |
246 | 0 | None |
247 | | } |
248 | 0 | } |
249 | | |
250 | | /// Convert from underlying bit representation, dropping any bits |
251 | | /// that do not correspond to flags. |
252 | | #[inline] |
253 | 0 | pub const fn from_bits_truncate(bits: u8) -> Self { |
254 | 0 | Self { |
255 | 0 | bits: bits & Self::all().bits, |
256 | 0 | } |
257 | 0 | } |
258 | | |
259 | | /// Returns `true` if no flags are currently stored. |
260 | | #[inline] |
261 | 0 | pub const fn is_empty(&self) -> bool { |
262 | 0 | self.bits() == Self::empty().bits() |
263 | 0 | } |
264 | | |
265 | | /// Returns `true` if there are flags common to both `self` and `other`. |
266 | | #[inline] |
267 | 0 | pub const fn intersects(&self, other: Self) -> bool { |
268 | 0 | !(Self { |
269 | 0 | bits: self.bits & other.bits, |
270 | 0 | }) |
271 | 0 | .is_empty() |
272 | 0 | } |
273 | | |
274 | | /// Returns `true` if all of the flags in `other` are contained within `self`. |
275 | | #[inline] |
276 | 0 | pub const fn contains(&self, other: Self) -> bool { |
277 | 0 | (self.bits & other.bits) == other.bits |
278 | 0 | } |
279 | | |
280 | | /// Inserts the specified flags in-place. |
281 | | #[inline] |
282 | 0 | pub fn insert(&mut self, other: Self) { |
283 | 0 | self.bits |= other.bits; |
284 | 0 | } |
285 | | |
286 | | /// Removes the specified flags in-place. |
287 | | #[inline] |
288 | 0 | pub fn remove(&mut self, other: Self) { |
289 | 0 | self.bits &= !other.bits; |
290 | 0 | } |
291 | | |
292 | | /// Toggles the specified flags in-place. |
293 | | #[inline] |
294 | 0 | pub fn toggle(&mut self, other: Self) { |
295 | 0 | self.bits ^= other.bits; |
296 | 0 | } |
297 | | |
298 | | /// Returns the intersection between the flags in `self` and |
299 | | /// `other`. |
300 | | /// |
301 | | /// Specifically, the returned set contains only the flags which are |
302 | | /// present in *both* `self` *and* `other`. |
303 | | /// |
304 | | /// This is equivalent to using the `&` operator (e.g. |
305 | | /// [`ops::BitAnd`]), as in `flags & other`. |
306 | | /// |
307 | | /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html |
308 | | #[inline] |
309 | | #[must_use] |
310 | 0 | pub const fn intersection(self, other: Self) -> Self { |
311 | 0 | Self { |
312 | 0 | bits: self.bits & other.bits, |
313 | 0 | } |
314 | 0 | } |
315 | | |
316 | | /// Returns the union of between the flags in `self` and `other`. |
317 | | /// |
318 | | /// Specifically, the returned set contains all flags which are |
319 | | /// present in *either* `self` *or* `other`, including any which are |
320 | | /// present in both. |
321 | | /// |
322 | | /// This is equivalent to using the `|` operator (e.g. |
323 | | /// [`ops::BitOr`]), as in `flags | other`. |
324 | | /// |
325 | | /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html |
326 | | #[inline] |
327 | | #[must_use] |
328 | 0 | pub const fn union(self, other: Self) -> Self { |
329 | 0 | Self { |
330 | 0 | bits: self.bits | other.bits, |
331 | 0 | } |
332 | 0 | } |
333 | | |
334 | | /// Returns the difference between the flags in `self` and `other`. |
335 | | /// |
336 | | /// Specifically, the returned set contains all flags present in |
337 | | /// `self`, except for the ones present in `other`. |
338 | | /// |
339 | | /// It is also conceptually equivalent to the "bit-clear" operation: |
340 | | /// `flags & !other` (and this syntax is also supported). |
341 | | /// |
342 | | /// This is equivalent to using the `-` operator (e.g. |
343 | | /// [`ops::Sub`]), as in `flags - other`. |
344 | | /// |
345 | | /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html |
346 | | #[inline] |
347 | | #[must_use] |
348 | 0 | pub const fn difference(self, other: Self) -> Self { |
349 | 0 | Self { |
350 | 0 | bits: self.bits & !other.bits, |
351 | 0 | } |
352 | 0 | } |
353 | | } |
354 | | |
355 | | impl std::ops::BitOr for BitmapFlags { |
356 | | type Output = Self; |
357 | | |
358 | | /// Returns the union of the two sets of flags. |
359 | | #[inline] |
360 | 0 | fn bitor(self, other: BitmapFlags) -> Self { |
361 | 0 | Self { |
362 | 0 | bits: self.bits | other.bits, |
363 | 0 | } |
364 | 0 | } |
365 | | } |
366 | | |
367 | | impl std::ops::BitOrAssign for BitmapFlags { |
368 | | /// Adds the set of flags. |
369 | | #[inline] |
370 | 0 | fn bitor_assign(&mut self, other: Self) { |
371 | 0 | self.bits |= other.bits; |
372 | 0 | } |
373 | | } |
374 | | |
375 | | impl std::ops::BitXor for BitmapFlags { |
376 | | type Output = Self; |
377 | | |
378 | | /// Returns the left flags, but with all the right flags toggled. |
379 | | #[inline] |
380 | 0 | fn bitxor(self, other: Self) -> Self { |
381 | 0 | Self { |
382 | 0 | bits: self.bits ^ other.bits, |
383 | 0 | } |
384 | 0 | } |
385 | | } |
386 | | |
387 | | impl std::ops::BitXorAssign for BitmapFlags { |
388 | | /// Toggles the set of flags. |
389 | | #[inline] |
390 | 0 | fn bitxor_assign(&mut self, other: Self) { |
391 | 0 | self.bits ^= other.bits; |
392 | 0 | } |
393 | | } |
394 | | |
395 | | impl std::ops::BitAnd for BitmapFlags { |
396 | | type Output = Self; |
397 | | |
398 | | /// Returns the intersection between the two sets of flags. |
399 | | #[inline] |
400 | 0 | fn bitand(self, other: Self) -> Self { |
401 | 0 | Self { |
402 | 0 | bits: self.bits & other.bits, |
403 | 0 | } |
404 | 0 | } |
405 | | } |
406 | | |
407 | | impl std::ops::BitAndAssign for BitmapFlags { |
408 | | /// Disables all flags disabled in the set. |
409 | | #[inline] |
410 | 0 | fn bitand_assign(&mut self, other: Self) { |
411 | 0 | self.bits &= other.bits; |
412 | 0 | } |
413 | | } |
414 | | |
415 | | impl std::ops::Sub for BitmapFlags { |
416 | | type Output = Self; |
417 | | |
418 | | /// Returns the set difference of the two sets of flags. |
419 | | #[inline] |
420 | 0 | fn sub(self, other: Self) -> Self { |
421 | 0 | Self { |
422 | 0 | bits: self.bits & !other.bits, |
423 | 0 | } |
424 | 0 | } |
425 | | } |
426 | | |
427 | | impl std::ops::SubAssign for BitmapFlags { |
428 | | /// Disables all flags enabled in the set. |
429 | | #[inline] |
430 | 0 | fn sub_assign(&mut self, other: Self) { |
431 | 0 | self.bits &= !other.bits; |
432 | 0 | } |
433 | | } |
434 | | |
435 | | impl std::ops::Not for BitmapFlags { |
436 | | type Output = Self; |
437 | | |
438 | | /// Returns the complement of this set of flags. |
439 | | #[inline] |
440 | 0 | fn not(self) -> Self { |
441 | 0 | Self { bits: !self.bits } & Self::all() |
442 | 0 | } |
443 | | } |
444 | | |
445 | | impl std::fmt::Debug for BitmapFlags { |
446 | 0 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
447 | 0 | let members: &[(&str, Self)] = &[ |
448 | 0 | ("HORIZONTAL_METRICS", Self::HORIZONTAL_METRICS), |
449 | 0 | ("VERTICAL_METRICS", Self::VERTICAL_METRICS), |
450 | 0 | ]; |
451 | 0 | let mut first = true; |
452 | 0 | for (name, value) in members { |
453 | 0 | if self.contains(*value) { |
454 | 0 | if !first { |
455 | 0 | f.write_str(" | ")?; |
456 | 0 | } |
457 | 0 | first = false; |
458 | 0 | f.write_str(name)?; |
459 | 0 | } |
460 | | } |
461 | 0 | if first { |
462 | 0 | f.write_str("(empty)")?; |
463 | 0 | } |
464 | 0 | Ok(()) |
465 | 0 | } |
466 | | } |
467 | | |
468 | | impl std::fmt::Binary for BitmapFlags { |
469 | 0 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
470 | 0 | std::fmt::Binary::fmt(&self.bits, f) |
471 | 0 | } |
472 | | } |
473 | | |
474 | | impl std::fmt::Octal for BitmapFlags { |
475 | 0 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
476 | 0 | std::fmt::Octal::fmt(&self.bits, f) |
477 | 0 | } |
478 | | } |
479 | | |
480 | | impl std::fmt::LowerHex for BitmapFlags { |
481 | 0 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
482 | 0 | std::fmt::LowerHex::fmt(&self.bits, f) |
483 | 0 | } |
484 | | } |
485 | | |
486 | | impl std::fmt::UpperHex for BitmapFlags { |
487 | 0 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
488 | 0 | std::fmt::UpperHex::fmt(&self.bits, f) |
489 | 0 | } |
490 | | } |
491 | | |
492 | | impl font_types::Scalar for BitmapFlags { |
493 | | type Raw = <u8 as font_types::Scalar>::Raw; |
494 | 0 | fn to_raw(self) -> Self::Raw { |
495 | 0 | self.bits().to_raw() |
496 | 0 | } |
497 | 0 | fn from_raw(raw: Self::Raw) -> Self { |
498 | 0 | let t = <u8>::from_raw(raw); |
499 | 0 | Self::from_bits_truncate(t) |
500 | 0 | } |
501 | | } |
502 | | |
503 | | /// [BigGlyphMetrics](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#bigglyphmetrics) record. |
504 | | #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] |
505 | | #[repr(C)] |
506 | | #[repr(packed)] |
507 | | pub struct BigGlyphMetrics { |
508 | | /// Number of rows of data. |
509 | | pub height: u8, |
510 | | /// Number of columns of data. |
511 | | pub width: u8, |
512 | | /// Distance in pixels from the horizontal origin to the left edge of the bitmap. |
513 | | pub hori_bearing_x: BigEndian<i8>, |
514 | | /// Distance in pixels from the horizontal origin to the top edge of the bitmap. |
515 | | pub hori_bearing_y: BigEndian<i8>, |
516 | | /// Horizontal advance width in pixels. |
517 | | pub hori_advance: u8, |
518 | | /// Distance in pixels from the vertical origin to the left edge of the bitmap. |
519 | | pub vert_bearing_x: BigEndian<i8>, |
520 | | /// Distance in pixels from the vertical origin to the top edge of the bitmap. |
521 | | pub vert_bearing_y: BigEndian<i8>, |
522 | | /// Vertical advance width in pixels. |
523 | | pub vert_advance: u8, |
524 | | } |
525 | | |
526 | | impl BigGlyphMetrics { |
527 | | /// Number of rows of data. |
528 | 0 | pub fn height(&self) -> u8 { |
529 | 0 | self.height |
530 | 0 | } |
531 | | |
532 | | /// Number of columns of data. |
533 | 0 | pub fn width(&self) -> u8 { |
534 | 0 | self.width |
535 | 0 | } |
536 | | |
537 | | /// Distance in pixels from the horizontal origin to the left edge of the bitmap. |
538 | 0 | pub fn hori_bearing_x(&self) -> i8 { |
539 | 0 | self.hori_bearing_x.get() |
540 | 0 | } |
541 | | |
542 | | /// Distance in pixels from the horizontal origin to the top edge of the bitmap. |
543 | 0 | pub fn hori_bearing_y(&self) -> i8 { |
544 | 0 | self.hori_bearing_y.get() |
545 | 0 | } |
546 | | |
547 | | /// Horizontal advance width in pixels. |
548 | 0 | pub fn hori_advance(&self) -> u8 { |
549 | 0 | self.hori_advance |
550 | 0 | } |
551 | | |
552 | | /// Distance in pixels from the vertical origin to the left edge of the bitmap. |
553 | 0 | pub fn vert_bearing_x(&self) -> i8 { |
554 | 0 | self.vert_bearing_x.get() |
555 | 0 | } |
556 | | |
557 | | /// Distance in pixels from the vertical origin to the top edge of the bitmap. |
558 | 0 | pub fn vert_bearing_y(&self) -> i8 { |
559 | 0 | self.vert_bearing_y.get() |
560 | 0 | } |
561 | | |
562 | | /// Vertical advance width in pixels. |
563 | 0 | pub fn vert_advance(&self) -> u8 { |
564 | 0 | self.vert_advance |
565 | 0 | } |
566 | | } |
567 | | |
568 | | impl FixedSize for BigGlyphMetrics { |
569 | | const RAW_BYTE_LEN: usize = u8::RAW_BYTE_LEN |
570 | | + u8::RAW_BYTE_LEN |
571 | | + i8::RAW_BYTE_LEN |
572 | | + i8::RAW_BYTE_LEN |
573 | | + u8::RAW_BYTE_LEN |
574 | | + i8::RAW_BYTE_LEN |
575 | | + i8::RAW_BYTE_LEN |
576 | | + u8::RAW_BYTE_LEN; |
577 | | } |
578 | | |
579 | | /// [SmallGlyphMetrics](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#smallglyphmetrics) record. |
580 | | #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] |
581 | | #[repr(C)] |
582 | | #[repr(packed)] |
583 | | pub struct SmallGlyphMetrics { |
584 | | /// Number of rows of data. |
585 | | pub height: u8, |
586 | | /// Number of columns of data. |
587 | | pub width: u8, |
588 | | /// Distance in pixels from the horizontal origin to the left edge of the bitmap (for horizontal text); or distance in pixels from the vertical origin to the top edge of the bitmap (for vertical text). |
589 | | pub bearing_x: BigEndian<i8>, |
590 | | /// Distance in pixels from the horizontal origin to the top edge of the bitmap (for horizontal text); or distance in pixels from the vertical origin to the left edge of the bitmap (for vertical text). |
591 | | pub bearing_y: BigEndian<i8>, |
592 | | /// Horizontal or vertical advance width in pixels. |
593 | | pub advance: u8, |
594 | | } |
595 | | |
596 | | impl SmallGlyphMetrics { |
597 | | /// Number of rows of data. |
598 | 0 | pub fn height(&self) -> u8 { |
599 | 0 | self.height |
600 | 0 | } |
601 | | |
602 | | /// Number of columns of data. |
603 | 0 | pub fn width(&self) -> u8 { |
604 | 0 | self.width |
605 | 0 | } |
606 | | |
607 | | /// Distance in pixels from the horizontal origin to the left edge of the bitmap (for horizontal text); or distance in pixels from the vertical origin to the top edge of the bitmap (for vertical text). |
608 | 0 | pub fn bearing_x(&self) -> i8 { |
609 | 0 | self.bearing_x.get() |
610 | 0 | } |
611 | | |
612 | | /// Distance in pixels from the horizontal origin to the top edge of the bitmap (for horizontal text); or distance in pixels from the vertical origin to the left edge of the bitmap (for vertical text). |
613 | 0 | pub fn bearing_y(&self) -> i8 { |
614 | 0 | self.bearing_y.get() |
615 | 0 | } |
616 | | |
617 | | /// Horizontal or vertical advance width in pixels. |
618 | 0 | pub fn advance(&self) -> u8 { |
619 | 0 | self.advance |
620 | 0 | } |
621 | | } |
622 | | |
623 | | impl FixedSize for SmallGlyphMetrics { |
624 | | const RAW_BYTE_LEN: usize = u8::RAW_BYTE_LEN |
625 | | + u8::RAW_BYTE_LEN |
626 | | + i8::RAW_BYTE_LEN |
627 | | + i8::RAW_BYTE_LEN |
628 | | + u8::RAW_BYTE_LEN; |
629 | | } |
630 | | |
631 | | impl<'a> MinByteRange<'a> for IndexSubtableList<'a> { |
632 | 0 | fn min_byte_range(&self) -> Range<usize> { |
633 | 0 | 0..self.index_subtable_records_byte_range().end |
634 | 0 | } |
635 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
636 | 0 | let range = self.min_byte_range(); |
637 | 0 | self.offset_data().as_bytes().get(range).unwrap_or_default() |
638 | 0 | } |
639 | | } |
640 | | |
641 | | impl ReadArgs for IndexSubtableList<'_> { |
642 | | type Args = u32; |
643 | | } |
644 | | |
645 | | impl<'a> FontRead<'a> for IndexSubtableList<'a> { |
646 | 0 | fn read_with_args(data: FontData<'a>, args: u32) -> Result<Self, ReadError> { |
647 | 0 | let number_of_index_subtables = args; |
648 | | |
649 | | #[allow(clippy::absurd_extreme_comparisons)] |
650 | 0 | if data.len() < Self::MIN_SIZE { |
651 | 0 | return Err(ReadError::OutOfBounds); |
652 | 0 | } |
653 | 0 | let Some(data) = TableDataRef::new(data.as_bytes()) else { |
654 | 0 | return Err(ReadError::OutOfBounds); |
655 | | }; |
656 | 0 | Ok(Self { |
657 | 0 | data, |
658 | 0 | number_of_index_subtables, |
659 | 0 | }) |
660 | 0 | } |
661 | | } |
662 | | |
663 | | impl<'a> IndexSubtableList<'a> { |
664 | | /// A constructor that requires additional arguments. |
665 | | /// |
666 | | /// This type requires some external state in order to be |
667 | | /// parsed. |
668 | 0 | pub fn read(data: FontData<'a>, number_of_index_subtables: u32) -> Result<Self, ReadError> { |
669 | 0 | let args = number_of_index_subtables; |
670 | 0 | Self::read_with_args(data, args) |
671 | 0 | } |
672 | | } |
673 | | |
674 | | /// The fields at the start of the table, which are read directly. |
675 | | #[derive(Clone, Copy, bytemuck :: AnyBitPattern)] |
676 | | #[repr(C, packed)] |
677 | | #[doc(hidden)] |
678 | | pub struct IndexSubtableListFixedHeader {} |
679 | | |
680 | | #[allow(clippy::absurd_extreme_comparisons)] |
681 | | const _: () = |
682 | | assert!(std::mem::size_of::<IndexSubtableListFixedHeader>() <= IndexSubtableList::MIN_SIZE); |
683 | | |
684 | | /// [IndexSubtableList](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#indexsubtablelist) table. |
685 | | #[derive(Clone)] |
686 | | pub struct IndexSubtableList<'a> { |
687 | | data: TableDataRef<'a, IndexSubtableListFixedHeader>, |
688 | | number_of_index_subtables: u32, |
689 | | } |
690 | | |
691 | | #[allow(clippy::needless_lifetimes)] |
692 | | impl<'a> IndexSubtableList<'a> { |
693 | | pub const MIN_SIZE: usize = 0; |
694 | | basic_table_impls!(impl_the_methods); |
695 | | |
696 | | /// Array of IndexSubtableRecords. |
697 | 0 | pub fn index_subtable_records(&self) -> &'a [IndexSubtableRecord] { |
698 | 0 | let range = self.index_subtable_records_byte_range(); |
699 | 0 | self.offset_data() |
700 | 0 | .read_array(range) |
701 | 0 | .ok() |
702 | 0 | .unwrap_or_default() |
703 | 0 | } |
704 | | |
705 | 0 | pub(crate) fn number_of_index_subtables(&self) -> u32 { |
706 | 0 | self.number_of_index_subtables |
707 | 0 | } |
708 | | |
709 | 0 | pub fn index_subtable_records_byte_range(&self) -> Range<usize> { |
710 | 0 | let number_of_index_subtables = self.number_of_index_subtables(); |
711 | 0 | let start = 0; |
712 | 0 | let end = start |
713 | 0 | + (transforms::to_usize(number_of_index_subtables)) |
714 | 0 | .saturating_mul(IndexSubtableRecord::RAW_BYTE_LEN); |
715 | 0 | start..end |
716 | 0 | } |
717 | | } |
718 | | |
719 | | #[allow(clippy::absurd_extreme_comparisons)] |
720 | | const _: () = assert!(FontData::default_data_long_enough( |
721 | | IndexSubtableList::MIN_SIZE |
722 | | )); |
723 | | |
724 | | impl Default for IndexSubtableList<'_> { |
725 | 0 | fn default() -> Self { |
726 | | Self { |
727 | 0 | data: TableDataRef::new(FontData::default_table_data().as_bytes()) |
728 | 0 | .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")), |
729 | 0 | number_of_index_subtables: Default::default(), |
730 | | } |
731 | 0 | } |
732 | | } |
733 | | |
734 | | #[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)] |
735 | | #[repr(C)] |
736 | | #[repr(packed)] |
737 | | pub struct IndexSubtableRecord { |
738 | | /// First glyph ID of this range. |
739 | | pub first_glyph_index: BigEndian<GlyphId16>, |
740 | | /// Last glyph ID of this range (inclusive). |
741 | | pub last_glyph_index: BigEndian<GlyphId16>, |
742 | | /// Offset to an IndexSubtable from the start of the IndexSubtableList. |
743 | | pub index_subtable_offset: BigEndian<Offset32>, |
744 | | } |
745 | | |
746 | | impl IndexSubtableRecord { |
747 | | /// First glyph ID of this range. |
748 | 0 | pub fn first_glyph_index(&self) -> GlyphId16 { |
749 | 0 | self.first_glyph_index.get() |
750 | 0 | } |
751 | | |
752 | | /// Last glyph ID of this range (inclusive). |
753 | 0 | pub fn last_glyph_index(&self) -> GlyphId16 { |
754 | 0 | self.last_glyph_index.get() |
755 | 0 | } |
756 | | |
757 | | /// Offset to an IndexSubtable from the start of the IndexSubtableList. |
758 | 0 | pub fn index_subtable_offset(&self) -> Offset32 { |
759 | 0 | self.index_subtable_offset.get() |
760 | 0 | } |
761 | | |
762 | | /// Offset to an IndexSubtable from the start of the IndexSubtableList. |
763 | | /// |
764 | | /// The `data` argument should be retrieved from the parent table |
765 | | /// By calling its `offset_data` method. |
766 | 0 | pub fn index_subtable<'a>(&self, data: FontData<'a>) -> Result<IndexSubtable<'a>, ReadError> { |
767 | 0 | let args = (self.last_glyph_index(), self.first_glyph_index()); |
768 | 0 | self.index_subtable_offset().resolve_with_args(data, args) |
769 | 0 | } |
770 | | } |
771 | | |
772 | | impl FixedSize for IndexSubtableRecord { |
773 | | const RAW_BYTE_LEN: usize = |
774 | | GlyphId16::RAW_BYTE_LEN + GlyphId16::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN; |
775 | | } |
776 | | |
777 | | impl Format<u16> for IndexSubtable1<'_> { |
778 | | const FORMAT: u16 = 1; |
779 | | } |
780 | | |
781 | | impl<'a> MinByteRange<'a> for IndexSubtable1<'a> { |
782 | 0 | fn min_byte_range(&self) -> Range<usize> { |
783 | 0 | 0..self.sbit_offsets_byte_range().end |
784 | 0 | } |
785 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
786 | 0 | let range = self.min_byte_range(); |
787 | 0 | self.offset_data().as_bytes().get(range).unwrap_or_default() |
788 | 0 | } |
789 | | } |
790 | | |
791 | | impl ReadArgs for IndexSubtable1<'_> { |
792 | | type Args = (GlyphId16, GlyphId16); |
793 | | } |
794 | | |
795 | | impl<'a> FontRead<'a> for IndexSubtable1<'a> { |
796 | 0 | fn read_with_args(data: FontData<'a>, args: (GlyphId16, GlyphId16)) -> Result<Self, ReadError> { |
797 | 0 | let (last_glyph_index, first_glyph_index) = args; |
798 | | |
799 | | #[allow(clippy::absurd_extreme_comparisons)] |
800 | 0 | if data.len() < Self::MIN_SIZE { |
801 | 0 | return Err(ReadError::OutOfBounds); |
802 | 0 | } |
803 | 0 | let Some(data) = TableDataRef::new(data.as_bytes()) else { |
804 | 0 | return Err(ReadError::OutOfBounds); |
805 | | }; |
806 | 0 | Ok(Self { |
807 | 0 | data, |
808 | 0 | last_glyph_index, |
809 | 0 | first_glyph_index, |
810 | 0 | }) |
811 | 0 | } |
812 | | } |
813 | | |
814 | | impl<'a> IndexSubtable1<'a> { |
815 | | /// A constructor that requires additional arguments. |
816 | | /// |
817 | | /// This type requires some external state in order to be |
818 | | /// parsed. |
819 | 0 | pub fn read( |
820 | 0 | data: FontData<'a>, |
821 | 0 | last_glyph_index: GlyphId16, |
822 | 0 | first_glyph_index: GlyphId16, |
823 | 0 | ) -> Result<Self, ReadError> { |
824 | 0 | let args = (last_glyph_index, first_glyph_index); |
825 | 0 | Self::read_with_args(data, args) |
826 | 0 | } |
827 | | } |
828 | | |
829 | | /// The fields at the start of the table, which are read directly. |
830 | | #[derive(Clone, Copy, bytemuck :: AnyBitPattern)] |
831 | | #[repr(C, packed)] |
832 | | #[doc(hidden)] |
833 | | pub struct IndexSubtable1FixedHeader { |
834 | | pub index_format: BigEndian<u16>, |
835 | | pub image_format: BigEndian<u16>, |
836 | | pub image_data_offset: BigEndian<u32>, |
837 | | } |
838 | | |
839 | | #[allow(clippy::absurd_extreme_comparisons)] |
840 | | const _: () = assert!(std::mem::size_of::<IndexSubtable1FixedHeader>() <= IndexSubtable1::MIN_SIZE); |
841 | | |
842 | | /// [IndexSubTable1](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#indexsubtable1-variable-metrics-glyphs-with-4-byte-offsets): variable-metrics glyphs with 4-byte offsets. |
843 | | #[derive(Clone)] |
844 | | pub struct IndexSubtable1<'a> { |
845 | | data: TableDataRef<'a, IndexSubtable1FixedHeader>, |
846 | | last_glyph_index: GlyphId16, |
847 | | first_glyph_index: GlyphId16, |
848 | | } |
849 | | |
850 | | #[allow(clippy::needless_lifetimes)] |
851 | | impl<'a> IndexSubtable1<'a> { |
852 | | pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN); |
853 | | basic_table_impls!(impl_the_methods); |
854 | | |
855 | | /// Format of this IndexSubTable. |
856 | 0 | pub fn index_format(&self) -> u16 { |
857 | 0 | self.data.header().index_format.get() |
858 | 0 | } |
859 | | |
860 | | /// Format of EBDT image data. |
861 | 0 | pub fn image_format(&self) -> u16 { |
862 | 0 | self.data.header().image_format.get() |
863 | 0 | } |
864 | | |
865 | | /// Offset to image data in EBDT table. |
866 | 0 | pub fn image_data_offset(&self) -> u32 { |
867 | 0 | self.data.header().image_data_offset.get() |
868 | 0 | } |
869 | | |
870 | 0 | pub fn sbit_offsets(&self) -> &'a [BigEndian<u32>] { |
871 | 0 | let range = self.sbit_offsets_byte_range(); |
872 | 0 | self.offset_data() |
873 | 0 | .read_array(range) |
874 | 0 | .ok() |
875 | 0 | .unwrap_or_default() |
876 | 0 | } |
877 | | |
878 | 0 | pub(crate) fn last_glyph_index(&self) -> GlyphId16 { |
879 | 0 | self.last_glyph_index |
880 | 0 | } |
881 | | |
882 | 0 | pub(crate) fn first_glyph_index(&self) -> GlyphId16 { |
883 | 0 | self.first_glyph_index |
884 | 0 | } |
885 | | |
886 | 0 | pub fn index_format_byte_range(&self) -> Range<usize> { |
887 | 0 | let start = 0; |
888 | 0 | let end = start + u16::RAW_BYTE_LEN; |
889 | 0 | start..end |
890 | 0 | } |
891 | | |
892 | 0 | pub fn image_format_byte_range(&self) -> Range<usize> { |
893 | 0 | let start = self.index_format_byte_range().end; |
894 | 0 | let end = start + u16::RAW_BYTE_LEN; |
895 | 0 | start..end |
896 | 0 | } |
897 | | |
898 | 0 | pub fn image_data_offset_byte_range(&self) -> Range<usize> { |
899 | 0 | let start = self.image_format_byte_range().end; |
900 | 0 | let end = start + u32::RAW_BYTE_LEN; |
901 | 0 | start..end |
902 | 0 | } |
903 | | |
904 | 0 | pub fn sbit_offsets_byte_range(&self) -> Range<usize> { |
905 | 0 | let last_glyph_index = self.last_glyph_index(); |
906 | 0 | let first_glyph_index = self.first_glyph_index(); |
907 | 0 | let start = self.image_data_offset_byte_range().end; |
908 | 0 | let end = start |
909 | 0 | + (transforms::subtract_add_two(last_glyph_index, first_glyph_index)) |
910 | 0 | .saturating_mul(u32::RAW_BYTE_LEN); |
911 | 0 | start..end |
912 | 0 | } |
913 | | } |
914 | | |
915 | | const _: () = assert!(FontData::default_data_long_enough(IndexSubtable1::MIN_SIZE)); |
916 | | |
917 | | impl Default for IndexSubtable1<'_> { |
918 | 0 | fn default() -> Self { |
919 | | Self { |
920 | 0 | data: TableDataRef::new(FontData::default_format_1_u16_table_data().as_bytes()) |
921 | 0 | .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")), |
922 | 0 | last_glyph_index: Default::default(), |
923 | 0 | first_glyph_index: Default::default(), |
924 | | } |
925 | 0 | } |
926 | | } |
927 | | |
928 | | impl Format<u16> for IndexSubtable2<'_> { |
929 | | const FORMAT: u16 = 2; |
930 | | } |
931 | | |
932 | | impl<'a> MinByteRange<'a> for IndexSubtable2<'a> { |
933 | 0 | fn min_byte_range(&self) -> Range<usize> { |
934 | 0 | 0..self.big_metrics_byte_range().end |
935 | 0 | } |
936 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
937 | 0 | let range = self.min_byte_range(); |
938 | 0 | self.offset_data().as_bytes().get(range).unwrap_or_default() |
939 | 0 | } |
940 | | } |
941 | | |
942 | | impl ReadArgs for IndexSubtable2<'_> { |
943 | | type Args = (); |
944 | | } |
945 | | |
946 | | impl<'a> FontRead<'a> for IndexSubtable2<'a> { |
947 | 0 | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
948 | | #[allow(clippy::absurd_extreme_comparisons)] |
949 | 0 | if data.len() < Self::MIN_SIZE { |
950 | 0 | return Err(ReadError::OutOfBounds); |
951 | 0 | } |
952 | 0 | let Some(data) = TableDataRef::new(data.as_bytes()) else { |
953 | 0 | return Err(ReadError::OutOfBounds); |
954 | | }; |
955 | 0 | Ok(Self { data }) |
956 | 0 | } |
957 | | } |
958 | | |
959 | | /// The fields at the start of the table, which are read directly. |
960 | | #[derive(Clone, Copy, bytemuck :: AnyBitPattern)] |
961 | | #[repr(C, packed)] |
962 | | #[doc(hidden)] |
963 | | pub struct IndexSubtable2FixedHeader { |
964 | | pub index_format: BigEndian<u16>, |
965 | | pub image_format: BigEndian<u16>, |
966 | | pub image_data_offset: BigEndian<u32>, |
967 | | pub image_size: BigEndian<u32>, |
968 | | pub big_metrics: BigGlyphMetrics, |
969 | | } |
970 | | |
971 | | #[allow(clippy::absurd_extreme_comparisons)] |
972 | | const _: () = assert!(std::mem::size_of::<IndexSubtable2FixedHeader>() <= IndexSubtable2::MIN_SIZE); |
973 | | |
974 | | /// [IndexSubTable2](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#indexsubtable2-all-glyphs-have-identical-metrics): all glyphs have identical metrics. |
975 | | #[derive(Clone)] |
976 | | pub struct IndexSubtable2<'a> { |
977 | | data: TableDataRef<'a, IndexSubtable2FixedHeader>, |
978 | | } |
979 | | |
980 | | #[allow(clippy::needless_lifetimes)] |
981 | | impl<'a> IndexSubtable2<'a> { |
982 | | pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN |
983 | | + u16::RAW_BYTE_LEN |
984 | | + u32::RAW_BYTE_LEN |
985 | | + u32::RAW_BYTE_LEN |
986 | | + BigGlyphMetrics::RAW_BYTE_LEN); |
987 | | basic_table_impls!(impl_the_methods); |
988 | | |
989 | | /// Format of this IndexSubTable. |
990 | 0 | pub fn index_format(&self) -> u16 { |
991 | 0 | self.data.header().index_format.get() |
992 | 0 | } |
993 | | |
994 | | /// Format of EBDT image data. |
995 | 0 | pub fn image_format(&self) -> u16 { |
996 | 0 | self.data.header().image_format.get() |
997 | 0 | } |
998 | | |
999 | | /// Offset to image data in EBDT table. |
1000 | 0 | pub fn image_data_offset(&self) -> u32 { |
1001 | 0 | self.data.header().image_data_offset.get() |
1002 | 0 | } |
1003 | | |
1004 | | /// All the glyphs are of the same size. |
1005 | 0 | pub fn image_size(&self) -> u32 { |
1006 | 0 | self.data.header().image_size.get() |
1007 | 0 | } |
1008 | | |
1009 | | /// All glyphs have the same metrics; glyph data may be compressed, byte-aligned, or bit-aligned. |
1010 | 0 | pub fn big_metrics(&self) -> &'a BigGlyphMetrics { |
1011 | 0 | &self.data.header().big_metrics |
1012 | 0 | } |
1013 | | |
1014 | 0 | pub fn index_format_byte_range(&self) -> Range<usize> { |
1015 | 0 | let start = 0; |
1016 | 0 | let end = start + u16::RAW_BYTE_LEN; |
1017 | 0 | start..end |
1018 | 0 | } |
1019 | | |
1020 | 0 | pub fn image_format_byte_range(&self) -> Range<usize> { |
1021 | 0 | let start = self.index_format_byte_range().end; |
1022 | 0 | let end = start + u16::RAW_BYTE_LEN; |
1023 | 0 | start..end |
1024 | 0 | } |
1025 | | |
1026 | 0 | pub fn image_data_offset_byte_range(&self) -> Range<usize> { |
1027 | 0 | let start = self.image_format_byte_range().end; |
1028 | 0 | let end = start + u32::RAW_BYTE_LEN; |
1029 | 0 | start..end |
1030 | 0 | } |
1031 | | |
1032 | 0 | pub fn image_size_byte_range(&self) -> Range<usize> { |
1033 | 0 | let start = self.image_data_offset_byte_range().end; |
1034 | 0 | let end = start + u32::RAW_BYTE_LEN; |
1035 | 0 | start..end |
1036 | 0 | } |
1037 | | |
1038 | 0 | pub fn big_metrics_byte_range(&self) -> Range<usize> { |
1039 | 0 | let start = self.image_size_byte_range().end; |
1040 | 0 | let end = start + BigGlyphMetrics::RAW_BYTE_LEN; |
1041 | 0 | start..end |
1042 | 0 | } |
1043 | | } |
1044 | | |
1045 | | impl Format<u16> for IndexSubtable3<'_> { |
1046 | | const FORMAT: u16 = 3; |
1047 | | } |
1048 | | |
1049 | | impl<'a> MinByteRange<'a> for IndexSubtable3<'a> { |
1050 | 0 | fn min_byte_range(&self) -> Range<usize> { |
1051 | 0 | 0..self.sbit_offsets_byte_range().end |
1052 | 0 | } |
1053 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
1054 | 0 | let range = self.min_byte_range(); |
1055 | 0 | self.offset_data().as_bytes().get(range).unwrap_or_default() |
1056 | 0 | } |
1057 | | } |
1058 | | |
1059 | | impl ReadArgs for IndexSubtable3<'_> { |
1060 | | type Args = (GlyphId16, GlyphId16); |
1061 | | } |
1062 | | |
1063 | | impl<'a> FontRead<'a> for IndexSubtable3<'a> { |
1064 | 0 | fn read_with_args(data: FontData<'a>, args: (GlyphId16, GlyphId16)) -> Result<Self, ReadError> { |
1065 | 0 | let (last_glyph_index, first_glyph_index) = args; |
1066 | | |
1067 | | #[allow(clippy::absurd_extreme_comparisons)] |
1068 | 0 | if data.len() < Self::MIN_SIZE { |
1069 | 0 | return Err(ReadError::OutOfBounds); |
1070 | 0 | } |
1071 | 0 | let Some(data) = TableDataRef::new(data.as_bytes()) else { |
1072 | 0 | return Err(ReadError::OutOfBounds); |
1073 | | }; |
1074 | 0 | Ok(Self { |
1075 | 0 | data, |
1076 | 0 | last_glyph_index, |
1077 | 0 | first_glyph_index, |
1078 | 0 | }) |
1079 | 0 | } |
1080 | | } |
1081 | | |
1082 | | impl<'a> IndexSubtable3<'a> { |
1083 | | /// A constructor that requires additional arguments. |
1084 | | /// |
1085 | | /// This type requires some external state in order to be |
1086 | | /// parsed. |
1087 | 0 | pub fn read( |
1088 | 0 | data: FontData<'a>, |
1089 | 0 | last_glyph_index: GlyphId16, |
1090 | 0 | first_glyph_index: GlyphId16, |
1091 | 0 | ) -> Result<Self, ReadError> { |
1092 | 0 | let args = (last_glyph_index, first_glyph_index); |
1093 | 0 | Self::read_with_args(data, args) |
1094 | 0 | } |
1095 | | } |
1096 | | |
1097 | | /// The fields at the start of the table, which are read directly. |
1098 | | #[derive(Clone, Copy, bytemuck :: AnyBitPattern)] |
1099 | | #[repr(C, packed)] |
1100 | | #[doc(hidden)] |
1101 | | pub struct IndexSubtable3FixedHeader { |
1102 | | pub index_format: BigEndian<u16>, |
1103 | | pub image_format: BigEndian<u16>, |
1104 | | pub image_data_offset: BigEndian<u32>, |
1105 | | } |
1106 | | |
1107 | | #[allow(clippy::absurd_extreme_comparisons)] |
1108 | | const _: () = assert!(std::mem::size_of::<IndexSubtable3FixedHeader>() <= IndexSubtable3::MIN_SIZE); |
1109 | | |
1110 | | /// [IndexSubTable3](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#indexsubtable3-variable-metrics-glyphs-with-2-byte-offsets): variable-metrics glyphs with 2-byte offsets. |
1111 | | #[derive(Clone)] |
1112 | | pub struct IndexSubtable3<'a> { |
1113 | | data: TableDataRef<'a, IndexSubtable3FixedHeader>, |
1114 | | last_glyph_index: GlyphId16, |
1115 | | first_glyph_index: GlyphId16, |
1116 | | } |
1117 | | |
1118 | | #[allow(clippy::needless_lifetimes)] |
1119 | | impl<'a> IndexSubtable3<'a> { |
1120 | | pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN); |
1121 | | basic_table_impls!(impl_the_methods); |
1122 | | |
1123 | | /// Format of this IndexSubTable. |
1124 | 0 | pub fn index_format(&self) -> u16 { |
1125 | 0 | self.data.header().index_format.get() |
1126 | 0 | } |
1127 | | |
1128 | | /// Format of EBDT image data. |
1129 | 0 | pub fn image_format(&self) -> u16 { |
1130 | 0 | self.data.header().image_format.get() |
1131 | 0 | } |
1132 | | |
1133 | | /// Offset to image data in EBDT table. |
1134 | 0 | pub fn image_data_offset(&self) -> u32 { |
1135 | 0 | self.data.header().image_data_offset.get() |
1136 | 0 | } |
1137 | | |
1138 | 0 | pub fn sbit_offsets(&self) -> &'a [BigEndian<u16>] { |
1139 | 0 | let range = self.sbit_offsets_byte_range(); |
1140 | 0 | self.offset_data() |
1141 | 0 | .read_array(range) |
1142 | 0 | .ok() |
1143 | 0 | .unwrap_or_default() |
1144 | 0 | } |
1145 | | |
1146 | 0 | pub(crate) fn last_glyph_index(&self) -> GlyphId16 { |
1147 | 0 | self.last_glyph_index |
1148 | 0 | } |
1149 | | |
1150 | 0 | pub(crate) fn first_glyph_index(&self) -> GlyphId16 { |
1151 | 0 | self.first_glyph_index |
1152 | 0 | } |
1153 | | |
1154 | 0 | pub fn index_format_byte_range(&self) -> Range<usize> { |
1155 | 0 | let start = 0; |
1156 | 0 | let end = start + u16::RAW_BYTE_LEN; |
1157 | 0 | start..end |
1158 | 0 | } |
1159 | | |
1160 | 0 | pub fn image_format_byte_range(&self) -> Range<usize> { |
1161 | 0 | let start = self.index_format_byte_range().end; |
1162 | 0 | let end = start + u16::RAW_BYTE_LEN; |
1163 | 0 | start..end |
1164 | 0 | } |
1165 | | |
1166 | 0 | pub fn image_data_offset_byte_range(&self) -> Range<usize> { |
1167 | 0 | let start = self.image_format_byte_range().end; |
1168 | 0 | let end = start + u32::RAW_BYTE_LEN; |
1169 | 0 | start..end |
1170 | 0 | } |
1171 | | |
1172 | 0 | pub fn sbit_offsets_byte_range(&self) -> Range<usize> { |
1173 | 0 | let last_glyph_index = self.last_glyph_index(); |
1174 | 0 | let first_glyph_index = self.first_glyph_index(); |
1175 | 0 | let start = self.image_data_offset_byte_range().end; |
1176 | 0 | let end = start |
1177 | 0 | + (transforms::subtract_add_two(last_glyph_index, first_glyph_index)) |
1178 | 0 | .saturating_mul(u16::RAW_BYTE_LEN); |
1179 | 0 | start..end |
1180 | 0 | } |
1181 | | } |
1182 | | |
1183 | | impl Format<u16> for IndexSubtable4<'_> { |
1184 | | const FORMAT: u16 = 4; |
1185 | | } |
1186 | | |
1187 | | impl<'a> MinByteRange<'a> for IndexSubtable4<'a> { |
1188 | 0 | fn min_byte_range(&self) -> Range<usize> { |
1189 | 0 | 0..self.glyph_array_byte_range().end |
1190 | 0 | } |
1191 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
1192 | 0 | let range = self.min_byte_range(); |
1193 | 0 | self.offset_data().as_bytes().get(range).unwrap_or_default() |
1194 | 0 | } |
1195 | | } |
1196 | | |
1197 | | impl ReadArgs for IndexSubtable4<'_> { |
1198 | | type Args = (); |
1199 | | } |
1200 | | |
1201 | | impl<'a> FontRead<'a> for IndexSubtable4<'a> { |
1202 | 0 | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
1203 | | #[allow(clippy::absurd_extreme_comparisons)] |
1204 | 0 | if data.len() < Self::MIN_SIZE { |
1205 | 0 | return Err(ReadError::OutOfBounds); |
1206 | 0 | } |
1207 | 0 | let Some(data) = TableDataRef::new(data.as_bytes()) else { |
1208 | 0 | return Err(ReadError::OutOfBounds); |
1209 | | }; |
1210 | 0 | Ok(Self { data }) |
1211 | 0 | } |
1212 | | } |
1213 | | |
1214 | | /// The fields at the start of the table, which are read directly. |
1215 | | #[derive(Clone, Copy, bytemuck :: AnyBitPattern)] |
1216 | | #[repr(C, packed)] |
1217 | | #[doc(hidden)] |
1218 | | pub struct IndexSubtable4FixedHeader { |
1219 | | pub index_format: BigEndian<u16>, |
1220 | | pub image_format: BigEndian<u16>, |
1221 | | pub image_data_offset: BigEndian<u32>, |
1222 | | pub num_glyphs: BigEndian<u32>, |
1223 | | } |
1224 | | |
1225 | | #[allow(clippy::absurd_extreme_comparisons)] |
1226 | | const _: () = assert!(std::mem::size_of::<IndexSubtable4FixedHeader>() <= IndexSubtable4::MIN_SIZE); |
1227 | | |
1228 | | /// [IndexSubTable4](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#indexsubtable3-variable-metrics-glyphs-with-2-byte-offsets): variable-metrics glyphs with sparse glyph codes. |
1229 | | #[derive(Clone)] |
1230 | | pub struct IndexSubtable4<'a> { |
1231 | | data: TableDataRef<'a, IndexSubtable4FixedHeader>, |
1232 | | } |
1233 | | |
1234 | | #[allow(clippy::needless_lifetimes)] |
1235 | | impl<'a> IndexSubtable4<'a> { |
1236 | | pub const MIN_SIZE: usize = |
1237 | | (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN); |
1238 | | basic_table_impls!(impl_the_methods); |
1239 | | |
1240 | | /// Format of this IndexSubTable. |
1241 | 0 | pub fn index_format(&self) -> u16 { |
1242 | 0 | self.data.header().index_format.get() |
1243 | 0 | } |
1244 | | |
1245 | | /// Format of EBDT image data. |
1246 | 0 | pub fn image_format(&self) -> u16 { |
1247 | 0 | self.data.header().image_format.get() |
1248 | 0 | } |
1249 | | |
1250 | | /// Offset to image data in EBDT table. |
1251 | 0 | pub fn image_data_offset(&self) -> u32 { |
1252 | 0 | self.data.header().image_data_offset.get() |
1253 | 0 | } |
1254 | | |
1255 | | /// Array length. |
1256 | 0 | pub fn num_glyphs(&self) -> u32 { |
1257 | 0 | self.data.header().num_glyphs.get() |
1258 | 0 | } |
1259 | | |
1260 | | /// One per glyph. |
1261 | 0 | pub fn glyph_array(&self) -> &'a [GlyphIdOffsetPair] { |
1262 | 0 | let range = self.glyph_array_byte_range(); |
1263 | 0 | self.offset_data() |
1264 | 0 | .read_array(range) |
1265 | 0 | .ok() |
1266 | 0 | .unwrap_or_default() |
1267 | 0 | } |
1268 | | |
1269 | 0 | pub fn index_format_byte_range(&self) -> Range<usize> { |
1270 | 0 | let start = 0; |
1271 | 0 | let end = start + u16::RAW_BYTE_LEN; |
1272 | 0 | start..end |
1273 | 0 | } |
1274 | | |
1275 | 0 | pub fn image_format_byte_range(&self) -> Range<usize> { |
1276 | 0 | let start = self.index_format_byte_range().end; |
1277 | 0 | let end = start + u16::RAW_BYTE_LEN; |
1278 | 0 | start..end |
1279 | 0 | } |
1280 | | |
1281 | 0 | pub fn image_data_offset_byte_range(&self) -> Range<usize> { |
1282 | 0 | let start = self.image_format_byte_range().end; |
1283 | 0 | let end = start + u32::RAW_BYTE_LEN; |
1284 | 0 | start..end |
1285 | 0 | } |
1286 | | |
1287 | 0 | pub fn num_glyphs_byte_range(&self) -> Range<usize> { |
1288 | 0 | let start = self.image_data_offset_byte_range().end; |
1289 | 0 | let end = start + u32::RAW_BYTE_LEN; |
1290 | 0 | start..end |
1291 | 0 | } |
1292 | | |
1293 | 0 | pub fn glyph_array_byte_range(&self) -> Range<usize> { |
1294 | 0 | let num_glyphs = self.num_glyphs(); |
1295 | 0 | let start = self.num_glyphs_byte_range().end; |
1296 | 0 | let end = start |
1297 | 0 | + (transforms::add(num_glyphs, 1_usize)) |
1298 | 0 | .saturating_mul(GlyphIdOffsetPair::RAW_BYTE_LEN); |
1299 | 0 | start..end |
1300 | 0 | } |
1301 | | } |
1302 | | |
1303 | | /// [GlyphIdOffsetPair](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#glyphidoffsetpair-record) record. |
1304 | | #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] |
1305 | | #[repr(C)] |
1306 | | #[repr(packed)] |
1307 | | pub struct GlyphIdOffsetPair { |
1308 | | /// Glyph ID of glyph present. |
1309 | | pub glyph_id: BigEndian<GlyphId16>, |
1310 | | /// Location in EBDT. |
1311 | | pub sbit_offset: BigEndian<u16>, |
1312 | | } |
1313 | | |
1314 | | impl GlyphIdOffsetPair { |
1315 | | /// Glyph ID of glyph present. |
1316 | 0 | pub fn glyph_id(&self) -> GlyphId16 { |
1317 | 0 | self.glyph_id.get() |
1318 | 0 | } |
1319 | | |
1320 | | /// Location in EBDT. |
1321 | 0 | pub fn sbit_offset(&self) -> u16 { |
1322 | 0 | self.sbit_offset.get() |
1323 | 0 | } |
1324 | | } |
1325 | | |
1326 | | impl FixedSize for GlyphIdOffsetPair { |
1327 | | const RAW_BYTE_LEN: usize = GlyphId16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; |
1328 | | } |
1329 | | |
1330 | | impl Format<u16> for IndexSubtable5<'_> { |
1331 | | const FORMAT: u16 = 5; |
1332 | | } |
1333 | | |
1334 | | impl<'a> MinByteRange<'a> for IndexSubtable5<'a> { |
1335 | 0 | fn min_byte_range(&self) -> Range<usize> { |
1336 | 0 | 0..self.glyph_array_byte_range().end |
1337 | 0 | } |
1338 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
1339 | 0 | let range = self.min_byte_range(); |
1340 | 0 | self.offset_data().as_bytes().get(range).unwrap_or_default() |
1341 | 0 | } |
1342 | | } |
1343 | | |
1344 | | impl ReadArgs for IndexSubtable5<'_> { |
1345 | | type Args = (); |
1346 | | } |
1347 | | |
1348 | | impl<'a> FontRead<'a> for IndexSubtable5<'a> { |
1349 | 0 | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
1350 | | #[allow(clippy::absurd_extreme_comparisons)] |
1351 | 0 | if data.len() < Self::MIN_SIZE { |
1352 | 0 | return Err(ReadError::OutOfBounds); |
1353 | 0 | } |
1354 | 0 | let Some(data) = TableDataRef::new(data.as_bytes()) else { |
1355 | 0 | return Err(ReadError::OutOfBounds); |
1356 | | }; |
1357 | 0 | Ok(Self { data }) |
1358 | 0 | } |
1359 | | } |
1360 | | |
1361 | | /// The fields at the start of the table, which are read directly. |
1362 | | #[derive(Clone, Copy, bytemuck :: AnyBitPattern)] |
1363 | | #[repr(C, packed)] |
1364 | | #[doc(hidden)] |
1365 | | pub struct IndexSubtable5FixedHeader { |
1366 | | pub index_format: BigEndian<u16>, |
1367 | | pub image_format: BigEndian<u16>, |
1368 | | pub image_data_offset: BigEndian<u32>, |
1369 | | pub image_size: BigEndian<u32>, |
1370 | | pub big_metrics: BigGlyphMetrics, |
1371 | | pub num_glyphs: BigEndian<u32>, |
1372 | | } |
1373 | | |
1374 | | #[allow(clippy::absurd_extreme_comparisons)] |
1375 | | const _: () = assert!(std::mem::size_of::<IndexSubtable5FixedHeader>() <= IndexSubtable5::MIN_SIZE); |
1376 | | |
1377 | | /// [IndexSubTable5](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#indexsubtable5-constant-metrics-glyphs-with-sparse-glyph-codes): constant-metrics glyphs with sparse glyph codes |
1378 | | #[derive(Clone)] |
1379 | | pub struct IndexSubtable5<'a> { |
1380 | | data: TableDataRef<'a, IndexSubtable5FixedHeader>, |
1381 | | } |
1382 | | |
1383 | | #[allow(clippy::needless_lifetimes)] |
1384 | | impl<'a> IndexSubtable5<'a> { |
1385 | | pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN |
1386 | | + u16::RAW_BYTE_LEN |
1387 | | + u32::RAW_BYTE_LEN |
1388 | | + u32::RAW_BYTE_LEN |
1389 | | + BigGlyphMetrics::RAW_BYTE_LEN |
1390 | | + u32::RAW_BYTE_LEN); |
1391 | | basic_table_impls!(impl_the_methods); |
1392 | | |
1393 | | /// Format of this IndexSubTable. |
1394 | 0 | pub fn index_format(&self) -> u16 { |
1395 | 0 | self.data.header().index_format.get() |
1396 | 0 | } |
1397 | | |
1398 | | /// Format of EBDT image data. |
1399 | 0 | pub fn image_format(&self) -> u16 { |
1400 | 0 | self.data.header().image_format.get() |
1401 | 0 | } |
1402 | | |
1403 | | /// Offset to image data in EBDT table. |
1404 | 0 | pub fn image_data_offset(&self) -> u32 { |
1405 | 0 | self.data.header().image_data_offset.get() |
1406 | 0 | } |
1407 | | |
1408 | | /// All glyphs have the same data size. |
1409 | 0 | pub fn image_size(&self) -> u32 { |
1410 | 0 | self.data.header().image_size.get() |
1411 | 0 | } |
1412 | | |
1413 | | /// All glyphs have the same metrics. |
1414 | 0 | pub fn big_metrics(&self) -> &'a BigGlyphMetrics { |
1415 | 0 | &self.data.header().big_metrics |
1416 | 0 | } |
1417 | | |
1418 | | /// Array length. |
1419 | 0 | pub fn num_glyphs(&self) -> u32 { |
1420 | 0 | self.data.header().num_glyphs.get() |
1421 | 0 | } |
1422 | | |
1423 | | /// One per glyph, sorted by glyhph ID. |
1424 | 0 | pub fn glyph_array(&self) -> &'a [BigEndian<GlyphId16>] { |
1425 | 0 | let range = self.glyph_array_byte_range(); |
1426 | 0 | self.offset_data() |
1427 | 0 | .read_array(range) |
1428 | 0 | .ok() |
1429 | 0 | .unwrap_or_default() |
1430 | 0 | } |
1431 | | |
1432 | 0 | pub fn index_format_byte_range(&self) -> Range<usize> { |
1433 | 0 | let start = 0; |
1434 | 0 | let end = start + u16::RAW_BYTE_LEN; |
1435 | 0 | start..end |
1436 | 0 | } |
1437 | | |
1438 | 0 | pub fn image_format_byte_range(&self) -> Range<usize> { |
1439 | 0 | let start = self.index_format_byte_range().end; |
1440 | 0 | let end = start + u16::RAW_BYTE_LEN; |
1441 | 0 | start..end |
1442 | 0 | } |
1443 | | |
1444 | 0 | pub fn image_data_offset_byte_range(&self) -> Range<usize> { |
1445 | 0 | let start = self.image_format_byte_range().end; |
1446 | 0 | let end = start + u32::RAW_BYTE_LEN; |
1447 | 0 | start..end |
1448 | 0 | } |
1449 | | |
1450 | 0 | pub fn image_size_byte_range(&self) -> Range<usize> { |
1451 | 0 | let start = self.image_data_offset_byte_range().end; |
1452 | 0 | let end = start + u32::RAW_BYTE_LEN; |
1453 | 0 | start..end |
1454 | 0 | } |
1455 | | |
1456 | 0 | pub fn big_metrics_byte_range(&self) -> Range<usize> { |
1457 | 0 | let start = self.image_size_byte_range().end; |
1458 | 0 | let end = start + BigGlyphMetrics::RAW_BYTE_LEN; |
1459 | 0 | start..end |
1460 | 0 | } |
1461 | | |
1462 | 0 | pub fn num_glyphs_byte_range(&self) -> Range<usize> { |
1463 | 0 | let start = self.big_metrics_byte_range().end; |
1464 | 0 | let end = start + u32::RAW_BYTE_LEN; |
1465 | 0 | start..end |
1466 | 0 | } |
1467 | | |
1468 | 0 | pub fn glyph_array_byte_range(&self) -> Range<usize> { |
1469 | 0 | let num_glyphs = self.num_glyphs(); |
1470 | 0 | let start = self.num_glyphs_byte_range().end; |
1471 | 0 | let end = |
1472 | 0 | start + (transforms::to_usize(num_glyphs)).saturating_mul(GlyphId16::RAW_BYTE_LEN); |
1473 | 0 | start..end |
1474 | 0 | } |
1475 | | } |
1476 | | |
1477 | | /// [EbdtComponent](https://learn.microsoft.com/en-us/typography/opentype/spec/ebdt#ebdtcomponent-record) record. |
1478 | | #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] |
1479 | | #[repr(C)] |
1480 | | #[repr(packed)] |
1481 | | pub struct BdtComponent { |
1482 | | /// Component glyph ID. |
1483 | | pub glyph_id: BigEndian<GlyphId16>, |
1484 | | /// Position of component left. |
1485 | | pub x_offset: BigEndian<i8>, |
1486 | | /// Position of component top. |
1487 | | pub y_offset: BigEndian<i8>, |
1488 | | } |
1489 | | |
1490 | | impl BdtComponent { |
1491 | | /// Component glyph ID. |
1492 | 0 | pub fn glyph_id(&self) -> GlyphId16 { |
1493 | 0 | self.glyph_id.get() |
1494 | 0 | } |
1495 | | |
1496 | | /// Position of component left. |
1497 | 0 | pub fn x_offset(&self) -> i8 { |
1498 | 0 | self.x_offset.get() |
1499 | 0 | } |
1500 | | |
1501 | | /// Position of component top. |
1502 | 0 | pub fn y_offset(&self) -> i8 { |
1503 | 0 | self.y_offset.get() |
1504 | 0 | } |
1505 | | } |
1506 | | |
1507 | | impl FixedSize for BdtComponent { |
1508 | | const RAW_BYTE_LEN: usize = GlyphId16::RAW_BYTE_LEN + i8::RAW_BYTE_LEN + i8::RAW_BYTE_LEN; |
1509 | | } |