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 /// [cmap](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#overview) 9 #[derive(Debug, Clone, Copy)] 10 #[doc(hidden)] 11 pub struct CmapMarker { 12 encoding_records_byte_len: usize, 13 } 14 15 impl CmapMarker { version_byte_range(&self) -> Range<usize>16 fn version_byte_range(&self) -> Range<usize> { 17 let start = 0; 18 start..start + u16::RAW_BYTE_LEN 19 } num_tables_byte_range(&self) -> Range<usize>20 fn num_tables_byte_range(&self) -> Range<usize> { 21 let start = self.version_byte_range().end; 22 start..start + u16::RAW_BYTE_LEN 23 } encoding_records_byte_range(&self) -> Range<usize>24 fn encoding_records_byte_range(&self) -> Range<usize> { 25 let start = self.num_tables_byte_range().end; 26 start..start + self.encoding_records_byte_len 27 } 28 } 29 30 impl TopLevelTable for Cmap<'_> { 31 /// `cmap` 32 const TAG: Tag = Tag::new(b"cmap"); 33 } 34 35 impl<'a> FontRead<'a> for Cmap<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>36 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 37 let mut cursor = data.cursor(); 38 cursor.advance::<u16>(); 39 let num_tables: u16 = cursor.read()?; 40 let encoding_records_byte_len = num_tables as usize * EncodingRecord::RAW_BYTE_LEN; 41 cursor.advance_by(encoding_records_byte_len); 42 cursor.finish(CmapMarker { 43 encoding_records_byte_len, 44 }) 45 } 46 } 47 48 /// [cmap](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#overview) 49 pub type Cmap<'a> = TableRef<'a, CmapMarker>; 50 51 impl<'a> Cmap<'a> { 52 /// Table version number (0). version(&self) -> u1653 pub fn version(&self) -> u16 { 54 let range = self.shape.version_byte_range(); 55 self.data.read_at(range.start).unwrap() 56 } 57 58 /// Number of encoding tables that follow. num_tables(&self) -> u1659 pub fn num_tables(&self) -> u16 { 60 let range = self.shape.num_tables_byte_range(); 61 self.data.read_at(range.start).unwrap() 62 } 63 encoding_records(&self) -> &'a [EncodingRecord]64 pub fn encoding_records(&self) -> &'a [EncodingRecord] { 65 let range = self.shape.encoding_records_byte_range(); 66 self.data.read_array(range).unwrap() 67 } 68 } 69 70 #[cfg(feature = "traversal")] 71 impl<'a> SomeTable<'a> for Cmap<'a> { type_name(&self) -> &str72 fn type_name(&self) -> &str { 73 "Cmap" 74 } get_field(&self, idx: usize) -> Option<Field<'a>>75 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 76 match idx { 77 0usize => Some(Field::new("version", self.version())), 78 1usize => Some(Field::new("num_tables", self.num_tables())), 79 2usize => Some(Field::new( 80 "encoding_records", 81 traversal::FieldType::array_of_records( 82 stringify!(EncodingRecord), 83 self.encoding_records(), 84 self.offset_data(), 85 ), 86 )), 87 _ => None, 88 } 89 } 90 } 91 92 #[cfg(feature = "traversal")] 93 impl<'a> std::fmt::Debug for Cmap<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result94 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 95 (self as &dyn SomeTable<'a>).fmt(f) 96 } 97 } 98 99 /// [Encoding Record](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#encoding-records-and-encodings) 100 #[derive(Clone, Debug)] 101 #[repr(C)] 102 #[repr(packed)] 103 pub struct EncodingRecord { 104 /// Platform ID. 105 pub platform_id: BigEndian<PlatformId>, 106 /// Platform-specific encoding ID. 107 pub encoding_id: BigEndian<u16>, 108 /// Byte offset from beginning of the [`Cmap`] table to the subtable for this 109 /// encoding. 110 pub subtable_offset: BigEndian<Offset32>, 111 } 112 113 impl EncodingRecord { 114 /// Platform ID. platform_id(&self) -> PlatformId115 pub fn platform_id(&self) -> PlatformId { 116 self.platform_id.get() 117 } 118 119 /// Platform-specific encoding ID. encoding_id(&self) -> u16120 pub fn encoding_id(&self) -> u16 { 121 self.encoding_id.get() 122 } 123 124 /// Byte offset from beginning of the [`Cmap`] table to the subtable for this 125 /// encoding. subtable_offset(&self) -> Offset32126 pub fn subtable_offset(&self) -> Offset32 { 127 self.subtable_offset.get() 128 } 129 130 /// Byte offset from beginning of the [`Cmap`] table to the subtable for this 131 /// encoding. 132 /// 133 /// The `data` argument should be retrieved from the parent table 134 /// By calling its `offset_data` method. subtable<'a>(&self, data: FontData<'a>) -> Result<CmapSubtable<'a>, ReadError>135 pub fn subtable<'a>(&self, data: FontData<'a>) -> Result<CmapSubtable<'a>, ReadError> { 136 self.subtable_offset().resolve(data) 137 } 138 } 139 140 impl FixedSize for EncodingRecord { 141 const RAW_BYTE_LEN: usize = 142 PlatformId::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN; 143 } 144 145 impl sealed::Sealed for EncodingRecord {} 146 147 /// SAFETY: see the [`FromBytes`] trait documentation. 148 unsafe impl FromBytes for EncodingRecord { this_trait_should_only_be_implemented_in_generated_code()149 fn this_trait_should_only_be_implemented_in_generated_code() {} 150 } 151 152 #[cfg(feature = "traversal")] 153 impl<'a> SomeRecord<'a> for EncodingRecord { traverse(self, data: FontData<'a>) -> RecordResolver<'a>154 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 155 RecordResolver { 156 name: "EncodingRecord", 157 get_field: Box::new(move |idx, _data| match idx { 158 0usize => Some(Field::new("platform_id", self.platform_id())), 159 1usize => Some(Field::new("encoding_id", self.encoding_id())), 160 2usize => Some(Field::new( 161 "subtable_offset", 162 FieldType::offset(self.subtable_offset(), self.subtable(_data)), 163 )), 164 _ => None, 165 }), 166 data, 167 } 168 } 169 } 170 171 /// <https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#platform-ids> 172 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] 173 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 174 #[repr(u16)] 175 #[allow(clippy::manual_non_exhaustive)] 176 pub enum PlatformId { 177 #[default] 178 Unicode = 0, 179 Macintosh = 1, 180 ISO = 2, 181 Windows = 3, 182 Custom = 4, 183 #[doc(hidden)] 184 /// If font data is malformed we will map unknown values to this variant 185 Unknown, 186 } 187 188 impl PlatformId { 189 /// Create from a raw scalar. 190 /// 191 /// This will never fail; unknown values will be mapped to the `Unknown` variant new(raw: u16) -> Self192 pub fn new(raw: u16) -> Self { 193 match raw { 194 0 => Self::Unicode, 195 1 => Self::Macintosh, 196 2 => Self::ISO, 197 3 => Self::Windows, 198 4 => Self::Custom, 199 _ => Self::Unknown, 200 } 201 } 202 } 203 204 impl font_types::Scalar for PlatformId { 205 type Raw = <u16 as font_types::Scalar>::Raw; to_raw(self) -> Self::Raw206 fn to_raw(self) -> Self::Raw { 207 (self as u16).to_raw() 208 } from_raw(raw: Self::Raw) -> Self209 fn from_raw(raw: Self::Raw) -> Self { 210 let t = <u16>::from_raw(raw); 211 Self::new(t) 212 } 213 } 214 215 #[cfg(feature = "traversal")] 216 impl<'a> From<PlatformId> for FieldType<'a> { from(src: PlatformId) -> FieldType<'a>217 fn from(src: PlatformId) -> FieldType<'a> { 218 (src as u16).into() 219 } 220 } 221 222 /// The different cmap subtable formats. 223 #[derive(Clone)] 224 pub enum CmapSubtable<'a> { 225 Format0(Cmap0<'a>), 226 Format2(Cmap2<'a>), 227 Format4(Cmap4<'a>), 228 Format6(Cmap6<'a>), 229 Format8(Cmap8<'a>), 230 Format10(Cmap10<'a>), 231 Format12(Cmap12<'a>), 232 Format13(Cmap13<'a>), 233 Format14(Cmap14<'a>), 234 } 235 236 impl<'a> CmapSubtable<'a> { 237 /// Format number is set to 0. format(&self) -> u16238 pub fn format(&self) -> u16 { 239 match self { 240 Self::Format0(item) => item.format(), 241 Self::Format2(item) => item.format(), 242 Self::Format4(item) => item.format(), 243 Self::Format6(item) => item.format(), 244 Self::Format8(item) => item.format(), 245 Self::Format10(item) => item.format(), 246 Self::Format12(item) => item.format(), 247 Self::Format13(item) => item.format(), 248 Self::Format14(item) => item.format(), 249 } 250 } 251 } 252 253 impl<'a> FontRead<'a> for CmapSubtable<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>254 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 255 let format: u16 = data.read_at(0usize)?; 256 match format { 257 Cmap0Marker::FORMAT => Ok(Self::Format0(FontRead::read(data)?)), 258 Cmap2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)), 259 Cmap4Marker::FORMAT => Ok(Self::Format4(FontRead::read(data)?)), 260 Cmap6Marker::FORMAT => Ok(Self::Format6(FontRead::read(data)?)), 261 Cmap8Marker::FORMAT => Ok(Self::Format8(FontRead::read(data)?)), 262 Cmap10Marker::FORMAT => Ok(Self::Format10(FontRead::read(data)?)), 263 Cmap12Marker::FORMAT => Ok(Self::Format12(FontRead::read(data)?)), 264 Cmap13Marker::FORMAT => Ok(Self::Format13(FontRead::read(data)?)), 265 Cmap14Marker::FORMAT => Ok(Self::Format14(FontRead::read(data)?)), 266 other => Err(ReadError::InvalidFormat(other.into())), 267 } 268 } 269 } 270 271 #[cfg(feature = "traversal")] 272 impl<'a> CmapSubtable<'a> { dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>273 fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> { 274 match self { 275 Self::Format0(table) => table, 276 Self::Format2(table) => table, 277 Self::Format4(table) => table, 278 Self::Format6(table) => table, 279 Self::Format8(table) => table, 280 Self::Format10(table) => table, 281 Self::Format12(table) => table, 282 Self::Format13(table) => table, 283 Self::Format14(table) => table, 284 } 285 } 286 } 287 288 #[cfg(feature = "traversal")] 289 impl<'a> std::fmt::Debug for CmapSubtable<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result290 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 291 self.dyn_inner().fmt(f) 292 } 293 } 294 295 #[cfg(feature = "traversal")] 296 impl<'a> SomeTable<'a> for CmapSubtable<'a> { type_name(&self) -> &str297 fn type_name(&self) -> &str { 298 self.dyn_inner().type_name() 299 } get_field(&self, idx: usize) -> Option<Field<'a>>300 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 301 self.dyn_inner().get_field(idx) 302 } 303 } 304 305 impl Format<u16> for Cmap0Marker { 306 const FORMAT: u16 = 0; 307 } 308 309 /// [cmap Format 0](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-0-byte-encoding-table): Byte encoding table 310 #[derive(Debug, Clone, Copy)] 311 #[doc(hidden)] 312 pub struct Cmap0Marker { 313 glyph_id_array_byte_len: usize, 314 } 315 316 impl Cmap0Marker { format_byte_range(&self) -> Range<usize>317 fn format_byte_range(&self) -> Range<usize> { 318 let start = 0; 319 start..start + u16::RAW_BYTE_LEN 320 } length_byte_range(&self) -> Range<usize>321 fn length_byte_range(&self) -> Range<usize> { 322 let start = self.format_byte_range().end; 323 start..start + u16::RAW_BYTE_LEN 324 } language_byte_range(&self) -> Range<usize>325 fn language_byte_range(&self) -> Range<usize> { 326 let start = self.length_byte_range().end; 327 start..start + u16::RAW_BYTE_LEN 328 } glyph_id_array_byte_range(&self) -> Range<usize>329 fn glyph_id_array_byte_range(&self) -> Range<usize> { 330 let start = self.language_byte_range().end; 331 start..start + self.glyph_id_array_byte_len 332 } 333 } 334 335 impl<'a> FontRead<'a> for Cmap0<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>336 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 337 let mut cursor = data.cursor(); 338 cursor.advance::<u16>(); 339 cursor.advance::<u16>(); 340 cursor.advance::<u16>(); 341 let glyph_id_array_byte_len = 256_usize * u8::RAW_BYTE_LEN; 342 cursor.advance_by(glyph_id_array_byte_len); 343 cursor.finish(Cmap0Marker { 344 glyph_id_array_byte_len, 345 }) 346 } 347 } 348 349 /// [cmap Format 0](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-0-byte-encoding-table): Byte encoding table 350 pub type Cmap0<'a> = TableRef<'a, Cmap0Marker>; 351 352 impl<'a> Cmap0<'a> { 353 /// Format number is set to 0. format(&self) -> u16354 pub fn format(&self) -> u16 { 355 let range = self.shape.format_byte_range(); 356 self.data.read_at(range.start).unwrap() 357 } 358 359 /// This is the length in bytes of the subtable. length(&self) -> u16360 pub fn length(&self) -> u16 { 361 let range = self.shape.length_byte_range(); 362 self.data.read_at(range.start).unwrap() 363 } 364 365 /// For requirements on use of the language field, see “Use of 366 /// the language field in 'cmap' subtables” in this document. language(&self) -> u16367 pub fn language(&self) -> u16 { 368 let range = self.shape.language_byte_range(); 369 self.data.read_at(range.start).unwrap() 370 } 371 372 /// An array that maps character codes to glyph index values. glyph_id_array(&self) -> &'a [u8]373 pub fn glyph_id_array(&self) -> &'a [u8] { 374 let range = self.shape.glyph_id_array_byte_range(); 375 self.data.read_array(range).unwrap() 376 } 377 } 378 379 #[cfg(feature = "traversal")] 380 impl<'a> SomeTable<'a> for Cmap0<'a> { type_name(&self) -> &str381 fn type_name(&self) -> &str { 382 "Cmap0" 383 } get_field(&self, idx: usize) -> Option<Field<'a>>384 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 385 match idx { 386 0usize => Some(Field::new("format", self.format())), 387 1usize => Some(Field::new("length", self.length())), 388 2usize => Some(Field::new("language", self.language())), 389 3usize => Some(Field::new("glyph_id_array", self.glyph_id_array())), 390 _ => None, 391 } 392 } 393 } 394 395 #[cfg(feature = "traversal")] 396 impl<'a> std::fmt::Debug for Cmap0<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result397 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 398 (self as &dyn SomeTable<'a>).fmt(f) 399 } 400 } 401 402 impl Format<u16> for Cmap2Marker { 403 const FORMAT: u16 = 2; 404 } 405 406 /// [cmap Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-2-high-byte-mapping-through-table): High-byte mapping through table 407 #[derive(Debug, Clone, Copy)] 408 #[doc(hidden)] 409 pub struct Cmap2Marker { 410 sub_header_keys_byte_len: usize, 411 } 412 413 impl Cmap2Marker { format_byte_range(&self) -> Range<usize>414 fn format_byte_range(&self) -> Range<usize> { 415 let start = 0; 416 start..start + u16::RAW_BYTE_LEN 417 } length_byte_range(&self) -> Range<usize>418 fn length_byte_range(&self) -> Range<usize> { 419 let start = self.format_byte_range().end; 420 start..start + u16::RAW_BYTE_LEN 421 } language_byte_range(&self) -> Range<usize>422 fn language_byte_range(&self) -> Range<usize> { 423 let start = self.length_byte_range().end; 424 start..start + u16::RAW_BYTE_LEN 425 } sub_header_keys_byte_range(&self) -> Range<usize>426 fn sub_header_keys_byte_range(&self) -> Range<usize> { 427 let start = self.language_byte_range().end; 428 start..start + self.sub_header_keys_byte_len 429 } 430 } 431 432 impl<'a> FontRead<'a> for Cmap2<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>433 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 434 let mut cursor = data.cursor(); 435 cursor.advance::<u16>(); 436 cursor.advance::<u16>(); 437 cursor.advance::<u16>(); 438 let sub_header_keys_byte_len = 256_usize * u16::RAW_BYTE_LEN; 439 cursor.advance_by(sub_header_keys_byte_len); 440 cursor.finish(Cmap2Marker { 441 sub_header_keys_byte_len, 442 }) 443 } 444 } 445 446 /// [cmap Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-2-high-byte-mapping-through-table): High-byte mapping through table 447 pub type Cmap2<'a> = TableRef<'a, Cmap2Marker>; 448 449 impl<'a> Cmap2<'a> { 450 /// Format number is set to 2. format(&self) -> u16451 pub fn format(&self) -> u16 { 452 let range = self.shape.format_byte_range(); 453 self.data.read_at(range.start).unwrap() 454 } 455 456 /// This is the length in bytes of the subtable. length(&self) -> u16457 pub fn length(&self) -> u16 { 458 let range = self.shape.length_byte_range(); 459 self.data.read_at(range.start).unwrap() 460 } 461 462 /// For requirements on use of the language field, see “Use of 463 /// the language field in 'cmap' subtables” in this document. language(&self) -> u16464 pub fn language(&self) -> u16 { 465 let range = self.shape.language_byte_range(); 466 self.data.read_at(range.start).unwrap() 467 } 468 469 /// Array that maps high bytes to subHeaders: value is subHeader 470 /// index × 8. sub_header_keys(&self) -> &'a [BigEndian<u16>]471 pub fn sub_header_keys(&self) -> &'a [BigEndian<u16>] { 472 let range = self.shape.sub_header_keys_byte_range(); 473 self.data.read_array(range).unwrap() 474 } 475 } 476 477 #[cfg(feature = "traversal")] 478 impl<'a> SomeTable<'a> for Cmap2<'a> { type_name(&self) -> &str479 fn type_name(&self) -> &str { 480 "Cmap2" 481 } get_field(&self, idx: usize) -> Option<Field<'a>>482 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 483 match idx { 484 0usize => Some(Field::new("format", self.format())), 485 1usize => Some(Field::new("length", self.length())), 486 2usize => Some(Field::new("language", self.language())), 487 3usize => Some(Field::new("sub_header_keys", self.sub_header_keys())), 488 _ => None, 489 } 490 } 491 } 492 493 #[cfg(feature = "traversal")] 494 impl<'a> std::fmt::Debug for Cmap2<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result495 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 496 (self as &dyn SomeTable<'a>).fmt(f) 497 } 498 } 499 500 /// Part of [Cmap2] 501 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 502 #[repr(C)] 503 #[repr(packed)] 504 pub struct SubHeader { 505 /// First valid low byte for this SubHeader. 506 pub first_code: BigEndian<u16>, 507 /// Number of valid low bytes for this SubHeader. 508 pub entry_count: BigEndian<u16>, 509 /// See text below. 510 pub id_delta: BigEndian<i16>, 511 /// See text below. 512 pub id_range_offset: BigEndian<u16>, 513 } 514 515 impl SubHeader { 516 /// First valid low byte for this SubHeader. first_code(&self) -> u16517 pub fn first_code(&self) -> u16 { 518 self.first_code.get() 519 } 520 521 /// Number of valid low bytes for this SubHeader. entry_count(&self) -> u16522 pub fn entry_count(&self) -> u16 { 523 self.entry_count.get() 524 } 525 526 /// See text below. id_delta(&self) -> i16527 pub fn id_delta(&self) -> i16 { 528 self.id_delta.get() 529 } 530 531 /// See text below. id_range_offset(&self) -> u16532 pub fn id_range_offset(&self) -> u16 { 533 self.id_range_offset.get() 534 } 535 } 536 537 impl FixedSize for SubHeader { 538 const RAW_BYTE_LEN: usize = 539 u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + i16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; 540 } 541 542 impl sealed::Sealed for SubHeader {} 543 544 /// SAFETY: see the [`FromBytes`] trait documentation. 545 unsafe impl FromBytes for SubHeader { this_trait_should_only_be_implemented_in_generated_code()546 fn this_trait_should_only_be_implemented_in_generated_code() {} 547 } 548 549 #[cfg(feature = "traversal")] 550 impl<'a> SomeRecord<'a> for SubHeader { traverse(self, data: FontData<'a>) -> RecordResolver<'a>551 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 552 RecordResolver { 553 name: "SubHeader", 554 get_field: Box::new(move |idx, _data| match idx { 555 0usize => Some(Field::new("first_code", self.first_code())), 556 1usize => Some(Field::new("entry_count", self.entry_count())), 557 2usize => Some(Field::new("id_delta", self.id_delta())), 558 3usize => Some(Field::new("id_range_offset", self.id_range_offset())), 559 _ => None, 560 }), 561 data, 562 } 563 } 564 } 565 566 impl Format<u16> for Cmap4Marker { 567 const FORMAT: u16 = 4; 568 } 569 570 /// [cmap Format 4](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-4-segment-mapping-to-delta-values): Segment mapping to delta values 571 #[derive(Debug, Clone, Copy)] 572 #[doc(hidden)] 573 pub struct Cmap4Marker { 574 end_code_byte_len: usize, 575 start_code_byte_len: usize, 576 id_delta_byte_len: usize, 577 id_range_offsets_byte_len: usize, 578 glyph_id_array_byte_len: usize, 579 } 580 581 impl Cmap4Marker { format_byte_range(&self) -> Range<usize>582 fn format_byte_range(&self) -> Range<usize> { 583 let start = 0; 584 start..start + u16::RAW_BYTE_LEN 585 } length_byte_range(&self) -> Range<usize>586 fn length_byte_range(&self) -> Range<usize> { 587 let start = self.format_byte_range().end; 588 start..start + u16::RAW_BYTE_LEN 589 } language_byte_range(&self) -> Range<usize>590 fn language_byte_range(&self) -> Range<usize> { 591 let start = self.length_byte_range().end; 592 start..start + u16::RAW_BYTE_LEN 593 } seg_count_x2_byte_range(&self) -> Range<usize>594 fn seg_count_x2_byte_range(&self) -> Range<usize> { 595 let start = self.language_byte_range().end; 596 start..start + u16::RAW_BYTE_LEN 597 } search_range_byte_range(&self) -> Range<usize>598 fn search_range_byte_range(&self) -> Range<usize> { 599 let start = self.seg_count_x2_byte_range().end; 600 start..start + u16::RAW_BYTE_LEN 601 } entry_selector_byte_range(&self) -> Range<usize>602 fn entry_selector_byte_range(&self) -> Range<usize> { 603 let start = self.search_range_byte_range().end; 604 start..start + u16::RAW_BYTE_LEN 605 } range_shift_byte_range(&self) -> Range<usize>606 fn range_shift_byte_range(&self) -> Range<usize> { 607 let start = self.entry_selector_byte_range().end; 608 start..start + u16::RAW_BYTE_LEN 609 } end_code_byte_range(&self) -> Range<usize>610 fn end_code_byte_range(&self) -> Range<usize> { 611 let start = self.range_shift_byte_range().end; 612 start..start + self.end_code_byte_len 613 } reserved_pad_byte_range(&self) -> Range<usize>614 fn reserved_pad_byte_range(&self) -> Range<usize> { 615 let start = self.end_code_byte_range().end; 616 start..start + u16::RAW_BYTE_LEN 617 } start_code_byte_range(&self) -> Range<usize>618 fn start_code_byte_range(&self) -> Range<usize> { 619 let start = self.reserved_pad_byte_range().end; 620 start..start + self.start_code_byte_len 621 } id_delta_byte_range(&self) -> Range<usize>622 fn id_delta_byte_range(&self) -> Range<usize> { 623 let start = self.start_code_byte_range().end; 624 start..start + self.id_delta_byte_len 625 } id_range_offsets_byte_range(&self) -> Range<usize>626 fn id_range_offsets_byte_range(&self) -> Range<usize> { 627 let start = self.id_delta_byte_range().end; 628 start..start + self.id_range_offsets_byte_len 629 } glyph_id_array_byte_range(&self) -> Range<usize>630 fn glyph_id_array_byte_range(&self) -> Range<usize> { 631 let start = self.id_range_offsets_byte_range().end; 632 start..start + self.glyph_id_array_byte_len 633 } 634 } 635 636 impl<'a> FontRead<'a> for Cmap4<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>637 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 638 let mut cursor = data.cursor(); 639 cursor.advance::<u16>(); 640 cursor.advance::<u16>(); 641 cursor.advance::<u16>(); 642 let seg_count_x2: u16 = cursor.read()?; 643 cursor.advance::<u16>(); 644 cursor.advance::<u16>(); 645 cursor.advance::<u16>(); 646 let end_code_byte_len = transforms::half(seg_count_x2) * u16::RAW_BYTE_LEN; 647 cursor.advance_by(end_code_byte_len); 648 cursor.advance::<u16>(); 649 let start_code_byte_len = transforms::half(seg_count_x2) * u16::RAW_BYTE_LEN; 650 cursor.advance_by(start_code_byte_len); 651 let id_delta_byte_len = transforms::half(seg_count_x2) * i16::RAW_BYTE_LEN; 652 cursor.advance_by(id_delta_byte_len); 653 let id_range_offsets_byte_len = transforms::half(seg_count_x2) * u16::RAW_BYTE_LEN; 654 cursor.advance_by(id_range_offsets_byte_len); 655 let glyph_id_array_byte_len = 656 cursor.remaining_bytes() / u16::RAW_BYTE_LEN * u16::RAW_BYTE_LEN; 657 cursor.advance_by(glyph_id_array_byte_len); 658 cursor.finish(Cmap4Marker { 659 end_code_byte_len, 660 start_code_byte_len, 661 id_delta_byte_len, 662 id_range_offsets_byte_len, 663 glyph_id_array_byte_len, 664 }) 665 } 666 } 667 668 /// [cmap Format 4](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-4-segment-mapping-to-delta-values): Segment mapping to delta values 669 pub type Cmap4<'a> = TableRef<'a, Cmap4Marker>; 670 671 impl<'a> Cmap4<'a> { 672 /// Format number is set to 4. format(&self) -> u16673 pub fn format(&self) -> u16 { 674 let range = self.shape.format_byte_range(); 675 self.data.read_at(range.start).unwrap() 676 } 677 678 /// This is the length in bytes of the subtable. length(&self) -> u16679 pub fn length(&self) -> u16 { 680 let range = self.shape.length_byte_range(); 681 self.data.read_at(range.start).unwrap() 682 } 683 684 /// For requirements on use of the language field, see “Use of 685 /// the language field in 'cmap' subtables” in this document. language(&self) -> u16686 pub fn language(&self) -> u16 { 687 let range = self.shape.language_byte_range(); 688 self.data.read_at(range.start).unwrap() 689 } 690 691 /// 2 × segCount. seg_count_x2(&self) -> u16692 pub fn seg_count_x2(&self) -> u16 { 693 let range = self.shape.seg_count_x2_byte_range(); 694 self.data.read_at(range.start).unwrap() 695 } 696 697 /// Maximum power of 2 less than or equal to segCount, times 2 698 /// ((2**floor(log2(segCount))) * 2, where “**” is an 699 /// exponentiation operator) search_range(&self) -> u16700 pub fn search_range(&self) -> u16 { 701 let range = self.shape.search_range_byte_range(); 702 self.data.read_at(range.start).unwrap() 703 } 704 705 /// Log2 of the maximum power of 2 less than or equal to numTables 706 /// (log2(searchRange/2), which is equal to floor(log2(segCount))) entry_selector(&self) -> u16707 pub fn entry_selector(&self) -> u16 { 708 let range = self.shape.entry_selector_byte_range(); 709 self.data.read_at(range.start).unwrap() 710 } 711 712 /// segCount times 2, minus searchRange ((segCount * 2) - 713 /// searchRange) range_shift(&self) -> u16714 pub fn range_shift(&self) -> u16 { 715 let range = self.shape.range_shift_byte_range(); 716 self.data.read_at(range.start).unwrap() 717 } 718 719 /// End characterCode for each segment, last=0xFFFF. end_code(&self) -> &'a [BigEndian<u16>]720 pub fn end_code(&self) -> &'a [BigEndian<u16>] { 721 let range = self.shape.end_code_byte_range(); 722 self.data.read_array(range).unwrap() 723 } 724 725 /// Start character code for each segment. start_code(&self) -> &'a [BigEndian<u16>]726 pub fn start_code(&self) -> &'a [BigEndian<u16>] { 727 let range = self.shape.start_code_byte_range(); 728 self.data.read_array(range).unwrap() 729 } 730 731 /// Delta for all character codes in segment. id_delta(&self) -> &'a [BigEndian<i16>]732 pub fn id_delta(&self) -> &'a [BigEndian<i16>] { 733 let range = self.shape.id_delta_byte_range(); 734 self.data.read_array(range).unwrap() 735 } 736 737 /// Offsets into glyphIdArray or 0 id_range_offsets(&self) -> &'a [BigEndian<u16>]738 pub fn id_range_offsets(&self) -> &'a [BigEndian<u16>] { 739 let range = self.shape.id_range_offsets_byte_range(); 740 self.data.read_array(range).unwrap() 741 } 742 743 /// Glyph index array (arbitrary length) glyph_id_array(&self) -> &'a [BigEndian<u16>]744 pub fn glyph_id_array(&self) -> &'a [BigEndian<u16>] { 745 let range = self.shape.glyph_id_array_byte_range(); 746 self.data.read_array(range).unwrap() 747 } 748 } 749 750 #[cfg(feature = "traversal")] 751 impl<'a> SomeTable<'a> for Cmap4<'a> { type_name(&self) -> &str752 fn type_name(&self) -> &str { 753 "Cmap4" 754 } get_field(&self, idx: usize) -> Option<Field<'a>>755 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 756 match idx { 757 0usize => Some(Field::new("format", self.format())), 758 1usize => Some(Field::new("length", self.length())), 759 2usize => Some(Field::new("language", self.language())), 760 3usize => Some(Field::new("seg_count_x2", self.seg_count_x2())), 761 4usize => Some(Field::new("search_range", self.search_range())), 762 5usize => Some(Field::new("entry_selector", self.entry_selector())), 763 6usize => Some(Field::new("range_shift", self.range_shift())), 764 7usize => Some(Field::new("end_code", self.end_code())), 765 8usize => Some(Field::new("start_code", self.start_code())), 766 9usize => Some(Field::new("id_delta", self.id_delta())), 767 10usize => Some(Field::new("id_range_offsets", self.id_range_offsets())), 768 11usize => Some(Field::new("glyph_id_array", self.glyph_id_array())), 769 _ => None, 770 } 771 } 772 } 773 774 #[cfg(feature = "traversal")] 775 impl<'a> std::fmt::Debug for Cmap4<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result776 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 777 (self as &dyn SomeTable<'a>).fmt(f) 778 } 779 } 780 781 impl Format<u16> for Cmap6Marker { 782 const FORMAT: u16 = 6; 783 } 784 785 /// [cmap Format 6](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-6-trimmed-table-mapping): Trimmed table mapping 786 #[derive(Debug, Clone, Copy)] 787 #[doc(hidden)] 788 pub struct Cmap6Marker { 789 glyph_id_array_byte_len: usize, 790 } 791 792 impl Cmap6Marker { format_byte_range(&self) -> Range<usize>793 fn format_byte_range(&self) -> Range<usize> { 794 let start = 0; 795 start..start + u16::RAW_BYTE_LEN 796 } length_byte_range(&self) -> Range<usize>797 fn length_byte_range(&self) -> Range<usize> { 798 let start = self.format_byte_range().end; 799 start..start + u16::RAW_BYTE_LEN 800 } language_byte_range(&self) -> Range<usize>801 fn language_byte_range(&self) -> Range<usize> { 802 let start = self.length_byte_range().end; 803 start..start + u16::RAW_BYTE_LEN 804 } first_code_byte_range(&self) -> Range<usize>805 fn first_code_byte_range(&self) -> Range<usize> { 806 let start = self.language_byte_range().end; 807 start..start + u16::RAW_BYTE_LEN 808 } entry_count_byte_range(&self) -> Range<usize>809 fn entry_count_byte_range(&self) -> Range<usize> { 810 let start = self.first_code_byte_range().end; 811 start..start + u16::RAW_BYTE_LEN 812 } glyph_id_array_byte_range(&self) -> Range<usize>813 fn glyph_id_array_byte_range(&self) -> Range<usize> { 814 let start = self.entry_count_byte_range().end; 815 start..start + self.glyph_id_array_byte_len 816 } 817 } 818 819 impl<'a> FontRead<'a> for Cmap6<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>820 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 821 let mut cursor = data.cursor(); 822 cursor.advance::<u16>(); 823 cursor.advance::<u16>(); 824 cursor.advance::<u16>(); 825 cursor.advance::<u16>(); 826 let entry_count: u16 = cursor.read()?; 827 let glyph_id_array_byte_len = entry_count as usize * u16::RAW_BYTE_LEN; 828 cursor.advance_by(glyph_id_array_byte_len); 829 cursor.finish(Cmap6Marker { 830 glyph_id_array_byte_len, 831 }) 832 } 833 } 834 835 /// [cmap Format 6](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-6-trimmed-table-mapping): Trimmed table mapping 836 pub type Cmap6<'a> = TableRef<'a, Cmap6Marker>; 837 838 impl<'a> Cmap6<'a> { 839 /// Format number is set to 6. format(&self) -> u16840 pub fn format(&self) -> u16 { 841 let range = self.shape.format_byte_range(); 842 self.data.read_at(range.start).unwrap() 843 } 844 845 /// This is the length in bytes of the subtable. length(&self) -> u16846 pub fn length(&self) -> u16 { 847 let range = self.shape.length_byte_range(); 848 self.data.read_at(range.start).unwrap() 849 } 850 851 /// For requirements on use of the language field, see “Use of 852 /// the language field in 'cmap' subtables” in this document. language(&self) -> u16853 pub fn language(&self) -> u16 { 854 let range = self.shape.language_byte_range(); 855 self.data.read_at(range.start).unwrap() 856 } 857 858 /// First character code of subrange. first_code(&self) -> u16859 pub fn first_code(&self) -> u16 { 860 let range = self.shape.first_code_byte_range(); 861 self.data.read_at(range.start).unwrap() 862 } 863 864 /// Number of character codes in subrange. entry_count(&self) -> u16865 pub fn entry_count(&self) -> u16 { 866 let range = self.shape.entry_count_byte_range(); 867 self.data.read_at(range.start).unwrap() 868 } 869 870 /// Array of glyph index values for character codes in the range. glyph_id_array(&self) -> &'a [BigEndian<u16>]871 pub fn glyph_id_array(&self) -> &'a [BigEndian<u16>] { 872 let range = self.shape.glyph_id_array_byte_range(); 873 self.data.read_array(range).unwrap() 874 } 875 } 876 877 #[cfg(feature = "traversal")] 878 impl<'a> SomeTable<'a> for Cmap6<'a> { type_name(&self) -> &str879 fn type_name(&self) -> &str { 880 "Cmap6" 881 } get_field(&self, idx: usize) -> Option<Field<'a>>882 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 883 match idx { 884 0usize => Some(Field::new("format", self.format())), 885 1usize => Some(Field::new("length", self.length())), 886 2usize => Some(Field::new("language", self.language())), 887 3usize => Some(Field::new("first_code", self.first_code())), 888 4usize => Some(Field::new("entry_count", self.entry_count())), 889 5usize => Some(Field::new("glyph_id_array", self.glyph_id_array())), 890 _ => None, 891 } 892 } 893 } 894 895 #[cfg(feature = "traversal")] 896 impl<'a> std::fmt::Debug for Cmap6<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result897 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 898 (self as &dyn SomeTable<'a>).fmt(f) 899 } 900 } 901 902 impl Format<u16> for Cmap8Marker { 903 const FORMAT: u16 = 8; 904 } 905 906 /// [cmap Format 8](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-8-mixed-16-bit-and-32-bit-coverage): mixed 16-bit and 32-bit coverage 907 #[derive(Debug, Clone, Copy)] 908 #[doc(hidden)] 909 pub struct Cmap8Marker { 910 is32_byte_len: usize, 911 groups_byte_len: usize, 912 } 913 914 impl Cmap8Marker { format_byte_range(&self) -> Range<usize>915 fn format_byte_range(&self) -> Range<usize> { 916 let start = 0; 917 start..start + u16::RAW_BYTE_LEN 918 } reserved_byte_range(&self) -> Range<usize>919 fn reserved_byte_range(&self) -> Range<usize> { 920 let start = self.format_byte_range().end; 921 start..start + u16::RAW_BYTE_LEN 922 } length_byte_range(&self) -> Range<usize>923 fn length_byte_range(&self) -> Range<usize> { 924 let start = self.reserved_byte_range().end; 925 start..start + u32::RAW_BYTE_LEN 926 } language_byte_range(&self) -> Range<usize>927 fn language_byte_range(&self) -> Range<usize> { 928 let start = self.length_byte_range().end; 929 start..start + u32::RAW_BYTE_LEN 930 } is32_byte_range(&self) -> Range<usize>931 fn is32_byte_range(&self) -> Range<usize> { 932 let start = self.language_byte_range().end; 933 start..start + self.is32_byte_len 934 } num_groups_byte_range(&self) -> Range<usize>935 fn num_groups_byte_range(&self) -> Range<usize> { 936 let start = self.is32_byte_range().end; 937 start..start + u32::RAW_BYTE_LEN 938 } groups_byte_range(&self) -> Range<usize>939 fn groups_byte_range(&self) -> Range<usize> { 940 let start = self.num_groups_byte_range().end; 941 start..start + self.groups_byte_len 942 } 943 } 944 945 impl<'a> FontRead<'a> for Cmap8<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>946 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 947 let mut cursor = data.cursor(); 948 cursor.advance::<u16>(); 949 cursor.advance::<u16>(); 950 cursor.advance::<u32>(); 951 cursor.advance::<u32>(); 952 let is32_byte_len = 8192_usize * u8::RAW_BYTE_LEN; 953 cursor.advance_by(is32_byte_len); 954 let num_groups: u32 = cursor.read()?; 955 let groups_byte_len = num_groups as usize * SequentialMapGroup::RAW_BYTE_LEN; 956 cursor.advance_by(groups_byte_len); 957 cursor.finish(Cmap8Marker { 958 is32_byte_len, 959 groups_byte_len, 960 }) 961 } 962 } 963 964 /// [cmap Format 8](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-8-mixed-16-bit-and-32-bit-coverage): mixed 16-bit and 32-bit coverage 965 pub type Cmap8<'a> = TableRef<'a, Cmap8Marker>; 966 967 impl<'a> Cmap8<'a> { 968 /// Subtable format; set to 8. format(&self) -> u16969 pub fn format(&self) -> u16 { 970 let range = self.shape.format_byte_range(); 971 self.data.read_at(range.start).unwrap() 972 } 973 974 /// Byte length of this subtable (including the header) length(&self) -> u32975 pub fn length(&self) -> u32 { 976 let range = self.shape.length_byte_range(); 977 self.data.read_at(range.start).unwrap() 978 } 979 980 /// For requirements on use of the language field, see “Use of 981 /// the language field in 'cmap' subtables” in this document. language(&self) -> u32982 pub fn language(&self) -> u32 { 983 let range = self.shape.language_byte_range(); 984 self.data.read_at(range.start).unwrap() 985 } 986 987 /// Tightly packed array of bits (8K bytes total) indicating 988 /// whether the particular 16-bit (index) value is the start of a 989 /// 32-bit character code is32(&self) -> &'a [u8]990 pub fn is32(&self) -> &'a [u8] { 991 let range = self.shape.is32_byte_range(); 992 self.data.read_array(range).unwrap() 993 } 994 995 /// Number of groupings which follow num_groups(&self) -> u32996 pub fn num_groups(&self) -> u32 { 997 let range = self.shape.num_groups_byte_range(); 998 self.data.read_at(range.start).unwrap() 999 } 1000 1001 /// Array of SequentialMapGroup records. groups(&self) -> &'a [SequentialMapGroup]1002 pub fn groups(&self) -> &'a [SequentialMapGroup] { 1003 let range = self.shape.groups_byte_range(); 1004 self.data.read_array(range).unwrap() 1005 } 1006 } 1007 1008 #[cfg(feature = "traversal")] 1009 impl<'a> SomeTable<'a> for Cmap8<'a> { type_name(&self) -> &str1010 fn type_name(&self) -> &str { 1011 "Cmap8" 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("format", self.format())), 1016 1usize => Some(Field::new("length", self.length())), 1017 2usize => Some(Field::new("language", self.language())), 1018 3usize => Some(Field::new("is32", self.is32())), 1019 4usize => Some(Field::new("num_groups", self.num_groups())), 1020 5usize => Some(Field::new( 1021 "groups", 1022 traversal::FieldType::array_of_records( 1023 stringify!(SequentialMapGroup), 1024 self.groups(), 1025 self.offset_data(), 1026 ), 1027 )), 1028 _ => None, 1029 } 1030 } 1031 } 1032 1033 #[cfg(feature = "traversal")] 1034 impl<'a> std::fmt::Debug for Cmap8<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1035 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1036 (self as &dyn SomeTable<'a>).fmt(f) 1037 } 1038 } 1039 1040 /// Used in [Cmap8] and [Cmap12] 1041 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 1042 #[repr(C)] 1043 #[repr(packed)] 1044 pub struct SequentialMapGroup { 1045 /// First character code in this group; note that if this group is 1046 /// for one or more 16-bit character codes (which is determined 1047 /// from the is32 array), this 32-bit value will have the high 1048 /// 16-bits set to zero 1049 pub start_char_code: BigEndian<u32>, 1050 /// Last character code in this group; same condition as listed 1051 /// above for the startCharCode 1052 pub end_char_code: BigEndian<u32>, 1053 /// Glyph index corresponding to the starting character code 1054 pub start_glyph_id: BigEndian<u32>, 1055 } 1056 1057 impl SequentialMapGroup { 1058 /// First character code in this group; note that if this group is 1059 /// for one or more 16-bit character codes (which is determined 1060 /// from the is32 array), this 32-bit value will have the high 1061 /// 16-bits set to zero start_char_code(&self) -> u321062 pub fn start_char_code(&self) -> u32 { 1063 self.start_char_code.get() 1064 } 1065 1066 /// Last character code in this group; same condition as listed 1067 /// above for the startCharCode end_char_code(&self) -> u321068 pub fn end_char_code(&self) -> u32 { 1069 self.end_char_code.get() 1070 } 1071 1072 /// Glyph index corresponding to the starting character code start_glyph_id(&self) -> u321073 pub fn start_glyph_id(&self) -> u32 { 1074 self.start_glyph_id.get() 1075 } 1076 } 1077 1078 impl FixedSize for SequentialMapGroup { 1079 const RAW_BYTE_LEN: usize = u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN; 1080 } 1081 1082 impl sealed::Sealed for SequentialMapGroup {} 1083 1084 /// SAFETY: see the [`FromBytes`] trait documentation. 1085 unsafe impl FromBytes for SequentialMapGroup { this_trait_should_only_be_implemented_in_generated_code()1086 fn this_trait_should_only_be_implemented_in_generated_code() {} 1087 } 1088 1089 #[cfg(feature = "traversal")] 1090 impl<'a> SomeRecord<'a> for SequentialMapGroup { traverse(self, data: FontData<'a>) -> RecordResolver<'a>1091 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 1092 RecordResolver { 1093 name: "SequentialMapGroup", 1094 get_field: Box::new(move |idx, _data| match idx { 1095 0usize => Some(Field::new("start_char_code", self.start_char_code())), 1096 1usize => Some(Field::new("end_char_code", self.end_char_code())), 1097 2usize => Some(Field::new("start_glyph_id", self.start_glyph_id())), 1098 _ => None, 1099 }), 1100 data, 1101 } 1102 } 1103 } 1104 1105 impl Format<u16> for Cmap10Marker { 1106 const FORMAT: u16 = 10; 1107 } 1108 1109 /// [cmap Format 10](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-10-trimmed-array): Tr 1110 #[derive(Debug, Clone, Copy)] 1111 #[doc(hidden)] 1112 pub struct Cmap10Marker { 1113 glyph_id_array_byte_len: usize, 1114 } 1115 1116 impl Cmap10Marker { format_byte_range(&self) -> Range<usize>1117 fn format_byte_range(&self) -> Range<usize> { 1118 let start = 0; 1119 start..start + u16::RAW_BYTE_LEN 1120 } reserved_byte_range(&self) -> Range<usize>1121 fn reserved_byte_range(&self) -> Range<usize> { 1122 let start = self.format_byte_range().end; 1123 start..start + u16::RAW_BYTE_LEN 1124 } length_byte_range(&self) -> Range<usize>1125 fn length_byte_range(&self) -> Range<usize> { 1126 let start = self.reserved_byte_range().end; 1127 start..start + u32::RAW_BYTE_LEN 1128 } language_byte_range(&self) -> Range<usize>1129 fn language_byte_range(&self) -> Range<usize> { 1130 let start = self.length_byte_range().end; 1131 start..start + u32::RAW_BYTE_LEN 1132 } start_char_code_byte_range(&self) -> Range<usize>1133 fn start_char_code_byte_range(&self) -> Range<usize> { 1134 let start = self.language_byte_range().end; 1135 start..start + u32::RAW_BYTE_LEN 1136 } num_chars_byte_range(&self) -> Range<usize>1137 fn num_chars_byte_range(&self) -> Range<usize> { 1138 let start = self.start_char_code_byte_range().end; 1139 start..start + u32::RAW_BYTE_LEN 1140 } glyph_id_array_byte_range(&self) -> Range<usize>1141 fn glyph_id_array_byte_range(&self) -> Range<usize> { 1142 let start = self.num_chars_byte_range().end; 1143 start..start + self.glyph_id_array_byte_len 1144 } 1145 } 1146 1147 impl<'a> FontRead<'a> for Cmap10<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1148 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1149 let mut cursor = data.cursor(); 1150 cursor.advance::<u16>(); 1151 cursor.advance::<u16>(); 1152 cursor.advance::<u32>(); 1153 cursor.advance::<u32>(); 1154 cursor.advance::<u32>(); 1155 cursor.advance::<u32>(); 1156 let glyph_id_array_byte_len = 1157 cursor.remaining_bytes() / u16::RAW_BYTE_LEN * u16::RAW_BYTE_LEN; 1158 cursor.advance_by(glyph_id_array_byte_len); 1159 cursor.finish(Cmap10Marker { 1160 glyph_id_array_byte_len, 1161 }) 1162 } 1163 } 1164 1165 /// [cmap Format 10](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-10-trimmed-array): Tr 1166 pub type Cmap10<'a> = TableRef<'a, Cmap10Marker>; 1167 1168 impl<'a> Cmap10<'a> { 1169 /// Subtable format; set to 10. format(&self) -> u161170 pub fn format(&self) -> u16 { 1171 let range = self.shape.format_byte_range(); 1172 self.data.read_at(range.start).unwrap() 1173 } 1174 1175 /// Byte length of this subtable (including the header) length(&self) -> u321176 pub fn length(&self) -> u32 { 1177 let range = self.shape.length_byte_range(); 1178 self.data.read_at(range.start).unwrap() 1179 } 1180 1181 /// For requirements on use of the language field, see “Use of 1182 /// the language field in 'cmap' subtables” in this document. language(&self) -> u321183 pub fn language(&self) -> u32 { 1184 let range = self.shape.language_byte_range(); 1185 self.data.read_at(range.start).unwrap() 1186 } 1187 1188 /// First character code covered start_char_code(&self) -> u321189 pub fn start_char_code(&self) -> u32 { 1190 let range = self.shape.start_char_code_byte_range(); 1191 self.data.read_at(range.start).unwrap() 1192 } 1193 1194 /// Number of character codes covered num_chars(&self) -> u321195 pub fn num_chars(&self) -> u32 { 1196 let range = self.shape.num_chars_byte_range(); 1197 self.data.read_at(range.start).unwrap() 1198 } 1199 1200 /// Array of glyph indices for the character codes covered glyph_id_array(&self) -> &'a [BigEndian<u16>]1201 pub fn glyph_id_array(&self) -> &'a [BigEndian<u16>] { 1202 let range = self.shape.glyph_id_array_byte_range(); 1203 self.data.read_array(range).unwrap() 1204 } 1205 } 1206 1207 #[cfg(feature = "traversal")] 1208 impl<'a> SomeTable<'a> for Cmap10<'a> { type_name(&self) -> &str1209 fn type_name(&self) -> &str { 1210 "Cmap10" 1211 } get_field(&self, idx: usize) -> Option<Field<'a>>1212 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1213 match idx { 1214 0usize => Some(Field::new("format", self.format())), 1215 1usize => Some(Field::new("length", self.length())), 1216 2usize => Some(Field::new("language", self.language())), 1217 3usize => Some(Field::new("start_char_code", self.start_char_code())), 1218 4usize => Some(Field::new("num_chars", self.num_chars())), 1219 5usize => Some(Field::new("glyph_id_array", self.glyph_id_array())), 1220 _ => None, 1221 } 1222 } 1223 } 1224 1225 #[cfg(feature = "traversal")] 1226 impl<'a> std::fmt::Debug for Cmap10<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1227 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1228 (self as &dyn SomeTable<'a>).fmt(f) 1229 } 1230 } 1231 1232 impl Format<u16> for Cmap12Marker { 1233 const FORMAT: u16 = 12; 1234 } 1235 1236 /// [cmap Format 12](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-12-segmented-coverage): Segmented coverage 1237 #[derive(Debug, Clone, Copy)] 1238 #[doc(hidden)] 1239 pub struct Cmap12Marker { 1240 groups_byte_len: usize, 1241 } 1242 1243 impl Cmap12Marker { format_byte_range(&self) -> Range<usize>1244 fn format_byte_range(&self) -> Range<usize> { 1245 let start = 0; 1246 start..start + u16::RAW_BYTE_LEN 1247 } reserved_byte_range(&self) -> Range<usize>1248 fn reserved_byte_range(&self) -> Range<usize> { 1249 let start = self.format_byte_range().end; 1250 start..start + u16::RAW_BYTE_LEN 1251 } length_byte_range(&self) -> Range<usize>1252 fn length_byte_range(&self) -> Range<usize> { 1253 let start = self.reserved_byte_range().end; 1254 start..start + u32::RAW_BYTE_LEN 1255 } language_byte_range(&self) -> Range<usize>1256 fn language_byte_range(&self) -> Range<usize> { 1257 let start = self.length_byte_range().end; 1258 start..start + u32::RAW_BYTE_LEN 1259 } num_groups_byte_range(&self) -> Range<usize>1260 fn num_groups_byte_range(&self) -> Range<usize> { 1261 let start = self.language_byte_range().end; 1262 start..start + u32::RAW_BYTE_LEN 1263 } groups_byte_range(&self) -> Range<usize>1264 fn groups_byte_range(&self) -> Range<usize> { 1265 let start = self.num_groups_byte_range().end; 1266 start..start + self.groups_byte_len 1267 } 1268 } 1269 1270 impl<'a> FontRead<'a> for Cmap12<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1271 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1272 let mut cursor = data.cursor(); 1273 cursor.advance::<u16>(); 1274 cursor.advance::<u16>(); 1275 cursor.advance::<u32>(); 1276 cursor.advance::<u32>(); 1277 let num_groups: u32 = cursor.read()?; 1278 let groups_byte_len = num_groups as usize * SequentialMapGroup::RAW_BYTE_LEN; 1279 cursor.advance_by(groups_byte_len); 1280 cursor.finish(Cmap12Marker { groups_byte_len }) 1281 } 1282 } 1283 1284 /// [cmap Format 12](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-12-segmented-coverage): Segmented coverage 1285 pub type Cmap12<'a> = TableRef<'a, Cmap12Marker>; 1286 1287 impl<'a> Cmap12<'a> { 1288 /// Subtable format; set to 12. format(&self) -> u161289 pub fn format(&self) -> u16 { 1290 let range = self.shape.format_byte_range(); 1291 self.data.read_at(range.start).unwrap() 1292 } 1293 1294 /// Byte length of this subtable (including the header) length(&self) -> u321295 pub fn length(&self) -> u32 { 1296 let range = self.shape.length_byte_range(); 1297 self.data.read_at(range.start).unwrap() 1298 } 1299 1300 /// For requirements on use of the language field, see “Use of 1301 /// the language field in 'cmap' subtables” in this document. language(&self) -> u321302 pub fn language(&self) -> u32 { 1303 let range = self.shape.language_byte_range(); 1304 self.data.read_at(range.start).unwrap() 1305 } 1306 1307 /// Number of groupings which follow num_groups(&self) -> u321308 pub fn num_groups(&self) -> u32 { 1309 let range = self.shape.num_groups_byte_range(); 1310 self.data.read_at(range.start).unwrap() 1311 } 1312 1313 /// Array of SequentialMapGroup records. groups(&self) -> &'a [SequentialMapGroup]1314 pub fn groups(&self) -> &'a [SequentialMapGroup] { 1315 let range = self.shape.groups_byte_range(); 1316 self.data.read_array(range).unwrap() 1317 } 1318 } 1319 1320 #[cfg(feature = "traversal")] 1321 impl<'a> SomeTable<'a> for Cmap12<'a> { type_name(&self) -> &str1322 fn type_name(&self) -> &str { 1323 "Cmap12" 1324 } get_field(&self, idx: usize) -> Option<Field<'a>>1325 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1326 match idx { 1327 0usize => Some(Field::new("format", self.format())), 1328 1usize => Some(Field::new("length", self.length())), 1329 2usize => Some(Field::new("language", self.language())), 1330 3usize => Some(Field::new("num_groups", self.num_groups())), 1331 4usize => Some(Field::new( 1332 "groups", 1333 traversal::FieldType::array_of_records( 1334 stringify!(SequentialMapGroup), 1335 self.groups(), 1336 self.offset_data(), 1337 ), 1338 )), 1339 _ => None, 1340 } 1341 } 1342 } 1343 1344 #[cfg(feature = "traversal")] 1345 impl<'a> std::fmt::Debug for Cmap12<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1346 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1347 (self as &dyn SomeTable<'a>).fmt(f) 1348 } 1349 } 1350 1351 impl Format<u16> for Cmap13Marker { 1352 const FORMAT: u16 = 13; 1353 } 1354 1355 /// [cmap Format 13](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-13-many-to-one-range-mappings): Many-to-one range mappings 1356 #[derive(Debug, Clone, Copy)] 1357 #[doc(hidden)] 1358 pub struct Cmap13Marker { 1359 groups_byte_len: usize, 1360 } 1361 1362 impl Cmap13Marker { format_byte_range(&self) -> Range<usize>1363 fn format_byte_range(&self) -> Range<usize> { 1364 let start = 0; 1365 start..start + u16::RAW_BYTE_LEN 1366 } reserved_byte_range(&self) -> Range<usize>1367 fn reserved_byte_range(&self) -> Range<usize> { 1368 let start = self.format_byte_range().end; 1369 start..start + u16::RAW_BYTE_LEN 1370 } length_byte_range(&self) -> Range<usize>1371 fn length_byte_range(&self) -> Range<usize> { 1372 let start = self.reserved_byte_range().end; 1373 start..start + u32::RAW_BYTE_LEN 1374 } language_byte_range(&self) -> Range<usize>1375 fn language_byte_range(&self) -> Range<usize> { 1376 let start = self.length_byte_range().end; 1377 start..start + u32::RAW_BYTE_LEN 1378 } num_groups_byte_range(&self) -> Range<usize>1379 fn num_groups_byte_range(&self) -> Range<usize> { 1380 let start = self.language_byte_range().end; 1381 start..start + u32::RAW_BYTE_LEN 1382 } groups_byte_range(&self) -> Range<usize>1383 fn groups_byte_range(&self) -> Range<usize> { 1384 let start = self.num_groups_byte_range().end; 1385 start..start + self.groups_byte_len 1386 } 1387 } 1388 1389 impl<'a> FontRead<'a> for Cmap13<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1390 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1391 let mut cursor = data.cursor(); 1392 cursor.advance::<u16>(); 1393 cursor.advance::<u16>(); 1394 cursor.advance::<u32>(); 1395 cursor.advance::<u32>(); 1396 let num_groups: u32 = cursor.read()?; 1397 let groups_byte_len = num_groups as usize * ConstantMapGroup::RAW_BYTE_LEN; 1398 cursor.advance_by(groups_byte_len); 1399 cursor.finish(Cmap13Marker { groups_byte_len }) 1400 } 1401 } 1402 1403 /// [cmap Format 13](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-13-many-to-one-range-mappings): Many-to-one range mappings 1404 pub type Cmap13<'a> = TableRef<'a, Cmap13Marker>; 1405 1406 impl<'a> Cmap13<'a> { 1407 /// Subtable format; set to 13. format(&self) -> u161408 pub fn format(&self) -> u16 { 1409 let range = self.shape.format_byte_range(); 1410 self.data.read_at(range.start).unwrap() 1411 } 1412 1413 /// Byte length of this subtable (including the header) length(&self) -> u321414 pub fn length(&self) -> u32 { 1415 let range = self.shape.length_byte_range(); 1416 self.data.read_at(range.start).unwrap() 1417 } 1418 1419 /// For requirements on use of the language field, see “Use of 1420 /// the language field in 'cmap' subtables” in this document. language(&self) -> u321421 pub fn language(&self) -> u32 { 1422 let range = self.shape.language_byte_range(); 1423 self.data.read_at(range.start).unwrap() 1424 } 1425 1426 /// Number of groupings which follow num_groups(&self) -> u321427 pub fn num_groups(&self) -> u32 { 1428 let range = self.shape.num_groups_byte_range(); 1429 self.data.read_at(range.start).unwrap() 1430 } 1431 1432 /// Array of ConstantMapGroup records. groups(&self) -> &'a [ConstantMapGroup]1433 pub fn groups(&self) -> &'a [ConstantMapGroup] { 1434 let range = self.shape.groups_byte_range(); 1435 self.data.read_array(range).unwrap() 1436 } 1437 } 1438 1439 #[cfg(feature = "traversal")] 1440 impl<'a> SomeTable<'a> for Cmap13<'a> { type_name(&self) -> &str1441 fn type_name(&self) -> &str { 1442 "Cmap13" 1443 } get_field(&self, idx: usize) -> Option<Field<'a>>1444 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1445 match idx { 1446 0usize => Some(Field::new("format", self.format())), 1447 1usize => Some(Field::new("length", self.length())), 1448 2usize => Some(Field::new("language", self.language())), 1449 3usize => Some(Field::new("num_groups", self.num_groups())), 1450 4usize => Some(Field::new( 1451 "groups", 1452 traversal::FieldType::array_of_records( 1453 stringify!(ConstantMapGroup), 1454 self.groups(), 1455 self.offset_data(), 1456 ), 1457 )), 1458 _ => None, 1459 } 1460 } 1461 } 1462 1463 #[cfg(feature = "traversal")] 1464 impl<'a> std::fmt::Debug for Cmap13<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1465 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1466 (self as &dyn SomeTable<'a>).fmt(f) 1467 } 1468 } 1469 1470 /// Part of [Cmap13] 1471 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 1472 #[repr(C)] 1473 #[repr(packed)] 1474 pub struct ConstantMapGroup { 1475 /// First character code in this group 1476 pub start_char_code: BigEndian<u32>, 1477 /// Last character code in this group 1478 pub end_char_code: BigEndian<u32>, 1479 /// Glyph index to be used for all the characters in the group’s 1480 /// range. 1481 pub glyph_id: BigEndian<u32>, 1482 } 1483 1484 impl ConstantMapGroup { 1485 /// First character code in this group start_char_code(&self) -> u321486 pub fn start_char_code(&self) -> u32 { 1487 self.start_char_code.get() 1488 } 1489 1490 /// Last character code in this group end_char_code(&self) -> u321491 pub fn end_char_code(&self) -> u32 { 1492 self.end_char_code.get() 1493 } 1494 1495 /// Glyph index to be used for all the characters in the group’s 1496 /// range. glyph_id(&self) -> u321497 pub fn glyph_id(&self) -> u32 { 1498 self.glyph_id.get() 1499 } 1500 } 1501 1502 impl FixedSize for ConstantMapGroup { 1503 const RAW_BYTE_LEN: usize = u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN; 1504 } 1505 1506 impl sealed::Sealed for ConstantMapGroup {} 1507 1508 /// SAFETY: see the [`FromBytes`] trait documentation. 1509 unsafe impl FromBytes for ConstantMapGroup { this_trait_should_only_be_implemented_in_generated_code()1510 fn this_trait_should_only_be_implemented_in_generated_code() {} 1511 } 1512 1513 #[cfg(feature = "traversal")] 1514 impl<'a> SomeRecord<'a> for ConstantMapGroup { traverse(self, data: FontData<'a>) -> RecordResolver<'a>1515 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 1516 RecordResolver { 1517 name: "ConstantMapGroup", 1518 get_field: Box::new(move |idx, _data| match idx { 1519 0usize => Some(Field::new("start_char_code", self.start_char_code())), 1520 1usize => Some(Field::new("end_char_code", self.end_char_code())), 1521 2usize => Some(Field::new("glyph_id", self.glyph_id())), 1522 _ => None, 1523 }), 1524 data, 1525 } 1526 } 1527 } 1528 1529 impl Format<u16> for Cmap14Marker { 1530 const FORMAT: u16 = 14; 1531 } 1532 1533 /// [cmap Format 14](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-14-unicode-variation-sequences): Unicode Variation Sequences 1534 #[derive(Debug, Clone, Copy)] 1535 #[doc(hidden)] 1536 pub struct Cmap14Marker { 1537 var_selector_byte_len: usize, 1538 } 1539 1540 impl Cmap14Marker { format_byte_range(&self) -> Range<usize>1541 fn format_byte_range(&self) -> Range<usize> { 1542 let start = 0; 1543 start..start + u16::RAW_BYTE_LEN 1544 } length_byte_range(&self) -> Range<usize>1545 fn length_byte_range(&self) -> Range<usize> { 1546 let start = self.format_byte_range().end; 1547 start..start + u32::RAW_BYTE_LEN 1548 } num_var_selector_records_byte_range(&self) -> Range<usize>1549 fn num_var_selector_records_byte_range(&self) -> Range<usize> { 1550 let start = self.length_byte_range().end; 1551 start..start + u32::RAW_BYTE_LEN 1552 } var_selector_byte_range(&self) -> Range<usize>1553 fn var_selector_byte_range(&self) -> Range<usize> { 1554 let start = self.num_var_selector_records_byte_range().end; 1555 start..start + self.var_selector_byte_len 1556 } 1557 } 1558 1559 impl<'a> FontRead<'a> for Cmap14<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1560 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1561 let mut cursor = data.cursor(); 1562 cursor.advance::<u16>(); 1563 cursor.advance::<u32>(); 1564 let num_var_selector_records: u32 = cursor.read()?; 1565 let var_selector_byte_len = 1566 num_var_selector_records as usize * VariationSelector::RAW_BYTE_LEN; 1567 cursor.advance_by(var_selector_byte_len); 1568 cursor.finish(Cmap14Marker { 1569 var_selector_byte_len, 1570 }) 1571 } 1572 } 1573 1574 /// [cmap Format 14](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-14-unicode-variation-sequences): Unicode Variation Sequences 1575 pub type Cmap14<'a> = TableRef<'a, Cmap14Marker>; 1576 1577 impl<'a> Cmap14<'a> { 1578 /// Subtable format. Set to 14. format(&self) -> u161579 pub fn format(&self) -> u16 { 1580 let range = self.shape.format_byte_range(); 1581 self.data.read_at(range.start).unwrap() 1582 } 1583 1584 /// Byte length of this subtable (including this header) length(&self) -> u321585 pub fn length(&self) -> u32 { 1586 let range = self.shape.length_byte_range(); 1587 self.data.read_at(range.start).unwrap() 1588 } 1589 1590 /// Number of variation Selector Records num_var_selector_records(&self) -> u321591 pub fn num_var_selector_records(&self) -> u32 { 1592 let range = self.shape.num_var_selector_records_byte_range(); 1593 self.data.read_at(range.start).unwrap() 1594 } 1595 1596 /// Array of VariationSelector records. var_selector(&self) -> &'a [VariationSelector]1597 pub fn var_selector(&self) -> &'a [VariationSelector] { 1598 let range = self.shape.var_selector_byte_range(); 1599 self.data.read_array(range).unwrap() 1600 } 1601 } 1602 1603 #[cfg(feature = "traversal")] 1604 impl<'a> SomeTable<'a> for Cmap14<'a> { type_name(&self) -> &str1605 fn type_name(&self) -> &str { 1606 "Cmap14" 1607 } get_field(&self, idx: usize) -> Option<Field<'a>>1608 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1609 match idx { 1610 0usize => Some(Field::new("format", self.format())), 1611 1usize => Some(Field::new("length", self.length())), 1612 2usize => Some(Field::new( 1613 "num_var_selector_records", 1614 self.num_var_selector_records(), 1615 )), 1616 3usize => Some(Field::new( 1617 "var_selector", 1618 traversal::FieldType::array_of_records( 1619 stringify!(VariationSelector), 1620 self.var_selector(), 1621 self.offset_data(), 1622 ), 1623 )), 1624 _ => None, 1625 } 1626 } 1627 } 1628 1629 #[cfg(feature = "traversal")] 1630 impl<'a> std::fmt::Debug for Cmap14<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1631 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1632 (self as &dyn SomeTable<'a>).fmt(f) 1633 } 1634 } 1635 1636 /// Part of [Cmap14] 1637 #[derive(Clone, Debug)] 1638 #[repr(C)] 1639 #[repr(packed)] 1640 pub struct VariationSelector { 1641 /// Variation selector 1642 pub var_selector: BigEndian<Uint24>, 1643 /// Offset from the start of the [`Cmap14`] subtable to Default UVS 1644 /// Table. May be NULL. 1645 pub default_uvs_offset: BigEndian<Nullable<Offset32>>, 1646 /// Offset from the start of the [`Cmap14`] subtable to Non-Default 1647 /// UVS Table. May be NULL. 1648 pub non_default_uvs_offset: BigEndian<Nullable<Offset32>>, 1649 } 1650 1651 impl VariationSelector { 1652 /// Variation selector var_selector(&self) -> Uint241653 pub fn var_selector(&self) -> Uint24 { 1654 self.var_selector.get() 1655 } 1656 1657 /// Offset from the start of the [`Cmap14`] subtable to Default UVS 1658 /// Table. May be NULL. default_uvs_offset(&self) -> Nullable<Offset32>1659 pub fn default_uvs_offset(&self) -> Nullable<Offset32> { 1660 self.default_uvs_offset.get() 1661 } 1662 1663 /// Offset from the start of the [`Cmap14`] subtable to Default UVS 1664 /// Table. May be NULL. 1665 /// 1666 /// The `data` argument should be retrieved from the parent table 1667 /// By calling its `offset_data` method. default_uvs<'a>(&self, data: FontData<'a>) -> Option<Result<DefaultUvs<'a>, ReadError>>1668 pub fn default_uvs<'a>(&self, data: FontData<'a>) -> Option<Result<DefaultUvs<'a>, ReadError>> { 1669 self.default_uvs_offset().resolve(data) 1670 } 1671 1672 /// Offset from the start of the [`Cmap14`] subtable to Non-Default 1673 /// UVS Table. May be NULL. non_default_uvs_offset(&self) -> Nullable<Offset32>1674 pub fn non_default_uvs_offset(&self) -> Nullable<Offset32> { 1675 self.non_default_uvs_offset.get() 1676 } 1677 1678 /// Offset from the start of the [`Cmap14`] subtable to Non-Default 1679 /// UVS Table. May be NULL. 1680 /// 1681 /// The `data` argument should be retrieved from the parent table 1682 /// By calling its `offset_data` method. non_default_uvs<'a>( &self, data: FontData<'a>, ) -> Option<Result<NonDefaultUvs<'a>, ReadError>>1683 pub fn non_default_uvs<'a>( 1684 &self, 1685 data: FontData<'a>, 1686 ) -> Option<Result<NonDefaultUvs<'a>, ReadError>> { 1687 self.non_default_uvs_offset().resolve(data) 1688 } 1689 } 1690 1691 impl FixedSize for VariationSelector { 1692 const RAW_BYTE_LEN: usize = 1693 Uint24::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN; 1694 } 1695 1696 impl sealed::Sealed for VariationSelector {} 1697 1698 /// SAFETY: see the [`FromBytes`] trait documentation. 1699 unsafe impl FromBytes for VariationSelector { this_trait_should_only_be_implemented_in_generated_code()1700 fn this_trait_should_only_be_implemented_in_generated_code() {} 1701 } 1702 1703 #[cfg(feature = "traversal")] 1704 impl<'a> SomeRecord<'a> for VariationSelector { traverse(self, data: FontData<'a>) -> RecordResolver<'a>1705 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 1706 RecordResolver { 1707 name: "VariationSelector", 1708 get_field: Box::new(move |idx, _data| match idx { 1709 0usize => Some(Field::new("var_selector", self.var_selector())), 1710 1usize => Some(Field::new( 1711 "default_uvs_offset", 1712 FieldType::offset(self.default_uvs_offset(), self.default_uvs(_data)), 1713 )), 1714 2usize => Some(Field::new( 1715 "non_default_uvs_offset", 1716 FieldType::offset(self.non_default_uvs_offset(), self.non_default_uvs(_data)), 1717 )), 1718 _ => None, 1719 }), 1720 data, 1721 } 1722 } 1723 } 1724 1725 /// [Default UVS table](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#default-uvs-table) 1726 #[derive(Debug, Clone, Copy)] 1727 #[doc(hidden)] 1728 pub struct DefaultUvsMarker { 1729 ranges_byte_len: usize, 1730 } 1731 1732 impl DefaultUvsMarker { num_unicode_value_ranges_byte_range(&self) -> Range<usize>1733 fn num_unicode_value_ranges_byte_range(&self) -> Range<usize> { 1734 let start = 0; 1735 start..start + u32::RAW_BYTE_LEN 1736 } ranges_byte_range(&self) -> Range<usize>1737 fn ranges_byte_range(&self) -> Range<usize> { 1738 let start = self.num_unicode_value_ranges_byte_range().end; 1739 start..start + self.ranges_byte_len 1740 } 1741 } 1742 1743 impl<'a> FontRead<'a> for DefaultUvs<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1744 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1745 let mut cursor = data.cursor(); 1746 let num_unicode_value_ranges: u32 = cursor.read()?; 1747 let ranges_byte_len = num_unicode_value_ranges as usize * UnicodeRange::RAW_BYTE_LEN; 1748 cursor.advance_by(ranges_byte_len); 1749 cursor.finish(DefaultUvsMarker { ranges_byte_len }) 1750 } 1751 } 1752 1753 /// [Default UVS table](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#default-uvs-table) 1754 pub type DefaultUvs<'a> = TableRef<'a, DefaultUvsMarker>; 1755 1756 impl<'a> DefaultUvs<'a> { 1757 /// Number of Unicode character ranges. num_unicode_value_ranges(&self) -> u321758 pub fn num_unicode_value_ranges(&self) -> u32 { 1759 let range = self.shape.num_unicode_value_ranges_byte_range(); 1760 self.data.read_at(range.start).unwrap() 1761 } 1762 1763 /// Array of UnicodeRange records. ranges(&self) -> &'a [UnicodeRange]1764 pub fn ranges(&self) -> &'a [UnicodeRange] { 1765 let range = self.shape.ranges_byte_range(); 1766 self.data.read_array(range).unwrap() 1767 } 1768 } 1769 1770 #[cfg(feature = "traversal")] 1771 impl<'a> SomeTable<'a> for DefaultUvs<'a> { type_name(&self) -> &str1772 fn type_name(&self) -> &str { 1773 "DefaultUvs" 1774 } get_field(&self, idx: usize) -> Option<Field<'a>>1775 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1776 match idx { 1777 0usize => Some(Field::new( 1778 "num_unicode_value_ranges", 1779 self.num_unicode_value_ranges(), 1780 )), 1781 1usize => Some(Field::new( 1782 "ranges", 1783 traversal::FieldType::array_of_records( 1784 stringify!(UnicodeRange), 1785 self.ranges(), 1786 self.offset_data(), 1787 ), 1788 )), 1789 _ => None, 1790 } 1791 } 1792 } 1793 1794 #[cfg(feature = "traversal")] 1795 impl<'a> std::fmt::Debug for DefaultUvs<'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 /// [Non-Default UVS table](https://learn.microsoft.com/en-us/typography/opentype/spec/cmap#non-default-uvs-table) 1802 #[derive(Debug, Clone, Copy)] 1803 #[doc(hidden)] 1804 pub struct NonDefaultUvsMarker { 1805 uvs_mapping_byte_len: usize, 1806 } 1807 1808 impl NonDefaultUvsMarker { num_uvs_mappings_byte_range(&self) -> Range<usize>1809 fn num_uvs_mappings_byte_range(&self) -> Range<usize> { 1810 let start = 0; 1811 start..start + u32::RAW_BYTE_LEN 1812 } uvs_mapping_byte_range(&self) -> Range<usize>1813 fn uvs_mapping_byte_range(&self) -> Range<usize> { 1814 let start = self.num_uvs_mappings_byte_range().end; 1815 start..start + self.uvs_mapping_byte_len 1816 } 1817 } 1818 1819 impl<'a> FontRead<'a> for NonDefaultUvs<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1820 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1821 let mut cursor = data.cursor(); 1822 let num_uvs_mappings: u32 = cursor.read()?; 1823 let uvs_mapping_byte_len = num_uvs_mappings as usize * UvsMapping::RAW_BYTE_LEN; 1824 cursor.advance_by(uvs_mapping_byte_len); 1825 cursor.finish(NonDefaultUvsMarker { 1826 uvs_mapping_byte_len, 1827 }) 1828 } 1829 } 1830 1831 /// [Non-Default UVS table](https://learn.microsoft.com/en-us/typography/opentype/spec/cmap#non-default-uvs-table) 1832 pub type NonDefaultUvs<'a> = TableRef<'a, NonDefaultUvsMarker>; 1833 1834 impl<'a> NonDefaultUvs<'a> { num_uvs_mappings(&self) -> u321835 pub fn num_uvs_mappings(&self) -> u32 { 1836 let range = self.shape.num_uvs_mappings_byte_range(); 1837 self.data.read_at(range.start).unwrap() 1838 } 1839 uvs_mapping(&self) -> &'a [UvsMapping]1840 pub fn uvs_mapping(&self) -> &'a [UvsMapping] { 1841 let range = self.shape.uvs_mapping_byte_range(); 1842 self.data.read_array(range).unwrap() 1843 } 1844 } 1845 1846 #[cfg(feature = "traversal")] 1847 impl<'a> SomeTable<'a> for NonDefaultUvs<'a> { type_name(&self) -> &str1848 fn type_name(&self) -> &str { 1849 "NonDefaultUvs" 1850 } get_field(&self, idx: usize) -> Option<Field<'a>>1851 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1852 match idx { 1853 0usize => Some(Field::new("num_uvs_mappings", self.num_uvs_mappings())), 1854 1usize => Some(Field::new( 1855 "uvs_mapping", 1856 traversal::FieldType::array_of_records( 1857 stringify!(UvsMapping), 1858 self.uvs_mapping(), 1859 self.offset_data(), 1860 ), 1861 )), 1862 _ => None, 1863 } 1864 } 1865 } 1866 1867 #[cfg(feature = "traversal")] 1868 impl<'a> std::fmt::Debug for NonDefaultUvs<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1869 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1870 (self as &dyn SomeTable<'a>).fmt(f) 1871 } 1872 } 1873 1874 /// Part of [Cmap14] 1875 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 1876 #[repr(C)] 1877 #[repr(packed)] 1878 pub struct UvsMapping { 1879 /// Base Unicode value of the UVS 1880 pub unicode_value: BigEndian<Uint24>, 1881 /// Glyph ID of the UVS 1882 pub glyph_id: BigEndian<u16>, 1883 } 1884 1885 impl UvsMapping { 1886 /// Base Unicode value of the UVS unicode_value(&self) -> Uint241887 pub fn unicode_value(&self) -> Uint24 { 1888 self.unicode_value.get() 1889 } 1890 1891 /// Glyph ID of the UVS glyph_id(&self) -> u161892 pub fn glyph_id(&self) -> u16 { 1893 self.glyph_id.get() 1894 } 1895 } 1896 1897 impl FixedSize for UvsMapping { 1898 const RAW_BYTE_LEN: usize = Uint24::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; 1899 } 1900 1901 impl sealed::Sealed for UvsMapping {} 1902 1903 /// SAFETY: see the [`FromBytes`] trait documentation. 1904 unsafe impl FromBytes for UvsMapping { this_trait_should_only_be_implemented_in_generated_code()1905 fn this_trait_should_only_be_implemented_in_generated_code() {} 1906 } 1907 1908 #[cfg(feature = "traversal")] 1909 impl<'a> SomeRecord<'a> for UvsMapping { traverse(self, data: FontData<'a>) -> RecordResolver<'a>1910 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 1911 RecordResolver { 1912 name: "UvsMapping", 1913 get_field: Box::new(move |idx, _data| match idx { 1914 0usize => Some(Field::new("unicode_value", self.unicode_value())), 1915 1usize => Some(Field::new("glyph_id", self.glyph_id())), 1916 _ => None, 1917 }), 1918 data, 1919 } 1920 } 1921 } 1922 1923 /// Part of [Cmap14] 1924 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 1925 #[repr(C)] 1926 #[repr(packed)] 1927 pub struct UnicodeRange { 1928 /// First value in this range 1929 pub start_unicode_value: BigEndian<Uint24>, 1930 /// Number of additional values in this range 1931 pub additional_count: u8, 1932 } 1933 1934 impl UnicodeRange { 1935 /// First value in this range start_unicode_value(&self) -> Uint241936 pub fn start_unicode_value(&self) -> Uint24 { 1937 self.start_unicode_value.get() 1938 } 1939 1940 /// Number of additional values in this range additional_count(&self) -> u81941 pub fn additional_count(&self) -> u8 { 1942 self.additional_count 1943 } 1944 } 1945 1946 impl FixedSize for UnicodeRange { 1947 const RAW_BYTE_LEN: usize = Uint24::RAW_BYTE_LEN + u8::RAW_BYTE_LEN; 1948 } 1949 1950 impl sealed::Sealed for UnicodeRange {} 1951 1952 /// SAFETY: see the [`FromBytes`] trait documentation. 1953 unsafe impl FromBytes for UnicodeRange { this_trait_should_only_be_implemented_in_generated_code()1954 fn this_trait_should_only_be_implemented_in_generated_code() {} 1955 } 1956 1957 #[cfg(feature = "traversal")] 1958 impl<'a> SomeRecord<'a> for UnicodeRange { traverse(self, data: FontData<'a>) -> RecordResolver<'a>1959 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 1960 RecordResolver { 1961 name: "UnicodeRange", 1962 get_field: Box::new(move |idx, _data| match idx { 1963 0usize => Some(Field::new( 1964 "start_unicode_value", 1965 self.start_unicode_value(), 1966 )), 1967 1usize => Some(Field::new("additional_count", self.additional_count())), 1968 _ => None, 1969 }), 1970 data, 1971 } 1972 } 1973 } 1974