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 /// [Script List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#script-list-table-and-script-record) 9 #[derive(Debug, Clone, Copy)] 10 #[doc(hidden)] 11 pub struct ScriptListMarker { 12 script_records_byte_len: usize, 13 } 14 15 impl ScriptListMarker { script_count_byte_range(&self) -> Range<usize>16 fn script_count_byte_range(&self) -> Range<usize> { 17 let start = 0; 18 start..start + u16::RAW_BYTE_LEN 19 } script_records_byte_range(&self) -> Range<usize>20 fn script_records_byte_range(&self) -> Range<usize> { 21 let start = self.script_count_byte_range().end; 22 start..start + self.script_records_byte_len 23 } 24 } 25 26 impl<'a> FontRead<'a> for ScriptList<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>27 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 28 let mut cursor = data.cursor(); 29 let script_count: u16 = cursor.read()?; 30 let script_records_byte_len = script_count as usize * ScriptRecord::RAW_BYTE_LEN; 31 cursor.advance_by(script_records_byte_len); 32 cursor.finish(ScriptListMarker { 33 script_records_byte_len, 34 }) 35 } 36 } 37 38 /// [Script List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#script-list-table-and-script-record) 39 pub type ScriptList<'a> = TableRef<'a, ScriptListMarker>; 40 41 impl<'a> ScriptList<'a> { 42 /// Number of ScriptRecords script_count(&self) -> u1643 pub fn script_count(&self) -> u16 { 44 let range = self.shape.script_count_byte_range(); 45 self.data.read_at(range.start).unwrap() 46 } 47 48 /// Array of ScriptRecords, listed alphabetically by script tag script_records(&self) -> &'a [ScriptRecord]49 pub fn script_records(&self) -> &'a [ScriptRecord] { 50 let range = self.shape.script_records_byte_range(); 51 self.data.read_array(range).unwrap() 52 } 53 } 54 55 #[cfg(feature = "traversal")] 56 impl<'a> SomeTable<'a> for ScriptList<'a> { type_name(&self) -> &str57 fn type_name(&self) -> &str { 58 "ScriptList" 59 } get_field(&self, idx: usize) -> Option<Field<'a>>60 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 61 match idx { 62 0usize => Some(Field::new("script_count", self.script_count())), 63 1usize => Some(Field::new( 64 "script_records", 65 traversal::FieldType::array_of_records( 66 stringify!(ScriptRecord), 67 self.script_records(), 68 self.offset_data(), 69 ), 70 )), 71 _ => None, 72 } 73 } 74 } 75 76 #[cfg(feature = "traversal")] 77 impl<'a> std::fmt::Debug for ScriptList<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result78 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 79 (self as &dyn SomeTable<'a>).fmt(f) 80 } 81 } 82 83 /// [Script Record](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#script-list-table-and-script-record) 84 #[derive(Clone, Debug)] 85 #[repr(C)] 86 #[repr(packed)] 87 pub struct ScriptRecord { 88 /// 4-byte script tag identifier 89 pub script_tag: BigEndian<Tag>, 90 /// Offset to Script table, from beginning of ScriptList 91 pub script_offset: BigEndian<Offset16>, 92 } 93 94 impl ScriptRecord { 95 /// 4-byte script tag identifier script_tag(&self) -> Tag96 pub fn script_tag(&self) -> Tag { 97 self.script_tag.get() 98 } 99 100 /// Offset to Script table, from beginning of ScriptList script_offset(&self) -> Offset16101 pub fn script_offset(&self) -> Offset16 { 102 self.script_offset.get() 103 } 104 105 /// Offset to Script table, from beginning of ScriptList 106 /// 107 /// The `data` argument should be retrieved from the parent table 108 /// By calling its `offset_data` method. script<'a>(&self, data: FontData<'a>) -> Result<Script<'a>, ReadError>109 pub fn script<'a>(&self, data: FontData<'a>) -> Result<Script<'a>, ReadError> { 110 self.script_offset().resolve(data) 111 } 112 } 113 114 impl FixedSize for ScriptRecord { 115 const RAW_BYTE_LEN: usize = Tag::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN; 116 } 117 118 impl sealed::Sealed for ScriptRecord {} 119 120 /// SAFETY: see the [`FromBytes`] trait documentation. 121 unsafe impl FromBytes for ScriptRecord { this_trait_should_only_be_implemented_in_generated_code()122 fn this_trait_should_only_be_implemented_in_generated_code() {} 123 } 124 125 #[cfg(feature = "traversal")] 126 impl<'a> SomeRecord<'a> for ScriptRecord { traverse(self, data: FontData<'a>) -> RecordResolver<'a>127 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 128 RecordResolver { 129 name: "ScriptRecord", 130 get_field: Box::new(move |idx, _data| match idx { 131 0usize => Some(Field::new("script_tag", self.script_tag())), 132 1usize => Some(Field::new( 133 "script_offset", 134 FieldType::offset(self.script_offset(), self.script(_data)), 135 )), 136 _ => None, 137 }), 138 data, 139 } 140 } 141 } 142 143 /// [Script Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#script-table-and-language-system-record) 144 #[derive(Debug, Clone, Copy)] 145 #[doc(hidden)] 146 pub struct ScriptMarker { 147 lang_sys_records_byte_len: usize, 148 } 149 150 impl ScriptMarker { default_lang_sys_offset_byte_range(&self) -> Range<usize>151 fn default_lang_sys_offset_byte_range(&self) -> Range<usize> { 152 let start = 0; 153 start..start + Offset16::RAW_BYTE_LEN 154 } lang_sys_count_byte_range(&self) -> Range<usize>155 fn lang_sys_count_byte_range(&self) -> Range<usize> { 156 let start = self.default_lang_sys_offset_byte_range().end; 157 start..start + u16::RAW_BYTE_LEN 158 } lang_sys_records_byte_range(&self) -> Range<usize>159 fn lang_sys_records_byte_range(&self) -> Range<usize> { 160 let start = self.lang_sys_count_byte_range().end; 161 start..start + self.lang_sys_records_byte_len 162 } 163 } 164 165 impl<'a> FontRead<'a> for Script<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>166 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 167 let mut cursor = data.cursor(); 168 cursor.advance::<Offset16>(); 169 let lang_sys_count: u16 = cursor.read()?; 170 let lang_sys_records_byte_len = lang_sys_count as usize * LangSysRecord::RAW_BYTE_LEN; 171 cursor.advance_by(lang_sys_records_byte_len); 172 cursor.finish(ScriptMarker { 173 lang_sys_records_byte_len, 174 }) 175 } 176 } 177 178 /// [Script Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#script-table-and-language-system-record) 179 pub type Script<'a> = TableRef<'a, ScriptMarker>; 180 181 impl<'a> Script<'a> { 182 /// Offset to default LangSys table, from beginning of Script table 183 /// — may be NULL default_lang_sys_offset(&self) -> Nullable<Offset16>184 pub fn default_lang_sys_offset(&self) -> Nullable<Offset16> { 185 let range = self.shape.default_lang_sys_offset_byte_range(); 186 self.data.read_at(range.start).unwrap() 187 } 188 189 /// Attempt to resolve [`default_lang_sys_offset`][Self::default_lang_sys_offset]. default_lang_sys(&self) -> Option<Result<LangSys<'a>, ReadError>>190 pub fn default_lang_sys(&self) -> Option<Result<LangSys<'a>, ReadError>> { 191 let data = self.data; 192 self.default_lang_sys_offset().resolve(data) 193 } 194 195 /// Number of LangSysRecords for this script — excluding the 196 /// default LangSys lang_sys_count(&self) -> u16197 pub fn lang_sys_count(&self) -> u16 { 198 let range = self.shape.lang_sys_count_byte_range(); 199 self.data.read_at(range.start).unwrap() 200 } 201 202 /// Array of LangSysRecords, listed alphabetically by LangSys tag lang_sys_records(&self) -> &'a [LangSysRecord]203 pub fn lang_sys_records(&self) -> &'a [LangSysRecord] { 204 let range = self.shape.lang_sys_records_byte_range(); 205 self.data.read_array(range).unwrap() 206 } 207 } 208 209 #[cfg(feature = "traversal")] 210 impl<'a> SomeTable<'a> for Script<'a> { type_name(&self) -> &str211 fn type_name(&self) -> &str { 212 "Script" 213 } get_field(&self, idx: usize) -> Option<Field<'a>>214 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 215 match idx { 216 0usize => Some(Field::new( 217 "default_lang_sys_offset", 218 FieldType::offset(self.default_lang_sys_offset(), self.default_lang_sys()), 219 )), 220 1usize => Some(Field::new("lang_sys_count", self.lang_sys_count())), 221 2usize => Some(Field::new( 222 "lang_sys_records", 223 traversal::FieldType::array_of_records( 224 stringify!(LangSysRecord), 225 self.lang_sys_records(), 226 self.offset_data(), 227 ), 228 )), 229 _ => None, 230 } 231 } 232 } 233 234 #[cfg(feature = "traversal")] 235 impl<'a> std::fmt::Debug for Script<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result236 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 237 (self as &dyn SomeTable<'a>).fmt(f) 238 } 239 } 240 241 #[derive(Clone, Debug)] 242 #[repr(C)] 243 #[repr(packed)] 244 pub struct LangSysRecord { 245 /// 4-byte LangSysTag identifier 246 pub lang_sys_tag: BigEndian<Tag>, 247 /// Offset to LangSys table, from beginning of Script table 248 pub lang_sys_offset: BigEndian<Offset16>, 249 } 250 251 impl LangSysRecord { 252 /// 4-byte LangSysTag identifier lang_sys_tag(&self) -> Tag253 pub fn lang_sys_tag(&self) -> Tag { 254 self.lang_sys_tag.get() 255 } 256 257 /// Offset to LangSys table, from beginning of Script table lang_sys_offset(&self) -> Offset16258 pub fn lang_sys_offset(&self) -> Offset16 { 259 self.lang_sys_offset.get() 260 } 261 262 /// Offset to LangSys table, from beginning of Script table 263 /// 264 /// The `data` argument should be retrieved from the parent table 265 /// By calling its `offset_data` method. lang_sys<'a>(&self, data: FontData<'a>) -> Result<LangSys<'a>, ReadError>266 pub fn lang_sys<'a>(&self, data: FontData<'a>) -> Result<LangSys<'a>, ReadError> { 267 self.lang_sys_offset().resolve(data) 268 } 269 } 270 271 impl FixedSize for LangSysRecord { 272 const RAW_BYTE_LEN: usize = Tag::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN; 273 } 274 275 impl sealed::Sealed for LangSysRecord {} 276 277 /// SAFETY: see the [`FromBytes`] trait documentation. 278 unsafe impl FromBytes for LangSysRecord { this_trait_should_only_be_implemented_in_generated_code()279 fn this_trait_should_only_be_implemented_in_generated_code() {} 280 } 281 282 #[cfg(feature = "traversal")] 283 impl<'a> SomeRecord<'a> for LangSysRecord { traverse(self, data: FontData<'a>) -> RecordResolver<'a>284 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 285 RecordResolver { 286 name: "LangSysRecord", 287 get_field: Box::new(move |idx, _data| match idx { 288 0usize => Some(Field::new("lang_sys_tag", self.lang_sys_tag())), 289 1usize => Some(Field::new( 290 "lang_sys_offset", 291 FieldType::offset(self.lang_sys_offset(), self.lang_sys(_data)), 292 )), 293 _ => None, 294 }), 295 data, 296 } 297 } 298 } 299 300 /// [Language System Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#language-system-table) 301 #[derive(Debug, Clone, Copy)] 302 #[doc(hidden)] 303 pub struct LangSysMarker { 304 feature_indices_byte_len: usize, 305 } 306 307 impl LangSysMarker { lookup_order_offset_byte_range(&self) -> Range<usize>308 fn lookup_order_offset_byte_range(&self) -> Range<usize> { 309 let start = 0; 310 start..start + u16::RAW_BYTE_LEN 311 } required_feature_index_byte_range(&self) -> Range<usize>312 fn required_feature_index_byte_range(&self) -> Range<usize> { 313 let start = self.lookup_order_offset_byte_range().end; 314 start..start + u16::RAW_BYTE_LEN 315 } feature_index_count_byte_range(&self) -> Range<usize>316 fn feature_index_count_byte_range(&self) -> Range<usize> { 317 let start = self.required_feature_index_byte_range().end; 318 start..start + u16::RAW_BYTE_LEN 319 } feature_indices_byte_range(&self) -> Range<usize>320 fn feature_indices_byte_range(&self) -> Range<usize> { 321 let start = self.feature_index_count_byte_range().end; 322 start..start + self.feature_indices_byte_len 323 } 324 } 325 326 impl<'a> FontRead<'a> for LangSys<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>327 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 328 let mut cursor = data.cursor(); 329 cursor.advance::<u16>(); 330 cursor.advance::<u16>(); 331 let feature_index_count: u16 = cursor.read()?; 332 let feature_indices_byte_len = feature_index_count as usize * u16::RAW_BYTE_LEN; 333 cursor.advance_by(feature_indices_byte_len); 334 cursor.finish(LangSysMarker { 335 feature_indices_byte_len, 336 }) 337 } 338 } 339 340 /// [Language System Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#language-system-table) 341 pub type LangSys<'a> = TableRef<'a, LangSysMarker>; 342 343 impl<'a> LangSys<'a> { 344 /// Index of a feature required for this language system; if no 345 /// required features = 0xFFFF required_feature_index(&self) -> u16346 pub fn required_feature_index(&self) -> u16 { 347 let range = self.shape.required_feature_index_byte_range(); 348 self.data.read_at(range.start).unwrap() 349 } 350 351 /// Number of feature index values for this language system — 352 /// excludes the required feature feature_index_count(&self) -> u16353 pub fn feature_index_count(&self) -> u16 { 354 let range = self.shape.feature_index_count_byte_range(); 355 self.data.read_at(range.start).unwrap() 356 } 357 358 /// Array of indices into the FeatureList, in arbitrary order feature_indices(&self) -> &'a [BigEndian<u16>]359 pub fn feature_indices(&self) -> &'a [BigEndian<u16>] { 360 let range = self.shape.feature_indices_byte_range(); 361 self.data.read_array(range).unwrap() 362 } 363 } 364 365 #[cfg(feature = "traversal")] 366 impl<'a> SomeTable<'a> for LangSys<'a> { type_name(&self) -> &str367 fn type_name(&self) -> &str { 368 "LangSys" 369 } get_field(&self, idx: usize) -> Option<Field<'a>>370 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 371 match idx { 372 0usize => Some(Field::new( 373 "required_feature_index", 374 self.required_feature_index(), 375 )), 376 1usize => Some(Field::new( 377 "feature_index_count", 378 self.feature_index_count(), 379 )), 380 2usize => Some(Field::new("feature_indices", self.feature_indices())), 381 _ => None, 382 } 383 } 384 } 385 386 #[cfg(feature = "traversal")] 387 impl<'a> std::fmt::Debug for LangSys<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result388 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 389 (self as &dyn SomeTable<'a>).fmt(f) 390 } 391 } 392 393 /// [Feature List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#feature-list-table) 394 #[derive(Debug, Clone, Copy)] 395 #[doc(hidden)] 396 pub struct FeatureListMarker { 397 feature_records_byte_len: usize, 398 } 399 400 impl FeatureListMarker { feature_count_byte_range(&self) -> Range<usize>401 fn feature_count_byte_range(&self) -> Range<usize> { 402 let start = 0; 403 start..start + u16::RAW_BYTE_LEN 404 } feature_records_byte_range(&self) -> Range<usize>405 fn feature_records_byte_range(&self) -> Range<usize> { 406 let start = self.feature_count_byte_range().end; 407 start..start + self.feature_records_byte_len 408 } 409 } 410 411 impl<'a> FontRead<'a> for FeatureList<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>412 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 413 let mut cursor = data.cursor(); 414 let feature_count: u16 = cursor.read()?; 415 let feature_records_byte_len = feature_count as usize * FeatureRecord::RAW_BYTE_LEN; 416 cursor.advance_by(feature_records_byte_len); 417 cursor.finish(FeatureListMarker { 418 feature_records_byte_len, 419 }) 420 } 421 } 422 423 /// [Feature List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#feature-list-table) 424 pub type FeatureList<'a> = TableRef<'a, FeatureListMarker>; 425 426 impl<'a> FeatureList<'a> { 427 /// Number of FeatureRecords in this table feature_count(&self) -> u16428 pub fn feature_count(&self) -> u16 { 429 let range = self.shape.feature_count_byte_range(); 430 self.data.read_at(range.start).unwrap() 431 } 432 433 /// Array of FeatureRecords — zero-based (first feature has 434 /// FeatureIndex = 0), listed alphabetically by feature tag feature_records(&self) -> &'a [FeatureRecord]435 pub fn feature_records(&self) -> &'a [FeatureRecord] { 436 let range = self.shape.feature_records_byte_range(); 437 self.data.read_array(range).unwrap() 438 } 439 } 440 441 #[cfg(feature = "traversal")] 442 impl<'a> SomeTable<'a> for FeatureList<'a> { type_name(&self) -> &str443 fn type_name(&self) -> &str { 444 "FeatureList" 445 } get_field(&self, idx: usize) -> Option<Field<'a>>446 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 447 match idx { 448 0usize => Some(Field::new("feature_count", self.feature_count())), 449 1usize => Some(Field::new( 450 "feature_records", 451 traversal::FieldType::array_of_records( 452 stringify!(FeatureRecord), 453 self.feature_records(), 454 self.offset_data(), 455 ), 456 )), 457 _ => None, 458 } 459 } 460 } 461 462 #[cfg(feature = "traversal")] 463 impl<'a> std::fmt::Debug for FeatureList<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result464 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 465 (self as &dyn SomeTable<'a>).fmt(f) 466 } 467 } 468 469 /// Part of [FeatureList] 470 #[derive(Clone, Debug)] 471 #[repr(C)] 472 #[repr(packed)] 473 pub struct FeatureRecord { 474 /// 4-byte feature identification tag 475 pub feature_tag: BigEndian<Tag>, 476 /// Offset to Feature table, from beginning of FeatureList 477 pub feature_offset: BigEndian<Offset16>, 478 } 479 480 impl FeatureRecord { 481 /// 4-byte feature identification tag feature_tag(&self) -> Tag482 pub fn feature_tag(&self) -> Tag { 483 self.feature_tag.get() 484 } 485 486 /// Offset to Feature table, from beginning of FeatureList feature_offset(&self) -> Offset16487 pub fn feature_offset(&self) -> Offset16 { 488 self.feature_offset.get() 489 } 490 491 /// Offset to Feature table, from beginning of FeatureList 492 /// 493 /// The `data` argument should be retrieved from the parent table 494 /// By calling its `offset_data` method. feature<'a>(&self, data: FontData<'a>) -> Result<Feature<'a>, ReadError>495 pub fn feature<'a>(&self, data: FontData<'a>) -> Result<Feature<'a>, ReadError> { 496 let args = self.feature_tag(); 497 self.feature_offset().resolve_with_args(data, &args) 498 } 499 } 500 501 impl FixedSize for FeatureRecord { 502 const RAW_BYTE_LEN: usize = Tag::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN; 503 } 504 505 impl sealed::Sealed for FeatureRecord {} 506 507 /// SAFETY: see the [`FromBytes`] trait documentation. 508 unsafe impl FromBytes for FeatureRecord { this_trait_should_only_be_implemented_in_generated_code()509 fn this_trait_should_only_be_implemented_in_generated_code() {} 510 } 511 512 #[cfg(feature = "traversal")] 513 impl<'a> SomeRecord<'a> for FeatureRecord { traverse(self, data: FontData<'a>) -> RecordResolver<'a>514 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 515 RecordResolver { 516 name: "FeatureRecord", 517 get_field: Box::new(move |idx, _data| match idx { 518 0usize => Some(Field::new("feature_tag", self.feature_tag())), 519 1usize => Some(Field::new( 520 "feature_offset", 521 FieldType::offset(self.feature_offset(), self.feature(_data)), 522 )), 523 _ => None, 524 }), 525 data, 526 } 527 } 528 } 529 530 /// [Feature Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#feature-table) 531 #[derive(Debug, Clone, Copy)] 532 #[doc(hidden)] 533 pub struct FeatureMarker { 534 feature_tag: Tag, 535 lookup_list_indices_byte_len: usize, 536 } 537 538 impl FeatureMarker { feature_params_offset_byte_range(&self) -> Range<usize>539 fn feature_params_offset_byte_range(&self) -> Range<usize> { 540 let start = 0; 541 start..start + Offset16::RAW_BYTE_LEN 542 } lookup_index_count_byte_range(&self) -> Range<usize>543 fn lookup_index_count_byte_range(&self) -> Range<usize> { 544 let start = self.feature_params_offset_byte_range().end; 545 start..start + u16::RAW_BYTE_LEN 546 } lookup_list_indices_byte_range(&self) -> Range<usize>547 fn lookup_list_indices_byte_range(&self) -> Range<usize> { 548 let start = self.lookup_index_count_byte_range().end; 549 start..start + self.lookup_list_indices_byte_len 550 } 551 } 552 553 impl ReadArgs for Feature<'_> { 554 type Args = Tag; 555 } 556 557 impl<'a> FontReadWithArgs<'a> for Feature<'a> { read_with_args(data: FontData<'a>, args: &Tag) -> Result<Self, ReadError>558 fn read_with_args(data: FontData<'a>, args: &Tag) -> Result<Self, ReadError> { 559 let feature_tag = *args; 560 let mut cursor = data.cursor(); 561 cursor.advance::<Offset16>(); 562 let lookup_index_count: u16 = cursor.read()?; 563 let lookup_list_indices_byte_len = lookup_index_count as usize * u16::RAW_BYTE_LEN; 564 cursor.advance_by(lookup_list_indices_byte_len); 565 cursor.finish(FeatureMarker { 566 feature_tag, 567 lookup_list_indices_byte_len, 568 }) 569 } 570 } 571 572 impl<'a> Feature<'a> { 573 /// A constructor that requires additional arguments. 574 /// 575 /// This type requires some external state in order to be 576 /// parsed. read(data: FontData<'a>, feature_tag: Tag) -> Result<Self, ReadError>577 pub fn read(data: FontData<'a>, feature_tag: Tag) -> Result<Self, ReadError> { 578 let args = feature_tag; 579 Self::read_with_args(data, &args) 580 } 581 } 582 583 /// [Feature Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#feature-table) 584 pub type Feature<'a> = TableRef<'a, FeatureMarker>; 585 586 impl<'a> Feature<'a> { 587 /// Offset from start of Feature table to FeatureParams table, if defined for the feature and present, else NULL feature_params_offset(&self) -> Nullable<Offset16>588 pub fn feature_params_offset(&self) -> Nullable<Offset16> { 589 let range = self.shape.feature_params_offset_byte_range(); 590 self.data.read_at(range.start).unwrap() 591 } 592 593 /// Attempt to resolve [`feature_params_offset`][Self::feature_params_offset]. feature_params(&self) -> Option<Result<FeatureParams<'a>, ReadError>>594 pub fn feature_params(&self) -> Option<Result<FeatureParams<'a>, ReadError>> { 595 let data = self.data; 596 let args = self.feature_tag(); 597 self.feature_params_offset().resolve_with_args(data, &args) 598 } 599 600 /// Number of LookupList indices for this feature lookup_index_count(&self) -> u16601 pub fn lookup_index_count(&self) -> u16 { 602 let range = self.shape.lookup_index_count_byte_range(); 603 self.data.read_at(range.start).unwrap() 604 } 605 606 /// Array of indices into the LookupList — zero-based (first 607 /// lookup is LookupListIndex = 0) lookup_list_indices(&self) -> &'a [BigEndian<u16>]608 pub fn lookup_list_indices(&self) -> &'a [BigEndian<u16>] { 609 let range = self.shape.lookup_list_indices_byte_range(); 610 self.data.read_array(range).unwrap() 611 } 612 feature_tag(&self) -> Tag613 pub(crate) fn feature_tag(&self) -> Tag { 614 self.shape.feature_tag 615 } 616 } 617 618 #[cfg(feature = "traversal")] 619 impl<'a> SomeTable<'a> for Feature<'a> { type_name(&self) -> &str620 fn type_name(&self) -> &str { 621 "Feature" 622 } get_field(&self, idx: usize) -> Option<Field<'a>>623 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 624 match idx { 625 0usize => Some(Field::new( 626 "feature_params_offset", 627 FieldType::offset(self.feature_params_offset(), self.feature_params()), 628 )), 629 1usize => Some(Field::new("lookup_index_count", self.lookup_index_count())), 630 2usize => Some(Field::new( 631 "lookup_list_indices", 632 self.lookup_list_indices(), 633 )), 634 _ => None, 635 } 636 } 637 } 638 639 #[cfg(feature = "traversal")] 640 impl<'a> std::fmt::Debug for Feature<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result641 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 642 (self as &dyn SomeTable<'a>).fmt(f) 643 } 644 } 645 646 /// [Lookup List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#lookup-list-table) 647 #[derive(Debug)] 648 #[doc(hidden)] 649 pub struct LookupListMarker<T = ()> { 650 lookup_offsets_byte_len: usize, 651 offset_type: std::marker::PhantomData<*const T>, 652 } 653 654 impl<T> LookupListMarker<T> { lookup_count_byte_range(&self) -> Range<usize>655 fn lookup_count_byte_range(&self) -> Range<usize> { 656 let start = 0; 657 start..start + u16::RAW_BYTE_LEN 658 } lookup_offsets_byte_range(&self) -> Range<usize>659 fn lookup_offsets_byte_range(&self) -> Range<usize> { 660 let start = self.lookup_count_byte_range().end; 661 start..start + self.lookup_offsets_byte_len 662 } 663 } 664 665 impl<T> Clone for LookupListMarker<T> { clone(&self) -> Self666 fn clone(&self) -> Self { 667 *self 668 } 669 } 670 671 impl<T> Copy for LookupListMarker<T> {} 672 673 impl<'a, T> FontRead<'a> for LookupList<'a, T> { read(data: FontData<'a>) -> Result<Self, ReadError>674 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 675 let mut cursor = data.cursor(); 676 let lookup_count: u16 = cursor.read()?; 677 let lookup_offsets_byte_len = lookup_count as usize * Offset16::RAW_BYTE_LEN; 678 cursor.advance_by(lookup_offsets_byte_len); 679 cursor.finish(LookupListMarker { 680 lookup_offsets_byte_len, 681 offset_type: std::marker::PhantomData, 682 }) 683 } 684 } 685 686 impl<'a> LookupList<'a, ()> { 687 #[allow(dead_code)] into_concrete<T>(self) -> LookupList<'a, T>688 pub(crate) fn into_concrete<T>(self) -> LookupList<'a, T> { 689 let TableRef { data, shape } = self; 690 TableRef { 691 shape: LookupListMarker { 692 lookup_offsets_byte_len: shape.lookup_offsets_byte_len, 693 offset_type: std::marker::PhantomData, 694 }, 695 data, 696 } 697 } 698 } 699 700 impl<'a, T> LookupList<'a, T> { 701 #[allow(dead_code)] 702 /// Replace the specific generic type on this implementation with `()` of_unit_type(&self) -> LookupList<'a, ()>703 pub(crate) fn of_unit_type(&self) -> LookupList<'a, ()> { 704 let TableRef { data, shape } = self; 705 TableRef { 706 shape: LookupListMarker { 707 lookup_offsets_byte_len: shape.lookup_offsets_byte_len, 708 offset_type: std::marker::PhantomData, 709 }, 710 data: *data, 711 } 712 } 713 } 714 715 /// [Lookup List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#lookup-list-table) 716 pub type LookupList<'a, T> = TableRef<'a, LookupListMarker<T>>; 717 718 impl<'a, T> LookupList<'a, T> { 719 /// Number of lookups in this table lookup_count(&self) -> u16720 pub fn lookup_count(&self) -> u16 { 721 let range = self.shape.lookup_count_byte_range(); 722 self.data.read_at(range.start).unwrap() 723 } 724 725 /// Array of offsets to Lookup tables, from beginning of LookupList 726 /// — zero based (first lookup is Lookup index = 0) lookup_offsets(&self) -> &'a [BigEndian<Offset16>]727 pub fn lookup_offsets(&self) -> &'a [BigEndian<Offset16>] { 728 let range = self.shape.lookup_offsets_byte_range(); 729 self.data.read_array(range).unwrap() 730 } 731 732 /// A dynamically resolving wrapper for [`lookup_offsets`][Self::lookup_offsets]. lookups(&self) -> ArrayOfOffsets<'a, T, Offset16> where T: FontRead<'a>,733 pub fn lookups(&self) -> ArrayOfOffsets<'a, T, Offset16> 734 where 735 T: FontRead<'a>, 736 { 737 let data = self.data; 738 let offsets = self.lookup_offsets(); 739 ArrayOfOffsets::new(offsets, data, ()) 740 } 741 } 742 743 #[cfg(feature = "traversal")] 744 impl<'a, T: FontRead<'a> + SomeTable<'a> + 'a> SomeTable<'a> for LookupList<'a, T> { type_name(&self) -> &str745 fn type_name(&self) -> &str { 746 "LookupList" 747 } get_field(&self, idx: usize) -> Option<Field<'a>>748 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 749 match idx { 750 0usize => Some(Field::new("lookup_count", self.lookup_count())), 751 1usize => Some({ 752 let data = self.data; 753 Field::new( 754 "lookup_offsets", 755 FieldType::array_of_offsets( 756 better_type_name::<T>(), 757 self.lookup_offsets(), 758 move |off| { 759 let target = off.get().resolve::<T>(data); 760 FieldType::offset(off.get(), target) 761 }, 762 ), 763 ) 764 }), 765 _ => None, 766 } 767 } 768 } 769 770 #[cfg(feature = "traversal")] 771 impl<'a, T: FontRead<'a> + SomeTable<'a> + 'a> std::fmt::Debug for LookupList<'a, T> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result772 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 773 (self as &dyn SomeTable<'a>).fmt(f) 774 } 775 } 776 777 /// [Lookup Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#lookup-table) 778 #[derive(Debug)] 779 #[doc(hidden)] 780 pub struct LookupMarker<T = ()> { 781 subtable_offsets_byte_len: usize, 782 offset_type: std::marker::PhantomData<*const T>, 783 } 784 785 impl<T> LookupMarker<T> { lookup_type_byte_range(&self) -> Range<usize>786 fn lookup_type_byte_range(&self) -> Range<usize> { 787 let start = 0; 788 start..start + u16::RAW_BYTE_LEN 789 } lookup_flag_byte_range(&self) -> Range<usize>790 fn lookup_flag_byte_range(&self) -> Range<usize> { 791 let start = self.lookup_type_byte_range().end; 792 start..start + LookupFlag::RAW_BYTE_LEN 793 } sub_table_count_byte_range(&self) -> Range<usize>794 fn sub_table_count_byte_range(&self) -> Range<usize> { 795 let start = self.lookup_flag_byte_range().end; 796 start..start + u16::RAW_BYTE_LEN 797 } subtable_offsets_byte_range(&self) -> Range<usize>798 fn subtable_offsets_byte_range(&self) -> Range<usize> { 799 let start = self.sub_table_count_byte_range().end; 800 start..start + self.subtable_offsets_byte_len 801 } mark_filtering_set_byte_range(&self) -> Range<usize>802 fn mark_filtering_set_byte_range(&self) -> Range<usize> { 803 let start = self.subtable_offsets_byte_range().end; 804 start..start + u16::RAW_BYTE_LEN 805 } 806 } 807 808 impl<T> Clone for LookupMarker<T> { clone(&self) -> Self809 fn clone(&self) -> Self { 810 *self 811 } 812 } 813 814 impl<T> Copy for LookupMarker<T> {} 815 816 impl<'a, T> FontRead<'a> for Lookup<'a, T> { read(data: FontData<'a>) -> Result<Self, ReadError>817 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 818 let mut cursor = data.cursor(); 819 cursor.advance::<u16>(); 820 cursor.advance::<LookupFlag>(); 821 let sub_table_count: u16 = cursor.read()?; 822 let subtable_offsets_byte_len = sub_table_count as usize * Offset16::RAW_BYTE_LEN; 823 cursor.advance_by(subtable_offsets_byte_len); 824 cursor.advance::<u16>(); 825 cursor.finish(LookupMarker { 826 subtable_offsets_byte_len, 827 offset_type: std::marker::PhantomData, 828 }) 829 } 830 } 831 832 impl<'a> Lookup<'a, ()> { 833 #[allow(dead_code)] into_concrete<T>(self) -> Lookup<'a, T>834 pub(crate) fn into_concrete<T>(self) -> Lookup<'a, T> { 835 let TableRef { data, shape } = self; 836 TableRef { 837 shape: LookupMarker { 838 subtable_offsets_byte_len: shape.subtable_offsets_byte_len, 839 offset_type: std::marker::PhantomData, 840 }, 841 data, 842 } 843 } 844 } 845 846 impl<'a, T> Lookup<'a, T> { 847 #[allow(dead_code)] 848 /// Replace the specific generic type on this implementation with `()` of_unit_type(&self) -> Lookup<'a, ()>849 pub(crate) fn of_unit_type(&self) -> Lookup<'a, ()> { 850 let TableRef { data, shape } = self; 851 TableRef { 852 shape: LookupMarker { 853 subtable_offsets_byte_len: shape.subtable_offsets_byte_len, 854 offset_type: std::marker::PhantomData, 855 }, 856 data: *data, 857 } 858 } 859 } 860 861 /// [Lookup Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#lookup-table) 862 pub type Lookup<'a, T> = TableRef<'a, LookupMarker<T>>; 863 864 impl<'a, T> Lookup<'a, T> { 865 /// Different enumerations for GSUB and GPOS lookup_type(&self) -> u16866 pub fn lookup_type(&self) -> u16 { 867 let range = self.shape.lookup_type_byte_range(); 868 self.data.read_at(range.start).unwrap() 869 } 870 871 /// Lookup qualifiers lookup_flag(&self) -> LookupFlag872 pub fn lookup_flag(&self) -> LookupFlag { 873 let range = self.shape.lookup_flag_byte_range(); 874 self.data.read_at(range.start).unwrap() 875 } 876 877 /// Number of subtables for this lookup sub_table_count(&self) -> u16878 pub fn sub_table_count(&self) -> u16 { 879 let range = self.shape.sub_table_count_byte_range(); 880 self.data.read_at(range.start).unwrap() 881 } 882 883 /// Array of offsets to lookup subtables, from beginning of Lookup 884 /// table subtable_offsets(&self) -> &'a [BigEndian<Offset16>]885 pub fn subtable_offsets(&self) -> &'a [BigEndian<Offset16>] { 886 let range = self.shape.subtable_offsets_byte_range(); 887 self.data.read_array(range).unwrap() 888 } 889 890 /// A dynamically resolving wrapper for [`subtable_offsets`][Self::subtable_offsets]. subtables(&self) -> ArrayOfOffsets<'a, T, Offset16> where T: FontRead<'a>,891 pub fn subtables(&self) -> ArrayOfOffsets<'a, T, Offset16> 892 where 893 T: FontRead<'a>, 894 { 895 let data = self.data; 896 let offsets = self.subtable_offsets(); 897 ArrayOfOffsets::new(offsets, data, ()) 898 } 899 900 /// Index (base 0) into GDEF mark glyph sets structure. This field 901 /// is only present if the USE_MARK_FILTERING_SET lookup flag is 902 /// set. mark_filtering_set(&self) -> u16903 pub fn mark_filtering_set(&self) -> u16 { 904 let range = self.shape.mark_filtering_set_byte_range(); 905 self.data.read_at(range.start).unwrap() 906 } 907 } 908 909 #[cfg(feature = "traversal")] 910 impl<'a, T: FontRead<'a> + SomeTable<'a> + 'a> SomeTable<'a> for Lookup<'a, T> { type_name(&self) -> &str911 fn type_name(&self) -> &str { 912 "Lookup" 913 } get_field(&self, idx: usize) -> Option<Field<'a>>914 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 915 match idx { 916 0usize => Some(Field::new("lookup_type", self.lookup_type())), 917 1usize => Some(Field::new("lookup_flag", self.traverse_lookup_flag())), 918 2usize => Some(Field::new("sub_table_count", self.sub_table_count())), 919 3usize => Some({ 920 let data = self.data; 921 Field::new( 922 "subtable_offsets", 923 FieldType::array_of_offsets( 924 better_type_name::<T>(), 925 self.subtable_offsets(), 926 move |off| { 927 let target = off.get().resolve::<T>(data); 928 FieldType::offset(off.get(), target) 929 }, 930 ), 931 ) 932 }), 933 4usize => Some(Field::new("mark_filtering_set", self.mark_filtering_set())), 934 _ => None, 935 } 936 } 937 } 938 939 #[cfg(feature = "traversal")] 940 impl<'a, T: FontRead<'a> + SomeTable<'a> + 'a> std::fmt::Debug for Lookup<'a, T> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result941 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 942 (self as &dyn SomeTable<'a>).fmt(f) 943 } 944 } 945 946 impl Format<u16> for CoverageFormat1Marker { 947 const FORMAT: u16 = 1; 948 } 949 950 /// [Coverage Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#coverage-format-1) 951 #[derive(Debug, Clone, Copy)] 952 #[doc(hidden)] 953 pub struct CoverageFormat1Marker { 954 glyph_array_byte_len: usize, 955 } 956 957 impl CoverageFormat1Marker { coverage_format_byte_range(&self) -> Range<usize>958 fn coverage_format_byte_range(&self) -> Range<usize> { 959 let start = 0; 960 start..start + u16::RAW_BYTE_LEN 961 } glyph_count_byte_range(&self) -> Range<usize>962 fn glyph_count_byte_range(&self) -> Range<usize> { 963 let start = self.coverage_format_byte_range().end; 964 start..start + u16::RAW_BYTE_LEN 965 } glyph_array_byte_range(&self) -> Range<usize>966 fn glyph_array_byte_range(&self) -> Range<usize> { 967 let start = self.glyph_count_byte_range().end; 968 start..start + self.glyph_array_byte_len 969 } 970 } 971 972 impl<'a> FontRead<'a> for CoverageFormat1<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>973 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 974 let mut cursor = data.cursor(); 975 cursor.advance::<u16>(); 976 let glyph_count: u16 = cursor.read()?; 977 let glyph_array_byte_len = glyph_count as usize * GlyphId::RAW_BYTE_LEN; 978 cursor.advance_by(glyph_array_byte_len); 979 cursor.finish(CoverageFormat1Marker { 980 glyph_array_byte_len, 981 }) 982 } 983 } 984 985 /// [Coverage Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#coverage-format-1) 986 pub type CoverageFormat1<'a> = TableRef<'a, CoverageFormat1Marker>; 987 988 impl<'a> CoverageFormat1<'a> { 989 /// Format identifier — format = 1 coverage_format(&self) -> u16990 pub fn coverage_format(&self) -> u16 { 991 let range = self.shape.coverage_format_byte_range(); 992 self.data.read_at(range.start).unwrap() 993 } 994 995 /// Number of glyphs in the glyph array glyph_count(&self) -> u16996 pub fn glyph_count(&self) -> u16 { 997 let range = self.shape.glyph_count_byte_range(); 998 self.data.read_at(range.start).unwrap() 999 } 1000 1001 /// Array of glyph IDs — in numerical order glyph_array(&self) -> &'a [BigEndian<GlyphId>]1002 pub fn glyph_array(&self) -> &'a [BigEndian<GlyphId>] { 1003 let range = self.shape.glyph_array_byte_range(); 1004 self.data.read_array(range).unwrap() 1005 } 1006 } 1007 1008 #[cfg(feature = "traversal")] 1009 impl<'a> SomeTable<'a> for CoverageFormat1<'a> { type_name(&self) -> &str1010 fn type_name(&self) -> &str { 1011 "CoverageFormat1" 1012 } get_field(&self, idx: usize) -> Option<Field<'a>>1013 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1014 match idx { 1015 0usize => Some(Field::new("coverage_format", self.coverage_format())), 1016 1usize => Some(Field::new("glyph_count", self.glyph_count())), 1017 2usize => Some(Field::new("glyph_array", self.glyph_array())), 1018 _ => None, 1019 } 1020 } 1021 } 1022 1023 #[cfg(feature = "traversal")] 1024 impl<'a> std::fmt::Debug for CoverageFormat1<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1025 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1026 (self as &dyn SomeTable<'a>).fmt(f) 1027 } 1028 } 1029 1030 impl Format<u16> for CoverageFormat2Marker { 1031 const FORMAT: u16 = 2; 1032 } 1033 1034 /// [Coverage Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#coverage-format-2) 1035 #[derive(Debug, Clone, Copy)] 1036 #[doc(hidden)] 1037 pub struct CoverageFormat2Marker { 1038 range_records_byte_len: usize, 1039 } 1040 1041 impl CoverageFormat2Marker { coverage_format_byte_range(&self) -> Range<usize>1042 fn coverage_format_byte_range(&self) -> Range<usize> { 1043 let start = 0; 1044 start..start + u16::RAW_BYTE_LEN 1045 } range_count_byte_range(&self) -> Range<usize>1046 fn range_count_byte_range(&self) -> Range<usize> { 1047 let start = self.coverage_format_byte_range().end; 1048 start..start + u16::RAW_BYTE_LEN 1049 } range_records_byte_range(&self) -> Range<usize>1050 fn range_records_byte_range(&self) -> Range<usize> { 1051 let start = self.range_count_byte_range().end; 1052 start..start + self.range_records_byte_len 1053 } 1054 } 1055 1056 impl<'a> FontRead<'a> for CoverageFormat2<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1057 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1058 let mut cursor = data.cursor(); 1059 cursor.advance::<u16>(); 1060 let range_count: u16 = cursor.read()?; 1061 let range_records_byte_len = range_count as usize * RangeRecord::RAW_BYTE_LEN; 1062 cursor.advance_by(range_records_byte_len); 1063 cursor.finish(CoverageFormat2Marker { 1064 range_records_byte_len, 1065 }) 1066 } 1067 } 1068 1069 /// [Coverage Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#coverage-format-2) 1070 pub type CoverageFormat2<'a> = TableRef<'a, CoverageFormat2Marker>; 1071 1072 impl<'a> CoverageFormat2<'a> { 1073 /// Format identifier — format = 2 coverage_format(&self) -> u161074 pub fn coverage_format(&self) -> u16 { 1075 let range = self.shape.coverage_format_byte_range(); 1076 self.data.read_at(range.start).unwrap() 1077 } 1078 1079 /// Number of RangeRecords range_count(&self) -> u161080 pub fn range_count(&self) -> u16 { 1081 let range = self.shape.range_count_byte_range(); 1082 self.data.read_at(range.start).unwrap() 1083 } 1084 1085 /// Array of glyph ranges — ordered by startGlyphID. range_records(&self) -> &'a [RangeRecord]1086 pub fn range_records(&self) -> &'a [RangeRecord] { 1087 let range = self.shape.range_records_byte_range(); 1088 self.data.read_array(range).unwrap() 1089 } 1090 } 1091 1092 #[cfg(feature = "traversal")] 1093 impl<'a> SomeTable<'a> for CoverageFormat2<'a> { type_name(&self) -> &str1094 fn type_name(&self) -> &str { 1095 "CoverageFormat2" 1096 } get_field(&self, idx: usize) -> Option<Field<'a>>1097 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1098 match idx { 1099 0usize => Some(Field::new("coverage_format", self.coverage_format())), 1100 1usize => Some(Field::new("range_count", self.range_count())), 1101 2usize => Some(Field::new( 1102 "range_records", 1103 traversal::FieldType::array_of_records( 1104 stringify!(RangeRecord), 1105 self.range_records(), 1106 self.offset_data(), 1107 ), 1108 )), 1109 _ => None, 1110 } 1111 } 1112 } 1113 1114 #[cfg(feature = "traversal")] 1115 impl<'a> std::fmt::Debug for CoverageFormat2<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1116 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1117 (self as &dyn SomeTable<'a>).fmt(f) 1118 } 1119 } 1120 1121 /// Used in [CoverageFormat2] 1122 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 1123 #[repr(C)] 1124 #[repr(packed)] 1125 pub struct RangeRecord { 1126 /// First glyph ID in the range 1127 pub start_glyph_id: BigEndian<GlyphId>, 1128 /// Last glyph ID in the range 1129 pub end_glyph_id: BigEndian<GlyphId>, 1130 /// Coverage Index of first glyph ID in range 1131 pub start_coverage_index: BigEndian<u16>, 1132 } 1133 1134 impl RangeRecord { 1135 /// First glyph ID in the range start_glyph_id(&self) -> GlyphId1136 pub fn start_glyph_id(&self) -> GlyphId { 1137 self.start_glyph_id.get() 1138 } 1139 1140 /// Last glyph ID in the range end_glyph_id(&self) -> GlyphId1141 pub fn end_glyph_id(&self) -> GlyphId { 1142 self.end_glyph_id.get() 1143 } 1144 1145 /// Coverage Index of first glyph ID in range start_coverage_index(&self) -> u161146 pub fn start_coverage_index(&self) -> u16 { 1147 self.start_coverage_index.get() 1148 } 1149 } 1150 1151 impl FixedSize for RangeRecord { 1152 const RAW_BYTE_LEN: usize = GlyphId::RAW_BYTE_LEN + GlyphId::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; 1153 } 1154 1155 impl sealed::Sealed for RangeRecord {} 1156 1157 /// SAFETY: see the [`FromBytes`] trait documentation. 1158 unsafe impl FromBytes for RangeRecord { this_trait_should_only_be_implemented_in_generated_code()1159 fn this_trait_should_only_be_implemented_in_generated_code() {} 1160 } 1161 1162 #[cfg(feature = "traversal")] 1163 impl<'a> SomeRecord<'a> for RangeRecord { traverse(self, data: FontData<'a>) -> RecordResolver<'a>1164 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 1165 RecordResolver { 1166 name: "RangeRecord", 1167 get_field: Box::new(move |idx, _data| match idx { 1168 0usize => Some(Field::new("start_glyph_id", self.start_glyph_id())), 1169 1usize => Some(Field::new("end_glyph_id", self.end_glyph_id())), 1170 2usize => Some(Field::new( 1171 "start_coverage_index", 1172 self.start_coverage_index(), 1173 )), 1174 _ => None, 1175 }), 1176 data, 1177 } 1178 } 1179 } 1180 1181 /// [Coverage Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#coverage-table) 1182 #[derive(Clone)] 1183 pub enum CoverageTable<'a> { 1184 Format1(CoverageFormat1<'a>), 1185 Format2(CoverageFormat2<'a>), 1186 } 1187 1188 impl<'a> CoverageTable<'a> { 1189 /// Format identifier — format = 1 coverage_format(&self) -> u161190 pub fn coverage_format(&self) -> u16 { 1191 match self { 1192 Self::Format1(item) => item.coverage_format(), 1193 Self::Format2(item) => item.coverage_format(), 1194 } 1195 } 1196 } 1197 1198 impl<'a> FontRead<'a> for CoverageTable<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1199 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1200 let format: u16 = data.read_at(0usize)?; 1201 match format { 1202 CoverageFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)), 1203 CoverageFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)), 1204 other => Err(ReadError::InvalidFormat(other.into())), 1205 } 1206 } 1207 } 1208 1209 #[cfg(feature = "traversal")] 1210 impl<'a> CoverageTable<'a> { dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>1211 fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> { 1212 match self { 1213 Self::Format1(table) => table, 1214 Self::Format2(table) => table, 1215 } 1216 } 1217 } 1218 1219 #[cfg(feature = "traversal")] 1220 impl<'a> std::fmt::Debug for CoverageTable<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1221 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1222 self.dyn_inner().fmt(f) 1223 } 1224 } 1225 1226 #[cfg(feature = "traversal")] 1227 impl<'a> SomeTable<'a> for CoverageTable<'a> { type_name(&self) -> &str1228 fn type_name(&self) -> &str { 1229 self.dyn_inner().type_name() 1230 } get_field(&self, idx: usize) -> Option<Field<'a>>1231 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1232 self.dyn_inner().get_field(idx) 1233 } 1234 } 1235 1236 impl Format<u16> for ClassDefFormat1Marker { 1237 const FORMAT: u16 = 1; 1238 } 1239 1240 /// [Class Definition Table Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table-format-1) 1241 #[derive(Debug, Clone, Copy)] 1242 #[doc(hidden)] 1243 pub struct ClassDefFormat1Marker { 1244 class_value_array_byte_len: usize, 1245 } 1246 1247 impl ClassDefFormat1Marker { class_format_byte_range(&self) -> Range<usize>1248 fn class_format_byte_range(&self) -> Range<usize> { 1249 let start = 0; 1250 start..start + u16::RAW_BYTE_LEN 1251 } start_glyph_id_byte_range(&self) -> Range<usize>1252 fn start_glyph_id_byte_range(&self) -> Range<usize> { 1253 let start = self.class_format_byte_range().end; 1254 start..start + GlyphId::RAW_BYTE_LEN 1255 } glyph_count_byte_range(&self) -> Range<usize>1256 fn glyph_count_byte_range(&self) -> Range<usize> { 1257 let start = self.start_glyph_id_byte_range().end; 1258 start..start + u16::RAW_BYTE_LEN 1259 } class_value_array_byte_range(&self) -> Range<usize>1260 fn class_value_array_byte_range(&self) -> Range<usize> { 1261 let start = self.glyph_count_byte_range().end; 1262 start..start + self.class_value_array_byte_len 1263 } 1264 } 1265 1266 impl<'a> FontRead<'a> for ClassDefFormat1<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1267 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1268 let mut cursor = data.cursor(); 1269 cursor.advance::<u16>(); 1270 cursor.advance::<GlyphId>(); 1271 let glyph_count: u16 = cursor.read()?; 1272 let class_value_array_byte_len = glyph_count as usize * u16::RAW_BYTE_LEN; 1273 cursor.advance_by(class_value_array_byte_len); 1274 cursor.finish(ClassDefFormat1Marker { 1275 class_value_array_byte_len, 1276 }) 1277 } 1278 } 1279 1280 /// [Class Definition Table Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table-format-1) 1281 pub type ClassDefFormat1<'a> = TableRef<'a, ClassDefFormat1Marker>; 1282 1283 impl<'a> ClassDefFormat1<'a> { 1284 /// Format identifier — format = 1 class_format(&self) -> u161285 pub fn class_format(&self) -> u16 { 1286 let range = self.shape.class_format_byte_range(); 1287 self.data.read_at(range.start).unwrap() 1288 } 1289 1290 /// First glyph ID of the classValueArray start_glyph_id(&self) -> GlyphId1291 pub fn start_glyph_id(&self) -> GlyphId { 1292 let range = self.shape.start_glyph_id_byte_range(); 1293 self.data.read_at(range.start).unwrap() 1294 } 1295 1296 /// Size of the classValueArray glyph_count(&self) -> u161297 pub fn glyph_count(&self) -> u16 { 1298 let range = self.shape.glyph_count_byte_range(); 1299 self.data.read_at(range.start).unwrap() 1300 } 1301 1302 /// Array of Class Values — one per glyph ID class_value_array(&self) -> &'a [BigEndian<u16>]1303 pub fn class_value_array(&self) -> &'a [BigEndian<u16>] { 1304 let range = self.shape.class_value_array_byte_range(); 1305 self.data.read_array(range).unwrap() 1306 } 1307 } 1308 1309 #[cfg(feature = "traversal")] 1310 impl<'a> SomeTable<'a> for ClassDefFormat1<'a> { type_name(&self) -> &str1311 fn type_name(&self) -> &str { 1312 "ClassDefFormat1" 1313 } get_field(&self, idx: usize) -> Option<Field<'a>>1314 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1315 match idx { 1316 0usize => Some(Field::new("class_format", self.class_format())), 1317 1usize => Some(Field::new("start_glyph_id", self.start_glyph_id())), 1318 2usize => Some(Field::new("glyph_count", self.glyph_count())), 1319 3usize => Some(Field::new("class_value_array", self.class_value_array())), 1320 _ => None, 1321 } 1322 } 1323 } 1324 1325 #[cfg(feature = "traversal")] 1326 impl<'a> std::fmt::Debug for ClassDefFormat1<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1327 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1328 (self as &dyn SomeTable<'a>).fmt(f) 1329 } 1330 } 1331 1332 impl Format<u16> for ClassDefFormat2Marker { 1333 const FORMAT: u16 = 2; 1334 } 1335 1336 /// [Class Definition Table Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table-format-2) 1337 #[derive(Debug, Clone, Copy)] 1338 #[doc(hidden)] 1339 pub struct ClassDefFormat2Marker { 1340 class_range_records_byte_len: usize, 1341 } 1342 1343 impl ClassDefFormat2Marker { class_format_byte_range(&self) -> Range<usize>1344 fn class_format_byte_range(&self) -> Range<usize> { 1345 let start = 0; 1346 start..start + u16::RAW_BYTE_LEN 1347 } class_range_count_byte_range(&self) -> Range<usize>1348 fn class_range_count_byte_range(&self) -> Range<usize> { 1349 let start = self.class_format_byte_range().end; 1350 start..start + u16::RAW_BYTE_LEN 1351 } class_range_records_byte_range(&self) -> Range<usize>1352 fn class_range_records_byte_range(&self) -> Range<usize> { 1353 let start = self.class_range_count_byte_range().end; 1354 start..start + self.class_range_records_byte_len 1355 } 1356 } 1357 1358 impl<'a> FontRead<'a> for ClassDefFormat2<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1359 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1360 let mut cursor = data.cursor(); 1361 cursor.advance::<u16>(); 1362 let class_range_count: u16 = cursor.read()?; 1363 let class_range_records_byte_len = 1364 class_range_count as usize * ClassRangeRecord::RAW_BYTE_LEN; 1365 cursor.advance_by(class_range_records_byte_len); 1366 cursor.finish(ClassDefFormat2Marker { 1367 class_range_records_byte_len, 1368 }) 1369 } 1370 } 1371 1372 /// [Class Definition Table Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table-format-2) 1373 pub type ClassDefFormat2<'a> = TableRef<'a, ClassDefFormat2Marker>; 1374 1375 impl<'a> ClassDefFormat2<'a> { 1376 /// Format identifier — format = 2 class_format(&self) -> u161377 pub fn class_format(&self) -> u16 { 1378 let range = self.shape.class_format_byte_range(); 1379 self.data.read_at(range.start).unwrap() 1380 } 1381 1382 /// Number of ClassRangeRecords class_range_count(&self) -> u161383 pub fn class_range_count(&self) -> u16 { 1384 let range = self.shape.class_range_count_byte_range(); 1385 self.data.read_at(range.start).unwrap() 1386 } 1387 1388 /// Array of ClassRangeRecords — ordered by startGlyphID class_range_records(&self) -> &'a [ClassRangeRecord]1389 pub fn class_range_records(&self) -> &'a [ClassRangeRecord] { 1390 let range = self.shape.class_range_records_byte_range(); 1391 self.data.read_array(range).unwrap() 1392 } 1393 } 1394 1395 #[cfg(feature = "traversal")] 1396 impl<'a> SomeTable<'a> for ClassDefFormat2<'a> { type_name(&self) -> &str1397 fn type_name(&self) -> &str { 1398 "ClassDefFormat2" 1399 } get_field(&self, idx: usize) -> Option<Field<'a>>1400 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1401 match idx { 1402 0usize => Some(Field::new("class_format", self.class_format())), 1403 1usize => Some(Field::new("class_range_count", self.class_range_count())), 1404 2usize => Some(Field::new( 1405 "class_range_records", 1406 traversal::FieldType::array_of_records( 1407 stringify!(ClassRangeRecord), 1408 self.class_range_records(), 1409 self.offset_data(), 1410 ), 1411 )), 1412 _ => None, 1413 } 1414 } 1415 } 1416 1417 #[cfg(feature = "traversal")] 1418 impl<'a> std::fmt::Debug for ClassDefFormat2<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1419 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1420 (self as &dyn SomeTable<'a>).fmt(f) 1421 } 1422 } 1423 1424 /// Used in [ClassDefFormat2] 1425 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 1426 #[repr(C)] 1427 #[repr(packed)] 1428 pub struct ClassRangeRecord { 1429 /// First glyph ID in the range 1430 pub start_glyph_id: BigEndian<GlyphId>, 1431 /// Last glyph ID in the range 1432 pub end_glyph_id: BigEndian<GlyphId>, 1433 /// Applied to all glyphs in the range 1434 pub class: BigEndian<u16>, 1435 } 1436 1437 impl ClassRangeRecord { 1438 /// First glyph ID in the range start_glyph_id(&self) -> GlyphId1439 pub fn start_glyph_id(&self) -> GlyphId { 1440 self.start_glyph_id.get() 1441 } 1442 1443 /// Last glyph ID in the range end_glyph_id(&self) -> GlyphId1444 pub fn end_glyph_id(&self) -> GlyphId { 1445 self.end_glyph_id.get() 1446 } 1447 1448 /// Applied to all glyphs in the range class(&self) -> u161449 pub fn class(&self) -> u16 { 1450 self.class.get() 1451 } 1452 } 1453 1454 impl FixedSize for ClassRangeRecord { 1455 const RAW_BYTE_LEN: usize = GlyphId::RAW_BYTE_LEN + GlyphId::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; 1456 } 1457 1458 impl sealed::Sealed for ClassRangeRecord {} 1459 1460 /// SAFETY: see the [`FromBytes`] trait documentation. 1461 unsafe impl FromBytes for ClassRangeRecord { this_trait_should_only_be_implemented_in_generated_code()1462 fn this_trait_should_only_be_implemented_in_generated_code() {} 1463 } 1464 1465 #[cfg(feature = "traversal")] 1466 impl<'a> SomeRecord<'a> for ClassRangeRecord { traverse(self, data: FontData<'a>) -> RecordResolver<'a>1467 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 1468 RecordResolver { 1469 name: "ClassRangeRecord", 1470 get_field: Box::new(move |idx, _data| match idx { 1471 0usize => Some(Field::new("start_glyph_id", self.start_glyph_id())), 1472 1usize => Some(Field::new("end_glyph_id", self.end_glyph_id())), 1473 2usize => Some(Field::new("class", self.class())), 1474 _ => None, 1475 }), 1476 data, 1477 } 1478 } 1479 } 1480 1481 /// A [Class Definition Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table) 1482 #[derive(Clone)] 1483 pub enum ClassDef<'a> { 1484 Format1(ClassDefFormat1<'a>), 1485 Format2(ClassDefFormat2<'a>), 1486 } 1487 1488 impl<'a> ClassDef<'a> { 1489 /// Format identifier — format = 1 class_format(&self) -> u161490 pub fn class_format(&self) -> u16 { 1491 match self { 1492 Self::Format1(item) => item.class_format(), 1493 Self::Format2(item) => item.class_format(), 1494 } 1495 } 1496 } 1497 1498 impl<'a> FontRead<'a> for ClassDef<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1499 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1500 let format: u16 = data.read_at(0usize)?; 1501 match format { 1502 ClassDefFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)), 1503 ClassDefFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)), 1504 other => Err(ReadError::InvalidFormat(other.into())), 1505 } 1506 } 1507 } 1508 1509 #[cfg(feature = "traversal")] 1510 impl<'a> ClassDef<'a> { dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>1511 fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> { 1512 match self { 1513 Self::Format1(table) => table, 1514 Self::Format2(table) => table, 1515 } 1516 } 1517 } 1518 1519 #[cfg(feature = "traversal")] 1520 impl<'a> std::fmt::Debug for ClassDef<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1521 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1522 self.dyn_inner().fmt(f) 1523 } 1524 } 1525 1526 #[cfg(feature = "traversal")] 1527 impl<'a> SomeTable<'a> for ClassDef<'a> { type_name(&self) -> &str1528 fn type_name(&self) -> &str { 1529 self.dyn_inner().type_name() 1530 } get_field(&self, idx: usize) -> Option<Field<'a>>1531 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1532 self.dyn_inner().get_field(idx) 1533 } 1534 } 1535 1536 /// [Sequence Lookup Record](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#sequence-lookup-record) 1537 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 1538 #[repr(C)] 1539 #[repr(packed)] 1540 pub struct SequenceLookupRecord { 1541 /// Index (zero-based) into the input glyph sequence 1542 pub sequence_index: BigEndian<u16>, 1543 /// Index (zero-based) into the LookupList 1544 pub lookup_list_index: BigEndian<u16>, 1545 } 1546 1547 impl SequenceLookupRecord { 1548 /// Index (zero-based) into the input glyph sequence sequence_index(&self) -> u161549 pub fn sequence_index(&self) -> u16 { 1550 self.sequence_index.get() 1551 } 1552 1553 /// Index (zero-based) into the LookupList lookup_list_index(&self) -> u161554 pub fn lookup_list_index(&self) -> u16 { 1555 self.lookup_list_index.get() 1556 } 1557 } 1558 1559 impl FixedSize for SequenceLookupRecord { 1560 const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; 1561 } 1562 1563 impl sealed::Sealed for SequenceLookupRecord {} 1564 1565 /// SAFETY: see the [`FromBytes`] trait documentation. 1566 unsafe impl FromBytes for SequenceLookupRecord { this_trait_should_only_be_implemented_in_generated_code()1567 fn this_trait_should_only_be_implemented_in_generated_code() {} 1568 } 1569 1570 #[cfg(feature = "traversal")] 1571 impl<'a> SomeRecord<'a> for SequenceLookupRecord { traverse(self, data: FontData<'a>) -> RecordResolver<'a>1572 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 1573 RecordResolver { 1574 name: "SequenceLookupRecord", 1575 get_field: Box::new(move |idx, _data| match idx { 1576 0usize => Some(Field::new("sequence_index", self.sequence_index())), 1577 1usize => Some(Field::new("lookup_list_index", self.lookup_list_index())), 1578 _ => None, 1579 }), 1580 data, 1581 } 1582 } 1583 } 1584 1585 impl Format<u16> for SequenceContextFormat1Marker { 1586 const FORMAT: u16 = 1; 1587 } 1588 1589 /// [Sequence Context Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#sequence-context-format-1-simple-glyph-contexts) 1590 #[derive(Debug, Clone, Copy)] 1591 #[doc(hidden)] 1592 pub struct SequenceContextFormat1Marker { 1593 seq_rule_set_offsets_byte_len: usize, 1594 } 1595 1596 impl SequenceContextFormat1Marker { format_byte_range(&self) -> Range<usize>1597 fn format_byte_range(&self) -> Range<usize> { 1598 let start = 0; 1599 start..start + u16::RAW_BYTE_LEN 1600 } coverage_offset_byte_range(&self) -> Range<usize>1601 fn coverage_offset_byte_range(&self) -> Range<usize> { 1602 let start = self.format_byte_range().end; 1603 start..start + Offset16::RAW_BYTE_LEN 1604 } seq_rule_set_count_byte_range(&self) -> Range<usize>1605 fn seq_rule_set_count_byte_range(&self) -> Range<usize> { 1606 let start = self.coverage_offset_byte_range().end; 1607 start..start + u16::RAW_BYTE_LEN 1608 } seq_rule_set_offsets_byte_range(&self) -> Range<usize>1609 fn seq_rule_set_offsets_byte_range(&self) -> Range<usize> { 1610 let start = self.seq_rule_set_count_byte_range().end; 1611 start..start + self.seq_rule_set_offsets_byte_len 1612 } 1613 } 1614 1615 impl<'a> FontRead<'a> for SequenceContextFormat1<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1616 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1617 let mut cursor = data.cursor(); 1618 cursor.advance::<u16>(); 1619 cursor.advance::<Offset16>(); 1620 let seq_rule_set_count: u16 = cursor.read()?; 1621 let seq_rule_set_offsets_byte_len = seq_rule_set_count as usize * Offset16::RAW_BYTE_LEN; 1622 cursor.advance_by(seq_rule_set_offsets_byte_len); 1623 cursor.finish(SequenceContextFormat1Marker { 1624 seq_rule_set_offsets_byte_len, 1625 }) 1626 } 1627 } 1628 1629 /// [Sequence Context Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#sequence-context-format-1-simple-glyph-contexts) 1630 pub type SequenceContextFormat1<'a> = TableRef<'a, SequenceContextFormat1Marker>; 1631 1632 impl<'a> SequenceContextFormat1<'a> { 1633 /// Format identifier: format = 1 format(&self) -> u161634 pub fn format(&self) -> u16 { 1635 let range = self.shape.format_byte_range(); 1636 self.data.read_at(range.start).unwrap() 1637 } 1638 1639 /// Offset to Coverage table, from beginning of 1640 /// SequenceContextFormat1 table coverage_offset(&self) -> Offset161641 pub fn coverage_offset(&self) -> Offset16 { 1642 let range = self.shape.coverage_offset_byte_range(); 1643 self.data.read_at(range.start).unwrap() 1644 } 1645 1646 /// Attempt to resolve [`coverage_offset`][Self::coverage_offset]. coverage(&self) -> Result<CoverageTable<'a>, ReadError>1647 pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> { 1648 let data = self.data; 1649 self.coverage_offset().resolve(data) 1650 } 1651 1652 /// Number of SequenceRuleSet tables seq_rule_set_count(&self) -> u161653 pub fn seq_rule_set_count(&self) -> u16 { 1654 let range = self.shape.seq_rule_set_count_byte_range(); 1655 self.data.read_at(range.start).unwrap() 1656 } 1657 1658 /// Array of offsets to SequenceRuleSet tables, from beginning of 1659 /// SequenceContextFormat1 table (offsets may be NULL) seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>]1660 pub fn seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>] { 1661 let range = self.shape.seq_rule_set_offsets_byte_range(); 1662 self.data.read_array(range).unwrap() 1663 } 1664 1665 /// A dynamically resolving wrapper for [`seq_rule_set_offsets`][Self::seq_rule_set_offsets]. seq_rule_sets(&self) -> ArrayOfNullableOffsets<'a, SequenceRuleSet<'a>, Offset16>1666 pub fn seq_rule_sets(&self) -> ArrayOfNullableOffsets<'a, SequenceRuleSet<'a>, Offset16> { 1667 let data = self.data; 1668 let offsets = self.seq_rule_set_offsets(); 1669 ArrayOfNullableOffsets::new(offsets, data, ()) 1670 } 1671 } 1672 1673 #[cfg(feature = "traversal")] 1674 impl<'a> SomeTable<'a> for SequenceContextFormat1<'a> { type_name(&self) -> &str1675 fn type_name(&self) -> &str { 1676 "SequenceContextFormat1" 1677 } get_field(&self, idx: usize) -> Option<Field<'a>>1678 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1679 match idx { 1680 0usize => Some(Field::new("format", self.format())), 1681 1usize => Some(Field::new( 1682 "coverage_offset", 1683 FieldType::offset(self.coverage_offset(), self.coverage()), 1684 )), 1685 2usize => Some(Field::new("seq_rule_set_count", self.seq_rule_set_count())), 1686 3usize => Some({ 1687 let data = self.data; 1688 Field::new( 1689 "seq_rule_set_offsets", 1690 FieldType::array_of_offsets( 1691 better_type_name::<SequenceRuleSet>(), 1692 self.seq_rule_set_offsets(), 1693 move |off| { 1694 let target = off.get().resolve::<SequenceRuleSet>(data); 1695 FieldType::offset(off.get(), target) 1696 }, 1697 ), 1698 ) 1699 }), 1700 _ => None, 1701 } 1702 } 1703 } 1704 1705 #[cfg(feature = "traversal")] 1706 impl<'a> std::fmt::Debug for SequenceContextFormat1<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1707 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1708 (self as &dyn SomeTable<'a>).fmt(f) 1709 } 1710 } 1711 1712 /// Part of [SequenceContextFormat1] 1713 #[derive(Debug, Clone, Copy)] 1714 #[doc(hidden)] 1715 pub struct SequenceRuleSetMarker { 1716 seq_rule_offsets_byte_len: usize, 1717 } 1718 1719 impl SequenceRuleSetMarker { seq_rule_count_byte_range(&self) -> Range<usize>1720 fn seq_rule_count_byte_range(&self) -> Range<usize> { 1721 let start = 0; 1722 start..start + u16::RAW_BYTE_LEN 1723 } seq_rule_offsets_byte_range(&self) -> Range<usize>1724 fn seq_rule_offsets_byte_range(&self) -> Range<usize> { 1725 let start = self.seq_rule_count_byte_range().end; 1726 start..start + self.seq_rule_offsets_byte_len 1727 } 1728 } 1729 1730 impl<'a> FontRead<'a> for SequenceRuleSet<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1731 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1732 let mut cursor = data.cursor(); 1733 let seq_rule_count: u16 = cursor.read()?; 1734 let seq_rule_offsets_byte_len = seq_rule_count as usize * Offset16::RAW_BYTE_LEN; 1735 cursor.advance_by(seq_rule_offsets_byte_len); 1736 cursor.finish(SequenceRuleSetMarker { 1737 seq_rule_offsets_byte_len, 1738 }) 1739 } 1740 } 1741 1742 /// Part of [SequenceContextFormat1] 1743 pub type SequenceRuleSet<'a> = TableRef<'a, SequenceRuleSetMarker>; 1744 1745 impl<'a> SequenceRuleSet<'a> { 1746 /// Number of SequenceRule tables seq_rule_count(&self) -> u161747 pub fn seq_rule_count(&self) -> u16 { 1748 let range = self.shape.seq_rule_count_byte_range(); 1749 self.data.read_at(range.start).unwrap() 1750 } 1751 1752 /// Array of offsets to SequenceRule tables, from beginning of the 1753 /// SequenceRuleSet table seq_rule_offsets(&self) -> &'a [BigEndian<Offset16>]1754 pub fn seq_rule_offsets(&self) -> &'a [BigEndian<Offset16>] { 1755 let range = self.shape.seq_rule_offsets_byte_range(); 1756 self.data.read_array(range).unwrap() 1757 } 1758 1759 /// A dynamically resolving wrapper for [`seq_rule_offsets`][Self::seq_rule_offsets]. seq_rules(&self) -> ArrayOfOffsets<'a, SequenceRule<'a>, Offset16>1760 pub fn seq_rules(&self) -> ArrayOfOffsets<'a, SequenceRule<'a>, Offset16> { 1761 let data = self.data; 1762 let offsets = self.seq_rule_offsets(); 1763 ArrayOfOffsets::new(offsets, data, ()) 1764 } 1765 } 1766 1767 #[cfg(feature = "traversal")] 1768 impl<'a> SomeTable<'a> for SequenceRuleSet<'a> { type_name(&self) -> &str1769 fn type_name(&self) -> &str { 1770 "SequenceRuleSet" 1771 } get_field(&self, idx: usize) -> Option<Field<'a>>1772 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1773 match idx { 1774 0usize => Some(Field::new("seq_rule_count", self.seq_rule_count())), 1775 1usize => Some({ 1776 let data = self.data; 1777 Field::new( 1778 "seq_rule_offsets", 1779 FieldType::array_of_offsets( 1780 better_type_name::<SequenceRule>(), 1781 self.seq_rule_offsets(), 1782 move |off| { 1783 let target = off.get().resolve::<SequenceRule>(data); 1784 FieldType::offset(off.get(), target) 1785 }, 1786 ), 1787 ) 1788 }), 1789 _ => None, 1790 } 1791 } 1792 } 1793 1794 #[cfg(feature = "traversal")] 1795 impl<'a> std::fmt::Debug for SequenceRuleSet<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1796 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1797 (self as &dyn SomeTable<'a>).fmt(f) 1798 } 1799 } 1800 1801 /// Part of [SequenceContextFormat1] 1802 #[derive(Debug, Clone, Copy)] 1803 #[doc(hidden)] 1804 pub struct SequenceRuleMarker { 1805 input_sequence_byte_len: usize, 1806 seq_lookup_records_byte_len: usize, 1807 } 1808 1809 impl SequenceRuleMarker { glyph_count_byte_range(&self) -> Range<usize>1810 fn glyph_count_byte_range(&self) -> Range<usize> { 1811 let start = 0; 1812 start..start + u16::RAW_BYTE_LEN 1813 } seq_lookup_count_byte_range(&self) -> Range<usize>1814 fn seq_lookup_count_byte_range(&self) -> Range<usize> { 1815 let start = self.glyph_count_byte_range().end; 1816 start..start + u16::RAW_BYTE_LEN 1817 } input_sequence_byte_range(&self) -> Range<usize>1818 fn input_sequence_byte_range(&self) -> Range<usize> { 1819 let start = self.seq_lookup_count_byte_range().end; 1820 start..start + self.input_sequence_byte_len 1821 } seq_lookup_records_byte_range(&self) -> Range<usize>1822 fn seq_lookup_records_byte_range(&self) -> Range<usize> { 1823 let start = self.input_sequence_byte_range().end; 1824 start..start + self.seq_lookup_records_byte_len 1825 } 1826 } 1827 1828 impl<'a> FontRead<'a> for SequenceRule<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1829 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1830 let mut cursor = data.cursor(); 1831 let glyph_count: u16 = cursor.read()?; 1832 let seq_lookup_count: u16 = cursor.read()?; 1833 let input_sequence_byte_len = 1834 transforms::subtract(glyph_count, 1_usize) * GlyphId::RAW_BYTE_LEN; 1835 cursor.advance_by(input_sequence_byte_len); 1836 let seq_lookup_records_byte_len = 1837 seq_lookup_count as usize * SequenceLookupRecord::RAW_BYTE_LEN; 1838 cursor.advance_by(seq_lookup_records_byte_len); 1839 cursor.finish(SequenceRuleMarker { 1840 input_sequence_byte_len, 1841 seq_lookup_records_byte_len, 1842 }) 1843 } 1844 } 1845 1846 /// Part of [SequenceContextFormat1] 1847 pub type SequenceRule<'a> = TableRef<'a, SequenceRuleMarker>; 1848 1849 impl<'a> SequenceRule<'a> { 1850 /// Number of glyphs in the input glyph sequence glyph_count(&self) -> u161851 pub fn glyph_count(&self) -> u16 { 1852 let range = self.shape.glyph_count_byte_range(); 1853 self.data.read_at(range.start).unwrap() 1854 } 1855 1856 /// Number of SequenceLookupRecords seq_lookup_count(&self) -> u161857 pub fn seq_lookup_count(&self) -> u16 { 1858 let range = self.shape.seq_lookup_count_byte_range(); 1859 self.data.read_at(range.start).unwrap() 1860 } 1861 1862 /// Array of input glyph IDs—starting with the second glyph input_sequence(&self) -> &'a [BigEndian<GlyphId>]1863 pub fn input_sequence(&self) -> &'a [BigEndian<GlyphId>] { 1864 let range = self.shape.input_sequence_byte_range(); 1865 self.data.read_array(range).unwrap() 1866 } 1867 1868 /// Array of Sequence lookup records seq_lookup_records(&self) -> &'a [SequenceLookupRecord]1869 pub fn seq_lookup_records(&self) -> &'a [SequenceLookupRecord] { 1870 let range = self.shape.seq_lookup_records_byte_range(); 1871 self.data.read_array(range).unwrap() 1872 } 1873 } 1874 1875 #[cfg(feature = "traversal")] 1876 impl<'a> SomeTable<'a> for SequenceRule<'a> { type_name(&self) -> &str1877 fn type_name(&self) -> &str { 1878 "SequenceRule" 1879 } get_field(&self, idx: usize) -> Option<Field<'a>>1880 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1881 match idx { 1882 0usize => Some(Field::new("glyph_count", self.glyph_count())), 1883 1usize => Some(Field::new("seq_lookup_count", self.seq_lookup_count())), 1884 2usize => Some(Field::new("input_sequence", self.input_sequence())), 1885 3usize => Some(Field::new( 1886 "seq_lookup_records", 1887 traversal::FieldType::array_of_records( 1888 stringify!(SequenceLookupRecord), 1889 self.seq_lookup_records(), 1890 self.offset_data(), 1891 ), 1892 )), 1893 _ => None, 1894 } 1895 } 1896 } 1897 1898 #[cfg(feature = "traversal")] 1899 impl<'a> std::fmt::Debug for SequenceRule<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1900 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1901 (self as &dyn SomeTable<'a>).fmt(f) 1902 } 1903 } 1904 1905 impl Format<u16> for SequenceContextFormat2Marker { 1906 const FORMAT: u16 = 2; 1907 } 1908 1909 /// [Sequence Context Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#sequence-context-format-2-class-based-glyph-contexts) 1910 #[derive(Debug, Clone, Copy)] 1911 #[doc(hidden)] 1912 pub struct SequenceContextFormat2Marker { 1913 class_seq_rule_set_offsets_byte_len: usize, 1914 } 1915 1916 impl SequenceContextFormat2Marker { format_byte_range(&self) -> Range<usize>1917 fn format_byte_range(&self) -> Range<usize> { 1918 let start = 0; 1919 start..start + u16::RAW_BYTE_LEN 1920 } coverage_offset_byte_range(&self) -> Range<usize>1921 fn coverage_offset_byte_range(&self) -> Range<usize> { 1922 let start = self.format_byte_range().end; 1923 start..start + Offset16::RAW_BYTE_LEN 1924 } class_def_offset_byte_range(&self) -> Range<usize>1925 fn class_def_offset_byte_range(&self) -> Range<usize> { 1926 let start = self.coverage_offset_byte_range().end; 1927 start..start + Offset16::RAW_BYTE_LEN 1928 } class_seq_rule_set_count_byte_range(&self) -> Range<usize>1929 fn class_seq_rule_set_count_byte_range(&self) -> Range<usize> { 1930 let start = self.class_def_offset_byte_range().end; 1931 start..start + u16::RAW_BYTE_LEN 1932 } class_seq_rule_set_offsets_byte_range(&self) -> Range<usize>1933 fn class_seq_rule_set_offsets_byte_range(&self) -> Range<usize> { 1934 let start = self.class_seq_rule_set_count_byte_range().end; 1935 start..start + self.class_seq_rule_set_offsets_byte_len 1936 } 1937 } 1938 1939 impl<'a> FontRead<'a> for SequenceContextFormat2<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1940 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1941 let mut cursor = data.cursor(); 1942 cursor.advance::<u16>(); 1943 cursor.advance::<Offset16>(); 1944 cursor.advance::<Offset16>(); 1945 let class_seq_rule_set_count: u16 = cursor.read()?; 1946 let class_seq_rule_set_offsets_byte_len = 1947 class_seq_rule_set_count as usize * Offset16::RAW_BYTE_LEN; 1948 cursor.advance_by(class_seq_rule_set_offsets_byte_len); 1949 cursor.finish(SequenceContextFormat2Marker { 1950 class_seq_rule_set_offsets_byte_len, 1951 }) 1952 } 1953 } 1954 1955 /// [Sequence Context Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#sequence-context-format-2-class-based-glyph-contexts) 1956 pub type SequenceContextFormat2<'a> = TableRef<'a, SequenceContextFormat2Marker>; 1957 1958 impl<'a> SequenceContextFormat2<'a> { 1959 /// Format identifier: format = 2 format(&self) -> u161960 pub fn format(&self) -> u16 { 1961 let range = self.shape.format_byte_range(); 1962 self.data.read_at(range.start).unwrap() 1963 } 1964 1965 /// Offset to Coverage table, from beginning of 1966 /// SequenceContextFormat2 table coverage_offset(&self) -> Offset161967 pub fn coverage_offset(&self) -> Offset16 { 1968 let range = self.shape.coverage_offset_byte_range(); 1969 self.data.read_at(range.start).unwrap() 1970 } 1971 1972 /// Attempt to resolve [`coverage_offset`][Self::coverage_offset]. coverage(&self) -> Result<CoverageTable<'a>, ReadError>1973 pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> { 1974 let data = self.data; 1975 self.coverage_offset().resolve(data) 1976 } 1977 1978 /// Offset to ClassDef table, from beginning of 1979 /// SequenceContextFormat2 table class_def_offset(&self) -> Offset161980 pub fn class_def_offset(&self) -> Offset16 { 1981 let range = self.shape.class_def_offset_byte_range(); 1982 self.data.read_at(range.start).unwrap() 1983 } 1984 1985 /// Attempt to resolve [`class_def_offset`][Self::class_def_offset]. class_def(&self) -> Result<ClassDef<'a>, ReadError>1986 pub fn class_def(&self) -> Result<ClassDef<'a>, ReadError> { 1987 let data = self.data; 1988 self.class_def_offset().resolve(data) 1989 } 1990 1991 /// Number of ClassSequenceRuleSet tables class_seq_rule_set_count(&self) -> u161992 pub fn class_seq_rule_set_count(&self) -> u16 { 1993 let range = self.shape.class_seq_rule_set_count_byte_range(); 1994 self.data.read_at(range.start).unwrap() 1995 } 1996 1997 /// Array of offsets to ClassSequenceRuleSet tables, from beginning 1998 /// of SequenceContextFormat2 table (may be NULL) class_seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>]1999 pub fn class_seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>] { 2000 let range = self.shape.class_seq_rule_set_offsets_byte_range(); 2001 self.data.read_array(range).unwrap() 2002 } 2003 2004 /// A dynamically resolving wrapper for [`class_seq_rule_set_offsets`][Self::class_seq_rule_set_offsets]. class_seq_rule_sets( &self, ) -> ArrayOfNullableOffsets<'a, ClassSequenceRuleSet<'a>, Offset16>2005 pub fn class_seq_rule_sets( 2006 &self, 2007 ) -> ArrayOfNullableOffsets<'a, ClassSequenceRuleSet<'a>, Offset16> { 2008 let data = self.data; 2009 let offsets = self.class_seq_rule_set_offsets(); 2010 ArrayOfNullableOffsets::new(offsets, data, ()) 2011 } 2012 } 2013 2014 #[cfg(feature = "traversal")] 2015 impl<'a> SomeTable<'a> for SequenceContextFormat2<'a> { type_name(&self) -> &str2016 fn type_name(&self) -> &str { 2017 "SequenceContextFormat2" 2018 } get_field(&self, idx: usize) -> Option<Field<'a>>2019 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 2020 match idx { 2021 0usize => Some(Field::new("format", self.format())), 2022 1usize => Some(Field::new( 2023 "coverage_offset", 2024 FieldType::offset(self.coverage_offset(), self.coverage()), 2025 )), 2026 2usize => Some(Field::new( 2027 "class_def_offset", 2028 FieldType::offset(self.class_def_offset(), self.class_def()), 2029 )), 2030 3usize => Some(Field::new( 2031 "class_seq_rule_set_count", 2032 self.class_seq_rule_set_count(), 2033 )), 2034 4usize => Some({ 2035 let data = self.data; 2036 Field::new( 2037 "class_seq_rule_set_offsets", 2038 FieldType::array_of_offsets( 2039 better_type_name::<ClassSequenceRuleSet>(), 2040 self.class_seq_rule_set_offsets(), 2041 move |off| { 2042 let target = off.get().resolve::<ClassSequenceRuleSet>(data); 2043 FieldType::offset(off.get(), target) 2044 }, 2045 ), 2046 ) 2047 }), 2048 _ => None, 2049 } 2050 } 2051 } 2052 2053 #[cfg(feature = "traversal")] 2054 impl<'a> std::fmt::Debug for SequenceContextFormat2<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2055 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 2056 (self as &dyn SomeTable<'a>).fmt(f) 2057 } 2058 } 2059 2060 /// Part of [SequenceContextFormat2] 2061 #[derive(Debug, Clone, Copy)] 2062 #[doc(hidden)] 2063 pub struct ClassSequenceRuleSetMarker { 2064 class_seq_rule_offsets_byte_len: usize, 2065 } 2066 2067 impl ClassSequenceRuleSetMarker { class_seq_rule_count_byte_range(&self) -> Range<usize>2068 fn class_seq_rule_count_byte_range(&self) -> Range<usize> { 2069 let start = 0; 2070 start..start + u16::RAW_BYTE_LEN 2071 } class_seq_rule_offsets_byte_range(&self) -> Range<usize>2072 fn class_seq_rule_offsets_byte_range(&self) -> Range<usize> { 2073 let start = self.class_seq_rule_count_byte_range().end; 2074 start..start + self.class_seq_rule_offsets_byte_len 2075 } 2076 } 2077 2078 impl<'a> FontRead<'a> for ClassSequenceRuleSet<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>2079 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 2080 let mut cursor = data.cursor(); 2081 let class_seq_rule_count: u16 = cursor.read()?; 2082 let class_seq_rule_offsets_byte_len = 2083 class_seq_rule_count as usize * Offset16::RAW_BYTE_LEN; 2084 cursor.advance_by(class_seq_rule_offsets_byte_len); 2085 cursor.finish(ClassSequenceRuleSetMarker { 2086 class_seq_rule_offsets_byte_len, 2087 }) 2088 } 2089 } 2090 2091 /// Part of [SequenceContextFormat2] 2092 pub type ClassSequenceRuleSet<'a> = TableRef<'a, ClassSequenceRuleSetMarker>; 2093 2094 impl<'a> ClassSequenceRuleSet<'a> { 2095 /// Number of ClassSequenceRule tables class_seq_rule_count(&self) -> u162096 pub fn class_seq_rule_count(&self) -> u16 { 2097 let range = self.shape.class_seq_rule_count_byte_range(); 2098 self.data.read_at(range.start).unwrap() 2099 } 2100 2101 /// Array of offsets to ClassSequenceRule tables, from beginning of 2102 /// ClassSequenceRuleSet table class_seq_rule_offsets(&self) -> &'a [BigEndian<Offset16>]2103 pub fn class_seq_rule_offsets(&self) -> &'a [BigEndian<Offset16>] { 2104 let range = self.shape.class_seq_rule_offsets_byte_range(); 2105 self.data.read_array(range).unwrap() 2106 } 2107 2108 /// A dynamically resolving wrapper for [`class_seq_rule_offsets`][Self::class_seq_rule_offsets]. class_seq_rules(&self) -> ArrayOfOffsets<'a, ClassSequenceRule<'a>, Offset16>2109 pub fn class_seq_rules(&self) -> ArrayOfOffsets<'a, ClassSequenceRule<'a>, Offset16> { 2110 let data = self.data; 2111 let offsets = self.class_seq_rule_offsets(); 2112 ArrayOfOffsets::new(offsets, data, ()) 2113 } 2114 } 2115 2116 #[cfg(feature = "traversal")] 2117 impl<'a> SomeTable<'a> for ClassSequenceRuleSet<'a> { type_name(&self) -> &str2118 fn type_name(&self) -> &str { 2119 "ClassSequenceRuleSet" 2120 } get_field(&self, idx: usize) -> Option<Field<'a>>2121 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 2122 match idx { 2123 0usize => Some(Field::new( 2124 "class_seq_rule_count", 2125 self.class_seq_rule_count(), 2126 )), 2127 1usize => Some({ 2128 let data = self.data; 2129 Field::new( 2130 "class_seq_rule_offsets", 2131 FieldType::array_of_offsets( 2132 better_type_name::<ClassSequenceRule>(), 2133 self.class_seq_rule_offsets(), 2134 move |off| { 2135 let target = off.get().resolve::<ClassSequenceRule>(data); 2136 FieldType::offset(off.get(), target) 2137 }, 2138 ), 2139 ) 2140 }), 2141 _ => None, 2142 } 2143 } 2144 } 2145 2146 #[cfg(feature = "traversal")] 2147 impl<'a> std::fmt::Debug for ClassSequenceRuleSet<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2148 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 2149 (self as &dyn SomeTable<'a>).fmt(f) 2150 } 2151 } 2152 2153 /// Part of [SequenceContextFormat2] 2154 #[derive(Debug, Clone, Copy)] 2155 #[doc(hidden)] 2156 pub struct ClassSequenceRuleMarker { 2157 input_sequence_byte_len: usize, 2158 seq_lookup_records_byte_len: usize, 2159 } 2160 2161 impl ClassSequenceRuleMarker { glyph_count_byte_range(&self) -> Range<usize>2162 fn glyph_count_byte_range(&self) -> Range<usize> { 2163 let start = 0; 2164 start..start + u16::RAW_BYTE_LEN 2165 } seq_lookup_count_byte_range(&self) -> Range<usize>2166 fn seq_lookup_count_byte_range(&self) -> Range<usize> { 2167 let start = self.glyph_count_byte_range().end; 2168 start..start + u16::RAW_BYTE_LEN 2169 } input_sequence_byte_range(&self) -> Range<usize>2170 fn input_sequence_byte_range(&self) -> Range<usize> { 2171 let start = self.seq_lookup_count_byte_range().end; 2172 start..start + self.input_sequence_byte_len 2173 } seq_lookup_records_byte_range(&self) -> Range<usize>2174 fn seq_lookup_records_byte_range(&self) -> Range<usize> { 2175 let start = self.input_sequence_byte_range().end; 2176 start..start + self.seq_lookup_records_byte_len 2177 } 2178 } 2179 2180 impl<'a> FontRead<'a> for ClassSequenceRule<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>2181 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 2182 let mut cursor = data.cursor(); 2183 let glyph_count: u16 = cursor.read()?; 2184 let seq_lookup_count: u16 = cursor.read()?; 2185 let input_sequence_byte_len = 2186 transforms::subtract(glyph_count, 1_usize) * u16::RAW_BYTE_LEN; 2187 cursor.advance_by(input_sequence_byte_len); 2188 let seq_lookup_records_byte_len = 2189 seq_lookup_count as usize * SequenceLookupRecord::RAW_BYTE_LEN; 2190 cursor.advance_by(seq_lookup_records_byte_len); 2191 cursor.finish(ClassSequenceRuleMarker { 2192 input_sequence_byte_len, 2193 seq_lookup_records_byte_len, 2194 }) 2195 } 2196 } 2197 2198 /// Part of [SequenceContextFormat2] 2199 pub type ClassSequenceRule<'a> = TableRef<'a, ClassSequenceRuleMarker>; 2200 2201 impl<'a> ClassSequenceRule<'a> { 2202 /// Number of glyphs to be matched glyph_count(&self) -> u162203 pub fn glyph_count(&self) -> u16 { 2204 let range = self.shape.glyph_count_byte_range(); 2205 self.data.read_at(range.start).unwrap() 2206 } 2207 2208 /// Number of SequenceLookupRecords seq_lookup_count(&self) -> u162209 pub fn seq_lookup_count(&self) -> u16 { 2210 let range = self.shape.seq_lookup_count_byte_range(); 2211 self.data.read_at(range.start).unwrap() 2212 } 2213 2214 /// Sequence of classes to be matched to the input glyph sequence, 2215 /// beginning with the second glyph position input_sequence(&self) -> &'a [BigEndian<u16>]2216 pub fn input_sequence(&self) -> &'a [BigEndian<u16>] { 2217 let range = self.shape.input_sequence_byte_range(); 2218 self.data.read_array(range).unwrap() 2219 } 2220 2221 /// Array of SequenceLookupRecords seq_lookup_records(&self) -> &'a [SequenceLookupRecord]2222 pub fn seq_lookup_records(&self) -> &'a [SequenceLookupRecord] { 2223 let range = self.shape.seq_lookup_records_byte_range(); 2224 self.data.read_array(range).unwrap() 2225 } 2226 } 2227 2228 #[cfg(feature = "traversal")] 2229 impl<'a> SomeTable<'a> for ClassSequenceRule<'a> { type_name(&self) -> &str2230 fn type_name(&self) -> &str { 2231 "ClassSequenceRule" 2232 } get_field(&self, idx: usize) -> Option<Field<'a>>2233 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 2234 match idx { 2235 0usize => Some(Field::new("glyph_count", self.glyph_count())), 2236 1usize => Some(Field::new("seq_lookup_count", self.seq_lookup_count())), 2237 2usize => Some(Field::new("input_sequence", self.input_sequence())), 2238 3usize => Some(Field::new( 2239 "seq_lookup_records", 2240 traversal::FieldType::array_of_records( 2241 stringify!(SequenceLookupRecord), 2242 self.seq_lookup_records(), 2243 self.offset_data(), 2244 ), 2245 )), 2246 _ => None, 2247 } 2248 } 2249 } 2250 2251 #[cfg(feature = "traversal")] 2252 impl<'a> std::fmt::Debug for ClassSequenceRule<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2253 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 2254 (self as &dyn SomeTable<'a>).fmt(f) 2255 } 2256 } 2257 2258 impl Format<u16> for SequenceContextFormat3Marker { 2259 const FORMAT: u16 = 3; 2260 } 2261 2262 /// [Sequence Context Format 3](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#sequence-context-format-3-coverage-based-glyph-contexts) 2263 #[derive(Debug, Clone, Copy)] 2264 #[doc(hidden)] 2265 pub struct SequenceContextFormat3Marker { 2266 coverage_offsets_byte_len: usize, 2267 seq_lookup_records_byte_len: usize, 2268 } 2269 2270 impl SequenceContextFormat3Marker { format_byte_range(&self) -> Range<usize>2271 fn format_byte_range(&self) -> Range<usize> { 2272 let start = 0; 2273 start..start + u16::RAW_BYTE_LEN 2274 } glyph_count_byte_range(&self) -> Range<usize>2275 fn glyph_count_byte_range(&self) -> Range<usize> { 2276 let start = self.format_byte_range().end; 2277 start..start + u16::RAW_BYTE_LEN 2278 } seq_lookup_count_byte_range(&self) -> Range<usize>2279 fn seq_lookup_count_byte_range(&self) -> Range<usize> { 2280 let start = self.glyph_count_byte_range().end; 2281 start..start + u16::RAW_BYTE_LEN 2282 } coverage_offsets_byte_range(&self) -> Range<usize>2283 fn coverage_offsets_byte_range(&self) -> Range<usize> { 2284 let start = self.seq_lookup_count_byte_range().end; 2285 start..start + self.coverage_offsets_byte_len 2286 } seq_lookup_records_byte_range(&self) -> Range<usize>2287 fn seq_lookup_records_byte_range(&self) -> Range<usize> { 2288 let start = self.coverage_offsets_byte_range().end; 2289 start..start + self.seq_lookup_records_byte_len 2290 } 2291 } 2292 2293 impl<'a> FontRead<'a> for SequenceContextFormat3<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>2294 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 2295 let mut cursor = data.cursor(); 2296 cursor.advance::<u16>(); 2297 let glyph_count: u16 = cursor.read()?; 2298 let seq_lookup_count: u16 = cursor.read()?; 2299 let coverage_offsets_byte_len = glyph_count as usize * Offset16::RAW_BYTE_LEN; 2300 cursor.advance_by(coverage_offsets_byte_len); 2301 let seq_lookup_records_byte_len = 2302 seq_lookup_count as usize * SequenceLookupRecord::RAW_BYTE_LEN; 2303 cursor.advance_by(seq_lookup_records_byte_len); 2304 cursor.finish(SequenceContextFormat3Marker { 2305 coverage_offsets_byte_len, 2306 seq_lookup_records_byte_len, 2307 }) 2308 } 2309 } 2310 2311 /// [Sequence Context Format 3](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#sequence-context-format-3-coverage-based-glyph-contexts) 2312 pub type SequenceContextFormat3<'a> = TableRef<'a, SequenceContextFormat3Marker>; 2313 2314 impl<'a> SequenceContextFormat3<'a> { 2315 /// Format identifier: format = 3 format(&self) -> u162316 pub fn format(&self) -> u16 { 2317 let range = self.shape.format_byte_range(); 2318 self.data.read_at(range.start).unwrap() 2319 } 2320 2321 /// Number of glyphs in the input sequence glyph_count(&self) -> u162322 pub fn glyph_count(&self) -> u16 { 2323 let range = self.shape.glyph_count_byte_range(); 2324 self.data.read_at(range.start).unwrap() 2325 } 2326 2327 /// Number of SequenceLookupRecords seq_lookup_count(&self) -> u162328 pub fn seq_lookup_count(&self) -> u16 { 2329 let range = self.shape.seq_lookup_count_byte_range(); 2330 self.data.read_at(range.start).unwrap() 2331 } 2332 2333 /// Array of offsets to Coverage tables, from beginning of 2334 /// SequenceContextFormat3 subtable coverage_offsets(&self) -> &'a [BigEndian<Offset16>]2335 pub fn coverage_offsets(&self) -> &'a [BigEndian<Offset16>] { 2336 let range = self.shape.coverage_offsets_byte_range(); 2337 self.data.read_array(range).unwrap() 2338 } 2339 2340 /// A dynamically resolving wrapper for [`coverage_offsets`][Self::coverage_offsets]. coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset16>2341 pub fn coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset16> { 2342 let data = self.data; 2343 let offsets = self.coverage_offsets(); 2344 ArrayOfOffsets::new(offsets, data, ()) 2345 } 2346 2347 /// Array of SequenceLookupRecords seq_lookup_records(&self) -> &'a [SequenceLookupRecord]2348 pub fn seq_lookup_records(&self) -> &'a [SequenceLookupRecord] { 2349 let range = self.shape.seq_lookup_records_byte_range(); 2350 self.data.read_array(range).unwrap() 2351 } 2352 } 2353 2354 #[cfg(feature = "traversal")] 2355 impl<'a> SomeTable<'a> for SequenceContextFormat3<'a> { type_name(&self) -> &str2356 fn type_name(&self) -> &str { 2357 "SequenceContextFormat3" 2358 } get_field(&self, idx: usize) -> Option<Field<'a>>2359 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 2360 match idx { 2361 0usize => Some(Field::new("format", self.format())), 2362 1usize => Some(Field::new("glyph_count", self.glyph_count())), 2363 2usize => Some(Field::new("seq_lookup_count", self.seq_lookup_count())), 2364 3usize => Some({ 2365 let data = self.data; 2366 Field::new( 2367 "coverage_offsets", 2368 FieldType::array_of_offsets( 2369 better_type_name::<CoverageTable>(), 2370 self.coverage_offsets(), 2371 move |off| { 2372 let target = off.get().resolve::<CoverageTable>(data); 2373 FieldType::offset(off.get(), target) 2374 }, 2375 ), 2376 ) 2377 }), 2378 4usize => Some(Field::new( 2379 "seq_lookup_records", 2380 traversal::FieldType::array_of_records( 2381 stringify!(SequenceLookupRecord), 2382 self.seq_lookup_records(), 2383 self.offset_data(), 2384 ), 2385 )), 2386 _ => None, 2387 } 2388 } 2389 } 2390 2391 #[cfg(feature = "traversal")] 2392 impl<'a> std::fmt::Debug for SequenceContextFormat3<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2393 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 2394 (self as &dyn SomeTable<'a>).fmt(f) 2395 } 2396 } 2397 2398 #[derive(Clone)] 2399 pub enum SequenceContext<'a> { 2400 Format1(SequenceContextFormat1<'a>), 2401 Format2(SequenceContextFormat2<'a>), 2402 Format3(SequenceContextFormat3<'a>), 2403 } 2404 2405 impl<'a> SequenceContext<'a> { 2406 /// Format identifier: format = 1 format(&self) -> u162407 pub fn format(&self) -> u16 { 2408 match self { 2409 Self::Format1(item) => item.format(), 2410 Self::Format2(item) => item.format(), 2411 Self::Format3(item) => item.format(), 2412 } 2413 } 2414 } 2415 2416 impl<'a> FontRead<'a> for SequenceContext<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>2417 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 2418 let format: u16 = data.read_at(0usize)?; 2419 match format { 2420 SequenceContextFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)), 2421 SequenceContextFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)), 2422 SequenceContextFormat3Marker::FORMAT => Ok(Self::Format3(FontRead::read(data)?)), 2423 other => Err(ReadError::InvalidFormat(other.into())), 2424 } 2425 } 2426 } 2427 2428 #[cfg(feature = "traversal")] 2429 impl<'a> SequenceContext<'a> { dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>2430 fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> { 2431 match self { 2432 Self::Format1(table) => table, 2433 Self::Format2(table) => table, 2434 Self::Format3(table) => table, 2435 } 2436 } 2437 } 2438 2439 #[cfg(feature = "traversal")] 2440 impl<'a> std::fmt::Debug for SequenceContext<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2441 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 2442 self.dyn_inner().fmt(f) 2443 } 2444 } 2445 2446 #[cfg(feature = "traversal")] 2447 impl<'a> SomeTable<'a> for SequenceContext<'a> { type_name(&self) -> &str2448 fn type_name(&self) -> &str { 2449 self.dyn_inner().type_name() 2450 } get_field(&self, idx: usize) -> Option<Field<'a>>2451 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 2452 self.dyn_inner().get_field(idx) 2453 } 2454 } 2455 2456 impl Format<u16> for ChainedSequenceContextFormat1Marker { 2457 const FORMAT: u16 = 1; 2458 } 2459 2460 /// [Chained Sequence Context Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#chained-sequence-context-format-1-simple-glyph-contexts) 2461 #[derive(Debug, Clone, Copy)] 2462 #[doc(hidden)] 2463 pub struct ChainedSequenceContextFormat1Marker { 2464 chained_seq_rule_set_offsets_byte_len: usize, 2465 } 2466 2467 impl ChainedSequenceContextFormat1Marker { format_byte_range(&self) -> Range<usize>2468 fn format_byte_range(&self) -> Range<usize> { 2469 let start = 0; 2470 start..start + u16::RAW_BYTE_LEN 2471 } coverage_offset_byte_range(&self) -> Range<usize>2472 fn coverage_offset_byte_range(&self) -> Range<usize> { 2473 let start = self.format_byte_range().end; 2474 start..start + Offset16::RAW_BYTE_LEN 2475 } chained_seq_rule_set_count_byte_range(&self) -> Range<usize>2476 fn chained_seq_rule_set_count_byte_range(&self) -> Range<usize> { 2477 let start = self.coverage_offset_byte_range().end; 2478 start..start + u16::RAW_BYTE_LEN 2479 } chained_seq_rule_set_offsets_byte_range(&self) -> Range<usize>2480 fn chained_seq_rule_set_offsets_byte_range(&self) -> Range<usize> { 2481 let start = self.chained_seq_rule_set_count_byte_range().end; 2482 start..start + self.chained_seq_rule_set_offsets_byte_len 2483 } 2484 } 2485 2486 impl<'a> FontRead<'a> for ChainedSequenceContextFormat1<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>2487 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 2488 let mut cursor = data.cursor(); 2489 cursor.advance::<u16>(); 2490 cursor.advance::<Offset16>(); 2491 let chained_seq_rule_set_count: u16 = cursor.read()?; 2492 let chained_seq_rule_set_offsets_byte_len = 2493 chained_seq_rule_set_count as usize * Offset16::RAW_BYTE_LEN; 2494 cursor.advance_by(chained_seq_rule_set_offsets_byte_len); 2495 cursor.finish(ChainedSequenceContextFormat1Marker { 2496 chained_seq_rule_set_offsets_byte_len, 2497 }) 2498 } 2499 } 2500 2501 /// [Chained Sequence Context Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#chained-sequence-context-format-1-simple-glyph-contexts) 2502 pub type ChainedSequenceContextFormat1<'a> = TableRef<'a, ChainedSequenceContextFormat1Marker>; 2503 2504 impl<'a> ChainedSequenceContextFormat1<'a> { 2505 /// Format identifier: format = 1 format(&self) -> u162506 pub fn format(&self) -> u16 { 2507 let range = self.shape.format_byte_range(); 2508 self.data.read_at(range.start).unwrap() 2509 } 2510 2511 /// Offset to Coverage table, from beginning of 2512 /// ChainSequenceContextFormat1 table coverage_offset(&self) -> Offset162513 pub fn coverage_offset(&self) -> Offset16 { 2514 let range = self.shape.coverage_offset_byte_range(); 2515 self.data.read_at(range.start).unwrap() 2516 } 2517 2518 /// Attempt to resolve [`coverage_offset`][Self::coverage_offset]. coverage(&self) -> Result<CoverageTable<'a>, ReadError>2519 pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> { 2520 let data = self.data; 2521 self.coverage_offset().resolve(data) 2522 } 2523 2524 /// Number of ChainedSequenceRuleSet tables chained_seq_rule_set_count(&self) -> u162525 pub fn chained_seq_rule_set_count(&self) -> u16 { 2526 let range = self.shape.chained_seq_rule_set_count_byte_range(); 2527 self.data.read_at(range.start).unwrap() 2528 } 2529 2530 /// Array of offsets to ChainedSeqRuleSet tables, from beginning of 2531 /// ChainedSequenceContextFormat1 table (may be NULL) chained_seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>]2532 pub fn chained_seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>] { 2533 let range = self.shape.chained_seq_rule_set_offsets_byte_range(); 2534 self.data.read_array(range).unwrap() 2535 } 2536 2537 /// A dynamically resolving wrapper for [`chained_seq_rule_set_offsets`][Self::chained_seq_rule_set_offsets]. chained_seq_rule_sets( &self, ) -> ArrayOfNullableOffsets<'a, ChainedSequenceRuleSet<'a>, Offset16>2538 pub fn chained_seq_rule_sets( 2539 &self, 2540 ) -> ArrayOfNullableOffsets<'a, ChainedSequenceRuleSet<'a>, Offset16> { 2541 let data = self.data; 2542 let offsets = self.chained_seq_rule_set_offsets(); 2543 ArrayOfNullableOffsets::new(offsets, data, ()) 2544 } 2545 } 2546 2547 #[cfg(feature = "traversal")] 2548 impl<'a> SomeTable<'a> for ChainedSequenceContextFormat1<'a> { type_name(&self) -> &str2549 fn type_name(&self) -> &str { 2550 "ChainedSequenceContextFormat1" 2551 } get_field(&self, idx: usize) -> Option<Field<'a>>2552 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 2553 match idx { 2554 0usize => Some(Field::new("format", self.format())), 2555 1usize => Some(Field::new( 2556 "coverage_offset", 2557 FieldType::offset(self.coverage_offset(), self.coverage()), 2558 )), 2559 2usize => Some(Field::new( 2560 "chained_seq_rule_set_count", 2561 self.chained_seq_rule_set_count(), 2562 )), 2563 3usize => Some({ 2564 let data = self.data; 2565 Field::new( 2566 "chained_seq_rule_set_offsets", 2567 FieldType::array_of_offsets( 2568 better_type_name::<ChainedSequenceRuleSet>(), 2569 self.chained_seq_rule_set_offsets(), 2570 move |off| { 2571 let target = off.get().resolve::<ChainedSequenceRuleSet>(data); 2572 FieldType::offset(off.get(), target) 2573 }, 2574 ), 2575 ) 2576 }), 2577 _ => None, 2578 } 2579 } 2580 } 2581 2582 #[cfg(feature = "traversal")] 2583 impl<'a> std::fmt::Debug for ChainedSequenceContextFormat1<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2584 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 2585 (self as &dyn SomeTable<'a>).fmt(f) 2586 } 2587 } 2588 2589 /// Part of [ChainedSequenceContextFormat1] 2590 #[derive(Debug, Clone, Copy)] 2591 #[doc(hidden)] 2592 pub struct ChainedSequenceRuleSetMarker { 2593 chained_seq_rule_offsets_byte_len: usize, 2594 } 2595 2596 impl ChainedSequenceRuleSetMarker { chained_seq_rule_count_byte_range(&self) -> Range<usize>2597 fn chained_seq_rule_count_byte_range(&self) -> Range<usize> { 2598 let start = 0; 2599 start..start + u16::RAW_BYTE_LEN 2600 } chained_seq_rule_offsets_byte_range(&self) -> Range<usize>2601 fn chained_seq_rule_offsets_byte_range(&self) -> Range<usize> { 2602 let start = self.chained_seq_rule_count_byte_range().end; 2603 start..start + self.chained_seq_rule_offsets_byte_len 2604 } 2605 } 2606 2607 impl<'a> FontRead<'a> for ChainedSequenceRuleSet<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>2608 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 2609 let mut cursor = data.cursor(); 2610 let chained_seq_rule_count: u16 = cursor.read()?; 2611 let chained_seq_rule_offsets_byte_len = 2612 chained_seq_rule_count as usize * Offset16::RAW_BYTE_LEN; 2613 cursor.advance_by(chained_seq_rule_offsets_byte_len); 2614 cursor.finish(ChainedSequenceRuleSetMarker { 2615 chained_seq_rule_offsets_byte_len, 2616 }) 2617 } 2618 } 2619 2620 /// Part of [ChainedSequenceContextFormat1] 2621 pub type ChainedSequenceRuleSet<'a> = TableRef<'a, ChainedSequenceRuleSetMarker>; 2622 2623 impl<'a> ChainedSequenceRuleSet<'a> { 2624 /// Number of ChainedSequenceRule tables chained_seq_rule_count(&self) -> u162625 pub fn chained_seq_rule_count(&self) -> u16 { 2626 let range = self.shape.chained_seq_rule_count_byte_range(); 2627 self.data.read_at(range.start).unwrap() 2628 } 2629 2630 /// Array of offsets to ChainedSequenceRule tables, from beginning 2631 /// of ChainedSequenceRuleSet table chained_seq_rule_offsets(&self) -> &'a [BigEndian<Offset16>]2632 pub fn chained_seq_rule_offsets(&self) -> &'a [BigEndian<Offset16>] { 2633 let range = self.shape.chained_seq_rule_offsets_byte_range(); 2634 self.data.read_array(range).unwrap() 2635 } 2636 2637 /// A dynamically resolving wrapper for [`chained_seq_rule_offsets`][Self::chained_seq_rule_offsets]. chained_seq_rules(&self) -> ArrayOfOffsets<'a, ChainedSequenceRule<'a>, Offset16>2638 pub fn chained_seq_rules(&self) -> ArrayOfOffsets<'a, ChainedSequenceRule<'a>, Offset16> { 2639 let data = self.data; 2640 let offsets = self.chained_seq_rule_offsets(); 2641 ArrayOfOffsets::new(offsets, data, ()) 2642 } 2643 } 2644 2645 #[cfg(feature = "traversal")] 2646 impl<'a> SomeTable<'a> for ChainedSequenceRuleSet<'a> { type_name(&self) -> &str2647 fn type_name(&self) -> &str { 2648 "ChainedSequenceRuleSet" 2649 } get_field(&self, idx: usize) -> Option<Field<'a>>2650 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 2651 match idx { 2652 0usize => Some(Field::new( 2653 "chained_seq_rule_count", 2654 self.chained_seq_rule_count(), 2655 )), 2656 1usize => Some({ 2657 let data = self.data; 2658 Field::new( 2659 "chained_seq_rule_offsets", 2660 FieldType::array_of_offsets( 2661 better_type_name::<ChainedSequenceRule>(), 2662 self.chained_seq_rule_offsets(), 2663 move |off| { 2664 let target = off.get().resolve::<ChainedSequenceRule>(data); 2665 FieldType::offset(off.get(), target) 2666 }, 2667 ), 2668 ) 2669 }), 2670 _ => None, 2671 } 2672 } 2673 } 2674 2675 #[cfg(feature = "traversal")] 2676 impl<'a> std::fmt::Debug for ChainedSequenceRuleSet<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2677 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 2678 (self as &dyn SomeTable<'a>).fmt(f) 2679 } 2680 } 2681 2682 /// Part of [ChainedSequenceContextFormat1] 2683 #[derive(Debug, Clone, Copy)] 2684 #[doc(hidden)] 2685 pub struct ChainedSequenceRuleMarker { 2686 backtrack_sequence_byte_len: usize, 2687 input_sequence_byte_len: usize, 2688 lookahead_sequence_byte_len: usize, 2689 seq_lookup_records_byte_len: usize, 2690 } 2691 2692 impl ChainedSequenceRuleMarker { backtrack_glyph_count_byte_range(&self) -> Range<usize>2693 fn backtrack_glyph_count_byte_range(&self) -> Range<usize> { 2694 let start = 0; 2695 start..start + u16::RAW_BYTE_LEN 2696 } backtrack_sequence_byte_range(&self) -> Range<usize>2697 fn backtrack_sequence_byte_range(&self) -> Range<usize> { 2698 let start = self.backtrack_glyph_count_byte_range().end; 2699 start..start + self.backtrack_sequence_byte_len 2700 } input_glyph_count_byte_range(&self) -> Range<usize>2701 fn input_glyph_count_byte_range(&self) -> Range<usize> { 2702 let start = self.backtrack_sequence_byte_range().end; 2703 start..start + u16::RAW_BYTE_LEN 2704 } input_sequence_byte_range(&self) -> Range<usize>2705 fn input_sequence_byte_range(&self) -> Range<usize> { 2706 let start = self.input_glyph_count_byte_range().end; 2707 start..start + self.input_sequence_byte_len 2708 } lookahead_glyph_count_byte_range(&self) -> Range<usize>2709 fn lookahead_glyph_count_byte_range(&self) -> Range<usize> { 2710 let start = self.input_sequence_byte_range().end; 2711 start..start + u16::RAW_BYTE_LEN 2712 } lookahead_sequence_byte_range(&self) -> Range<usize>2713 fn lookahead_sequence_byte_range(&self) -> Range<usize> { 2714 let start = self.lookahead_glyph_count_byte_range().end; 2715 start..start + self.lookahead_sequence_byte_len 2716 } seq_lookup_count_byte_range(&self) -> Range<usize>2717 fn seq_lookup_count_byte_range(&self) -> Range<usize> { 2718 let start = self.lookahead_sequence_byte_range().end; 2719 start..start + u16::RAW_BYTE_LEN 2720 } seq_lookup_records_byte_range(&self) -> Range<usize>2721 fn seq_lookup_records_byte_range(&self) -> Range<usize> { 2722 let start = self.seq_lookup_count_byte_range().end; 2723 start..start + self.seq_lookup_records_byte_len 2724 } 2725 } 2726 2727 impl<'a> FontRead<'a> for ChainedSequenceRule<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>2728 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 2729 let mut cursor = data.cursor(); 2730 let backtrack_glyph_count: u16 = cursor.read()?; 2731 let backtrack_sequence_byte_len = backtrack_glyph_count as usize * GlyphId::RAW_BYTE_LEN; 2732 cursor.advance_by(backtrack_sequence_byte_len); 2733 let input_glyph_count: u16 = cursor.read()?; 2734 let input_sequence_byte_len = 2735 transforms::subtract(input_glyph_count, 1_usize) * GlyphId::RAW_BYTE_LEN; 2736 cursor.advance_by(input_sequence_byte_len); 2737 let lookahead_glyph_count: u16 = cursor.read()?; 2738 let lookahead_sequence_byte_len = lookahead_glyph_count as usize * GlyphId::RAW_BYTE_LEN; 2739 cursor.advance_by(lookahead_sequence_byte_len); 2740 let seq_lookup_count: u16 = cursor.read()?; 2741 let seq_lookup_records_byte_len = 2742 seq_lookup_count as usize * SequenceLookupRecord::RAW_BYTE_LEN; 2743 cursor.advance_by(seq_lookup_records_byte_len); 2744 cursor.finish(ChainedSequenceRuleMarker { 2745 backtrack_sequence_byte_len, 2746 input_sequence_byte_len, 2747 lookahead_sequence_byte_len, 2748 seq_lookup_records_byte_len, 2749 }) 2750 } 2751 } 2752 2753 /// Part of [ChainedSequenceContextFormat1] 2754 pub type ChainedSequenceRule<'a> = TableRef<'a, ChainedSequenceRuleMarker>; 2755 2756 impl<'a> ChainedSequenceRule<'a> { 2757 /// Number of glyphs in the backtrack sequence backtrack_glyph_count(&self) -> u162758 pub fn backtrack_glyph_count(&self) -> u16 { 2759 let range = self.shape.backtrack_glyph_count_byte_range(); 2760 self.data.read_at(range.start).unwrap() 2761 } 2762 2763 /// Array of backtrack glyph IDs backtrack_sequence(&self) -> &'a [BigEndian<GlyphId>]2764 pub fn backtrack_sequence(&self) -> &'a [BigEndian<GlyphId>] { 2765 let range = self.shape.backtrack_sequence_byte_range(); 2766 self.data.read_array(range).unwrap() 2767 } 2768 2769 /// Number of glyphs in the input sequence input_glyph_count(&self) -> u162770 pub fn input_glyph_count(&self) -> u16 { 2771 let range = self.shape.input_glyph_count_byte_range(); 2772 self.data.read_at(range.start).unwrap() 2773 } 2774 2775 /// Array of input glyph IDs—start with second glyph input_sequence(&self) -> &'a [BigEndian<GlyphId>]2776 pub fn input_sequence(&self) -> &'a [BigEndian<GlyphId>] { 2777 let range = self.shape.input_sequence_byte_range(); 2778 self.data.read_array(range).unwrap() 2779 } 2780 2781 /// Number of glyphs in the lookahead sequence lookahead_glyph_count(&self) -> u162782 pub fn lookahead_glyph_count(&self) -> u16 { 2783 let range = self.shape.lookahead_glyph_count_byte_range(); 2784 self.data.read_at(range.start).unwrap() 2785 } 2786 2787 /// Array of lookahead glyph IDs lookahead_sequence(&self) -> &'a [BigEndian<GlyphId>]2788 pub fn lookahead_sequence(&self) -> &'a [BigEndian<GlyphId>] { 2789 let range = self.shape.lookahead_sequence_byte_range(); 2790 self.data.read_array(range).unwrap() 2791 } 2792 2793 /// Number of SequenceLookupRecords seq_lookup_count(&self) -> u162794 pub fn seq_lookup_count(&self) -> u16 { 2795 let range = self.shape.seq_lookup_count_byte_range(); 2796 self.data.read_at(range.start).unwrap() 2797 } 2798 2799 /// Array of SequenceLookupRecords seq_lookup_records(&self) -> &'a [SequenceLookupRecord]2800 pub fn seq_lookup_records(&self) -> &'a [SequenceLookupRecord] { 2801 let range = self.shape.seq_lookup_records_byte_range(); 2802 self.data.read_array(range).unwrap() 2803 } 2804 } 2805 2806 #[cfg(feature = "traversal")] 2807 impl<'a> SomeTable<'a> for ChainedSequenceRule<'a> { type_name(&self) -> &str2808 fn type_name(&self) -> &str { 2809 "ChainedSequenceRule" 2810 } get_field(&self, idx: usize) -> Option<Field<'a>>2811 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 2812 match idx { 2813 0usize => Some(Field::new( 2814 "backtrack_glyph_count", 2815 self.backtrack_glyph_count(), 2816 )), 2817 1usize => Some(Field::new("backtrack_sequence", self.backtrack_sequence())), 2818 2usize => Some(Field::new("input_glyph_count", self.input_glyph_count())), 2819 3usize => Some(Field::new("input_sequence", self.input_sequence())), 2820 4usize => Some(Field::new( 2821 "lookahead_glyph_count", 2822 self.lookahead_glyph_count(), 2823 )), 2824 5usize => Some(Field::new("lookahead_sequence", self.lookahead_sequence())), 2825 6usize => Some(Field::new("seq_lookup_count", self.seq_lookup_count())), 2826 7usize => Some(Field::new( 2827 "seq_lookup_records", 2828 traversal::FieldType::array_of_records( 2829 stringify!(SequenceLookupRecord), 2830 self.seq_lookup_records(), 2831 self.offset_data(), 2832 ), 2833 )), 2834 _ => None, 2835 } 2836 } 2837 } 2838 2839 #[cfg(feature = "traversal")] 2840 impl<'a> std::fmt::Debug for ChainedSequenceRule<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2841 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 2842 (self as &dyn SomeTable<'a>).fmt(f) 2843 } 2844 } 2845 2846 impl Format<u16> for ChainedSequenceContextFormat2Marker { 2847 const FORMAT: u16 = 2; 2848 } 2849 2850 /// [Chained Sequence Context Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#chained-sequence-context-format-2-class-based-glyph-contexts) 2851 #[derive(Debug, Clone, Copy)] 2852 #[doc(hidden)] 2853 pub struct ChainedSequenceContextFormat2Marker { 2854 chained_class_seq_rule_set_offsets_byte_len: usize, 2855 } 2856 2857 impl ChainedSequenceContextFormat2Marker { format_byte_range(&self) -> Range<usize>2858 fn format_byte_range(&self) -> Range<usize> { 2859 let start = 0; 2860 start..start + u16::RAW_BYTE_LEN 2861 } coverage_offset_byte_range(&self) -> Range<usize>2862 fn coverage_offset_byte_range(&self) -> Range<usize> { 2863 let start = self.format_byte_range().end; 2864 start..start + Offset16::RAW_BYTE_LEN 2865 } backtrack_class_def_offset_byte_range(&self) -> Range<usize>2866 fn backtrack_class_def_offset_byte_range(&self) -> Range<usize> { 2867 let start = self.coverage_offset_byte_range().end; 2868 start..start + Offset16::RAW_BYTE_LEN 2869 } input_class_def_offset_byte_range(&self) -> Range<usize>2870 fn input_class_def_offset_byte_range(&self) -> Range<usize> { 2871 let start = self.backtrack_class_def_offset_byte_range().end; 2872 start..start + Offset16::RAW_BYTE_LEN 2873 } lookahead_class_def_offset_byte_range(&self) -> Range<usize>2874 fn lookahead_class_def_offset_byte_range(&self) -> Range<usize> { 2875 let start = self.input_class_def_offset_byte_range().end; 2876 start..start + Offset16::RAW_BYTE_LEN 2877 } chained_class_seq_rule_set_count_byte_range(&self) -> Range<usize>2878 fn chained_class_seq_rule_set_count_byte_range(&self) -> Range<usize> { 2879 let start = self.lookahead_class_def_offset_byte_range().end; 2880 start..start + u16::RAW_BYTE_LEN 2881 } chained_class_seq_rule_set_offsets_byte_range(&self) -> Range<usize>2882 fn chained_class_seq_rule_set_offsets_byte_range(&self) -> Range<usize> { 2883 let start = self.chained_class_seq_rule_set_count_byte_range().end; 2884 start..start + self.chained_class_seq_rule_set_offsets_byte_len 2885 } 2886 } 2887 2888 impl<'a> FontRead<'a> for ChainedSequenceContextFormat2<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>2889 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 2890 let mut cursor = data.cursor(); 2891 cursor.advance::<u16>(); 2892 cursor.advance::<Offset16>(); 2893 cursor.advance::<Offset16>(); 2894 cursor.advance::<Offset16>(); 2895 cursor.advance::<Offset16>(); 2896 let chained_class_seq_rule_set_count: u16 = cursor.read()?; 2897 let chained_class_seq_rule_set_offsets_byte_len = 2898 chained_class_seq_rule_set_count as usize * Offset16::RAW_BYTE_LEN; 2899 cursor.advance_by(chained_class_seq_rule_set_offsets_byte_len); 2900 cursor.finish(ChainedSequenceContextFormat2Marker { 2901 chained_class_seq_rule_set_offsets_byte_len, 2902 }) 2903 } 2904 } 2905 2906 /// [Chained Sequence Context Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#chained-sequence-context-format-2-class-based-glyph-contexts) 2907 pub type ChainedSequenceContextFormat2<'a> = TableRef<'a, ChainedSequenceContextFormat2Marker>; 2908 2909 impl<'a> ChainedSequenceContextFormat2<'a> { 2910 /// Format identifier: format = 2 format(&self) -> u162911 pub fn format(&self) -> u16 { 2912 let range = self.shape.format_byte_range(); 2913 self.data.read_at(range.start).unwrap() 2914 } 2915 2916 /// Offset to Coverage table, from beginning of 2917 /// ChainedSequenceContextFormat2 table coverage_offset(&self) -> Offset162918 pub fn coverage_offset(&self) -> Offset16 { 2919 let range = self.shape.coverage_offset_byte_range(); 2920 self.data.read_at(range.start).unwrap() 2921 } 2922 2923 /// Attempt to resolve [`coverage_offset`][Self::coverage_offset]. coverage(&self) -> Result<CoverageTable<'a>, ReadError>2924 pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> { 2925 let data = self.data; 2926 self.coverage_offset().resolve(data) 2927 } 2928 2929 /// Offset to ClassDef table containing backtrack sequence context, 2930 /// from beginning of ChainedSequenceContextFormat2 table backtrack_class_def_offset(&self) -> Offset162931 pub fn backtrack_class_def_offset(&self) -> Offset16 { 2932 let range = self.shape.backtrack_class_def_offset_byte_range(); 2933 self.data.read_at(range.start).unwrap() 2934 } 2935 2936 /// Attempt to resolve [`backtrack_class_def_offset`][Self::backtrack_class_def_offset]. backtrack_class_def(&self) -> Result<ClassDef<'a>, ReadError>2937 pub fn backtrack_class_def(&self) -> Result<ClassDef<'a>, ReadError> { 2938 let data = self.data; 2939 self.backtrack_class_def_offset().resolve(data) 2940 } 2941 2942 /// Offset to ClassDef table containing input sequence context, 2943 /// from beginning of ChainedSequenceContextFormat2 table input_class_def_offset(&self) -> Offset162944 pub fn input_class_def_offset(&self) -> Offset16 { 2945 let range = self.shape.input_class_def_offset_byte_range(); 2946 self.data.read_at(range.start).unwrap() 2947 } 2948 2949 /// Attempt to resolve [`input_class_def_offset`][Self::input_class_def_offset]. input_class_def(&self) -> Result<ClassDef<'a>, ReadError>2950 pub fn input_class_def(&self) -> Result<ClassDef<'a>, ReadError> { 2951 let data = self.data; 2952 self.input_class_def_offset().resolve(data) 2953 } 2954 2955 /// Offset to ClassDef table containing lookahead sequence context, 2956 /// from beginning of ChainedSequenceContextFormat2 table lookahead_class_def_offset(&self) -> Offset162957 pub fn lookahead_class_def_offset(&self) -> Offset16 { 2958 let range = self.shape.lookahead_class_def_offset_byte_range(); 2959 self.data.read_at(range.start).unwrap() 2960 } 2961 2962 /// Attempt to resolve [`lookahead_class_def_offset`][Self::lookahead_class_def_offset]. lookahead_class_def(&self) -> Result<ClassDef<'a>, ReadError>2963 pub fn lookahead_class_def(&self) -> Result<ClassDef<'a>, ReadError> { 2964 let data = self.data; 2965 self.lookahead_class_def_offset().resolve(data) 2966 } 2967 2968 /// Number of ChainedClassSequenceRuleSet tables chained_class_seq_rule_set_count(&self) -> u162969 pub fn chained_class_seq_rule_set_count(&self) -> u16 { 2970 let range = self.shape.chained_class_seq_rule_set_count_byte_range(); 2971 self.data.read_at(range.start).unwrap() 2972 } 2973 2974 /// Array of offsets to ChainedClassSequenceRuleSet tables, from 2975 /// beginning of ChainedSequenceContextFormat2 table (may be NULL) chained_class_seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>]2976 pub fn chained_class_seq_rule_set_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>] { 2977 let range = self.shape.chained_class_seq_rule_set_offsets_byte_range(); 2978 self.data.read_array(range).unwrap() 2979 } 2980 2981 /// A dynamically resolving wrapper for [`chained_class_seq_rule_set_offsets`][Self::chained_class_seq_rule_set_offsets]. chained_class_seq_rule_sets( &self, ) -> ArrayOfNullableOffsets<'a, ChainedClassSequenceRuleSet<'a>, Offset16>2982 pub fn chained_class_seq_rule_sets( 2983 &self, 2984 ) -> ArrayOfNullableOffsets<'a, ChainedClassSequenceRuleSet<'a>, Offset16> { 2985 let data = self.data; 2986 let offsets = self.chained_class_seq_rule_set_offsets(); 2987 ArrayOfNullableOffsets::new(offsets, data, ()) 2988 } 2989 } 2990 2991 #[cfg(feature = "traversal")] 2992 impl<'a> SomeTable<'a> for ChainedSequenceContextFormat2<'a> { type_name(&self) -> &str2993 fn type_name(&self) -> &str { 2994 "ChainedSequenceContextFormat2" 2995 } get_field(&self, idx: usize) -> Option<Field<'a>>2996 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 2997 match idx { 2998 0usize => Some(Field::new("format", self.format())), 2999 1usize => Some(Field::new( 3000 "coverage_offset", 3001 FieldType::offset(self.coverage_offset(), self.coverage()), 3002 )), 3003 2usize => Some(Field::new( 3004 "backtrack_class_def_offset", 3005 FieldType::offset( 3006 self.backtrack_class_def_offset(), 3007 self.backtrack_class_def(), 3008 ), 3009 )), 3010 3usize => Some(Field::new( 3011 "input_class_def_offset", 3012 FieldType::offset(self.input_class_def_offset(), self.input_class_def()), 3013 )), 3014 4usize => Some(Field::new( 3015 "lookahead_class_def_offset", 3016 FieldType::offset( 3017 self.lookahead_class_def_offset(), 3018 self.lookahead_class_def(), 3019 ), 3020 )), 3021 5usize => Some(Field::new( 3022 "chained_class_seq_rule_set_count", 3023 self.chained_class_seq_rule_set_count(), 3024 )), 3025 6usize => Some({ 3026 let data = self.data; 3027 Field::new( 3028 "chained_class_seq_rule_set_offsets", 3029 FieldType::array_of_offsets( 3030 better_type_name::<ChainedClassSequenceRuleSet>(), 3031 self.chained_class_seq_rule_set_offsets(), 3032 move |off| { 3033 let target = off.get().resolve::<ChainedClassSequenceRuleSet>(data); 3034 FieldType::offset(off.get(), target) 3035 }, 3036 ), 3037 ) 3038 }), 3039 _ => None, 3040 } 3041 } 3042 } 3043 3044 #[cfg(feature = "traversal")] 3045 impl<'a> std::fmt::Debug for ChainedSequenceContextFormat2<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3046 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3047 (self as &dyn SomeTable<'a>).fmt(f) 3048 } 3049 } 3050 3051 /// Part of [ChainedSequenceContextFormat2] 3052 #[derive(Debug, Clone, Copy)] 3053 #[doc(hidden)] 3054 pub struct ChainedClassSequenceRuleSetMarker { 3055 chained_class_seq_rule_offsets_byte_len: usize, 3056 } 3057 3058 impl ChainedClassSequenceRuleSetMarker { chained_class_seq_rule_count_byte_range(&self) -> Range<usize>3059 fn chained_class_seq_rule_count_byte_range(&self) -> Range<usize> { 3060 let start = 0; 3061 start..start + u16::RAW_BYTE_LEN 3062 } chained_class_seq_rule_offsets_byte_range(&self) -> Range<usize>3063 fn chained_class_seq_rule_offsets_byte_range(&self) -> Range<usize> { 3064 let start = self.chained_class_seq_rule_count_byte_range().end; 3065 start..start + self.chained_class_seq_rule_offsets_byte_len 3066 } 3067 } 3068 3069 impl<'a> FontRead<'a> for ChainedClassSequenceRuleSet<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>3070 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 3071 let mut cursor = data.cursor(); 3072 let chained_class_seq_rule_count: u16 = cursor.read()?; 3073 let chained_class_seq_rule_offsets_byte_len = 3074 chained_class_seq_rule_count as usize * Offset16::RAW_BYTE_LEN; 3075 cursor.advance_by(chained_class_seq_rule_offsets_byte_len); 3076 cursor.finish(ChainedClassSequenceRuleSetMarker { 3077 chained_class_seq_rule_offsets_byte_len, 3078 }) 3079 } 3080 } 3081 3082 /// Part of [ChainedSequenceContextFormat2] 3083 pub type ChainedClassSequenceRuleSet<'a> = TableRef<'a, ChainedClassSequenceRuleSetMarker>; 3084 3085 impl<'a> ChainedClassSequenceRuleSet<'a> { 3086 /// Number of ChainedClassSequenceRule tables chained_class_seq_rule_count(&self) -> u163087 pub fn chained_class_seq_rule_count(&self) -> u16 { 3088 let range = self.shape.chained_class_seq_rule_count_byte_range(); 3089 self.data.read_at(range.start).unwrap() 3090 } 3091 3092 /// Array of offsets to ChainedClassSequenceRule tables, from 3093 /// beginning of ChainedClassSequenceRuleSet chained_class_seq_rule_offsets(&self) -> &'a [BigEndian<Offset16>]3094 pub fn chained_class_seq_rule_offsets(&self) -> &'a [BigEndian<Offset16>] { 3095 let range = self.shape.chained_class_seq_rule_offsets_byte_range(); 3096 self.data.read_array(range).unwrap() 3097 } 3098 3099 /// A dynamically resolving wrapper for [`chained_class_seq_rule_offsets`][Self::chained_class_seq_rule_offsets]. chained_class_seq_rules( &self, ) -> ArrayOfOffsets<'a, ChainedClassSequenceRule<'a>, Offset16>3100 pub fn chained_class_seq_rules( 3101 &self, 3102 ) -> ArrayOfOffsets<'a, ChainedClassSequenceRule<'a>, Offset16> { 3103 let data = self.data; 3104 let offsets = self.chained_class_seq_rule_offsets(); 3105 ArrayOfOffsets::new(offsets, data, ()) 3106 } 3107 } 3108 3109 #[cfg(feature = "traversal")] 3110 impl<'a> SomeTable<'a> for ChainedClassSequenceRuleSet<'a> { type_name(&self) -> &str3111 fn type_name(&self) -> &str { 3112 "ChainedClassSequenceRuleSet" 3113 } get_field(&self, idx: usize) -> Option<Field<'a>>3114 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3115 match idx { 3116 0usize => Some(Field::new( 3117 "chained_class_seq_rule_count", 3118 self.chained_class_seq_rule_count(), 3119 )), 3120 1usize => Some({ 3121 let data = self.data; 3122 Field::new( 3123 "chained_class_seq_rule_offsets", 3124 FieldType::array_of_offsets( 3125 better_type_name::<ChainedClassSequenceRule>(), 3126 self.chained_class_seq_rule_offsets(), 3127 move |off| { 3128 let target = off.get().resolve::<ChainedClassSequenceRule>(data); 3129 FieldType::offset(off.get(), target) 3130 }, 3131 ), 3132 ) 3133 }), 3134 _ => None, 3135 } 3136 } 3137 } 3138 3139 #[cfg(feature = "traversal")] 3140 impl<'a> std::fmt::Debug for ChainedClassSequenceRuleSet<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3141 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3142 (self as &dyn SomeTable<'a>).fmt(f) 3143 } 3144 } 3145 3146 /// Part of [ChainedSequenceContextFormat2] 3147 #[derive(Debug, Clone, Copy)] 3148 #[doc(hidden)] 3149 pub struct ChainedClassSequenceRuleMarker { 3150 backtrack_sequence_byte_len: usize, 3151 input_sequence_byte_len: usize, 3152 lookahead_sequence_byte_len: usize, 3153 seq_lookup_records_byte_len: usize, 3154 } 3155 3156 impl ChainedClassSequenceRuleMarker { backtrack_glyph_count_byte_range(&self) -> Range<usize>3157 fn backtrack_glyph_count_byte_range(&self) -> Range<usize> { 3158 let start = 0; 3159 start..start + u16::RAW_BYTE_LEN 3160 } backtrack_sequence_byte_range(&self) -> Range<usize>3161 fn backtrack_sequence_byte_range(&self) -> Range<usize> { 3162 let start = self.backtrack_glyph_count_byte_range().end; 3163 start..start + self.backtrack_sequence_byte_len 3164 } input_glyph_count_byte_range(&self) -> Range<usize>3165 fn input_glyph_count_byte_range(&self) -> Range<usize> { 3166 let start = self.backtrack_sequence_byte_range().end; 3167 start..start + u16::RAW_BYTE_LEN 3168 } input_sequence_byte_range(&self) -> Range<usize>3169 fn input_sequence_byte_range(&self) -> Range<usize> { 3170 let start = self.input_glyph_count_byte_range().end; 3171 start..start + self.input_sequence_byte_len 3172 } lookahead_glyph_count_byte_range(&self) -> Range<usize>3173 fn lookahead_glyph_count_byte_range(&self) -> Range<usize> { 3174 let start = self.input_sequence_byte_range().end; 3175 start..start + u16::RAW_BYTE_LEN 3176 } lookahead_sequence_byte_range(&self) -> Range<usize>3177 fn lookahead_sequence_byte_range(&self) -> Range<usize> { 3178 let start = self.lookahead_glyph_count_byte_range().end; 3179 start..start + self.lookahead_sequence_byte_len 3180 } seq_lookup_count_byte_range(&self) -> Range<usize>3181 fn seq_lookup_count_byte_range(&self) -> Range<usize> { 3182 let start = self.lookahead_sequence_byte_range().end; 3183 start..start + u16::RAW_BYTE_LEN 3184 } seq_lookup_records_byte_range(&self) -> Range<usize>3185 fn seq_lookup_records_byte_range(&self) -> Range<usize> { 3186 let start = self.seq_lookup_count_byte_range().end; 3187 start..start + self.seq_lookup_records_byte_len 3188 } 3189 } 3190 3191 impl<'a> FontRead<'a> for ChainedClassSequenceRule<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>3192 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 3193 let mut cursor = data.cursor(); 3194 let backtrack_glyph_count: u16 = cursor.read()?; 3195 let backtrack_sequence_byte_len = backtrack_glyph_count as usize * u16::RAW_BYTE_LEN; 3196 cursor.advance_by(backtrack_sequence_byte_len); 3197 let input_glyph_count: u16 = cursor.read()?; 3198 let input_sequence_byte_len = 3199 transforms::subtract(input_glyph_count, 1_usize) * u16::RAW_BYTE_LEN; 3200 cursor.advance_by(input_sequence_byte_len); 3201 let lookahead_glyph_count: u16 = cursor.read()?; 3202 let lookahead_sequence_byte_len = lookahead_glyph_count as usize * u16::RAW_BYTE_LEN; 3203 cursor.advance_by(lookahead_sequence_byte_len); 3204 let seq_lookup_count: u16 = cursor.read()?; 3205 let seq_lookup_records_byte_len = 3206 seq_lookup_count as usize * SequenceLookupRecord::RAW_BYTE_LEN; 3207 cursor.advance_by(seq_lookup_records_byte_len); 3208 cursor.finish(ChainedClassSequenceRuleMarker { 3209 backtrack_sequence_byte_len, 3210 input_sequence_byte_len, 3211 lookahead_sequence_byte_len, 3212 seq_lookup_records_byte_len, 3213 }) 3214 } 3215 } 3216 3217 /// Part of [ChainedSequenceContextFormat2] 3218 pub type ChainedClassSequenceRule<'a> = TableRef<'a, ChainedClassSequenceRuleMarker>; 3219 3220 impl<'a> ChainedClassSequenceRule<'a> { 3221 /// Number of glyphs in the backtrack sequence backtrack_glyph_count(&self) -> u163222 pub fn backtrack_glyph_count(&self) -> u16 { 3223 let range = self.shape.backtrack_glyph_count_byte_range(); 3224 self.data.read_at(range.start).unwrap() 3225 } 3226 3227 /// Array of backtrack-sequence classes backtrack_sequence(&self) -> &'a [BigEndian<u16>]3228 pub fn backtrack_sequence(&self) -> &'a [BigEndian<u16>] { 3229 let range = self.shape.backtrack_sequence_byte_range(); 3230 self.data.read_array(range).unwrap() 3231 } 3232 3233 /// Total number of glyphs in the input sequence input_glyph_count(&self) -> u163234 pub fn input_glyph_count(&self) -> u16 { 3235 let range = self.shape.input_glyph_count_byte_range(); 3236 self.data.read_at(range.start).unwrap() 3237 } 3238 3239 /// Array of input sequence classes, beginning with the second 3240 /// glyph position input_sequence(&self) -> &'a [BigEndian<u16>]3241 pub fn input_sequence(&self) -> &'a [BigEndian<u16>] { 3242 let range = self.shape.input_sequence_byte_range(); 3243 self.data.read_array(range).unwrap() 3244 } 3245 3246 /// Number of glyphs in the lookahead sequence lookahead_glyph_count(&self) -> u163247 pub fn lookahead_glyph_count(&self) -> u16 { 3248 let range = self.shape.lookahead_glyph_count_byte_range(); 3249 self.data.read_at(range.start).unwrap() 3250 } 3251 3252 /// Array of lookahead-sequence classes lookahead_sequence(&self) -> &'a [BigEndian<u16>]3253 pub fn lookahead_sequence(&self) -> &'a [BigEndian<u16>] { 3254 let range = self.shape.lookahead_sequence_byte_range(); 3255 self.data.read_array(range).unwrap() 3256 } 3257 3258 /// Number of SequenceLookupRecords seq_lookup_count(&self) -> u163259 pub fn seq_lookup_count(&self) -> u16 { 3260 let range = self.shape.seq_lookup_count_byte_range(); 3261 self.data.read_at(range.start).unwrap() 3262 } 3263 3264 /// Array of SequenceLookupRecords seq_lookup_records(&self) -> &'a [SequenceLookupRecord]3265 pub fn seq_lookup_records(&self) -> &'a [SequenceLookupRecord] { 3266 let range = self.shape.seq_lookup_records_byte_range(); 3267 self.data.read_array(range).unwrap() 3268 } 3269 } 3270 3271 #[cfg(feature = "traversal")] 3272 impl<'a> SomeTable<'a> for ChainedClassSequenceRule<'a> { type_name(&self) -> &str3273 fn type_name(&self) -> &str { 3274 "ChainedClassSequenceRule" 3275 } get_field(&self, idx: usize) -> Option<Field<'a>>3276 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3277 match idx { 3278 0usize => Some(Field::new( 3279 "backtrack_glyph_count", 3280 self.backtrack_glyph_count(), 3281 )), 3282 1usize => Some(Field::new("backtrack_sequence", self.backtrack_sequence())), 3283 2usize => Some(Field::new("input_glyph_count", self.input_glyph_count())), 3284 3usize => Some(Field::new("input_sequence", self.input_sequence())), 3285 4usize => Some(Field::new( 3286 "lookahead_glyph_count", 3287 self.lookahead_glyph_count(), 3288 )), 3289 5usize => Some(Field::new("lookahead_sequence", self.lookahead_sequence())), 3290 6usize => Some(Field::new("seq_lookup_count", self.seq_lookup_count())), 3291 7usize => Some(Field::new( 3292 "seq_lookup_records", 3293 traversal::FieldType::array_of_records( 3294 stringify!(SequenceLookupRecord), 3295 self.seq_lookup_records(), 3296 self.offset_data(), 3297 ), 3298 )), 3299 _ => None, 3300 } 3301 } 3302 } 3303 3304 #[cfg(feature = "traversal")] 3305 impl<'a> std::fmt::Debug for ChainedClassSequenceRule<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3306 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3307 (self as &dyn SomeTable<'a>).fmt(f) 3308 } 3309 } 3310 3311 impl Format<u16> for ChainedSequenceContextFormat3Marker { 3312 const FORMAT: u16 = 3; 3313 } 3314 3315 /// [Chained Sequence Context Format 3](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#chained-sequence-context-format-3-coverage-based-glyph-contexts) 3316 #[derive(Debug, Clone, Copy)] 3317 #[doc(hidden)] 3318 pub struct ChainedSequenceContextFormat3Marker { 3319 backtrack_coverage_offsets_byte_len: usize, 3320 input_coverage_offsets_byte_len: usize, 3321 lookahead_coverage_offsets_byte_len: usize, 3322 seq_lookup_records_byte_len: usize, 3323 } 3324 3325 impl ChainedSequenceContextFormat3Marker { format_byte_range(&self) -> Range<usize>3326 fn format_byte_range(&self) -> Range<usize> { 3327 let start = 0; 3328 start..start + u16::RAW_BYTE_LEN 3329 } backtrack_glyph_count_byte_range(&self) -> Range<usize>3330 fn backtrack_glyph_count_byte_range(&self) -> Range<usize> { 3331 let start = self.format_byte_range().end; 3332 start..start + u16::RAW_BYTE_LEN 3333 } backtrack_coverage_offsets_byte_range(&self) -> Range<usize>3334 fn backtrack_coverage_offsets_byte_range(&self) -> Range<usize> { 3335 let start = self.backtrack_glyph_count_byte_range().end; 3336 start..start + self.backtrack_coverage_offsets_byte_len 3337 } input_glyph_count_byte_range(&self) -> Range<usize>3338 fn input_glyph_count_byte_range(&self) -> Range<usize> { 3339 let start = self.backtrack_coverage_offsets_byte_range().end; 3340 start..start + u16::RAW_BYTE_LEN 3341 } input_coverage_offsets_byte_range(&self) -> Range<usize>3342 fn input_coverage_offsets_byte_range(&self) -> Range<usize> { 3343 let start = self.input_glyph_count_byte_range().end; 3344 start..start + self.input_coverage_offsets_byte_len 3345 } lookahead_glyph_count_byte_range(&self) -> Range<usize>3346 fn lookahead_glyph_count_byte_range(&self) -> Range<usize> { 3347 let start = self.input_coverage_offsets_byte_range().end; 3348 start..start + u16::RAW_BYTE_LEN 3349 } lookahead_coverage_offsets_byte_range(&self) -> Range<usize>3350 fn lookahead_coverage_offsets_byte_range(&self) -> Range<usize> { 3351 let start = self.lookahead_glyph_count_byte_range().end; 3352 start..start + self.lookahead_coverage_offsets_byte_len 3353 } seq_lookup_count_byte_range(&self) -> Range<usize>3354 fn seq_lookup_count_byte_range(&self) -> Range<usize> { 3355 let start = self.lookahead_coverage_offsets_byte_range().end; 3356 start..start + u16::RAW_BYTE_LEN 3357 } seq_lookup_records_byte_range(&self) -> Range<usize>3358 fn seq_lookup_records_byte_range(&self) -> Range<usize> { 3359 let start = self.seq_lookup_count_byte_range().end; 3360 start..start + self.seq_lookup_records_byte_len 3361 } 3362 } 3363 3364 impl<'a> FontRead<'a> for ChainedSequenceContextFormat3<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>3365 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 3366 let mut cursor = data.cursor(); 3367 cursor.advance::<u16>(); 3368 let backtrack_glyph_count: u16 = cursor.read()?; 3369 let backtrack_coverage_offsets_byte_len = 3370 backtrack_glyph_count as usize * Offset16::RAW_BYTE_LEN; 3371 cursor.advance_by(backtrack_coverage_offsets_byte_len); 3372 let input_glyph_count: u16 = cursor.read()?; 3373 let input_coverage_offsets_byte_len = input_glyph_count as usize * Offset16::RAW_BYTE_LEN; 3374 cursor.advance_by(input_coverage_offsets_byte_len); 3375 let lookahead_glyph_count: u16 = cursor.read()?; 3376 let lookahead_coverage_offsets_byte_len = 3377 lookahead_glyph_count as usize * Offset16::RAW_BYTE_LEN; 3378 cursor.advance_by(lookahead_coverage_offsets_byte_len); 3379 let seq_lookup_count: u16 = cursor.read()?; 3380 let seq_lookup_records_byte_len = 3381 seq_lookup_count as usize * SequenceLookupRecord::RAW_BYTE_LEN; 3382 cursor.advance_by(seq_lookup_records_byte_len); 3383 cursor.finish(ChainedSequenceContextFormat3Marker { 3384 backtrack_coverage_offsets_byte_len, 3385 input_coverage_offsets_byte_len, 3386 lookahead_coverage_offsets_byte_len, 3387 seq_lookup_records_byte_len, 3388 }) 3389 } 3390 } 3391 3392 /// [Chained Sequence Context Format 3](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#chained-sequence-context-format-3-coverage-based-glyph-contexts) 3393 pub type ChainedSequenceContextFormat3<'a> = TableRef<'a, ChainedSequenceContextFormat3Marker>; 3394 3395 impl<'a> ChainedSequenceContextFormat3<'a> { 3396 /// Format identifier: format = 3 format(&self) -> u163397 pub fn format(&self) -> u16 { 3398 let range = self.shape.format_byte_range(); 3399 self.data.read_at(range.start).unwrap() 3400 } 3401 3402 /// Number of glyphs in the backtrack sequence backtrack_glyph_count(&self) -> u163403 pub fn backtrack_glyph_count(&self) -> u16 { 3404 let range = self.shape.backtrack_glyph_count_byte_range(); 3405 self.data.read_at(range.start).unwrap() 3406 } 3407 3408 /// Array of offsets to coverage tables for the backtrack sequence backtrack_coverage_offsets(&self) -> &'a [BigEndian<Offset16>]3409 pub fn backtrack_coverage_offsets(&self) -> &'a [BigEndian<Offset16>] { 3410 let range = self.shape.backtrack_coverage_offsets_byte_range(); 3411 self.data.read_array(range).unwrap() 3412 } 3413 3414 /// A dynamically resolving wrapper for [`backtrack_coverage_offsets`][Self::backtrack_coverage_offsets]. backtrack_coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset16>3415 pub fn backtrack_coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset16> { 3416 let data = self.data; 3417 let offsets = self.backtrack_coverage_offsets(); 3418 ArrayOfOffsets::new(offsets, data, ()) 3419 } 3420 3421 /// Number of glyphs in the input sequence input_glyph_count(&self) -> u163422 pub fn input_glyph_count(&self) -> u16 { 3423 let range = self.shape.input_glyph_count_byte_range(); 3424 self.data.read_at(range.start).unwrap() 3425 } 3426 3427 /// Array of offsets to coverage tables for the input sequence input_coverage_offsets(&self) -> &'a [BigEndian<Offset16>]3428 pub fn input_coverage_offsets(&self) -> &'a [BigEndian<Offset16>] { 3429 let range = self.shape.input_coverage_offsets_byte_range(); 3430 self.data.read_array(range).unwrap() 3431 } 3432 3433 /// A dynamically resolving wrapper for [`input_coverage_offsets`][Self::input_coverage_offsets]. input_coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset16>3434 pub fn input_coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset16> { 3435 let data = self.data; 3436 let offsets = self.input_coverage_offsets(); 3437 ArrayOfOffsets::new(offsets, data, ()) 3438 } 3439 3440 /// Number of glyphs in the lookahead sequence lookahead_glyph_count(&self) -> u163441 pub fn lookahead_glyph_count(&self) -> u16 { 3442 let range = self.shape.lookahead_glyph_count_byte_range(); 3443 self.data.read_at(range.start).unwrap() 3444 } 3445 3446 /// Array of offsets to coverage tables for the lookahead sequence lookahead_coverage_offsets(&self) -> &'a [BigEndian<Offset16>]3447 pub fn lookahead_coverage_offsets(&self) -> &'a [BigEndian<Offset16>] { 3448 let range = self.shape.lookahead_coverage_offsets_byte_range(); 3449 self.data.read_array(range).unwrap() 3450 } 3451 3452 /// A dynamically resolving wrapper for [`lookahead_coverage_offsets`][Self::lookahead_coverage_offsets]. lookahead_coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset16>3453 pub fn lookahead_coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset16> { 3454 let data = self.data; 3455 let offsets = self.lookahead_coverage_offsets(); 3456 ArrayOfOffsets::new(offsets, data, ()) 3457 } 3458 3459 /// Number of SequenceLookupRecords seq_lookup_count(&self) -> u163460 pub fn seq_lookup_count(&self) -> u16 { 3461 let range = self.shape.seq_lookup_count_byte_range(); 3462 self.data.read_at(range.start).unwrap() 3463 } 3464 3465 /// Array of SequenceLookupRecords seq_lookup_records(&self) -> &'a [SequenceLookupRecord]3466 pub fn seq_lookup_records(&self) -> &'a [SequenceLookupRecord] { 3467 let range = self.shape.seq_lookup_records_byte_range(); 3468 self.data.read_array(range).unwrap() 3469 } 3470 } 3471 3472 #[cfg(feature = "traversal")] 3473 impl<'a> SomeTable<'a> for ChainedSequenceContextFormat3<'a> { type_name(&self) -> &str3474 fn type_name(&self) -> &str { 3475 "ChainedSequenceContextFormat3" 3476 } get_field(&self, idx: usize) -> Option<Field<'a>>3477 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3478 match idx { 3479 0usize => Some(Field::new("format", self.format())), 3480 1usize => Some(Field::new( 3481 "backtrack_glyph_count", 3482 self.backtrack_glyph_count(), 3483 )), 3484 2usize => Some({ 3485 let data = self.data; 3486 Field::new( 3487 "backtrack_coverage_offsets", 3488 FieldType::array_of_offsets( 3489 better_type_name::<CoverageTable>(), 3490 self.backtrack_coverage_offsets(), 3491 move |off| { 3492 let target = off.get().resolve::<CoverageTable>(data); 3493 FieldType::offset(off.get(), target) 3494 }, 3495 ), 3496 ) 3497 }), 3498 3usize => Some(Field::new("input_glyph_count", self.input_glyph_count())), 3499 4usize => Some({ 3500 let data = self.data; 3501 Field::new( 3502 "input_coverage_offsets", 3503 FieldType::array_of_offsets( 3504 better_type_name::<CoverageTable>(), 3505 self.input_coverage_offsets(), 3506 move |off| { 3507 let target = off.get().resolve::<CoverageTable>(data); 3508 FieldType::offset(off.get(), target) 3509 }, 3510 ), 3511 ) 3512 }), 3513 5usize => Some(Field::new( 3514 "lookahead_glyph_count", 3515 self.lookahead_glyph_count(), 3516 )), 3517 6usize => Some({ 3518 let data = self.data; 3519 Field::new( 3520 "lookahead_coverage_offsets", 3521 FieldType::array_of_offsets( 3522 better_type_name::<CoverageTable>(), 3523 self.lookahead_coverage_offsets(), 3524 move |off| { 3525 let target = off.get().resolve::<CoverageTable>(data); 3526 FieldType::offset(off.get(), target) 3527 }, 3528 ), 3529 ) 3530 }), 3531 7usize => Some(Field::new("seq_lookup_count", self.seq_lookup_count())), 3532 8usize => Some(Field::new( 3533 "seq_lookup_records", 3534 traversal::FieldType::array_of_records( 3535 stringify!(SequenceLookupRecord), 3536 self.seq_lookup_records(), 3537 self.offset_data(), 3538 ), 3539 )), 3540 _ => None, 3541 } 3542 } 3543 } 3544 3545 #[cfg(feature = "traversal")] 3546 impl<'a> std::fmt::Debug for ChainedSequenceContextFormat3<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3547 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3548 (self as &dyn SomeTable<'a>).fmt(f) 3549 } 3550 } 3551 3552 #[derive(Clone)] 3553 pub enum ChainedSequenceContext<'a> { 3554 Format1(ChainedSequenceContextFormat1<'a>), 3555 Format2(ChainedSequenceContextFormat2<'a>), 3556 Format3(ChainedSequenceContextFormat3<'a>), 3557 } 3558 3559 impl<'a> ChainedSequenceContext<'a> { 3560 /// Format identifier: format = 1 format(&self) -> u163561 pub fn format(&self) -> u16 { 3562 match self { 3563 Self::Format1(item) => item.format(), 3564 Self::Format2(item) => item.format(), 3565 Self::Format3(item) => item.format(), 3566 } 3567 } 3568 } 3569 3570 impl<'a> FontRead<'a> for ChainedSequenceContext<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>3571 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 3572 let format: u16 = data.read_at(0usize)?; 3573 match format { 3574 ChainedSequenceContextFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)), 3575 ChainedSequenceContextFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)), 3576 ChainedSequenceContextFormat3Marker::FORMAT => Ok(Self::Format3(FontRead::read(data)?)), 3577 other => Err(ReadError::InvalidFormat(other.into())), 3578 } 3579 } 3580 } 3581 3582 #[cfg(feature = "traversal")] 3583 impl<'a> ChainedSequenceContext<'a> { dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>3584 fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> { 3585 match self { 3586 Self::Format1(table) => table, 3587 Self::Format2(table) => table, 3588 Self::Format3(table) => table, 3589 } 3590 } 3591 } 3592 3593 #[cfg(feature = "traversal")] 3594 impl<'a> std::fmt::Debug for ChainedSequenceContext<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3595 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3596 self.dyn_inner().fmt(f) 3597 } 3598 } 3599 3600 #[cfg(feature = "traversal")] 3601 impl<'a> SomeTable<'a> for ChainedSequenceContext<'a> { type_name(&self) -> &str3602 fn type_name(&self) -> &str { 3603 self.dyn_inner().type_name() 3604 } get_field(&self, idx: usize) -> Option<Field<'a>>3605 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3606 self.dyn_inner().get_field(idx) 3607 } 3608 } 3609 3610 /// [Device](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#device-and-variationindex-tables) 3611 /// delta formats 3612 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] 3613 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 3614 #[repr(u16)] 3615 #[allow(clippy::manual_non_exhaustive)] 3616 pub enum DeltaFormat { 3617 /// Signed 2-bit value, 8 values per uint16 3618 #[default] 3619 Local2BitDeltas = 0x0001, 3620 /// Signed 4-bit value, 4 values per uint16 3621 Local4BitDeltas = 0x0002, 3622 /// Signed 8-bit value, 2 values per uint16 3623 Local8BitDeltas = 0x0003, 3624 /// VariationIndex table, contains a delta-set index pair. 3625 VariationIndex = 0x8000, 3626 #[doc(hidden)] 3627 /// If font data is malformed we will map unknown values to this variant 3628 Unknown, 3629 } 3630 3631 impl DeltaFormat { 3632 /// Create from a raw scalar. 3633 /// 3634 /// This will never fail; unknown values will be mapped to the `Unknown` variant new(raw: u16) -> Self3635 pub fn new(raw: u16) -> Self { 3636 match raw { 3637 0x0001 => Self::Local2BitDeltas, 3638 0x0002 => Self::Local4BitDeltas, 3639 0x0003 => Self::Local8BitDeltas, 3640 0x8000 => Self::VariationIndex, 3641 _ => Self::Unknown, 3642 } 3643 } 3644 } 3645 3646 impl font_types::Scalar for DeltaFormat { 3647 type Raw = <u16 as font_types::Scalar>::Raw; to_raw(self) -> Self::Raw3648 fn to_raw(self) -> Self::Raw { 3649 (self as u16).to_raw() 3650 } from_raw(raw: Self::Raw) -> Self3651 fn from_raw(raw: Self::Raw) -> Self { 3652 let t = <u16>::from_raw(raw); 3653 Self::new(t) 3654 } 3655 } 3656 3657 #[cfg(feature = "traversal")] 3658 impl<'a> From<DeltaFormat> for FieldType<'a> { from(src: DeltaFormat) -> FieldType<'a>3659 fn from(src: DeltaFormat) -> FieldType<'a> { 3660 (src as u16).into() 3661 } 3662 } 3663 3664 /// [Device Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#device-and-variationindex-tables) 3665 #[derive(Debug, Clone, Copy)] 3666 #[doc(hidden)] 3667 pub struct DeviceMarker { 3668 delta_value_byte_len: usize, 3669 } 3670 3671 impl DeviceMarker { start_size_byte_range(&self) -> Range<usize>3672 fn start_size_byte_range(&self) -> Range<usize> { 3673 let start = 0; 3674 start..start + u16::RAW_BYTE_LEN 3675 } end_size_byte_range(&self) -> Range<usize>3676 fn end_size_byte_range(&self) -> Range<usize> { 3677 let start = self.start_size_byte_range().end; 3678 start..start + u16::RAW_BYTE_LEN 3679 } delta_format_byte_range(&self) -> Range<usize>3680 fn delta_format_byte_range(&self) -> Range<usize> { 3681 let start = self.end_size_byte_range().end; 3682 start..start + DeltaFormat::RAW_BYTE_LEN 3683 } delta_value_byte_range(&self) -> Range<usize>3684 fn delta_value_byte_range(&self) -> Range<usize> { 3685 let start = self.delta_format_byte_range().end; 3686 start..start + self.delta_value_byte_len 3687 } 3688 } 3689 3690 impl<'a> FontRead<'a> for Device<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>3691 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 3692 let mut cursor = data.cursor(); 3693 let start_size: u16 = cursor.read()?; 3694 let end_size: u16 = cursor.read()?; 3695 let delta_format: DeltaFormat = cursor.read()?; 3696 let delta_value_byte_len = 3697 DeltaFormat::value_count(delta_format, start_size, end_size) * u16::RAW_BYTE_LEN; 3698 cursor.advance_by(delta_value_byte_len); 3699 cursor.finish(DeviceMarker { 3700 delta_value_byte_len, 3701 }) 3702 } 3703 } 3704 3705 /// [Device Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#device-and-variationindex-tables) 3706 pub type Device<'a> = TableRef<'a, DeviceMarker>; 3707 3708 impl<'a> Device<'a> { 3709 /// Smallest size to correct, in ppem start_size(&self) -> u163710 pub fn start_size(&self) -> u16 { 3711 let range = self.shape.start_size_byte_range(); 3712 self.data.read_at(range.start).unwrap() 3713 } 3714 3715 /// Largest size to correct, in ppem end_size(&self) -> u163716 pub fn end_size(&self) -> u16 { 3717 let range = self.shape.end_size_byte_range(); 3718 self.data.read_at(range.start).unwrap() 3719 } 3720 3721 /// Format of deltaValue array data: 0x0001, 0x0002, or 0x0003 delta_format(&self) -> DeltaFormat3722 pub fn delta_format(&self) -> DeltaFormat { 3723 let range = self.shape.delta_format_byte_range(); 3724 self.data.read_at(range.start).unwrap() 3725 } 3726 3727 /// Array of compressed data delta_value(&self) -> &'a [BigEndian<u16>]3728 pub fn delta_value(&self) -> &'a [BigEndian<u16>] { 3729 let range = self.shape.delta_value_byte_range(); 3730 self.data.read_array(range).unwrap() 3731 } 3732 } 3733 3734 #[cfg(feature = "traversal")] 3735 impl<'a> SomeTable<'a> for Device<'a> { type_name(&self) -> &str3736 fn type_name(&self) -> &str { 3737 "Device" 3738 } get_field(&self, idx: usize) -> Option<Field<'a>>3739 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3740 match idx { 3741 0usize => Some(Field::new("start_size", self.start_size())), 3742 1usize => Some(Field::new("end_size", self.end_size())), 3743 2usize => Some(Field::new("delta_format", self.delta_format())), 3744 3usize => Some(Field::new("delta_value", self.delta_value())), 3745 _ => None, 3746 } 3747 } 3748 } 3749 3750 #[cfg(feature = "traversal")] 3751 impl<'a> std::fmt::Debug for Device<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3752 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3753 (self as &dyn SomeTable<'a>).fmt(f) 3754 } 3755 } 3756 3757 /// Variation index table 3758 #[derive(Debug, Clone, Copy)] 3759 #[doc(hidden)] 3760 pub struct VariationIndexMarker {} 3761 3762 impl VariationIndexMarker { delta_set_outer_index_byte_range(&self) -> Range<usize>3763 fn delta_set_outer_index_byte_range(&self) -> Range<usize> { 3764 let start = 0; 3765 start..start + u16::RAW_BYTE_LEN 3766 } delta_set_inner_index_byte_range(&self) -> Range<usize>3767 fn delta_set_inner_index_byte_range(&self) -> Range<usize> { 3768 let start = self.delta_set_outer_index_byte_range().end; 3769 start..start + u16::RAW_BYTE_LEN 3770 } delta_format_byte_range(&self) -> Range<usize>3771 fn delta_format_byte_range(&self) -> Range<usize> { 3772 let start = self.delta_set_inner_index_byte_range().end; 3773 start..start + DeltaFormat::RAW_BYTE_LEN 3774 } 3775 } 3776 3777 impl<'a> FontRead<'a> for VariationIndex<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>3778 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 3779 let mut cursor = data.cursor(); 3780 cursor.advance::<u16>(); 3781 cursor.advance::<u16>(); 3782 cursor.advance::<DeltaFormat>(); 3783 cursor.finish(VariationIndexMarker {}) 3784 } 3785 } 3786 3787 /// Variation index table 3788 pub type VariationIndex<'a> = TableRef<'a, VariationIndexMarker>; 3789 3790 impl<'a> VariationIndex<'a> { 3791 /// A delta-set outer index — used to select an item variation 3792 /// data subtable within the item variation store. delta_set_outer_index(&self) -> u163793 pub fn delta_set_outer_index(&self) -> u16 { 3794 let range = self.shape.delta_set_outer_index_byte_range(); 3795 self.data.read_at(range.start).unwrap() 3796 } 3797 3798 /// A delta-set inner index — used to select a delta-set row 3799 /// within an item variation data subtable. delta_set_inner_index(&self) -> u163800 pub fn delta_set_inner_index(&self) -> u16 { 3801 let range = self.shape.delta_set_inner_index_byte_range(); 3802 self.data.read_at(range.start).unwrap() 3803 } 3804 3805 /// Format, = 0x8000 delta_format(&self) -> DeltaFormat3806 pub fn delta_format(&self) -> DeltaFormat { 3807 let range = self.shape.delta_format_byte_range(); 3808 self.data.read_at(range.start).unwrap() 3809 } 3810 } 3811 3812 #[cfg(feature = "traversal")] 3813 impl<'a> SomeTable<'a> for VariationIndex<'a> { type_name(&self) -> &str3814 fn type_name(&self) -> &str { 3815 "VariationIndex" 3816 } get_field(&self, idx: usize) -> Option<Field<'a>>3817 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3818 match idx { 3819 0usize => Some(Field::new( 3820 "delta_set_outer_index", 3821 self.delta_set_outer_index(), 3822 )), 3823 1usize => Some(Field::new( 3824 "delta_set_inner_index", 3825 self.delta_set_inner_index(), 3826 )), 3827 2usize => Some(Field::new("delta_format", self.delta_format())), 3828 _ => None, 3829 } 3830 } 3831 } 3832 3833 #[cfg(feature = "traversal")] 3834 impl<'a> std::fmt::Debug for VariationIndex<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3835 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3836 (self as &dyn SomeTable<'a>).fmt(f) 3837 } 3838 } 3839 3840 /// Either a [Device] table (in a non-variable font) or a [VariationIndex] table (in a variable font) 3841 #[derive(Clone)] 3842 pub enum DeviceOrVariationIndex<'a> { 3843 Device(Device<'a>), 3844 VariationIndex(VariationIndex<'a>), 3845 } 3846 3847 impl<'a> FontRead<'a> for DeviceOrVariationIndex<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>3848 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 3849 let format: DeltaFormat = data.read_at(4usize)?; 3850 3851 #[allow(clippy::redundant_guards)] 3852 match format { 3853 format if format != DeltaFormat::VariationIndex => { 3854 Ok(Self::Device(FontRead::read(data)?)) 3855 } 3856 format if format == DeltaFormat::VariationIndex => { 3857 Ok(Self::VariationIndex(FontRead::read(data)?)) 3858 } 3859 other => Err(ReadError::InvalidFormat(other.into())), 3860 } 3861 } 3862 } 3863 3864 #[cfg(feature = "traversal")] 3865 impl<'a> DeviceOrVariationIndex<'a> { dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>3866 fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> { 3867 match self { 3868 Self::Device(table) => table, 3869 Self::VariationIndex(table) => table, 3870 } 3871 } 3872 } 3873 3874 #[cfg(feature = "traversal")] 3875 impl<'a> std::fmt::Debug for DeviceOrVariationIndex<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3876 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3877 self.dyn_inner().fmt(f) 3878 } 3879 } 3880 3881 #[cfg(feature = "traversal")] 3882 impl<'a> SomeTable<'a> for DeviceOrVariationIndex<'a> { type_name(&self) -> &str3883 fn type_name(&self) -> &str { 3884 self.dyn_inner().type_name() 3885 } get_field(&self, idx: usize) -> Option<Field<'a>>3886 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3887 self.dyn_inner().get_field(idx) 3888 } 3889 } 3890 3891 /// [FeatureVariations Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#featurevariations-table) 3892 #[derive(Debug, Clone, Copy)] 3893 #[doc(hidden)] 3894 pub struct FeatureVariationsMarker { 3895 feature_variation_records_byte_len: usize, 3896 } 3897 3898 impl FeatureVariationsMarker { version_byte_range(&self) -> Range<usize>3899 fn version_byte_range(&self) -> Range<usize> { 3900 let start = 0; 3901 start..start + MajorMinor::RAW_BYTE_LEN 3902 } feature_variation_record_count_byte_range(&self) -> Range<usize>3903 fn feature_variation_record_count_byte_range(&self) -> Range<usize> { 3904 let start = self.version_byte_range().end; 3905 start..start + u32::RAW_BYTE_LEN 3906 } feature_variation_records_byte_range(&self) -> Range<usize>3907 fn feature_variation_records_byte_range(&self) -> Range<usize> { 3908 let start = self.feature_variation_record_count_byte_range().end; 3909 start..start + self.feature_variation_records_byte_len 3910 } 3911 } 3912 3913 impl<'a> FontRead<'a> for FeatureVariations<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>3914 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 3915 let mut cursor = data.cursor(); 3916 cursor.advance::<MajorMinor>(); 3917 let feature_variation_record_count: u32 = cursor.read()?; 3918 let feature_variation_records_byte_len = 3919 feature_variation_record_count as usize * FeatureVariationRecord::RAW_BYTE_LEN; 3920 cursor.advance_by(feature_variation_records_byte_len); 3921 cursor.finish(FeatureVariationsMarker { 3922 feature_variation_records_byte_len, 3923 }) 3924 } 3925 } 3926 3927 /// [FeatureVariations Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#featurevariations-table) 3928 pub type FeatureVariations<'a> = TableRef<'a, FeatureVariationsMarker>; 3929 3930 impl<'a> FeatureVariations<'a> { version(&self) -> MajorMinor3931 pub fn version(&self) -> MajorMinor { 3932 let range = self.shape.version_byte_range(); 3933 self.data.read_at(range.start).unwrap() 3934 } 3935 3936 /// Number of feature variation records. feature_variation_record_count(&self) -> u323937 pub fn feature_variation_record_count(&self) -> u32 { 3938 let range = self.shape.feature_variation_record_count_byte_range(); 3939 self.data.read_at(range.start).unwrap() 3940 } 3941 3942 /// Array of feature variation records. feature_variation_records(&self) -> &'a [FeatureVariationRecord]3943 pub fn feature_variation_records(&self) -> &'a [FeatureVariationRecord] { 3944 let range = self.shape.feature_variation_records_byte_range(); 3945 self.data.read_array(range).unwrap() 3946 } 3947 } 3948 3949 #[cfg(feature = "traversal")] 3950 impl<'a> SomeTable<'a> for FeatureVariations<'a> { type_name(&self) -> &str3951 fn type_name(&self) -> &str { 3952 "FeatureVariations" 3953 } get_field(&self, idx: usize) -> Option<Field<'a>>3954 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3955 match idx { 3956 0usize => Some(Field::new("version", self.version())), 3957 1usize => Some(Field::new( 3958 "feature_variation_record_count", 3959 self.feature_variation_record_count(), 3960 )), 3961 2usize => Some(Field::new( 3962 "feature_variation_records", 3963 traversal::FieldType::array_of_records( 3964 stringify!(FeatureVariationRecord), 3965 self.feature_variation_records(), 3966 self.offset_data(), 3967 ), 3968 )), 3969 _ => None, 3970 } 3971 } 3972 } 3973 3974 #[cfg(feature = "traversal")] 3975 impl<'a> std::fmt::Debug for FeatureVariations<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3976 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3977 (self as &dyn SomeTable<'a>).fmt(f) 3978 } 3979 } 3980 3981 /// Part of [FeatureVariations] 3982 #[derive(Clone, Debug)] 3983 #[repr(C)] 3984 #[repr(packed)] 3985 pub struct FeatureVariationRecord { 3986 /// Offset to a condition set table, from beginning of 3987 /// FeatureVariations table. 3988 pub condition_set_offset: BigEndian<Nullable<Offset32>>, 3989 /// Offset to a feature table substitution table, from beginning of 3990 /// the FeatureVariations table. 3991 pub feature_table_substitution_offset: BigEndian<Nullable<Offset32>>, 3992 } 3993 3994 impl FeatureVariationRecord { 3995 /// Offset to a condition set table, from beginning of 3996 /// FeatureVariations table. condition_set_offset(&self) -> Nullable<Offset32>3997 pub fn condition_set_offset(&self) -> Nullable<Offset32> { 3998 self.condition_set_offset.get() 3999 } 4000 4001 /// Offset to a condition set table, from beginning of 4002 /// FeatureVariations table. 4003 /// 4004 /// The `data` argument should be retrieved from the parent table 4005 /// By calling its `offset_data` method. condition_set<'a>( &self, data: FontData<'a>, ) -> Option<Result<ConditionSet<'a>, ReadError>>4006 pub fn condition_set<'a>( 4007 &self, 4008 data: FontData<'a>, 4009 ) -> Option<Result<ConditionSet<'a>, ReadError>> { 4010 self.condition_set_offset().resolve(data) 4011 } 4012 4013 /// Offset to a feature table substitution table, from beginning of 4014 /// the FeatureVariations table. feature_table_substitution_offset(&self) -> Nullable<Offset32>4015 pub fn feature_table_substitution_offset(&self) -> Nullable<Offset32> { 4016 self.feature_table_substitution_offset.get() 4017 } 4018 4019 /// Offset to a feature table substitution table, from beginning of 4020 /// the FeatureVariations table. 4021 /// 4022 /// The `data` argument should be retrieved from the parent table 4023 /// By calling its `offset_data` method. feature_table_substitution<'a>( &self, data: FontData<'a>, ) -> Option<Result<FeatureTableSubstitution<'a>, ReadError>>4024 pub fn feature_table_substitution<'a>( 4025 &self, 4026 data: FontData<'a>, 4027 ) -> Option<Result<FeatureTableSubstitution<'a>, ReadError>> { 4028 self.feature_table_substitution_offset().resolve(data) 4029 } 4030 } 4031 4032 impl FixedSize for FeatureVariationRecord { 4033 const RAW_BYTE_LEN: usize = Offset32::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN; 4034 } 4035 4036 impl sealed::Sealed for FeatureVariationRecord {} 4037 4038 /// SAFETY: see the [`FromBytes`] trait documentation. 4039 unsafe impl FromBytes for FeatureVariationRecord { this_trait_should_only_be_implemented_in_generated_code()4040 fn this_trait_should_only_be_implemented_in_generated_code() {} 4041 } 4042 4043 #[cfg(feature = "traversal")] 4044 impl<'a> SomeRecord<'a> for FeatureVariationRecord { traverse(self, data: FontData<'a>) -> RecordResolver<'a>4045 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 4046 RecordResolver { 4047 name: "FeatureVariationRecord", 4048 get_field: Box::new(move |idx, _data| match idx { 4049 0usize => Some(Field::new( 4050 "condition_set_offset", 4051 FieldType::offset(self.condition_set_offset(), self.condition_set(_data)), 4052 )), 4053 1usize => Some(Field::new( 4054 "feature_table_substitution_offset", 4055 FieldType::offset( 4056 self.feature_table_substitution_offset(), 4057 self.feature_table_substitution(_data), 4058 ), 4059 )), 4060 _ => None, 4061 }), 4062 data, 4063 } 4064 } 4065 } 4066 4067 /// [ConditionSet Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#conditionset-table) 4068 #[derive(Debug, Clone, Copy)] 4069 #[doc(hidden)] 4070 pub struct ConditionSetMarker { 4071 condition_offsets_byte_len: usize, 4072 } 4073 4074 impl ConditionSetMarker { condition_count_byte_range(&self) -> Range<usize>4075 fn condition_count_byte_range(&self) -> Range<usize> { 4076 let start = 0; 4077 start..start + u16::RAW_BYTE_LEN 4078 } condition_offsets_byte_range(&self) -> Range<usize>4079 fn condition_offsets_byte_range(&self) -> Range<usize> { 4080 let start = self.condition_count_byte_range().end; 4081 start..start + self.condition_offsets_byte_len 4082 } 4083 } 4084 4085 impl<'a> FontRead<'a> for ConditionSet<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>4086 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 4087 let mut cursor = data.cursor(); 4088 let condition_count: u16 = cursor.read()?; 4089 let condition_offsets_byte_len = condition_count as usize * Offset32::RAW_BYTE_LEN; 4090 cursor.advance_by(condition_offsets_byte_len); 4091 cursor.finish(ConditionSetMarker { 4092 condition_offsets_byte_len, 4093 }) 4094 } 4095 } 4096 4097 /// [ConditionSet Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#conditionset-table) 4098 pub type ConditionSet<'a> = TableRef<'a, ConditionSetMarker>; 4099 4100 impl<'a> ConditionSet<'a> { 4101 /// Number of conditions for this condition set. condition_count(&self) -> u164102 pub fn condition_count(&self) -> u16 { 4103 let range = self.shape.condition_count_byte_range(); 4104 self.data.read_at(range.start).unwrap() 4105 } 4106 4107 /// Array of offsets to condition tables, from beginning of the 4108 /// ConditionSet table. condition_offsets(&self) -> &'a [BigEndian<Offset32>]4109 pub fn condition_offsets(&self) -> &'a [BigEndian<Offset32>] { 4110 let range = self.shape.condition_offsets_byte_range(); 4111 self.data.read_array(range).unwrap() 4112 } 4113 4114 /// A dynamically resolving wrapper for [`condition_offsets`][Self::condition_offsets]. conditions(&self) -> ArrayOfOffsets<'a, ConditionFormat1<'a>, Offset32>4115 pub fn conditions(&self) -> ArrayOfOffsets<'a, ConditionFormat1<'a>, Offset32> { 4116 let data = self.data; 4117 let offsets = self.condition_offsets(); 4118 ArrayOfOffsets::new(offsets, data, ()) 4119 } 4120 } 4121 4122 #[cfg(feature = "traversal")] 4123 impl<'a> SomeTable<'a> for ConditionSet<'a> { type_name(&self) -> &str4124 fn type_name(&self) -> &str { 4125 "ConditionSet" 4126 } get_field(&self, idx: usize) -> Option<Field<'a>>4127 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 4128 match idx { 4129 0usize => Some(Field::new("condition_count", self.condition_count())), 4130 1usize => Some({ 4131 let data = self.data; 4132 Field::new( 4133 "condition_offsets", 4134 FieldType::array_of_offsets( 4135 better_type_name::<ConditionFormat1>(), 4136 self.condition_offsets(), 4137 move |off| { 4138 let target = off.get().resolve::<ConditionFormat1>(data); 4139 FieldType::offset(off.get(), target) 4140 }, 4141 ), 4142 ) 4143 }), 4144 _ => None, 4145 } 4146 } 4147 } 4148 4149 #[cfg(feature = "traversal")] 4150 impl<'a> std::fmt::Debug for ConditionSet<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result4151 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 4152 (self as &dyn SomeTable<'a>).fmt(f) 4153 } 4154 } 4155 4156 impl Format<u16> for ConditionFormat1Marker { 4157 const FORMAT: u16 = 1; 4158 } 4159 4160 /// [Condition Table Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#condition-table-format-1-font-variation-axis-range): Font Variation Axis Range 4161 #[derive(Debug, Clone, Copy)] 4162 #[doc(hidden)] 4163 pub struct ConditionFormat1Marker {} 4164 4165 impl ConditionFormat1Marker { format_byte_range(&self) -> Range<usize>4166 fn format_byte_range(&self) -> Range<usize> { 4167 let start = 0; 4168 start..start + u16::RAW_BYTE_LEN 4169 } axis_index_byte_range(&self) -> Range<usize>4170 fn axis_index_byte_range(&self) -> Range<usize> { 4171 let start = self.format_byte_range().end; 4172 start..start + u16::RAW_BYTE_LEN 4173 } filter_range_min_value_byte_range(&self) -> Range<usize>4174 fn filter_range_min_value_byte_range(&self) -> Range<usize> { 4175 let start = self.axis_index_byte_range().end; 4176 start..start + F2Dot14::RAW_BYTE_LEN 4177 } filter_range_max_value_byte_range(&self) -> Range<usize>4178 fn filter_range_max_value_byte_range(&self) -> Range<usize> { 4179 let start = self.filter_range_min_value_byte_range().end; 4180 start..start + F2Dot14::RAW_BYTE_LEN 4181 } 4182 } 4183 4184 impl<'a> FontRead<'a> for ConditionFormat1<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>4185 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 4186 let mut cursor = data.cursor(); 4187 cursor.advance::<u16>(); 4188 cursor.advance::<u16>(); 4189 cursor.advance::<F2Dot14>(); 4190 cursor.advance::<F2Dot14>(); 4191 cursor.finish(ConditionFormat1Marker {}) 4192 } 4193 } 4194 4195 /// [Condition Table Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#condition-table-format-1-font-variation-axis-range): Font Variation Axis Range 4196 pub type ConditionFormat1<'a> = TableRef<'a, ConditionFormat1Marker>; 4197 4198 impl<'a> ConditionFormat1<'a> { 4199 /// Format, = 1 format(&self) -> u164200 pub fn format(&self) -> u16 { 4201 let range = self.shape.format_byte_range(); 4202 self.data.read_at(range.start).unwrap() 4203 } 4204 4205 /// Index (zero-based) for the variation axis within the 'fvar' 4206 /// table. axis_index(&self) -> u164207 pub fn axis_index(&self) -> u16 { 4208 let range = self.shape.axis_index_byte_range(); 4209 self.data.read_at(range.start).unwrap() 4210 } 4211 4212 /// Minimum value of the font variation instances that satisfy this 4213 /// condition. filter_range_min_value(&self) -> F2Dot144214 pub fn filter_range_min_value(&self) -> F2Dot14 { 4215 let range = self.shape.filter_range_min_value_byte_range(); 4216 self.data.read_at(range.start).unwrap() 4217 } 4218 4219 /// Maximum value of the font variation instances that satisfy this 4220 /// condition. filter_range_max_value(&self) -> F2Dot144221 pub fn filter_range_max_value(&self) -> F2Dot14 { 4222 let range = self.shape.filter_range_max_value_byte_range(); 4223 self.data.read_at(range.start).unwrap() 4224 } 4225 } 4226 4227 #[cfg(feature = "traversal")] 4228 impl<'a> SomeTable<'a> for ConditionFormat1<'a> { type_name(&self) -> &str4229 fn type_name(&self) -> &str { 4230 "ConditionFormat1" 4231 } get_field(&self, idx: usize) -> Option<Field<'a>>4232 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 4233 match idx { 4234 0usize => Some(Field::new("format", self.format())), 4235 1usize => Some(Field::new("axis_index", self.axis_index())), 4236 2usize => Some(Field::new( 4237 "filter_range_min_value", 4238 self.filter_range_min_value(), 4239 )), 4240 3usize => Some(Field::new( 4241 "filter_range_max_value", 4242 self.filter_range_max_value(), 4243 )), 4244 _ => None, 4245 } 4246 } 4247 } 4248 4249 #[cfg(feature = "traversal")] 4250 impl<'a> std::fmt::Debug for ConditionFormat1<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result4251 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 4252 (self as &dyn SomeTable<'a>).fmt(f) 4253 } 4254 } 4255 4256 /// [FeatureTableSubstitution Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#featuretablesubstitution-table) 4257 #[derive(Debug, Clone, Copy)] 4258 #[doc(hidden)] 4259 pub struct FeatureTableSubstitutionMarker { 4260 substitutions_byte_len: usize, 4261 } 4262 4263 impl FeatureTableSubstitutionMarker { version_byte_range(&self) -> Range<usize>4264 fn version_byte_range(&self) -> Range<usize> { 4265 let start = 0; 4266 start..start + MajorMinor::RAW_BYTE_LEN 4267 } substitution_count_byte_range(&self) -> Range<usize>4268 fn substitution_count_byte_range(&self) -> Range<usize> { 4269 let start = self.version_byte_range().end; 4270 start..start + u16::RAW_BYTE_LEN 4271 } substitutions_byte_range(&self) -> Range<usize>4272 fn substitutions_byte_range(&self) -> Range<usize> { 4273 let start = self.substitution_count_byte_range().end; 4274 start..start + self.substitutions_byte_len 4275 } 4276 } 4277 4278 impl<'a> FontRead<'a> for FeatureTableSubstitution<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>4279 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 4280 let mut cursor = data.cursor(); 4281 cursor.advance::<MajorMinor>(); 4282 let substitution_count: u16 = cursor.read()?; 4283 let substitutions_byte_len = 4284 substitution_count as usize * FeatureTableSubstitutionRecord::RAW_BYTE_LEN; 4285 cursor.advance_by(substitutions_byte_len); 4286 cursor.finish(FeatureTableSubstitutionMarker { 4287 substitutions_byte_len, 4288 }) 4289 } 4290 } 4291 4292 /// [FeatureTableSubstitution Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#featuretablesubstitution-table) 4293 pub type FeatureTableSubstitution<'a> = TableRef<'a, FeatureTableSubstitutionMarker>; 4294 4295 impl<'a> FeatureTableSubstitution<'a> { 4296 /// Major & minor version of the table: (1, 0) version(&self) -> MajorMinor4297 pub fn version(&self) -> MajorMinor { 4298 let range = self.shape.version_byte_range(); 4299 self.data.read_at(range.start).unwrap() 4300 } 4301 4302 /// Number of feature table substitution records. substitution_count(&self) -> u164303 pub fn substitution_count(&self) -> u16 { 4304 let range = self.shape.substitution_count_byte_range(); 4305 self.data.read_at(range.start).unwrap() 4306 } 4307 4308 /// Array of feature table substitution records. substitutions(&self) -> &'a [FeatureTableSubstitutionRecord]4309 pub fn substitutions(&self) -> &'a [FeatureTableSubstitutionRecord] { 4310 let range = self.shape.substitutions_byte_range(); 4311 self.data.read_array(range).unwrap() 4312 } 4313 } 4314 4315 #[cfg(feature = "traversal")] 4316 impl<'a> SomeTable<'a> for FeatureTableSubstitution<'a> { type_name(&self) -> &str4317 fn type_name(&self) -> &str { 4318 "FeatureTableSubstitution" 4319 } get_field(&self, idx: usize) -> Option<Field<'a>>4320 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 4321 match idx { 4322 0usize => Some(Field::new("version", self.version())), 4323 1usize => Some(Field::new("substitution_count", self.substitution_count())), 4324 2usize => Some(Field::new( 4325 "substitutions", 4326 traversal::FieldType::array_of_records( 4327 stringify!(FeatureTableSubstitutionRecord), 4328 self.substitutions(), 4329 self.offset_data(), 4330 ), 4331 )), 4332 _ => None, 4333 } 4334 } 4335 } 4336 4337 #[cfg(feature = "traversal")] 4338 impl<'a> std::fmt::Debug for FeatureTableSubstitution<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result4339 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 4340 (self as &dyn SomeTable<'a>).fmt(f) 4341 } 4342 } 4343 4344 /// Used in [FeatureTableSubstitution] 4345 #[derive(Clone, Debug)] 4346 #[repr(C)] 4347 #[repr(packed)] 4348 pub struct FeatureTableSubstitutionRecord { 4349 /// The feature table index to match. 4350 pub feature_index: BigEndian<u16>, 4351 /// Offset to an alternate feature table, from start of the 4352 /// FeatureTableSubstitution table. 4353 pub alternate_feature_offset: BigEndian<Offset32>, 4354 } 4355 4356 impl FeatureTableSubstitutionRecord { 4357 /// The feature table index to match. feature_index(&self) -> u164358 pub fn feature_index(&self) -> u16 { 4359 self.feature_index.get() 4360 } 4361 4362 /// Offset to an alternate feature table, from start of the 4363 /// FeatureTableSubstitution table. alternate_feature_offset(&self) -> Offset324364 pub fn alternate_feature_offset(&self) -> Offset32 { 4365 self.alternate_feature_offset.get() 4366 } 4367 } 4368 4369 impl FixedSize for FeatureTableSubstitutionRecord { 4370 const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN; 4371 } 4372 4373 impl sealed::Sealed for FeatureTableSubstitutionRecord {} 4374 4375 /// SAFETY: see the [`FromBytes`] trait documentation. 4376 unsafe impl FromBytes for FeatureTableSubstitutionRecord { this_trait_should_only_be_implemented_in_generated_code()4377 fn this_trait_should_only_be_implemented_in_generated_code() {} 4378 } 4379 4380 #[cfg(feature = "traversal")] 4381 impl<'a> SomeRecord<'a> for FeatureTableSubstitutionRecord { traverse(self, data: FontData<'a>) -> RecordResolver<'a>4382 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 4383 RecordResolver { 4384 name: "FeatureTableSubstitutionRecord", 4385 get_field: Box::new(move |idx, _data| match idx { 4386 0usize => Some(Field::new("feature_index", self.feature_index())), 4387 1usize => Some(Field::new( 4388 "alternate_feature_offset", 4389 FieldType::offset( 4390 self.alternate_feature_offset(), 4391 self.alternate_feature(_data), 4392 ), 4393 )), 4394 _ => None, 4395 }), 4396 data, 4397 } 4398 } 4399 } 4400 4401 #[derive(Debug, Clone, Copy)] 4402 #[doc(hidden)] 4403 pub struct SizeParamsMarker {} 4404 4405 impl SizeParamsMarker { design_size_byte_range(&self) -> Range<usize>4406 fn design_size_byte_range(&self) -> Range<usize> { 4407 let start = 0; 4408 start..start + u16::RAW_BYTE_LEN 4409 } identifier_byte_range(&self) -> Range<usize>4410 fn identifier_byte_range(&self) -> Range<usize> { 4411 let start = self.design_size_byte_range().end; 4412 start..start + u16::RAW_BYTE_LEN 4413 } name_entry_byte_range(&self) -> Range<usize>4414 fn name_entry_byte_range(&self) -> Range<usize> { 4415 let start = self.identifier_byte_range().end; 4416 start..start + u16::RAW_BYTE_LEN 4417 } range_start_byte_range(&self) -> Range<usize>4418 fn range_start_byte_range(&self) -> Range<usize> { 4419 let start = self.name_entry_byte_range().end; 4420 start..start + u16::RAW_BYTE_LEN 4421 } range_end_byte_range(&self) -> Range<usize>4422 fn range_end_byte_range(&self) -> Range<usize> { 4423 let start = self.range_start_byte_range().end; 4424 start..start + u16::RAW_BYTE_LEN 4425 } 4426 } 4427 4428 impl<'a> FontRead<'a> for SizeParams<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>4429 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 4430 let mut cursor = data.cursor(); 4431 cursor.advance::<u16>(); 4432 cursor.advance::<u16>(); 4433 cursor.advance::<u16>(); 4434 cursor.advance::<u16>(); 4435 cursor.advance::<u16>(); 4436 cursor.finish(SizeParamsMarker {}) 4437 } 4438 } 4439 4440 pub type SizeParams<'a> = TableRef<'a, SizeParamsMarker>; 4441 4442 impl<'a> SizeParams<'a> { 4443 /// The first value represents the design size in 720/inch units (decipoints). 4444 /// 4445 /// The design size entry must be non-zero. When there is a design size but 4446 /// no recommended size range, the rest of the array will consist of zeros. design_size(&self) -> u164447 pub fn design_size(&self) -> u16 { 4448 let range = self.shape.design_size_byte_range(); 4449 self.data.read_at(range.start).unwrap() 4450 } 4451 4452 /// The second value has no independent meaning, but serves as an identifier that associates fonts in a subfamily. 4453 /// 4454 /// All fonts which share a Typographic or Font Family name and which differ 4455 /// only by size range shall have the same subfamily value, and no fonts 4456 /// which differ in weight or style shall have the same subfamily value. 4457 /// If this value is zero, the remaining fields in the array will be ignored. identifier(&self) -> u164458 pub fn identifier(&self) -> u16 { 4459 let range = self.shape.identifier_byte_range(); 4460 self.data.read_at(range.start).unwrap() 4461 } 4462 4463 /// The third value enables applications to use a single name for the subfamily identified by the second value. 4464 /// 4465 /// If the preceding value is non-zero, this value must be set in the range 4466 /// 256 – 32767 (inclusive). It records the value of a field in the 'name' 4467 /// table, which must contain English-language strings encoded in Windows 4468 /// Unicode and Macintosh Roman, and may contain additional strings localized 4469 /// to other scripts and languages. Each of these strings is the name 4470 /// an application should use, in combination with the family name, to 4471 /// represent the subfamily in a menu. Applications will choose the 4472 /// appropriate version based on their selection criteria. name_entry(&self) -> u164473 pub fn name_entry(&self) -> u16 { 4474 let range = self.shape.name_entry_byte_range(); 4475 self.data.read_at(range.start).unwrap() 4476 } 4477 4478 /// The fourth and fifth values represent the small end of the recommended 4479 /// usage range (exclusive) and the large end of the recommended usage range 4480 /// (inclusive), stored in 720/inch units (decipoints). 4481 /// 4482 /// Ranges must not overlap, and should generally be contiguous. range_start(&self) -> u164483 pub fn range_start(&self) -> u16 { 4484 let range = self.shape.range_start_byte_range(); 4485 self.data.read_at(range.start).unwrap() 4486 } 4487 range_end(&self) -> u164488 pub fn range_end(&self) -> u16 { 4489 let range = self.shape.range_end_byte_range(); 4490 self.data.read_at(range.start).unwrap() 4491 } 4492 } 4493 4494 #[cfg(feature = "traversal")] 4495 impl<'a> SomeTable<'a> for SizeParams<'a> { type_name(&self) -> &str4496 fn type_name(&self) -> &str { 4497 "SizeParams" 4498 } get_field(&self, idx: usize) -> Option<Field<'a>>4499 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 4500 match idx { 4501 0usize => Some(Field::new("design_size", self.design_size())), 4502 1usize => Some(Field::new("identifier", self.identifier())), 4503 2usize => Some(Field::new("name_entry", self.name_entry())), 4504 3usize => Some(Field::new("range_start", self.range_start())), 4505 4usize => Some(Field::new("range_end", self.range_end())), 4506 _ => None, 4507 } 4508 } 4509 } 4510 4511 #[cfg(feature = "traversal")] 4512 impl<'a> std::fmt::Debug for SizeParams<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result4513 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 4514 (self as &dyn SomeTable<'a>).fmt(f) 4515 } 4516 } 4517 4518 #[derive(Debug, Clone, Copy)] 4519 #[doc(hidden)] 4520 pub struct StylisticSetParamsMarker {} 4521 4522 impl StylisticSetParamsMarker { version_byte_range(&self) -> Range<usize>4523 fn version_byte_range(&self) -> Range<usize> { 4524 let start = 0; 4525 start..start + u16::RAW_BYTE_LEN 4526 } ui_name_id_byte_range(&self) -> Range<usize>4527 fn ui_name_id_byte_range(&self) -> Range<usize> { 4528 let start = self.version_byte_range().end; 4529 start..start + NameId::RAW_BYTE_LEN 4530 } 4531 } 4532 4533 impl<'a> FontRead<'a> for StylisticSetParams<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>4534 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 4535 let mut cursor = data.cursor(); 4536 cursor.advance::<u16>(); 4537 cursor.advance::<NameId>(); 4538 cursor.finish(StylisticSetParamsMarker {}) 4539 } 4540 } 4541 4542 pub type StylisticSetParams<'a> = TableRef<'a, StylisticSetParamsMarker>; 4543 4544 impl<'a> StylisticSetParams<'a> { version(&self) -> u164545 pub fn version(&self) -> u16 { 4546 let range = self.shape.version_byte_range(); 4547 self.data.read_at(range.start).unwrap() 4548 } 4549 4550 /// The 'name' table name ID that specifies a string (or strings, for 4551 /// multiple languages) for a user-interface label for this feature. 4552 /// 4553 /// The value of uiLabelNameId is expected to be in the font-specific name 4554 /// ID range (256-32767), though that is not a requirement in this Feature 4555 /// Parameters specification. The user-interface label for the feature can 4556 /// be provided in multiple languages. An English string should be included 4557 /// as a fallback. The string should be kept to a minimal length to fit 4558 /// comfortably with different application interfaces. ui_name_id(&self) -> NameId4559 pub fn ui_name_id(&self) -> NameId { 4560 let range = self.shape.ui_name_id_byte_range(); 4561 self.data.read_at(range.start).unwrap() 4562 } 4563 } 4564 4565 #[cfg(feature = "traversal")] 4566 impl<'a> SomeTable<'a> for StylisticSetParams<'a> { type_name(&self) -> &str4567 fn type_name(&self) -> &str { 4568 "StylisticSetParams" 4569 } get_field(&self, idx: usize) -> Option<Field<'a>>4570 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 4571 match idx { 4572 0usize => Some(Field::new("version", self.version())), 4573 1usize => Some(Field::new("ui_name_id", self.ui_name_id())), 4574 _ => None, 4575 } 4576 } 4577 } 4578 4579 #[cfg(feature = "traversal")] 4580 impl<'a> std::fmt::Debug for StylisticSetParams<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result4581 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 4582 (self as &dyn SomeTable<'a>).fmt(f) 4583 } 4584 } 4585 4586 impl Format<u16> for CharacterVariantParamsMarker { 4587 const FORMAT: u16 = 0; 4588 } 4589 4590 /// featureParams for ['cv01'-'cv99'](https://docs.microsoft.com/en-us/typography/opentype/spec/features_ae#cv01-cv99) 4591 #[derive(Debug, Clone, Copy)] 4592 #[doc(hidden)] 4593 pub struct CharacterVariantParamsMarker { 4594 character_byte_len: usize, 4595 } 4596 4597 impl CharacterVariantParamsMarker { format_byte_range(&self) -> Range<usize>4598 fn format_byte_range(&self) -> Range<usize> { 4599 let start = 0; 4600 start..start + u16::RAW_BYTE_LEN 4601 } feat_ui_label_name_id_byte_range(&self) -> Range<usize>4602 fn feat_ui_label_name_id_byte_range(&self) -> Range<usize> { 4603 let start = self.format_byte_range().end; 4604 start..start + NameId::RAW_BYTE_LEN 4605 } feat_ui_tooltip_text_name_id_byte_range(&self) -> Range<usize>4606 fn feat_ui_tooltip_text_name_id_byte_range(&self) -> Range<usize> { 4607 let start = self.feat_ui_label_name_id_byte_range().end; 4608 start..start + NameId::RAW_BYTE_LEN 4609 } sample_text_name_id_byte_range(&self) -> Range<usize>4610 fn sample_text_name_id_byte_range(&self) -> Range<usize> { 4611 let start = self.feat_ui_tooltip_text_name_id_byte_range().end; 4612 start..start + NameId::RAW_BYTE_LEN 4613 } num_named_parameters_byte_range(&self) -> Range<usize>4614 fn num_named_parameters_byte_range(&self) -> Range<usize> { 4615 let start = self.sample_text_name_id_byte_range().end; 4616 start..start + u16::RAW_BYTE_LEN 4617 } first_param_ui_label_name_id_byte_range(&self) -> Range<usize>4618 fn first_param_ui_label_name_id_byte_range(&self) -> Range<usize> { 4619 let start = self.num_named_parameters_byte_range().end; 4620 start..start + NameId::RAW_BYTE_LEN 4621 } char_count_byte_range(&self) -> Range<usize>4622 fn char_count_byte_range(&self) -> Range<usize> { 4623 let start = self.first_param_ui_label_name_id_byte_range().end; 4624 start..start + u16::RAW_BYTE_LEN 4625 } character_byte_range(&self) -> Range<usize>4626 fn character_byte_range(&self) -> Range<usize> { 4627 let start = self.char_count_byte_range().end; 4628 start..start + self.character_byte_len 4629 } 4630 } 4631 4632 impl<'a> FontRead<'a> for CharacterVariantParams<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>4633 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 4634 let mut cursor = data.cursor(); 4635 cursor.advance::<u16>(); 4636 cursor.advance::<NameId>(); 4637 cursor.advance::<NameId>(); 4638 cursor.advance::<NameId>(); 4639 cursor.advance::<u16>(); 4640 cursor.advance::<NameId>(); 4641 let char_count: u16 = cursor.read()?; 4642 let character_byte_len = char_count as usize * Uint24::RAW_BYTE_LEN; 4643 cursor.advance_by(character_byte_len); 4644 cursor.finish(CharacterVariantParamsMarker { character_byte_len }) 4645 } 4646 } 4647 4648 /// featureParams for ['cv01'-'cv99'](https://docs.microsoft.com/en-us/typography/opentype/spec/features_ae#cv01-cv99) 4649 pub type CharacterVariantParams<'a> = TableRef<'a, CharacterVariantParamsMarker>; 4650 4651 impl<'a> CharacterVariantParams<'a> { 4652 /// Format number is set to 0. format(&self) -> u164653 pub fn format(&self) -> u16 { 4654 let range = self.shape.format_byte_range(); 4655 self.data.read_at(range.start).unwrap() 4656 } 4657 4658 /// The 'name' table name ID that specifies a string (or strings, 4659 /// for multiple languages) for a user-interface label for this 4660 /// feature. (May be NULL.) feat_ui_label_name_id(&self) -> NameId4661 pub fn feat_ui_label_name_id(&self) -> NameId { 4662 let range = self.shape.feat_ui_label_name_id_byte_range(); 4663 self.data.read_at(range.start).unwrap() 4664 } 4665 4666 /// The 'name' table name ID that specifies a string (or strings, 4667 /// for multiple languages) that an application can use for tooltip 4668 /// text for this feature. (May be NULL.) feat_ui_tooltip_text_name_id(&self) -> NameId4669 pub fn feat_ui_tooltip_text_name_id(&self) -> NameId { 4670 let range = self.shape.feat_ui_tooltip_text_name_id_byte_range(); 4671 self.data.read_at(range.start).unwrap() 4672 } 4673 4674 /// The 'name' table name ID that specifies sample text that 4675 /// illustrates the effect of this feature. (May be NULL.) sample_text_name_id(&self) -> NameId4676 pub fn sample_text_name_id(&self) -> NameId { 4677 let range = self.shape.sample_text_name_id_byte_range(); 4678 self.data.read_at(range.start).unwrap() 4679 } 4680 4681 /// Number of named parameters. (May be zero.) num_named_parameters(&self) -> u164682 pub fn num_named_parameters(&self) -> u16 { 4683 let range = self.shape.num_named_parameters_byte_range(); 4684 self.data.read_at(range.start).unwrap() 4685 } 4686 4687 /// The first 'name' table name ID used to specify strings for 4688 /// user-interface labels for the feature parameters. (Must be zero 4689 /// if numParameters is zero.) first_param_ui_label_name_id(&self) -> NameId4690 pub fn first_param_ui_label_name_id(&self) -> NameId { 4691 let range = self.shape.first_param_ui_label_name_id_byte_range(); 4692 self.data.read_at(range.start).unwrap() 4693 } 4694 4695 /// The count of characters for which this feature provides glyph 4696 /// variants. (May be zero.) char_count(&self) -> u164697 pub fn char_count(&self) -> u16 { 4698 let range = self.shape.char_count_byte_range(); 4699 self.data.read_at(range.start).unwrap() 4700 } 4701 4702 /// The Unicode Scalar Value of the characters for which this 4703 /// feature provides glyph variants. character(&self) -> &'a [BigEndian<Uint24>]4704 pub fn character(&self) -> &'a [BigEndian<Uint24>] { 4705 let range = self.shape.character_byte_range(); 4706 self.data.read_array(range).unwrap() 4707 } 4708 } 4709 4710 #[cfg(feature = "traversal")] 4711 impl<'a> SomeTable<'a> for CharacterVariantParams<'a> { type_name(&self) -> &str4712 fn type_name(&self) -> &str { 4713 "CharacterVariantParams" 4714 } get_field(&self, idx: usize) -> Option<Field<'a>>4715 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 4716 match idx { 4717 0usize => Some(Field::new("format", self.format())), 4718 1usize => Some(Field::new( 4719 "feat_ui_label_name_id", 4720 self.feat_ui_label_name_id(), 4721 )), 4722 2usize => Some(Field::new( 4723 "feat_ui_tooltip_text_name_id", 4724 self.feat_ui_tooltip_text_name_id(), 4725 )), 4726 3usize => Some(Field::new( 4727 "sample_text_name_id", 4728 self.sample_text_name_id(), 4729 )), 4730 4usize => Some(Field::new( 4731 "num_named_parameters", 4732 self.num_named_parameters(), 4733 )), 4734 5usize => Some(Field::new( 4735 "first_param_ui_label_name_id", 4736 self.first_param_ui_label_name_id(), 4737 )), 4738 6usize => Some(Field::new("char_count", self.char_count())), 4739 7usize => Some(Field::new("character", self.character())), 4740 _ => None, 4741 } 4742 } 4743 } 4744 4745 #[cfg(feature = "traversal")] 4746 impl<'a> std::fmt::Debug for CharacterVariantParams<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result4747 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 4748 (self as &dyn SomeTable<'a>).fmt(f) 4749 } 4750 } 4751