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)] 10 #[repr(C)] 11 #[repr(packed)] 12 pub struct BitmapSize { 13 /// Offset to index subtable from beginning of EBLC/CBLC. 14 pub index_subtable_array_offset: BigEndian<u32>, 15 /// Number of bytes in corresponding index subtables and array. 16 pub index_tables_size: BigEndian<u32>, 17 /// There is an index subtable for each range or format change. 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<GlyphId>, 27 /// Highest glyph index for this size. 28 pub end_glyph_index: BigEndian<GlyphId>, 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 index subtable from beginning of EBLC/CBLC. index_subtable_array_offset(&self) -> u3242 pub fn index_subtable_array_offset(&self) -> u32 { 43 self.index_subtable_array_offset.get() 44 } 45 46 /// Number of bytes in corresponding index subtables and array. index_tables_size(&self) -> u3247 pub fn index_tables_size(&self) -> u32 { 48 self.index_tables_size.get() 49 } 50 51 /// There is an index subtable for each range or format change. number_of_index_subtables(&self) -> u3252 pub fn number_of_index_subtables(&self) -> u32 { 53 self.number_of_index_subtables.get() 54 } 55 56 /// Not used; set to 0. color_ref(&self) -> u3257 pub fn color_ref(&self) -> u32 { 58 self.color_ref.get() 59 } 60 61 /// Line metrics for text rendered horizontally. hori(&self) -> &SbitLineMetrics62 pub fn hori(&self) -> &SbitLineMetrics { 63 &self.hori 64 } 65 66 /// Line metrics for text rendered vertically. vert(&self) -> &SbitLineMetrics67 pub fn vert(&self) -> &SbitLineMetrics { 68 &self.vert 69 } 70 71 /// Lowest glyph index for this size. start_glyph_index(&self) -> GlyphId72 pub fn start_glyph_index(&self) -> GlyphId { 73 self.start_glyph_index.get() 74 } 75 76 /// Highest glyph index for this size. end_glyph_index(&self) -> GlyphId77 pub fn end_glyph_index(&self) -> GlyphId { 78 self.end_glyph_index.get() 79 } 80 81 /// Horizontal pixels per em. ppem_x(&self) -> u882 pub fn ppem_x(&self) -> u8 { 83 self.ppem_x 84 } 85 86 /// Vertical pixels per em. ppem_y(&self) -> u887 pub fn ppem_y(&self) -> u8 { 88 self.ppem_y 89 } 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). bit_depth(&self) -> u893 pub fn bit_depth(&self) -> u8 { 94 self.bit_depth 95 } 96 97 /// Vertical or horizontal. flags(&self) -> BitmapFlags98 pub fn flags(&self) -> BitmapFlags { 99 self.flags.get() 100 } 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 + GlyphId::RAW_BYTE_LEN 111 + GlyphId::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 impl sealed::Sealed for BitmapSize {} 119 120 /// SAFETY: see the [`FromBytes`] trait documentation. 121 unsafe impl FromBytes for BitmapSize { this_trait_should_only_be_implemented_in_generated_code()122 fn this_trait_should_only_be_implemented_in_generated_code() {} 123 } 124 125 #[cfg(feature = "traversal")] 126 impl<'a> SomeRecord<'a> for BitmapSize { traverse(self, data: FontData<'a>) -> RecordResolver<'a>127 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 128 RecordResolver { 129 name: "BitmapSize", 130 get_field: Box::new(move |idx, _data| match idx { 131 0usize => Some(Field::new( 132 "index_subtable_array_offset", 133 self.index_subtable_array_offset(), 134 )), 135 1usize => Some(Field::new("index_tables_size", self.index_tables_size())), 136 2usize => Some(Field::new( 137 "number_of_index_subtables", 138 self.number_of_index_subtables(), 139 )), 140 3usize => Some(Field::new("color_ref", self.color_ref())), 141 4usize => Some(Field::new("hori", self.hori().traversal_type(_data))), 142 5usize => Some(Field::new("vert", self.vert().traversal_type(_data))), 143 6usize => Some(Field::new("start_glyph_index", self.start_glyph_index())), 144 7usize => Some(Field::new("end_glyph_index", self.end_glyph_index())), 145 8usize => Some(Field::new("ppem_x", self.ppem_x())), 146 9usize => Some(Field::new("ppem_y", self.ppem_y())), 147 10usize => Some(Field::new("bit_depth", self.bit_depth())), 148 11usize => Some(Field::new("flags", self.flags())), 149 _ => None, 150 }), 151 data, 152 } 153 } 154 } 155 156 /// [SbitLineMetrics](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#sbitlinemetrics-record) record. 157 #[derive(Clone, Debug, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 158 #[repr(C)] 159 #[repr(packed)] 160 pub struct SbitLineMetrics { 161 pub ascender: BigEndian<i8>, 162 pub descender: BigEndian<i8>, 163 pub width_max: u8, 164 pub caret_slope_numerator: BigEndian<i8>, 165 pub caret_slope_denominator: u8, 166 pub caret_offset: BigEndian<i8>, 167 pub min_origin_sb: BigEndian<i8>, 168 pub min_advance_sb: BigEndian<i8>, 169 pub max_before_bl: BigEndian<i8>, 170 pub min_after_bl: BigEndian<i8>, 171 pub pad1: BigEndian<i8>, 172 pub pad2: BigEndian<i8>, 173 } 174 175 impl SbitLineMetrics { ascender(&self) -> i8176 pub fn ascender(&self) -> i8 { 177 self.ascender.get() 178 } 179 descender(&self) -> i8180 pub fn descender(&self) -> i8 { 181 self.descender.get() 182 } 183 width_max(&self) -> u8184 pub fn width_max(&self) -> u8 { 185 self.width_max 186 } 187 caret_slope_numerator(&self) -> i8188 pub fn caret_slope_numerator(&self) -> i8 { 189 self.caret_slope_numerator.get() 190 } 191 caret_slope_denominator(&self) -> u8192 pub fn caret_slope_denominator(&self) -> u8 { 193 self.caret_slope_denominator 194 } 195 caret_offset(&self) -> i8196 pub fn caret_offset(&self) -> i8 { 197 self.caret_offset.get() 198 } 199 min_origin_sb(&self) -> i8200 pub fn min_origin_sb(&self) -> i8 { 201 self.min_origin_sb.get() 202 } 203 min_advance_sb(&self) -> i8204 pub fn min_advance_sb(&self) -> i8 { 205 self.min_advance_sb.get() 206 } 207 max_before_bl(&self) -> i8208 pub fn max_before_bl(&self) -> i8 { 209 self.max_before_bl.get() 210 } 211 min_after_bl(&self) -> i8212 pub fn min_after_bl(&self) -> i8 { 213 self.min_after_bl.get() 214 } 215 pad1(&self) -> i8216 pub fn pad1(&self) -> i8 { 217 self.pad1.get() 218 } 219 pad2(&self) -> i8220 pub fn pad2(&self) -> i8 { 221 self.pad2.get() 222 } 223 } 224 225 impl FixedSize for SbitLineMetrics { 226 const RAW_BYTE_LEN: usize = i8::RAW_BYTE_LEN 227 + i8::RAW_BYTE_LEN 228 + u8::RAW_BYTE_LEN 229 + i8::RAW_BYTE_LEN 230 + u8::RAW_BYTE_LEN 231 + i8::RAW_BYTE_LEN 232 + i8::RAW_BYTE_LEN 233 + i8::RAW_BYTE_LEN 234 + i8::RAW_BYTE_LEN 235 + i8::RAW_BYTE_LEN 236 + i8::RAW_BYTE_LEN 237 + i8::RAW_BYTE_LEN; 238 } 239 240 impl sealed::Sealed for SbitLineMetrics {} 241 242 /// SAFETY: see the [`FromBytes`] trait documentation. 243 unsafe impl FromBytes for SbitLineMetrics { this_trait_should_only_be_implemented_in_generated_code()244 fn this_trait_should_only_be_implemented_in_generated_code() {} 245 } 246 247 #[cfg(feature = "traversal")] 248 impl<'a> SomeRecord<'a> for SbitLineMetrics { traverse(self, data: FontData<'a>) -> RecordResolver<'a>249 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 250 RecordResolver { 251 name: "SbitLineMetrics", 252 get_field: Box::new(move |idx, _data| match idx { 253 0usize => Some(Field::new("ascender", self.ascender())), 254 1usize => Some(Field::new("descender", self.descender())), 255 2usize => Some(Field::new("width_max", self.width_max())), 256 3usize => Some(Field::new( 257 "caret_slope_numerator", 258 self.caret_slope_numerator(), 259 )), 260 4usize => Some(Field::new( 261 "caret_slope_denominator", 262 self.caret_slope_denominator(), 263 )), 264 5usize => Some(Field::new("caret_offset", self.caret_offset())), 265 6usize => Some(Field::new("min_origin_sb", self.min_origin_sb())), 266 7usize => Some(Field::new("min_advance_sb", self.min_advance_sb())), 267 8usize => Some(Field::new("max_before_bl", self.max_before_bl())), 268 9usize => Some(Field::new("min_after_bl", self.min_after_bl())), 269 10usize => Some(Field::new("pad1", self.pad1())), 270 11usize => Some(Field::new("pad2", self.pad2())), 271 _ => None, 272 }), 273 data, 274 } 275 } 276 } 277 278 /// [Bitmap flags](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#bitmap-flags). 279 #[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] 280 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 281 pub struct BitmapFlags { 282 bits: u8, 283 } 284 285 impl BitmapFlags { 286 /// Horizontal 287 pub const HORIZONTAL_METRICS: Self = Self { bits: 0x01 }; 288 289 /// Vertical 290 pub const VERTICAL_METRICS: Self = Self { bits: 0x02 }; 291 } 292 293 impl BitmapFlags { 294 /// Returns an empty set of flags. 295 #[inline] empty() -> Self296 pub const fn empty() -> Self { 297 Self { bits: 0 } 298 } 299 300 /// Returns the set containing all flags. 301 #[inline] all() -> Self302 pub const fn all() -> Self { 303 Self { 304 bits: Self::HORIZONTAL_METRICS.bits | Self::VERTICAL_METRICS.bits, 305 } 306 } 307 308 /// Returns the raw value of the flags currently stored. 309 #[inline] bits(&self) -> u8310 pub const fn bits(&self) -> u8 { 311 self.bits 312 } 313 314 /// Convert from underlying bit representation, unless that 315 /// representation contains bits that do not correspond to a flag. 316 #[inline] from_bits(bits: u8) -> Option<Self>317 pub const fn from_bits(bits: u8) -> Option<Self> { 318 if (bits & !Self::all().bits()) == 0 { 319 Some(Self { bits }) 320 } else { 321 None 322 } 323 } 324 325 /// Convert from underlying bit representation, dropping any bits 326 /// that do not correspond to flags. 327 #[inline] from_bits_truncate(bits: u8) -> Self328 pub const fn from_bits_truncate(bits: u8) -> Self { 329 Self { 330 bits: bits & Self::all().bits, 331 } 332 } 333 334 /// Returns `true` if no flags are currently stored. 335 #[inline] is_empty(&self) -> bool336 pub const fn is_empty(&self) -> bool { 337 self.bits() == Self::empty().bits() 338 } 339 340 /// Returns `true` if there are flags common to both `self` and `other`. 341 #[inline] intersects(&self, other: Self) -> bool342 pub const fn intersects(&self, other: Self) -> bool { 343 !(Self { 344 bits: self.bits & other.bits, 345 }) 346 .is_empty() 347 } 348 349 /// Returns `true` if all of the flags in `other` are contained within `self`. 350 #[inline] contains(&self, other: Self) -> bool351 pub const fn contains(&self, other: Self) -> bool { 352 (self.bits & other.bits) == other.bits 353 } 354 355 /// Inserts the specified flags in-place. 356 #[inline] insert(&mut self, other: Self)357 pub fn insert(&mut self, other: Self) { 358 self.bits |= other.bits; 359 } 360 361 /// Removes the specified flags in-place. 362 #[inline] remove(&mut self, other: Self)363 pub fn remove(&mut self, other: Self) { 364 self.bits &= !other.bits; 365 } 366 367 /// Toggles the specified flags in-place. 368 #[inline] toggle(&mut self, other: Self)369 pub fn toggle(&mut self, other: Self) { 370 self.bits ^= other.bits; 371 } 372 373 /// Returns the intersection between the flags in `self` and 374 /// `other`. 375 /// 376 /// Specifically, the returned set contains only the flags which are 377 /// present in *both* `self` *and* `other`. 378 /// 379 /// This is equivalent to using the `&` operator (e.g. 380 /// [`ops::BitAnd`]), as in `flags & other`. 381 /// 382 /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html 383 #[inline] 384 #[must_use] intersection(self, other: Self) -> Self385 pub const fn intersection(self, other: Self) -> Self { 386 Self { 387 bits: self.bits & other.bits, 388 } 389 } 390 391 /// Returns the union of between the flags in `self` and `other`. 392 /// 393 /// Specifically, the returned set contains all flags which are 394 /// present in *either* `self` *or* `other`, including any which are 395 /// present in both. 396 /// 397 /// This is equivalent to using the `|` operator (e.g. 398 /// [`ops::BitOr`]), as in `flags | other`. 399 /// 400 /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html 401 #[inline] 402 #[must_use] union(self, other: Self) -> Self403 pub const fn union(self, other: Self) -> Self { 404 Self { 405 bits: self.bits | other.bits, 406 } 407 } 408 409 /// Returns the difference between the flags in `self` and `other`. 410 /// 411 /// Specifically, the returned set contains all flags present in 412 /// `self`, except for the ones present in `other`. 413 /// 414 /// It is also conceptually equivalent to the "bit-clear" operation: 415 /// `flags & !other` (and this syntax is also supported). 416 /// 417 /// This is equivalent to using the `-` operator (e.g. 418 /// [`ops::Sub`]), as in `flags - other`. 419 /// 420 /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html 421 #[inline] 422 #[must_use] difference(self, other: Self) -> Self423 pub const fn difference(self, other: Self) -> Self { 424 Self { 425 bits: self.bits & !other.bits, 426 } 427 } 428 } 429 430 impl std::ops::BitOr for BitmapFlags { 431 type Output = Self; 432 433 /// Returns the union of the two sets of flags. 434 #[inline] bitor(self, other: BitmapFlags) -> Self435 fn bitor(self, other: BitmapFlags) -> Self { 436 Self { 437 bits: self.bits | other.bits, 438 } 439 } 440 } 441 442 impl std::ops::BitOrAssign for BitmapFlags { 443 /// Adds the set of flags. 444 #[inline] bitor_assign(&mut self, other: Self)445 fn bitor_assign(&mut self, other: Self) { 446 self.bits |= other.bits; 447 } 448 } 449 450 impl std::ops::BitXor for BitmapFlags { 451 type Output = Self; 452 453 /// Returns the left flags, but with all the right flags toggled. 454 #[inline] bitxor(self, other: Self) -> Self455 fn bitxor(self, other: Self) -> Self { 456 Self { 457 bits: self.bits ^ other.bits, 458 } 459 } 460 } 461 462 impl std::ops::BitXorAssign for BitmapFlags { 463 /// Toggles the set of flags. 464 #[inline] bitxor_assign(&mut self, other: Self)465 fn bitxor_assign(&mut self, other: Self) { 466 self.bits ^= other.bits; 467 } 468 } 469 470 impl std::ops::BitAnd for BitmapFlags { 471 type Output = Self; 472 473 /// Returns the intersection between the two sets of flags. 474 #[inline] bitand(self, other: Self) -> Self475 fn bitand(self, other: Self) -> Self { 476 Self { 477 bits: self.bits & other.bits, 478 } 479 } 480 } 481 482 impl std::ops::BitAndAssign for BitmapFlags { 483 /// Disables all flags disabled in the set. 484 #[inline] bitand_assign(&mut self, other: Self)485 fn bitand_assign(&mut self, other: Self) { 486 self.bits &= other.bits; 487 } 488 } 489 490 impl std::ops::Sub for BitmapFlags { 491 type Output = Self; 492 493 /// Returns the set difference of the two sets of flags. 494 #[inline] sub(self, other: Self) -> Self495 fn sub(self, other: Self) -> Self { 496 Self { 497 bits: self.bits & !other.bits, 498 } 499 } 500 } 501 502 impl std::ops::SubAssign for BitmapFlags { 503 /// Disables all flags enabled in the set. 504 #[inline] sub_assign(&mut self, other: Self)505 fn sub_assign(&mut self, other: Self) { 506 self.bits &= !other.bits; 507 } 508 } 509 510 impl std::ops::Not for BitmapFlags { 511 type Output = Self; 512 513 /// Returns the complement of this set of flags. 514 #[inline] not(self) -> Self515 fn not(self) -> Self { 516 Self { bits: !self.bits } & Self::all() 517 } 518 } 519 520 impl std::fmt::Debug for BitmapFlags { fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result521 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 522 let members: &[(&str, Self)] = &[ 523 ("HORIZONTAL_METRICS", Self::HORIZONTAL_METRICS), 524 ("VERTICAL_METRICS", Self::VERTICAL_METRICS), 525 ]; 526 let mut first = true; 527 for (name, value) in members { 528 if self.contains(*value) { 529 if !first { 530 f.write_str(" | ")?; 531 } 532 first = false; 533 f.write_str(name)?; 534 } 535 } 536 if first { 537 f.write_str("(empty)")?; 538 } 539 Ok(()) 540 } 541 } 542 543 impl std::fmt::Binary for BitmapFlags { fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result544 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 545 std::fmt::Binary::fmt(&self.bits, f) 546 } 547 } 548 549 impl std::fmt::Octal for BitmapFlags { fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result550 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 551 std::fmt::Octal::fmt(&self.bits, f) 552 } 553 } 554 555 impl std::fmt::LowerHex for BitmapFlags { fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result556 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 557 std::fmt::LowerHex::fmt(&self.bits, f) 558 } 559 } 560 561 impl std::fmt::UpperHex for BitmapFlags { fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result562 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 563 std::fmt::UpperHex::fmt(&self.bits, f) 564 } 565 } 566 567 impl font_types::Scalar for BitmapFlags { 568 type Raw = <u8 as font_types::Scalar>::Raw; to_raw(self) -> Self::Raw569 fn to_raw(self) -> Self::Raw { 570 self.bits().to_raw() 571 } from_raw(raw: Self::Raw) -> Self572 fn from_raw(raw: Self::Raw) -> Self { 573 let t = <u8>::from_raw(raw); 574 Self::from_bits_truncate(t) 575 } 576 } 577 578 #[cfg(feature = "traversal")] 579 impl<'a> From<BitmapFlags> for FieldType<'a> { from(src: BitmapFlags) -> FieldType<'a>580 fn from(src: BitmapFlags) -> FieldType<'a> { 581 src.bits().into() 582 } 583 } 584 585 /// [BigGlyphMetrics](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#bigglyphmetrics) record. 586 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 587 #[repr(C)] 588 #[repr(packed)] 589 pub struct BigGlyphMetrics { 590 /// Number of rows of data. 591 pub height: u8, 592 /// Number of columns of data. 593 pub width: u8, 594 /// Distance in pixels from the horizontal origin to the left edge of the bitmap. 595 pub hori_bearing_x: BigEndian<i8>, 596 /// Distance in pixels from the horizontal origin to the top edge of the bitmap. 597 pub hori_bearing_y: BigEndian<i8>, 598 /// Horizontal advance width in pixels. 599 pub hori_advance: u8, 600 /// Distance in pixels from the vertical origin to the left edge of the bitmap. 601 pub vert_bearing_x: BigEndian<i8>, 602 /// Distance in pixels from the vertical origin to the top edge of the bitmap. 603 pub vert_bearing_y: BigEndian<i8>, 604 /// Vertical advance width in pixels. 605 pub vert_advance: u8, 606 } 607 608 impl BigGlyphMetrics { 609 /// Number of rows of data. height(&self) -> u8610 pub fn height(&self) -> u8 { 611 self.height 612 } 613 614 /// Number of columns of data. width(&self) -> u8615 pub fn width(&self) -> u8 { 616 self.width 617 } 618 619 /// Distance in pixels from the horizontal origin to the left edge of the bitmap. hori_bearing_x(&self) -> i8620 pub fn hori_bearing_x(&self) -> i8 { 621 self.hori_bearing_x.get() 622 } 623 624 /// Distance in pixels from the horizontal origin to the top edge of the bitmap. hori_bearing_y(&self) -> i8625 pub fn hori_bearing_y(&self) -> i8 { 626 self.hori_bearing_y.get() 627 } 628 629 /// Horizontal advance width in pixels. hori_advance(&self) -> u8630 pub fn hori_advance(&self) -> u8 { 631 self.hori_advance 632 } 633 634 /// Distance in pixels from the vertical origin to the left edge of the bitmap. vert_bearing_x(&self) -> i8635 pub fn vert_bearing_x(&self) -> i8 { 636 self.vert_bearing_x.get() 637 } 638 639 /// Distance in pixels from the vertical origin to the top edge of the bitmap. vert_bearing_y(&self) -> i8640 pub fn vert_bearing_y(&self) -> i8 { 641 self.vert_bearing_y.get() 642 } 643 644 /// Vertical advance width in pixels. vert_advance(&self) -> u8645 pub fn vert_advance(&self) -> u8 { 646 self.vert_advance 647 } 648 } 649 650 impl FixedSize for BigGlyphMetrics { 651 const RAW_BYTE_LEN: usize = u8::RAW_BYTE_LEN 652 + u8::RAW_BYTE_LEN 653 + i8::RAW_BYTE_LEN 654 + i8::RAW_BYTE_LEN 655 + u8::RAW_BYTE_LEN 656 + i8::RAW_BYTE_LEN 657 + i8::RAW_BYTE_LEN 658 + u8::RAW_BYTE_LEN; 659 } 660 661 impl sealed::Sealed for BigGlyphMetrics {} 662 663 /// SAFETY: see the [`FromBytes`] trait documentation. 664 unsafe impl FromBytes for BigGlyphMetrics { this_trait_should_only_be_implemented_in_generated_code()665 fn this_trait_should_only_be_implemented_in_generated_code() {} 666 } 667 668 #[cfg(feature = "traversal")] 669 impl<'a> SomeRecord<'a> for BigGlyphMetrics { traverse(self, data: FontData<'a>) -> RecordResolver<'a>670 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 671 RecordResolver { 672 name: "BigGlyphMetrics", 673 get_field: Box::new(move |idx, _data| match idx { 674 0usize => Some(Field::new("height", self.height())), 675 1usize => Some(Field::new("width", self.width())), 676 2usize => Some(Field::new("hori_bearing_x", self.hori_bearing_x())), 677 3usize => Some(Field::new("hori_bearing_y", self.hori_bearing_y())), 678 4usize => Some(Field::new("hori_advance", self.hori_advance())), 679 5usize => Some(Field::new("vert_bearing_x", self.vert_bearing_x())), 680 6usize => Some(Field::new("vert_bearing_y", self.vert_bearing_y())), 681 7usize => Some(Field::new("vert_advance", self.vert_advance())), 682 _ => None, 683 }), 684 data, 685 } 686 } 687 } 688 689 /// [SmallGlyphMetrics](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#smallglyphmetrics) record. 690 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 691 #[repr(C)] 692 #[repr(packed)] 693 pub struct SmallGlyphMetrics { 694 /// Number of rows of data. 695 pub height: u8, 696 /// Number of columns of data. 697 pub width: u8, 698 /// 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). 699 pub bearing_x: BigEndian<i8>, 700 /// 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). 701 pub bearing_y: BigEndian<i8>, 702 /// Horizontal or vertical advance width in pixels. 703 pub advance: u8, 704 } 705 706 impl SmallGlyphMetrics { 707 /// Number of rows of data. height(&self) -> u8708 pub fn height(&self) -> u8 { 709 self.height 710 } 711 712 /// Number of columns of data. width(&self) -> u8713 pub fn width(&self) -> u8 { 714 self.width 715 } 716 717 /// 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). bearing_x(&self) -> i8718 pub fn bearing_x(&self) -> i8 { 719 self.bearing_x.get() 720 } 721 722 /// 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). bearing_y(&self) -> i8723 pub fn bearing_y(&self) -> i8 { 724 self.bearing_y.get() 725 } 726 727 /// Horizontal or vertical advance width in pixels. advance(&self) -> u8728 pub fn advance(&self) -> u8 { 729 self.advance 730 } 731 } 732 733 impl FixedSize for SmallGlyphMetrics { 734 const RAW_BYTE_LEN: usize = u8::RAW_BYTE_LEN 735 + u8::RAW_BYTE_LEN 736 + i8::RAW_BYTE_LEN 737 + i8::RAW_BYTE_LEN 738 + u8::RAW_BYTE_LEN; 739 } 740 741 impl sealed::Sealed for SmallGlyphMetrics {} 742 743 /// SAFETY: see the [`FromBytes`] trait documentation. 744 unsafe impl FromBytes for SmallGlyphMetrics { this_trait_should_only_be_implemented_in_generated_code()745 fn this_trait_should_only_be_implemented_in_generated_code() {} 746 } 747 748 #[cfg(feature = "traversal")] 749 impl<'a> SomeRecord<'a> for SmallGlyphMetrics { traverse(self, data: FontData<'a>) -> RecordResolver<'a>750 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 751 RecordResolver { 752 name: "SmallGlyphMetrics", 753 get_field: Box::new(move |idx, _data| match idx { 754 0usize => Some(Field::new("height", self.height())), 755 1usize => Some(Field::new("width", self.width())), 756 2usize => Some(Field::new("bearing_x", self.bearing_x())), 757 3usize => Some(Field::new("bearing_y", self.bearing_y())), 758 4usize => Some(Field::new("advance", self.advance())), 759 _ => None, 760 }), 761 data, 762 } 763 } 764 } 765 766 /// [IndexSubtableArray](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#indexsubtablearray) table. 767 #[derive(Debug, Clone, Copy)] 768 #[doc(hidden)] 769 pub struct IndexSubtableArrayMarker {} 770 771 impl IndexSubtableArrayMarker { first_glyph_index_byte_range(&self) -> Range<usize>772 fn first_glyph_index_byte_range(&self) -> Range<usize> { 773 let start = 0; 774 start..start + GlyphId::RAW_BYTE_LEN 775 } last_glyph_index_byte_range(&self) -> Range<usize>776 fn last_glyph_index_byte_range(&self) -> Range<usize> { 777 let start = self.first_glyph_index_byte_range().end; 778 start..start + GlyphId::RAW_BYTE_LEN 779 } additional_offset_to_index_subtable_byte_range(&self) -> Range<usize>780 fn additional_offset_to_index_subtable_byte_range(&self) -> Range<usize> { 781 let start = self.last_glyph_index_byte_range().end; 782 start..start + u32::RAW_BYTE_LEN 783 } 784 } 785 786 impl<'a> FontRead<'a> for IndexSubtableArray<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>787 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 788 let mut cursor = data.cursor(); 789 cursor.advance::<GlyphId>(); 790 cursor.advance::<GlyphId>(); 791 cursor.advance::<u32>(); 792 cursor.finish(IndexSubtableArrayMarker {}) 793 } 794 } 795 796 /// [IndexSubtableArray](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#indexsubtablearray) table. 797 pub type IndexSubtableArray<'a> = TableRef<'a, IndexSubtableArrayMarker>; 798 799 impl<'a> IndexSubtableArray<'a> { 800 /// First glyph ID of this range. first_glyph_index(&self) -> GlyphId801 pub fn first_glyph_index(&self) -> GlyphId { 802 let range = self.shape.first_glyph_index_byte_range(); 803 self.data.read_at(range.start).unwrap() 804 } 805 806 /// Last glyph ID of this range (inclusive). last_glyph_index(&self) -> GlyphId807 pub fn last_glyph_index(&self) -> GlyphId { 808 let range = self.shape.last_glyph_index_byte_range(); 809 self.data.read_at(range.start).unwrap() 810 } 811 812 /// Add to indexSubTableArrayOffset to get offset from beginning of EBLC. additional_offset_to_index_subtable(&self) -> u32813 pub fn additional_offset_to_index_subtable(&self) -> u32 { 814 let range = self.shape.additional_offset_to_index_subtable_byte_range(); 815 self.data.read_at(range.start).unwrap() 816 } 817 } 818 819 #[cfg(feature = "traversal")] 820 impl<'a> SomeTable<'a> for IndexSubtableArray<'a> { type_name(&self) -> &str821 fn type_name(&self) -> &str { 822 "IndexSubtableArray" 823 } get_field(&self, idx: usize) -> Option<Field<'a>>824 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 825 match idx { 826 0usize => Some(Field::new("first_glyph_index", self.first_glyph_index())), 827 1usize => Some(Field::new("last_glyph_index", self.last_glyph_index())), 828 2usize => Some(Field::new( 829 "additional_offset_to_index_subtable", 830 self.additional_offset_to_index_subtable(), 831 )), 832 _ => None, 833 } 834 } 835 } 836 837 #[cfg(feature = "traversal")] 838 impl<'a> std::fmt::Debug for IndexSubtableArray<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result839 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 840 (self as &dyn SomeTable<'a>).fmt(f) 841 } 842 } 843 844 /// [IndexSubtables](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#indexsubtables) format type. 845 #[derive(Clone)] 846 pub enum IndexSubtable<'a> { 847 Format1(IndexSubtable1<'a>), 848 Format2(IndexSubtable2<'a>), 849 Format3(IndexSubtable3<'a>), 850 Format4(IndexSubtable4<'a>), 851 Format5(IndexSubtable5<'a>), 852 } 853 854 impl<'a> IndexSubtable<'a> { 855 /// Format of this IndexSubTable. index_format(&self) -> u16856 pub fn index_format(&self) -> u16 { 857 match self { 858 Self::Format1(item) => item.index_format(), 859 Self::Format2(item) => item.index_format(), 860 Self::Format3(item) => item.index_format(), 861 Self::Format4(item) => item.index_format(), 862 Self::Format5(item) => item.index_format(), 863 } 864 } 865 866 /// Format of EBDT image data. image_format(&self) -> u16867 pub fn image_format(&self) -> u16 { 868 match self { 869 Self::Format1(item) => item.image_format(), 870 Self::Format2(item) => item.image_format(), 871 Self::Format3(item) => item.image_format(), 872 Self::Format4(item) => item.image_format(), 873 Self::Format5(item) => item.image_format(), 874 } 875 } 876 877 /// Offset to image data in EBDT table. image_data_offset(&self) -> u32878 pub fn image_data_offset(&self) -> u32 { 879 match self { 880 Self::Format1(item) => item.image_data_offset(), 881 Self::Format2(item) => item.image_data_offset(), 882 Self::Format3(item) => item.image_data_offset(), 883 Self::Format4(item) => item.image_data_offset(), 884 Self::Format5(item) => item.image_data_offset(), 885 } 886 } 887 } 888 889 impl<'a> FontRead<'a> for IndexSubtable<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>890 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 891 let format: u16 = data.read_at(0usize)?; 892 match format { 893 IndexSubtable1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)), 894 IndexSubtable2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)), 895 IndexSubtable3Marker::FORMAT => Ok(Self::Format3(FontRead::read(data)?)), 896 IndexSubtable4Marker::FORMAT => Ok(Self::Format4(FontRead::read(data)?)), 897 IndexSubtable5Marker::FORMAT => Ok(Self::Format5(FontRead::read(data)?)), 898 other => Err(ReadError::InvalidFormat(other.into())), 899 } 900 } 901 } 902 903 #[cfg(feature = "traversal")] 904 impl<'a> IndexSubtable<'a> { dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>905 fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> { 906 match self { 907 Self::Format1(table) => table, 908 Self::Format2(table) => table, 909 Self::Format3(table) => table, 910 Self::Format4(table) => table, 911 Self::Format5(table) => table, 912 } 913 } 914 } 915 916 #[cfg(feature = "traversal")] 917 impl<'a> std::fmt::Debug for IndexSubtable<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result918 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 919 self.dyn_inner().fmt(f) 920 } 921 } 922 923 #[cfg(feature = "traversal")] 924 impl<'a> SomeTable<'a> for IndexSubtable<'a> { type_name(&self) -> &str925 fn type_name(&self) -> &str { 926 self.dyn_inner().type_name() 927 } get_field(&self, idx: usize) -> Option<Field<'a>>928 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 929 self.dyn_inner().get_field(idx) 930 } 931 } 932 933 impl Format<u16> for IndexSubtable1Marker { 934 const FORMAT: u16 = 1; 935 } 936 937 /// [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. 938 #[derive(Debug, Clone, Copy)] 939 #[doc(hidden)] 940 pub struct IndexSubtable1Marker { 941 sbit_offsets_byte_len: usize, 942 } 943 944 impl IndexSubtable1Marker { index_format_byte_range(&self) -> Range<usize>945 fn index_format_byte_range(&self) -> Range<usize> { 946 let start = 0; 947 start..start + u16::RAW_BYTE_LEN 948 } image_format_byte_range(&self) -> Range<usize>949 fn image_format_byte_range(&self) -> Range<usize> { 950 let start = self.index_format_byte_range().end; 951 start..start + u16::RAW_BYTE_LEN 952 } image_data_offset_byte_range(&self) -> Range<usize>953 fn image_data_offset_byte_range(&self) -> Range<usize> { 954 let start = self.image_format_byte_range().end; 955 start..start + u32::RAW_BYTE_LEN 956 } sbit_offsets_byte_range(&self) -> Range<usize>957 fn sbit_offsets_byte_range(&self) -> Range<usize> { 958 let start = self.image_data_offset_byte_range().end; 959 start..start + self.sbit_offsets_byte_len 960 } 961 } 962 963 impl<'a> FontRead<'a> for IndexSubtable1<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>964 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 965 let mut cursor = data.cursor(); 966 cursor.advance::<u16>(); 967 cursor.advance::<u16>(); 968 cursor.advance::<u32>(); 969 let sbit_offsets_byte_len = 970 cursor.remaining_bytes() / u32::RAW_BYTE_LEN * u32::RAW_BYTE_LEN; 971 cursor.advance_by(sbit_offsets_byte_len); 972 cursor.finish(IndexSubtable1Marker { 973 sbit_offsets_byte_len, 974 }) 975 } 976 } 977 978 /// [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. 979 pub type IndexSubtable1<'a> = TableRef<'a, IndexSubtable1Marker>; 980 981 impl<'a> IndexSubtable1<'a> { 982 /// Format of this IndexSubTable. index_format(&self) -> u16983 pub fn index_format(&self) -> u16 { 984 let range = self.shape.index_format_byte_range(); 985 self.data.read_at(range.start).unwrap() 986 } 987 988 /// Format of EBDT image data. image_format(&self) -> u16989 pub fn image_format(&self) -> u16 { 990 let range = self.shape.image_format_byte_range(); 991 self.data.read_at(range.start).unwrap() 992 } 993 994 /// Offset to image data in EBDT table. image_data_offset(&self) -> u32995 pub fn image_data_offset(&self) -> u32 { 996 let range = self.shape.image_data_offset_byte_range(); 997 self.data.read_at(range.start).unwrap() 998 } 999 sbit_offsets(&self) -> &'a [BigEndian<u32>]1000 pub fn sbit_offsets(&self) -> &'a [BigEndian<u32>] { 1001 let range = self.shape.sbit_offsets_byte_range(); 1002 self.data.read_array(range).unwrap() 1003 } 1004 } 1005 1006 #[cfg(feature = "traversal")] 1007 impl<'a> SomeTable<'a> for IndexSubtable1<'a> { type_name(&self) -> &str1008 fn type_name(&self) -> &str { 1009 "IndexSubtable1" 1010 } get_field(&self, idx: usize) -> Option<Field<'a>>1011 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1012 match idx { 1013 0usize => Some(Field::new("index_format", self.index_format())), 1014 1usize => Some(Field::new("image_format", self.image_format())), 1015 2usize => Some(Field::new("image_data_offset", self.image_data_offset())), 1016 3usize => Some(Field::new("sbit_offsets", self.sbit_offsets())), 1017 _ => None, 1018 } 1019 } 1020 } 1021 1022 #[cfg(feature = "traversal")] 1023 impl<'a> std::fmt::Debug for IndexSubtable1<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1024 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1025 (self as &dyn SomeTable<'a>).fmt(f) 1026 } 1027 } 1028 1029 impl Format<u16> for IndexSubtable2Marker { 1030 const FORMAT: u16 = 2; 1031 } 1032 1033 /// [IndexSubTable2](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#indexsubtable2-all-glyphs-have-identical-metrics): all glyphs have identical metrics. 1034 #[derive(Debug, Clone, Copy)] 1035 #[doc(hidden)] 1036 pub struct IndexSubtable2Marker { 1037 big_metrics_byte_len: usize, 1038 } 1039 1040 impl IndexSubtable2Marker { index_format_byte_range(&self) -> Range<usize>1041 fn index_format_byte_range(&self) -> Range<usize> { 1042 let start = 0; 1043 start..start + u16::RAW_BYTE_LEN 1044 } image_format_byte_range(&self) -> Range<usize>1045 fn image_format_byte_range(&self) -> Range<usize> { 1046 let start = self.index_format_byte_range().end; 1047 start..start + u16::RAW_BYTE_LEN 1048 } image_data_offset_byte_range(&self) -> Range<usize>1049 fn image_data_offset_byte_range(&self) -> Range<usize> { 1050 let start = self.image_format_byte_range().end; 1051 start..start + u32::RAW_BYTE_LEN 1052 } image_size_byte_range(&self) -> Range<usize>1053 fn image_size_byte_range(&self) -> Range<usize> { 1054 let start = self.image_data_offset_byte_range().end; 1055 start..start + u32::RAW_BYTE_LEN 1056 } big_metrics_byte_range(&self) -> Range<usize>1057 fn big_metrics_byte_range(&self) -> Range<usize> { 1058 let start = self.image_size_byte_range().end; 1059 start..start + self.big_metrics_byte_len 1060 } 1061 } 1062 1063 impl<'a> FontRead<'a> for IndexSubtable2<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1064 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1065 let mut cursor = data.cursor(); 1066 cursor.advance::<u16>(); 1067 cursor.advance::<u16>(); 1068 cursor.advance::<u32>(); 1069 cursor.advance::<u32>(); 1070 let big_metrics_byte_len = BigGlyphMetrics::RAW_BYTE_LEN; 1071 cursor.advance_by(big_metrics_byte_len); 1072 cursor.finish(IndexSubtable2Marker { 1073 big_metrics_byte_len, 1074 }) 1075 } 1076 } 1077 1078 /// [IndexSubTable2](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#indexsubtable2-all-glyphs-have-identical-metrics): all glyphs have identical metrics. 1079 pub type IndexSubtable2<'a> = TableRef<'a, IndexSubtable2Marker>; 1080 1081 impl<'a> IndexSubtable2<'a> { 1082 /// Format of this IndexSubTable. index_format(&self) -> u161083 pub fn index_format(&self) -> u16 { 1084 let range = self.shape.index_format_byte_range(); 1085 self.data.read_at(range.start).unwrap() 1086 } 1087 1088 /// Format of EBDT image data. image_format(&self) -> u161089 pub fn image_format(&self) -> u16 { 1090 let range = self.shape.image_format_byte_range(); 1091 self.data.read_at(range.start).unwrap() 1092 } 1093 1094 /// Offset to image data in EBDT table. image_data_offset(&self) -> u321095 pub fn image_data_offset(&self) -> u32 { 1096 let range = self.shape.image_data_offset_byte_range(); 1097 self.data.read_at(range.start).unwrap() 1098 } 1099 1100 /// All the glyphs are of the same size. image_size(&self) -> u321101 pub fn image_size(&self) -> u32 { 1102 let range = self.shape.image_size_byte_range(); 1103 self.data.read_at(range.start).unwrap() 1104 } 1105 1106 /// All glyphs have the same metrics; glyph data may be compressed, byte-aligned, or bit-aligned. big_metrics(&self) -> &'a [BigGlyphMetrics]1107 pub fn big_metrics(&self) -> &'a [BigGlyphMetrics] { 1108 let range = self.shape.big_metrics_byte_range(); 1109 self.data.read_array(range).unwrap() 1110 } 1111 } 1112 1113 #[cfg(feature = "traversal")] 1114 impl<'a> SomeTable<'a> for IndexSubtable2<'a> { type_name(&self) -> &str1115 fn type_name(&self) -> &str { 1116 "IndexSubtable2" 1117 } get_field(&self, idx: usize) -> Option<Field<'a>>1118 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1119 match idx { 1120 0usize => Some(Field::new("index_format", self.index_format())), 1121 1usize => Some(Field::new("image_format", self.image_format())), 1122 2usize => Some(Field::new("image_data_offset", self.image_data_offset())), 1123 3usize => Some(Field::new("image_size", self.image_size())), 1124 4usize => Some(Field::new( 1125 "big_metrics", 1126 traversal::FieldType::array_of_records( 1127 stringify!(BigGlyphMetrics), 1128 self.big_metrics(), 1129 self.offset_data(), 1130 ), 1131 )), 1132 _ => None, 1133 } 1134 } 1135 } 1136 1137 #[cfg(feature = "traversal")] 1138 impl<'a> std::fmt::Debug for IndexSubtable2<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1139 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1140 (self as &dyn SomeTable<'a>).fmt(f) 1141 } 1142 } 1143 1144 impl Format<u16> for IndexSubtable3Marker { 1145 const FORMAT: u16 = 3; 1146 } 1147 1148 /// [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. 1149 #[derive(Debug, Clone, Copy)] 1150 #[doc(hidden)] 1151 pub struct IndexSubtable3Marker { 1152 sbit_offsets_byte_len: usize, 1153 } 1154 1155 impl IndexSubtable3Marker { index_format_byte_range(&self) -> Range<usize>1156 fn index_format_byte_range(&self) -> Range<usize> { 1157 let start = 0; 1158 start..start + u16::RAW_BYTE_LEN 1159 } image_format_byte_range(&self) -> Range<usize>1160 fn image_format_byte_range(&self) -> Range<usize> { 1161 let start = self.index_format_byte_range().end; 1162 start..start + u16::RAW_BYTE_LEN 1163 } image_data_offset_byte_range(&self) -> Range<usize>1164 fn image_data_offset_byte_range(&self) -> Range<usize> { 1165 let start = self.image_format_byte_range().end; 1166 start..start + u32::RAW_BYTE_LEN 1167 } sbit_offsets_byte_range(&self) -> Range<usize>1168 fn sbit_offsets_byte_range(&self) -> Range<usize> { 1169 let start = self.image_data_offset_byte_range().end; 1170 start..start + self.sbit_offsets_byte_len 1171 } 1172 } 1173 1174 impl<'a> FontRead<'a> for IndexSubtable3<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1175 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1176 let mut cursor = data.cursor(); 1177 cursor.advance::<u16>(); 1178 cursor.advance::<u16>(); 1179 cursor.advance::<u32>(); 1180 let sbit_offsets_byte_len = 1181 cursor.remaining_bytes() / u16::RAW_BYTE_LEN * u16::RAW_BYTE_LEN; 1182 cursor.advance_by(sbit_offsets_byte_len); 1183 cursor.finish(IndexSubtable3Marker { 1184 sbit_offsets_byte_len, 1185 }) 1186 } 1187 } 1188 1189 /// [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. 1190 pub type IndexSubtable3<'a> = TableRef<'a, IndexSubtable3Marker>; 1191 1192 impl<'a> IndexSubtable3<'a> { 1193 /// Format of this IndexSubTable. index_format(&self) -> u161194 pub fn index_format(&self) -> u16 { 1195 let range = self.shape.index_format_byte_range(); 1196 self.data.read_at(range.start).unwrap() 1197 } 1198 1199 /// Format of EBDT image data. image_format(&self) -> u161200 pub fn image_format(&self) -> u16 { 1201 let range = self.shape.image_format_byte_range(); 1202 self.data.read_at(range.start).unwrap() 1203 } 1204 1205 /// Offset to image data in EBDT table. image_data_offset(&self) -> u321206 pub fn image_data_offset(&self) -> u32 { 1207 let range = self.shape.image_data_offset_byte_range(); 1208 self.data.read_at(range.start).unwrap() 1209 } 1210 sbit_offsets(&self) -> &'a [BigEndian<u16>]1211 pub fn sbit_offsets(&self) -> &'a [BigEndian<u16>] { 1212 let range = self.shape.sbit_offsets_byte_range(); 1213 self.data.read_array(range).unwrap() 1214 } 1215 } 1216 1217 #[cfg(feature = "traversal")] 1218 impl<'a> SomeTable<'a> for IndexSubtable3<'a> { type_name(&self) -> &str1219 fn type_name(&self) -> &str { 1220 "IndexSubtable3" 1221 } get_field(&self, idx: usize) -> Option<Field<'a>>1222 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1223 match idx { 1224 0usize => Some(Field::new("index_format", self.index_format())), 1225 1usize => Some(Field::new("image_format", self.image_format())), 1226 2usize => Some(Field::new("image_data_offset", self.image_data_offset())), 1227 3usize => Some(Field::new("sbit_offsets", self.sbit_offsets())), 1228 _ => None, 1229 } 1230 } 1231 } 1232 1233 #[cfg(feature = "traversal")] 1234 impl<'a> std::fmt::Debug for IndexSubtable3<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1235 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1236 (self as &dyn SomeTable<'a>).fmt(f) 1237 } 1238 } 1239 1240 impl Format<u16> for IndexSubtable4Marker { 1241 const FORMAT: u16 = 4; 1242 } 1243 1244 /// [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. 1245 #[derive(Debug, Clone, Copy)] 1246 #[doc(hidden)] 1247 pub struct IndexSubtable4Marker { 1248 glyph_array_byte_len: usize, 1249 } 1250 1251 impl IndexSubtable4Marker { index_format_byte_range(&self) -> Range<usize>1252 fn index_format_byte_range(&self) -> Range<usize> { 1253 let start = 0; 1254 start..start + u16::RAW_BYTE_LEN 1255 } image_format_byte_range(&self) -> Range<usize>1256 fn image_format_byte_range(&self) -> Range<usize> { 1257 let start = self.index_format_byte_range().end; 1258 start..start + u16::RAW_BYTE_LEN 1259 } image_data_offset_byte_range(&self) -> Range<usize>1260 fn image_data_offset_byte_range(&self) -> Range<usize> { 1261 let start = self.image_format_byte_range().end; 1262 start..start + u32::RAW_BYTE_LEN 1263 } num_glyphs_byte_range(&self) -> Range<usize>1264 fn num_glyphs_byte_range(&self) -> Range<usize> { 1265 let start = self.image_data_offset_byte_range().end; 1266 start..start + u32::RAW_BYTE_LEN 1267 } glyph_array_byte_range(&self) -> Range<usize>1268 fn glyph_array_byte_range(&self) -> Range<usize> { 1269 let start = self.num_glyphs_byte_range().end; 1270 start..start + self.glyph_array_byte_len 1271 } 1272 } 1273 1274 impl<'a> FontRead<'a> for IndexSubtable4<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1275 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1276 let mut cursor = data.cursor(); 1277 cursor.advance::<u16>(); 1278 cursor.advance::<u16>(); 1279 cursor.advance::<u32>(); 1280 let num_glyphs: u32 = cursor.read()?; 1281 let glyph_array_byte_len = 1282 transforms::add(num_glyphs, 1_usize) * GlyphIdOffsetPair::RAW_BYTE_LEN; 1283 cursor.advance_by(glyph_array_byte_len); 1284 cursor.finish(IndexSubtable4Marker { 1285 glyph_array_byte_len, 1286 }) 1287 } 1288 } 1289 1290 /// [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. 1291 pub type IndexSubtable4<'a> = TableRef<'a, IndexSubtable4Marker>; 1292 1293 impl<'a> IndexSubtable4<'a> { 1294 /// Format of this IndexSubTable. index_format(&self) -> u161295 pub fn index_format(&self) -> u16 { 1296 let range = self.shape.index_format_byte_range(); 1297 self.data.read_at(range.start).unwrap() 1298 } 1299 1300 /// Format of EBDT image data. image_format(&self) -> u161301 pub fn image_format(&self) -> u16 { 1302 let range = self.shape.image_format_byte_range(); 1303 self.data.read_at(range.start).unwrap() 1304 } 1305 1306 /// Offset to image data in EBDT table. image_data_offset(&self) -> u321307 pub fn image_data_offset(&self) -> u32 { 1308 let range = self.shape.image_data_offset_byte_range(); 1309 self.data.read_at(range.start).unwrap() 1310 } 1311 1312 /// Array length. num_glyphs(&self) -> u321313 pub fn num_glyphs(&self) -> u32 { 1314 let range = self.shape.num_glyphs_byte_range(); 1315 self.data.read_at(range.start).unwrap() 1316 } 1317 1318 /// One per glyph. glyph_array(&self) -> &'a [GlyphIdOffsetPair]1319 pub fn glyph_array(&self) -> &'a [GlyphIdOffsetPair] { 1320 let range = self.shape.glyph_array_byte_range(); 1321 self.data.read_array(range).unwrap() 1322 } 1323 } 1324 1325 #[cfg(feature = "traversal")] 1326 impl<'a> SomeTable<'a> for IndexSubtable4<'a> { type_name(&self) -> &str1327 fn type_name(&self) -> &str { 1328 "IndexSubtable4" 1329 } get_field(&self, idx: usize) -> Option<Field<'a>>1330 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1331 match idx { 1332 0usize => Some(Field::new("index_format", self.index_format())), 1333 1usize => Some(Field::new("image_format", self.image_format())), 1334 2usize => Some(Field::new("image_data_offset", self.image_data_offset())), 1335 3usize => Some(Field::new("num_glyphs", self.num_glyphs())), 1336 4usize => Some(Field::new( 1337 "glyph_array", 1338 traversal::FieldType::array_of_records( 1339 stringify!(GlyphIdOffsetPair), 1340 self.glyph_array(), 1341 self.offset_data(), 1342 ), 1343 )), 1344 _ => None, 1345 } 1346 } 1347 } 1348 1349 #[cfg(feature = "traversal")] 1350 impl<'a> std::fmt::Debug for IndexSubtable4<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1351 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1352 (self as &dyn SomeTable<'a>).fmt(f) 1353 } 1354 } 1355 1356 /// [GlyphIdOffsetPair](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#glyphidoffsetpair-record) record. 1357 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 1358 #[repr(C)] 1359 #[repr(packed)] 1360 pub struct GlyphIdOffsetPair { 1361 /// Glyph ID of glyph present. 1362 pub glyph_id: BigEndian<GlyphId>, 1363 /// Location in EBDT. 1364 pub sbit_offset: BigEndian<u16>, 1365 } 1366 1367 impl GlyphIdOffsetPair { 1368 /// Glyph ID of glyph present. glyph_id(&self) -> GlyphId1369 pub fn glyph_id(&self) -> GlyphId { 1370 self.glyph_id.get() 1371 } 1372 1373 /// Location in EBDT. sbit_offset(&self) -> u161374 pub fn sbit_offset(&self) -> u16 { 1375 self.sbit_offset.get() 1376 } 1377 } 1378 1379 impl FixedSize for GlyphIdOffsetPair { 1380 const RAW_BYTE_LEN: usize = GlyphId::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; 1381 } 1382 1383 impl sealed::Sealed for GlyphIdOffsetPair {} 1384 1385 /// SAFETY: see the [`FromBytes`] trait documentation. 1386 unsafe impl FromBytes for GlyphIdOffsetPair { this_trait_should_only_be_implemented_in_generated_code()1387 fn this_trait_should_only_be_implemented_in_generated_code() {} 1388 } 1389 1390 #[cfg(feature = "traversal")] 1391 impl<'a> SomeRecord<'a> for GlyphIdOffsetPair { traverse(self, data: FontData<'a>) -> RecordResolver<'a>1392 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 1393 RecordResolver { 1394 name: "GlyphIdOffsetPair", 1395 get_field: Box::new(move |idx, _data| match idx { 1396 0usize => Some(Field::new("glyph_id", self.glyph_id())), 1397 1usize => Some(Field::new("sbit_offset", self.sbit_offset())), 1398 _ => None, 1399 }), 1400 data, 1401 } 1402 } 1403 } 1404 1405 impl Format<u16> for IndexSubtable5Marker { 1406 const FORMAT: u16 = 5; 1407 } 1408 1409 /// [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 1410 #[derive(Debug, Clone, Copy)] 1411 #[doc(hidden)] 1412 pub struct IndexSubtable5Marker { 1413 big_metrics_byte_len: usize, 1414 glyph_array_byte_len: usize, 1415 } 1416 1417 impl IndexSubtable5Marker { index_format_byte_range(&self) -> Range<usize>1418 fn index_format_byte_range(&self) -> Range<usize> { 1419 let start = 0; 1420 start..start + u16::RAW_BYTE_LEN 1421 } image_format_byte_range(&self) -> Range<usize>1422 fn image_format_byte_range(&self) -> Range<usize> { 1423 let start = self.index_format_byte_range().end; 1424 start..start + u16::RAW_BYTE_LEN 1425 } image_data_offset_byte_range(&self) -> Range<usize>1426 fn image_data_offset_byte_range(&self) -> Range<usize> { 1427 let start = self.image_format_byte_range().end; 1428 start..start + u32::RAW_BYTE_LEN 1429 } image_size_byte_range(&self) -> Range<usize>1430 fn image_size_byte_range(&self) -> Range<usize> { 1431 let start = self.image_data_offset_byte_range().end; 1432 start..start + u32::RAW_BYTE_LEN 1433 } big_metrics_byte_range(&self) -> Range<usize>1434 fn big_metrics_byte_range(&self) -> Range<usize> { 1435 let start = self.image_size_byte_range().end; 1436 start..start + self.big_metrics_byte_len 1437 } num_glyphs_byte_range(&self) -> Range<usize>1438 fn num_glyphs_byte_range(&self) -> Range<usize> { 1439 let start = self.big_metrics_byte_range().end; 1440 start..start + u32::RAW_BYTE_LEN 1441 } glyph_array_byte_range(&self) -> Range<usize>1442 fn glyph_array_byte_range(&self) -> Range<usize> { 1443 let start = self.num_glyphs_byte_range().end; 1444 start..start + self.glyph_array_byte_len 1445 } 1446 } 1447 1448 impl<'a> FontRead<'a> for IndexSubtable5<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1449 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1450 let mut cursor = data.cursor(); 1451 cursor.advance::<u16>(); 1452 cursor.advance::<u16>(); 1453 cursor.advance::<u32>(); 1454 cursor.advance::<u32>(); 1455 let big_metrics_byte_len = BigGlyphMetrics::RAW_BYTE_LEN; 1456 cursor.advance_by(big_metrics_byte_len); 1457 let num_glyphs: u32 = cursor.read()?; 1458 let glyph_array_byte_len = num_glyphs as usize * GlyphId::RAW_BYTE_LEN; 1459 cursor.advance_by(glyph_array_byte_len); 1460 cursor.finish(IndexSubtable5Marker { 1461 big_metrics_byte_len, 1462 glyph_array_byte_len, 1463 }) 1464 } 1465 } 1466 1467 /// [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 1468 pub type IndexSubtable5<'a> = TableRef<'a, IndexSubtable5Marker>; 1469 1470 impl<'a> IndexSubtable5<'a> { 1471 /// Format of this IndexSubTable. index_format(&self) -> u161472 pub fn index_format(&self) -> u16 { 1473 let range = self.shape.index_format_byte_range(); 1474 self.data.read_at(range.start).unwrap() 1475 } 1476 1477 /// Format of EBDT image data. image_format(&self) -> u161478 pub fn image_format(&self) -> u16 { 1479 let range = self.shape.image_format_byte_range(); 1480 self.data.read_at(range.start).unwrap() 1481 } 1482 1483 /// Offset to image data in EBDT table. image_data_offset(&self) -> u321484 pub fn image_data_offset(&self) -> u32 { 1485 let range = self.shape.image_data_offset_byte_range(); 1486 self.data.read_at(range.start).unwrap() 1487 } 1488 1489 /// All glyphs have the same data size. image_size(&self) -> u321490 pub fn image_size(&self) -> u32 { 1491 let range = self.shape.image_size_byte_range(); 1492 self.data.read_at(range.start).unwrap() 1493 } 1494 1495 /// All glyphs have the same metrics. big_metrics(&self) -> &'a [BigGlyphMetrics]1496 pub fn big_metrics(&self) -> &'a [BigGlyphMetrics] { 1497 let range = self.shape.big_metrics_byte_range(); 1498 self.data.read_array(range).unwrap() 1499 } 1500 1501 /// Array length. num_glyphs(&self) -> u321502 pub fn num_glyphs(&self) -> u32 { 1503 let range = self.shape.num_glyphs_byte_range(); 1504 self.data.read_at(range.start).unwrap() 1505 } 1506 1507 /// One per glyph, sorted by glyhph ID. glyph_array(&self) -> &'a [BigEndian<GlyphId>]1508 pub fn glyph_array(&self) -> &'a [BigEndian<GlyphId>] { 1509 let range = self.shape.glyph_array_byte_range(); 1510 self.data.read_array(range).unwrap() 1511 } 1512 } 1513 1514 #[cfg(feature = "traversal")] 1515 impl<'a> SomeTable<'a> for IndexSubtable5<'a> { type_name(&self) -> &str1516 fn type_name(&self) -> &str { 1517 "IndexSubtable5" 1518 } get_field(&self, idx: usize) -> Option<Field<'a>>1519 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1520 match idx { 1521 0usize => Some(Field::new("index_format", self.index_format())), 1522 1usize => Some(Field::new("image_format", self.image_format())), 1523 2usize => Some(Field::new("image_data_offset", self.image_data_offset())), 1524 3usize => Some(Field::new("image_size", self.image_size())), 1525 4usize => Some(Field::new( 1526 "big_metrics", 1527 traversal::FieldType::array_of_records( 1528 stringify!(BigGlyphMetrics), 1529 self.big_metrics(), 1530 self.offset_data(), 1531 ), 1532 )), 1533 5usize => Some(Field::new("num_glyphs", self.num_glyphs())), 1534 6usize => Some(Field::new("glyph_array", self.glyph_array())), 1535 _ => None, 1536 } 1537 } 1538 } 1539 1540 #[cfg(feature = "traversal")] 1541 impl<'a> std::fmt::Debug for IndexSubtable5<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1542 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1543 (self as &dyn SomeTable<'a>).fmt(f) 1544 } 1545 } 1546 1547 /// [EbdtComponent](https://learn.microsoft.com/en-us/typography/opentype/spec/ebdt#ebdtcomponent-record) record. 1548 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 1549 #[repr(C)] 1550 #[repr(packed)] 1551 pub struct BdtComponent { 1552 /// Component glyph ID. 1553 pub glyph_id: BigEndian<GlyphId>, 1554 /// Position of component left. 1555 pub x_offset: BigEndian<i8>, 1556 /// Position of component top. 1557 pub y_offset: BigEndian<i8>, 1558 } 1559 1560 impl BdtComponent { 1561 /// Component glyph ID. glyph_id(&self) -> GlyphId1562 pub fn glyph_id(&self) -> GlyphId { 1563 self.glyph_id.get() 1564 } 1565 1566 /// Position of component left. x_offset(&self) -> i81567 pub fn x_offset(&self) -> i8 { 1568 self.x_offset.get() 1569 } 1570 1571 /// Position of component top. y_offset(&self) -> i81572 pub fn y_offset(&self) -> i8 { 1573 self.y_offset.get() 1574 } 1575 } 1576 1577 impl FixedSize for BdtComponent { 1578 const RAW_BYTE_LEN: usize = GlyphId::RAW_BYTE_LEN + i8::RAW_BYTE_LEN + i8::RAW_BYTE_LEN; 1579 } 1580 1581 impl sealed::Sealed for BdtComponent {} 1582 1583 /// SAFETY: see the [`FromBytes`] trait documentation. 1584 unsafe impl FromBytes for BdtComponent { this_trait_should_only_be_implemented_in_generated_code()1585 fn this_trait_should_only_be_implemented_in_generated_code() {} 1586 } 1587 1588 #[cfg(feature = "traversal")] 1589 impl<'a> SomeRecord<'a> for BdtComponent { traverse(self, data: FontData<'a>) -> RecordResolver<'a>1590 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 1591 RecordResolver { 1592 name: "BdtComponent", 1593 get_field: Box::new(move |idx, _data| match idx { 1594 0usize => Some(Field::new("glyph_id", self.glyph_id())), 1595 1usize => Some(Field::new("x_offset", self.x_offset())), 1596 2usize => Some(Field::new("y_offset", self.y_offset())), 1597 _ => None, 1598 }), 1599 data, 1600 } 1601 } 1602 } 1603