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 /// [Class Definition Table Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table-format-1) 9 /// [GPOS Version 1.0](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#gpos-header) 10 #[derive(Debug, Clone, Copy)] 11 #[doc(hidden)] 12 pub struct GposMarker { 13 feature_variations_offset_byte_start: Option<usize>, 14 } 15 16 impl GposMarker { version_byte_range(&self) -> Range<usize>17 fn version_byte_range(&self) -> Range<usize> { 18 let start = 0; 19 start..start + MajorMinor::RAW_BYTE_LEN 20 } script_list_offset_byte_range(&self) -> Range<usize>21 fn script_list_offset_byte_range(&self) -> Range<usize> { 22 let start = self.version_byte_range().end; 23 start..start + Offset16::RAW_BYTE_LEN 24 } feature_list_offset_byte_range(&self) -> Range<usize>25 fn feature_list_offset_byte_range(&self) -> Range<usize> { 26 let start = self.script_list_offset_byte_range().end; 27 start..start + Offset16::RAW_BYTE_LEN 28 } lookup_list_offset_byte_range(&self) -> Range<usize>29 fn lookup_list_offset_byte_range(&self) -> Range<usize> { 30 let start = self.feature_list_offset_byte_range().end; 31 start..start + Offset16::RAW_BYTE_LEN 32 } feature_variations_offset_byte_range(&self) -> Option<Range<usize>>33 fn feature_variations_offset_byte_range(&self) -> Option<Range<usize>> { 34 let start = self.feature_variations_offset_byte_start?; 35 Some(start..start + Offset32::RAW_BYTE_LEN) 36 } 37 } 38 39 impl TopLevelTable for Gpos<'_> { 40 /// `GPOS` 41 const TAG: Tag = Tag::new(b"GPOS"); 42 } 43 44 impl<'a> FontRead<'a> for Gpos<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>45 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 46 let mut cursor = data.cursor(); 47 let version: MajorMinor = cursor.read()?; 48 cursor.advance::<Offset16>(); 49 cursor.advance::<Offset16>(); 50 cursor.advance::<Offset16>(); 51 let feature_variations_offset_byte_start = version 52 .compatible((1, 1)) 53 .then(|| cursor.position()) 54 .transpose()?; 55 version 56 .compatible((1, 1)) 57 .then(|| cursor.advance::<Offset32>()); 58 cursor.finish(GposMarker { 59 feature_variations_offset_byte_start, 60 }) 61 } 62 } 63 64 /// [Class Definition Table Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table-format-1) 65 /// [GPOS Version 1.0](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#gpos-header) 66 pub type Gpos<'a> = TableRef<'a, GposMarker>; 67 68 impl<'a> Gpos<'a> { 69 /// The major and minor version of the GPOS table, as a tuple (u16, u16) version(&self) -> MajorMinor70 pub fn version(&self) -> MajorMinor { 71 let range = self.shape.version_byte_range(); 72 self.data.read_at(range.start).unwrap() 73 } 74 75 /// Offset to ScriptList table, from beginning of GPOS table script_list_offset(&self) -> Offset1676 pub fn script_list_offset(&self) -> Offset16 { 77 let range = self.shape.script_list_offset_byte_range(); 78 self.data.read_at(range.start).unwrap() 79 } 80 81 /// Attempt to resolve [`script_list_offset`][Self::script_list_offset]. script_list(&self) -> Result<ScriptList<'a>, ReadError>82 pub fn script_list(&self) -> Result<ScriptList<'a>, ReadError> { 83 let data = self.data; 84 self.script_list_offset().resolve(data) 85 } 86 87 /// Offset to FeatureList table, from beginning of GPOS table feature_list_offset(&self) -> Offset1688 pub fn feature_list_offset(&self) -> Offset16 { 89 let range = self.shape.feature_list_offset_byte_range(); 90 self.data.read_at(range.start).unwrap() 91 } 92 93 /// Attempt to resolve [`feature_list_offset`][Self::feature_list_offset]. feature_list(&self) -> Result<FeatureList<'a>, ReadError>94 pub fn feature_list(&self) -> Result<FeatureList<'a>, ReadError> { 95 let data = self.data; 96 self.feature_list_offset().resolve(data) 97 } 98 99 /// Offset to LookupList table, from beginning of GPOS table lookup_list_offset(&self) -> Offset16100 pub fn lookup_list_offset(&self) -> Offset16 { 101 let range = self.shape.lookup_list_offset_byte_range(); 102 self.data.read_at(range.start).unwrap() 103 } 104 105 /// Attempt to resolve [`lookup_list_offset`][Self::lookup_list_offset]. lookup_list(&self) -> Result<PositionLookupList<'a>, ReadError>106 pub fn lookup_list(&self) -> Result<PositionLookupList<'a>, ReadError> { 107 let data = self.data; 108 self.lookup_list_offset().resolve(data) 109 } 110 feature_variations_offset(&self) -> Option<Nullable<Offset32>>111 pub fn feature_variations_offset(&self) -> Option<Nullable<Offset32>> { 112 let range = self.shape.feature_variations_offset_byte_range()?; 113 Some(self.data.read_at(range.start).unwrap()) 114 } 115 116 /// Attempt to resolve [`feature_variations_offset`][Self::feature_variations_offset]. feature_variations(&self) -> Option<Result<FeatureVariations<'a>, ReadError>>117 pub fn feature_variations(&self) -> Option<Result<FeatureVariations<'a>, ReadError>> { 118 let data = self.data; 119 self.feature_variations_offset().map(|x| x.resolve(data))? 120 } 121 } 122 123 #[cfg(feature = "traversal")] 124 impl<'a> SomeTable<'a> for Gpos<'a> { type_name(&self) -> &str125 fn type_name(&self) -> &str { 126 "Gpos" 127 } get_field(&self, idx: usize) -> Option<Field<'a>>128 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 129 let version = self.version(); 130 match idx { 131 0usize => Some(Field::new("version", self.version())), 132 1usize => Some(Field::new( 133 "script_list_offset", 134 FieldType::offset(self.script_list_offset(), self.script_list()), 135 )), 136 2usize => Some(Field::new( 137 "feature_list_offset", 138 FieldType::offset(self.feature_list_offset(), self.feature_list()), 139 )), 140 3usize => Some(Field::new( 141 "lookup_list_offset", 142 FieldType::offset(self.lookup_list_offset(), self.lookup_list()), 143 )), 144 4usize if version.compatible((1, 1)) => Some(Field::new( 145 "feature_variations_offset", 146 FieldType::offset( 147 self.feature_variations_offset().unwrap(), 148 self.feature_variations().unwrap(), 149 ), 150 )), 151 _ => None, 152 } 153 } 154 } 155 156 #[cfg(feature = "traversal")] 157 impl<'a> std::fmt::Debug for Gpos<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result158 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 159 (self as &dyn SomeTable<'a>).fmt(f) 160 } 161 } 162 163 /// A [GPOS Lookup](https://learn.microsoft.com/en-us/typography/opentype/spec/gpos#gsubLookupTypeEnum) subtable. 164 pub enum PositionLookup<'a> { 165 Single(Lookup<'a, SinglePos<'a>>), 166 Pair(Lookup<'a, PairPos<'a>>), 167 Cursive(Lookup<'a, CursivePosFormat1<'a>>), 168 MarkToBase(Lookup<'a, MarkBasePosFormat1<'a>>), 169 MarkToLig(Lookup<'a, MarkLigPosFormat1<'a>>), 170 MarkToMark(Lookup<'a, MarkMarkPosFormat1<'a>>), 171 Contextual(Lookup<'a, PositionSequenceContext<'a>>), 172 ChainContextual(Lookup<'a, PositionChainContext<'a>>), 173 Extension(Lookup<'a, ExtensionSubtable<'a>>), 174 } 175 176 impl<'a> FontRead<'a> for PositionLookup<'a> { read(bytes: FontData<'a>) -> Result<Self, ReadError>177 fn read(bytes: FontData<'a>) -> Result<Self, ReadError> { 178 let untyped = Lookup::read(bytes)?; 179 match untyped.lookup_type() { 180 1 => Ok(PositionLookup::Single(untyped.into_concrete())), 181 2 => Ok(PositionLookup::Pair(untyped.into_concrete())), 182 3 => Ok(PositionLookup::Cursive(untyped.into_concrete())), 183 4 => Ok(PositionLookup::MarkToBase(untyped.into_concrete())), 184 5 => Ok(PositionLookup::MarkToLig(untyped.into_concrete())), 185 6 => Ok(PositionLookup::MarkToMark(untyped.into_concrete())), 186 7 => Ok(PositionLookup::Contextual(untyped.into_concrete())), 187 8 => Ok(PositionLookup::ChainContextual(untyped.into_concrete())), 188 9 => Ok(PositionLookup::Extension(untyped.into_concrete())), 189 other => Err(ReadError::InvalidFormat(other.into())), 190 } 191 } 192 } 193 194 impl<'a> PositionLookup<'a> { 195 #[allow(dead_code)] 196 /// Return the inner table, removing the specific generics. 197 /// 198 /// This lets us return a single concrete type we can call methods on. of_unit_type(&self) -> Lookup<'a, ()>199 pub(crate) fn of_unit_type(&self) -> Lookup<'a, ()> { 200 match self { 201 PositionLookup::Single(inner) => inner.of_unit_type(), 202 PositionLookup::Pair(inner) => inner.of_unit_type(), 203 PositionLookup::Cursive(inner) => inner.of_unit_type(), 204 PositionLookup::MarkToBase(inner) => inner.of_unit_type(), 205 PositionLookup::MarkToLig(inner) => inner.of_unit_type(), 206 PositionLookup::MarkToMark(inner) => inner.of_unit_type(), 207 PositionLookup::Contextual(inner) => inner.of_unit_type(), 208 PositionLookup::ChainContextual(inner) => inner.of_unit_type(), 209 PositionLookup::Extension(inner) => inner.of_unit_type(), 210 } 211 } 212 } 213 214 #[cfg(feature = "traversal")] 215 impl<'a> PositionLookup<'a> { dyn_inner(&self) -> &(dyn SomeTable<'a> + 'a)216 fn dyn_inner(&self) -> &(dyn SomeTable<'a> + 'a) { 217 match self { 218 PositionLookup::Single(table) => table, 219 PositionLookup::Pair(table) => table, 220 PositionLookup::Cursive(table) => table, 221 PositionLookup::MarkToBase(table) => table, 222 PositionLookup::MarkToLig(table) => table, 223 PositionLookup::MarkToMark(table) => table, 224 PositionLookup::Contextual(table) => table, 225 PositionLookup::ChainContextual(table) => table, 226 PositionLookup::Extension(table) => table, 227 } 228 } 229 } 230 231 #[cfg(feature = "traversal")] 232 impl<'a> SomeTable<'a> for PositionLookup<'a> { get_field(&self, idx: usize) -> Option<Field<'a>>233 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 234 self.dyn_inner().get_field(idx) 235 } type_name(&self) -> &str236 fn type_name(&self) -> &str { 237 self.dyn_inner().type_name() 238 } 239 } 240 241 #[cfg(feature = "traversal")] 242 impl<'a> std::fmt::Debug for PositionLookup<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result243 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 244 self.dyn_inner().fmt(f) 245 } 246 } 247 248 /// See [ValueRecord] 249 #[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] 250 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 251 pub struct ValueFormat { 252 bits: u16, 253 } 254 255 impl ValueFormat { 256 /// Includes horizontal adjustment for placement 257 pub const X_PLACEMENT: Self = Self { bits: 0x0001 }; 258 259 /// Includes vertical adjustment for placement 260 pub const Y_PLACEMENT: Self = Self { bits: 0x0002 }; 261 262 /// Includes horizontal adjustment for advance 263 pub const X_ADVANCE: Self = Self { bits: 0x0004 }; 264 265 /// Includes vertical adjustment for advance 266 pub const Y_ADVANCE: Self = Self { bits: 0x0008 }; 267 268 /// Includes Device table (non-variable font) / VariationIndex 269 /// table (variable font) for horizontal placement 270 pub const X_PLACEMENT_DEVICE: Self = Self { bits: 0x0010 }; 271 272 /// Includes Device table (non-variable font) / VariationIndex 273 /// table (variable font) for vertical placement 274 pub const Y_PLACEMENT_DEVICE: Self = Self { bits: 0x0020 }; 275 276 /// Includes Device table (non-variable font) / VariationIndex 277 /// table (variable font) for horizontal advance 278 pub const X_ADVANCE_DEVICE: Self = Self { bits: 0x0040 }; 279 280 /// Includes Device table (non-variable font) / VariationIndex 281 /// table (variable font) for vertical advance 282 pub const Y_ADVANCE_DEVICE: Self = Self { bits: 0x0080 }; 283 } 284 285 impl ValueFormat { 286 /// Returns an empty set of flags. 287 #[inline] empty() -> Self288 pub const fn empty() -> Self { 289 Self { bits: 0 } 290 } 291 292 /// Returns the set containing all flags. 293 #[inline] all() -> Self294 pub const fn all() -> Self { 295 Self { 296 bits: Self::X_PLACEMENT.bits 297 | Self::Y_PLACEMENT.bits 298 | Self::X_ADVANCE.bits 299 | Self::Y_ADVANCE.bits 300 | Self::X_PLACEMENT_DEVICE.bits 301 | Self::Y_PLACEMENT_DEVICE.bits 302 | Self::X_ADVANCE_DEVICE.bits 303 | Self::Y_ADVANCE_DEVICE.bits, 304 } 305 } 306 307 /// Returns the raw value of the flags currently stored. 308 #[inline] bits(&self) -> u16309 pub const fn bits(&self) -> u16 { 310 self.bits 311 } 312 313 /// Convert from underlying bit representation, unless that 314 /// representation contains bits that do not correspond to a flag. 315 #[inline] from_bits(bits: u16) -> Option<Self>316 pub const fn from_bits(bits: u16) -> Option<Self> { 317 if (bits & !Self::all().bits()) == 0 { 318 Some(Self { bits }) 319 } else { 320 None 321 } 322 } 323 324 /// Convert from underlying bit representation, dropping any bits 325 /// that do not correspond to flags. 326 #[inline] from_bits_truncate(bits: u16) -> Self327 pub const fn from_bits_truncate(bits: u16) -> Self { 328 Self { 329 bits: bits & Self::all().bits, 330 } 331 } 332 333 /// Returns `true` if no flags are currently stored. 334 #[inline] is_empty(&self) -> bool335 pub const fn is_empty(&self) -> bool { 336 self.bits() == Self::empty().bits() 337 } 338 339 /// Returns `true` if there are flags common to both `self` and `other`. 340 #[inline] intersects(&self, other: Self) -> bool341 pub const fn intersects(&self, other: Self) -> bool { 342 !(Self { 343 bits: self.bits & other.bits, 344 }) 345 .is_empty() 346 } 347 348 /// Returns `true` if all of the flags in `other` are contained within `self`. 349 #[inline] contains(&self, other: Self) -> bool350 pub const fn contains(&self, other: Self) -> bool { 351 (self.bits & other.bits) == other.bits 352 } 353 354 /// Inserts the specified flags in-place. 355 #[inline] insert(&mut self, other: Self)356 pub fn insert(&mut self, other: Self) { 357 self.bits |= other.bits; 358 } 359 360 /// Removes the specified flags in-place. 361 #[inline] remove(&mut self, other: Self)362 pub fn remove(&mut self, other: Self) { 363 self.bits &= !other.bits; 364 } 365 366 /// Toggles the specified flags in-place. 367 #[inline] toggle(&mut self, other: Self)368 pub fn toggle(&mut self, other: Self) { 369 self.bits ^= other.bits; 370 } 371 372 /// Returns the intersection between the flags in `self` and 373 /// `other`. 374 /// 375 /// Specifically, the returned set contains only the flags which are 376 /// present in *both* `self` *and* `other`. 377 /// 378 /// This is equivalent to using the `&` operator (e.g. 379 /// [`ops::BitAnd`]), as in `flags & other`. 380 /// 381 /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html 382 #[inline] 383 #[must_use] intersection(self, other: Self) -> Self384 pub const fn intersection(self, other: Self) -> Self { 385 Self { 386 bits: self.bits & other.bits, 387 } 388 } 389 390 /// Returns the union of between the flags in `self` and `other`. 391 /// 392 /// Specifically, the returned set contains all flags which are 393 /// present in *either* `self` *or* `other`, including any which are 394 /// present in both. 395 /// 396 /// This is equivalent to using the `|` operator (e.g. 397 /// [`ops::BitOr`]), as in `flags | other`. 398 /// 399 /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html 400 #[inline] 401 #[must_use] union(self, other: Self) -> Self402 pub const fn union(self, other: Self) -> Self { 403 Self { 404 bits: self.bits | other.bits, 405 } 406 } 407 408 /// Returns the difference between the flags in `self` and `other`. 409 /// 410 /// Specifically, the returned set contains all flags present in 411 /// `self`, except for the ones present in `other`. 412 /// 413 /// It is also conceptually equivalent to the "bit-clear" operation: 414 /// `flags & !other` (and this syntax is also supported). 415 /// 416 /// This is equivalent to using the `-` operator (e.g. 417 /// [`ops::Sub`]), as in `flags - other`. 418 /// 419 /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html 420 #[inline] 421 #[must_use] difference(self, other: Self) -> Self422 pub const fn difference(self, other: Self) -> Self { 423 Self { 424 bits: self.bits & !other.bits, 425 } 426 } 427 } 428 429 impl std::ops::BitOr for ValueFormat { 430 type Output = Self; 431 432 /// Returns the union of the two sets of flags. 433 #[inline] bitor(self, other: ValueFormat) -> Self434 fn bitor(self, other: ValueFormat) -> Self { 435 Self { 436 bits: self.bits | other.bits, 437 } 438 } 439 } 440 441 impl std::ops::BitOrAssign for ValueFormat { 442 /// Adds the set of flags. 443 #[inline] bitor_assign(&mut self, other: Self)444 fn bitor_assign(&mut self, other: Self) { 445 self.bits |= other.bits; 446 } 447 } 448 449 impl std::ops::BitXor for ValueFormat { 450 type Output = Self; 451 452 /// Returns the left flags, but with all the right flags toggled. 453 #[inline] bitxor(self, other: Self) -> Self454 fn bitxor(self, other: Self) -> Self { 455 Self { 456 bits: self.bits ^ other.bits, 457 } 458 } 459 } 460 461 impl std::ops::BitXorAssign for ValueFormat { 462 /// Toggles the set of flags. 463 #[inline] bitxor_assign(&mut self, other: Self)464 fn bitxor_assign(&mut self, other: Self) { 465 self.bits ^= other.bits; 466 } 467 } 468 469 impl std::ops::BitAnd for ValueFormat { 470 type Output = Self; 471 472 /// Returns the intersection between the two sets of flags. 473 #[inline] bitand(self, other: Self) -> Self474 fn bitand(self, other: Self) -> Self { 475 Self { 476 bits: self.bits & other.bits, 477 } 478 } 479 } 480 481 impl std::ops::BitAndAssign for ValueFormat { 482 /// Disables all flags disabled in the set. 483 #[inline] bitand_assign(&mut self, other: Self)484 fn bitand_assign(&mut self, other: Self) { 485 self.bits &= other.bits; 486 } 487 } 488 489 impl std::ops::Sub for ValueFormat { 490 type Output = Self; 491 492 /// Returns the set difference of the two sets of flags. 493 #[inline] sub(self, other: Self) -> Self494 fn sub(self, other: Self) -> Self { 495 Self { 496 bits: self.bits & !other.bits, 497 } 498 } 499 } 500 501 impl std::ops::SubAssign for ValueFormat { 502 /// Disables all flags enabled in the set. 503 #[inline] sub_assign(&mut self, other: Self)504 fn sub_assign(&mut self, other: Self) { 505 self.bits &= !other.bits; 506 } 507 } 508 509 impl std::ops::Not for ValueFormat { 510 type Output = Self; 511 512 /// Returns the complement of this set of flags. 513 #[inline] not(self) -> Self514 fn not(self) -> Self { 515 Self { bits: !self.bits } & Self::all() 516 } 517 } 518 519 impl std::fmt::Debug for ValueFormat { fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result520 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 521 let members: &[(&str, Self)] = &[ 522 ("X_PLACEMENT", Self::X_PLACEMENT), 523 ("Y_PLACEMENT", Self::Y_PLACEMENT), 524 ("X_ADVANCE", Self::X_ADVANCE), 525 ("Y_ADVANCE", Self::Y_ADVANCE), 526 ("X_PLACEMENT_DEVICE", Self::X_PLACEMENT_DEVICE), 527 ("Y_PLACEMENT_DEVICE", Self::Y_PLACEMENT_DEVICE), 528 ("X_ADVANCE_DEVICE", Self::X_ADVANCE_DEVICE), 529 ("Y_ADVANCE_DEVICE", Self::Y_ADVANCE_DEVICE), 530 ]; 531 let mut first = true; 532 for (name, value) in members { 533 if self.contains(*value) { 534 if !first { 535 f.write_str(" | ")?; 536 } 537 first = false; 538 f.write_str(name)?; 539 } 540 } 541 if first { 542 f.write_str("(empty)")?; 543 } 544 Ok(()) 545 } 546 } 547 548 impl std::fmt::Binary for ValueFormat { fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result549 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 550 std::fmt::Binary::fmt(&self.bits, f) 551 } 552 } 553 554 impl std::fmt::Octal for ValueFormat { fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result555 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 556 std::fmt::Octal::fmt(&self.bits, f) 557 } 558 } 559 560 impl std::fmt::LowerHex for ValueFormat { fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result561 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 562 std::fmt::LowerHex::fmt(&self.bits, f) 563 } 564 } 565 566 impl std::fmt::UpperHex for ValueFormat { fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result567 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 568 std::fmt::UpperHex::fmt(&self.bits, f) 569 } 570 } 571 572 impl font_types::Scalar for ValueFormat { 573 type Raw = <u16 as font_types::Scalar>::Raw; to_raw(self) -> Self::Raw574 fn to_raw(self) -> Self::Raw { 575 self.bits().to_raw() 576 } from_raw(raw: Self::Raw) -> Self577 fn from_raw(raw: Self::Raw) -> Self { 578 let t = <u16>::from_raw(raw); 579 Self::from_bits_truncate(t) 580 } 581 } 582 583 #[cfg(feature = "traversal")] 584 impl<'a> From<ValueFormat> for FieldType<'a> { from(src: ValueFormat) -> FieldType<'a>585 fn from(src: ValueFormat) -> FieldType<'a> { 586 src.bits().into() 587 } 588 } 589 590 /// [Anchor Tables](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#anchor-tables) 591 /// position one glyph with respect to another. 592 #[derive(Clone)] 593 pub enum AnchorTable<'a> { 594 Format1(AnchorFormat1<'a>), 595 Format2(AnchorFormat2<'a>), 596 Format3(AnchorFormat3<'a>), 597 } 598 599 impl<'a> AnchorTable<'a> { 600 /// Format identifier, = 1 anchor_format(&self) -> u16601 pub fn anchor_format(&self) -> u16 { 602 match self { 603 Self::Format1(item) => item.anchor_format(), 604 Self::Format2(item) => item.anchor_format(), 605 Self::Format3(item) => item.anchor_format(), 606 } 607 } 608 609 /// Horizontal value, in design units x_coordinate(&self) -> i16610 pub fn x_coordinate(&self) -> i16 { 611 match self { 612 Self::Format1(item) => item.x_coordinate(), 613 Self::Format2(item) => item.x_coordinate(), 614 Self::Format3(item) => item.x_coordinate(), 615 } 616 } 617 618 /// Vertical value, in design units y_coordinate(&self) -> i16619 pub fn y_coordinate(&self) -> i16 { 620 match self { 621 Self::Format1(item) => item.y_coordinate(), 622 Self::Format2(item) => item.y_coordinate(), 623 Self::Format3(item) => item.y_coordinate(), 624 } 625 } 626 } 627 628 impl<'a> FontRead<'a> for AnchorTable<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>629 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 630 let format: u16 = data.read_at(0usize)?; 631 match format { 632 AnchorFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)), 633 AnchorFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)), 634 AnchorFormat3Marker::FORMAT => Ok(Self::Format3(FontRead::read(data)?)), 635 other => Err(ReadError::InvalidFormat(other.into())), 636 } 637 } 638 } 639 640 #[cfg(feature = "traversal")] 641 impl<'a> AnchorTable<'a> { dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>642 fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> { 643 match self { 644 Self::Format1(table) => table, 645 Self::Format2(table) => table, 646 Self::Format3(table) => table, 647 } 648 } 649 } 650 651 #[cfg(feature = "traversal")] 652 impl<'a> std::fmt::Debug for AnchorTable<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result653 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 654 self.dyn_inner().fmt(f) 655 } 656 } 657 658 #[cfg(feature = "traversal")] 659 impl<'a> SomeTable<'a> for AnchorTable<'a> { type_name(&self) -> &str660 fn type_name(&self) -> &str { 661 self.dyn_inner().type_name() 662 } get_field(&self, idx: usize) -> Option<Field<'a>>663 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 664 self.dyn_inner().get_field(idx) 665 } 666 } 667 668 impl Format<u16> for AnchorFormat1Marker { 669 const FORMAT: u16 = 1; 670 } 671 672 /// [Anchor Table Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#anchor-table-format-1-design-units): Design Units 673 #[derive(Debug, Clone, Copy)] 674 #[doc(hidden)] 675 pub struct AnchorFormat1Marker {} 676 677 impl AnchorFormat1Marker { anchor_format_byte_range(&self) -> Range<usize>678 fn anchor_format_byte_range(&self) -> Range<usize> { 679 let start = 0; 680 start..start + u16::RAW_BYTE_LEN 681 } x_coordinate_byte_range(&self) -> Range<usize>682 fn x_coordinate_byte_range(&self) -> Range<usize> { 683 let start = self.anchor_format_byte_range().end; 684 start..start + i16::RAW_BYTE_LEN 685 } y_coordinate_byte_range(&self) -> Range<usize>686 fn y_coordinate_byte_range(&self) -> Range<usize> { 687 let start = self.x_coordinate_byte_range().end; 688 start..start + i16::RAW_BYTE_LEN 689 } 690 } 691 692 impl<'a> FontRead<'a> for AnchorFormat1<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>693 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 694 let mut cursor = data.cursor(); 695 cursor.advance::<u16>(); 696 cursor.advance::<i16>(); 697 cursor.advance::<i16>(); 698 cursor.finish(AnchorFormat1Marker {}) 699 } 700 } 701 702 /// [Anchor Table Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#anchor-table-format-1-design-units): Design Units 703 pub type AnchorFormat1<'a> = TableRef<'a, AnchorFormat1Marker>; 704 705 impl<'a> AnchorFormat1<'a> { 706 /// Format identifier, = 1 anchor_format(&self) -> u16707 pub fn anchor_format(&self) -> u16 { 708 let range = self.shape.anchor_format_byte_range(); 709 self.data.read_at(range.start).unwrap() 710 } 711 712 /// Horizontal value, in design units x_coordinate(&self) -> i16713 pub fn x_coordinate(&self) -> i16 { 714 let range = self.shape.x_coordinate_byte_range(); 715 self.data.read_at(range.start).unwrap() 716 } 717 718 /// Vertical value, in design units y_coordinate(&self) -> i16719 pub fn y_coordinate(&self) -> i16 { 720 let range = self.shape.y_coordinate_byte_range(); 721 self.data.read_at(range.start).unwrap() 722 } 723 } 724 725 #[cfg(feature = "traversal")] 726 impl<'a> SomeTable<'a> for AnchorFormat1<'a> { type_name(&self) -> &str727 fn type_name(&self) -> &str { 728 "AnchorFormat1" 729 } get_field(&self, idx: usize) -> Option<Field<'a>>730 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 731 match idx { 732 0usize => Some(Field::new("anchor_format", self.anchor_format())), 733 1usize => Some(Field::new("x_coordinate", self.x_coordinate())), 734 2usize => Some(Field::new("y_coordinate", self.y_coordinate())), 735 _ => None, 736 } 737 } 738 } 739 740 #[cfg(feature = "traversal")] 741 impl<'a> std::fmt::Debug for AnchorFormat1<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result742 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 743 (self as &dyn SomeTable<'a>).fmt(f) 744 } 745 } 746 747 impl Format<u16> for AnchorFormat2Marker { 748 const FORMAT: u16 = 2; 749 } 750 751 /// [Anchor Table Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#anchor-table-format-2-design-units-plus-contour-point): Design Units Plus Contour Point 752 #[derive(Debug, Clone, Copy)] 753 #[doc(hidden)] 754 pub struct AnchorFormat2Marker {} 755 756 impl AnchorFormat2Marker { anchor_format_byte_range(&self) -> Range<usize>757 fn anchor_format_byte_range(&self) -> Range<usize> { 758 let start = 0; 759 start..start + u16::RAW_BYTE_LEN 760 } x_coordinate_byte_range(&self) -> Range<usize>761 fn x_coordinate_byte_range(&self) -> Range<usize> { 762 let start = self.anchor_format_byte_range().end; 763 start..start + i16::RAW_BYTE_LEN 764 } y_coordinate_byte_range(&self) -> Range<usize>765 fn y_coordinate_byte_range(&self) -> Range<usize> { 766 let start = self.x_coordinate_byte_range().end; 767 start..start + i16::RAW_BYTE_LEN 768 } anchor_point_byte_range(&self) -> Range<usize>769 fn anchor_point_byte_range(&self) -> Range<usize> { 770 let start = self.y_coordinate_byte_range().end; 771 start..start + u16::RAW_BYTE_LEN 772 } 773 } 774 775 impl<'a> FontRead<'a> for AnchorFormat2<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>776 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 777 let mut cursor = data.cursor(); 778 cursor.advance::<u16>(); 779 cursor.advance::<i16>(); 780 cursor.advance::<i16>(); 781 cursor.advance::<u16>(); 782 cursor.finish(AnchorFormat2Marker {}) 783 } 784 } 785 786 /// [Anchor Table Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#anchor-table-format-2-design-units-plus-contour-point): Design Units Plus Contour Point 787 pub type AnchorFormat2<'a> = TableRef<'a, AnchorFormat2Marker>; 788 789 impl<'a> AnchorFormat2<'a> { 790 /// Format identifier, = 2 anchor_format(&self) -> u16791 pub fn anchor_format(&self) -> u16 { 792 let range = self.shape.anchor_format_byte_range(); 793 self.data.read_at(range.start).unwrap() 794 } 795 796 /// Horizontal value, in design units x_coordinate(&self) -> i16797 pub fn x_coordinate(&self) -> i16 { 798 let range = self.shape.x_coordinate_byte_range(); 799 self.data.read_at(range.start).unwrap() 800 } 801 802 /// Vertical value, in design units y_coordinate(&self) -> i16803 pub fn y_coordinate(&self) -> i16 { 804 let range = self.shape.y_coordinate_byte_range(); 805 self.data.read_at(range.start).unwrap() 806 } 807 808 /// Index to glyph contour point anchor_point(&self) -> u16809 pub fn anchor_point(&self) -> u16 { 810 let range = self.shape.anchor_point_byte_range(); 811 self.data.read_at(range.start).unwrap() 812 } 813 } 814 815 #[cfg(feature = "traversal")] 816 impl<'a> SomeTable<'a> for AnchorFormat2<'a> { type_name(&self) -> &str817 fn type_name(&self) -> &str { 818 "AnchorFormat2" 819 } get_field(&self, idx: usize) -> Option<Field<'a>>820 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 821 match idx { 822 0usize => Some(Field::new("anchor_format", self.anchor_format())), 823 1usize => Some(Field::new("x_coordinate", self.x_coordinate())), 824 2usize => Some(Field::new("y_coordinate", self.y_coordinate())), 825 3usize => Some(Field::new("anchor_point", self.anchor_point())), 826 _ => None, 827 } 828 } 829 } 830 831 #[cfg(feature = "traversal")] 832 impl<'a> std::fmt::Debug for AnchorFormat2<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result833 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 834 (self as &dyn SomeTable<'a>).fmt(f) 835 } 836 } 837 838 impl Format<u16> for AnchorFormat3Marker { 839 const FORMAT: u16 = 3; 840 } 841 842 /// [Anchor Table Format 3](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#anchor-table-format-3-design-units-plus-device-or-variationindex-tables): Design Units Plus Device or VariationIndex Tables 843 #[derive(Debug, Clone, Copy)] 844 #[doc(hidden)] 845 pub struct AnchorFormat3Marker {} 846 847 impl AnchorFormat3Marker { anchor_format_byte_range(&self) -> Range<usize>848 fn anchor_format_byte_range(&self) -> Range<usize> { 849 let start = 0; 850 start..start + u16::RAW_BYTE_LEN 851 } x_coordinate_byte_range(&self) -> Range<usize>852 fn x_coordinate_byte_range(&self) -> Range<usize> { 853 let start = self.anchor_format_byte_range().end; 854 start..start + i16::RAW_BYTE_LEN 855 } y_coordinate_byte_range(&self) -> Range<usize>856 fn y_coordinate_byte_range(&self) -> Range<usize> { 857 let start = self.x_coordinate_byte_range().end; 858 start..start + i16::RAW_BYTE_LEN 859 } x_device_offset_byte_range(&self) -> Range<usize>860 fn x_device_offset_byte_range(&self) -> Range<usize> { 861 let start = self.y_coordinate_byte_range().end; 862 start..start + Offset16::RAW_BYTE_LEN 863 } y_device_offset_byte_range(&self) -> Range<usize>864 fn y_device_offset_byte_range(&self) -> Range<usize> { 865 let start = self.x_device_offset_byte_range().end; 866 start..start + Offset16::RAW_BYTE_LEN 867 } 868 } 869 870 impl<'a> FontRead<'a> for AnchorFormat3<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>871 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 872 let mut cursor = data.cursor(); 873 cursor.advance::<u16>(); 874 cursor.advance::<i16>(); 875 cursor.advance::<i16>(); 876 cursor.advance::<Offset16>(); 877 cursor.advance::<Offset16>(); 878 cursor.finish(AnchorFormat3Marker {}) 879 } 880 } 881 882 /// [Anchor Table Format 3](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#anchor-table-format-3-design-units-plus-device-or-variationindex-tables): Design Units Plus Device or VariationIndex Tables 883 pub type AnchorFormat3<'a> = TableRef<'a, AnchorFormat3Marker>; 884 885 impl<'a> AnchorFormat3<'a> { 886 /// Format identifier, = 3 anchor_format(&self) -> u16887 pub fn anchor_format(&self) -> u16 { 888 let range = self.shape.anchor_format_byte_range(); 889 self.data.read_at(range.start).unwrap() 890 } 891 892 /// Horizontal value, in design units x_coordinate(&self) -> i16893 pub fn x_coordinate(&self) -> i16 { 894 let range = self.shape.x_coordinate_byte_range(); 895 self.data.read_at(range.start).unwrap() 896 } 897 898 /// Vertical value, in design units y_coordinate(&self) -> i16899 pub fn y_coordinate(&self) -> i16 { 900 let range = self.shape.y_coordinate_byte_range(); 901 self.data.read_at(range.start).unwrap() 902 } 903 904 /// Offset to Device table (non-variable font) / VariationIndex 905 /// table (variable font) for X coordinate, from beginning of 906 /// Anchor table (may be NULL) x_device_offset(&self) -> Nullable<Offset16>907 pub fn x_device_offset(&self) -> Nullable<Offset16> { 908 let range = self.shape.x_device_offset_byte_range(); 909 self.data.read_at(range.start).unwrap() 910 } 911 912 /// Attempt to resolve [`x_device_offset`][Self::x_device_offset]. x_device(&self) -> Option<Result<DeviceOrVariationIndex<'a>, ReadError>>913 pub fn x_device(&self) -> Option<Result<DeviceOrVariationIndex<'a>, ReadError>> { 914 let data = self.data; 915 self.x_device_offset().resolve(data) 916 } 917 918 /// Offset to Device table (non-variable font) / VariationIndex 919 /// table (variable font) for Y coordinate, from beginning of 920 /// Anchor table (may be NULL) y_device_offset(&self) -> Nullable<Offset16>921 pub fn y_device_offset(&self) -> Nullable<Offset16> { 922 let range = self.shape.y_device_offset_byte_range(); 923 self.data.read_at(range.start).unwrap() 924 } 925 926 /// Attempt to resolve [`y_device_offset`][Self::y_device_offset]. y_device(&self) -> Option<Result<DeviceOrVariationIndex<'a>, ReadError>>927 pub fn y_device(&self) -> Option<Result<DeviceOrVariationIndex<'a>, ReadError>> { 928 let data = self.data; 929 self.y_device_offset().resolve(data) 930 } 931 } 932 933 #[cfg(feature = "traversal")] 934 impl<'a> SomeTable<'a> for AnchorFormat3<'a> { type_name(&self) -> &str935 fn type_name(&self) -> &str { 936 "AnchorFormat3" 937 } get_field(&self, idx: usize) -> Option<Field<'a>>938 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 939 match idx { 940 0usize => Some(Field::new("anchor_format", self.anchor_format())), 941 1usize => Some(Field::new("x_coordinate", self.x_coordinate())), 942 2usize => Some(Field::new("y_coordinate", self.y_coordinate())), 943 3usize => Some(Field::new( 944 "x_device_offset", 945 FieldType::offset(self.x_device_offset(), self.x_device()), 946 )), 947 4usize => Some(Field::new( 948 "y_device_offset", 949 FieldType::offset(self.y_device_offset(), self.y_device()), 950 )), 951 _ => None, 952 } 953 } 954 } 955 956 #[cfg(feature = "traversal")] 957 impl<'a> std::fmt::Debug for AnchorFormat3<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result958 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 959 (self as &dyn SomeTable<'a>).fmt(f) 960 } 961 } 962 963 /// [Mark Array Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#mark-array-table) 964 #[derive(Debug, Clone, Copy)] 965 #[doc(hidden)] 966 pub struct MarkArrayMarker { 967 mark_records_byte_len: usize, 968 } 969 970 impl MarkArrayMarker { mark_count_byte_range(&self) -> Range<usize>971 fn mark_count_byte_range(&self) -> Range<usize> { 972 let start = 0; 973 start..start + u16::RAW_BYTE_LEN 974 } mark_records_byte_range(&self) -> Range<usize>975 fn mark_records_byte_range(&self) -> Range<usize> { 976 let start = self.mark_count_byte_range().end; 977 start..start + self.mark_records_byte_len 978 } 979 } 980 981 impl<'a> FontRead<'a> for MarkArray<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>982 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 983 let mut cursor = data.cursor(); 984 let mark_count: u16 = cursor.read()?; 985 let mark_records_byte_len = mark_count as usize * MarkRecord::RAW_BYTE_LEN; 986 cursor.advance_by(mark_records_byte_len); 987 cursor.finish(MarkArrayMarker { 988 mark_records_byte_len, 989 }) 990 } 991 } 992 993 /// [Mark Array Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#mark-array-table) 994 pub type MarkArray<'a> = TableRef<'a, MarkArrayMarker>; 995 996 impl<'a> MarkArray<'a> { 997 /// Number of MarkRecords mark_count(&self) -> u16998 pub fn mark_count(&self) -> u16 { 999 let range = self.shape.mark_count_byte_range(); 1000 self.data.read_at(range.start).unwrap() 1001 } 1002 1003 /// Array of MarkRecords, ordered by corresponding glyphs in the 1004 /// associated mark Coverage table. mark_records(&self) -> &'a [MarkRecord]1005 pub fn mark_records(&self) -> &'a [MarkRecord] { 1006 let range = self.shape.mark_records_byte_range(); 1007 self.data.read_array(range).unwrap() 1008 } 1009 } 1010 1011 #[cfg(feature = "traversal")] 1012 impl<'a> SomeTable<'a> for MarkArray<'a> { type_name(&self) -> &str1013 fn type_name(&self) -> &str { 1014 "MarkArray" 1015 } get_field(&self, idx: usize) -> Option<Field<'a>>1016 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1017 match idx { 1018 0usize => Some(Field::new("mark_count", self.mark_count())), 1019 1usize => Some(Field::new( 1020 "mark_records", 1021 traversal::FieldType::array_of_records( 1022 stringify!(MarkRecord), 1023 self.mark_records(), 1024 self.offset_data(), 1025 ), 1026 )), 1027 _ => None, 1028 } 1029 } 1030 } 1031 1032 #[cfg(feature = "traversal")] 1033 impl<'a> std::fmt::Debug for MarkArray<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1034 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1035 (self as &dyn SomeTable<'a>).fmt(f) 1036 } 1037 } 1038 1039 /// Part of [MarkArray] 1040 #[derive(Clone, Debug)] 1041 #[repr(C)] 1042 #[repr(packed)] 1043 pub struct MarkRecord { 1044 /// Class defined for the associated mark. 1045 pub mark_class: BigEndian<u16>, 1046 /// Offset to Anchor table, from beginning of MarkArray table. 1047 pub mark_anchor_offset: BigEndian<Offset16>, 1048 } 1049 1050 impl MarkRecord { 1051 /// Class defined for the associated mark. mark_class(&self) -> u161052 pub fn mark_class(&self) -> u16 { 1053 self.mark_class.get() 1054 } 1055 1056 /// Offset to Anchor table, from beginning of MarkArray table. mark_anchor_offset(&self) -> Offset161057 pub fn mark_anchor_offset(&self) -> Offset16 { 1058 self.mark_anchor_offset.get() 1059 } 1060 1061 /// Offset to Anchor table, from beginning of MarkArray table. 1062 /// 1063 /// The `data` argument should be retrieved from the parent table 1064 /// By calling its `offset_data` method. mark_anchor<'a>(&self, data: FontData<'a>) -> Result<AnchorTable<'a>, ReadError>1065 pub fn mark_anchor<'a>(&self, data: FontData<'a>) -> Result<AnchorTable<'a>, ReadError> { 1066 self.mark_anchor_offset().resolve(data) 1067 } 1068 } 1069 1070 impl FixedSize for MarkRecord { 1071 const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN; 1072 } 1073 1074 impl sealed::Sealed for MarkRecord {} 1075 1076 /// SAFETY: see the [`FromBytes`] trait documentation. 1077 unsafe impl FromBytes for MarkRecord { this_trait_should_only_be_implemented_in_generated_code()1078 fn this_trait_should_only_be_implemented_in_generated_code() {} 1079 } 1080 1081 #[cfg(feature = "traversal")] 1082 impl<'a> SomeRecord<'a> for MarkRecord { traverse(self, data: FontData<'a>) -> RecordResolver<'a>1083 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 1084 RecordResolver { 1085 name: "MarkRecord", 1086 get_field: Box::new(move |idx, _data| match idx { 1087 0usize => Some(Field::new("mark_class", self.mark_class())), 1088 1usize => Some(Field::new( 1089 "mark_anchor_offset", 1090 FieldType::offset(self.mark_anchor_offset(), self.mark_anchor(_data)), 1091 )), 1092 _ => None, 1093 }), 1094 data, 1095 } 1096 } 1097 } 1098 1099 /// [Lookup Type 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#lookup-type-1-single-adjustment-positioning-subtable): Single Adjustment Positioning Subtable 1100 #[derive(Clone)] 1101 pub enum SinglePos<'a> { 1102 Format1(SinglePosFormat1<'a>), 1103 Format2(SinglePosFormat2<'a>), 1104 } 1105 1106 impl<'a> SinglePos<'a> { 1107 /// Format identifier: format = 1 pos_format(&self) -> u161108 pub fn pos_format(&self) -> u16 { 1109 match self { 1110 Self::Format1(item) => item.pos_format(), 1111 Self::Format2(item) => item.pos_format(), 1112 } 1113 } 1114 1115 /// Offset to Coverage table, from beginning of SinglePos subtable. coverage_offset(&self) -> Offset161116 pub fn coverage_offset(&self) -> Offset16 { 1117 match self { 1118 Self::Format1(item) => item.coverage_offset(), 1119 Self::Format2(item) => item.coverage_offset(), 1120 } 1121 } 1122 1123 /// Defines the types of data in the ValueRecord. value_format(&self) -> ValueFormat1124 pub fn value_format(&self) -> ValueFormat { 1125 match self { 1126 Self::Format1(item) => item.value_format(), 1127 Self::Format2(item) => item.value_format(), 1128 } 1129 } 1130 } 1131 1132 impl<'a> FontRead<'a> for SinglePos<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1133 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1134 let format: u16 = data.read_at(0usize)?; 1135 match format { 1136 SinglePosFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)), 1137 SinglePosFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)), 1138 other => Err(ReadError::InvalidFormat(other.into())), 1139 } 1140 } 1141 } 1142 1143 #[cfg(feature = "traversal")] 1144 impl<'a> SinglePos<'a> { dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>1145 fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> { 1146 match self { 1147 Self::Format1(table) => table, 1148 Self::Format2(table) => table, 1149 } 1150 } 1151 } 1152 1153 #[cfg(feature = "traversal")] 1154 impl<'a> std::fmt::Debug for SinglePos<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1155 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1156 self.dyn_inner().fmt(f) 1157 } 1158 } 1159 1160 #[cfg(feature = "traversal")] 1161 impl<'a> SomeTable<'a> for SinglePos<'a> { type_name(&self) -> &str1162 fn type_name(&self) -> &str { 1163 self.dyn_inner().type_name() 1164 } get_field(&self, idx: usize) -> Option<Field<'a>>1165 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1166 self.dyn_inner().get_field(idx) 1167 } 1168 } 1169 1170 impl Format<u16> for SinglePosFormat1Marker { 1171 const FORMAT: u16 = 1; 1172 } 1173 1174 /// [Single Adjustment Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#single-adjustment-positioning-format-1-single-positioning-value): Single Positioning Value 1175 #[derive(Debug, Clone, Copy)] 1176 #[doc(hidden)] 1177 pub struct SinglePosFormat1Marker { 1178 value_record_byte_len: usize, 1179 } 1180 1181 impl SinglePosFormat1Marker { pos_format_byte_range(&self) -> Range<usize>1182 fn pos_format_byte_range(&self) -> Range<usize> { 1183 let start = 0; 1184 start..start + u16::RAW_BYTE_LEN 1185 } coverage_offset_byte_range(&self) -> Range<usize>1186 fn coverage_offset_byte_range(&self) -> Range<usize> { 1187 let start = self.pos_format_byte_range().end; 1188 start..start + Offset16::RAW_BYTE_LEN 1189 } value_format_byte_range(&self) -> Range<usize>1190 fn value_format_byte_range(&self) -> Range<usize> { 1191 let start = self.coverage_offset_byte_range().end; 1192 start..start + ValueFormat::RAW_BYTE_LEN 1193 } value_record_byte_range(&self) -> Range<usize>1194 fn value_record_byte_range(&self) -> Range<usize> { 1195 let start = self.value_format_byte_range().end; 1196 start..start + self.value_record_byte_len 1197 } 1198 } 1199 1200 impl<'a> FontRead<'a> for SinglePosFormat1<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1201 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1202 let mut cursor = data.cursor(); 1203 cursor.advance::<u16>(); 1204 cursor.advance::<Offset16>(); 1205 let value_format: ValueFormat = cursor.read()?; 1206 let value_record_byte_len = <ValueRecord as ComputeSize>::compute_size(&value_format); 1207 cursor.advance_by(value_record_byte_len); 1208 cursor.finish(SinglePosFormat1Marker { 1209 value_record_byte_len, 1210 }) 1211 } 1212 } 1213 1214 /// [Single Adjustment Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#single-adjustment-positioning-format-1-single-positioning-value): Single Positioning Value 1215 pub type SinglePosFormat1<'a> = TableRef<'a, SinglePosFormat1Marker>; 1216 1217 impl<'a> SinglePosFormat1<'a> { 1218 /// Format identifier: format = 1 pos_format(&self) -> u161219 pub fn pos_format(&self) -> u16 { 1220 let range = self.shape.pos_format_byte_range(); 1221 self.data.read_at(range.start).unwrap() 1222 } 1223 1224 /// Offset to Coverage table, from beginning of SinglePos subtable. coverage_offset(&self) -> Offset161225 pub fn coverage_offset(&self) -> Offset16 { 1226 let range = self.shape.coverage_offset_byte_range(); 1227 self.data.read_at(range.start).unwrap() 1228 } 1229 1230 /// Attempt to resolve [`coverage_offset`][Self::coverage_offset]. coverage(&self) -> Result<CoverageTable<'a>, ReadError>1231 pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> { 1232 let data = self.data; 1233 self.coverage_offset().resolve(data) 1234 } 1235 1236 /// Defines the types of data in the ValueRecord. value_format(&self) -> ValueFormat1237 pub fn value_format(&self) -> ValueFormat { 1238 let range = self.shape.value_format_byte_range(); 1239 self.data.read_at(range.start).unwrap() 1240 } 1241 1242 /// Defines positioning value(s) — applied to all glyphs in the 1243 /// Coverage table. value_record(&self) -> ValueRecord1244 pub fn value_record(&self) -> ValueRecord { 1245 let range = self.shape.value_record_byte_range(); 1246 self.data 1247 .read_with_args(range, &self.value_format()) 1248 .unwrap() 1249 } 1250 } 1251 1252 #[cfg(feature = "traversal")] 1253 impl<'a> SomeTable<'a> for SinglePosFormat1<'a> { type_name(&self) -> &str1254 fn type_name(&self) -> &str { 1255 "SinglePosFormat1" 1256 } get_field(&self, idx: usize) -> Option<Field<'a>>1257 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1258 match idx { 1259 0usize => Some(Field::new("pos_format", self.pos_format())), 1260 1usize => Some(Field::new( 1261 "coverage_offset", 1262 FieldType::offset(self.coverage_offset(), self.coverage()), 1263 )), 1264 2usize => Some(Field::new("value_format", self.value_format())), 1265 3usize => Some(Field::new( 1266 "value_record", 1267 self.value_record().traversal_type(self.offset_data()), 1268 )), 1269 _ => None, 1270 } 1271 } 1272 } 1273 1274 #[cfg(feature = "traversal")] 1275 impl<'a> std::fmt::Debug for SinglePosFormat1<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1276 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1277 (self as &dyn SomeTable<'a>).fmt(f) 1278 } 1279 } 1280 1281 impl Format<u16> for SinglePosFormat2Marker { 1282 const FORMAT: u16 = 2; 1283 } 1284 1285 /// [Single Adjustment Positioning Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#single-adjustment-positioning-format-2-array-of-positioning-values): Array of Positioning Values 1286 #[derive(Debug, Clone, Copy)] 1287 #[doc(hidden)] 1288 pub struct SinglePosFormat2Marker { 1289 value_records_byte_len: usize, 1290 } 1291 1292 impl SinglePosFormat2Marker { pos_format_byte_range(&self) -> Range<usize>1293 fn pos_format_byte_range(&self) -> Range<usize> { 1294 let start = 0; 1295 start..start + u16::RAW_BYTE_LEN 1296 } coverage_offset_byte_range(&self) -> Range<usize>1297 fn coverage_offset_byte_range(&self) -> Range<usize> { 1298 let start = self.pos_format_byte_range().end; 1299 start..start + Offset16::RAW_BYTE_LEN 1300 } value_format_byte_range(&self) -> Range<usize>1301 fn value_format_byte_range(&self) -> Range<usize> { 1302 let start = self.coverage_offset_byte_range().end; 1303 start..start + ValueFormat::RAW_BYTE_LEN 1304 } value_count_byte_range(&self) -> Range<usize>1305 fn value_count_byte_range(&self) -> Range<usize> { 1306 let start = self.value_format_byte_range().end; 1307 start..start + u16::RAW_BYTE_LEN 1308 } value_records_byte_range(&self) -> Range<usize>1309 fn value_records_byte_range(&self) -> Range<usize> { 1310 let start = self.value_count_byte_range().end; 1311 start..start + self.value_records_byte_len 1312 } 1313 } 1314 1315 impl<'a> FontRead<'a> for SinglePosFormat2<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1316 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1317 let mut cursor = data.cursor(); 1318 cursor.advance::<u16>(); 1319 cursor.advance::<Offset16>(); 1320 let value_format: ValueFormat = cursor.read()?; 1321 let value_count: u16 = cursor.read()?; 1322 let value_records_byte_len = 1323 value_count as usize * <ValueRecord as ComputeSize>::compute_size(&value_format); 1324 cursor.advance_by(value_records_byte_len); 1325 cursor.finish(SinglePosFormat2Marker { 1326 value_records_byte_len, 1327 }) 1328 } 1329 } 1330 1331 /// [Single Adjustment Positioning Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#single-adjustment-positioning-format-2-array-of-positioning-values): Array of Positioning Values 1332 pub type SinglePosFormat2<'a> = TableRef<'a, SinglePosFormat2Marker>; 1333 1334 impl<'a> SinglePosFormat2<'a> { 1335 /// Format identifier: format = 2 pos_format(&self) -> u161336 pub fn pos_format(&self) -> u16 { 1337 let range = self.shape.pos_format_byte_range(); 1338 self.data.read_at(range.start).unwrap() 1339 } 1340 1341 /// Offset to Coverage table, from beginning of SinglePos subtable. coverage_offset(&self) -> Offset161342 pub fn coverage_offset(&self) -> Offset16 { 1343 let range = self.shape.coverage_offset_byte_range(); 1344 self.data.read_at(range.start).unwrap() 1345 } 1346 1347 /// Attempt to resolve [`coverage_offset`][Self::coverage_offset]. coverage(&self) -> Result<CoverageTable<'a>, ReadError>1348 pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> { 1349 let data = self.data; 1350 self.coverage_offset().resolve(data) 1351 } 1352 1353 /// Defines the types of data in the ValueRecords. value_format(&self) -> ValueFormat1354 pub fn value_format(&self) -> ValueFormat { 1355 let range = self.shape.value_format_byte_range(); 1356 self.data.read_at(range.start).unwrap() 1357 } 1358 1359 /// Number of ValueRecords — must equal glyphCount in the 1360 /// Coverage table. value_count(&self) -> u161361 pub fn value_count(&self) -> u16 { 1362 let range = self.shape.value_count_byte_range(); 1363 self.data.read_at(range.start).unwrap() 1364 } 1365 1366 /// Array of ValueRecords — positioning values applied to glyphs. value_records(&self) -> ComputedArray<'a, ValueRecord>1367 pub fn value_records(&self) -> ComputedArray<'a, ValueRecord> { 1368 let range = self.shape.value_records_byte_range(); 1369 self.data 1370 .read_with_args(range, &self.value_format()) 1371 .unwrap() 1372 } 1373 } 1374 1375 #[cfg(feature = "traversal")] 1376 impl<'a> SomeTable<'a> for SinglePosFormat2<'a> { type_name(&self) -> &str1377 fn type_name(&self) -> &str { 1378 "SinglePosFormat2" 1379 } get_field(&self, idx: usize) -> Option<Field<'a>>1380 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1381 match idx { 1382 0usize => Some(Field::new("pos_format", self.pos_format())), 1383 1usize => Some(Field::new( 1384 "coverage_offset", 1385 FieldType::offset(self.coverage_offset(), self.coverage()), 1386 )), 1387 2usize => Some(Field::new("value_format", self.value_format())), 1388 3usize => Some(Field::new("value_count", self.value_count())), 1389 4usize => Some(Field::new( 1390 "value_records", 1391 traversal::FieldType::computed_array( 1392 "ValueRecord", 1393 self.value_records(), 1394 self.offset_data(), 1395 ), 1396 )), 1397 _ => None, 1398 } 1399 } 1400 } 1401 1402 #[cfg(feature = "traversal")] 1403 impl<'a> std::fmt::Debug for SinglePosFormat2<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1404 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1405 (self as &dyn SomeTable<'a>).fmt(f) 1406 } 1407 } 1408 1409 /// [Lookup Type 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#lookup-type-1-single-adjustment-positioning-subtable): Single Adjustment Positioning Subtable 1410 #[derive(Clone)] 1411 pub enum PairPos<'a> { 1412 Format1(PairPosFormat1<'a>), 1413 Format2(PairPosFormat2<'a>), 1414 } 1415 1416 impl<'a> PairPos<'a> { 1417 /// Format identifier: format = 1 pos_format(&self) -> u161418 pub fn pos_format(&self) -> u16 { 1419 match self { 1420 Self::Format1(item) => item.pos_format(), 1421 Self::Format2(item) => item.pos_format(), 1422 } 1423 } 1424 1425 /// Offset to Coverage table, from beginning of PairPos subtable. coverage_offset(&self) -> Offset161426 pub fn coverage_offset(&self) -> Offset16 { 1427 match self { 1428 Self::Format1(item) => item.coverage_offset(), 1429 Self::Format2(item) => item.coverage_offset(), 1430 } 1431 } 1432 1433 /// Defines the types of data in valueRecord1 — for the first 1434 /// glyph in the pair (may be zero). value_format1(&self) -> ValueFormat1435 pub fn value_format1(&self) -> ValueFormat { 1436 match self { 1437 Self::Format1(item) => item.value_format1(), 1438 Self::Format2(item) => item.value_format1(), 1439 } 1440 } 1441 1442 /// Defines the types of data in valueRecord2 — for the second 1443 /// glyph in the pair (may be zero). value_format2(&self) -> ValueFormat1444 pub fn value_format2(&self) -> ValueFormat { 1445 match self { 1446 Self::Format1(item) => item.value_format2(), 1447 Self::Format2(item) => item.value_format2(), 1448 } 1449 } 1450 } 1451 1452 impl<'a> FontRead<'a> for PairPos<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1453 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1454 let format: u16 = data.read_at(0usize)?; 1455 match format { 1456 PairPosFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)), 1457 PairPosFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)), 1458 other => Err(ReadError::InvalidFormat(other.into())), 1459 } 1460 } 1461 } 1462 1463 #[cfg(feature = "traversal")] 1464 impl<'a> PairPos<'a> { dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>1465 fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> { 1466 match self { 1467 Self::Format1(table) => table, 1468 Self::Format2(table) => table, 1469 } 1470 } 1471 } 1472 1473 #[cfg(feature = "traversal")] 1474 impl<'a> std::fmt::Debug for PairPos<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1475 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1476 self.dyn_inner().fmt(f) 1477 } 1478 } 1479 1480 #[cfg(feature = "traversal")] 1481 impl<'a> SomeTable<'a> for PairPos<'a> { type_name(&self) -> &str1482 fn type_name(&self) -> &str { 1483 self.dyn_inner().type_name() 1484 } get_field(&self, idx: usize) -> Option<Field<'a>>1485 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1486 self.dyn_inner().get_field(idx) 1487 } 1488 } 1489 1490 impl Format<u16> for PairPosFormat1Marker { 1491 const FORMAT: u16 = 1; 1492 } 1493 1494 /// [Pair Adjustment Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#pair-adjustment-positioning-format-1-adjustments-for-glyph-pairs): Adjustments for Glyph Pairs 1495 #[derive(Debug, Clone, Copy)] 1496 #[doc(hidden)] 1497 pub struct PairPosFormat1Marker { 1498 pair_set_offsets_byte_len: usize, 1499 } 1500 1501 impl PairPosFormat1Marker { pos_format_byte_range(&self) -> Range<usize>1502 fn pos_format_byte_range(&self) -> Range<usize> { 1503 let start = 0; 1504 start..start + u16::RAW_BYTE_LEN 1505 } coverage_offset_byte_range(&self) -> Range<usize>1506 fn coverage_offset_byte_range(&self) -> Range<usize> { 1507 let start = self.pos_format_byte_range().end; 1508 start..start + Offset16::RAW_BYTE_LEN 1509 } value_format1_byte_range(&self) -> Range<usize>1510 fn value_format1_byte_range(&self) -> Range<usize> { 1511 let start = self.coverage_offset_byte_range().end; 1512 start..start + ValueFormat::RAW_BYTE_LEN 1513 } value_format2_byte_range(&self) -> Range<usize>1514 fn value_format2_byte_range(&self) -> Range<usize> { 1515 let start = self.value_format1_byte_range().end; 1516 start..start + ValueFormat::RAW_BYTE_LEN 1517 } pair_set_count_byte_range(&self) -> Range<usize>1518 fn pair_set_count_byte_range(&self) -> Range<usize> { 1519 let start = self.value_format2_byte_range().end; 1520 start..start + u16::RAW_BYTE_LEN 1521 } pair_set_offsets_byte_range(&self) -> Range<usize>1522 fn pair_set_offsets_byte_range(&self) -> Range<usize> { 1523 let start = self.pair_set_count_byte_range().end; 1524 start..start + self.pair_set_offsets_byte_len 1525 } 1526 } 1527 1528 impl<'a> FontRead<'a> for PairPosFormat1<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1529 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1530 let mut cursor = data.cursor(); 1531 cursor.advance::<u16>(); 1532 cursor.advance::<Offset16>(); 1533 cursor.advance::<ValueFormat>(); 1534 cursor.advance::<ValueFormat>(); 1535 let pair_set_count: u16 = cursor.read()?; 1536 let pair_set_offsets_byte_len = pair_set_count as usize * Offset16::RAW_BYTE_LEN; 1537 cursor.advance_by(pair_set_offsets_byte_len); 1538 cursor.finish(PairPosFormat1Marker { 1539 pair_set_offsets_byte_len, 1540 }) 1541 } 1542 } 1543 1544 /// [Pair Adjustment Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#pair-adjustment-positioning-format-1-adjustments-for-glyph-pairs): Adjustments for Glyph Pairs 1545 pub type PairPosFormat1<'a> = TableRef<'a, PairPosFormat1Marker>; 1546 1547 impl<'a> PairPosFormat1<'a> { 1548 /// Format identifier: format = 1 pos_format(&self) -> u161549 pub fn pos_format(&self) -> u16 { 1550 let range = self.shape.pos_format_byte_range(); 1551 self.data.read_at(range.start).unwrap() 1552 } 1553 1554 /// Offset to Coverage table, from beginning of PairPos subtable. coverage_offset(&self) -> Offset161555 pub fn coverage_offset(&self) -> Offset16 { 1556 let range = self.shape.coverage_offset_byte_range(); 1557 self.data.read_at(range.start).unwrap() 1558 } 1559 1560 /// Attempt to resolve [`coverage_offset`][Self::coverage_offset]. coverage(&self) -> Result<CoverageTable<'a>, ReadError>1561 pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> { 1562 let data = self.data; 1563 self.coverage_offset().resolve(data) 1564 } 1565 1566 /// Defines the types of data in valueRecord1 — for the first 1567 /// glyph in the pair (may be zero). value_format1(&self) -> ValueFormat1568 pub fn value_format1(&self) -> ValueFormat { 1569 let range = self.shape.value_format1_byte_range(); 1570 self.data.read_at(range.start).unwrap() 1571 } 1572 1573 /// Defines the types of data in valueRecord2 — for the second 1574 /// glyph in the pair (may be zero). value_format2(&self) -> ValueFormat1575 pub fn value_format2(&self) -> ValueFormat { 1576 let range = self.shape.value_format2_byte_range(); 1577 self.data.read_at(range.start).unwrap() 1578 } 1579 1580 /// Number of PairSet tables pair_set_count(&self) -> u161581 pub fn pair_set_count(&self) -> u16 { 1582 let range = self.shape.pair_set_count_byte_range(); 1583 self.data.read_at(range.start).unwrap() 1584 } 1585 1586 /// Array of offsets to PairSet tables. Offsets are from beginning 1587 /// of PairPos subtable, ordered by Coverage Index. pair_set_offsets(&self) -> &'a [BigEndian<Offset16>]1588 pub fn pair_set_offsets(&self) -> &'a [BigEndian<Offset16>] { 1589 let range = self.shape.pair_set_offsets_byte_range(); 1590 self.data.read_array(range).unwrap() 1591 } 1592 1593 /// A dynamically resolving wrapper for [`pair_set_offsets`][Self::pair_set_offsets]. pair_sets(&self) -> ArrayOfOffsets<'a, PairSet<'a>, Offset16>1594 pub fn pair_sets(&self) -> ArrayOfOffsets<'a, PairSet<'a>, Offset16> { 1595 let data = self.data; 1596 let offsets = self.pair_set_offsets(); 1597 let args = (self.value_format1(), self.value_format2()); 1598 ArrayOfOffsets::new(offsets, data, args) 1599 } 1600 } 1601 1602 #[cfg(feature = "traversal")] 1603 impl<'a> SomeTable<'a> for PairPosFormat1<'a> { type_name(&self) -> &str1604 fn type_name(&self) -> &str { 1605 "PairPosFormat1" 1606 } get_field(&self, idx: usize) -> Option<Field<'a>>1607 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1608 match idx { 1609 0usize => Some(Field::new("pos_format", self.pos_format())), 1610 1usize => Some(Field::new( 1611 "coverage_offset", 1612 FieldType::offset(self.coverage_offset(), self.coverage()), 1613 )), 1614 2usize => Some(Field::new("value_format1", self.value_format1())), 1615 3usize => Some(Field::new("value_format2", self.value_format2())), 1616 4usize => Some(Field::new("pair_set_count", self.pair_set_count())), 1617 5usize => Some({ 1618 let data = self.data; 1619 let args = (self.value_format1(), self.value_format2()); 1620 Field::new( 1621 "pair_set_offsets", 1622 FieldType::array_of_offsets( 1623 better_type_name::<PairSet>(), 1624 self.pair_set_offsets(), 1625 move |off| { 1626 let target = off.get().resolve_with_args::<PairSet>(data, &args); 1627 FieldType::offset(off.get(), target) 1628 }, 1629 ), 1630 ) 1631 }), 1632 _ => None, 1633 } 1634 } 1635 } 1636 1637 #[cfg(feature = "traversal")] 1638 impl<'a> std::fmt::Debug for PairPosFormat1<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1639 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1640 (self as &dyn SomeTable<'a>).fmt(f) 1641 } 1642 } 1643 1644 /// Part of [PairPosFormat1] 1645 #[derive(Debug, Clone, Copy)] 1646 #[doc(hidden)] 1647 pub struct PairSetMarker { 1648 value_format1: ValueFormat, 1649 value_format2: ValueFormat, 1650 pair_value_records_byte_len: usize, 1651 } 1652 1653 impl PairSetMarker { pair_value_count_byte_range(&self) -> Range<usize>1654 fn pair_value_count_byte_range(&self) -> Range<usize> { 1655 let start = 0; 1656 start..start + u16::RAW_BYTE_LEN 1657 } pair_value_records_byte_range(&self) -> Range<usize>1658 fn pair_value_records_byte_range(&self) -> Range<usize> { 1659 let start = self.pair_value_count_byte_range().end; 1660 start..start + self.pair_value_records_byte_len 1661 } 1662 } 1663 1664 impl ReadArgs for PairSet<'_> { 1665 type Args = (ValueFormat, ValueFormat); 1666 } 1667 1668 impl<'a> FontReadWithArgs<'a> for PairSet<'a> { read_with_args( data: FontData<'a>, args: &(ValueFormat, ValueFormat), ) -> Result<Self, ReadError>1669 fn read_with_args( 1670 data: FontData<'a>, 1671 args: &(ValueFormat, ValueFormat), 1672 ) -> Result<Self, ReadError> { 1673 let (value_format1, value_format2) = *args; 1674 let mut cursor = data.cursor(); 1675 let pair_value_count: u16 = cursor.read()?; 1676 let pair_value_records_byte_len = pair_value_count as usize 1677 * <PairValueRecord as ComputeSize>::compute_size(&(value_format1, value_format2)); 1678 cursor.advance_by(pair_value_records_byte_len); 1679 cursor.finish(PairSetMarker { 1680 value_format1, 1681 value_format2, 1682 pair_value_records_byte_len, 1683 }) 1684 } 1685 } 1686 1687 impl<'a> PairSet<'a> { 1688 /// A constructor that requires additional arguments. 1689 /// 1690 /// This type requires some external state in order to be 1691 /// parsed. read( data: FontData<'a>, value_format1: ValueFormat, value_format2: ValueFormat, ) -> Result<Self, ReadError>1692 pub fn read( 1693 data: FontData<'a>, 1694 value_format1: ValueFormat, 1695 value_format2: ValueFormat, 1696 ) -> Result<Self, ReadError> { 1697 let args = (value_format1, value_format2); 1698 Self::read_with_args(data, &args) 1699 } 1700 } 1701 1702 /// Part of [PairPosFormat1] 1703 pub type PairSet<'a> = TableRef<'a, PairSetMarker>; 1704 1705 impl<'a> PairSet<'a> { 1706 /// Number of PairValueRecords pair_value_count(&self) -> u161707 pub fn pair_value_count(&self) -> u16 { 1708 let range = self.shape.pair_value_count_byte_range(); 1709 self.data.read_at(range.start).unwrap() 1710 } 1711 1712 /// Array of PairValueRecords, ordered by glyph ID of the second 1713 /// glyph. pair_value_records(&self) -> ComputedArray<'a, PairValueRecord>1714 pub fn pair_value_records(&self) -> ComputedArray<'a, PairValueRecord> { 1715 let range = self.shape.pair_value_records_byte_range(); 1716 self.data 1717 .read_with_args(range, &(self.value_format1(), self.value_format2())) 1718 .unwrap() 1719 } 1720 value_format1(&self) -> ValueFormat1721 pub(crate) fn value_format1(&self) -> ValueFormat { 1722 self.shape.value_format1 1723 } 1724 value_format2(&self) -> ValueFormat1725 pub(crate) fn value_format2(&self) -> ValueFormat { 1726 self.shape.value_format2 1727 } 1728 } 1729 1730 #[cfg(feature = "traversal")] 1731 impl<'a> SomeTable<'a> for PairSet<'a> { type_name(&self) -> &str1732 fn type_name(&self) -> &str { 1733 "PairSet" 1734 } get_field(&self, idx: usize) -> Option<Field<'a>>1735 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1736 match idx { 1737 0usize => Some(Field::new("pair_value_count", self.pair_value_count())), 1738 1usize => Some(Field::new( 1739 "pair_value_records", 1740 traversal::FieldType::computed_array( 1741 "PairValueRecord", 1742 self.pair_value_records(), 1743 self.offset_data(), 1744 ), 1745 )), 1746 _ => None, 1747 } 1748 } 1749 } 1750 1751 #[cfg(feature = "traversal")] 1752 impl<'a> std::fmt::Debug for PairSet<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1753 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1754 (self as &dyn SomeTable<'a>).fmt(f) 1755 } 1756 } 1757 1758 /// Part of [PairSet] 1759 #[derive(Clone, Debug)] 1760 pub struct PairValueRecord { 1761 /// Glyph ID of second glyph in the pair (first glyph is listed in 1762 /// the Coverage table). 1763 pub second_glyph: BigEndian<GlyphId>, 1764 /// Positioning data for the first glyph in the pair. 1765 pub value_record1: ValueRecord, 1766 /// Positioning data for the second glyph in the pair. 1767 pub value_record2: ValueRecord, 1768 } 1769 1770 impl PairValueRecord { 1771 /// Glyph ID of second glyph in the pair (first glyph is listed in 1772 /// the Coverage table). second_glyph(&self) -> GlyphId1773 pub fn second_glyph(&self) -> GlyphId { 1774 self.second_glyph.get() 1775 } 1776 1777 /// Positioning data for the first glyph in the pair. value_record1(&self) -> &ValueRecord1778 pub fn value_record1(&self) -> &ValueRecord { 1779 &self.value_record1 1780 } 1781 1782 /// Positioning data for the second glyph in the pair. value_record2(&self) -> &ValueRecord1783 pub fn value_record2(&self) -> &ValueRecord { 1784 &self.value_record2 1785 } 1786 } 1787 1788 impl ReadArgs for PairValueRecord { 1789 type Args = (ValueFormat, ValueFormat); 1790 } 1791 1792 impl ComputeSize for PairValueRecord { compute_size(args: &(ValueFormat, ValueFormat)) -> usize1793 fn compute_size(args: &(ValueFormat, ValueFormat)) -> usize { 1794 let (value_format1, value_format2) = *args; 1795 GlyphId::RAW_BYTE_LEN 1796 + <ValueRecord as ComputeSize>::compute_size(&value_format1) 1797 + <ValueRecord as ComputeSize>::compute_size(&value_format2) 1798 } 1799 } 1800 1801 impl<'a> FontReadWithArgs<'a> for PairValueRecord { read_with_args( data: FontData<'a>, args: &(ValueFormat, ValueFormat), ) -> Result<Self, ReadError>1802 fn read_with_args( 1803 data: FontData<'a>, 1804 args: &(ValueFormat, ValueFormat), 1805 ) -> Result<Self, ReadError> { 1806 let mut cursor = data.cursor(); 1807 let (value_format1, value_format2) = *args; 1808 Ok(Self { 1809 second_glyph: cursor.read_be()?, 1810 value_record1: cursor.read_with_args(&value_format1)?, 1811 value_record2: cursor.read_with_args(&value_format2)?, 1812 }) 1813 } 1814 } 1815 1816 impl<'a> PairValueRecord { 1817 /// A constructor that requires additional arguments. 1818 /// 1819 /// This type requires some external state in order to be 1820 /// parsed. read( data: FontData<'a>, value_format1: ValueFormat, value_format2: ValueFormat, ) -> Result<Self, ReadError>1821 pub fn read( 1822 data: FontData<'a>, 1823 value_format1: ValueFormat, 1824 value_format2: ValueFormat, 1825 ) -> Result<Self, ReadError> { 1826 let args = (value_format1, value_format2); 1827 Self::read_with_args(data, &args) 1828 } 1829 } 1830 1831 #[cfg(feature = "traversal")] 1832 impl<'a> SomeRecord<'a> for PairValueRecord { traverse(self, data: FontData<'a>) -> RecordResolver<'a>1833 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 1834 RecordResolver { 1835 name: "PairValueRecord", 1836 get_field: Box::new(move |idx, _data| match idx { 1837 0usize => Some(Field::new("second_glyph", self.second_glyph())), 1838 1usize => Some(Field::new( 1839 "value_record1", 1840 self.value_record1().traversal_type(_data), 1841 )), 1842 2usize => Some(Field::new( 1843 "value_record2", 1844 self.value_record2().traversal_type(_data), 1845 )), 1846 _ => None, 1847 }), 1848 data, 1849 } 1850 } 1851 } 1852 1853 impl Format<u16> for PairPosFormat2Marker { 1854 const FORMAT: u16 = 2; 1855 } 1856 1857 /// [Pair Adjustment Positioning Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#pair-adjustment-positioning-format-2-class-pair-adjustment): Class Pair Adjustment 1858 #[derive(Debug, Clone, Copy)] 1859 #[doc(hidden)] 1860 pub struct PairPosFormat2Marker { 1861 class1_records_byte_len: usize, 1862 } 1863 1864 impl PairPosFormat2Marker { pos_format_byte_range(&self) -> Range<usize>1865 fn pos_format_byte_range(&self) -> Range<usize> { 1866 let start = 0; 1867 start..start + u16::RAW_BYTE_LEN 1868 } coverage_offset_byte_range(&self) -> Range<usize>1869 fn coverage_offset_byte_range(&self) -> Range<usize> { 1870 let start = self.pos_format_byte_range().end; 1871 start..start + Offset16::RAW_BYTE_LEN 1872 } value_format1_byte_range(&self) -> Range<usize>1873 fn value_format1_byte_range(&self) -> Range<usize> { 1874 let start = self.coverage_offset_byte_range().end; 1875 start..start + ValueFormat::RAW_BYTE_LEN 1876 } value_format2_byte_range(&self) -> Range<usize>1877 fn value_format2_byte_range(&self) -> Range<usize> { 1878 let start = self.value_format1_byte_range().end; 1879 start..start + ValueFormat::RAW_BYTE_LEN 1880 } class_def1_offset_byte_range(&self) -> Range<usize>1881 fn class_def1_offset_byte_range(&self) -> Range<usize> { 1882 let start = self.value_format2_byte_range().end; 1883 start..start + Offset16::RAW_BYTE_LEN 1884 } class_def2_offset_byte_range(&self) -> Range<usize>1885 fn class_def2_offset_byte_range(&self) -> Range<usize> { 1886 let start = self.class_def1_offset_byte_range().end; 1887 start..start + Offset16::RAW_BYTE_LEN 1888 } class1_count_byte_range(&self) -> Range<usize>1889 fn class1_count_byte_range(&self) -> Range<usize> { 1890 let start = self.class_def2_offset_byte_range().end; 1891 start..start + u16::RAW_BYTE_LEN 1892 } class2_count_byte_range(&self) -> Range<usize>1893 fn class2_count_byte_range(&self) -> Range<usize> { 1894 let start = self.class1_count_byte_range().end; 1895 start..start + u16::RAW_BYTE_LEN 1896 } class1_records_byte_range(&self) -> Range<usize>1897 fn class1_records_byte_range(&self) -> Range<usize> { 1898 let start = self.class2_count_byte_range().end; 1899 start..start + self.class1_records_byte_len 1900 } 1901 } 1902 1903 impl<'a> FontRead<'a> for PairPosFormat2<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1904 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1905 let mut cursor = data.cursor(); 1906 cursor.advance::<u16>(); 1907 cursor.advance::<Offset16>(); 1908 let value_format1: ValueFormat = cursor.read()?; 1909 let value_format2: ValueFormat = cursor.read()?; 1910 cursor.advance::<Offset16>(); 1911 cursor.advance::<Offset16>(); 1912 let class1_count: u16 = cursor.read()?; 1913 let class2_count: u16 = cursor.read()?; 1914 let class1_records_byte_len = class1_count as usize 1915 * <Class1Record as ComputeSize>::compute_size(&( 1916 class2_count, 1917 value_format1, 1918 value_format2, 1919 )); 1920 cursor.advance_by(class1_records_byte_len); 1921 cursor.finish(PairPosFormat2Marker { 1922 class1_records_byte_len, 1923 }) 1924 } 1925 } 1926 1927 /// [Pair Adjustment Positioning Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#pair-adjustment-positioning-format-2-class-pair-adjustment): Class Pair Adjustment 1928 pub type PairPosFormat2<'a> = TableRef<'a, PairPosFormat2Marker>; 1929 1930 impl<'a> PairPosFormat2<'a> { 1931 /// Format identifier: format = 2 pos_format(&self) -> u161932 pub fn pos_format(&self) -> u16 { 1933 let range = self.shape.pos_format_byte_range(); 1934 self.data.read_at(range.start).unwrap() 1935 } 1936 1937 /// Offset to Coverage table, from beginning of PairPos subtable. coverage_offset(&self) -> Offset161938 pub fn coverage_offset(&self) -> Offset16 { 1939 let range = self.shape.coverage_offset_byte_range(); 1940 self.data.read_at(range.start).unwrap() 1941 } 1942 1943 /// Attempt to resolve [`coverage_offset`][Self::coverage_offset]. coverage(&self) -> Result<CoverageTable<'a>, ReadError>1944 pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> { 1945 let data = self.data; 1946 self.coverage_offset().resolve(data) 1947 } 1948 1949 /// ValueRecord definition — for the first glyph of the pair (may 1950 /// be zero). value_format1(&self) -> ValueFormat1951 pub fn value_format1(&self) -> ValueFormat { 1952 let range = self.shape.value_format1_byte_range(); 1953 self.data.read_at(range.start).unwrap() 1954 } 1955 1956 /// ValueRecord definition — for the second glyph of the pair 1957 /// (may be zero). value_format2(&self) -> ValueFormat1958 pub fn value_format2(&self) -> ValueFormat { 1959 let range = self.shape.value_format2_byte_range(); 1960 self.data.read_at(range.start).unwrap() 1961 } 1962 1963 /// Offset to ClassDef table, from beginning of PairPos subtable 1964 /// — for the first glyph of the pair. class_def1_offset(&self) -> Offset161965 pub fn class_def1_offset(&self) -> Offset16 { 1966 let range = self.shape.class_def1_offset_byte_range(); 1967 self.data.read_at(range.start).unwrap() 1968 } 1969 1970 /// Attempt to resolve [`class_def1_offset`][Self::class_def1_offset]. class_def1(&self) -> Result<ClassDef<'a>, ReadError>1971 pub fn class_def1(&self) -> Result<ClassDef<'a>, ReadError> { 1972 let data = self.data; 1973 self.class_def1_offset().resolve(data) 1974 } 1975 1976 /// Offset to ClassDef table, from beginning of PairPos subtable 1977 /// — for the second glyph of the pair. class_def2_offset(&self) -> Offset161978 pub fn class_def2_offset(&self) -> Offset16 { 1979 let range = self.shape.class_def2_offset_byte_range(); 1980 self.data.read_at(range.start).unwrap() 1981 } 1982 1983 /// Attempt to resolve [`class_def2_offset`][Self::class_def2_offset]. class_def2(&self) -> Result<ClassDef<'a>, ReadError>1984 pub fn class_def2(&self) -> Result<ClassDef<'a>, ReadError> { 1985 let data = self.data; 1986 self.class_def2_offset().resolve(data) 1987 } 1988 1989 /// Number of classes in classDef1 table — includes Class 0. class1_count(&self) -> u161990 pub fn class1_count(&self) -> u16 { 1991 let range = self.shape.class1_count_byte_range(); 1992 self.data.read_at(range.start).unwrap() 1993 } 1994 1995 /// Number of classes in classDef2 table — includes Class 0. class2_count(&self) -> u161996 pub fn class2_count(&self) -> u16 { 1997 let range = self.shape.class2_count_byte_range(); 1998 self.data.read_at(range.start).unwrap() 1999 } 2000 2001 /// Array of Class1 records, ordered by classes in classDef1. class1_records(&self) -> ComputedArray<'a, Class1Record<'a>>2002 pub fn class1_records(&self) -> ComputedArray<'a, Class1Record<'a>> { 2003 let range = self.shape.class1_records_byte_range(); 2004 self.data 2005 .read_with_args( 2006 range, 2007 &( 2008 self.class2_count(), 2009 self.value_format1(), 2010 self.value_format2(), 2011 ), 2012 ) 2013 .unwrap() 2014 } 2015 } 2016 2017 #[cfg(feature = "traversal")] 2018 impl<'a> SomeTable<'a> for PairPosFormat2<'a> { type_name(&self) -> &str2019 fn type_name(&self) -> &str { 2020 "PairPosFormat2" 2021 } get_field(&self, idx: usize) -> Option<Field<'a>>2022 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 2023 match idx { 2024 0usize => Some(Field::new("pos_format", self.pos_format())), 2025 1usize => Some(Field::new( 2026 "coverage_offset", 2027 FieldType::offset(self.coverage_offset(), self.coverage()), 2028 )), 2029 2usize => Some(Field::new("value_format1", self.value_format1())), 2030 3usize => Some(Field::new("value_format2", self.value_format2())), 2031 4usize => Some(Field::new( 2032 "class_def1_offset", 2033 FieldType::offset(self.class_def1_offset(), self.class_def1()), 2034 )), 2035 5usize => Some(Field::new( 2036 "class_def2_offset", 2037 FieldType::offset(self.class_def2_offset(), self.class_def2()), 2038 )), 2039 6usize => Some(Field::new("class1_count", self.class1_count())), 2040 7usize => Some(Field::new("class2_count", self.class2_count())), 2041 8usize => Some(Field::new( 2042 "class1_records", 2043 traversal::FieldType::computed_array( 2044 "Class1Record", 2045 self.class1_records(), 2046 self.offset_data(), 2047 ), 2048 )), 2049 _ => None, 2050 } 2051 } 2052 } 2053 2054 #[cfg(feature = "traversal")] 2055 impl<'a> std::fmt::Debug for PairPosFormat2<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2056 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 2057 (self as &dyn SomeTable<'a>).fmt(f) 2058 } 2059 } 2060 2061 /// Part of [PairPosFormat2] 2062 #[derive(Clone, Debug)] 2063 pub struct Class1Record<'a> { 2064 /// Array of Class2 records, ordered by classes in classDef2. 2065 pub class2_records: ComputedArray<'a, Class2Record>, 2066 } 2067 2068 impl<'a> Class1Record<'a> { 2069 /// Array of Class2 records, ordered by classes in classDef2. class2_records(&self) -> &ComputedArray<'a, Class2Record>2070 pub fn class2_records(&self) -> &ComputedArray<'a, Class2Record> { 2071 &self.class2_records 2072 } 2073 } 2074 2075 impl ReadArgs for Class1Record<'_> { 2076 type Args = (u16, ValueFormat, ValueFormat); 2077 } 2078 2079 impl ComputeSize for Class1Record<'_> { compute_size(args: &(u16, ValueFormat, ValueFormat)) -> usize2080 fn compute_size(args: &(u16, ValueFormat, ValueFormat)) -> usize { 2081 let (class2_count, value_format1, value_format2) = *args; 2082 class2_count as usize 2083 * <Class2Record as ComputeSize>::compute_size(&(value_format1, value_format2)) 2084 } 2085 } 2086 2087 impl<'a> FontReadWithArgs<'a> for Class1Record<'a> { read_with_args( data: FontData<'a>, args: &(u16, ValueFormat, ValueFormat), ) -> Result<Self, ReadError>2088 fn read_with_args( 2089 data: FontData<'a>, 2090 args: &(u16, ValueFormat, ValueFormat), 2091 ) -> Result<Self, ReadError> { 2092 let mut cursor = data.cursor(); 2093 let (class2_count, value_format1, value_format2) = *args; 2094 Ok(Self { 2095 class2_records: cursor 2096 .read_computed_array(class2_count as usize, &(value_format1, value_format2))?, 2097 }) 2098 } 2099 } 2100 2101 impl<'a> Class1Record<'a> { 2102 /// A constructor that requires additional arguments. 2103 /// 2104 /// This type requires some external state in order to be 2105 /// parsed. read( data: FontData<'a>, class2_count: u16, value_format1: ValueFormat, value_format2: ValueFormat, ) -> Result<Self, ReadError>2106 pub fn read( 2107 data: FontData<'a>, 2108 class2_count: u16, 2109 value_format1: ValueFormat, 2110 value_format2: ValueFormat, 2111 ) -> Result<Self, ReadError> { 2112 let args = (class2_count, value_format1, value_format2); 2113 Self::read_with_args(data, &args) 2114 } 2115 } 2116 2117 #[cfg(feature = "traversal")] 2118 impl<'a> SomeRecord<'a> for Class1Record<'a> { traverse(self, data: FontData<'a>) -> RecordResolver<'a>2119 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 2120 RecordResolver { 2121 name: "Class1Record", 2122 get_field: Box::new(move |idx, _data| match idx { 2123 0usize => Some(Field::new( 2124 "class2_records", 2125 traversal::FieldType::computed_array( 2126 "Class2Record", 2127 self.class2_records().clone(), 2128 FontData::new(&[]), 2129 ), 2130 )), 2131 _ => None, 2132 }), 2133 data, 2134 } 2135 } 2136 } 2137 2138 /// Part of [PairPosFormat2] 2139 #[derive(Clone, Debug)] 2140 pub struct Class2Record { 2141 /// Positioning for first glyph — empty if valueFormat1 = 0. 2142 pub value_record1: ValueRecord, 2143 /// Positioning for second glyph — empty if valueFormat2 = 0. 2144 pub value_record2: ValueRecord, 2145 } 2146 2147 impl Class2Record { 2148 /// Positioning for first glyph — empty if valueFormat1 = 0. value_record1(&self) -> &ValueRecord2149 pub fn value_record1(&self) -> &ValueRecord { 2150 &self.value_record1 2151 } 2152 2153 /// Positioning for second glyph — empty if valueFormat2 = 0. value_record2(&self) -> &ValueRecord2154 pub fn value_record2(&self) -> &ValueRecord { 2155 &self.value_record2 2156 } 2157 } 2158 2159 impl ReadArgs for Class2Record { 2160 type Args = (ValueFormat, ValueFormat); 2161 } 2162 2163 impl ComputeSize for Class2Record { compute_size(args: &(ValueFormat, ValueFormat)) -> usize2164 fn compute_size(args: &(ValueFormat, ValueFormat)) -> usize { 2165 let (value_format1, value_format2) = *args; 2166 <ValueRecord as ComputeSize>::compute_size(&value_format1) 2167 + <ValueRecord as ComputeSize>::compute_size(&value_format2) 2168 } 2169 } 2170 2171 impl<'a> FontReadWithArgs<'a> for Class2Record { read_with_args( data: FontData<'a>, args: &(ValueFormat, ValueFormat), ) -> Result<Self, ReadError>2172 fn read_with_args( 2173 data: FontData<'a>, 2174 args: &(ValueFormat, ValueFormat), 2175 ) -> Result<Self, ReadError> { 2176 let mut cursor = data.cursor(); 2177 let (value_format1, value_format2) = *args; 2178 Ok(Self { 2179 value_record1: cursor.read_with_args(&value_format1)?, 2180 value_record2: cursor.read_with_args(&value_format2)?, 2181 }) 2182 } 2183 } 2184 2185 impl<'a> Class2Record { 2186 /// A constructor that requires additional arguments. 2187 /// 2188 /// This type requires some external state in order to be 2189 /// parsed. read( data: FontData<'a>, value_format1: ValueFormat, value_format2: ValueFormat, ) -> Result<Self, ReadError>2190 pub fn read( 2191 data: FontData<'a>, 2192 value_format1: ValueFormat, 2193 value_format2: ValueFormat, 2194 ) -> Result<Self, ReadError> { 2195 let args = (value_format1, value_format2); 2196 Self::read_with_args(data, &args) 2197 } 2198 } 2199 2200 #[cfg(feature = "traversal")] 2201 impl<'a> SomeRecord<'a> for Class2Record { traverse(self, data: FontData<'a>) -> RecordResolver<'a>2202 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 2203 RecordResolver { 2204 name: "Class2Record", 2205 get_field: Box::new(move |idx, _data| match idx { 2206 0usize => Some(Field::new( 2207 "value_record1", 2208 self.value_record1().traversal_type(_data), 2209 )), 2210 1usize => Some(Field::new( 2211 "value_record2", 2212 self.value_record2().traversal_type(_data), 2213 )), 2214 _ => None, 2215 }), 2216 data, 2217 } 2218 } 2219 } 2220 2221 impl Format<u16> for CursivePosFormat1Marker { 2222 const FORMAT: u16 = 1; 2223 } 2224 2225 /// [Cursive Attachment Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#cursive-attachment-positioning-format1-cursive-attachment): Cursvie attachment 2226 #[derive(Debug, Clone, Copy)] 2227 #[doc(hidden)] 2228 pub struct CursivePosFormat1Marker { 2229 entry_exit_record_byte_len: usize, 2230 } 2231 2232 impl CursivePosFormat1Marker { pos_format_byte_range(&self) -> Range<usize>2233 fn pos_format_byte_range(&self) -> Range<usize> { 2234 let start = 0; 2235 start..start + u16::RAW_BYTE_LEN 2236 } coverage_offset_byte_range(&self) -> Range<usize>2237 fn coverage_offset_byte_range(&self) -> Range<usize> { 2238 let start = self.pos_format_byte_range().end; 2239 start..start + Offset16::RAW_BYTE_LEN 2240 } entry_exit_count_byte_range(&self) -> Range<usize>2241 fn entry_exit_count_byte_range(&self) -> Range<usize> { 2242 let start = self.coverage_offset_byte_range().end; 2243 start..start + u16::RAW_BYTE_LEN 2244 } entry_exit_record_byte_range(&self) -> Range<usize>2245 fn entry_exit_record_byte_range(&self) -> Range<usize> { 2246 let start = self.entry_exit_count_byte_range().end; 2247 start..start + self.entry_exit_record_byte_len 2248 } 2249 } 2250 2251 impl<'a> FontRead<'a> for CursivePosFormat1<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>2252 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 2253 let mut cursor = data.cursor(); 2254 cursor.advance::<u16>(); 2255 cursor.advance::<Offset16>(); 2256 let entry_exit_count: u16 = cursor.read()?; 2257 let entry_exit_record_byte_len = entry_exit_count as usize * EntryExitRecord::RAW_BYTE_LEN; 2258 cursor.advance_by(entry_exit_record_byte_len); 2259 cursor.finish(CursivePosFormat1Marker { 2260 entry_exit_record_byte_len, 2261 }) 2262 } 2263 } 2264 2265 /// [Cursive Attachment Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#cursive-attachment-positioning-format1-cursive-attachment): Cursvie attachment 2266 pub type CursivePosFormat1<'a> = TableRef<'a, CursivePosFormat1Marker>; 2267 2268 impl<'a> CursivePosFormat1<'a> { 2269 /// Format identifier: format = 1 pos_format(&self) -> u162270 pub fn pos_format(&self) -> u16 { 2271 let range = self.shape.pos_format_byte_range(); 2272 self.data.read_at(range.start).unwrap() 2273 } 2274 2275 /// Offset to Coverage table, from beginning of CursivePos subtable. coverage_offset(&self) -> Offset162276 pub fn coverage_offset(&self) -> Offset16 { 2277 let range = self.shape.coverage_offset_byte_range(); 2278 self.data.read_at(range.start).unwrap() 2279 } 2280 2281 /// Attempt to resolve [`coverage_offset`][Self::coverage_offset]. coverage(&self) -> Result<CoverageTable<'a>, ReadError>2282 pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> { 2283 let data = self.data; 2284 self.coverage_offset().resolve(data) 2285 } 2286 2287 /// Number of EntryExit records entry_exit_count(&self) -> u162288 pub fn entry_exit_count(&self) -> u16 { 2289 let range = self.shape.entry_exit_count_byte_range(); 2290 self.data.read_at(range.start).unwrap() 2291 } 2292 2293 /// Array of EntryExit records, in Coverage index order. entry_exit_record(&self) -> &'a [EntryExitRecord]2294 pub fn entry_exit_record(&self) -> &'a [EntryExitRecord] { 2295 let range = self.shape.entry_exit_record_byte_range(); 2296 self.data.read_array(range).unwrap() 2297 } 2298 } 2299 2300 #[cfg(feature = "traversal")] 2301 impl<'a> SomeTable<'a> for CursivePosFormat1<'a> { type_name(&self) -> &str2302 fn type_name(&self) -> &str { 2303 "CursivePosFormat1" 2304 } get_field(&self, idx: usize) -> Option<Field<'a>>2305 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 2306 match idx { 2307 0usize => Some(Field::new("pos_format", self.pos_format())), 2308 1usize => Some(Field::new( 2309 "coverage_offset", 2310 FieldType::offset(self.coverage_offset(), self.coverage()), 2311 )), 2312 2usize => Some(Field::new("entry_exit_count", self.entry_exit_count())), 2313 3usize => Some(Field::new( 2314 "entry_exit_record", 2315 traversal::FieldType::array_of_records( 2316 stringify!(EntryExitRecord), 2317 self.entry_exit_record(), 2318 self.offset_data(), 2319 ), 2320 )), 2321 _ => None, 2322 } 2323 } 2324 } 2325 2326 #[cfg(feature = "traversal")] 2327 impl<'a> std::fmt::Debug for CursivePosFormat1<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2328 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 2329 (self as &dyn SomeTable<'a>).fmt(f) 2330 } 2331 } 2332 2333 /// Part of [CursivePosFormat1] 2334 #[derive(Clone, Debug)] 2335 #[repr(C)] 2336 #[repr(packed)] 2337 pub struct EntryExitRecord { 2338 /// Offset to entryAnchor table, from beginning of CursivePos 2339 /// subtable (may be NULL). 2340 pub entry_anchor_offset: BigEndian<Nullable<Offset16>>, 2341 /// Offset to exitAnchor table, from beginning of CursivePos 2342 /// subtable (may be NULL). 2343 pub exit_anchor_offset: BigEndian<Nullable<Offset16>>, 2344 } 2345 2346 impl EntryExitRecord { 2347 /// Offset to entryAnchor table, from beginning of CursivePos 2348 /// subtable (may be NULL). entry_anchor_offset(&self) -> Nullable<Offset16>2349 pub fn entry_anchor_offset(&self) -> Nullable<Offset16> { 2350 self.entry_anchor_offset.get() 2351 } 2352 2353 /// Offset to entryAnchor table, from beginning of CursivePos 2354 /// subtable (may be NULL). 2355 /// 2356 /// The `data` argument should be retrieved from the parent table 2357 /// By calling its `offset_data` method. entry_anchor<'a>( &self, data: FontData<'a>, ) -> Option<Result<AnchorTable<'a>, ReadError>>2358 pub fn entry_anchor<'a>( 2359 &self, 2360 data: FontData<'a>, 2361 ) -> Option<Result<AnchorTable<'a>, ReadError>> { 2362 self.entry_anchor_offset().resolve(data) 2363 } 2364 2365 /// Offset to exitAnchor table, from beginning of CursivePos 2366 /// subtable (may be NULL). exit_anchor_offset(&self) -> Nullable<Offset16>2367 pub fn exit_anchor_offset(&self) -> Nullable<Offset16> { 2368 self.exit_anchor_offset.get() 2369 } 2370 2371 /// Offset to exitAnchor table, from beginning of CursivePos 2372 /// subtable (may be NULL). 2373 /// 2374 /// The `data` argument should be retrieved from the parent table 2375 /// By calling its `offset_data` method. exit_anchor<'a>( &self, data: FontData<'a>, ) -> Option<Result<AnchorTable<'a>, ReadError>>2376 pub fn exit_anchor<'a>( 2377 &self, 2378 data: FontData<'a>, 2379 ) -> Option<Result<AnchorTable<'a>, ReadError>> { 2380 self.exit_anchor_offset().resolve(data) 2381 } 2382 } 2383 2384 impl FixedSize for EntryExitRecord { 2385 const RAW_BYTE_LEN: usize = Offset16::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN; 2386 } 2387 2388 impl sealed::Sealed for EntryExitRecord {} 2389 2390 /// SAFETY: see the [`FromBytes`] trait documentation. 2391 unsafe impl FromBytes for EntryExitRecord { this_trait_should_only_be_implemented_in_generated_code()2392 fn this_trait_should_only_be_implemented_in_generated_code() {} 2393 } 2394 2395 #[cfg(feature = "traversal")] 2396 impl<'a> SomeRecord<'a> for EntryExitRecord { traverse(self, data: FontData<'a>) -> RecordResolver<'a>2397 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 2398 RecordResolver { 2399 name: "EntryExitRecord", 2400 get_field: Box::new(move |idx, _data| match idx { 2401 0usize => Some(Field::new( 2402 "entry_anchor_offset", 2403 FieldType::offset(self.entry_anchor_offset(), self.entry_anchor(_data)), 2404 )), 2405 1usize => Some(Field::new( 2406 "exit_anchor_offset", 2407 FieldType::offset(self.exit_anchor_offset(), self.exit_anchor(_data)), 2408 )), 2409 _ => None, 2410 }), 2411 data, 2412 } 2413 } 2414 } 2415 2416 impl Format<u16> for MarkBasePosFormat1Marker { 2417 const FORMAT: u16 = 1; 2418 } 2419 2420 /// [Mark-to-Base Attachment Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#mark-to-base-attachment-positioning-format-1-mark-to-base-attachment-point): Mark-to-base Attachment Point 2421 #[derive(Debug, Clone, Copy)] 2422 #[doc(hidden)] 2423 pub struct MarkBasePosFormat1Marker {} 2424 2425 impl MarkBasePosFormat1Marker { pos_format_byte_range(&self) -> Range<usize>2426 fn pos_format_byte_range(&self) -> Range<usize> { 2427 let start = 0; 2428 start..start + u16::RAW_BYTE_LEN 2429 } mark_coverage_offset_byte_range(&self) -> Range<usize>2430 fn mark_coverage_offset_byte_range(&self) -> Range<usize> { 2431 let start = self.pos_format_byte_range().end; 2432 start..start + Offset16::RAW_BYTE_LEN 2433 } base_coverage_offset_byte_range(&self) -> Range<usize>2434 fn base_coverage_offset_byte_range(&self) -> Range<usize> { 2435 let start = self.mark_coverage_offset_byte_range().end; 2436 start..start + Offset16::RAW_BYTE_LEN 2437 } mark_class_count_byte_range(&self) -> Range<usize>2438 fn mark_class_count_byte_range(&self) -> Range<usize> { 2439 let start = self.base_coverage_offset_byte_range().end; 2440 start..start + u16::RAW_BYTE_LEN 2441 } mark_array_offset_byte_range(&self) -> Range<usize>2442 fn mark_array_offset_byte_range(&self) -> Range<usize> { 2443 let start = self.mark_class_count_byte_range().end; 2444 start..start + Offset16::RAW_BYTE_LEN 2445 } base_array_offset_byte_range(&self) -> Range<usize>2446 fn base_array_offset_byte_range(&self) -> Range<usize> { 2447 let start = self.mark_array_offset_byte_range().end; 2448 start..start + Offset16::RAW_BYTE_LEN 2449 } 2450 } 2451 2452 impl<'a> FontRead<'a> for MarkBasePosFormat1<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>2453 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 2454 let mut cursor = data.cursor(); 2455 cursor.advance::<u16>(); 2456 cursor.advance::<Offset16>(); 2457 cursor.advance::<Offset16>(); 2458 cursor.advance::<u16>(); 2459 cursor.advance::<Offset16>(); 2460 cursor.advance::<Offset16>(); 2461 cursor.finish(MarkBasePosFormat1Marker {}) 2462 } 2463 } 2464 2465 /// [Mark-to-Base Attachment Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#mark-to-base-attachment-positioning-format-1-mark-to-base-attachment-point): Mark-to-base Attachment Point 2466 pub type MarkBasePosFormat1<'a> = TableRef<'a, MarkBasePosFormat1Marker>; 2467 2468 impl<'a> MarkBasePosFormat1<'a> { 2469 /// Format identifier: format = 1 pos_format(&self) -> u162470 pub fn pos_format(&self) -> u16 { 2471 let range = self.shape.pos_format_byte_range(); 2472 self.data.read_at(range.start).unwrap() 2473 } 2474 2475 /// Offset to markCoverage table, from beginning of MarkBasePos 2476 /// subtable. mark_coverage_offset(&self) -> Offset162477 pub fn mark_coverage_offset(&self) -> Offset16 { 2478 let range = self.shape.mark_coverage_offset_byte_range(); 2479 self.data.read_at(range.start).unwrap() 2480 } 2481 2482 /// Attempt to resolve [`mark_coverage_offset`][Self::mark_coverage_offset]. mark_coverage(&self) -> Result<CoverageTable<'a>, ReadError>2483 pub fn mark_coverage(&self) -> Result<CoverageTable<'a>, ReadError> { 2484 let data = self.data; 2485 self.mark_coverage_offset().resolve(data) 2486 } 2487 2488 /// Offset to baseCoverage table, from beginning of MarkBasePos 2489 /// subtable. base_coverage_offset(&self) -> Offset162490 pub fn base_coverage_offset(&self) -> Offset16 { 2491 let range = self.shape.base_coverage_offset_byte_range(); 2492 self.data.read_at(range.start).unwrap() 2493 } 2494 2495 /// Attempt to resolve [`base_coverage_offset`][Self::base_coverage_offset]. base_coverage(&self) -> Result<CoverageTable<'a>, ReadError>2496 pub fn base_coverage(&self) -> Result<CoverageTable<'a>, ReadError> { 2497 let data = self.data; 2498 self.base_coverage_offset().resolve(data) 2499 } 2500 2501 /// Number of classes defined for marks mark_class_count(&self) -> u162502 pub fn mark_class_count(&self) -> u16 { 2503 let range = self.shape.mark_class_count_byte_range(); 2504 self.data.read_at(range.start).unwrap() 2505 } 2506 2507 /// Offset to MarkArray table, from beginning of MarkBasePos 2508 /// subtable. mark_array_offset(&self) -> Offset162509 pub fn mark_array_offset(&self) -> Offset16 { 2510 let range = self.shape.mark_array_offset_byte_range(); 2511 self.data.read_at(range.start).unwrap() 2512 } 2513 2514 /// Attempt to resolve [`mark_array_offset`][Self::mark_array_offset]. mark_array(&self) -> Result<MarkArray<'a>, ReadError>2515 pub fn mark_array(&self) -> Result<MarkArray<'a>, ReadError> { 2516 let data = self.data; 2517 self.mark_array_offset().resolve(data) 2518 } 2519 2520 /// Offset to BaseArray table, from beginning of MarkBasePos 2521 /// subtable. base_array_offset(&self) -> Offset162522 pub fn base_array_offset(&self) -> Offset16 { 2523 let range = self.shape.base_array_offset_byte_range(); 2524 self.data.read_at(range.start).unwrap() 2525 } 2526 2527 /// Attempt to resolve [`base_array_offset`][Self::base_array_offset]. base_array(&self) -> Result<BaseArray<'a>, ReadError>2528 pub fn base_array(&self) -> Result<BaseArray<'a>, ReadError> { 2529 let data = self.data; 2530 let args = self.mark_class_count(); 2531 self.base_array_offset().resolve_with_args(data, &args) 2532 } 2533 } 2534 2535 #[cfg(feature = "traversal")] 2536 impl<'a> SomeTable<'a> for MarkBasePosFormat1<'a> { type_name(&self) -> &str2537 fn type_name(&self) -> &str { 2538 "MarkBasePosFormat1" 2539 } get_field(&self, idx: usize) -> Option<Field<'a>>2540 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 2541 match idx { 2542 0usize => Some(Field::new("pos_format", self.pos_format())), 2543 1usize => Some(Field::new( 2544 "mark_coverage_offset", 2545 FieldType::offset(self.mark_coverage_offset(), self.mark_coverage()), 2546 )), 2547 2usize => Some(Field::new( 2548 "base_coverage_offset", 2549 FieldType::offset(self.base_coverage_offset(), self.base_coverage()), 2550 )), 2551 3usize => Some(Field::new("mark_class_count", self.mark_class_count())), 2552 4usize => Some(Field::new( 2553 "mark_array_offset", 2554 FieldType::offset(self.mark_array_offset(), self.mark_array()), 2555 )), 2556 5usize => Some(Field::new( 2557 "base_array_offset", 2558 FieldType::offset(self.base_array_offset(), self.base_array()), 2559 )), 2560 _ => None, 2561 } 2562 } 2563 } 2564 2565 #[cfg(feature = "traversal")] 2566 impl<'a> std::fmt::Debug for MarkBasePosFormat1<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2567 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 2568 (self as &dyn SomeTable<'a>).fmt(f) 2569 } 2570 } 2571 2572 /// Part of [MarkBasePosFormat1] 2573 #[derive(Debug, Clone, Copy)] 2574 #[doc(hidden)] 2575 pub struct BaseArrayMarker { 2576 mark_class_count: u16, 2577 base_records_byte_len: usize, 2578 } 2579 2580 impl BaseArrayMarker { base_count_byte_range(&self) -> Range<usize>2581 fn base_count_byte_range(&self) -> Range<usize> { 2582 let start = 0; 2583 start..start + u16::RAW_BYTE_LEN 2584 } base_records_byte_range(&self) -> Range<usize>2585 fn base_records_byte_range(&self) -> Range<usize> { 2586 let start = self.base_count_byte_range().end; 2587 start..start + self.base_records_byte_len 2588 } 2589 } 2590 2591 impl ReadArgs for BaseArray<'_> { 2592 type Args = u16; 2593 } 2594 2595 impl<'a> FontReadWithArgs<'a> for BaseArray<'a> { read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError>2596 fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> { 2597 let mark_class_count = *args; 2598 let mut cursor = data.cursor(); 2599 let base_count: u16 = cursor.read()?; 2600 let base_records_byte_len = 2601 base_count as usize * <BaseRecord as ComputeSize>::compute_size(&mark_class_count); 2602 cursor.advance_by(base_records_byte_len); 2603 cursor.finish(BaseArrayMarker { 2604 mark_class_count, 2605 base_records_byte_len, 2606 }) 2607 } 2608 } 2609 2610 impl<'a> BaseArray<'a> { 2611 /// A constructor that requires additional arguments. 2612 /// 2613 /// This type requires some external state in order to be 2614 /// parsed. read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError>2615 pub fn read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError> { 2616 let args = mark_class_count; 2617 Self::read_with_args(data, &args) 2618 } 2619 } 2620 2621 /// Part of [MarkBasePosFormat1] 2622 pub type BaseArray<'a> = TableRef<'a, BaseArrayMarker>; 2623 2624 impl<'a> BaseArray<'a> { 2625 /// Number of BaseRecords base_count(&self) -> u162626 pub fn base_count(&self) -> u16 { 2627 let range = self.shape.base_count_byte_range(); 2628 self.data.read_at(range.start).unwrap() 2629 } 2630 2631 /// Array of BaseRecords, in order of baseCoverage Index. base_records(&self) -> ComputedArray<'a, BaseRecord<'a>>2632 pub fn base_records(&self) -> ComputedArray<'a, BaseRecord<'a>> { 2633 let range = self.shape.base_records_byte_range(); 2634 self.data 2635 .read_with_args(range, &self.mark_class_count()) 2636 .unwrap() 2637 } 2638 mark_class_count(&self) -> u162639 pub(crate) fn mark_class_count(&self) -> u16 { 2640 self.shape.mark_class_count 2641 } 2642 } 2643 2644 #[cfg(feature = "traversal")] 2645 impl<'a> SomeTable<'a> for BaseArray<'a> { type_name(&self) -> &str2646 fn type_name(&self) -> &str { 2647 "BaseArray" 2648 } get_field(&self, idx: usize) -> Option<Field<'a>>2649 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 2650 match idx { 2651 0usize => Some(Field::new("base_count", self.base_count())), 2652 1usize => Some(Field::new( 2653 "base_records", 2654 traversal::FieldType::computed_array( 2655 "BaseRecord", 2656 self.base_records(), 2657 self.offset_data(), 2658 ), 2659 )), 2660 _ => None, 2661 } 2662 } 2663 } 2664 2665 #[cfg(feature = "traversal")] 2666 impl<'a> std::fmt::Debug for BaseArray<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2667 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 2668 (self as &dyn SomeTable<'a>).fmt(f) 2669 } 2670 } 2671 2672 /// Part of [BaseArray] 2673 #[derive(Clone, Debug)] 2674 pub struct BaseRecord<'a> { 2675 /// Array of offsets (one per mark class) to Anchor tables. Offsets 2676 /// are from beginning of BaseArray table, ordered by class 2677 /// (offsets may be NULL). 2678 pub base_anchor_offsets: &'a [BigEndian<Nullable<Offset16>>], 2679 } 2680 2681 impl<'a> BaseRecord<'a> { 2682 /// Array of offsets (one per mark class) to Anchor tables. Offsets 2683 /// are from beginning of BaseArray table, ordered by class 2684 /// (offsets may be NULL). base_anchor_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>]2685 pub fn base_anchor_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>] { 2686 self.base_anchor_offsets 2687 } 2688 2689 /// Array of offsets (one per mark class) to Anchor tables. Offsets 2690 /// are from beginning of BaseArray table, ordered by class 2691 /// (offsets may be NULL). 2692 /// 2693 /// The `data` argument should be retrieved from the parent table 2694 /// By calling its `offset_data` method. base_anchors( &self, data: FontData<'a>, ) -> ArrayOfNullableOffsets<'a, AnchorTable<'a>, Offset16>2695 pub fn base_anchors( 2696 &self, 2697 data: FontData<'a>, 2698 ) -> ArrayOfNullableOffsets<'a, AnchorTable<'a>, Offset16> { 2699 let offsets = self.base_anchor_offsets(); 2700 ArrayOfNullableOffsets::new(offsets, data, ()) 2701 } 2702 } 2703 2704 impl ReadArgs for BaseRecord<'_> { 2705 type Args = u16; 2706 } 2707 2708 impl ComputeSize for BaseRecord<'_> { compute_size(args: &u16) -> usize2709 fn compute_size(args: &u16) -> usize { 2710 let mark_class_count = *args; 2711 mark_class_count as usize * Offset16::RAW_BYTE_LEN 2712 } 2713 } 2714 2715 impl<'a> FontReadWithArgs<'a> for BaseRecord<'a> { read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError>2716 fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> { 2717 let mut cursor = data.cursor(); 2718 let mark_class_count = *args; 2719 Ok(Self { 2720 base_anchor_offsets: cursor.read_array(mark_class_count as usize)?, 2721 }) 2722 } 2723 } 2724 2725 impl<'a> BaseRecord<'a> { 2726 /// A constructor that requires additional arguments. 2727 /// 2728 /// This type requires some external state in order to be 2729 /// parsed. read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError>2730 pub fn read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError> { 2731 let args = mark_class_count; 2732 Self::read_with_args(data, &args) 2733 } 2734 } 2735 2736 #[cfg(feature = "traversal")] 2737 impl<'a> SomeRecord<'a> for BaseRecord<'a> { traverse(self, data: FontData<'a>) -> RecordResolver<'a>2738 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 2739 RecordResolver { 2740 name: "BaseRecord", 2741 get_field: Box::new(move |idx, _data| match idx { 2742 0usize => Some({ 2743 Field::new( 2744 "base_anchor_offsets", 2745 FieldType::array_of_offsets( 2746 better_type_name::<AnchorTable>(), 2747 self.base_anchor_offsets(), 2748 move |off| { 2749 let target = off.get().resolve::<AnchorTable>(data); 2750 FieldType::offset(off.get(), target) 2751 }, 2752 ), 2753 ) 2754 }), 2755 _ => None, 2756 }), 2757 data, 2758 } 2759 } 2760 } 2761 2762 impl Format<u16> for MarkLigPosFormat1Marker { 2763 const FORMAT: u16 = 1; 2764 } 2765 2766 /// [Mark-to-Ligature Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#mark-to-ligature-attachment-positioning-format-1-mark-to-ligature-attachment): Mark-to-Ligature Attachment 2767 #[derive(Debug, Clone, Copy)] 2768 #[doc(hidden)] 2769 pub struct MarkLigPosFormat1Marker {} 2770 2771 impl MarkLigPosFormat1Marker { pos_format_byte_range(&self) -> Range<usize>2772 fn pos_format_byte_range(&self) -> Range<usize> { 2773 let start = 0; 2774 start..start + u16::RAW_BYTE_LEN 2775 } mark_coverage_offset_byte_range(&self) -> Range<usize>2776 fn mark_coverage_offset_byte_range(&self) -> Range<usize> { 2777 let start = self.pos_format_byte_range().end; 2778 start..start + Offset16::RAW_BYTE_LEN 2779 } ligature_coverage_offset_byte_range(&self) -> Range<usize>2780 fn ligature_coverage_offset_byte_range(&self) -> Range<usize> { 2781 let start = self.mark_coverage_offset_byte_range().end; 2782 start..start + Offset16::RAW_BYTE_LEN 2783 } mark_class_count_byte_range(&self) -> Range<usize>2784 fn mark_class_count_byte_range(&self) -> Range<usize> { 2785 let start = self.ligature_coverage_offset_byte_range().end; 2786 start..start + u16::RAW_BYTE_LEN 2787 } mark_array_offset_byte_range(&self) -> Range<usize>2788 fn mark_array_offset_byte_range(&self) -> Range<usize> { 2789 let start = self.mark_class_count_byte_range().end; 2790 start..start + Offset16::RAW_BYTE_LEN 2791 } ligature_array_offset_byte_range(&self) -> Range<usize>2792 fn ligature_array_offset_byte_range(&self) -> Range<usize> { 2793 let start = self.mark_array_offset_byte_range().end; 2794 start..start + Offset16::RAW_BYTE_LEN 2795 } 2796 } 2797 2798 impl<'a> FontRead<'a> for MarkLigPosFormat1<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>2799 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 2800 let mut cursor = data.cursor(); 2801 cursor.advance::<u16>(); 2802 cursor.advance::<Offset16>(); 2803 cursor.advance::<Offset16>(); 2804 cursor.advance::<u16>(); 2805 cursor.advance::<Offset16>(); 2806 cursor.advance::<Offset16>(); 2807 cursor.finish(MarkLigPosFormat1Marker {}) 2808 } 2809 } 2810 2811 /// [Mark-to-Ligature Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#mark-to-ligature-attachment-positioning-format-1-mark-to-ligature-attachment): Mark-to-Ligature Attachment 2812 pub type MarkLigPosFormat1<'a> = TableRef<'a, MarkLigPosFormat1Marker>; 2813 2814 impl<'a> MarkLigPosFormat1<'a> { 2815 /// Format identifier: format = 1 pos_format(&self) -> u162816 pub fn pos_format(&self) -> u16 { 2817 let range = self.shape.pos_format_byte_range(); 2818 self.data.read_at(range.start).unwrap() 2819 } 2820 2821 /// Offset to markCoverage table, from beginning of MarkLigPos 2822 /// subtable. mark_coverage_offset(&self) -> Offset162823 pub fn mark_coverage_offset(&self) -> Offset16 { 2824 let range = self.shape.mark_coverage_offset_byte_range(); 2825 self.data.read_at(range.start).unwrap() 2826 } 2827 2828 /// Attempt to resolve [`mark_coverage_offset`][Self::mark_coverage_offset]. mark_coverage(&self) -> Result<CoverageTable<'a>, ReadError>2829 pub fn mark_coverage(&self) -> Result<CoverageTable<'a>, ReadError> { 2830 let data = self.data; 2831 self.mark_coverage_offset().resolve(data) 2832 } 2833 2834 /// Offset to ligatureCoverage table, from beginning of MarkLigPos 2835 /// subtable. ligature_coverage_offset(&self) -> Offset162836 pub fn ligature_coverage_offset(&self) -> Offset16 { 2837 let range = self.shape.ligature_coverage_offset_byte_range(); 2838 self.data.read_at(range.start).unwrap() 2839 } 2840 2841 /// Attempt to resolve [`ligature_coverage_offset`][Self::ligature_coverage_offset]. ligature_coverage(&self) -> Result<CoverageTable<'a>, ReadError>2842 pub fn ligature_coverage(&self) -> Result<CoverageTable<'a>, ReadError> { 2843 let data = self.data; 2844 self.ligature_coverage_offset().resolve(data) 2845 } 2846 2847 /// Number of defined mark classes mark_class_count(&self) -> u162848 pub fn mark_class_count(&self) -> u16 { 2849 let range = self.shape.mark_class_count_byte_range(); 2850 self.data.read_at(range.start).unwrap() 2851 } 2852 2853 /// Offset to MarkArray table, from beginning of MarkLigPos 2854 /// subtable. mark_array_offset(&self) -> Offset162855 pub fn mark_array_offset(&self) -> Offset16 { 2856 let range = self.shape.mark_array_offset_byte_range(); 2857 self.data.read_at(range.start).unwrap() 2858 } 2859 2860 /// Attempt to resolve [`mark_array_offset`][Self::mark_array_offset]. mark_array(&self) -> Result<MarkArray<'a>, ReadError>2861 pub fn mark_array(&self) -> Result<MarkArray<'a>, ReadError> { 2862 let data = self.data; 2863 self.mark_array_offset().resolve(data) 2864 } 2865 2866 /// Offset to LigatureArray table, from beginning of MarkLigPos 2867 /// subtable. ligature_array_offset(&self) -> Offset162868 pub fn ligature_array_offset(&self) -> Offset16 { 2869 let range = self.shape.ligature_array_offset_byte_range(); 2870 self.data.read_at(range.start).unwrap() 2871 } 2872 2873 /// Attempt to resolve [`ligature_array_offset`][Self::ligature_array_offset]. ligature_array(&self) -> Result<LigatureArray<'a>, ReadError>2874 pub fn ligature_array(&self) -> Result<LigatureArray<'a>, ReadError> { 2875 let data = self.data; 2876 let args = self.mark_class_count(); 2877 self.ligature_array_offset().resolve_with_args(data, &args) 2878 } 2879 } 2880 2881 #[cfg(feature = "traversal")] 2882 impl<'a> SomeTable<'a> for MarkLigPosFormat1<'a> { type_name(&self) -> &str2883 fn type_name(&self) -> &str { 2884 "MarkLigPosFormat1" 2885 } get_field(&self, idx: usize) -> Option<Field<'a>>2886 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 2887 match idx { 2888 0usize => Some(Field::new("pos_format", self.pos_format())), 2889 1usize => Some(Field::new( 2890 "mark_coverage_offset", 2891 FieldType::offset(self.mark_coverage_offset(), self.mark_coverage()), 2892 )), 2893 2usize => Some(Field::new( 2894 "ligature_coverage_offset", 2895 FieldType::offset(self.ligature_coverage_offset(), self.ligature_coverage()), 2896 )), 2897 3usize => Some(Field::new("mark_class_count", self.mark_class_count())), 2898 4usize => Some(Field::new( 2899 "mark_array_offset", 2900 FieldType::offset(self.mark_array_offset(), self.mark_array()), 2901 )), 2902 5usize => Some(Field::new( 2903 "ligature_array_offset", 2904 FieldType::offset(self.ligature_array_offset(), self.ligature_array()), 2905 )), 2906 _ => None, 2907 } 2908 } 2909 } 2910 2911 #[cfg(feature = "traversal")] 2912 impl<'a> std::fmt::Debug for MarkLigPosFormat1<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2913 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 2914 (self as &dyn SomeTable<'a>).fmt(f) 2915 } 2916 } 2917 2918 /// Part of [MarkLigPosFormat1] 2919 #[derive(Debug, Clone, Copy)] 2920 #[doc(hidden)] 2921 pub struct LigatureArrayMarker { 2922 mark_class_count: u16, 2923 ligature_attach_offsets_byte_len: usize, 2924 } 2925 2926 impl LigatureArrayMarker { ligature_count_byte_range(&self) -> Range<usize>2927 fn ligature_count_byte_range(&self) -> Range<usize> { 2928 let start = 0; 2929 start..start + u16::RAW_BYTE_LEN 2930 } ligature_attach_offsets_byte_range(&self) -> Range<usize>2931 fn ligature_attach_offsets_byte_range(&self) -> Range<usize> { 2932 let start = self.ligature_count_byte_range().end; 2933 start..start + self.ligature_attach_offsets_byte_len 2934 } 2935 } 2936 2937 impl ReadArgs for LigatureArray<'_> { 2938 type Args = u16; 2939 } 2940 2941 impl<'a> FontReadWithArgs<'a> for LigatureArray<'a> { read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError>2942 fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> { 2943 let mark_class_count = *args; 2944 let mut cursor = data.cursor(); 2945 let ligature_count: u16 = cursor.read()?; 2946 let ligature_attach_offsets_byte_len = ligature_count as usize * Offset16::RAW_BYTE_LEN; 2947 cursor.advance_by(ligature_attach_offsets_byte_len); 2948 cursor.finish(LigatureArrayMarker { 2949 mark_class_count, 2950 ligature_attach_offsets_byte_len, 2951 }) 2952 } 2953 } 2954 2955 impl<'a> LigatureArray<'a> { 2956 /// A constructor that requires additional arguments. 2957 /// 2958 /// This type requires some external state in order to be 2959 /// parsed. read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError>2960 pub fn read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError> { 2961 let args = mark_class_count; 2962 Self::read_with_args(data, &args) 2963 } 2964 } 2965 2966 /// Part of [MarkLigPosFormat1] 2967 pub type LigatureArray<'a> = TableRef<'a, LigatureArrayMarker>; 2968 2969 impl<'a> LigatureArray<'a> { 2970 /// Number of LigatureAttach table offsets ligature_count(&self) -> u162971 pub fn ligature_count(&self) -> u16 { 2972 let range = self.shape.ligature_count_byte_range(); 2973 self.data.read_at(range.start).unwrap() 2974 } 2975 2976 /// Array of offsets to LigatureAttach tables. Offsets are from 2977 /// beginning of LigatureArray table, ordered by ligatureCoverage 2978 /// index. ligature_attach_offsets(&self) -> &'a [BigEndian<Offset16>]2979 pub fn ligature_attach_offsets(&self) -> &'a [BigEndian<Offset16>] { 2980 let range = self.shape.ligature_attach_offsets_byte_range(); 2981 self.data.read_array(range).unwrap() 2982 } 2983 2984 /// A dynamically resolving wrapper for [`ligature_attach_offsets`][Self::ligature_attach_offsets]. ligature_attaches(&self) -> ArrayOfOffsets<'a, LigatureAttach<'a>, Offset16>2985 pub fn ligature_attaches(&self) -> ArrayOfOffsets<'a, LigatureAttach<'a>, Offset16> { 2986 let data = self.data; 2987 let offsets = self.ligature_attach_offsets(); 2988 let args = self.mark_class_count(); 2989 ArrayOfOffsets::new(offsets, data, args) 2990 } 2991 mark_class_count(&self) -> u162992 pub(crate) fn mark_class_count(&self) -> u16 { 2993 self.shape.mark_class_count 2994 } 2995 } 2996 2997 #[cfg(feature = "traversal")] 2998 impl<'a> SomeTable<'a> for LigatureArray<'a> { type_name(&self) -> &str2999 fn type_name(&self) -> &str { 3000 "LigatureArray" 3001 } get_field(&self, idx: usize) -> Option<Field<'a>>3002 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3003 match idx { 3004 0usize => Some(Field::new("ligature_count", self.ligature_count())), 3005 1usize => Some({ 3006 let data = self.data; 3007 let args = self.mark_class_count(); 3008 Field::new( 3009 "ligature_attach_offsets", 3010 FieldType::array_of_offsets( 3011 better_type_name::<LigatureAttach>(), 3012 self.ligature_attach_offsets(), 3013 move |off| { 3014 let target = off.get().resolve_with_args::<LigatureAttach>(data, &args); 3015 FieldType::offset(off.get(), target) 3016 }, 3017 ), 3018 ) 3019 }), 3020 _ => None, 3021 } 3022 } 3023 } 3024 3025 #[cfg(feature = "traversal")] 3026 impl<'a> std::fmt::Debug for LigatureArray<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3027 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3028 (self as &dyn SomeTable<'a>).fmt(f) 3029 } 3030 } 3031 3032 /// Part of [MarkLigPosFormat1] 3033 #[derive(Debug, Clone, Copy)] 3034 #[doc(hidden)] 3035 pub struct LigatureAttachMarker { 3036 mark_class_count: u16, 3037 component_records_byte_len: usize, 3038 } 3039 3040 impl LigatureAttachMarker { component_count_byte_range(&self) -> Range<usize>3041 fn component_count_byte_range(&self) -> Range<usize> { 3042 let start = 0; 3043 start..start + u16::RAW_BYTE_LEN 3044 } component_records_byte_range(&self) -> Range<usize>3045 fn component_records_byte_range(&self) -> Range<usize> { 3046 let start = self.component_count_byte_range().end; 3047 start..start + self.component_records_byte_len 3048 } 3049 } 3050 3051 impl ReadArgs for LigatureAttach<'_> { 3052 type Args = u16; 3053 } 3054 3055 impl<'a> FontReadWithArgs<'a> for LigatureAttach<'a> { read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError>3056 fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> { 3057 let mark_class_count = *args; 3058 let mut cursor = data.cursor(); 3059 let component_count: u16 = cursor.read()?; 3060 let component_records_byte_len = component_count as usize 3061 * <ComponentRecord as ComputeSize>::compute_size(&mark_class_count); 3062 cursor.advance_by(component_records_byte_len); 3063 cursor.finish(LigatureAttachMarker { 3064 mark_class_count, 3065 component_records_byte_len, 3066 }) 3067 } 3068 } 3069 3070 impl<'a> LigatureAttach<'a> { 3071 /// A constructor that requires additional arguments. 3072 /// 3073 /// This type requires some external state in order to be 3074 /// parsed. read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError>3075 pub fn read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError> { 3076 let args = mark_class_count; 3077 Self::read_with_args(data, &args) 3078 } 3079 } 3080 3081 /// Part of [MarkLigPosFormat1] 3082 pub type LigatureAttach<'a> = TableRef<'a, LigatureAttachMarker>; 3083 3084 impl<'a> LigatureAttach<'a> { 3085 /// Number of ComponentRecords in this ligature component_count(&self) -> u163086 pub fn component_count(&self) -> u16 { 3087 let range = self.shape.component_count_byte_range(); 3088 self.data.read_at(range.start).unwrap() 3089 } 3090 3091 /// Array of Component records, ordered in writing direction. component_records(&self) -> ComputedArray<'a, ComponentRecord<'a>>3092 pub fn component_records(&self) -> ComputedArray<'a, ComponentRecord<'a>> { 3093 let range = self.shape.component_records_byte_range(); 3094 self.data 3095 .read_with_args(range, &self.mark_class_count()) 3096 .unwrap() 3097 } 3098 mark_class_count(&self) -> u163099 pub(crate) fn mark_class_count(&self) -> u16 { 3100 self.shape.mark_class_count 3101 } 3102 } 3103 3104 #[cfg(feature = "traversal")] 3105 impl<'a> SomeTable<'a> for LigatureAttach<'a> { type_name(&self) -> &str3106 fn type_name(&self) -> &str { 3107 "LigatureAttach" 3108 } get_field(&self, idx: usize) -> Option<Field<'a>>3109 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3110 match idx { 3111 0usize => Some(Field::new("component_count", self.component_count())), 3112 1usize => Some(Field::new( 3113 "component_records", 3114 traversal::FieldType::computed_array( 3115 "ComponentRecord", 3116 self.component_records(), 3117 self.offset_data(), 3118 ), 3119 )), 3120 _ => None, 3121 } 3122 } 3123 } 3124 3125 #[cfg(feature = "traversal")] 3126 impl<'a> std::fmt::Debug for LigatureAttach<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3127 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3128 (self as &dyn SomeTable<'a>).fmt(f) 3129 } 3130 } 3131 3132 /// Part of [MarkLigPosFormat1] 3133 #[derive(Clone, Debug)] 3134 pub struct ComponentRecord<'a> { 3135 /// Array of offsets (one per class) to Anchor tables. Offsets are 3136 /// from beginning of LigatureAttach table, ordered by class 3137 /// (offsets may be NULL). 3138 pub ligature_anchor_offsets: &'a [BigEndian<Nullable<Offset16>>], 3139 } 3140 3141 impl<'a> ComponentRecord<'a> { 3142 /// Array of offsets (one per class) to Anchor tables. Offsets are 3143 /// from beginning of LigatureAttach table, ordered by class 3144 /// (offsets may be NULL). ligature_anchor_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>]3145 pub fn ligature_anchor_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>] { 3146 self.ligature_anchor_offsets 3147 } 3148 3149 /// Array of offsets (one per class) to Anchor tables. Offsets are 3150 /// from beginning of LigatureAttach table, ordered by class 3151 /// (offsets may be NULL). 3152 /// 3153 /// The `data` argument should be retrieved from the parent table 3154 /// By calling its `offset_data` method. ligature_anchors( &self, data: FontData<'a>, ) -> ArrayOfNullableOffsets<'a, AnchorTable<'a>, Offset16>3155 pub fn ligature_anchors( 3156 &self, 3157 data: FontData<'a>, 3158 ) -> ArrayOfNullableOffsets<'a, AnchorTable<'a>, Offset16> { 3159 let offsets = self.ligature_anchor_offsets(); 3160 ArrayOfNullableOffsets::new(offsets, data, ()) 3161 } 3162 } 3163 3164 impl ReadArgs for ComponentRecord<'_> { 3165 type Args = u16; 3166 } 3167 3168 impl ComputeSize for ComponentRecord<'_> { compute_size(args: &u16) -> usize3169 fn compute_size(args: &u16) -> usize { 3170 let mark_class_count = *args; 3171 mark_class_count as usize * Offset16::RAW_BYTE_LEN 3172 } 3173 } 3174 3175 impl<'a> FontReadWithArgs<'a> for ComponentRecord<'a> { read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError>3176 fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> { 3177 let mut cursor = data.cursor(); 3178 let mark_class_count = *args; 3179 Ok(Self { 3180 ligature_anchor_offsets: cursor.read_array(mark_class_count as usize)?, 3181 }) 3182 } 3183 } 3184 3185 impl<'a> ComponentRecord<'a> { 3186 /// A constructor that requires additional arguments. 3187 /// 3188 /// This type requires some external state in order to be 3189 /// parsed. read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError>3190 pub fn read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError> { 3191 let args = mark_class_count; 3192 Self::read_with_args(data, &args) 3193 } 3194 } 3195 3196 #[cfg(feature = "traversal")] 3197 impl<'a> SomeRecord<'a> for ComponentRecord<'a> { traverse(self, data: FontData<'a>) -> RecordResolver<'a>3198 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 3199 RecordResolver { 3200 name: "ComponentRecord", 3201 get_field: Box::new(move |idx, _data| match idx { 3202 0usize => Some({ 3203 Field::new( 3204 "ligature_anchor_offsets", 3205 FieldType::array_of_offsets( 3206 better_type_name::<AnchorTable>(), 3207 self.ligature_anchor_offsets(), 3208 move |off| { 3209 let target = off.get().resolve::<AnchorTable>(data); 3210 FieldType::offset(off.get(), target) 3211 }, 3212 ), 3213 ) 3214 }), 3215 _ => None, 3216 }), 3217 data, 3218 } 3219 } 3220 } 3221 3222 impl Format<u16> for MarkMarkPosFormat1Marker { 3223 const FORMAT: u16 = 1; 3224 } 3225 3226 /// [Mark-to-Mark Attachment Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#mark-to-mark-attachment-positioning-format-1-mark-to-mark-attachment): Mark-to-Mark Attachment 3227 #[derive(Debug, Clone, Copy)] 3228 #[doc(hidden)] 3229 pub struct MarkMarkPosFormat1Marker {} 3230 3231 impl MarkMarkPosFormat1Marker { pos_format_byte_range(&self) -> Range<usize>3232 fn pos_format_byte_range(&self) -> Range<usize> { 3233 let start = 0; 3234 start..start + u16::RAW_BYTE_LEN 3235 } mark1_coverage_offset_byte_range(&self) -> Range<usize>3236 fn mark1_coverage_offset_byte_range(&self) -> Range<usize> { 3237 let start = self.pos_format_byte_range().end; 3238 start..start + Offset16::RAW_BYTE_LEN 3239 } mark2_coverage_offset_byte_range(&self) -> Range<usize>3240 fn mark2_coverage_offset_byte_range(&self) -> Range<usize> { 3241 let start = self.mark1_coverage_offset_byte_range().end; 3242 start..start + Offset16::RAW_BYTE_LEN 3243 } mark_class_count_byte_range(&self) -> Range<usize>3244 fn mark_class_count_byte_range(&self) -> Range<usize> { 3245 let start = self.mark2_coverage_offset_byte_range().end; 3246 start..start + u16::RAW_BYTE_LEN 3247 } mark1_array_offset_byte_range(&self) -> Range<usize>3248 fn mark1_array_offset_byte_range(&self) -> Range<usize> { 3249 let start = self.mark_class_count_byte_range().end; 3250 start..start + Offset16::RAW_BYTE_LEN 3251 } mark2_array_offset_byte_range(&self) -> Range<usize>3252 fn mark2_array_offset_byte_range(&self) -> Range<usize> { 3253 let start = self.mark1_array_offset_byte_range().end; 3254 start..start + Offset16::RAW_BYTE_LEN 3255 } 3256 } 3257 3258 impl<'a> FontRead<'a> for MarkMarkPosFormat1<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>3259 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 3260 let mut cursor = data.cursor(); 3261 cursor.advance::<u16>(); 3262 cursor.advance::<Offset16>(); 3263 cursor.advance::<Offset16>(); 3264 cursor.advance::<u16>(); 3265 cursor.advance::<Offset16>(); 3266 cursor.advance::<Offset16>(); 3267 cursor.finish(MarkMarkPosFormat1Marker {}) 3268 } 3269 } 3270 3271 /// [Mark-to-Mark Attachment Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#mark-to-mark-attachment-positioning-format-1-mark-to-mark-attachment): Mark-to-Mark Attachment 3272 pub type MarkMarkPosFormat1<'a> = TableRef<'a, MarkMarkPosFormat1Marker>; 3273 3274 impl<'a> MarkMarkPosFormat1<'a> { 3275 /// Format identifier: format = 1 pos_format(&self) -> u163276 pub fn pos_format(&self) -> u16 { 3277 let range = self.shape.pos_format_byte_range(); 3278 self.data.read_at(range.start).unwrap() 3279 } 3280 3281 /// Offset to Combining Mark Coverage table, from beginning of 3282 /// MarkMarkPos subtable. mark1_coverage_offset(&self) -> Offset163283 pub fn mark1_coverage_offset(&self) -> Offset16 { 3284 let range = self.shape.mark1_coverage_offset_byte_range(); 3285 self.data.read_at(range.start).unwrap() 3286 } 3287 3288 /// Attempt to resolve [`mark1_coverage_offset`][Self::mark1_coverage_offset]. mark1_coverage(&self) -> Result<CoverageTable<'a>, ReadError>3289 pub fn mark1_coverage(&self) -> Result<CoverageTable<'a>, ReadError> { 3290 let data = self.data; 3291 self.mark1_coverage_offset().resolve(data) 3292 } 3293 3294 /// Offset to Base Mark Coverage table, from beginning of 3295 /// MarkMarkPos subtable. mark2_coverage_offset(&self) -> Offset163296 pub fn mark2_coverage_offset(&self) -> Offset16 { 3297 let range = self.shape.mark2_coverage_offset_byte_range(); 3298 self.data.read_at(range.start).unwrap() 3299 } 3300 3301 /// Attempt to resolve [`mark2_coverage_offset`][Self::mark2_coverage_offset]. mark2_coverage(&self) -> Result<CoverageTable<'a>, ReadError>3302 pub fn mark2_coverage(&self) -> Result<CoverageTable<'a>, ReadError> { 3303 let data = self.data; 3304 self.mark2_coverage_offset().resolve(data) 3305 } 3306 3307 /// Number of Combining Mark classes defined mark_class_count(&self) -> u163308 pub fn mark_class_count(&self) -> u16 { 3309 let range = self.shape.mark_class_count_byte_range(); 3310 self.data.read_at(range.start).unwrap() 3311 } 3312 3313 /// Offset to MarkArray table for mark1, from beginning of 3314 /// MarkMarkPos subtable. mark1_array_offset(&self) -> Offset163315 pub fn mark1_array_offset(&self) -> Offset16 { 3316 let range = self.shape.mark1_array_offset_byte_range(); 3317 self.data.read_at(range.start).unwrap() 3318 } 3319 3320 /// Attempt to resolve [`mark1_array_offset`][Self::mark1_array_offset]. mark1_array(&self) -> Result<MarkArray<'a>, ReadError>3321 pub fn mark1_array(&self) -> Result<MarkArray<'a>, ReadError> { 3322 let data = self.data; 3323 self.mark1_array_offset().resolve(data) 3324 } 3325 3326 /// Offset to Mark2Array table for mark2, from beginning of 3327 /// MarkMarkPos subtable. mark2_array_offset(&self) -> Offset163328 pub fn mark2_array_offset(&self) -> Offset16 { 3329 let range = self.shape.mark2_array_offset_byte_range(); 3330 self.data.read_at(range.start).unwrap() 3331 } 3332 3333 /// Attempt to resolve [`mark2_array_offset`][Self::mark2_array_offset]. mark2_array(&self) -> Result<Mark2Array<'a>, ReadError>3334 pub fn mark2_array(&self) -> Result<Mark2Array<'a>, ReadError> { 3335 let data = self.data; 3336 let args = self.mark_class_count(); 3337 self.mark2_array_offset().resolve_with_args(data, &args) 3338 } 3339 } 3340 3341 #[cfg(feature = "traversal")] 3342 impl<'a> SomeTable<'a> for MarkMarkPosFormat1<'a> { type_name(&self) -> &str3343 fn type_name(&self) -> &str { 3344 "MarkMarkPosFormat1" 3345 } get_field(&self, idx: usize) -> Option<Field<'a>>3346 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3347 match idx { 3348 0usize => Some(Field::new("pos_format", self.pos_format())), 3349 1usize => Some(Field::new( 3350 "mark1_coverage_offset", 3351 FieldType::offset(self.mark1_coverage_offset(), self.mark1_coverage()), 3352 )), 3353 2usize => Some(Field::new( 3354 "mark2_coverage_offset", 3355 FieldType::offset(self.mark2_coverage_offset(), self.mark2_coverage()), 3356 )), 3357 3usize => Some(Field::new("mark_class_count", self.mark_class_count())), 3358 4usize => Some(Field::new( 3359 "mark1_array_offset", 3360 FieldType::offset(self.mark1_array_offset(), self.mark1_array()), 3361 )), 3362 5usize => Some(Field::new( 3363 "mark2_array_offset", 3364 FieldType::offset(self.mark2_array_offset(), self.mark2_array()), 3365 )), 3366 _ => None, 3367 } 3368 } 3369 } 3370 3371 #[cfg(feature = "traversal")] 3372 impl<'a> std::fmt::Debug for MarkMarkPosFormat1<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3373 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3374 (self as &dyn SomeTable<'a>).fmt(f) 3375 } 3376 } 3377 3378 /// Part of [MarkMarkPosFormat1]Class2Record 3379 #[derive(Debug, Clone, Copy)] 3380 #[doc(hidden)] 3381 pub struct Mark2ArrayMarker { 3382 mark_class_count: u16, 3383 mark2_records_byte_len: usize, 3384 } 3385 3386 impl Mark2ArrayMarker { mark2_count_byte_range(&self) -> Range<usize>3387 fn mark2_count_byte_range(&self) -> Range<usize> { 3388 let start = 0; 3389 start..start + u16::RAW_BYTE_LEN 3390 } mark2_records_byte_range(&self) -> Range<usize>3391 fn mark2_records_byte_range(&self) -> Range<usize> { 3392 let start = self.mark2_count_byte_range().end; 3393 start..start + self.mark2_records_byte_len 3394 } 3395 } 3396 3397 impl ReadArgs for Mark2Array<'_> { 3398 type Args = u16; 3399 } 3400 3401 impl<'a> FontReadWithArgs<'a> for Mark2Array<'a> { read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError>3402 fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> { 3403 let mark_class_count = *args; 3404 let mut cursor = data.cursor(); 3405 let mark2_count: u16 = cursor.read()?; 3406 let mark2_records_byte_len = 3407 mark2_count as usize * <Mark2Record as ComputeSize>::compute_size(&mark_class_count); 3408 cursor.advance_by(mark2_records_byte_len); 3409 cursor.finish(Mark2ArrayMarker { 3410 mark_class_count, 3411 mark2_records_byte_len, 3412 }) 3413 } 3414 } 3415 3416 impl<'a> Mark2Array<'a> { 3417 /// A constructor that requires additional arguments. 3418 /// 3419 /// This type requires some external state in order to be 3420 /// parsed. read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError>3421 pub fn read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError> { 3422 let args = mark_class_count; 3423 Self::read_with_args(data, &args) 3424 } 3425 } 3426 3427 /// Part of [MarkMarkPosFormat1]Class2Record 3428 pub type Mark2Array<'a> = TableRef<'a, Mark2ArrayMarker>; 3429 3430 impl<'a> Mark2Array<'a> { 3431 /// Number of Mark2 records mark2_count(&self) -> u163432 pub fn mark2_count(&self) -> u16 { 3433 let range = self.shape.mark2_count_byte_range(); 3434 self.data.read_at(range.start).unwrap() 3435 } 3436 3437 /// Array of Mark2Records, in Coverage order. mark2_records(&self) -> ComputedArray<'a, Mark2Record<'a>>3438 pub fn mark2_records(&self) -> ComputedArray<'a, Mark2Record<'a>> { 3439 let range = self.shape.mark2_records_byte_range(); 3440 self.data 3441 .read_with_args(range, &self.mark_class_count()) 3442 .unwrap() 3443 } 3444 mark_class_count(&self) -> u163445 pub(crate) fn mark_class_count(&self) -> u16 { 3446 self.shape.mark_class_count 3447 } 3448 } 3449 3450 #[cfg(feature = "traversal")] 3451 impl<'a> SomeTable<'a> for Mark2Array<'a> { type_name(&self) -> &str3452 fn type_name(&self) -> &str { 3453 "Mark2Array" 3454 } get_field(&self, idx: usize) -> Option<Field<'a>>3455 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3456 match idx { 3457 0usize => Some(Field::new("mark2_count", self.mark2_count())), 3458 1usize => Some(Field::new( 3459 "mark2_records", 3460 traversal::FieldType::computed_array( 3461 "Mark2Record", 3462 self.mark2_records(), 3463 self.offset_data(), 3464 ), 3465 )), 3466 _ => None, 3467 } 3468 } 3469 } 3470 3471 #[cfg(feature = "traversal")] 3472 impl<'a> std::fmt::Debug for Mark2Array<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3473 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3474 (self as &dyn SomeTable<'a>).fmt(f) 3475 } 3476 } 3477 3478 /// Part of [MarkMarkPosFormat1] 3479 #[derive(Clone, Debug)] 3480 pub struct Mark2Record<'a> { 3481 /// Array of offsets (one per class) to Anchor tables. Offsets are 3482 /// from beginning of Mark2Array table, in class order (offsets may 3483 /// be NULL). 3484 pub mark2_anchor_offsets: &'a [BigEndian<Nullable<Offset16>>], 3485 } 3486 3487 impl<'a> Mark2Record<'a> { 3488 /// Array of offsets (one per class) to Anchor tables. Offsets are 3489 /// from beginning of Mark2Array table, in class order (offsets may 3490 /// be NULL). mark2_anchor_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>]3491 pub fn mark2_anchor_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>] { 3492 self.mark2_anchor_offsets 3493 } 3494 3495 /// Array of offsets (one per class) to Anchor tables. Offsets are 3496 /// from beginning of Mark2Array table, in class order (offsets may 3497 /// be NULL). 3498 /// 3499 /// The `data` argument should be retrieved from the parent table 3500 /// By calling its `offset_data` method. mark2_anchors( &self, data: FontData<'a>, ) -> ArrayOfNullableOffsets<'a, AnchorTable<'a>, Offset16>3501 pub fn mark2_anchors( 3502 &self, 3503 data: FontData<'a>, 3504 ) -> ArrayOfNullableOffsets<'a, AnchorTable<'a>, Offset16> { 3505 let offsets = self.mark2_anchor_offsets(); 3506 ArrayOfNullableOffsets::new(offsets, data, ()) 3507 } 3508 } 3509 3510 impl ReadArgs for Mark2Record<'_> { 3511 type Args = u16; 3512 } 3513 3514 impl ComputeSize for Mark2Record<'_> { compute_size(args: &u16) -> usize3515 fn compute_size(args: &u16) -> usize { 3516 let mark_class_count = *args; 3517 mark_class_count as usize * Offset16::RAW_BYTE_LEN 3518 } 3519 } 3520 3521 impl<'a> FontReadWithArgs<'a> for Mark2Record<'a> { read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError>3522 fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> { 3523 let mut cursor = data.cursor(); 3524 let mark_class_count = *args; 3525 Ok(Self { 3526 mark2_anchor_offsets: cursor.read_array(mark_class_count as usize)?, 3527 }) 3528 } 3529 } 3530 3531 impl<'a> Mark2Record<'a> { 3532 /// A constructor that requires additional arguments. 3533 /// 3534 /// This type requires some external state in order to be 3535 /// parsed. read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError>3536 pub fn read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError> { 3537 let args = mark_class_count; 3538 Self::read_with_args(data, &args) 3539 } 3540 } 3541 3542 #[cfg(feature = "traversal")] 3543 impl<'a> SomeRecord<'a> for Mark2Record<'a> { traverse(self, data: FontData<'a>) -> RecordResolver<'a>3544 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 3545 RecordResolver { 3546 name: "Mark2Record", 3547 get_field: Box::new(move |idx, _data| match idx { 3548 0usize => Some({ 3549 Field::new( 3550 "mark2_anchor_offsets", 3551 FieldType::array_of_offsets( 3552 better_type_name::<AnchorTable>(), 3553 self.mark2_anchor_offsets(), 3554 move |off| { 3555 let target = off.get().resolve::<AnchorTable>(data); 3556 FieldType::offset(off.get(), target) 3557 }, 3558 ), 3559 ) 3560 }), 3561 _ => None, 3562 }), 3563 data, 3564 } 3565 } 3566 } 3567 3568 impl Format<u16> for ExtensionPosFormat1Marker { 3569 const FORMAT: u16 = 1; 3570 } 3571 3572 /// [Extension Positioning Subtable Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#extension-positioning-subtable-format-1) 3573 #[derive(Debug)] 3574 #[doc(hidden)] 3575 pub struct ExtensionPosFormat1Marker<T = ()> { 3576 offset_type: std::marker::PhantomData<*const T>, 3577 } 3578 3579 impl<T> ExtensionPosFormat1Marker<T> { pos_format_byte_range(&self) -> Range<usize>3580 fn pos_format_byte_range(&self) -> Range<usize> { 3581 let start = 0; 3582 start..start + u16::RAW_BYTE_LEN 3583 } extension_lookup_type_byte_range(&self) -> Range<usize>3584 fn extension_lookup_type_byte_range(&self) -> Range<usize> { 3585 let start = self.pos_format_byte_range().end; 3586 start..start + u16::RAW_BYTE_LEN 3587 } extension_offset_byte_range(&self) -> Range<usize>3588 fn extension_offset_byte_range(&self) -> Range<usize> { 3589 let start = self.extension_lookup_type_byte_range().end; 3590 start..start + Offset32::RAW_BYTE_LEN 3591 } 3592 } 3593 3594 impl<T> Clone for ExtensionPosFormat1Marker<T> { clone(&self) -> Self3595 fn clone(&self) -> Self { 3596 *self 3597 } 3598 } 3599 3600 impl<T> Copy for ExtensionPosFormat1Marker<T> {} 3601 3602 impl<'a, T> FontRead<'a> for ExtensionPosFormat1<'a, T> { read(data: FontData<'a>) -> Result<Self, ReadError>3603 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 3604 let mut cursor = data.cursor(); 3605 cursor.advance::<u16>(); 3606 cursor.advance::<u16>(); 3607 cursor.advance::<Offset32>(); 3608 cursor.finish(ExtensionPosFormat1Marker { 3609 offset_type: std::marker::PhantomData, 3610 }) 3611 } 3612 } 3613 3614 impl<'a> ExtensionPosFormat1<'a, ()> { 3615 #[allow(dead_code)] into_concrete<T>(self) -> ExtensionPosFormat1<'a, T>3616 pub(crate) fn into_concrete<T>(self) -> ExtensionPosFormat1<'a, T> { 3617 let TableRef { data, .. } = self; 3618 TableRef { 3619 shape: ExtensionPosFormat1Marker { 3620 offset_type: std::marker::PhantomData, 3621 }, 3622 data, 3623 } 3624 } 3625 } 3626 3627 impl<'a, T> ExtensionPosFormat1<'a, T> { 3628 #[allow(dead_code)] 3629 /// Replace the specific generic type on this implementation with `()` of_unit_type(&self) -> ExtensionPosFormat1<'a, ()>3630 pub(crate) fn of_unit_type(&self) -> ExtensionPosFormat1<'a, ()> { 3631 let TableRef { data, .. } = self; 3632 TableRef { 3633 shape: ExtensionPosFormat1Marker { 3634 offset_type: std::marker::PhantomData, 3635 }, 3636 data: *data, 3637 } 3638 } 3639 } 3640 3641 /// [Extension Positioning Subtable Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#extension-positioning-subtable-format-1) 3642 pub type ExtensionPosFormat1<'a, T> = TableRef<'a, ExtensionPosFormat1Marker<T>>; 3643 3644 impl<'a, T> ExtensionPosFormat1<'a, T> { 3645 /// Format identifier: format = 1 pos_format(&self) -> u163646 pub fn pos_format(&self) -> u16 { 3647 let range = self.shape.pos_format_byte_range(); 3648 self.data.read_at(range.start).unwrap() 3649 } 3650 3651 /// Lookup type of subtable referenced by extensionOffset (i.e. the 3652 /// extension subtable). extension_lookup_type(&self) -> u163653 pub fn extension_lookup_type(&self) -> u16 { 3654 let range = self.shape.extension_lookup_type_byte_range(); 3655 self.data.read_at(range.start).unwrap() 3656 } 3657 3658 /// Offset to the extension subtable, of lookup type 3659 /// extensionLookupType, relative to the start of the 3660 /// ExtensionPosFormat1 subtable. extension_offset(&self) -> Offset323661 pub fn extension_offset(&self) -> Offset32 { 3662 let range = self.shape.extension_offset_byte_range(); 3663 self.data.read_at(range.start).unwrap() 3664 } 3665 3666 /// Attempt to resolve [`extension_offset`][Self::extension_offset]. extension(&self) -> Result<T, ReadError> where T: FontRead<'a>,3667 pub fn extension(&self) -> Result<T, ReadError> 3668 where 3669 T: FontRead<'a>, 3670 { 3671 let data = self.data; 3672 self.extension_offset().resolve(data) 3673 } 3674 } 3675 3676 #[cfg(feature = "traversal")] 3677 impl<'a, T: FontRead<'a> + SomeTable<'a> + 'a> SomeTable<'a> for ExtensionPosFormat1<'a, T> { type_name(&self) -> &str3678 fn type_name(&self) -> &str { 3679 "ExtensionPosFormat1" 3680 } get_field(&self, idx: usize) -> Option<Field<'a>>3681 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3682 match idx { 3683 0usize => Some(Field::new("pos_format", self.pos_format())), 3684 1usize => Some(Field::new( 3685 "extension_lookup_type", 3686 self.extension_lookup_type(), 3687 )), 3688 2usize => Some(Field::new( 3689 "extension_offset", 3690 FieldType::offset(self.extension_offset(), self.extension()), 3691 )), 3692 _ => None, 3693 } 3694 } 3695 } 3696 3697 #[cfg(feature = "traversal")] 3698 impl<'a, T: FontRead<'a> + SomeTable<'a> + 'a> std::fmt::Debug for ExtensionPosFormat1<'a, T> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3699 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3700 (self as &dyn SomeTable<'a>).fmt(f) 3701 } 3702 } 3703 3704 /// A [GPOS Extension Positioning](https://learn.microsoft.com/en-us/typography/opentype/spec/gpos#lookuptype-9-extension-positioning) subtable 3705 pub enum ExtensionSubtable<'a> { 3706 Single(ExtensionPosFormat1<'a, SinglePos<'a>>), 3707 Pair(ExtensionPosFormat1<'a, PairPos<'a>>), 3708 Cursive(ExtensionPosFormat1<'a, CursivePosFormat1<'a>>), 3709 MarkToBase(ExtensionPosFormat1<'a, MarkBasePosFormat1<'a>>), 3710 MarkToLig(ExtensionPosFormat1<'a, MarkLigPosFormat1<'a>>), 3711 MarkToMark(ExtensionPosFormat1<'a, MarkMarkPosFormat1<'a>>), 3712 Contextual(ExtensionPosFormat1<'a, PositionSequenceContext<'a>>), 3713 ChainContextual(ExtensionPosFormat1<'a, PositionChainContext<'a>>), 3714 } 3715 3716 impl<'a> FontRead<'a> for ExtensionSubtable<'a> { read(bytes: FontData<'a>) -> Result<Self, ReadError>3717 fn read(bytes: FontData<'a>) -> Result<Self, ReadError> { 3718 let untyped = ExtensionPosFormat1::read(bytes)?; 3719 match untyped.extension_lookup_type() { 3720 1 => Ok(ExtensionSubtable::Single(untyped.into_concrete())), 3721 2 => Ok(ExtensionSubtable::Pair(untyped.into_concrete())), 3722 3 => Ok(ExtensionSubtable::Cursive(untyped.into_concrete())), 3723 4 => Ok(ExtensionSubtable::MarkToBase(untyped.into_concrete())), 3724 5 => Ok(ExtensionSubtable::MarkToLig(untyped.into_concrete())), 3725 6 => Ok(ExtensionSubtable::MarkToMark(untyped.into_concrete())), 3726 7 => Ok(ExtensionSubtable::Contextual(untyped.into_concrete())), 3727 8 => Ok(ExtensionSubtable::ChainContextual(untyped.into_concrete())), 3728 other => Err(ReadError::InvalidFormat(other.into())), 3729 } 3730 } 3731 } 3732 3733 impl<'a> ExtensionSubtable<'a> { 3734 #[allow(dead_code)] 3735 /// Return the inner table, removing the specific generics. 3736 /// 3737 /// This lets us return a single concrete type we can call methods on. of_unit_type(&self) -> ExtensionPosFormat1<'a, ()>3738 pub(crate) fn of_unit_type(&self) -> ExtensionPosFormat1<'a, ()> { 3739 match self { 3740 ExtensionSubtable::Single(inner) => inner.of_unit_type(), 3741 ExtensionSubtable::Pair(inner) => inner.of_unit_type(), 3742 ExtensionSubtable::Cursive(inner) => inner.of_unit_type(), 3743 ExtensionSubtable::MarkToBase(inner) => inner.of_unit_type(), 3744 ExtensionSubtable::MarkToLig(inner) => inner.of_unit_type(), 3745 ExtensionSubtable::MarkToMark(inner) => inner.of_unit_type(), 3746 ExtensionSubtable::Contextual(inner) => inner.of_unit_type(), 3747 ExtensionSubtable::ChainContextual(inner) => inner.of_unit_type(), 3748 } 3749 } 3750 } 3751 3752 #[cfg(feature = "traversal")] 3753 impl<'a> ExtensionSubtable<'a> { dyn_inner(&self) -> &(dyn SomeTable<'a> + 'a)3754 fn dyn_inner(&self) -> &(dyn SomeTable<'a> + 'a) { 3755 match self { 3756 ExtensionSubtable::Single(table) => table, 3757 ExtensionSubtable::Pair(table) => table, 3758 ExtensionSubtable::Cursive(table) => table, 3759 ExtensionSubtable::MarkToBase(table) => table, 3760 ExtensionSubtable::MarkToLig(table) => table, 3761 ExtensionSubtable::MarkToMark(table) => table, 3762 ExtensionSubtable::Contextual(table) => table, 3763 ExtensionSubtable::ChainContextual(table) => table, 3764 } 3765 } 3766 } 3767 3768 #[cfg(feature = "traversal")] 3769 impl<'a> SomeTable<'a> for ExtensionSubtable<'a> { get_field(&self, idx: usize) -> Option<Field<'a>>3770 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3771 self.dyn_inner().get_field(idx) 3772 } type_name(&self) -> &str3773 fn type_name(&self) -> &str { 3774 self.dyn_inner().type_name() 3775 } 3776 } 3777 3778 #[cfg(feature = "traversal")] 3779 impl<'a> std::fmt::Debug for ExtensionSubtable<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3780 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3781 self.dyn_inner().fmt(f) 3782 } 3783 } 3784