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 /// [GDEF](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#gdef-header) 1.0 9 #[derive(Debug, Clone, Copy)] 10 #[doc(hidden)] 11 pub struct GdefMarker { 12 mark_glyph_sets_def_offset_byte_start: Option<usize>, 13 item_var_store_offset_byte_start: Option<usize>, 14 } 15 16 impl GdefMarker { version_byte_range(&self) -> Range<usize>17 fn version_byte_range(&self) -> Range<usize> { 18 let start = 0; 19 start..start + MajorMinor::RAW_BYTE_LEN 20 } glyph_class_def_offset_byte_range(&self) -> Range<usize>21 fn glyph_class_def_offset_byte_range(&self) -> Range<usize> { 22 let start = self.version_byte_range().end; 23 start..start + Offset16::RAW_BYTE_LEN 24 } attach_list_offset_byte_range(&self) -> Range<usize>25 fn attach_list_offset_byte_range(&self) -> Range<usize> { 26 let start = self.glyph_class_def_offset_byte_range().end; 27 start..start + Offset16::RAW_BYTE_LEN 28 } lig_caret_list_offset_byte_range(&self) -> Range<usize>29 fn lig_caret_list_offset_byte_range(&self) -> Range<usize> { 30 let start = self.attach_list_offset_byte_range().end; 31 start..start + Offset16::RAW_BYTE_LEN 32 } mark_attach_class_def_offset_byte_range(&self) -> Range<usize>33 fn mark_attach_class_def_offset_byte_range(&self) -> Range<usize> { 34 let start = self.lig_caret_list_offset_byte_range().end; 35 start..start + Offset16::RAW_BYTE_LEN 36 } mark_glyph_sets_def_offset_byte_range(&self) -> Option<Range<usize>>37 fn mark_glyph_sets_def_offset_byte_range(&self) -> Option<Range<usize>> { 38 let start = self.mark_glyph_sets_def_offset_byte_start?; 39 Some(start..start + Offset16::RAW_BYTE_LEN) 40 } item_var_store_offset_byte_range(&self) -> Option<Range<usize>>41 fn item_var_store_offset_byte_range(&self) -> Option<Range<usize>> { 42 let start = self.item_var_store_offset_byte_start?; 43 Some(start..start + Offset32::RAW_BYTE_LEN) 44 } 45 } 46 47 impl TopLevelTable for Gdef<'_> { 48 /// `GDEF` 49 const TAG: Tag = Tag::new(b"GDEF"); 50 } 51 52 impl<'a> FontRead<'a> for Gdef<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>53 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 54 let mut cursor = data.cursor(); 55 let version: MajorMinor = cursor.read()?; 56 cursor.advance::<Offset16>(); 57 cursor.advance::<Offset16>(); 58 cursor.advance::<Offset16>(); 59 cursor.advance::<Offset16>(); 60 let mark_glyph_sets_def_offset_byte_start = version 61 .compatible((1, 2)) 62 .then(|| cursor.position()) 63 .transpose()?; 64 version 65 .compatible((1, 2)) 66 .then(|| cursor.advance::<Offset16>()); 67 let item_var_store_offset_byte_start = version 68 .compatible((1, 3)) 69 .then(|| cursor.position()) 70 .transpose()?; 71 version 72 .compatible((1, 3)) 73 .then(|| cursor.advance::<Offset32>()); 74 cursor.finish(GdefMarker { 75 mark_glyph_sets_def_offset_byte_start, 76 item_var_store_offset_byte_start, 77 }) 78 } 79 } 80 81 /// [GDEF](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#gdef-header) 1.0 82 pub type Gdef<'a> = TableRef<'a, GdefMarker>; 83 84 impl<'a> Gdef<'a> { 85 /// The major/minor version of the GDEF table version(&self) -> MajorMinor86 pub fn version(&self) -> MajorMinor { 87 let range = self.shape.version_byte_range(); 88 self.data.read_at(range.start).unwrap() 89 } 90 91 /// Offset to class definition table for glyph type, from beginning 92 /// of GDEF header (may be NULL) glyph_class_def_offset(&self) -> Nullable<Offset16>93 pub fn glyph_class_def_offset(&self) -> Nullable<Offset16> { 94 let range = self.shape.glyph_class_def_offset_byte_range(); 95 self.data.read_at(range.start).unwrap() 96 } 97 98 /// Attempt to resolve [`glyph_class_def_offset`][Self::glyph_class_def_offset]. glyph_class_def(&self) -> Option<Result<ClassDef<'a>, ReadError>>99 pub fn glyph_class_def(&self) -> Option<Result<ClassDef<'a>, ReadError>> { 100 let data = self.data; 101 self.glyph_class_def_offset().resolve(data) 102 } 103 104 /// Offset to attachment point list table, from beginning of GDEF 105 /// header (may be NULL) attach_list_offset(&self) -> Nullable<Offset16>106 pub fn attach_list_offset(&self) -> Nullable<Offset16> { 107 let range = self.shape.attach_list_offset_byte_range(); 108 self.data.read_at(range.start).unwrap() 109 } 110 111 /// Attempt to resolve [`attach_list_offset`][Self::attach_list_offset]. attach_list(&self) -> Option<Result<AttachList<'a>, ReadError>>112 pub fn attach_list(&self) -> Option<Result<AttachList<'a>, ReadError>> { 113 let data = self.data; 114 self.attach_list_offset().resolve(data) 115 } 116 117 /// Offset to ligature caret list table, from beginning of GDEF 118 /// header (may be NULL) lig_caret_list_offset(&self) -> Nullable<Offset16>119 pub fn lig_caret_list_offset(&self) -> Nullable<Offset16> { 120 let range = self.shape.lig_caret_list_offset_byte_range(); 121 self.data.read_at(range.start).unwrap() 122 } 123 124 /// Attempt to resolve [`lig_caret_list_offset`][Self::lig_caret_list_offset]. lig_caret_list(&self) -> Option<Result<LigCaretList<'a>, ReadError>>125 pub fn lig_caret_list(&self) -> Option<Result<LigCaretList<'a>, ReadError>> { 126 let data = self.data; 127 self.lig_caret_list_offset().resolve(data) 128 } 129 130 /// Offset to class definition table for mark attachment type, from 131 /// beginning of GDEF header (may be NULL) mark_attach_class_def_offset(&self) -> Nullable<Offset16>132 pub fn mark_attach_class_def_offset(&self) -> Nullable<Offset16> { 133 let range = self.shape.mark_attach_class_def_offset_byte_range(); 134 self.data.read_at(range.start).unwrap() 135 } 136 137 /// Attempt to resolve [`mark_attach_class_def_offset`][Self::mark_attach_class_def_offset]. mark_attach_class_def(&self) -> Option<Result<ClassDef<'a>, ReadError>>138 pub fn mark_attach_class_def(&self) -> Option<Result<ClassDef<'a>, ReadError>> { 139 let data = self.data; 140 self.mark_attach_class_def_offset().resolve(data) 141 } 142 143 /// Offset to the table of mark glyph set definitions, from 144 /// beginning of GDEF header (may be NULL) mark_glyph_sets_def_offset(&self) -> Option<Nullable<Offset16>>145 pub fn mark_glyph_sets_def_offset(&self) -> Option<Nullable<Offset16>> { 146 let range = self.shape.mark_glyph_sets_def_offset_byte_range()?; 147 Some(self.data.read_at(range.start).unwrap()) 148 } 149 150 /// Attempt to resolve [`mark_glyph_sets_def_offset`][Self::mark_glyph_sets_def_offset]. mark_glyph_sets_def(&self) -> Option<Result<MarkGlyphSets<'a>, ReadError>>151 pub fn mark_glyph_sets_def(&self) -> Option<Result<MarkGlyphSets<'a>, ReadError>> { 152 let data = self.data; 153 self.mark_glyph_sets_def_offset().map(|x| x.resolve(data))? 154 } 155 156 /// Offset to the Item Variation Store table, from beginning of 157 /// GDEF header (may be NULL) item_var_store_offset(&self) -> Option<Nullable<Offset32>>158 pub fn item_var_store_offset(&self) -> Option<Nullable<Offset32>> { 159 let range = self.shape.item_var_store_offset_byte_range()?; 160 Some(self.data.read_at(range.start).unwrap()) 161 } 162 163 /// Attempt to resolve [`item_var_store_offset`][Self::item_var_store_offset]. item_var_store(&self) -> Option<Result<ItemVariationStore<'a>, ReadError>>164 pub fn item_var_store(&self) -> Option<Result<ItemVariationStore<'a>, ReadError>> { 165 let data = self.data; 166 self.item_var_store_offset().map(|x| x.resolve(data))? 167 } 168 } 169 170 #[cfg(feature = "traversal")] 171 impl<'a> SomeTable<'a> for Gdef<'a> { type_name(&self) -> &str172 fn type_name(&self) -> &str { 173 "Gdef" 174 } get_field(&self, idx: usize) -> Option<Field<'a>>175 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 176 let version = self.version(); 177 match idx { 178 0usize => Some(Field::new("version", self.version())), 179 1usize => Some(Field::new( 180 "glyph_class_def_offset", 181 FieldType::offset(self.glyph_class_def_offset(), self.glyph_class_def()), 182 )), 183 2usize => Some(Field::new( 184 "attach_list_offset", 185 FieldType::offset(self.attach_list_offset(), self.attach_list()), 186 )), 187 3usize => Some(Field::new( 188 "lig_caret_list_offset", 189 FieldType::offset(self.lig_caret_list_offset(), self.lig_caret_list()), 190 )), 191 4usize => Some(Field::new( 192 "mark_attach_class_def_offset", 193 FieldType::offset( 194 self.mark_attach_class_def_offset(), 195 self.mark_attach_class_def(), 196 ), 197 )), 198 5usize if version.compatible((1, 2)) => Some(Field::new( 199 "mark_glyph_sets_def_offset", 200 FieldType::offset( 201 self.mark_glyph_sets_def_offset().unwrap(), 202 self.mark_glyph_sets_def().unwrap(), 203 ), 204 )), 205 6usize if version.compatible((1, 3)) => Some(Field::new( 206 "item_var_store_offset", 207 FieldType::offset( 208 self.item_var_store_offset().unwrap(), 209 self.item_var_store().unwrap(), 210 ), 211 )), 212 _ => None, 213 } 214 } 215 } 216 217 #[cfg(feature = "traversal")] 218 impl<'a> std::fmt::Debug for Gdef<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result219 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 220 (self as &dyn SomeTable<'a>).fmt(f) 221 } 222 } 223 224 /// Used in the [Glyph Class Definition Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#glyph-class-definition-table) 225 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] 226 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 227 #[repr(u16)] 228 #[allow(clippy::manual_non_exhaustive)] 229 pub enum GlyphClassDef { 230 #[default] 231 Base = 1, 232 Ligature = 2, 233 Mark = 3, 234 Component = 4, 235 #[doc(hidden)] 236 /// If font data is malformed we will map unknown values to this variant 237 Unknown, 238 } 239 240 impl GlyphClassDef { 241 /// Create from a raw scalar. 242 /// 243 /// This will never fail; unknown values will be mapped to the `Unknown` variant new(raw: u16) -> Self244 pub fn new(raw: u16) -> Self { 245 match raw { 246 1 => Self::Base, 247 2 => Self::Ligature, 248 3 => Self::Mark, 249 4 => Self::Component, 250 _ => Self::Unknown, 251 } 252 } 253 } 254 255 impl font_types::Scalar for GlyphClassDef { 256 type Raw = <u16 as font_types::Scalar>::Raw; to_raw(self) -> Self::Raw257 fn to_raw(self) -> Self::Raw { 258 (self as u16).to_raw() 259 } from_raw(raw: Self::Raw) -> Self260 fn from_raw(raw: Self::Raw) -> Self { 261 let t = <u16>::from_raw(raw); 262 Self::new(t) 263 } 264 } 265 266 #[cfg(feature = "traversal")] 267 impl<'a> From<GlyphClassDef> for FieldType<'a> { from(src: GlyphClassDef) -> FieldType<'a>268 fn from(src: GlyphClassDef) -> FieldType<'a> { 269 (src as u16).into() 270 } 271 } 272 273 /// [Attachment Point List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#attachment-point-list-table) 274 #[derive(Debug, Clone, Copy)] 275 #[doc(hidden)] 276 pub struct AttachListMarker { 277 attach_point_offsets_byte_len: usize, 278 } 279 280 impl AttachListMarker { coverage_offset_byte_range(&self) -> Range<usize>281 fn coverage_offset_byte_range(&self) -> Range<usize> { 282 let start = 0; 283 start..start + Offset16::RAW_BYTE_LEN 284 } glyph_count_byte_range(&self) -> Range<usize>285 fn glyph_count_byte_range(&self) -> Range<usize> { 286 let start = self.coverage_offset_byte_range().end; 287 start..start + u16::RAW_BYTE_LEN 288 } attach_point_offsets_byte_range(&self) -> Range<usize>289 fn attach_point_offsets_byte_range(&self) -> Range<usize> { 290 let start = self.glyph_count_byte_range().end; 291 start..start + self.attach_point_offsets_byte_len 292 } 293 } 294 295 impl<'a> FontRead<'a> for AttachList<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>296 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 297 let mut cursor = data.cursor(); 298 cursor.advance::<Offset16>(); 299 let glyph_count: u16 = cursor.read()?; 300 let attach_point_offsets_byte_len = glyph_count as usize * Offset16::RAW_BYTE_LEN; 301 cursor.advance_by(attach_point_offsets_byte_len); 302 cursor.finish(AttachListMarker { 303 attach_point_offsets_byte_len, 304 }) 305 } 306 } 307 308 /// [Attachment Point List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#attachment-point-list-table) 309 pub type AttachList<'a> = TableRef<'a, AttachListMarker>; 310 311 impl<'a> AttachList<'a> { 312 /// Offset to Coverage table - from beginning of AttachList table coverage_offset(&self) -> Offset16313 pub fn coverage_offset(&self) -> Offset16 { 314 let range = self.shape.coverage_offset_byte_range(); 315 self.data.read_at(range.start).unwrap() 316 } 317 318 /// Attempt to resolve [`coverage_offset`][Self::coverage_offset]. coverage(&self) -> Result<CoverageTable<'a>, ReadError>319 pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> { 320 let data = self.data; 321 self.coverage_offset().resolve(data) 322 } 323 324 /// Number of glyphs with attachment points glyph_count(&self) -> u16325 pub fn glyph_count(&self) -> u16 { 326 let range = self.shape.glyph_count_byte_range(); 327 self.data.read_at(range.start).unwrap() 328 } 329 330 /// Array of offsets to AttachPoint tables-from beginning of 331 /// AttachList table-in Coverage Index order attach_point_offsets(&self) -> &'a [BigEndian<Offset16>]332 pub fn attach_point_offsets(&self) -> &'a [BigEndian<Offset16>] { 333 let range = self.shape.attach_point_offsets_byte_range(); 334 self.data.read_array(range).unwrap() 335 } 336 337 /// A dynamically resolving wrapper for [`attach_point_offsets`][Self::attach_point_offsets]. attach_points(&self) -> ArrayOfOffsets<'a, AttachPoint<'a>, Offset16>338 pub fn attach_points(&self) -> ArrayOfOffsets<'a, AttachPoint<'a>, Offset16> { 339 let data = self.data; 340 let offsets = self.attach_point_offsets(); 341 ArrayOfOffsets::new(offsets, data, ()) 342 } 343 } 344 345 #[cfg(feature = "traversal")] 346 impl<'a> SomeTable<'a> for AttachList<'a> { type_name(&self) -> &str347 fn type_name(&self) -> &str { 348 "AttachList" 349 } get_field(&self, idx: usize) -> Option<Field<'a>>350 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 351 match idx { 352 0usize => Some(Field::new( 353 "coverage_offset", 354 FieldType::offset(self.coverage_offset(), self.coverage()), 355 )), 356 1usize => Some(Field::new("glyph_count", self.glyph_count())), 357 2usize => Some({ 358 let data = self.data; 359 Field::new( 360 "attach_point_offsets", 361 FieldType::array_of_offsets( 362 better_type_name::<AttachPoint>(), 363 self.attach_point_offsets(), 364 move |off| { 365 let target = off.get().resolve::<AttachPoint>(data); 366 FieldType::offset(off.get(), target) 367 }, 368 ), 369 ) 370 }), 371 _ => None, 372 } 373 } 374 } 375 376 #[cfg(feature = "traversal")] 377 impl<'a> std::fmt::Debug for AttachList<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result378 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 379 (self as &dyn SomeTable<'a>).fmt(f) 380 } 381 } 382 383 /// Part of [AttachList] 384 #[derive(Debug, Clone, Copy)] 385 #[doc(hidden)] 386 pub struct AttachPointMarker { 387 point_indices_byte_len: usize, 388 } 389 390 impl AttachPointMarker { point_count_byte_range(&self) -> Range<usize>391 fn point_count_byte_range(&self) -> Range<usize> { 392 let start = 0; 393 start..start + u16::RAW_BYTE_LEN 394 } point_indices_byte_range(&self) -> Range<usize>395 fn point_indices_byte_range(&self) -> Range<usize> { 396 let start = self.point_count_byte_range().end; 397 start..start + self.point_indices_byte_len 398 } 399 } 400 401 impl<'a> FontRead<'a> for AttachPoint<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>402 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 403 let mut cursor = data.cursor(); 404 let point_count: u16 = cursor.read()?; 405 let point_indices_byte_len = point_count as usize * u16::RAW_BYTE_LEN; 406 cursor.advance_by(point_indices_byte_len); 407 cursor.finish(AttachPointMarker { 408 point_indices_byte_len, 409 }) 410 } 411 } 412 413 /// Part of [AttachList] 414 pub type AttachPoint<'a> = TableRef<'a, AttachPointMarker>; 415 416 impl<'a> AttachPoint<'a> { 417 /// Number of attachment points on this glyph point_count(&self) -> u16418 pub fn point_count(&self) -> u16 { 419 let range = self.shape.point_count_byte_range(); 420 self.data.read_at(range.start).unwrap() 421 } 422 423 /// Array of contour point indices -in increasing numerical order point_indices(&self) -> &'a [BigEndian<u16>]424 pub fn point_indices(&self) -> &'a [BigEndian<u16>] { 425 let range = self.shape.point_indices_byte_range(); 426 self.data.read_array(range).unwrap() 427 } 428 } 429 430 #[cfg(feature = "traversal")] 431 impl<'a> SomeTable<'a> for AttachPoint<'a> { type_name(&self) -> &str432 fn type_name(&self) -> &str { 433 "AttachPoint" 434 } get_field(&self, idx: usize) -> Option<Field<'a>>435 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 436 match idx { 437 0usize => Some(Field::new("point_count", self.point_count())), 438 1usize => Some(Field::new("point_indices", self.point_indices())), 439 _ => None, 440 } 441 } 442 } 443 444 #[cfg(feature = "traversal")] 445 impl<'a> std::fmt::Debug for AttachPoint<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result446 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 447 (self as &dyn SomeTable<'a>).fmt(f) 448 } 449 } 450 451 /// [Ligature Caret List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#ligature-caret-list-table) 452 #[derive(Debug, Clone, Copy)] 453 #[doc(hidden)] 454 pub struct LigCaretListMarker { 455 lig_glyph_offsets_byte_len: usize, 456 } 457 458 impl LigCaretListMarker { coverage_offset_byte_range(&self) -> Range<usize>459 fn coverage_offset_byte_range(&self) -> Range<usize> { 460 let start = 0; 461 start..start + Offset16::RAW_BYTE_LEN 462 } lig_glyph_count_byte_range(&self) -> Range<usize>463 fn lig_glyph_count_byte_range(&self) -> Range<usize> { 464 let start = self.coverage_offset_byte_range().end; 465 start..start + u16::RAW_BYTE_LEN 466 } lig_glyph_offsets_byte_range(&self) -> Range<usize>467 fn lig_glyph_offsets_byte_range(&self) -> Range<usize> { 468 let start = self.lig_glyph_count_byte_range().end; 469 start..start + self.lig_glyph_offsets_byte_len 470 } 471 } 472 473 impl<'a> FontRead<'a> for LigCaretList<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>474 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 475 let mut cursor = data.cursor(); 476 cursor.advance::<Offset16>(); 477 let lig_glyph_count: u16 = cursor.read()?; 478 let lig_glyph_offsets_byte_len = lig_glyph_count as usize * Offset16::RAW_BYTE_LEN; 479 cursor.advance_by(lig_glyph_offsets_byte_len); 480 cursor.finish(LigCaretListMarker { 481 lig_glyph_offsets_byte_len, 482 }) 483 } 484 } 485 486 /// [Ligature Caret List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#ligature-caret-list-table) 487 pub type LigCaretList<'a> = TableRef<'a, LigCaretListMarker>; 488 489 impl<'a> LigCaretList<'a> { 490 /// Offset to Coverage table - from beginning of LigCaretList table coverage_offset(&self) -> Offset16491 pub fn coverage_offset(&self) -> Offset16 { 492 let range = self.shape.coverage_offset_byte_range(); 493 self.data.read_at(range.start).unwrap() 494 } 495 496 /// Attempt to resolve [`coverage_offset`][Self::coverage_offset]. coverage(&self) -> Result<CoverageTable<'a>, ReadError>497 pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> { 498 let data = self.data; 499 self.coverage_offset().resolve(data) 500 } 501 502 /// Number of ligature glyphs lig_glyph_count(&self) -> u16503 pub fn lig_glyph_count(&self) -> u16 { 504 let range = self.shape.lig_glyph_count_byte_range(); 505 self.data.read_at(range.start).unwrap() 506 } 507 508 /// Array of offsets to LigGlyph tables, from beginning of 509 /// LigCaretList table —in Coverage Index order lig_glyph_offsets(&self) -> &'a [BigEndian<Offset16>]510 pub fn lig_glyph_offsets(&self) -> &'a [BigEndian<Offset16>] { 511 let range = self.shape.lig_glyph_offsets_byte_range(); 512 self.data.read_array(range).unwrap() 513 } 514 515 /// A dynamically resolving wrapper for [`lig_glyph_offsets`][Self::lig_glyph_offsets]. lig_glyphs(&self) -> ArrayOfOffsets<'a, LigGlyph<'a>, Offset16>516 pub fn lig_glyphs(&self) -> ArrayOfOffsets<'a, LigGlyph<'a>, Offset16> { 517 let data = self.data; 518 let offsets = self.lig_glyph_offsets(); 519 ArrayOfOffsets::new(offsets, data, ()) 520 } 521 } 522 523 #[cfg(feature = "traversal")] 524 impl<'a> SomeTable<'a> for LigCaretList<'a> { type_name(&self) -> &str525 fn type_name(&self) -> &str { 526 "LigCaretList" 527 } get_field(&self, idx: usize) -> Option<Field<'a>>528 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 529 match idx { 530 0usize => Some(Field::new( 531 "coverage_offset", 532 FieldType::offset(self.coverage_offset(), self.coverage()), 533 )), 534 1usize => Some(Field::new("lig_glyph_count", self.lig_glyph_count())), 535 2usize => Some({ 536 let data = self.data; 537 Field::new( 538 "lig_glyph_offsets", 539 FieldType::array_of_offsets( 540 better_type_name::<LigGlyph>(), 541 self.lig_glyph_offsets(), 542 move |off| { 543 let target = off.get().resolve::<LigGlyph>(data); 544 FieldType::offset(off.get(), target) 545 }, 546 ), 547 ) 548 }), 549 _ => None, 550 } 551 } 552 } 553 554 #[cfg(feature = "traversal")] 555 impl<'a> std::fmt::Debug for LigCaretList<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result556 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 557 (self as &dyn SomeTable<'a>).fmt(f) 558 } 559 } 560 561 /// [Ligature Glyph Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#ligature-glyph-table) 562 #[derive(Debug, Clone, Copy)] 563 #[doc(hidden)] 564 pub struct LigGlyphMarker { 565 caret_value_offsets_byte_len: usize, 566 } 567 568 impl LigGlyphMarker { caret_count_byte_range(&self) -> Range<usize>569 fn caret_count_byte_range(&self) -> Range<usize> { 570 let start = 0; 571 start..start + u16::RAW_BYTE_LEN 572 } caret_value_offsets_byte_range(&self) -> Range<usize>573 fn caret_value_offsets_byte_range(&self) -> Range<usize> { 574 let start = self.caret_count_byte_range().end; 575 start..start + self.caret_value_offsets_byte_len 576 } 577 } 578 579 impl<'a> FontRead<'a> for LigGlyph<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>580 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 581 let mut cursor = data.cursor(); 582 let caret_count: u16 = cursor.read()?; 583 let caret_value_offsets_byte_len = caret_count as usize * Offset16::RAW_BYTE_LEN; 584 cursor.advance_by(caret_value_offsets_byte_len); 585 cursor.finish(LigGlyphMarker { 586 caret_value_offsets_byte_len, 587 }) 588 } 589 } 590 591 /// [Ligature Glyph Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#ligature-glyph-table) 592 pub type LigGlyph<'a> = TableRef<'a, LigGlyphMarker>; 593 594 impl<'a> LigGlyph<'a> { 595 /// Number of CaretValue tables for this ligature (components - 1) caret_count(&self) -> u16596 pub fn caret_count(&self) -> u16 { 597 let range = self.shape.caret_count_byte_range(); 598 self.data.read_at(range.start).unwrap() 599 } 600 601 /// Array of offsets to CaretValue tables, from beginning of 602 /// LigGlyph table — in increasing coordinate order caret_value_offsets(&self) -> &'a [BigEndian<Offset16>]603 pub fn caret_value_offsets(&self) -> &'a [BigEndian<Offset16>] { 604 let range = self.shape.caret_value_offsets_byte_range(); 605 self.data.read_array(range).unwrap() 606 } 607 608 /// A dynamically resolving wrapper for [`caret_value_offsets`][Self::caret_value_offsets]. caret_values(&self) -> ArrayOfOffsets<'a, CaretValue<'a>, Offset16>609 pub fn caret_values(&self) -> ArrayOfOffsets<'a, CaretValue<'a>, Offset16> { 610 let data = self.data; 611 let offsets = self.caret_value_offsets(); 612 ArrayOfOffsets::new(offsets, data, ()) 613 } 614 } 615 616 #[cfg(feature = "traversal")] 617 impl<'a> SomeTable<'a> for LigGlyph<'a> { type_name(&self) -> &str618 fn type_name(&self) -> &str { 619 "LigGlyph" 620 } get_field(&self, idx: usize) -> Option<Field<'a>>621 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 622 match idx { 623 0usize => Some(Field::new("caret_count", self.caret_count())), 624 1usize => Some({ 625 let data = self.data; 626 Field::new( 627 "caret_value_offsets", 628 FieldType::array_of_offsets( 629 better_type_name::<CaretValue>(), 630 self.caret_value_offsets(), 631 move |off| { 632 let target = off.get().resolve::<CaretValue>(data); 633 FieldType::offset(off.get(), target) 634 }, 635 ), 636 ) 637 }), 638 _ => None, 639 } 640 } 641 } 642 643 #[cfg(feature = "traversal")] 644 impl<'a> std::fmt::Debug for LigGlyph<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result645 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 646 (self as &dyn SomeTable<'a>).fmt(f) 647 } 648 } 649 650 /// [Caret Value Tables](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#caret-value-tables) 651 #[derive(Clone)] 652 pub enum CaretValue<'a> { 653 Format1(CaretValueFormat1<'a>), 654 Format2(CaretValueFormat2<'a>), 655 Format3(CaretValueFormat3<'a>), 656 } 657 658 impl<'a> CaretValue<'a> { 659 /// Format identifier: format = 1 caret_value_format(&self) -> u16660 pub fn caret_value_format(&self) -> u16 { 661 match self { 662 Self::Format1(item) => item.caret_value_format(), 663 Self::Format2(item) => item.caret_value_format(), 664 Self::Format3(item) => item.caret_value_format(), 665 } 666 } 667 } 668 669 impl<'a> FontRead<'a> for CaretValue<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>670 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 671 let format: u16 = data.read_at(0usize)?; 672 match format { 673 CaretValueFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)), 674 CaretValueFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)), 675 CaretValueFormat3Marker::FORMAT => Ok(Self::Format3(FontRead::read(data)?)), 676 other => Err(ReadError::InvalidFormat(other.into())), 677 } 678 } 679 } 680 681 #[cfg(feature = "traversal")] 682 impl<'a> CaretValue<'a> { dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>683 fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> { 684 match self { 685 Self::Format1(table) => table, 686 Self::Format2(table) => table, 687 Self::Format3(table) => table, 688 } 689 } 690 } 691 692 #[cfg(feature = "traversal")] 693 impl<'a> std::fmt::Debug for CaretValue<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result694 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 695 self.dyn_inner().fmt(f) 696 } 697 } 698 699 #[cfg(feature = "traversal")] 700 impl<'a> SomeTable<'a> for CaretValue<'a> { type_name(&self) -> &str701 fn type_name(&self) -> &str { 702 self.dyn_inner().type_name() 703 } get_field(&self, idx: usize) -> Option<Field<'a>>704 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 705 self.dyn_inner().get_field(idx) 706 } 707 } 708 709 impl Format<u16> for CaretValueFormat1Marker { 710 const FORMAT: u16 = 1; 711 } 712 713 /// [CaretValue Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#caretvalue-format-1) 714 #[derive(Debug, Clone, Copy)] 715 #[doc(hidden)] 716 pub struct CaretValueFormat1Marker {} 717 718 impl CaretValueFormat1Marker { caret_value_format_byte_range(&self) -> Range<usize>719 fn caret_value_format_byte_range(&self) -> Range<usize> { 720 let start = 0; 721 start..start + u16::RAW_BYTE_LEN 722 } coordinate_byte_range(&self) -> Range<usize>723 fn coordinate_byte_range(&self) -> Range<usize> { 724 let start = self.caret_value_format_byte_range().end; 725 start..start + i16::RAW_BYTE_LEN 726 } 727 } 728 729 impl<'a> FontRead<'a> for CaretValueFormat1<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>730 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 731 let mut cursor = data.cursor(); 732 cursor.advance::<u16>(); 733 cursor.advance::<i16>(); 734 cursor.finish(CaretValueFormat1Marker {}) 735 } 736 } 737 738 /// [CaretValue Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#caretvalue-format-1) 739 pub type CaretValueFormat1<'a> = TableRef<'a, CaretValueFormat1Marker>; 740 741 impl<'a> CaretValueFormat1<'a> { 742 /// Format identifier: format = 1 caret_value_format(&self) -> u16743 pub fn caret_value_format(&self) -> u16 { 744 let range = self.shape.caret_value_format_byte_range(); 745 self.data.read_at(range.start).unwrap() 746 } 747 748 /// X or Y value, in design units coordinate(&self) -> i16749 pub fn coordinate(&self) -> i16 { 750 let range = self.shape.coordinate_byte_range(); 751 self.data.read_at(range.start).unwrap() 752 } 753 } 754 755 #[cfg(feature = "traversal")] 756 impl<'a> SomeTable<'a> for CaretValueFormat1<'a> { type_name(&self) -> &str757 fn type_name(&self) -> &str { 758 "CaretValueFormat1" 759 } get_field(&self, idx: usize) -> Option<Field<'a>>760 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 761 match idx { 762 0usize => Some(Field::new("caret_value_format", self.caret_value_format())), 763 1usize => Some(Field::new("coordinate", self.coordinate())), 764 _ => None, 765 } 766 } 767 } 768 769 #[cfg(feature = "traversal")] 770 impl<'a> std::fmt::Debug for CaretValueFormat1<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result771 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 772 (self as &dyn SomeTable<'a>).fmt(f) 773 } 774 } 775 776 impl Format<u16> for CaretValueFormat2Marker { 777 const FORMAT: u16 = 2; 778 } 779 780 /// [CaretValue Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#caretvalue-format-2) 781 #[derive(Debug, Clone, Copy)] 782 #[doc(hidden)] 783 pub struct CaretValueFormat2Marker {} 784 785 impl CaretValueFormat2Marker { caret_value_format_byte_range(&self) -> Range<usize>786 fn caret_value_format_byte_range(&self) -> Range<usize> { 787 let start = 0; 788 start..start + u16::RAW_BYTE_LEN 789 } caret_value_point_index_byte_range(&self) -> Range<usize>790 fn caret_value_point_index_byte_range(&self) -> Range<usize> { 791 let start = self.caret_value_format_byte_range().end; 792 start..start + u16::RAW_BYTE_LEN 793 } 794 } 795 796 impl<'a> FontRead<'a> for CaretValueFormat2<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>797 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 798 let mut cursor = data.cursor(); 799 cursor.advance::<u16>(); 800 cursor.advance::<u16>(); 801 cursor.finish(CaretValueFormat2Marker {}) 802 } 803 } 804 805 /// [CaretValue Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#caretvalue-format-2) 806 pub type CaretValueFormat2<'a> = TableRef<'a, CaretValueFormat2Marker>; 807 808 impl<'a> CaretValueFormat2<'a> { 809 /// Format identifier: format = 2 caret_value_format(&self) -> u16810 pub fn caret_value_format(&self) -> u16 { 811 let range = self.shape.caret_value_format_byte_range(); 812 self.data.read_at(range.start).unwrap() 813 } 814 815 /// Contour point index on glyph caret_value_point_index(&self) -> u16816 pub fn caret_value_point_index(&self) -> u16 { 817 let range = self.shape.caret_value_point_index_byte_range(); 818 self.data.read_at(range.start).unwrap() 819 } 820 } 821 822 #[cfg(feature = "traversal")] 823 impl<'a> SomeTable<'a> for CaretValueFormat2<'a> { type_name(&self) -> &str824 fn type_name(&self) -> &str { 825 "CaretValueFormat2" 826 } get_field(&self, idx: usize) -> Option<Field<'a>>827 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 828 match idx { 829 0usize => Some(Field::new("caret_value_format", self.caret_value_format())), 830 1usize => Some(Field::new( 831 "caret_value_point_index", 832 self.caret_value_point_index(), 833 )), 834 _ => None, 835 } 836 } 837 } 838 839 #[cfg(feature = "traversal")] 840 impl<'a> std::fmt::Debug for CaretValueFormat2<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result841 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 842 (self as &dyn SomeTable<'a>).fmt(f) 843 } 844 } 845 846 impl Format<u16> for CaretValueFormat3Marker { 847 const FORMAT: u16 = 3; 848 } 849 850 /// [CaretValue Format 3](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#caretvalue-format-3) 851 #[derive(Debug, Clone, Copy)] 852 #[doc(hidden)] 853 pub struct CaretValueFormat3Marker {} 854 855 impl CaretValueFormat3Marker { caret_value_format_byte_range(&self) -> Range<usize>856 fn caret_value_format_byte_range(&self) -> Range<usize> { 857 let start = 0; 858 start..start + u16::RAW_BYTE_LEN 859 } coordinate_byte_range(&self) -> Range<usize>860 fn coordinate_byte_range(&self) -> Range<usize> { 861 let start = self.caret_value_format_byte_range().end; 862 start..start + i16::RAW_BYTE_LEN 863 } device_offset_byte_range(&self) -> Range<usize>864 fn device_offset_byte_range(&self) -> Range<usize> { 865 let start = self.coordinate_byte_range().end; 866 start..start + Offset16::RAW_BYTE_LEN 867 } 868 } 869 870 impl<'a> FontRead<'a> for CaretValueFormat3<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>871 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 872 let mut cursor = data.cursor(); 873 cursor.advance::<u16>(); 874 cursor.advance::<i16>(); 875 cursor.advance::<Offset16>(); 876 cursor.finish(CaretValueFormat3Marker {}) 877 } 878 } 879 880 /// [CaretValue Format 3](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#caretvalue-format-3) 881 pub type CaretValueFormat3<'a> = TableRef<'a, CaretValueFormat3Marker>; 882 883 impl<'a> CaretValueFormat3<'a> { 884 /// Format identifier-format = 3 caret_value_format(&self) -> u16885 pub fn caret_value_format(&self) -> u16 { 886 let range = self.shape.caret_value_format_byte_range(); 887 self.data.read_at(range.start).unwrap() 888 } 889 890 /// X or Y value, in design units coordinate(&self) -> i16891 pub fn coordinate(&self) -> i16 { 892 let range = self.shape.coordinate_byte_range(); 893 self.data.read_at(range.start).unwrap() 894 } 895 896 /// Offset to Device table (non-variable font) / Variation Index 897 /// table (variable font) for X or Y value-from beginning of 898 /// CaretValue table device_offset(&self) -> Offset16899 pub fn device_offset(&self) -> Offset16 { 900 let range = self.shape.device_offset_byte_range(); 901 self.data.read_at(range.start).unwrap() 902 } 903 904 /// Attempt to resolve [`device_offset`][Self::device_offset]. device(&self) -> Result<DeviceOrVariationIndex<'a>, ReadError>905 pub fn device(&self) -> Result<DeviceOrVariationIndex<'a>, ReadError> { 906 let data = self.data; 907 self.device_offset().resolve(data) 908 } 909 } 910 911 #[cfg(feature = "traversal")] 912 impl<'a> SomeTable<'a> for CaretValueFormat3<'a> { type_name(&self) -> &str913 fn type_name(&self) -> &str { 914 "CaretValueFormat3" 915 } get_field(&self, idx: usize) -> Option<Field<'a>>916 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 917 match idx { 918 0usize => Some(Field::new("caret_value_format", self.caret_value_format())), 919 1usize => Some(Field::new("coordinate", self.coordinate())), 920 2usize => Some(Field::new( 921 "device_offset", 922 FieldType::offset(self.device_offset(), self.device()), 923 )), 924 _ => None, 925 } 926 } 927 } 928 929 #[cfg(feature = "traversal")] 930 impl<'a> std::fmt::Debug for CaretValueFormat3<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result931 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 932 (self as &dyn SomeTable<'a>).fmt(f) 933 } 934 } 935 936 impl Format<u16> for MarkGlyphSetsMarker { 937 const FORMAT: u16 = 1; 938 } 939 940 /// [Mark Glyph Sets Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#mark-glyph-sets-table) 941 #[derive(Debug, Clone, Copy)] 942 #[doc(hidden)] 943 pub struct MarkGlyphSetsMarker { 944 coverage_offsets_byte_len: usize, 945 } 946 947 impl MarkGlyphSetsMarker { format_byte_range(&self) -> Range<usize>948 fn format_byte_range(&self) -> Range<usize> { 949 let start = 0; 950 start..start + u16::RAW_BYTE_LEN 951 } mark_glyph_set_count_byte_range(&self) -> Range<usize>952 fn mark_glyph_set_count_byte_range(&self) -> Range<usize> { 953 let start = self.format_byte_range().end; 954 start..start + u16::RAW_BYTE_LEN 955 } coverage_offsets_byte_range(&self) -> Range<usize>956 fn coverage_offsets_byte_range(&self) -> Range<usize> { 957 let start = self.mark_glyph_set_count_byte_range().end; 958 start..start + self.coverage_offsets_byte_len 959 } 960 } 961 962 impl<'a> FontRead<'a> for MarkGlyphSets<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>963 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 964 let mut cursor = data.cursor(); 965 cursor.advance::<u16>(); 966 let mark_glyph_set_count: u16 = cursor.read()?; 967 let coverage_offsets_byte_len = mark_glyph_set_count as usize * Offset32::RAW_BYTE_LEN; 968 cursor.advance_by(coverage_offsets_byte_len); 969 cursor.finish(MarkGlyphSetsMarker { 970 coverage_offsets_byte_len, 971 }) 972 } 973 } 974 975 /// [Mark Glyph Sets Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#mark-glyph-sets-table) 976 pub type MarkGlyphSets<'a> = TableRef<'a, MarkGlyphSetsMarker>; 977 978 impl<'a> MarkGlyphSets<'a> { 979 /// Format identifier == 1 format(&self) -> u16980 pub fn format(&self) -> u16 { 981 let range = self.shape.format_byte_range(); 982 self.data.read_at(range.start).unwrap() 983 } 984 985 /// Number of mark glyph sets defined mark_glyph_set_count(&self) -> u16986 pub fn mark_glyph_set_count(&self) -> u16 { 987 let range = self.shape.mark_glyph_set_count_byte_range(); 988 self.data.read_at(range.start).unwrap() 989 } 990 991 /// Array of offsets to mark glyph set coverage tables, from the 992 /// start of the MarkGlyphSets table. coverage_offsets(&self) -> &'a [BigEndian<Offset32>]993 pub fn coverage_offsets(&self) -> &'a [BigEndian<Offset32>] { 994 let range = self.shape.coverage_offsets_byte_range(); 995 self.data.read_array(range).unwrap() 996 } 997 998 /// A dynamically resolving wrapper for [`coverage_offsets`][Self::coverage_offsets]. coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset32>999 pub fn coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset32> { 1000 let data = self.data; 1001 let offsets = self.coverage_offsets(); 1002 ArrayOfOffsets::new(offsets, data, ()) 1003 } 1004 } 1005 1006 #[cfg(feature = "traversal")] 1007 impl<'a> SomeTable<'a> for MarkGlyphSets<'a> { type_name(&self) -> &str1008 fn type_name(&self) -> &str { 1009 "MarkGlyphSets" 1010 } get_field(&self, idx: usize) -> Option<Field<'a>>1011 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1012 match idx { 1013 0usize => Some(Field::new("format", self.format())), 1014 1usize => Some(Field::new( 1015 "mark_glyph_set_count", 1016 self.mark_glyph_set_count(), 1017 )), 1018 2usize => Some({ 1019 let data = self.data; 1020 Field::new( 1021 "coverage_offsets", 1022 FieldType::array_of_offsets( 1023 better_type_name::<CoverageTable>(), 1024 self.coverage_offsets(), 1025 move |off| { 1026 let target = off.get().resolve::<CoverageTable>(data); 1027 FieldType::offset(off.get(), target) 1028 }, 1029 ), 1030 ) 1031 }), 1032 _ => None, 1033 } 1034 } 1035 } 1036 1037 #[cfg(feature = "traversal")] 1038 impl<'a> std::fmt::Debug for MarkGlyphSets<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1039 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1040 (self as &dyn SomeTable<'a>).fmt(f) 1041 } 1042 } 1043