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 /// [COLR (Color)](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#colr-header) table 9 #[derive(Debug, Clone, Copy)] 10 #[doc(hidden)] 11 pub struct ColrMarker { 12 base_glyph_list_offset_byte_start: Option<usize>, 13 layer_list_offset_byte_start: Option<usize>, 14 clip_list_offset_byte_start: Option<usize>, 15 var_index_map_offset_byte_start: Option<usize>, 16 item_variation_store_offset_byte_start: Option<usize>, 17 } 18 19 impl ColrMarker { version_byte_range(&self) -> Range<usize>20 fn version_byte_range(&self) -> Range<usize> { 21 let start = 0; 22 start..start + u16::RAW_BYTE_LEN 23 } num_base_glyph_records_byte_range(&self) -> Range<usize>24 fn num_base_glyph_records_byte_range(&self) -> Range<usize> { 25 let start = self.version_byte_range().end; 26 start..start + u16::RAW_BYTE_LEN 27 } base_glyph_records_offset_byte_range(&self) -> Range<usize>28 fn base_glyph_records_offset_byte_range(&self) -> Range<usize> { 29 let start = self.num_base_glyph_records_byte_range().end; 30 start..start + Offset32::RAW_BYTE_LEN 31 } layer_records_offset_byte_range(&self) -> Range<usize>32 fn layer_records_offset_byte_range(&self) -> Range<usize> { 33 let start = self.base_glyph_records_offset_byte_range().end; 34 start..start + Offset32::RAW_BYTE_LEN 35 } num_layer_records_byte_range(&self) -> Range<usize>36 fn num_layer_records_byte_range(&self) -> Range<usize> { 37 let start = self.layer_records_offset_byte_range().end; 38 start..start + u16::RAW_BYTE_LEN 39 } base_glyph_list_offset_byte_range(&self) -> Option<Range<usize>>40 fn base_glyph_list_offset_byte_range(&self) -> Option<Range<usize>> { 41 let start = self.base_glyph_list_offset_byte_start?; 42 Some(start..start + Offset32::RAW_BYTE_LEN) 43 } layer_list_offset_byte_range(&self) -> Option<Range<usize>>44 fn layer_list_offset_byte_range(&self) -> Option<Range<usize>> { 45 let start = self.layer_list_offset_byte_start?; 46 Some(start..start + Offset32::RAW_BYTE_LEN) 47 } clip_list_offset_byte_range(&self) -> Option<Range<usize>>48 fn clip_list_offset_byte_range(&self) -> Option<Range<usize>> { 49 let start = self.clip_list_offset_byte_start?; 50 Some(start..start + Offset32::RAW_BYTE_LEN) 51 } var_index_map_offset_byte_range(&self) -> Option<Range<usize>>52 fn var_index_map_offset_byte_range(&self) -> Option<Range<usize>> { 53 let start = self.var_index_map_offset_byte_start?; 54 Some(start..start + Offset32::RAW_BYTE_LEN) 55 } item_variation_store_offset_byte_range(&self) -> Option<Range<usize>>56 fn item_variation_store_offset_byte_range(&self) -> Option<Range<usize>> { 57 let start = self.item_variation_store_offset_byte_start?; 58 Some(start..start + Offset32::RAW_BYTE_LEN) 59 } 60 } 61 62 impl TopLevelTable for Colr<'_> { 63 /// `COLR` 64 const TAG: Tag = Tag::new(b"COLR"); 65 } 66 67 impl<'a> FontRead<'a> for Colr<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>68 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 69 let mut cursor = data.cursor(); 70 let version: u16 = cursor.read()?; 71 cursor.advance::<u16>(); 72 cursor.advance::<Offset32>(); 73 cursor.advance::<Offset32>(); 74 cursor.advance::<u16>(); 75 let base_glyph_list_offset_byte_start = version 76 .compatible(1) 77 .then(|| cursor.position()) 78 .transpose()?; 79 version.compatible(1).then(|| cursor.advance::<Offset32>()); 80 let layer_list_offset_byte_start = version 81 .compatible(1) 82 .then(|| cursor.position()) 83 .transpose()?; 84 version.compatible(1).then(|| cursor.advance::<Offset32>()); 85 let clip_list_offset_byte_start = version 86 .compatible(1) 87 .then(|| cursor.position()) 88 .transpose()?; 89 version.compatible(1).then(|| cursor.advance::<Offset32>()); 90 let var_index_map_offset_byte_start = version 91 .compatible(1) 92 .then(|| cursor.position()) 93 .transpose()?; 94 version.compatible(1).then(|| cursor.advance::<Offset32>()); 95 let item_variation_store_offset_byte_start = version 96 .compatible(1) 97 .then(|| cursor.position()) 98 .transpose()?; 99 version.compatible(1).then(|| cursor.advance::<Offset32>()); 100 cursor.finish(ColrMarker { 101 base_glyph_list_offset_byte_start, 102 layer_list_offset_byte_start, 103 clip_list_offset_byte_start, 104 var_index_map_offset_byte_start, 105 item_variation_store_offset_byte_start, 106 }) 107 } 108 } 109 110 /// [COLR (Color)](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#colr-header) table 111 pub type Colr<'a> = TableRef<'a, ColrMarker>; 112 113 impl<'a> Colr<'a> { 114 /// Table version number - set to 0 or 1. version(&self) -> u16115 pub fn version(&self) -> u16 { 116 let range = self.shape.version_byte_range(); 117 self.data.read_at(range.start).unwrap() 118 } 119 120 /// Number of BaseGlyph records; may be 0 in a version 1 table. num_base_glyph_records(&self) -> u16121 pub fn num_base_glyph_records(&self) -> u16 { 122 let range = self.shape.num_base_glyph_records_byte_range(); 123 self.data.read_at(range.start).unwrap() 124 } 125 126 /// Offset to baseGlyphRecords array (may be NULL). base_glyph_records_offset(&self) -> Nullable<Offset32>127 pub fn base_glyph_records_offset(&self) -> Nullable<Offset32> { 128 let range = self.shape.base_glyph_records_offset_byte_range(); 129 self.data.read_at(range.start).unwrap() 130 } 131 132 /// Attempt to resolve [`base_glyph_records_offset`][Self::base_glyph_records_offset]. base_glyph_records(&self) -> Option<Result<&'a [BaseGlyph], ReadError>>133 pub fn base_glyph_records(&self) -> Option<Result<&'a [BaseGlyph], ReadError>> { 134 let data = self.data; 135 let args = self.num_base_glyph_records(); 136 self.base_glyph_records_offset() 137 .resolve_with_args(data, &args) 138 } 139 140 /// Offset to layerRecords array (may be NULL). layer_records_offset(&self) -> Nullable<Offset32>141 pub fn layer_records_offset(&self) -> Nullable<Offset32> { 142 let range = self.shape.layer_records_offset_byte_range(); 143 self.data.read_at(range.start).unwrap() 144 } 145 146 /// Attempt to resolve [`layer_records_offset`][Self::layer_records_offset]. layer_records(&self) -> Option<Result<&'a [Layer], ReadError>>147 pub fn layer_records(&self) -> Option<Result<&'a [Layer], ReadError>> { 148 let data = self.data; 149 let args = self.num_layer_records(); 150 self.layer_records_offset().resolve_with_args(data, &args) 151 } 152 153 /// Number of Layer records; may be 0 in a version 1 table. num_layer_records(&self) -> u16154 pub fn num_layer_records(&self) -> u16 { 155 let range = self.shape.num_layer_records_byte_range(); 156 self.data.read_at(range.start).unwrap() 157 } 158 159 /// Offset to BaseGlyphList table. base_glyph_list_offset(&self) -> Option<Nullable<Offset32>>160 pub fn base_glyph_list_offset(&self) -> Option<Nullable<Offset32>> { 161 let range = self.shape.base_glyph_list_offset_byte_range()?; 162 Some(self.data.read_at(range.start).unwrap()) 163 } 164 165 /// Attempt to resolve [`base_glyph_list_offset`][Self::base_glyph_list_offset]. base_glyph_list(&self) -> Option<Result<BaseGlyphList<'a>, ReadError>>166 pub fn base_glyph_list(&self) -> Option<Result<BaseGlyphList<'a>, ReadError>> { 167 let data = self.data; 168 self.base_glyph_list_offset().map(|x| x.resolve(data))? 169 } 170 171 /// Offset to LayerList table (may be NULL). layer_list_offset(&self) -> Option<Nullable<Offset32>>172 pub fn layer_list_offset(&self) -> Option<Nullable<Offset32>> { 173 let range = self.shape.layer_list_offset_byte_range()?; 174 Some(self.data.read_at(range.start).unwrap()) 175 } 176 177 /// Attempt to resolve [`layer_list_offset`][Self::layer_list_offset]. layer_list(&self) -> Option<Result<LayerList<'a>, ReadError>>178 pub fn layer_list(&self) -> Option<Result<LayerList<'a>, ReadError>> { 179 let data = self.data; 180 self.layer_list_offset().map(|x| x.resolve(data))? 181 } 182 183 /// Offset to ClipList table (may be NULL). clip_list_offset(&self) -> Option<Nullable<Offset32>>184 pub fn clip_list_offset(&self) -> Option<Nullable<Offset32>> { 185 let range = self.shape.clip_list_offset_byte_range()?; 186 Some(self.data.read_at(range.start).unwrap()) 187 } 188 189 /// Attempt to resolve [`clip_list_offset`][Self::clip_list_offset]. clip_list(&self) -> Option<Result<ClipList<'a>, ReadError>>190 pub fn clip_list(&self) -> Option<Result<ClipList<'a>, ReadError>> { 191 let data = self.data; 192 self.clip_list_offset().map(|x| x.resolve(data))? 193 } 194 195 /// Offset to DeltaSetIndexMap table (may be NULL). var_index_map_offset(&self) -> Option<Nullable<Offset32>>196 pub fn var_index_map_offset(&self) -> Option<Nullable<Offset32>> { 197 let range = self.shape.var_index_map_offset_byte_range()?; 198 Some(self.data.read_at(range.start).unwrap()) 199 } 200 201 /// Attempt to resolve [`var_index_map_offset`][Self::var_index_map_offset]. var_index_map(&self) -> Option<Result<DeltaSetIndexMap<'a>, ReadError>>202 pub fn var_index_map(&self) -> Option<Result<DeltaSetIndexMap<'a>, ReadError>> { 203 let data = self.data; 204 self.var_index_map_offset().map(|x| x.resolve(data))? 205 } 206 207 /// Offset to ItemVariationStore (may be NULL). item_variation_store_offset(&self) -> Option<Nullable<Offset32>>208 pub fn item_variation_store_offset(&self) -> Option<Nullable<Offset32>> { 209 let range = self.shape.item_variation_store_offset_byte_range()?; 210 Some(self.data.read_at(range.start).unwrap()) 211 } 212 213 /// Attempt to resolve [`item_variation_store_offset`][Self::item_variation_store_offset]. item_variation_store(&self) -> Option<Result<ItemVariationStore<'a>, ReadError>>214 pub fn item_variation_store(&self) -> Option<Result<ItemVariationStore<'a>, ReadError>> { 215 let data = self.data; 216 self.item_variation_store_offset() 217 .map(|x| x.resolve(data))? 218 } 219 } 220 221 #[cfg(feature = "traversal")] 222 impl<'a> SomeTable<'a> for Colr<'a> { type_name(&self) -> &str223 fn type_name(&self) -> &str { 224 "Colr" 225 } get_field(&self, idx: usize) -> Option<Field<'a>>226 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 227 let version = self.version(); 228 match idx { 229 0usize => Some(Field::new("version", self.version())), 230 1usize => Some(Field::new( 231 "num_base_glyph_records", 232 self.num_base_glyph_records(), 233 )), 234 2usize => Some(Field::new( 235 "base_glyph_records_offset", 236 traversal::FieldType::offset_to_array_of_records( 237 self.base_glyph_records_offset(), 238 self.base_glyph_records(), 239 stringify!(BaseGlyph), 240 self.offset_data(), 241 ), 242 )), 243 3usize => Some(Field::new( 244 "layer_records_offset", 245 traversal::FieldType::offset_to_array_of_records( 246 self.layer_records_offset(), 247 self.layer_records(), 248 stringify!(Layer), 249 self.offset_data(), 250 ), 251 )), 252 4usize => Some(Field::new("num_layer_records", self.num_layer_records())), 253 5usize if version.compatible(1) => Some(Field::new( 254 "base_glyph_list_offset", 255 FieldType::offset( 256 self.base_glyph_list_offset().unwrap(), 257 self.base_glyph_list().unwrap(), 258 ), 259 )), 260 6usize if version.compatible(1) => Some(Field::new( 261 "layer_list_offset", 262 FieldType::offset( 263 self.layer_list_offset().unwrap(), 264 self.layer_list().unwrap(), 265 ), 266 )), 267 7usize if version.compatible(1) => Some(Field::new( 268 "clip_list_offset", 269 FieldType::offset(self.clip_list_offset().unwrap(), self.clip_list().unwrap()), 270 )), 271 8usize if version.compatible(1) => Some(Field::new( 272 "var_index_map_offset", 273 FieldType::offset( 274 self.var_index_map_offset().unwrap(), 275 self.var_index_map().unwrap(), 276 ), 277 )), 278 9usize if version.compatible(1) => Some(Field::new( 279 "item_variation_store_offset", 280 FieldType::offset( 281 self.item_variation_store_offset().unwrap(), 282 self.item_variation_store().unwrap(), 283 ), 284 )), 285 _ => None, 286 } 287 } 288 } 289 290 #[cfg(feature = "traversal")] 291 impl<'a> std::fmt::Debug for Colr<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result292 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 293 (self as &dyn SomeTable<'a>).fmt(f) 294 } 295 } 296 297 /// [BaseGlyph](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyph-and-layer-records) record 298 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 299 #[repr(C)] 300 #[repr(packed)] 301 pub struct BaseGlyph { 302 /// Glyph ID of the base glyph. 303 pub glyph_id: BigEndian<GlyphId>, 304 /// Index (base 0) into the layerRecords array. 305 pub first_layer_index: BigEndian<u16>, 306 /// Number of color layers associated with this glyph. 307 pub num_layers: BigEndian<u16>, 308 } 309 310 impl BaseGlyph { 311 /// Glyph ID of the base glyph. glyph_id(&self) -> GlyphId312 pub fn glyph_id(&self) -> GlyphId { 313 self.glyph_id.get() 314 } 315 316 /// Index (base 0) into the layerRecords array. first_layer_index(&self) -> u16317 pub fn first_layer_index(&self) -> u16 { 318 self.first_layer_index.get() 319 } 320 321 /// Number of color layers associated with this glyph. num_layers(&self) -> u16322 pub fn num_layers(&self) -> u16 { 323 self.num_layers.get() 324 } 325 } 326 327 impl FixedSize for BaseGlyph { 328 const RAW_BYTE_LEN: usize = GlyphId::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; 329 } 330 331 impl sealed::Sealed for BaseGlyph {} 332 333 /// SAFETY: see the [`FromBytes`] trait documentation. 334 unsafe impl FromBytes for BaseGlyph { this_trait_should_only_be_implemented_in_generated_code()335 fn this_trait_should_only_be_implemented_in_generated_code() {} 336 } 337 338 #[cfg(feature = "traversal")] 339 impl<'a> SomeRecord<'a> for BaseGlyph { traverse(self, data: FontData<'a>) -> RecordResolver<'a>340 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 341 RecordResolver { 342 name: "BaseGlyph", 343 get_field: Box::new(move |idx, _data| match idx { 344 0usize => Some(Field::new("glyph_id", self.glyph_id())), 345 1usize => Some(Field::new("first_layer_index", self.first_layer_index())), 346 2usize => Some(Field::new("num_layers", self.num_layers())), 347 _ => None, 348 }), 349 data, 350 } 351 } 352 } 353 354 /// [Layer](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyph-and-layer-records) record 355 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 356 #[repr(C)] 357 #[repr(packed)] 358 pub struct Layer { 359 /// Glyph ID of the glyph used for a given layer. 360 pub glyph_id: BigEndian<GlyphId>, 361 /// Index (base 0) for a palette entry in the CPAL table. 362 pub palette_index: BigEndian<u16>, 363 } 364 365 impl Layer { 366 /// Glyph ID of the glyph used for a given layer. glyph_id(&self) -> GlyphId367 pub fn glyph_id(&self) -> GlyphId { 368 self.glyph_id.get() 369 } 370 371 /// Index (base 0) for a palette entry in the CPAL table. palette_index(&self) -> u16372 pub fn palette_index(&self) -> u16 { 373 self.palette_index.get() 374 } 375 } 376 377 impl FixedSize for Layer { 378 const RAW_BYTE_LEN: usize = GlyphId::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; 379 } 380 381 impl sealed::Sealed for Layer {} 382 383 /// SAFETY: see the [`FromBytes`] trait documentation. 384 unsafe impl FromBytes for Layer { this_trait_should_only_be_implemented_in_generated_code()385 fn this_trait_should_only_be_implemented_in_generated_code() {} 386 } 387 388 #[cfg(feature = "traversal")] 389 impl<'a> SomeRecord<'a> for Layer { traverse(self, data: FontData<'a>) -> RecordResolver<'a>390 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 391 RecordResolver { 392 name: "Layer", 393 get_field: Box::new(move |idx, _data| match idx { 394 0usize => Some(Field::new("glyph_id", self.glyph_id())), 395 1usize => Some(Field::new("palette_index", self.palette_index())), 396 _ => None, 397 }), 398 data, 399 } 400 } 401 } 402 403 /// [BaseGlyphList](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table 404 #[derive(Debug, Clone, Copy)] 405 #[doc(hidden)] 406 pub struct BaseGlyphListMarker { 407 base_glyph_paint_records_byte_len: usize, 408 } 409 410 impl BaseGlyphListMarker { num_base_glyph_paint_records_byte_range(&self) -> Range<usize>411 fn num_base_glyph_paint_records_byte_range(&self) -> Range<usize> { 412 let start = 0; 413 start..start + u32::RAW_BYTE_LEN 414 } base_glyph_paint_records_byte_range(&self) -> Range<usize>415 fn base_glyph_paint_records_byte_range(&self) -> Range<usize> { 416 let start = self.num_base_glyph_paint_records_byte_range().end; 417 start..start + self.base_glyph_paint_records_byte_len 418 } 419 } 420 421 impl<'a> FontRead<'a> for BaseGlyphList<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>422 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 423 let mut cursor = data.cursor(); 424 let num_base_glyph_paint_records: u32 = cursor.read()?; 425 let base_glyph_paint_records_byte_len = 426 num_base_glyph_paint_records as usize * BaseGlyphPaint::RAW_BYTE_LEN; 427 cursor.advance_by(base_glyph_paint_records_byte_len); 428 cursor.finish(BaseGlyphListMarker { 429 base_glyph_paint_records_byte_len, 430 }) 431 } 432 } 433 434 /// [BaseGlyphList](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table 435 pub type BaseGlyphList<'a> = TableRef<'a, BaseGlyphListMarker>; 436 437 impl<'a> BaseGlyphList<'a> { num_base_glyph_paint_records(&self) -> u32438 pub fn num_base_glyph_paint_records(&self) -> u32 { 439 let range = self.shape.num_base_glyph_paint_records_byte_range(); 440 self.data.read_at(range.start).unwrap() 441 } 442 base_glyph_paint_records(&self) -> &'a [BaseGlyphPaint]443 pub fn base_glyph_paint_records(&self) -> &'a [BaseGlyphPaint] { 444 let range = self.shape.base_glyph_paint_records_byte_range(); 445 self.data.read_array(range).unwrap() 446 } 447 } 448 449 #[cfg(feature = "traversal")] 450 impl<'a> SomeTable<'a> for BaseGlyphList<'a> { type_name(&self) -> &str451 fn type_name(&self) -> &str { 452 "BaseGlyphList" 453 } get_field(&self, idx: usize) -> Option<Field<'a>>454 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 455 match idx { 456 0usize => Some(Field::new( 457 "num_base_glyph_paint_records", 458 self.num_base_glyph_paint_records(), 459 )), 460 1usize => Some(Field::new( 461 "base_glyph_paint_records", 462 traversal::FieldType::array_of_records( 463 stringify!(BaseGlyphPaint), 464 self.base_glyph_paint_records(), 465 self.offset_data(), 466 ), 467 )), 468 _ => None, 469 } 470 } 471 } 472 473 #[cfg(feature = "traversal")] 474 impl<'a> std::fmt::Debug for BaseGlyphList<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result475 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 476 (self as &dyn SomeTable<'a>).fmt(f) 477 } 478 } 479 480 /// [BaseGlyphPaint](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record 481 #[derive(Clone, Debug)] 482 #[repr(C)] 483 #[repr(packed)] 484 pub struct BaseGlyphPaint { 485 /// Glyph ID of the base glyph. 486 pub glyph_id: BigEndian<GlyphId>, 487 /// Offset to a Paint table, from the beginning of the [`BaseGlyphList`] table. 488 pub paint_offset: BigEndian<Offset32>, 489 } 490 491 impl BaseGlyphPaint { 492 /// Glyph ID of the base glyph. glyph_id(&self) -> GlyphId493 pub fn glyph_id(&self) -> GlyphId { 494 self.glyph_id.get() 495 } 496 497 /// Offset to a Paint table, from the beginning of the [`BaseGlyphList`] table. paint_offset(&self) -> Offset32498 pub fn paint_offset(&self) -> Offset32 { 499 self.paint_offset.get() 500 } 501 502 /// Offset to a Paint table, from the beginning of the [`BaseGlyphList`] table. 503 /// 504 /// The `data` argument should be retrieved from the parent table 505 /// By calling its `offset_data` method. paint<'a>(&self, data: FontData<'a>) -> Result<Paint<'a>, ReadError>506 pub fn paint<'a>(&self, data: FontData<'a>) -> Result<Paint<'a>, ReadError> { 507 self.paint_offset().resolve(data) 508 } 509 } 510 511 impl FixedSize for BaseGlyphPaint { 512 const RAW_BYTE_LEN: usize = GlyphId::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN; 513 } 514 515 impl sealed::Sealed for BaseGlyphPaint {} 516 517 /// SAFETY: see the [`FromBytes`] trait documentation. 518 unsafe impl FromBytes for BaseGlyphPaint { this_trait_should_only_be_implemented_in_generated_code()519 fn this_trait_should_only_be_implemented_in_generated_code() {} 520 } 521 522 #[cfg(feature = "traversal")] 523 impl<'a> SomeRecord<'a> for BaseGlyphPaint { traverse(self, data: FontData<'a>) -> RecordResolver<'a>524 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 525 RecordResolver { 526 name: "BaseGlyphPaint", 527 get_field: Box::new(move |idx, _data| match idx { 528 0usize => Some(Field::new("glyph_id", self.glyph_id())), 529 1usize => Some(Field::new( 530 "paint_offset", 531 FieldType::offset(self.paint_offset(), self.paint(_data)), 532 )), 533 _ => None, 534 }), 535 data, 536 } 537 } 538 } 539 540 /// [LayerList](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table 541 #[derive(Debug, Clone, Copy)] 542 #[doc(hidden)] 543 pub struct LayerListMarker { 544 paint_offsets_byte_len: usize, 545 } 546 547 impl LayerListMarker { num_layers_byte_range(&self) -> Range<usize>548 fn num_layers_byte_range(&self) -> Range<usize> { 549 let start = 0; 550 start..start + u32::RAW_BYTE_LEN 551 } paint_offsets_byte_range(&self) -> Range<usize>552 fn paint_offsets_byte_range(&self) -> Range<usize> { 553 let start = self.num_layers_byte_range().end; 554 start..start + self.paint_offsets_byte_len 555 } 556 } 557 558 impl<'a> FontRead<'a> for LayerList<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>559 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 560 let mut cursor = data.cursor(); 561 let num_layers: u32 = cursor.read()?; 562 let paint_offsets_byte_len = num_layers as usize * Offset32::RAW_BYTE_LEN; 563 cursor.advance_by(paint_offsets_byte_len); 564 cursor.finish(LayerListMarker { 565 paint_offsets_byte_len, 566 }) 567 } 568 } 569 570 /// [LayerList](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table 571 pub type LayerList<'a> = TableRef<'a, LayerListMarker>; 572 573 impl<'a> LayerList<'a> { num_layers(&self) -> u32574 pub fn num_layers(&self) -> u32 { 575 let range = self.shape.num_layers_byte_range(); 576 self.data.read_at(range.start).unwrap() 577 } 578 579 /// Offsets to Paint tables. paint_offsets(&self) -> &'a [BigEndian<Offset32>]580 pub fn paint_offsets(&self) -> &'a [BigEndian<Offset32>] { 581 let range = self.shape.paint_offsets_byte_range(); 582 self.data.read_array(range).unwrap() 583 } 584 585 /// A dynamically resolving wrapper for [`paint_offsets`][Self::paint_offsets]. paints(&self) -> ArrayOfOffsets<'a, Paint<'a>, Offset32>586 pub fn paints(&self) -> ArrayOfOffsets<'a, Paint<'a>, Offset32> { 587 let data = self.data; 588 let offsets = self.paint_offsets(); 589 ArrayOfOffsets::new(offsets, data, ()) 590 } 591 } 592 593 #[cfg(feature = "traversal")] 594 impl<'a> SomeTable<'a> for LayerList<'a> { type_name(&self) -> &str595 fn type_name(&self) -> &str { 596 "LayerList" 597 } get_field(&self, idx: usize) -> Option<Field<'a>>598 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 599 match idx { 600 0usize => Some(Field::new("num_layers", self.num_layers())), 601 1usize => Some({ 602 let data = self.data; 603 Field::new( 604 "paint_offsets", 605 FieldType::array_of_offsets( 606 better_type_name::<Paint>(), 607 self.paint_offsets(), 608 move |off| { 609 let target = off.get().resolve::<Paint>(data); 610 FieldType::offset(off.get(), target) 611 }, 612 ), 613 ) 614 }), 615 _ => None, 616 } 617 } 618 } 619 620 #[cfg(feature = "traversal")] 621 impl<'a> std::fmt::Debug for LayerList<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result622 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 623 (self as &dyn SomeTable<'a>).fmt(f) 624 } 625 } 626 627 /// [ClipList](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table 628 #[derive(Debug, Clone, Copy)] 629 #[doc(hidden)] 630 pub struct ClipListMarker { 631 clips_byte_len: usize, 632 } 633 634 impl ClipListMarker { format_byte_range(&self) -> Range<usize>635 fn format_byte_range(&self) -> Range<usize> { 636 let start = 0; 637 start..start + u8::RAW_BYTE_LEN 638 } num_clips_byte_range(&self) -> Range<usize>639 fn num_clips_byte_range(&self) -> Range<usize> { 640 let start = self.format_byte_range().end; 641 start..start + u32::RAW_BYTE_LEN 642 } clips_byte_range(&self) -> Range<usize>643 fn clips_byte_range(&self) -> Range<usize> { 644 let start = self.num_clips_byte_range().end; 645 start..start + self.clips_byte_len 646 } 647 } 648 649 impl<'a> FontRead<'a> for ClipList<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>650 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 651 let mut cursor = data.cursor(); 652 cursor.advance::<u8>(); 653 let num_clips: u32 = cursor.read()?; 654 let clips_byte_len = num_clips as usize * Clip::RAW_BYTE_LEN; 655 cursor.advance_by(clips_byte_len); 656 cursor.finish(ClipListMarker { clips_byte_len }) 657 } 658 } 659 660 /// [ClipList](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table 661 pub type ClipList<'a> = TableRef<'a, ClipListMarker>; 662 663 impl<'a> ClipList<'a> { 664 /// Set to 1. format(&self) -> u8665 pub fn format(&self) -> u8 { 666 let range = self.shape.format_byte_range(); 667 self.data.read_at(range.start).unwrap() 668 } 669 670 /// Number of Clip records. num_clips(&self) -> u32671 pub fn num_clips(&self) -> u32 { 672 let range = self.shape.num_clips_byte_range(); 673 self.data.read_at(range.start).unwrap() 674 } 675 676 /// Clip records. Sorted by startGlyphID. clips(&self) -> &'a [Clip]677 pub fn clips(&self) -> &'a [Clip] { 678 let range = self.shape.clips_byte_range(); 679 self.data.read_array(range).unwrap() 680 } 681 } 682 683 #[cfg(feature = "traversal")] 684 impl<'a> SomeTable<'a> for ClipList<'a> { type_name(&self) -> &str685 fn type_name(&self) -> &str { 686 "ClipList" 687 } get_field(&self, idx: usize) -> Option<Field<'a>>688 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 689 match idx { 690 0usize => Some(Field::new("format", self.format())), 691 1usize => Some(Field::new("num_clips", self.num_clips())), 692 2usize => Some(Field::new( 693 "clips", 694 traversal::FieldType::array_of_records( 695 stringify!(Clip), 696 self.clips(), 697 self.offset_data(), 698 ), 699 )), 700 _ => None, 701 } 702 } 703 } 704 705 #[cfg(feature = "traversal")] 706 impl<'a> std::fmt::Debug for ClipList<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result707 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 708 (self as &dyn SomeTable<'a>).fmt(f) 709 } 710 } 711 712 /// [Clip](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record 713 #[derive(Clone, Debug)] 714 #[repr(C)] 715 #[repr(packed)] 716 pub struct Clip { 717 /// First glyph ID in the range. 718 pub start_glyph_id: BigEndian<GlyphId>, 719 /// Last glyph ID in the range. 720 pub end_glyph_id: BigEndian<GlyphId>, 721 /// Offset to a ClipBox table, from the beginning of the [`ClipList`] table. 722 pub clip_box_offset: BigEndian<Offset24>, 723 } 724 725 impl Clip { 726 /// First glyph ID in the range. start_glyph_id(&self) -> GlyphId727 pub fn start_glyph_id(&self) -> GlyphId { 728 self.start_glyph_id.get() 729 } 730 731 /// Last glyph ID in the range. end_glyph_id(&self) -> GlyphId732 pub fn end_glyph_id(&self) -> GlyphId { 733 self.end_glyph_id.get() 734 } 735 736 /// Offset to a ClipBox table, from the beginning of the [`ClipList`] table. clip_box_offset(&self) -> Offset24737 pub fn clip_box_offset(&self) -> Offset24 { 738 self.clip_box_offset.get() 739 } 740 741 /// Offset to a ClipBox table, from the beginning of the [`ClipList`] table. 742 /// 743 /// The `data` argument should be retrieved from the parent table 744 /// By calling its `offset_data` method. clip_box<'a>(&self, data: FontData<'a>) -> Result<ClipBox<'a>, ReadError>745 pub fn clip_box<'a>(&self, data: FontData<'a>) -> Result<ClipBox<'a>, ReadError> { 746 self.clip_box_offset().resolve(data) 747 } 748 } 749 750 impl FixedSize for Clip { 751 const RAW_BYTE_LEN: usize = 752 GlyphId::RAW_BYTE_LEN + GlyphId::RAW_BYTE_LEN + Offset24::RAW_BYTE_LEN; 753 } 754 755 impl sealed::Sealed for Clip {} 756 757 /// SAFETY: see the [`FromBytes`] trait documentation. 758 unsafe impl FromBytes for Clip { this_trait_should_only_be_implemented_in_generated_code()759 fn this_trait_should_only_be_implemented_in_generated_code() {} 760 } 761 762 #[cfg(feature = "traversal")] 763 impl<'a> SomeRecord<'a> for Clip { traverse(self, data: FontData<'a>) -> RecordResolver<'a>764 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 765 RecordResolver { 766 name: "Clip", 767 get_field: Box::new(move |idx, _data| match idx { 768 0usize => Some(Field::new("start_glyph_id", self.start_glyph_id())), 769 1usize => Some(Field::new("end_glyph_id", self.end_glyph_id())), 770 2usize => Some(Field::new( 771 "clip_box_offset", 772 FieldType::offset(self.clip_box_offset(), self.clip_box(_data)), 773 )), 774 _ => None, 775 }), 776 data, 777 } 778 } 779 } 780 781 /// [ClipBox](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table 782 #[derive(Clone)] 783 pub enum ClipBox<'a> { 784 Format1(ClipBoxFormat1<'a>), 785 Format2(ClipBoxFormat2<'a>), 786 } 787 788 impl<'a> ClipBox<'a> { 789 /// Set to 1. format(&self) -> u8790 pub fn format(&self) -> u8 { 791 match self { 792 Self::Format1(item) => item.format(), 793 Self::Format2(item) => item.format(), 794 } 795 } 796 797 /// Minimum x of clip box. x_min(&self) -> FWord798 pub fn x_min(&self) -> FWord { 799 match self { 800 Self::Format1(item) => item.x_min(), 801 Self::Format2(item) => item.x_min(), 802 } 803 } 804 805 /// Minimum y of clip box. y_min(&self) -> FWord806 pub fn y_min(&self) -> FWord { 807 match self { 808 Self::Format1(item) => item.y_min(), 809 Self::Format2(item) => item.y_min(), 810 } 811 } 812 813 /// Maximum x of clip box. x_max(&self) -> FWord814 pub fn x_max(&self) -> FWord { 815 match self { 816 Self::Format1(item) => item.x_max(), 817 Self::Format2(item) => item.x_max(), 818 } 819 } 820 821 /// Maximum y of clip box. y_max(&self) -> FWord822 pub fn y_max(&self) -> FWord { 823 match self { 824 Self::Format1(item) => item.y_max(), 825 Self::Format2(item) => item.y_max(), 826 } 827 } 828 } 829 830 impl<'a> FontRead<'a> for ClipBox<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>831 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 832 let format: u8 = data.read_at(0usize)?; 833 match format { 834 ClipBoxFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)), 835 ClipBoxFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)), 836 other => Err(ReadError::InvalidFormat(other.into())), 837 } 838 } 839 } 840 841 #[cfg(feature = "traversal")] 842 impl<'a> ClipBox<'a> { dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>843 fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> { 844 match self { 845 Self::Format1(table) => table, 846 Self::Format2(table) => table, 847 } 848 } 849 } 850 851 #[cfg(feature = "traversal")] 852 impl<'a> std::fmt::Debug for ClipBox<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result853 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 854 self.dyn_inner().fmt(f) 855 } 856 } 857 858 #[cfg(feature = "traversal")] 859 impl<'a> SomeTable<'a> for ClipBox<'a> { type_name(&self) -> &str860 fn type_name(&self) -> &str { 861 self.dyn_inner().type_name() 862 } get_field(&self, idx: usize) -> Option<Field<'a>>863 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 864 self.dyn_inner().get_field(idx) 865 } 866 } 867 868 impl Format<u8> for ClipBoxFormat1Marker { 869 const FORMAT: u8 = 1; 870 } 871 872 /// [ClipBoxFormat1](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record 873 #[derive(Debug, Clone, Copy)] 874 #[doc(hidden)] 875 pub struct ClipBoxFormat1Marker {} 876 877 impl ClipBoxFormat1Marker { format_byte_range(&self) -> Range<usize>878 fn format_byte_range(&self) -> Range<usize> { 879 let start = 0; 880 start..start + u8::RAW_BYTE_LEN 881 } x_min_byte_range(&self) -> Range<usize>882 fn x_min_byte_range(&self) -> Range<usize> { 883 let start = self.format_byte_range().end; 884 start..start + FWord::RAW_BYTE_LEN 885 } y_min_byte_range(&self) -> Range<usize>886 fn y_min_byte_range(&self) -> Range<usize> { 887 let start = self.x_min_byte_range().end; 888 start..start + FWord::RAW_BYTE_LEN 889 } x_max_byte_range(&self) -> Range<usize>890 fn x_max_byte_range(&self) -> Range<usize> { 891 let start = self.y_min_byte_range().end; 892 start..start + FWord::RAW_BYTE_LEN 893 } y_max_byte_range(&self) -> Range<usize>894 fn y_max_byte_range(&self) -> Range<usize> { 895 let start = self.x_max_byte_range().end; 896 start..start + FWord::RAW_BYTE_LEN 897 } 898 } 899 900 impl<'a> FontRead<'a> for ClipBoxFormat1<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>901 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 902 let mut cursor = data.cursor(); 903 cursor.advance::<u8>(); 904 cursor.advance::<FWord>(); 905 cursor.advance::<FWord>(); 906 cursor.advance::<FWord>(); 907 cursor.advance::<FWord>(); 908 cursor.finish(ClipBoxFormat1Marker {}) 909 } 910 } 911 912 /// [ClipBoxFormat1](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record 913 pub type ClipBoxFormat1<'a> = TableRef<'a, ClipBoxFormat1Marker>; 914 915 impl<'a> ClipBoxFormat1<'a> { 916 /// Set to 1. format(&self) -> u8917 pub fn format(&self) -> u8 { 918 let range = self.shape.format_byte_range(); 919 self.data.read_at(range.start).unwrap() 920 } 921 922 /// Minimum x of clip box. x_min(&self) -> FWord923 pub fn x_min(&self) -> FWord { 924 let range = self.shape.x_min_byte_range(); 925 self.data.read_at(range.start).unwrap() 926 } 927 928 /// Minimum y of clip box. y_min(&self) -> FWord929 pub fn y_min(&self) -> FWord { 930 let range = self.shape.y_min_byte_range(); 931 self.data.read_at(range.start).unwrap() 932 } 933 934 /// Maximum x of clip box. x_max(&self) -> FWord935 pub fn x_max(&self) -> FWord { 936 let range = self.shape.x_max_byte_range(); 937 self.data.read_at(range.start).unwrap() 938 } 939 940 /// Maximum y of clip box. y_max(&self) -> FWord941 pub fn y_max(&self) -> FWord { 942 let range = self.shape.y_max_byte_range(); 943 self.data.read_at(range.start).unwrap() 944 } 945 } 946 947 #[cfg(feature = "traversal")] 948 impl<'a> SomeTable<'a> for ClipBoxFormat1<'a> { type_name(&self) -> &str949 fn type_name(&self) -> &str { 950 "ClipBoxFormat1" 951 } get_field(&self, idx: usize) -> Option<Field<'a>>952 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 953 match idx { 954 0usize => Some(Field::new("format", self.format())), 955 1usize => Some(Field::new("x_min", self.x_min())), 956 2usize => Some(Field::new("y_min", self.y_min())), 957 3usize => Some(Field::new("x_max", self.x_max())), 958 4usize => Some(Field::new("y_max", self.y_max())), 959 _ => None, 960 } 961 } 962 } 963 964 #[cfg(feature = "traversal")] 965 impl<'a> std::fmt::Debug for ClipBoxFormat1<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result966 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 967 (self as &dyn SomeTable<'a>).fmt(f) 968 } 969 } 970 971 impl Format<u8> for ClipBoxFormat2Marker { 972 const FORMAT: u8 = 2; 973 } 974 975 /// [ClipBoxFormat2](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record 976 #[derive(Debug, Clone, Copy)] 977 #[doc(hidden)] 978 pub struct ClipBoxFormat2Marker {} 979 980 impl ClipBoxFormat2Marker { format_byte_range(&self) -> Range<usize>981 fn format_byte_range(&self) -> Range<usize> { 982 let start = 0; 983 start..start + u8::RAW_BYTE_LEN 984 } x_min_byte_range(&self) -> Range<usize>985 fn x_min_byte_range(&self) -> Range<usize> { 986 let start = self.format_byte_range().end; 987 start..start + FWord::RAW_BYTE_LEN 988 } y_min_byte_range(&self) -> Range<usize>989 fn y_min_byte_range(&self) -> Range<usize> { 990 let start = self.x_min_byte_range().end; 991 start..start + FWord::RAW_BYTE_LEN 992 } x_max_byte_range(&self) -> Range<usize>993 fn x_max_byte_range(&self) -> Range<usize> { 994 let start = self.y_min_byte_range().end; 995 start..start + FWord::RAW_BYTE_LEN 996 } y_max_byte_range(&self) -> Range<usize>997 fn y_max_byte_range(&self) -> Range<usize> { 998 let start = self.x_max_byte_range().end; 999 start..start + FWord::RAW_BYTE_LEN 1000 } var_index_base_byte_range(&self) -> Range<usize>1001 fn var_index_base_byte_range(&self) -> Range<usize> { 1002 let start = self.y_max_byte_range().end; 1003 start..start + u32::RAW_BYTE_LEN 1004 } 1005 } 1006 1007 impl<'a> FontRead<'a> for ClipBoxFormat2<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1008 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1009 let mut cursor = data.cursor(); 1010 cursor.advance::<u8>(); 1011 cursor.advance::<FWord>(); 1012 cursor.advance::<FWord>(); 1013 cursor.advance::<FWord>(); 1014 cursor.advance::<FWord>(); 1015 cursor.advance::<u32>(); 1016 cursor.finish(ClipBoxFormat2Marker {}) 1017 } 1018 } 1019 1020 /// [ClipBoxFormat2](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record 1021 pub type ClipBoxFormat2<'a> = TableRef<'a, ClipBoxFormat2Marker>; 1022 1023 impl<'a> ClipBoxFormat2<'a> { 1024 /// Set to 2. format(&self) -> u81025 pub fn format(&self) -> u8 { 1026 let range = self.shape.format_byte_range(); 1027 self.data.read_at(range.start).unwrap() 1028 } 1029 1030 /// Minimum x of clip box. For variation, use varIndexBase + 0. x_min(&self) -> FWord1031 pub fn x_min(&self) -> FWord { 1032 let range = self.shape.x_min_byte_range(); 1033 self.data.read_at(range.start).unwrap() 1034 } 1035 1036 /// Minimum y of clip box. For variation, use varIndexBase + 1. y_min(&self) -> FWord1037 pub fn y_min(&self) -> FWord { 1038 let range = self.shape.y_min_byte_range(); 1039 self.data.read_at(range.start).unwrap() 1040 } 1041 1042 /// Maximum x of clip box. For variation, use varIndexBase + 2. x_max(&self) -> FWord1043 pub fn x_max(&self) -> FWord { 1044 let range = self.shape.x_max_byte_range(); 1045 self.data.read_at(range.start).unwrap() 1046 } 1047 1048 /// Maximum y of clip box. For variation, use varIndexBase + 3. y_max(&self) -> FWord1049 pub fn y_max(&self) -> FWord { 1050 let range = self.shape.y_max_byte_range(); 1051 self.data.read_at(range.start).unwrap() 1052 } 1053 1054 /// Base index into DeltaSetIndexMap. var_index_base(&self) -> u321055 pub fn var_index_base(&self) -> u32 { 1056 let range = self.shape.var_index_base_byte_range(); 1057 self.data.read_at(range.start).unwrap() 1058 } 1059 } 1060 1061 #[cfg(feature = "traversal")] 1062 impl<'a> SomeTable<'a> for ClipBoxFormat2<'a> { type_name(&self) -> &str1063 fn type_name(&self) -> &str { 1064 "ClipBoxFormat2" 1065 } get_field(&self, idx: usize) -> Option<Field<'a>>1066 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1067 match idx { 1068 0usize => Some(Field::new("format", self.format())), 1069 1usize => Some(Field::new("x_min", self.x_min())), 1070 2usize => Some(Field::new("y_min", self.y_min())), 1071 3usize => Some(Field::new("x_max", self.x_max())), 1072 4usize => Some(Field::new("y_max", self.y_max())), 1073 5usize => Some(Field::new("var_index_base", self.var_index_base())), 1074 _ => None, 1075 } 1076 } 1077 } 1078 1079 #[cfg(feature = "traversal")] 1080 impl<'a> std::fmt::Debug for ClipBoxFormat2<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1081 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1082 (self as &dyn SomeTable<'a>).fmt(f) 1083 } 1084 } 1085 1086 /// [ColorIndex](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) record 1087 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 1088 #[repr(C)] 1089 #[repr(packed)] 1090 pub struct ColorIndex { 1091 /// Index for a CPAL palette entry. 1092 pub palette_index: BigEndian<u16>, 1093 /// Alpha value. 1094 pub alpha: BigEndian<F2Dot14>, 1095 } 1096 1097 impl ColorIndex { 1098 /// Index for a CPAL palette entry. palette_index(&self) -> u161099 pub fn palette_index(&self) -> u16 { 1100 self.palette_index.get() 1101 } 1102 1103 /// Alpha value. alpha(&self) -> F2Dot141104 pub fn alpha(&self) -> F2Dot14 { 1105 self.alpha.get() 1106 } 1107 } 1108 1109 impl FixedSize for ColorIndex { 1110 const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN; 1111 } 1112 1113 impl sealed::Sealed for ColorIndex {} 1114 1115 /// SAFETY: see the [`FromBytes`] trait documentation. 1116 unsafe impl FromBytes for ColorIndex { this_trait_should_only_be_implemented_in_generated_code()1117 fn this_trait_should_only_be_implemented_in_generated_code() {} 1118 } 1119 1120 #[cfg(feature = "traversal")] 1121 impl<'a> SomeRecord<'a> for ColorIndex { traverse(self, data: FontData<'a>) -> RecordResolver<'a>1122 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 1123 RecordResolver { 1124 name: "ColorIndex", 1125 get_field: Box::new(move |idx, _data| match idx { 1126 0usize => Some(Field::new("palette_index", self.palette_index())), 1127 1usize => Some(Field::new("alpha", self.alpha())), 1128 _ => None, 1129 }), 1130 data, 1131 } 1132 } 1133 } 1134 1135 /// [VarColorIndex](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) record 1136 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 1137 #[repr(C)] 1138 #[repr(packed)] 1139 pub struct VarColorIndex { 1140 /// Index for a CPAL palette entry. 1141 pub palette_index: BigEndian<u16>, 1142 /// Alpha value. For variation, use varIndexBase + 0. 1143 pub alpha: BigEndian<F2Dot14>, 1144 /// Base index into DeltaSetIndexMap. 1145 pub var_index_base: BigEndian<u32>, 1146 } 1147 1148 impl VarColorIndex { 1149 /// Index for a CPAL palette entry. palette_index(&self) -> u161150 pub fn palette_index(&self) -> u16 { 1151 self.palette_index.get() 1152 } 1153 1154 /// Alpha value. For variation, use varIndexBase + 0. alpha(&self) -> F2Dot141155 pub fn alpha(&self) -> F2Dot14 { 1156 self.alpha.get() 1157 } 1158 1159 /// Base index into DeltaSetIndexMap. var_index_base(&self) -> u321160 pub fn var_index_base(&self) -> u32 { 1161 self.var_index_base.get() 1162 } 1163 } 1164 1165 impl FixedSize for VarColorIndex { 1166 const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN + u32::RAW_BYTE_LEN; 1167 } 1168 1169 impl sealed::Sealed for VarColorIndex {} 1170 1171 /// SAFETY: see the [`FromBytes`] trait documentation. 1172 unsafe impl FromBytes for VarColorIndex { this_trait_should_only_be_implemented_in_generated_code()1173 fn this_trait_should_only_be_implemented_in_generated_code() {} 1174 } 1175 1176 #[cfg(feature = "traversal")] 1177 impl<'a> SomeRecord<'a> for VarColorIndex { traverse(self, data: FontData<'a>) -> RecordResolver<'a>1178 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 1179 RecordResolver { 1180 name: "VarColorIndex", 1181 get_field: Box::new(move |idx, _data| match idx { 1182 0usize => Some(Field::new("palette_index", self.palette_index())), 1183 1usize => Some(Field::new("alpha", self.alpha())), 1184 2usize => Some(Field::new("var_index_base", self.var_index_base())), 1185 _ => None, 1186 }), 1187 data, 1188 } 1189 } 1190 } 1191 1192 /// [ColorStop](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) record 1193 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 1194 #[repr(C)] 1195 #[repr(packed)] 1196 pub struct ColorStop { 1197 /// Position on a color line. 1198 pub stop_offset: BigEndian<F2Dot14>, 1199 /// Index for a CPAL palette entry. 1200 pub palette_index: BigEndian<u16>, 1201 /// Alpha value. 1202 pub alpha: BigEndian<F2Dot14>, 1203 } 1204 1205 impl ColorStop { 1206 /// Position on a color line. stop_offset(&self) -> F2Dot141207 pub fn stop_offset(&self) -> F2Dot14 { 1208 self.stop_offset.get() 1209 } 1210 1211 /// Index for a CPAL palette entry. palette_index(&self) -> u161212 pub fn palette_index(&self) -> u16 { 1213 self.palette_index.get() 1214 } 1215 1216 /// Alpha value. alpha(&self) -> F2Dot141217 pub fn alpha(&self) -> F2Dot14 { 1218 self.alpha.get() 1219 } 1220 } 1221 1222 impl FixedSize for ColorStop { 1223 const RAW_BYTE_LEN: usize = F2Dot14::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN; 1224 } 1225 1226 impl sealed::Sealed for ColorStop {} 1227 1228 /// SAFETY: see the [`FromBytes`] trait documentation. 1229 unsafe impl FromBytes for ColorStop { this_trait_should_only_be_implemented_in_generated_code()1230 fn this_trait_should_only_be_implemented_in_generated_code() {} 1231 } 1232 1233 #[cfg(feature = "traversal")] 1234 impl<'a> SomeRecord<'a> for ColorStop { traverse(self, data: FontData<'a>) -> RecordResolver<'a>1235 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 1236 RecordResolver { 1237 name: "ColorStop", 1238 get_field: Box::new(move |idx, _data| match idx { 1239 0usize => Some(Field::new("stop_offset", self.stop_offset())), 1240 1usize => Some(Field::new("palette_index", self.palette_index())), 1241 2usize => Some(Field::new("alpha", self.alpha())), 1242 _ => None, 1243 }), 1244 data, 1245 } 1246 } 1247 } 1248 1249 /// [VarColorStop](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) record 1250 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 1251 #[repr(C)] 1252 #[repr(packed)] 1253 pub struct VarColorStop { 1254 /// Position on a color line. For variation, use varIndexBase + 0. 1255 pub stop_offset: BigEndian<F2Dot14>, 1256 /// Index for a CPAL palette entry. 1257 pub palette_index: BigEndian<u16>, 1258 /// Alpha value. For variation, use varIndexBase + 1. 1259 pub alpha: BigEndian<F2Dot14>, 1260 /// Base index into DeltaSetIndexMap. 1261 pub var_index_base: BigEndian<u32>, 1262 } 1263 1264 impl VarColorStop { 1265 /// Position on a color line. For variation, use varIndexBase + 0. stop_offset(&self) -> F2Dot141266 pub fn stop_offset(&self) -> F2Dot14 { 1267 self.stop_offset.get() 1268 } 1269 1270 /// Index for a CPAL palette entry. palette_index(&self) -> u161271 pub fn palette_index(&self) -> u16 { 1272 self.palette_index.get() 1273 } 1274 1275 /// Alpha value. For variation, use varIndexBase + 1. alpha(&self) -> F2Dot141276 pub fn alpha(&self) -> F2Dot14 { 1277 self.alpha.get() 1278 } 1279 1280 /// Base index into DeltaSetIndexMap. var_index_base(&self) -> u321281 pub fn var_index_base(&self) -> u32 { 1282 self.var_index_base.get() 1283 } 1284 } 1285 1286 impl FixedSize for VarColorStop { 1287 const RAW_BYTE_LEN: usize = 1288 F2Dot14::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN + u32::RAW_BYTE_LEN; 1289 } 1290 1291 impl sealed::Sealed for VarColorStop {} 1292 1293 /// SAFETY: see the [`FromBytes`] trait documentation. 1294 unsafe impl FromBytes for VarColorStop { this_trait_should_only_be_implemented_in_generated_code()1295 fn this_trait_should_only_be_implemented_in_generated_code() {} 1296 } 1297 1298 #[cfg(feature = "traversal")] 1299 impl<'a> SomeRecord<'a> for VarColorStop { traverse(self, data: FontData<'a>) -> RecordResolver<'a>1300 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { 1301 RecordResolver { 1302 name: "VarColorStop", 1303 get_field: Box::new(move |idx, _data| match idx { 1304 0usize => Some(Field::new("stop_offset", self.stop_offset())), 1305 1usize => Some(Field::new("palette_index", self.palette_index())), 1306 2usize => Some(Field::new("alpha", self.alpha())), 1307 3usize => Some(Field::new("var_index_base", self.var_index_base())), 1308 _ => None, 1309 }), 1310 data, 1311 } 1312 } 1313 } 1314 1315 /// [ColorLine](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) table 1316 #[derive(Debug, Clone, Copy)] 1317 #[doc(hidden)] 1318 pub struct ColorLineMarker { 1319 color_stops_byte_len: usize, 1320 } 1321 1322 impl ColorLineMarker { extend_byte_range(&self) -> Range<usize>1323 fn extend_byte_range(&self) -> Range<usize> { 1324 let start = 0; 1325 start..start + Extend::RAW_BYTE_LEN 1326 } num_stops_byte_range(&self) -> Range<usize>1327 fn num_stops_byte_range(&self) -> Range<usize> { 1328 let start = self.extend_byte_range().end; 1329 start..start + u16::RAW_BYTE_LEN 1330 } color_stops_byte_range(&self) -> Range<usize>1331 fn color_stops_byte_range(&self) -> Range<usize> { 1332 let start = self.num_stops_byte_range().end; 1333 start..start + self.color_stops_byte_len 1334 } 1335 } 1336 1337 impl<'a> FontRead<'a> for ColorLine<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1338 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1339 let mut cursor = data.cursor(); 1340 cursor.advance::<Extend>(); 1341 let num_stops: u16 = cursor.read()?; 1342 let color_stops_byte_len = num_stops as usize * ColorStop::RAW_BYTE_LEN; 1343 cursor.advance_by(color_stops_byte_len); 1344 cursor.finish(ColorLineMarker { 1345 color_stops_byte_len, 1346 }) 1347 } 1348 } 1349 1350 /// [ColorLine](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) table 1351 pub type ColorLine<'a> = TableRef<'a, ColorLineMarker>; 1352 1353 impl<'a> ColorLine<'a> { 1354 /// An Extend enum value. extend(&self) -> Extend1355 pub fn extend(&self) -> Extend { 1356 let range = self.shape.extend_byte_range(); 1357 self.data.read_at(range.start).unwrap() 1358 } 1359 1360 /// Number of ColorStop records. num_stops(&self) -> u161361 pub fn num_stops(&self) -> u16 { 1362 let range = self.shape.num_stops_byte_range(); 1363 self.data.read_at(range.start).unwrap() 1364 } 1365 color_stops(&self) -> &'a [ColorStop]1366 pub fn color_stops(&self) -> &'a [ColorStop] { 1367 let range = self.shape.color_stops_byte_range(); 1368 self.data.read_array(range).unwrap() 1369 } 1370 } 1371 1372 #[cfg(feature = "traversal")] 1373 impl<'a> SomeTable<'a> for ColorLine<'a> { type_name(&self) -> &str1374 fn type_name(&self) -> &str { 1375 "ColorLine" 1376 } get_field(&self, idx: usize) -> Option<Field<'a>>1377 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1378 match idx { 1379 0usize => Some(Field::new("extend", self.extend())), 1380 1usize => Some(Field::new("num_stops", self.num_stops())), 1381 2usize => Some(Field::new( 1382 "color_stops", 1383 traversal::FieldType::array_of_records( 1384 stringify!(ColorStop), 1385 self.color_stops(), 1386 self.offset_data(), 1387 ), 1388 )), 1389 _ => None, 1390 } 1391 } 1392 } 1393 1394 #[cfg(feature = "traversal")] 1395 impl<'a> std::fmt::Debug for ColorLine<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1396 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1397 (self as &dyn SomeTable<'a>).fmt(f) 1398 } 1399 } 1400 1401 /// [VarColorLine](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) table 1402 #[derive(Debug, Clone, Copy)] 1403 #[doc(hidden)] 1404 pub struct VarColorLineMarker { 1405 color_stops_byte_len: usize, 1406 } 1407 1408 impl VarColorLineMarker { extend_byte_range(&self) -> Range<usize>1409 fn extend_byte_range(&self) -> Range<usize> { 1410 let start = 0; 1411 start..start + Extend::RAW_BYTE_LEN 1412 } num_stops_byte_range(&self) -> Range<usize>1413 fn num_stops_byte_range(&self) -> Range<usize> { 1414 let start = self.extend_byte_range().end; 1415 start..start + u16::RAW_BYTE_LEN 1416 } color_stops_byte_range(&self) -> Range<usize>1417 fn color_stops_byte_range(&self) -> Range<usize> { 1418 let start = self.num_stops_byte_range().end; 1419 start..start + self.color_stops_byte_len 1420 } 1421 } 1422 1423 impl<'a> FontRead<'a> for VarColorLine<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1424 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1425 let mut cursor = data.cursor(); 1426 cursor.advance::<Extend>(); 1427 let num_stops: u16 = cursor.read()?; 1428 let color_stops_byte_len = num_stops as usize * VarColorStop::RAW_BYTE_LEN; 1429 cursor.advance_by(color_stops_byte_len); 1430 cursor.finish(VarColorLineMarker { 1431 color_stops_byte_len, 1432 }) 1433 } 1434 } 1435 1436 /// [VarColorLine](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) table 1437 pub type VarColorLine<'a> = TableRef<'a, VarColorLineMarker>; 1438 1439 impl<'a> VarColorLine<'a> { 1440 /// An Extend enum value. extend(&self) -> Extend1441 pub fn extend(&self) -> Extend { 1442 let range = self.shape.extend_byte_range(); 1443 self.data.read_at(range.start).unwrap() 1444 } 1445 1446 /// Number of ColorStop records. num_stops(&self) -> u161447 pub fn num_stops(&self) -> u16 { 1448 let range = self.shape.num_stops_byte_range(); 1449 self.data.read_at(range.start).unwrap() 1450 } 1451 1452 /// Allows for variations. color_stops(&self) -> &'a [VarColorStop]1453 pub fn color_stops(&self) -> &'a [VarColorStop] { 1454 let range = self.shape.color_stops_byte_range(); 1455 self.data.read_array(range).unwrap() 1456 } 1457 } 1458 1459 #[cfg(feature = "traversal")] 1460 impl<'a> SomeTable<'a> for VarColorLine<'a> { type_name(&self) -> &str1461 fn type_name(&self) -> &str { 1462 "VarColorLine" 1463 } get_field(&self, idx: usize) -> Option<Field<'a>>1464 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1465 match idx { 1466 0usize => Some(Field::new("extend", self.extend())), 1467 1usize => Some(Field::new("num_stops", self.num_stops())), 1468 2usize => Some(Field::new( 1469 "color_stops", 1470 traversal::FieldType::array_of_records( 1471 stringify!(VarColorStop), 1472 self.color_stops(), 1473 self.offset_data(), 1474 ), 1475 )), 1476 _ => None, 1477 } 1478 } 1479 } 1480 1481 #[cfg(feature = "traversal")] 1482 impl<'a> std::fmt::Debug for VarColorLine<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1483 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1484 (self as &dyn SomeTable<'a>).fmt(f) 1485 } 1486 } 1487 1488 /// [Extend](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) enumeration 1489 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] 1490 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 1491 #[repr(u8)] 1492 #[allow(clippy::manual_non_exhaustive)] 1493 pub enum Extend { 1494 #[default] 1495 Pad = 0, 1496 Repeat = 1, 1497 Reflect = 2, 1498 #[doc(hidden)] 1499 /// If font data is malformed we will map unknown values to this variant 1500 Unknown, 1501 } 1502 1503 impl Extend { 1504 /// Create from a raw scalar. 1505 /// 1506 /// This will never fail; unknown values will be mapped to the `Unknown` variant new(raw: u8) -> Self1507 pub fn new(raw: u8) -> Self { 1508 match raw { 1509 0 => Self::Pad, 1510 1 => Self::Repeat, 1511 2 => Self::Reflect, 1512 _ => Self::Unknown, 1513 } 1514 } 1515 } 1516 1517 impl font_types::Scalar for Extend { 1518 type Raw = <u8 as font_types::Scalar>::Raw; to_raw(self) -> Self::Raw1519 fn to_raw(self) -> Self::Raw { 1520 (self as u8).to_raw() 1521 } from_raw(raw: Self::Raw) -> Self1522 fn from_raw(raw: Self::Raw) -> Self { 1523 let t = <u8>::from_raw(raw); 1524 Self::new(t) 1525 } 1526 } 1527 1528 #[cfg(feature = "traversal")] 1529 impl<'a> From<Extend> for FieldType<'a> { from(src: Extend) -> FieldType<'a>1530 fn from(src: Extend) -> FieldType<'a> { 1531 (src as u8).into() 1532 } 1533 } 1534 1535 /// [Paint](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#paint-tables) tables 1536 #[derive(Clone)] 1537 pub enum Paint<'a> { 1538 ColrLayers(PaintColrLayers<'a>), 1539 Solid(PaintSolid<'a>), 1540 VarSolid(PaintVarSolid<'a>), 1541 LinearGradient(PaintLinearGradient<'a>), 1542 VarLinearGradient(PaintVarLinearGradient<'a>), 1543 RadialGradient(PaintRadialGradient<'a>), 1544 VarRadialGradient(PaintVarRadialGradient<'a>), 1545 SweepGradient(PaintSweepGradient<'a>), 1546 VarSweepGradient(PaintVarSweepGradient<'a>), 1547 Glyph(PaintGlyph<'a>), 1548 ColrGlyph(PaintColrGlyph<'a>), 1549 Transform(PaintTransform<'a>), 1550 VarTransform(PaintVarTransform<'a>), 1551 Translate(PaintTranslate<'a>), 1552 VarTranslate(PaintVarTranslate<'a>), 1553 Scale(PaintScale<'a>), 1554 VarScale(PaintVarScale<'a>), 1555 ScaleAroundCenter(PaintScaleAroundCenter<'a>), 1556 VarScaleAroundCenter(PaintVarScaleAroundCenter<'a>), 1557 ScaleUniform(PaintScaleUniform<'a>), 1558 VarScaleUniform(PaintVarScaleUniform<'a>), 1559 ScaleUniformAroundCenter(PaintScaleUniformAroundCenter<'a>), 1560 VarScaleUniformAroundCenter(PaintVarScaleUniformAroundCenter<'a>), 1561 Rotate(PaintRotate<'a>), 1562 VarRotate(PaintVarRotate<'a>), 1563 RotateAroundCenter(PaintRotateAroundCenter<'a>), 1564 VarRotateAroundCenter(PaintVarRotateAroundCenter<'a>), 1565 Skew(PaintSkew<'a>), 1566 VarSkew(PaintVarSkew<'a>), 1567 SkewAroundCenter(PaintSkewAroundCenter<'a>), 1568 VarSkewAroundCenter(PaintVarSkewAroundCenter<'a>), 1569 Composite(PaintComposite<'a>), 1570 } 1571 1572 impl<'a> Paint<'a> { 1573 /// Set to 1. format(&self) -> u81574 pub fn format(&self) -> u8 { 1575 match self { 1576 Self::ColrLayers(item) => item.format(), 1577 Self::Solid(item) => item.format(), 1578 Self::VarSolid(item) => item.format(), 1579 Self::LinearGradient(item) => item.format(), 1580 Self::VarLinearGradient(item) => item.format(), 1581 Self::RadialGradient(item) => item.format(), 1582 Self::VarRadialGradient(item) => item.format(), 1583 Self::SweepGradient(item) => item.format(), 1584 Self::VarSweepGradient(item) => item.format(), 1585 Self::Glyph(item) => item.format(), 1586 Self::ColrGlyph(item) => item.format(), 1587 Self::Transform(item) => item.format(), 1588 Self::VarTransform(item) => item.format(), 1589 Self::Translate(item) => item.format(), 1590 Self::VarTranslate(item) => item.format(), 1591 Self::Scale(item) => item.format(), 1592 Self::VarScale(item) => item.format(), 1593 Self::ScaleAroundCenter(item) => item.format(), 1594 Self::VarScaleAroundCenter(item) => item.format(), 1595 Self::ScaleUniform(item) => item.format(), 1596 Self::VarScaleUniform(item) => item.format(), 1597 Self::ScaleUniformAroundCenter(item) => item.format(), 1598 Self::VarScaleUniformAroundCenter(item) => item.format(), 1599 Self::Rotate(item) => item.format(), 1600 Self::VarRotate(item) => item.format(), 1601 Self::RotateAroundCenter(item) => item.format(), 1602 Self::VarRotateAroundCenter(item) => item.format(), 1603 Self::Skew(item) => item.format(), 1604 Self::VarSkew(item) => item.format(), 1605 Self::SkewAroundCenter(item) => item.format(), 1606 Self::VarSkewAroundCenter(item) => item.format(), 1607 Self::Composite(item) => item.format(), 1608 } 1609 } 1610 } 1611 1612 impl<'a> FontRead<'a> for Paint<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1613 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1614 let format: u8 = data.read_at(0usize)?; 1615 match format { 1616 PaintColrLayersMarker::FORMAT => Ok(Self::ColrLayers(FontRead::read(data)?)), 1617 PaintSolidMarker::FORMAT => Ok(Self::Solid(FontRead::read(data)?)), 1618 PaintVarSolidMarker::FORMAT => Ok(Self::VarSolid(FontRead::read(data)?)), 1619 PaintLinearGradientMarker::FORMAT => Ok(Self::LinearGradient(FontRead::read(data)?)), 1620 PaintVarLinearGradientMarker::FORMAT => { 1621 Ok(Self::VarLinearGradient(FontRead::read(data)?)) 1622 } 1623 PaintRadialGradientMarker::FORMAT => Ok(Self::RadialGradient(FontRead::read(data)?)), 1624 PaintVarRadialGradientMarker::FORMAT => { 1625 Ok(Self::VarRadialGradient(FontRead::read(data)?)) 1626 } 1627 PaintSweepGradientMarker::FORMAT => Ok(Self::SweepGradient(FontRead::read(data)?)), 1628 PaintVarSweepGradientMarker::FORMAT => { 1629 Ok(Self::VarSweepGradient(FontRead::read(data)?)) 1630 } 1631 PaintGlyphMarker::FORMAT => Ok(Self::Glyph(FontRead::read(data)?)), 1632 PaintColrGlyphMarker::FORMAT => Ok(Self::ColrGlyph(FontRead::read(data)?)), 1633 PaintTransformMarker::FORMAT => Ok(Self::Transform(FontRead::read(data)?)), 1634 PaintVarTransformMarker::FORMAT => Ok(Self::VarTransform(FontRead::read(data)?)), 1635 PaintTranslateMarker::FORMAT => Ok(Self::Translate(FontRead::read(data)?)), 1636 PaintVarTranslateMarker::FORMAT => Ok(Self::VarTranslate(FontRead::read(data)?)), 1637 PaintScaleMarker::FORMAT => Ok(Self::Scale(FontRead::read(data)?)), 1638 PaintVarScaleMarker::FORMAT => Ok(Self::VarScale(FontRead::read(data)?)), 1639 PaintScaleAroundCenterMarker::FORMAT => { 1640 Ok(Self::ScaleAroundCenter(FontRead::read(data)?)) 1641 } 1642 PaintVarScaleAroundCenterMarker::FORMAT => { 1643 Ok(Self::VarScaleAroundCenter(FontRead::read(data)?)) 1644 } 1645 PaintScaleUniformMarker::FORMAT => Ok(Self::ScaleUniform(FontRead::read(data)?)), 1646 PaintVarScaleUniformMarker::FORMAT => Ok(Self::VarScaleUniform(FontRead::read(data)?)), 1647 PaintScaleUniformAroundCenterMarker::FORMAT => { 1648 Ok(Self::ScaleUniformAroundCenter(FontRead::read(data)?)) 1649 } 1650 PaintVarScaleUniformAroundCenterMarker::FORMAT => { 1651 Ok(Self::VarScaleUniformAroundCenter(FontRead::read(data)?)) 1652 } 1653 PaintRotateMarker::FORMAT => Ok(Self::Rotate(FontRead::read(data)?)), 1654 PaintVarRotateMarker::FORMAT => Ok(Self::VarRotate(FontRead::read(data)?)), 1655 PaintRotateAroundCenterMarker::FORMAT => { 1656 Ok(Self::RotateAroundCenter(FontRead::read(data)?)) 1657 } 1658 PaintVarRotateAroundCenterMarker::FORMAT => { 1659 Ok(Self::VarRotateAroundCenter(FontRead::read(data)?)) 1660 } 1661 PaintSkewMarker::FORMAT => Ok(Self::Skew(FontRead::read(data)?)), 1662 PaintVarSkewMarker::FORMAT => Ok(Self::VarSkew(FontRead::read(data)?)), 1663 PaintSkewAroundCenterMarker::FORMAT => { 1664 Ok(Self::SkewAroundCenter(FontRead::read(data)?)) 1665 } 1666 PaintVarSkewAroundCenterMarker::FORMAT => { 1667 Ok(Self::VarSkewAroundCenter(FontRead::read(data)?)) 1668 } 1669 PaintCompositeMarker::FORMAT => Ok(Self::Composite(FontRead::read(data)?)), 1670 other => Err(ReadError::InvalidFormat(other.into())), 1671 } 1672 } 1673 } 1674 1675 #[cfg(feature = "traversal")] 1676 impl<'a> Paint<'a> { dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>1677 fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> { 1678 match self { 1679 Self::ColrLayers(table) => table, 1680 Self::Solid(table) => table, 1681 Self::VarSolid(table) => table, 1682 Self::LinearGradient(table) => table, 1683 Self::VarLinearGradient(table) => table, 1684 Self::RadialGradient(table) => table, 1685 Self::VarRadialGradient(table) => table, 1686 Self::SweepGradient(table) => table, 1687 Self::VarSweepGradient(table) => table, 1688 Self::Glyph(table) => table, 1689 Self::ColrGlyph(table) => table, 1690 Self::Transform(table) => table, 1691 Self::VarTransform(table) => table, 1692 Self::Translate(table) => table, 1693 Self::VarTranslate(table) => table, 1694 Self::Scale(table) => table, 1695 Self::VarScale(table) => table, 1696 Self::ScaleAroundCenter(table) => table, 1697 Self::VarScaleAroundCenter(table) => table, 1698 Self::ScaleUniform(table) => table, 1699 Self::VarScaleUniform(table) => table, 1700 Self::ScaleUniformAroundCenter(table) => table, 1701 Self::VarScaleUniformAroundCenter(table) => table, 1702 Self::Rotate(table) => table, 1703 Self::VarRotate(table) => table, 1704 Self::RotateAroundCenter(table) => table, 1705 Self::VarRotateAroundCenter(table) => table, 1706 Self::Skew(table) => table, 1707 Self::VarSkew(table) => table, 1708 Self::SkewAroundCenter(table) => table, 1709 Self::VarSkewAroundCenter(table) => table, 1710 Self::Composite(table) => table, 1711 } 1712 } 1713 } 1714 1715 #[cfg(feature = "traversal")] 1716 impl<'a> std::fmt::Debug for Paint<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1717 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1718 self.dyn_inner().fmt(f) 1719 } 1720 } 1721 1722 #[cfg(feature = "traversal")] 1723 impl<'a> SomeTable<'a> for Paint<'a> { type_name(&self) -> &str1724 fn type_name(&self) -> &str { 1725 self.dyn_inner().type_name() 1726 } get_field(&self, idx: usize) -> Option<Field<'a>>1727 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1728 self.dyn_inner().get_field(idx) 1729 } 1730 } 1731 1732 impl Format<u8> for PaintColrLayersMarker { 1733 const FORMAT: u8 = 1; 1734 } 1735 1736 /// [PaintColrLayers](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-1-paintcolrlayers) table 1737 #[derive(Debug, Clone, Copy)] 1738 #[doc(hidden)] 1739 pub struct PaintColrLayersMarker {} 1740 1741 impl PaintColrLayersMarker { format_byte_range(&self) -> Range<usize>1742 fn format_byte_range(&self) -> Range<usize> { 1743 let start = 0; 1744 start..start + u8::RAW_BYTE_LEN 1745 } num_layers_byte_range(&self) -> Range<usize>1746 fn num_layers_byte_range(&self) -> Range<usize> { 1747 let start = self.format_byte_range().end; 1748 start..start + u8::RAW_BYTE_LEN 1749 } first_layer_index_byte_range(&self) -> Range<usize>1750 fn first_layer_index_byte_range(&self) -> Range<usize> { 1751 let start = self.num_layers_byte_range().end; 1752 start..start + u32::RAW_BYTE_LEN 1753 } 1754 } 1755 1756 impl<'a> FontRead<'a> for PaintColrLayers<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1757 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1758 let mut cursor = data.cursor(); 1759 cursor.advance::<u8>(); 1760 cursor.advance::<u8>(); 1761 cursor.advance::<u32>(); 1762 cursor.finish(PaintColrLayersMarker {}) 1763 } 1764 } 1765 1766 /// [PaintColrLayers](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-1-paintcolrlayers) table 1767 pub type PaintColrLayers<'a> = TableRef<'a, PaintColrLayersMarker>; 1768 1769 impl<'a> PaintColrLayers<'a> { 1770 /// Set to 1. format(&self) -> u81771 pub fn format(&self) -> u8 { 1772 let range = self.shape.format_byte_range(); 1773 self.data.read_at(range.start).unwrap() 1774 } 1775 1776 /// Number of offsets to paint tables to read from LayerList. num_layers(&self) -> u81777 pub fn num_layers(&self) -> u8 { 1778 let range = self.shape.num_layers_byte_range(); 1779 self.data.read_at(range.start).unwrap() 1780 } 1781 1782 /// Index (base 0) into the LayerList. first_layer_index(&self) -> u321783 pub fn first_layer_index(&self) -> u32 { 1784 let range = self.shape.first_layer_index_byte_range(); 1785 self.data.read_at(range.start).unwrap() 1786 } 1787 } 1788 1789 #[cfg(feature = "traversal")] 1790 impl<'a> SomeTable<'a> for PaintColrLayers<'a> { type_name(&self) -> &str1791 fn type_name(&self) -> &str { 1792 "PaintColrLayers" 1793 } get_field(&self, idx: usize) -> Option<Field<'a>>1794 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1795 match idx { 1796 0usize => Some(Field::new("format", self.format())), 1797 1usize => Some(Field::new("num_layers", self.num_layers())), 1798 2usize => Some(Field::new("first_layer_index", self.first_layer_index())), 1799 _ => None, 1800 } 1801 } 1802 } 1803 1804 #[cfg(feature = "traversal")] 1805 impl<'a> std::fmt::Debug for PaintColrLayers<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1806 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1807 (self as &dyn SomeTable<'a>).fmt(f) 1808 } 1809 } 1810 1811 impl Format<u8> for PaintSolidMarker { 1812 const FORMAT: u8 = 2; 1813 } 1814 1815 /// [PaintSolid](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-2-and-3-paintsolid-paintvarsolid) table 1816 #[derive(Debug, Clone, Copy)] 1817 #[doc(hidden)] 1818 pub struct PaintSolidMarker {} 1819 1820 impl PaintSolidMarker { format_byte_range(&self) -> Range<usize>1821 fn format_byte_range(&self) -> Range<usize> { 1822 let start = 0; 1823 start..start + u8::RAW_BYTE_LEN 1824 } palette_index_byte_range(&self) -> Range<usize>1825 fn palette_index_byte_range(&self) -> Range<usize> { 1826 let start = self.format_byte_range().end; 1827 start..start + u16::RAW_BYTE_LEN 1828 } alpha_byte_range(&self) -> Range<usize>1829 fn alpha_byte_range(&self) -> Range<usize> { 1830 let start = self.palette_index_byte_range().end; 1831 start..start + F2Dot14::RAW_BYTE_LEN 1832 } 1833 } 1834 1835 impl<'a> FontRead<'a> for PaintSolid<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1836 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1837 let mut cursor = data.cursor(); 1838 cursor.advance::<u8>(); 1839 cursor.advance::<u16>(); 1840 cursor.advance::<F2Dot14>(); 1841 cursor.finish(PaintSolidMarker {}) 1842 } 1843 } 1844 1845 /// [PaintSolid](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-2-and-3-paintsolid-paintvarsolid) table 1846 pub type PaintSolid<'a> = TableRef<'a, PaintSolidMarker>; 1847 1848 impl<'a> PaintSolid<'a> { 1849 /// Set to 2. format(&self) -> u81850 pub fn format(&self) -> u8 { 1851 let range = self.shape.format_byte_range(); 1852 self.data.read_at(range.start).unwrap() 1853 } 1854 1855 /// Index for a CPAL palette entry. palette_index(&self) -> u161856 pub fn palette_index(&self) -> u16 { 1857 let range = self.shape.palette_index_byte_range(); 1858 self.data.read_at(range.start).unwrap() 1859 } 1860 1861 /// Alpha value. alpha(&self) -> F2Dot141862 pub fn alpha(&self) -> F2Dot14 { 1863 let range = self.shape.alpha_byte_range(); 1864 self.data.read_at(range.start).unwrap() 1865 } 1866 } 1867 1868 #[cfg(feature = "traversal")] 1869 impl<'a> SomeTable<'a> for PaintSolid<'a> { type_name(&self) -> &str1870 fn type_name(&self) -> &str { 1871 "PaintSolid" 1872 } get_field(&self, idx: usize) -> Option<Field<'a>>1873 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1874 match idx { 1875 0usize => Some(Field::new("format", self.format())), 1876 1usize => Some(Field::new("palette_index", self.palette_index())), 1877 2usize => Some(Field::new("alpha", self.alpha())), 1878 _ => None, 1879 } 1880 } 1881 } 1882 1883 #[cfg(feature = "traversal")] 1884 impl<'a> std::fmt::Debug for PaintSolid<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1885 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1886 (self as &dyn SomeTable<'a>).fmt(f) 1887 } 1888 } 1889 1890 impl Format<u8> for PaintVarSolidMarker { 1891 const FORMAT: u8 = 3; 1892 } 1893 1894 /// [PaintVarSolid](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-2-and-3-paintsolid-paintvarsolid) table 1895 #[derive(Debug, Clone, Copy)] 1896 #[doc(hidden)] 1897 pub struct PaintVarSolidMarker {} 1898 1899 impl PaintVarSolidMarker { format_byte_range(&self) -> Range<usize>1900 fn format_byte_range(&self) -> Range<usize> { 1901 let start = 0; 1902 start..start + u8::RAW_BYTE_LEN 1903 } palette_index_byte_range(&self) -> Range<usize>1904 fn palette_index_byte_range(&self) -> Range<usize> { 1905 let start = self.format_byte_range().end; 1906 start..start + u16::RAW_BYTE_LEN 1907 } alpha_byte_range(&self) -> Range<usize>1908 fn alpha_byte_range(&self) -> Range<usize> { 1909 let start = self.palette_index_byte_range().end; 1910 start..start + F2Dot14::RAW_BYTE_LEN 1911 } var_index_base_byte_range(&self) -> Range<usize>1912 fn var_index_base_byte_range(&self) -> Range<usize> { 1913 let start = self.alpha_byte_range().end; 1914 start..start + u32::RAW_BYTE_LEN 1915 } 1916 } 1917 1918 impl<'a> FontRead<'a> for PaintVarSolid<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>1919 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 1920 let mut cursor = data.cursor(); 1921 cursor.advance::<u8>(); 1922 cursor.advance::<u16>(); 1923 cursor.advance::<F2Dot14>(); 1924 cursor.advance::<u32>(); 1925 cursor.finish(PaintVarSolidMarker {}) 1926 } 1927 } 1928 1929 /// [PaintVarSolid](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-2-and-3-paintsolid-paintvarsolid) table 1930 pub type PaintVarSolid<'a> = TableRef<'a, PaintVarSolidMarker>; 1931 1932 impl<'a> PaintVarSolid<'a> { 1933 /// Set to 3. format(&self) -> u81934 pub fn format(&self) -> u8 { 1935 let range = self.shape.format_byte_range(); 1936 self.data.read_at(range.start).unwrap() 1937 } 1938 1939 /// Index for a CPAL palette entry. palette_index(&self) -> u161940 pub fn palette_index(&self) -> u16 { 1941 let range = self.shape.palette_index_byte_range(); 1942 self.data.read_at(range.start).unwrap() 1943 } 1944 1945 /// Alpha value. For variation, use varIndexBase + 0. alpha(&self) -> F2Dot141946 pub fn alpha(&self) -> F2Dot14 { 1947 let range = self.shape.alpha_byte_range(); 1948 self.data.read_at(range.start).unwrap() 1949 } 1950 1951 /// Base index into DeltaSetIndexMap. var_index_base(&self) -> u321952 pub fn var_index_base(&self) -> u32 { 1953 let range = self.shape.var_index_base_byte_range(); 1954 self.data.read_at(range.start).unwrap() 1955 } 1956 } 1957 1958 #[cfg(feature = "traversal")] 1959 impl<'a> SomeTable<'a> for PaintVarSolid<'a> { type_name(&self) -> &str1960 fn type_name(&self) -> &str { 1961 "PaintVarSolid" 1962 } get_field(&self, idx: usize) -> Option<Field<'a>>1963 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 1964 match idx { 1965 0usize => Some(Field::new("format", self.format())), 1966 1usize => Some(Field::new("palette_index", self.palette_index())), 1967 2usize => Some(Field::new("alpha", self.alpha())), 1968 3usize => Some(Field::new("var_index_base", self.var_index_base())), 1969 _ => None, 1970 } 1971 } 1972 } 1973 1974 #[cfg(feature = "traversal")] 1975 impl<'a> std::fmt::Debug for PaintVarSolid<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1976 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1977 (self as &dyn SomeTable<'a>).fmt(f) 1978 } 1979 } 1980 1981 impl Format<u8> for PaintLinearGradientMarker { 1982 const FORMAT: u8 = 4; 1983 } 1984 1985 /// [PaintLinearGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-4-and-5-paintlineargradient-paintvarlineargradient) table 1986 #[derive(Debug, Clone, Copy)] 1987 #[doc(hidden)] 1988 pub struct PaintLinearGradientMarker {} 1989 1990 impl PaintLinearGradientMarker { format_byte_range(&self) -> Range<usize>1991 fn format_byte_range(&self) -> Range<usize> { 1992 let start = 0; 1993 start..start + u8::RAW_BYTE_LEN 1994 } color_line_offset_byte_range(&self) -> Range<usize>1995 fn color_line_offset_byte_range(&self) -> Range<usize> { 1996 let start = self.format_byte_range().end; 1997 start..start + Offset24::RAW_BYTE_LEN 1998 } x0_byte_range(&self) -> Range<usize>1999 fn x0_byte_range(&self) -> Range<usize> { 2000 let start = self.color_line_offset_byte_range().end; 2001 start..start + FWord::RAW_BYTE_LEN 2002 } y0_byte_range(&self) -> Range<usize>2003 fn y0_byte_range(&self) -> Range<usize> { 2004 let start = self.x0_byte_range().end; 2005 start..start + FWord::RAW_BYTE_LEN 2006 } x1_byte_range(&self) -> Range<usize>2007 fn x1_byte_range(&self) -> Range<usize> { 2008 let start = self.y0_byte_range().end; 2009 start..start + FWord::RAW_BYTE_LEN 2010 } y1_byte_range(&self) -> Range<usize>2011 fn y1_byte_range(&self) -> Range<usize> { 2012 let start = self.x1_byte_range().end; 2013 start..start + FWord::RAW_BYTE_LEN 2014 } x2_byte_range(&self) -> Range<usize>2015 fn x2_byte_range(&self) -> Range<usize> { 2016 let start = self.y1_byte_range().end; 2017 start..start + FWord::RAW_BYTE_LEN 2018 } y2_byte_range(&self) -> Range<usize>2019 fn y2_byte_range(&self) -> Range<usize> { 2020 let start = self.x2_byte_range().end; 2021 start..start + FWord::RAW_BYTE_LEN 2022 } 2023 } 2024 2025 impl<'a> FontRead<'a> for PaintLinearGradient<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>2026 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 2027 let mut cursor = data.cursor(); 2028 cursor.advance::<u8>(); 2029 cursor.advance::<Offset24>(); 2030 cursor.advance::<FWord>(); 2031 cursor.advance::<FWord>(); 2032 cursor.advance::<FWord>(); 2033 cursor.advance::<FWord>(); 2034 cursor.advance::<FWord>(); 2035 cursor.advance::<FWord>(); 2036 cursor.finish(PaintLinearGradientMarker {}) 2037 } 2038 } 2039 2040 /// [PaintLinearGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-4-and-5-paintlineargradient-paintvarlineargradient) table 2041 pub type PaintLinearGradient<'a> = TableRef<'a, PaintLinearGradientMarker>; 2042 2043 impl<'a> PaintLinearGradient<'a> { 2044 /// Set to 4. format(&self) -> u82045 pub fn format(&self) -> u8 { 2046 let range = self.shape.format_byte_range(); 2047 self.data.read_at(range.start).unwrap() 2048 } 2049 2050 /// Offset to ColorLine table. color_line_offset(&self) -> Offset242051 pub fn color_line_offset(&self) -> Offset24 { 2052 let range = self.shape.color_line_offset_byte_range(); 2053 self.data.read_at(range.start).unwrap() 2054 } 2055 2056 /// Attempt to resolve [`color_line_offset`][Self::color_line_offset]. color_line(&self) -> Result<ColorLine<'a>, ReadError>2057 pub fn color_line(&self) -> Result<ColorLine<'a>, ReadError> { 2058 let data = self.data; 2059 self.color_line_offset().resolve(data) 2060 } 2061 2062 /// Start point (p₀) x coordinate. x0(&self) -> FWord2063 pub fn x0(&self) -> FWord { 2064 let range = self.shape.x0_byte_range(); 2065 self.data.read_at(range.start).unwrap() 2066 } 2067 2068 /// Start point (p₀) y coordinate. y0(&self) -> FWord2069 pub fn y0(&self) -> FWord { 2070 let range = self.shape.y0_byte_range(); 2071 self.data.read_at(range.start).unwrap() 2072 } 2073 2074 /// End point (p₁) x coordinate. x1(&self) -> FWord2075 pub fn x1(&self) -> FWord { 2076 let range = self.shape.x1_byte_range(); 2077 self.data.read_at(range.start).unwrap() 2078 } 2079 2080 /// End point (p₁) y coordinate. y1(&self) -> FWord2081 pub fn y1(&self) -> FWord { 2082 let range = self.shape.y1_byte_range(); 2083 self.data.read_at(range.start).unwrap() 2084 } 2085 2086 /// Rotation point (p₂) x coordinate. x2(&self) -> FWord2087 pub fn x2(&self) -> FWord { 2088 let range = self.shape.x2_byte_range(); 2089 self.data.read_at(range.start).unwrap() 2090 } 2091 2092 /// Rotation point (p₂) y coordinate. y2(&self) -> FWord2093 pub fn y2(&self) -> FWord { 2094 let range = self.shape.y2_byte_range(); 2095 self.data.read_at(range.start).unwrap() 2096 } 2097 } 2098 2099 #[cfg(feature = "traversal")] 2100 impl<'a> SomeTable<'a> for PaintLinearGradient<'a> { type_name(&self) -> &str2101 fn type_name(&self) -> &str { 2102 "PaintLinearGradient" 2103 } get_field(&self, idx: usize) -> Option<Field<'a>>2104 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 2105 match idx { 2106 0usize => Some(Field::new("format", self.format())), 2107 1usize => Some(Field::new( 2108 "color_line_offset", 2109 FieldType::offset(self.color_line_offset(), self.color_line()), 2110 )), 2111 2usize => Some(Field::new("x0", self.x0())), 2112 3usize => Some(Field::new("y0", self.y0())), 2113 4usize => Some(Field::new("x1", self.x1())), 2114 5usize => Some(Field::new("y1", self.y1())), 2115 6usize => Some(Field::new("x2", self.x2())), 2116 7usize => Some(Field::new("y2", self.y2())), 2117 _ => None, 2118 } 2119 } 2120 } 2121 2122 #[cfg(feature = "traversal")] 2123 impl<'a> std::fmt::Debug for PaintLinearGradient<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2124 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 2125 (self as &dyn SomeTable<'a>).fmt(f) 2126 } 2127 } 2128 2129 impl Format<u8> for PaintVarLinearGradientMarker { 2130 const FORMAT: u8 = 5; 2131 } 2132 2133 /// [PaintVarLinearGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-4-and-5-paintlineargradient-paintvarlineargradient) table 2134 #[derive(Debug, Clone, Copy)] 2135 #[doc(hidden)] 2136 pub struct PaintVarLinearGradientMarker {} 2137 2138 impl PaintVarLinearGradientMarker { format_byte_range(&self) -> Range<usize>2139 fn format_byte_range(&self) -> Range<usize> { 2140 let start = 0; 2141 start..start + u8::RAW_BYTE_LEN 2142 } color_line_offset_byte_range(&self) -> Range<usize>2143 fn color_line_offset_byte_range(&self) -> Range<usize> { 2144 let start = self.format_byte_range().end; 2145 start..start + Offset24::RAW_BYTE_LEN 2146 } x0_byte_range(&self) -> Range<usize>2147 fn x0_byte_range(&self) -> Range<usize> { 2148 let start = self.color_line_offset_byte_range().end; 2149 start..start + FWord::RAW_BYTE_LEN 2150 } y0_byte_range(&self) -> Range<usize>2151 fn y0_byte_range(&self) -> Range<usize> { 2152 let start = self.x0_byte_range().end; 2153 start..start + FWord::RAW_BYTE_LEN 2154 } x1_byte_range(&self) -> Range<usize>2155 fn x1_byte_range(&self) -> Range<usize> { 2156 let start = self.y0_byte_range().end; 2157 start..start + FWord::RAW_BYTE_LEN 2158 } y1_byte_range(&self) -> Range<usize>2159 fn y1_byte_range(&self) -> Range<usize> { 2160 let start = self.x1_byte_range().end; 2161 start..start + FWord::RAW_BYTE_LEN 2162 } x2_byte_range(&self) -> Range<usize>2163 fn x2_byte_range(&self) -> Range<usize> { 2164 let start = self.y1_byte_range().end; 2165 start..start + FWord::RAW_BYTE_LEN 2166 } y2_byte_range(&self) -> Range<usize>2167 fn y2_byte_range(&self) -> Range<usize> { 2168 let start = self.x2_byte_range().end; 2169 start..start + FWord::RAW_BYTE_LEN 2170 } var_index_base_byte_range(&self) -> Range<usize>2171 fn var_index_base_byte_range(&self) -> Range<usize> { 2172 let start = self.y2_byte_range().end; 2173 start..start + u32::RAW_BYTE_LEN 2174 } 2175 } 2176 2177 impl<'a> FontRead<'a> for PaintVarLinearGradient<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>2178 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 2179 let mut cursor = data.cursor(); 2180 cursor.advance::<u8>(); 2181 cursor.advance::<Offset24>(); 2182 cursor.advance::<FWord>(); 2183 cursor.advance::<FWord>(); 2184 cursor.advance::<FWord>(); 2185 cursor.advance::<FWord>(); 2186 cursor.advance::<FWord>(); 2187 cursor.advance::<FWord>(); 2188 cursor.advance::<u32>(); 2189 cursor.finish(PaintVarLinearGradientMarker {}) 2190 } 2191 } 2192 2193 /// [PaintVarLinearGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-4-and-5-paintlineargradient-paintvarlineargradient) table 2194 pub type PaintVarLinearGradient<'a> = TableRef<'a, PaintVarLinearGradientMarker>; 2195 2196 impl<'a> PaintVarLinearGradient<'a> { 2197 /// Set to 5. format(&self) -> u82198 pub fn format(&self) -> u8 { 2199 let range = self.shape.format_byte_range(); 2200 self.data.read_at(range.start).unwrap() 2201 } 2202 2203 /// Offset to VarColorLine table. color_line_offset(&self) -> Offset242204 pub fn color_line_offset(&self) -> Offset24 { 2205 let range = self.shape.color_line_offset_byte_range(); 2206 self.data.read_at(range.start).unwrap() 2207 } 2208 2209 /// Attempt to resolve [`color_line_offset`][Self::color_line_offset]. color_line(&self) -> Result<VarColorLine<'a>, ReadError>2210 pub fn color_line(&self) -> Result<VarColorLine<'a>, ReadError> { 2211 let data = self.data; 2212 self.color_line_offset().resolve(data) 2213 } 2214 2215 /// Start point (p₀) x coordinate. For variation, use 2216 /// varIndexBase + 0. x0(&self) -> FWord2217 pub fn x0(&self) -> FWord { 2218 let range = self.shape.x0_byte_range(); 2219 self.data.read_at(range.start).unwrap() 2220 } 2221 2222 /// Start point (p₀) y coordinate. For variation, use 2223 /// varIndexBase + 1. y0(&self) -> FWord2224 pub fn y0(&self) -> FWord { 2225 let range = self.shape.y0_byte_range(); 2226 self.data.read_at(range.start).unwrap() 2227 } 2228 2229 /// End point (p₁) x coordinate. For variation, use varIndexBase 2230 /// + 2. x1(&self) -> FWord2231 pub fn x1(&self) -> FWord { 2232 let range = self.shape.x1_byte_range(); 2233 self.data.read_at(range.start).unwrap() 2234 } 2235 2236 /// End point (p₁) y coordinate. For variation, use varIndexBase 2237 /// + 3. y1(&self) -> FWord2238 pub fn y1(&self) -> FWord { 2239 let range = self.shape.y1_byte_range(); 2240 self.data.read_at(range.start).unwrap() 2241 } 2242 2243 /// Rotation point (p₂) x coordinate. For variation, use 2244 /// varIndexBase + 4. x2(&self) -> FWord2245 pub fn x2(&self) -> FWord { 2246 let range = self.shape.x2_byte_range(); 2247 self.data.read_at(range.start).unwrap() 2248 } 2249 2250 /// Rotation point (p₂) y coordinate. For variation, use 2251 /// varIndexBase + 5. y2(&self) -> FWord2252 pub fn y2(&self) -> FWord { 2253 let range = self.shape.y2_byte_range(); 2254 self.data.read_at(range.start).unwrap() 2255 } 2256 2257 /// Base index into DeltaSetIndexMap. var_index_base(&self) -> u322258 pub fn var_index_base(&self) -> u32 { 2259 let range = self.shape.var_index_base_byte_range(); 2260 self.data.read_at(range.start).unwrap() 2261 } 2262 } 2263 2264 #[cfg(feature = "traversal")] 2265 impl<'a> SomeTable<'a> for PaintVarLinearGradient<'a> { type_name(&self) -> &str2266 fn type_name(&self) -> &str { 2267 "PaintVarLinearGradient" 2268 } get_field(&self, idx: usize) -> Option<Field<'a>>2269 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 2270 match idx { 2271 0usize => Some(Field::new("format", self.format())), 2272 1usize => Some(Field::new( 2273 "color_line_offset", 2274 FieldType::offset(self.color_line_offset(), self.color_line()), 2275 )), 2276 2usize => Some(Field::new("x0", self.x0())), 2277 3usize => Some(Field::new("y0", self.y0())), 2278 4usize => Some(Field::new("x1", self.x1())), 2279 5usize => Some(Field::new("y1", self.y1())), 2280 6usize => Some(Field::new("x2", self.x2())), 2281 7usize => Some(Field::new("y2", self.y2())), 2282 8usize => Some(Field::new("var_index_base", self.var_index_base())), 2283 _ => None, 2284 } 2285 } 2286 } 2287 2288 #[cfg(feature = "traversal")] 2289 impl<'a> std::fmt::Debug for PaintVarLinearGradient<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2290 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 2291 (self as &dyn SomeTable<'a>).fmt(f) 2292 } 2293 } 2294 2295 impl Format<u8> for PaintRadialGradientMarker { 2296 const FORMAT: u8 = 6; 2297 } 2298 2299 /// [PaintRadialGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-6-and-7-paintradialgradient-paintvarradialgradient) table 2300 #[derive(Debug, Clone, Copy)] 2301 #[doc(hidden)] 2302 pub struct PaintRadialGradientMarker {} 2303 2304 impl PaintRadialGradientMarker { format_byte_range(&self) -> Range<usize>2305 fn format_byte_range(&self) -> Range<usize> { 2306 let start = 0; 2307 start..start + u8::RAW_BYTE_LEN 2308 } color_line_offset_byte_range(&self) -> Range<usize>2309 fn color_line_offset_byte_range(&self) -> Range<usize> { 2310 let start = self.format_byte_range().end; 2311 start..start + Offset24::RAW_BYTE_LEN 2312 } x0_byte_range(&self) -> Range<usize>2313 fn x0_byte_range(&self) -> Range<usize> { 2314 let start = self.color_line_offset_byte_range().end; 2315 start..start + FWord::RAW_BYTE_LEN 2316 } y0_byte_range(&self) -> Range<usize>2317 fn y0_byte_range(&self) -> Range<usize> { 2318 let start = self.x0_byte_range().end; 2319 start..start + FWord::RAW_BYTE_LEN 2320 } radius0_byte_range(&self) -> Range<usize>2321 fn radius0_byte_range(&self) -> Range<usize> { 2322 let start = self.y0_byte_range().end; 2323 start..start + UfWord::RAW_BYTE_LEN 2324 } x1_byte_range(&self) -> Range<usize>2325 fn x1_byte_range(&self) -> Range<usize> { 2326 let start = self.radius0_byte_range().end; 2327 start..start + FWord::RAW_BYTE_LEN 2328 } y1_byte_range(&self) -> Range<usize>2329 fn y1_byte_range(&self) -> Range<usize> { 2330 let start = self.x1_byte_range().end; 2331 start..start + FWord::RAW_BYTE_LEN 2332 } radius1_byte_range(&self) -> Range<usize>2333 fn radius1_byte_range(&self) -> Range<usize> { 2334 let start = self.y1_byte_range().end; 2335 start..start + UfWord::RAW_BYTE_LEN 2336 } 2337 } 2338 2339 impl<'a> FontRead<'a> for PaintRadialGradient<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>2340 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 2341 let mut cursor = data.cursor(); 2342 cursor.advance::<u8>(); 2343 cursor.advance::<Offset24>(); 2344 cursor.advance::<FWord>(); 2345 cursor.advance::<FWord>(); 2346 cursor.advance::<UfWord>(); 2347 cursor.advance::<FWord>(); 2348 cursor.advance::<FWord>(); 2349 cursor.advance::<UfWord>(); 2350 cursor.finish(PaintRadialGradientMarker {}) 2351 } 2352 } 2353 2354 /// [PaintRadialGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-6-and-7-paintradialgradient-paintvarradialgradient) table 2355 pub type PaintRadialGradient<'a> = TableRef<'a, PaintRadialGradientMarker>; 2356 2357 impl<'a> PaintRadialGradient<'a> { 2358 /// Set to 6. format(&self) -> u82359 pub fn format(&self) -> u8 { 2360 let range = self.shape.format_byte_range(); 2361 self.data.read_at(range.start).unwrap() 2362 } 2363 2364 /// Offset to ColorLine table. color_line_offset(&self) -> Offset242365 pub fn color_line_offset(&self) -> Offset24 { 2366 let range = self.shape.color_line_offset_byte_range(); 2367 self.data.read_at(range.start).unwrap() 2368 } 2369 2370 /// Attempt to resolve [`color_line_offset`][Self::color_line_offset]. color_line(&self) -> Result<ColorLine<'a>, ReadError>2371 pub fn color_line(&self) -> Result<ColorLine<'a>, ReadError> { 2372 let data = self.data; 2373 self.color_line_offset().resolve(data) 2374 } 2375 2376 /// Start circle center x coordinate. x0(&self) -> FWord2377 pub fn x0(&self) -> FWord { 2378 let range = self.shape.x0_byte_range(); 2379 self.data.read_at(range.start).unwrap() 2380 } 2381 2382 /// Start circle center y coordinate. y0(&self) -> FWord2383 pub fn y0(&self) -> FWord { 2384 let range = self.shape.y0_byte_range(); 2385 self.data.read_at(range.start).unwrap() 2386 } 2387 2388 /// Start circle radius. radius0(&self) -> UfWord2389 pub fn radius0(&self) -> UfWord { 2390 let range = self.shape.radius0_byte_range(); 2391 self.data.read_at(range.start).unwrap() 2392 } 2393 2394 /// End circle center x coordinate. x1(&self) -> FWord2395 pub fn x1(&self) -> FWord { 2396 let range = self.shape.x1_byte_range(); 2397 self.data.read_at(range.start).unwrap() 2398 } 2399 2400 /// End circle center y coordinate. y1(&self) -> FWord2401 pub fn y1(&self) -> FWord { 2402 let range = self.shape.y1_byte_range(); 2403 self.data.read_at(range.start).unwrap() 2404 } 2405 2406 /// End circle radius. radius1(&self) -> UfWord2407 pub fn radius1(&self) -> UfWord { 2408 let range = self.shape.radius1_byte_range(); 2409 self.data.read_at(range.start).unwrap() 2410 } 2411 } 2412 2413 #[cfg(feature = "traversal")] 2414 impl<'a> SomeTable<'a> for PaintRadialGradient<'a> { type_name(&self) -> &str2415 fn type_name(&self) -> &str { 2416 "PaintRadialGradient" 2417 } get_field(&self, idx: usize) -> Option<Field<'a>>2418 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 2419 match idx { 2420 0usize => Some(Field::new("format", self.format())), 2421 1usize => Some(Field::new( 2422 "color_line_offset", 2423 FieldType::offset(self.color_line_offset(), self.color_line()), 2424 )), 2425 2usize => Some(Field::new("x0", self.x0())), 2426 3usize => Some(Field::new("y0", self.y0())), 2427 4usize => Some(Field::new("radius0", self.radius0())), 2428 5usize => Some(Field::new("x1", self.x1())), 2429 6usize => Some(Field::new("y1", self.y1())), 2430 7usize => Some(Field::new("radius1", self.radius1())), 2431 _ => None, 2432 } 2433 } 2434 } 2435 2436 #[cfg(feature = "traversal")] 2437 impl<'a> std::fmt::Debug for PaintRadialGradient<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2438 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 2439 (self as &dyn SomeTable<'a>).fmt(f) 2440 } 2441 } 2442 2443 impl Format<u8> for PaintVarRadialGradientMarker { 2444 const FORMAT: u8 = 7; 2445 } 2446 2447 /// [PaintVarRadialGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-6-and-7-paintradialgradient-paintvarradialgradient) table 2448 #[derive(Debug, Clone, Copy)] 2449 #[doc(hidden)] 2450 pub struct PaintVarRadialGradientMarker {} 2451 2452 impl PaintVarRadialGradientMarker { format_byte_range(&self) -> Range<usize>2453 fn format_byte_range(&self) -> Range<usize> { 2454 let start = 0; 2455 start..start + u8::RAW_BYTE_LEN 2456 } color_line_offset_byte_range(&self) -> Range<usize>2457 fn color_line_offset_byte_range(&self) -> Range<usize> { 2458 let start = self.format_byte_range().end; 2459 start..start + Offset24::RAW_BYTE_LEN 2460 } x0_byte_range(&self) -> Range<usize>2461 fn x0_byte_range(&self) -> Range<usize> { 2462 let start = self.color_line_offset_byte_range().end; 2463 start..start + FWord::RAW_BYTE_LEN 2464 } y0_byte_range(&self) -> Range<usize>2465 fn y0_byte_range(&self) -> Range<usize> { 2466 let start = self.x0_byte_range().end; 2467 start..start + FWord::RAW_BYTE_LEN 2468 } radius0_byte_range(&self) -> Range<usize>2469 fn radius0_byte_range(&self) -> Range<usize> { 2470 let start = self.y0_byte_range().end; 2471 start..start + UfWord::RAW_BYTE_LEN 2472 } x1_byte_range(&self) -> Range<usize>2473 fn x1_byte_range(&self) -> Range<usize> { 2474 let start = self.radius0_byte_range().end; 2475 start..start + FWord::RAW_BYTE_LEN 2476 } y1_byte_range(&self) -> Range<usize>2477 fn y1_byte_range(&self) -> Range<usize> { 2478 let start = self.x1_byte_range().end; 2479 start..start + FWord::RAW_BYTE_LEN 2480 } radius1_byte_range(&self) -> Range<usize>2481 fn radius1_byte_range(&self) -> Range<usize> { 2482 let start = self.y1_byte_range().end; 2483 start..start + UfWord::RAW_BYTE_LEN 2484 } var_index_base_byte_range(&self) -> Range<usize>2485 fn var_index_base_byte_range(&self) -> Range<usize> { 2486 let start = self.radius1_byte_range().end; 2487 start..start + u32::RAW_BYTE_LEN 2488 } 2489 } 2490 2491 impl<'a> FontRead<'a> for PaintVarRadialGradient<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>2492 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 2493 let mut cursor = data.cursor(); 2494 cursor.advance::<u8>(); 2495 cursor.advance::<Offset24>(); 2496 cursor.advance::<FWord>(); 2497 cursor.advance::<FWord>(); 2498 cursor.advance::<UfWord>(); 2499 cursor.advance::<FWord>(); 2500 cursor.advance::<FWord>(); 2501 cursor.advance::<UfWord>(); 2502 cursor.advance::<u32>(); 2503 cursor.finish(PaintVarRadialGradientMarker {}) 2504 } 2505 } 2506 2507 /// [PaintVarRadialGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-6-and-7-paintradialgradient-paintvarradialgradient) table 2508 pub type PaintVarRadialGradient<'a> = TableRef<'a, PaintVarRadialGradientMarker>; 2509 2510 impl<'a> PaintVarRadialGradient<'a> { 2511 /// Set to 7. format(&self) -> u82512 pub fn format(&self) -> u8 { 2513 let range = self.shape.format_byte_range(); 2514 self.data.read_at(range.start).unwrap() 2515 } 2516 2517 /// Offset to VarColorLine table. color_line_offset(&self) -> Offset242518 pub fn color_line_offset(&self) -> Offset24 { 2519 let range = self.shape.color_line_offset_byte_range(); 2520 self.data.read_at(range.start).unwrap() 2521 } 2522 2523 /// Attempt to resolve [`color_line_offset`][Self::color_line_offset]. color_line(&self) -> Result<VarColorLine<'a>, ReadError>2524 pub fn color_line(&self) -> Result<VarColorLine<'a>, ReadError> { 2525 let data = self.data; 2526 self.color_line_offset().resolve(data) 2527 } 2528 2529 /// Start circle center x coordinate. For variation, use 2530 /// varIndexBase + 0. x0(&self) -> FWord2531 pub fn x0(&self) -> FWord { 2532 let range = self.shape.x0_byte_range(); 2533 self.data.read_at(range.start).unwrap() 2534 } 2535 2536 /// Start circle center y coordinate. For variation, use 2537 /// varIndexBase + 1. y0(&self) -> FWord2538 pub fn y0(&self) -> FWord { 2539 let range = self.shape.y0_byte_range(); 2540 self.data.read_at(range.start).unwrap() 2541 } 2542 2543 /// Start circle radius. For variation, use varIndexBase + 2. radius0(&self) -> UfWord2544 pub fn radius0(&self) -> UfWord { 2545 let range = self.shape.radius0_byte_range(); 2546 self.data.read_at(range.start).unwrap() 2547 } 2548 2549 /// End circle center x coordinate. For variation, use varIndexBase 2550 /// + 3. x1(&self) -> FWord2551 pub fn x1(&self) -> FWord { 2552 let range = self.shape.x1_byte_range(); 2553 self.data.read_at(range.start).unwrap() 2554 } 2555 2556 /// End circle center y coordinate. For variation, use varIndexBase 2557 /// + 4. y1(&self) -> FWord2558 pub fn y1(&self) -> FWord { 2559 let range = self.shape.y1_byte_range(); 2560 self.data.read_at(range.start).unwrap() 2561 } 2562 2563 /// End circle radius. For variation, use varIndexBase + 5. radius1(&self) -> UfWord2564 pub fn radius1(&self) -> UfWord { 2565 let range = self.shape.radius1_byte_range(); 2566 self.data.read_at(range.start).unwrap() 2567 } 2568 2569 /// Base index into DeltaSetIndexMap. var_index_base(&self) -> u322570 pub fn var_index_base(&self) -> u32 { 2571 let range = self.shape.var_index_base_byte_range(); 2572 self.data.read_at(range.start).unwrap() 2573 } 2574 } 2575 2576 #[cfg(feature = "traversal")] 2577 impl<'a> SomeTable<'a> for PaintVarRadialGradient<'a> { type_name(&self) -> &str2578 fn type_name(&self) -> &str { 2579 "PaintVarRadialGradient" 2580 } get_field(&self, idx: usize) -> Option<Field<'a>>2581 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 2582 match idx { 2583 0usize => Some(Field::new("format", self.format())), 2584 1usize => Some(Field::new( 2585 "color_line_offset", 2586 FieldType::offset(self.color_line_offset(), self.color_line()), 2587 )), 2588 2usize => Some(Field::new("x0", self.x0())), 2589 3usize => Some(Field::new("y0", self.y0())), 2590 4usize => Some(Field::new("radius0", self.radius0())), 2591 5usize => Some(Field::new("x1", self.x1())), 2592 6usize => Some(Field::new("y1", self.y1())), 2593 7usize => Some(Field::new("radius1", self.radius1())), 2594 8usize => Some(Field::new("var_index_base", self.var_index_base())), 2595 _ => None, 2596 } 2597 } 2598 } 2599 2600 #[cfg(feature = "traversal")] 2601 impl<'a> std::fmt::Debug for PaintVarRadialGradient<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2602 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 2603 (self as &dyn SomeTable<'a>).fmt(f) 2604 } 2605 } 2606 2607 impl Format<u8> for PaintSweepGradientMarker { 2608 const FORMAT: u8 = 8; 2609 } 2610 2611 /// [PaintSweepGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-8-and-9-paintsweepgradient-paintvarsweepgradient) table 2612 #[derive(Debug, Clone, Copy)] 2613 #[doc(hidden)] 2614 pub struct PaintSweepGradientMarker {} 2615 2616 impl PaintSweepGradientMarker { format_byte_range(&self) -> Range<usize>2617 fn format_byte_range(&self) -> Range<usize> { 2618 let start = 0; 2619 start..start + u8::RAW_BYTE_LEN 2620 } color_line_offset_byte_range(&self) -> Range<usize>2621 fn color_line_offset_byte_range(&self) -> Range<usize> { 2622 let start = self.format_byte_range().end; 2623 start..start + Offset24::RAW_BYTE_LEN 2624 } center_x_byte_range(&self) -> Range<usize>2625 fn center_x_byte_range(&self) -> Range<usize> { 2626 let start = self.color_line_offset_byte_range().end; 2627 start..start + FWord::RAW_BYTE_LEN 2628 } center_y_byte_range(&self) -> Range<usize>2629 fn center_y_byte_range(&self) -> Range<usize> { 2630 let start = self.center_x_byte_range().end; 2631 start..start + FWord::RAW_BYTE_LEN 2632 } start_angle_byte_range(&self) -> Range<usize>2633 fn start_angle_byte_range(&self) -> Range<usize> { 2634 let start = self.center_y_byte_range().end; 2635 start..start + F2Dot14::RAW_BYTE_LEN 2636 } end_angle_byte_range(&self) -> Range<usize>2637 fn end_angle_byte_range(&self) -> Range<usize> { 2638 let start = self.start_angle_byte_range().end; 2639 start..start + F2Dot14::RAW_BYTE_LEN 2640 } 2641 } 2642 2643 impl<'a> FontRead<'a> for PaintSweepGradient<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>2644 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 2645 let mut cursor = data.cursor(); 2646 cursor.advance::<u8>(); 2647 cursor.advance::<Offset24>(); 2648 cursor.advance::<FWord>(); 2649 cursor.advance::<FWord>(); 2650 cursor.advance::<F2Dot14>(); 2651 cursor.advance::<F2Dot14>(); 2652 cursor.finish(PaintSweepGradientMarker {}) 2653 } 2654 } 2655 2656 /// [PaintSweepGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-8-and-9-paintsweepgradient-paintvarsweepgradient) table 2657 pub type PaintSweepGradient<'a> = TableRef<'a, PaintSweepGradientMarker>; 2658 2659 impl<'a> PaintSweepGradient<'a> { 2660 /// Set to 8. format(&self) -> u82661 pub fn format(&self) -> u8 { 2662 let range = self.shape.format_byte_range(); 2663 self.data.read_at(range.start).unwrap() 2664 } 2665 2666 /// Offset to ColorLine table. color_line_offset(&self) -> Offset242667 pub fn color_line_offset(&self) -> Offset24 { 2668 let range = self.shape.color_line_offset_byte_range(); 2669 self.data.read_at(range.start).unwrap() 2670 } 2671 2672 /// Attempt to resolve [`color_line_offset`][Self::color_line_offset]. color_line(&self) -> Result<ColorLine<'a>, ReadError>2673 pub fn color_line(&self) -> Result<ColorLine<'a>, ReadError> { 2674 let data = self.data; 2675 self.color_line_offset().resolve(data) 2676 } 2677 2678 /// Center x coordinate. center_x(&self) -> FWord2679 pub fn center_x(&self) -> FWord { 2680 let range = self.shape.center_x_byte_range(); 2681 self.data.read_at(range.start).unwrap() 2682 } 2683 2684 /// Center y coordinate. center_y(&self) -> FWord2685 pub fn center_y(&self) -> FWord { 2686 let range = self.shape.center_y_byte_range(); 2687 self.data.read_at(range.start).unwrap() 2688 } 2689 2690 /// Start of the angular range of the gradient, 180° in 2691 /// counter-clockwise degrees per 1.0 of value. start_angle(&self) -> F2Dot142692 pub fn start_angle(&self) -> F2Dot14 { 2693 let range = self.shape.start_angle_byte_range(); 2694 self.data.read_at(range.start).unwrap() 2695 } 2696 2697 /// End of the angular range of the gradient, 180° in 2698 /// counter-clockwise degrees per 1.0 of value. end_angle(&self) -> F2Dot142699 pub fn end_angle(&self) -> F2Dot14 { 2700 let range = self.shape.end_angle_byte_range(); 2701 self.data.read_at(range.start).unwrap() 2702 } 2703 } 2704 2705 #[cfg(feature = "traversal")] 2706 impl<'a> SomeTable<'a> for PaintSweepGradient<'a> { type_name(&self) -> &str2707 fn type_name(&self) -> &str { 2708 "PaintSweepGradient" 2709 } get_field(&self, idx: usize) -> Option<Field<'a>>2710 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 2711 match idx { 2712 0usize => Some(Field::new("format", self.format())), 2713 1usize => Some(Field::new( 2714 "color_line_offset", 2715 FieldType::offset(self.color_line_offset(), self.color_line()), 2716 )), 2717 2usize => Some(Field::new("center_x", self.center_x())), 2718 3usize => Some(Field::new("center_y", self.center_y())), 2719 4usize => Some(Field::new("start_angle", self.start_angle())), 2720 5usize => Some(Field::new("end_angle", self.end_angle())), 2721 _ => None, 2722 } 2723 } 2724 } 2725 2726 #[cfg(feature = "traversal")] 2727 impl<'a> std::fmt::Debug for PaintSweepGradient<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2728 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 2729 (self as &dyn SomeTable<'a>).fmt(f) 2730 } 2731 } 2732 2733 impl Format<u8> for PaintVarSweepGradientMarker { 2734 const FORMAT: u8 = 9; 2735 } 2736 2737 /// [PaintVarSweepGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-8-and-9-paintsweepgradient-paintvarsweepgradient) table 2738 #[derive(Debug, Clone, Copy)] 2739 #[doc(hidden)] 2740 pub struct PaintVarSweepGradientMarker {} 2741 2742 impl PaintVarSweepGradientMarker { format_byte_range(&self) -> Range<usize>2743 fn format_byte_range(&self) -> Range<usize> { 2744 let start = 0; 2745 start..start + u8::RAW_BYTE_LEN 2746 } color_line_offset_byte_range(&self) -> Range<usize>2747 fn color_line_offset_byte_range(&self) -> Range<usize> { 2748 let start = self.format_byte_range().end; 2749 start..start + Offset24::RAW_BYTE_LEN 2750 } center_x_byte_range(&self) -> Range<usize>2751 fn center_x_byte_range(&self) -> Range<usize> { 2752 let start = self.color_line_offset_byte_range().end; 2753 start..start + FWord::RAW_BYTE_LEN 2754 } center_y_byte_range(&self) -> Range<usize>2755 fn center_y_byte_range(&self) -> Range<usize> { 2756 let start = self.center_x_byte_range().end; 2757 start..start + FWord::RAW_BYTE_LEN 2758 } start_angle_byte_range(&self) -> Range<usize>2759 fn start_angle_byte_range(&self) -> Range<usize> { 2760 let start = self.center_y_byte_range().end; 2761 start..start + F2Dot14::RAW_BYTE_LEN 2762 } end_angle_byte_range(&self) -> Range<usize>2763 fn end_angle_byte_range(&self) -> Range<usize> { 2764 let start = self.start_angle_byte_range().end; 2765 start..start + F2Dot14::RAW_BYTE_LEN 2766 } var_index_base_byte_range(&self) -> Range<usize>2767 fn var_index_base_byte_range(&self) -> Range<usize> { 2768 let start = self.end_angle_byte_range().end; 2769 start..start + u32::RAW_BYTE_LEN 2770 } 2771 } 2772 2773 impl<'a> FontRead<'a> for PaintVarSweepGradient<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>2774 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 2775 let mut cursor = data.cursor(); 2776 cursor.advance::<u8>(); 2777 cursor.advance::<Offset24>(); 2778 cursor.advance::<FWord>(); 2779 cursor.advance::<FWord>(); 2780 cursor.advance::<F2Dot14>(); 2781 cursor.advance::<F2Dot14>(); 2782 cursor.advance::<u32>(); 2783 cursor.finish(PaintVarSweepGradientMarker {}) 2784 } 2785 } 2786 2787 /// [PaintVarSweepGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-8-and-9-paintsweepgradient-paintvarsweepgradient) table 2788 pub type PaintVarSweepGradient<'a> = TableRef<'a, PaintVarSweepGradientMarker>; 2789 2790 impl<'a> PaintVarSweepGradient<'a> { 2791 /// Set to 9. format(&self) -> u82792 pub fn format(&self) -> u8 { 2793 let range = self.shape.format_byte_range(); 2794 self.data.read_at(range.start).unwrap() 2795 } 2796 2797 /// Offset to VarColorLine table. color_line_offset(&self) -> Offset242798 pub fn color_line_offset(&self) -> Offset24 { 2799 let range = self.shape.color_line_offset_byte_range(); 2800 self.data.read_at(range.start).unwrap() 2801 } 2802 2803 /// Attempt to resolve [`color_line_offset`][Self::color_line_offset]. color_line(&self) -> Result<VarColorLine<'a>, ReadError>2804 pub fn color_line(&self) -> Result<VarColorLine<'a>, ReadError> { 2805 let data = self.data; 2806 self.color_line_offset().resolve(data) 2807 } 2808 2809 /// Center x coordinate. For variation, use varIndexBase + 0. center_x(&self) -> FWord2810 pub fn center_x(&self) -> FWord { 2811 let range = self.shape.center_x_byte_range(); 2812 self.data.read_at(range.start).unwrap() 2813 } 2814 2815 /// Center y coordinate. For variation, use varIndexBase + 1. center_y(&self) -> FWord2816 pub fn center_y(&self) -> FWord { 2817 let range = self.shape.center_y_byte_range(); 2818 self.data.read_at(range.start).unwrap() 2819 } 2820 2821 /// Start of the angular range of the gradient, 180° in 2822 /// counter-clockwise degrees per 1.0 of value. For variation, use 2823 /// varIndexBase + 2. start_angle(&self) -> F2Dot142824 pub fn start_angle(&self) -> F2Dot14 { 2825 let range = self.shape.start_angle_byte_range(); 2826 self.data.read_at(range.start).unwrap() 2827 } 2828 2829 /// End of the angular range of the gradient, 180° in 2830 /// counter-clockwise degrees per 1.0 of value. For variation, use 2831 /// varIndexBase + 3. end_angle(&self) -> F2Dot142832 pub fn end_angle(&self) -> F2Dot14 { 2833 let range = self.shape.end_angle_byte_range(); 2834 self.data.read_at(range.start).unwrap() 2835 } 2836 2837 /// Base index into DeltaSetIndexMap. var_index_base(&self) -> u322838 pub fn var_index_base(&self) -> u32 { 2839 let range = self.shape.var_index_base_byte_range(); 2840 self.data.read_at(range.start).unwrap() 2841 } 2842 } 2843 2844 #[cfg(feature = "traversal")] 2845 impl<'a> SomeTable<'a> for PaintVarSweepGradient<'a> { type_name(&self) -> &str2846 fn type_name(&self) -> &str { 2847 "PaintVarSweepGradient" 2848 } get_field(&self, idx: usize) -> Option<Field<'a>>2849 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 2850 match idx { 2851 0usize => Some(Field::new("format", self.format())), 2852 1usize => Some(Field::new( 2853 "color_line_offset", 2854 FieldType::offset(self.color_line_offset(), self.color_line()), 2855 )), 2856 2usize => Some(Field::new("center_x", self.center_x())), 2857 3usize => Some(Field::new("center_y", self.center_y())), 2858 4usize => Some(Field::new("start_angle", self.start_angle())), 2859 5usize => Some(Field::new("end_angle", self.end_angle())), 2860 6usize => Some(Field::new("var_index_base", self.var_index_base())), 2861 _ => None, 2862 } 2863 } 2864 } 2865 2866 #[cfg(feature = "traversal")] 2867 impl<'a> std::fmt::Debug for PaintVarSweepGradient<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2868 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 2869 (self as &dyn SomeTable<'a>).fmt(f) 2870 } 2871 } 2872 2873 impl Format<u8> for PaintGlyphMarker { 2874 const FORMAT: u8 = 10; 2875 } 2876 2877 /// [PaintGlyph](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-10-paintglyph) table 2878 #[derive(Debug, Clone, Copy)] 2879 #[doc(hidden)] 2880 pub struct PaintGlyphMarker {} 2881 2882 impl PaintGlyphMarker { format_byte_range(&self) -> Range<usize>2883 fn format_byte_range(&self) -> Range<usize> { 2884 let start = 0; 2885 start..start + u8::RAW_BYTE_LEN 2886 } paint_offset_byte_range(&self) -> Range<usize>2887 fn paint_offset_byte_range(&self) -> Range<usize> { 2888 let start = self.format_byte_range().end; 2889 start..start + Offset24::RAW_BYTE_LEN 2890 } glyph_id_byte_range(&self) -> Range<usize>2891 fn glyph_id_byte_range(&self) -> Range<usize> { 2892 let start = self.paint_offset_byte_range().end; 2893 start..start + GlyphId::RAW_BYTE_LEN 2894 } 2895 } 2896 2897 impl<'a> FontRead<'a> for PaintGlyph<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>2898 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 2899 let mut cursor = data.cursor(); 2900 cursor.advance::<u8>(); 2901 cursor.advance::<Offset24>(); 2902 cursor.advance::<GlyphId>(); 2903 cursor.finish(PaintGlyphMarker {}) 2904 } 2905 } 2906 2907 /// [PaintGlyph](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-10-paintglyph) table 2908 pub type PaintGlyph<'a> = TableRef<'a, PaintGlyphMarker>; 2909 2910 impl<'a> PaintGlyph<'a> { 2911 /// Set to 10. format(&self) -> u82912 pub fn format(&self) -> u8 { 2913 let range = self.shape.format_byte_range(); 2914 self.data.read_at(range.start).unwrap() 2915 } 2916 2917 /// Offset to a Paint table. paint_offset(&self) -> Offset242918 pub fn paint_offset(&self) -> Offset24 { 2919 let range = self.shape.paint_offset_byte_range(); 2920 self.data.read_at(range.start).unwrap() 2921 } 2922 2923 /// Attempt to resolve [`paint_offset`][Self::paint_offset]. paint(&self) -> Result<Paint<'a>, ReadError>2924 pub fn paint(&self) -> Result<Paint<'a>, ReadError> { 2925 let data = self.data; 2926 self.paint_offset().resolve(data) 2927 } 2928 2929 /// Glyph ID for the source outline. glyph_id(&self) -> GlyphId2930 pub fn glyph_id(&self) -> GlyphId { 2931 let range = self.shape.glyph_id_byte_range(); 2932 self.data.read_at(range.start).unwrap() 2933 } 2934 } 2935 2936 #[cfg(feature = "traversal")] 2937 impl<'a> SomeTable<'a> for PaintGlyph<'a> { type_name(&self) -> &str2938 fn type_name(&self) -> &str { 2939 "PaintGlyph" 2940 } get_field(&self, idx: usize) -> Option<Field<'a>>2941 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 2942 match idx { 2943 0usize => Some(Field::new("format", self.format())), 2944 1usize => Some(Field::new( 2945 "paint_offset", 2946 FieldType::offset(self.paint_offset(), self.paint()), 2947 )), 2948 2usize => Some(Field::new("glyph_id", self.glyph_id())), 2949 _ => None, 2950 } 2951 } 2952 } 2953 2954 #[cfg(feature = "traversal")] 2955 impl<'a> std::fmt::Debug for PaintGlyph<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2956 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 2957 (self as &dyn SomeTable<'a>).fmt(f) 2958 } 2959 } 2960 2961 impl Format<u8> for PaintColrGlyphMarker { 2962 const FORMAT: u8 = 11; 2963 } 2964 2965 /// [PaintColrGlyph](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-11-paintcolrglyph) table 2966 #[derive(Debug, Clone, Copy)] 2967 #[doc(hidden)] 2968 pub struct PaintColrGlyphMarker {} 2969 2970 impl PaintColrGlyphMarker { format_byte_range(&self) -> Range<usize>2971 fn format_byte_range(&self) -> Range<usize> { 2972 let start = 0; 2973 start..start + u8::RAW_BYTE_LEN 2974 } glyph_id_byte_range(&self) -> Range<usize>2975 fn glyph_id_byte_range(&self) -> Range<usize> { 2976 let start = self.format_byte_range().end; 2977 start..start + GlyphId::RAW_BYTE_LEN 2978 } 2979 } 2980 2981 impl<'a> FontRead<'a> for PaintColrGlyph<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>2982 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 2983 let mut cursor = data.cursor(); 2984 cursor.advance::<u8>(); 2985 cursor.advance::<GlyphId>(); 2986 cursor.finish(PaintColrGlyphMarker {}) 2987 } 2988 } 2989 2990 /// [PaintColrGlyph](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-11-paintcolrglyph) table 2991 pub type PaintColrGlyph<'a> = TableRef<'a, PaintColrGlyphMarker>; 2992 2993 impl<'a> PaintColrGlyph<'a> { 2994 /// Set to 11. format(&self) -> u82995 pub fn format(&self) -> u8 { 2996 let range = self.shape.format_byte_range(); 2997 self.data.read_at(range.start).unwrap() 2998 } 2999 3000 /// Glyph ID for a BaseGlyphList base glyph. glyph_id(&self) -> GlyphId3001 pub fn glyph_id(&self) -> GlyphId { 3002 let range = self.shape.glyph_id_byte_range(); 3003 self.data.read_at(range.start).unwrap() 3004 } 3005 } 3006 3007 #[cfg(feature = "traversal")] 3008 impl<'a> SomeTable<'a> for PaintColrGlyph<'a> { type_name(&self) -> &str3009 fn type_name(&self) -> &str { 3010 "PaintColrGlyph" 3011 } get_field(&self, idx: usize) -> Option<Field<'a>>3012 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3013 match idx { 3014 0usize => Some(Field::new("format", self.format())), 3015 1usize => Some(Field::new("glyph_id", self.glyph_id())), 3016 _ => None, 3017 } 3018 } 3019 } 3020 3021 #[cfg(feature = "traversal")] 3022 impl<'a> std::fmt::Debug for PaintColrGlyph<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3023 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3024 (self as &dyn SomeTable<'a>).fmt(f) 3025 } 3026 } 3027 3028 impl Format<u8> for PaintTransformMarker { 3029 const FORMAT: u8 = 12; 3030 } 3031 3032 /// [PaintTransform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) table 3033 #[derive(Debug, Clone, Copy)] 3034 #[doc(hidden)] 3035 pub struct PaintTransformMarker {} 3036 3037 impl PaintTransformMarker { format_byte_range(&self) -> Range<usize>3038 fn format_byte_range(&self) -> Range<usize> { 3039 let start = 0; 3040 start..start + u8::RAW_BYTE_LEN 3041 } paint_offset_byte_range(&self) -> Range<usize>3042 fn paint_offset_byte_range(&self) -> Range<usize> { 3043 let start = self.format_byte_range().end; 3044 start..start + Offset24::RAW_BYTE_LEN 3045 } transform_offset_byte_range(&self) -> Range<usize>3046 fn transform_offset_byte_range(&self) -> Range<usize> { 3047 let start = self.paint_offset_byte_range().end; 3048 start..start + Offset24::RAW_BYTE_LEN 3049 } 3050 } 3051 3052 impl<'a> FontRead<'a> for PaintTransform<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>3053 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 3054 let mut cursor = data.cursor(); 3055 cursor.advance::<u8>(); 3056 cursor.advance::<Offset24>(); 3057 cursor.advance::<Offset24>(); 3058 cursor.finish(PaintTransformMarker {}) 3059 } 3060 } 3061 3062 /// [PaintTransform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) table 3063 pub type PaintTransform<'a> = TableRef<'a, PaintTransformMarker>; 3064 3065 impl<'a> PaintTransform<'a> { 3066 /// Set to 12. format(&self) -> u83067 pub fn format(&self) -> u8 { 3068 let range = self.shape.format_byte_range(); 3069 self.data.read_at(range.start).unwrap() 3070 } 3071 3072 /// Offset to a Paint subtable. paint_offset(&self) -> Offset243073 pub fn paint_offset(&self) -> Offset24 { 3074 let range = self.shape.paint_offset_byte_range(); 3075 self.data.read_at(range.start).unwrap() 3076 } 3077 3078 /// Attempt to resolve [`paint_offset`][Self::paint_offset]. paint(&self) -> Result<Paint<'a>, ReadError>3079 pub fn paint(&self) -> Result<Paint<'a>, ReadError> { 3080 let data = self.data; 3081 self.paint_offset().resolve(data) 3082 } 3083 3084 /// Offset to an Affine2x3 table. transform_offset(&self) -> Offset243085 pub fn transform_offset(&self) -> Offset24 { 3086 let range = self.shape.transform_offset_byte_range(); 3087 self.data.read_at(range.start).unwrap() 3088 } 3089 3090 /// Attempt to resolve [`transform_offset`][Self::transform_offset]. transform(&self) -> Result<Affine2x3<'a>, ReadError>3091 pub fn transform(&self) -> Result<Affine2x3<'a>, ReadError> { 3092 let data = self.data; 3093 self.transform_offset().resolve(data) 3094 } 3095 } 3096 3097 #[cfg(feature = "traversal")] 3098 impl<'a> SomeTable<'a> for PaintTransform<'a> { type_name(&self) -> &str3099 fn type_name(&self) -> &str { 3100 "PaintTransform" 3101 } get_field(&self, idx: usize) -> Option<Field<'a>>3102 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3103 match idx { 3104 0usize => Some(Field::new("format", self.format())), 3105 1usize => Some(Field::new( 3106 "paint_offset", 3107 FieldType::offset(self.paint_offset(), self.paint()), 3108 )), 3109 2usize => Some(Field::new( 3110 "transform_offset", 3111 FieldType::offset(self.transform_offset(), self.transform()), 3112 )), 3113 _ => None, 3114 } 3115 } 3116 } 3117 3118 #[cfg(feature = "traversal")] 3119 impl<'a> std::fmt::Debug for PaintTransform<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3120 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3121 (self as &dyn SomeTable<'a>).fmt(f) 3122 } 3123 } 3124 3125 impl Format<u8> for PaintVarTransformMarker { 3126 const FORMAT: u8 = 13; 3127 } 3128 3129 /// [PaintVarTransform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) table 3130 #[derive(Debug, Clone, Copy)] 3131 #[doc(hidden)] 3132 pub struct PaintVarTransformMarker {} 3133 3134 impl PaintVarTransformMarker { format_byte_range(&self) -> Range<usize>3135 fn format_byte_range(&self) -> Range<usize> { 3136 let start = 0; 3137 start..start + u8::RAW_BYTE_LEN 3138 } paint_offset_byte_range(&self) -> Range<usize>3139 fn paint_offset_byte_range(&self) -> Range<usize> { 3140 let start = self.format_byte_range().end; 3141 start..start + Offset24::RAW_BYTE_LEN 3142 } transform_offset_byte_range(&self) -> Range<usize>3143 fn transform_offset_byte_range(&self) -> Range<usize> { 3144 let start = self.paint_offset_byte_range().end; 3145 start..start + Offset24::RAW_BYTE_LEN 3146 } 3147 } 3148 3149 impl<'a> FontRead<'a> for PaintVarTransform<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>3150 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 3151 let mut cursor = data.cursor(); 3152 cursor.advance::<u8>(); 3153 cursor.advance::<Offset24>(); 3154 cursor.advance::<Offset24>(); 3155 cursor.finish(PaintVarTransformMarker {}) 3156 } 3157 } 3158 3159 /// [PaintVarTransform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) table 3160 pub type PaintVarTransform<'a> = TableRef<'a, PaintVarTransformMarker>; 3161 3162 impl<'a> PaintVarTransform<'a> { 3163 /// Set to 13. format(&self) -> u83164 pub fn format(&self) -> u8 { 3165 let range = self.shape.format_byte_range(); 3166 self.data.read_at(range.start).unwrap() 3167 } 3168 3169 /// Offset to a Paint subtable. paint_offset(&self) -> Offset243170 pub fn paint_offset(&self) -> Offset24 { 3171 let range = self.shape.paint_offset_byte_range(); 3172 self.data.read_at(range.start).unwrap() 3173 } 3174 3175 /// Attempt to resolve [`paint_offset`][Self::paint_offset]. paint(&self) -> Result<Paint<'a>, ReadError>3176 pub fn paint(&self) -> Result<Paint<'a>, ReadError> { 3177 let data = self.data; 3178 self.paint_offset().resolve(data) 3179 } 3180 3181 /// Offset to a VarAffine2x3 table. transform_offset(&self) -> Offset243182 pub fn transform_offset(&self) -> Offset24 { 3183 let range = self.shape.transform_offset_byte_range(); 3184 self.data.read_at(range.start).unwrap() 3185 } 3186 3187 /// Attempt to resolve [`transform_offset`][Self::transform_offset]. transform(&self) -> Result<VarAffine2x3<'a>, ReadError>3188 pub fn transform(&self) -> Result<VarAffine2x3<'a>, ReadError> { 3189 let data = self.data; 3190 self.transform_offset().resolve(data) 3191 } 3192 } 3193 3194 #[cfg(feature = "traversal")] 3195 impl<'a> SomeTable<'a> for PaintVarTransform<'a> { type_name(&self) -> &str3196 fn type_name(&self) -> &str { 3197 "PaintVarTransform" 3198 } get_field(&self, idx: usize) -> Option<Field<'a>>3199 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3200 match idx { 3201 0usize => Some(Field::new("format", self.format())), 3202 1usize => Some(Field::new( 3203 "paint_offset", 3204 FieldType::offset(self.paint_offset(), self.paint()), 3205 )), 3206 2usize => Some(Field::new( 3207 "transform_offset", 3208 FieldType::offset(self.transform_offset(), self.transform()), 3209 )), 3210 _ => None, 3211 } 3212 } 3213 } 3214 3215 #[cfg(feature = "traversal")] 3216 impl<'a> std::fmt::Debug for PaintVarTransform<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3217 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3218 (self as &dyn SomeTable<'a>).fmt(f) 3219 } 3220 } 3221 3222 /// [Affine2x3](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) record 3223 #[derive(Debug, Clone, Copy)] 3224 #[doc(hidden)] 3225 pub struct Affine2x3Marker {} 3226 3227 impl Affine2x3Marker { xx_byte_range(&self) -> Range<usize>3228 fn xx_byte_range(&self) -> Range<usize> { 3229 let start = 0; 3230 start..start + Fixed::RAW_BYTE_LEN 3231 } yx_byte_range(&self) -> Range<usize>3232 fn yx_byte_range(&self) -> Range<usize> { 3233 let start = self.xx_byte_range().end; 3234 start..start + Fixed::RAW_BYTE_LEN 3235 } xy_byte_range(&self) -> Range<usize>3236 fn xy_byte_range(&self) -> Range<usize> { 3237 let start = self.yx_byte_range().end; 3238 start..start + Fixed::RAW_BYTE_LEN 3239 } yy_byte_range(&self) -> Range<usize>3240 fn yy_byte_range(&self) -> Range<usize> { 3241 let start = self.xy_byte_range().end; 3242 start..start + Fixed::RAW_BYTE_LEN 3243 } dx_byte_range(&self) -> Range<usize>3244 fn dx_byte_range(&self) -> Range<usize> { 3245 let start = self.yy_byte_range().end; 3246 start..start + Fixed::RAW_BYTE_LEN 3247 } dy_byte_range(&self) -> Range<usize>3248 fn dy_byte_range(&self) -> Range<usize> { 3249 let start = self.dx_byte_range().end; 3250 start..start + Fixed::RAW_BYTE_LEN 3251 } 3252 } 3253 3254 impl<'a> FontRead<'a> for Affine2x3<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>3255 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 3256 let mut cursor = data.cursor(); 3257 cursor.advance::<Fixed>(); 3258 cursor.advance::<Fixed>(); 3259 cursor.advance::<Fixed>(); 3260 cursor.advance::<Fixed>(); 3261 cursor.advance::<Fixed>(); 3262 cursor.advance::<Fixed>(); 3263 cursor.finish(Affine2x3Marker {}) 3264 } 3265 } 3266 3267 /// [Affine2x3](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) record 3268 pub type Affine2x3<'a> = TableRef<'a, Affine2x3Marker>; 3269 3270 impl<'a> Affine2x3<'a> { 3271 /// x-component of transformed x-basis vector. xx(&self) -> Fixed3272 pub fn xx(&self) -> Fixed { 3273 let range = self.shape.xx_byte_range(); 3274 self.data.read_at(range.start).unwrap() 3275 } 3276 3277 /// y-component of transformed x-basis vector. yx(&self) -> Fixed3278 pub fn yx(&self) -> Fixed { 3279 let range = self.shape.yx_byte_range(); 3280 self.data.read_at(range.start).unwrap() 3281 } 3282 3283 /// x-component of transformed y-basis vector. xy(&self) -> Fixed3284 pub fn xy(&self) -> Fixed { 3285 let range = self.shape.xy_byte_range(); 3286 self.data.read_at(range.start).unwrap() 3287 } 3288 3289 /// y-component of transformed y-basis vector. yy(&self) -> Fixed3290 pub fn yy(&self) -> Fixed { 3291 let range = self.shape.yy_byte_range(); 3292 self.data.read_at(range.start).unwrap() 3293 } 3294 3295 /// Translation in x direction. dx(&self) -> Fixed3296 pub fn dx(&self) -> Fixed { 3297 let range = self.shape.dx_byte_range(); 3298 self.data.read_at(range.start).unwrap() 3299 } 3300 3301 /// Translation in y direction. dy(&self) -> Fixed3302 pub fn dy(&self) -> Fixed { 3303 let range = self.shape.dy_byte_range(); 3304 self.data.read_at(range.start).unwrap() 3305 } 3306 } 3307 3308 #[cfg(feature = "traversal")] 3309 impl<'a> SomeTable<'a> for Affine2x3<'a> { type_name(&self) -> &str3310 fn type_name(&self) -> &str { 3311 "Affine2x3" 3312 } get_field(&self, idx: usize) -> Option<Field<'a>>3313 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3314 match idx { 3315 0usize => Some(Field::new("xx", self.xx())), 3316 1usize => Some(Field::new("yx", self.yx())), 3317 2usize => Some(Field::new("xy", self.xy())), 3318 3usize => Some(Field::new("yy", self.yy())), 3319 4usize => Some(Field::new("dx", self.dx())), 3320 5usize => Some(Field::new("dy", self.dy())), 3321 _ => None, 3322 } 3323 } 3324 } 3325 3326 #[cfg(feature = "traversal")] 3327 impl<'a> std::fmt::Debug for Affine2x3<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3328 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3329 (self as &dyn SomeTable<'a>).fmt(f) 3330 } 3331 } 3332 3333 /// [VarAffine2x3](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) record 3334 #[derive(Debug, Clone, Copy)] 3335 #[doc(hidden)] 3336 pub struct VarAffine2x3Marker {} 3337 3338 impl VarAffine2x3Marker { xx_byte_range(&self) -> Range<usize>3339 fn xx_byte_range(&self) -> Range<usize> { 3340 let start = 0; 3341 start..start + Fixed::RAW_BYTE_LEN 3342 } yx_byte_range(&self) -> Range<usize>3343 fn yx_byte_range(&self) -> Range<usize> { 3344 let start = self.xx_byte_range().end; 3345 start..start + Fixed::RAW_BYTE_LEN 3346 } xy_byte_range(&self) -> Range<usize>3347 fn xy_byte_range(&self) -> Range<usize> { 3348 let start = self.yx_byte_range().end; 3349 start..start + Fixed::RAW_BYTE_LEN 3350 } yy_byte_range(&self) -> Range<usize>3351 fn yy_byte_range(&self) -> Range<usize> { 3352 let start = self.xy_byte_range().end; 3353 start..start + Fixed::RAW_BYTE_LEN 3354 } dx_byte_range(&self) -> Range<usize>3355 fn dx_byte_range(&self) -> Range<usize> { 3356 let start = self.yy_byte_range().end; 3357 start..start + Fixed::RAW_BYTE_LEN 3358 } dy_byte_range(&self) -> Range<usize>3359 fn dy_byte_range(&self) -> Range<usize> { 3360 let start = self.dx_byte_range().end; 3361 start..start + Fixed::RAW_BYTE_LEN 3362 } var_index_base_byte_range(&self) -> Range<usize>3363 fn var_index_base_byte_range(&self) -> Range<usize> { 3364 let start = self.dy_byte_range().end; 3365 start..start + u32::RAW_BYTE_LEN 3366 } 3367 } 3368 3369 impl<'a> FontRead<'a> for VarAffine2x3<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>3370 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 3371 let mut cursor = data.cursor(); 3372 cursor.advance::<Fixed>(); 3373 cursor.advance::<Fixed>(); 3374 cursor.advance::<Fixed>(); 3375 cursor.advance::<Fixed>(); 3376 cursor.advance::<Fixed>(); 3377 cursor.advance::<Fixed>(); 3378 cursor.advance::<u32>(); 3379 cursor.finish(VarAffine2x3Marker {}) 3380 } 3381 } 3382 3383 /// [VarAffine2x3](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) record 3384 pub type VarAffine2x3<'a> = TableRef<'a, VarAffine2x3Marker>; 3385 3386 impl<'a> VarAffine2x3<'a> { 3387 /// x-component of transformed x-basis vector. For variation, use 3388 /// varIndexBase + 0. xx(&self) -> Fixed3389 pub fn xx(&self) -> Fixed { 3390 let range = self.shape.xx_byte_range(); 3391 self.data.read_at(range.start).unwrap() 3392 } 3393 3394 /// y-component of transformed x-basis vector. For variation, use 3395 /// varIndexBase + 1. yx(&self) -> Fixed3396 pub fn yx(&self) -> Fixed { 3397 let range = self.shape.yx_byte_range(); 3398 self.data.read_at(range.start).unwrap() 3399 } 3400 3401 /// x-component of transformed y-basis vector. For variation, use 3402 /// varIndexBase + 2. xy(&self) -> Fixed3403 pub fn xy(&self) -> Fixed { 3404 let range = self.shape.xy_byte_range(); 3405 self.data.read_at(range.start).unwrap() 3406 } 3407 3408 /// y-component of transformed y-basis vector. For variation, use 3409 /// varIndexBase + 3. yy(&self) -> Fixed3410 pub fn yy(&self) -> Fixed { 3411 let range = self.shape.yy_byte_range(); 3412 self.data.read_at(range.start).unwrap() 3413 } 3414 3415 /// Translation in x direction. For variation, use varIndexBase + 4. dx(&self) -> Fixed3416 pub fn dx(&self) -> Fixed { 3417 let range = self.shape.dx_byte_range(); 3418 self.data.read_at(range.start).unwrap() 3419 } 3420 3421 /// Translation in y direction. For variation, use varIndexBase + 5. dy(&self) -> Fixed3422 pub fn dy(&self) -> Fixed { 3423 let range = self.shape.dy_byte_range(); 3424 self.data.read_at(range.start).unwrap() 3425 } 3426 3427 /// Base index into DeltaSetIndexMap. var_index_base(&self) -> u323428 pub fn var_index_base(&self) -> u32 { 3429 let range = self.shape.var_index_base_byte_range(); 3430 self.data.read_at(range.start).unwrap() 3431 } 3432 } 3433 3434 #[cfg(feature = "traversal")] 3435 impl<'a> SomeTable<'a> for VarAffine2x3<'a> { type_name(&self) -> &str3436 fn type_name(&self) -> &str { 3437 "VarAffine2x3" 3438 } get_field(&self, idx: usize) -> Option<Field<'a>>3439 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3440 match idx { 3441 0usize => Some(Field::new("xx", self.xx())), 3442 1usize => Some(Field::new("yx", self.yx())), 3443 2usize => Some(Field::new("xy", self.xy())), 3444 3usize => Some(Field::new("yy", self.yy())), 3445 4usize => Some(Field::new("dx", self.dx())), 3446 5usize => Some(Field::new("dy", self.dy())), 3447 6usize => Some(Field::new("var_index_base", self.var_index_base())), 3448 _ => None, 3449 } 3450 } 3451 } 3452 3453 #[cfg(feature = "traversal")] 3454 impl<'a> std::fmt::Debug for VarAffine2x3<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3455 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3456 (self as &dyn SomeTable<'a>).fmt(f) 3457 } 3458 } 3459 3460 impl Format<u8> for PaintTranslateMarker { 3461 const FORMAT: u8 = 14; 3462 } 3463 3464 /// [PaintTranslate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-14-and-15-painttranslate-paintvartranslate) table 3465 #[derive(Debug, Clone, Copy)] 3466 #[doc(hidden)] 3467 pub struct PaintTranslateMarker {} 3468 3469 impl PaintTranslateMarker { format_byte_range(&self) -> Range<usize>3470 fn format_byte_range(&self) -> Range<usize> { 3471 let start = 0; 3472 start..start + u8::RAW_BYTE_LEN 3473 } paint_offset_byte_range(&self) -> Range<usize>3474 fn paint_offset_byte_range(&self) -> Range<usize> { 3475 let start = self.format_byte_range().end; 3476 start..start + Offset24::RAW_BYTE_LEN 3477 } dx_byte_range(&self) -> Range<usize>3478 fn dx_byte_range(&self) -> Range<usize> { 3479 let start = self.paint_offset_byte_range().end; 3480 start..start + FWord::RAW_BYTE_LEN 3481 } dy_byte_range(&self) -> Range<usize>3482 fn dy_byte_range(&self) -> Range<usize> { 3483 let start = self.dx_byte_range().end; 3484 start..start + FWord::RAW_BYTE_LEN 3485 } 3486 } 3487 3488 impl<'a> FontRead<'a> for PaintTranslate<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>3489 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 3490 let mut cursor = data.cursor(); 3491 cursor.advance::<u8>(); 3492 cursor.advance::<Offset24>(); 3493 cursor.advance::<FWord>(); 3494 cursor.advance::<FWord>(); 3495 cursor.finish(PaintTranslateMarker {}) 3496 } 3497 } 3498 3499 /// [PaintTranslate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-14-and-15-painttranslate-paintvartranslate) table 3500 pub type PaintTranslate<'a> = TableRef<'a, PaintTranslateMarker>; 3501 3502 impl<'a> PaintTranslate<'a> { 3503 /// Set to 14. format(&self) -> u83504 pub fn format(&self) -> u8 { 3505 let range = self.shape.format_byte_range(); 3506 self.data.read_at(range.start).unwrap() 3507 } 3508 3509 /// Offset to a Paint subtable. paint_offset(&self) -> Offset243510 pub fn paint_offset(&self) -> Offset24 { 3511 let range = self.shape.paint_offset_byte_range(); 3512 self.data.read_at(range.start).unwrap() 3513 } 3514 3515 /// Attempt to resolve [`paint_offset`][Self::paint_offset]. paint(&self) -> Result<Paint<'a>, ReadError>3516 pub fn paint(&self) -> Result<Paint<'a>, ReadError> { 3517 let data = self.data; 3518 self.paint_offset().resolve(data) 3519 } 3520 3521 /// Translation in x direction. dx(&self) -> FWord3522 pub fn dx(&self) -> FWord { 3523 let range = self.shape.dx_byte_range(); 3524 self.data.read_at(range.start).unwrap() 3525 } 3526 3527 /// Translation in y direction. dy(&self) -> FWord3528 pub fn dy(&self) -> FWord { 3529 let range = self.shape.dy_byte_range(); 3530 self.data.read_at(range.start).unwrap() 3531 } 3532 } 3533 3534 #[cfg(feature = "traversal")] 3535 impl<'a> SomeTable<'a> for PaintTranslate<'a> { type_name(&self) -> &str3536 fn type_name(&self) -> &str { 3537 "PaintTranslate" 3538 } get_field(&self, idx: usize) -> Option<Field<'a>>3539 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3540 match idx { 3541 0usize => Some(Field::new("format", self.format())), 3542 1usize => Some(Field::new( 3543 "paint_offset", 3544 FieldType::offset(self.paint_offset(), self.paint()), 3545 )), 3546 2usize => Some(Field::new("dx", self.dx())), 3547 3usize => Some(Field::new("dy", self.dy())), 3548 _ => None, 3549 } 3550 } 3551 } 3552 3553 #[cfg(feature = "traversal")] 3554 impl<'a> std::fmt::Debug for PaintTranslate<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3555 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3556 (self as &dyn SomeTable<'a>).fmt(f) 3557 } 3558 } 3559 3560 impl Format<u8> for PaintVarTranslateMarker { 3561 const FORMAT: u8 = 15; 3562 } 3563 3564 /// [PaintVarTranslate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-14-and-15-painttranslate-paintvartranslate) table 3565 #[derive(Debug, Clone, Copy)] 3566 #[doc(hidden)] 3567 pub struct PaintVarTranslateMarker {} 3568 3569 impl PaintVarTranslateMarker { format_byte_range(&self) -> Range<usize>3570 fn format_byte_range(&self) -> Range<usize> { 3571 let start = 0; 3572 start..start + u8::RAW_BYTE_LEN 3573 } paint_offset_byte_range(&self) -> Range<usize>3574 fn paint_offset_byte_range(&self) -> Range<usize> { 3575 let start = self.format_byte_range().end; 3576 start..start + Offset24::RAW_BYTE_LEN 3577 } dx_byte_range(&self) -> Range<usize>3578 fn dx_byte_range(&self) -> Range<usize> { 3579 let start = self.paint_offset_byte_range().end; 3580 start..start + FWord::RAW_BYTE_LEN 3581 } dy_byte_range(&self) -> Range<usize>3582 fn dy_byte_range(&self) -> Range<usize> { 3583 let start = self.dx_byte_range().end; 3584 start..start + FWord::RAW_BYTE_LEN 3585 } var_index_base_byte_range(&self) -> Range<usize>3586 fn var_index_base_byte_range(&self) -> Range<usize> { 3587 let start = self.dy_byte_range().end; 3588 start..start + u32::RAW_BYTE_LEN 3589 } 3590 } 3591 3592 impl<'a> FontRead<'a> for PaintVarTranslate<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>3593 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 3594 let mut cursor = data.cursor(); 3595 cursor.advance::<u8>(); 3596 cursor.advance::<Offset24>(); 3597 cursor.advance::<FWord>(); 3598 cursor.advance::<FWord>(); 3599 cursor.advance::<u32>(); 3600 cursor.finish(PaintVarTranslateMarker {}) 3601 } 3602 } 3603 3604 /// [PaintVarTranslate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-14-and-15-painttranslate-paintvartranslate) table 3605 pub type PaintVarTranslate<'a> = TableRef<'a, PaintVarTranslateMarker>; 3606 3607 impl<'a> PaintVarTranslate<'a> { 3608 /// Set to 15. format(&self) -> u83609 pub fn format(&self) -> u8 { 3610 let range = self.shape.format_byte_range(); 3611 self.data.read_at(range.start).unwrap() 3612 } 3613 3614 /// Offset to a Paint subtable. paint_offset(&self) -> Offset243615 pub fn paint_offset(&self) -> Offset24 { 3616 let range = self.shape.paint_offset_byte_range(); 3617 self.data.read_at(range.start).unwrap() 3618 } 3619 3620 /// Attempt to resolve [`paint_offset`][Self::paint_offset]. paint(&self) -> Result<Paint<'a>, ReadError>3621 pub fn paint(&self) -> Result<Paint<'a>, ReadError> { 3622 let data = self.data; 3623 self.paint_offset().resolve(data) 3624 } 3625 3626 /// Translation in x direction. For variation, use varIndexBase + 0. dx(&self) -> FWord3627 pub fn dx(&self) -> FWord { 3628 let range = self.shape.dx_byte_range(); 3629 self.data.read_at(range.start).unwrap() 3630 } 3631 3632 /// Translation in y direction. For variation, use varIndexBase + 1. dy(&self) -> FWord3633 pub fn dy(&self) -> FWord { 3634 let range = self.shape.dy_byte_range(); 3635 self.data.read_at(range.start).unwrap() 3636 } 3637 3638 /// Base index into DeltaSetIndexMap. var_index_base(&self) -> u323639 pub fn var_index_base(&self) -> u32 { 3640 let range = self.shape.var_index_base_byte_range(); 3641 self.data.read_at(range.start).unwrap() 3642 } 3643 } 3644 3645 #[cfg(feature = "traversal")] 3646 impl<'a> SomeTable<'a> for PaintVarTranslate<'a> { type_name(&self) -> &str3647 fn type_name(&self) -> &str { 3648 "PaintVarTranslate" 3649 } get_field(&self, idx: usize) -> Option<Field<'a>>3650 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3651 match idx { 3652 0usize => Some(Field::new("format", self.format())), 3653 1usize => Some(Field::new( 3654 "paint_offset", 3655 FieldType::offset(self.paint_offset(), self.paint()), 3656 )), 3657 2usize => Some(Field::new("dx", self.dx())), 3658 3usize => Some(Field::new("dy", self.dy())), 3659 4usize => Some(Field::new("var_index_base", self.var_index_base())), 3660 _ => None, 3661 } 3662 } 3663 } 3664 3665 #[cfg(feature = "traversal")] 3666 impl<'a> std::fmt::Debug for PaintVarTranslate<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3667 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3668 (self as &dyn SomeTable<'a>).fmt(f) 3669 } 3670 } 3671 3672 impl Format<u8> for PaintScaleMarker { 3673 const FORMAT: u8 = 16; 3674 } 3675 3676 /// [PaintScale](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table 3677 #[derive(Debug, Clone, Copy)] 3678 #[doc(hidden)] 3679 pub struct PaintScaleMarker {} 3680 3681 impl PaintScaleMarker { format_byte_range(&self) -> Range<usize>3682 fn format_byte_range(&self) -> Range<usize> { 3683 let start = 0; 3684 start..start + u8::RAW_BYTE_LEN 3685 } paint_offset_byte_range(&self) -> Range<usize>3686 fn paint_offset_byte_range(&self) -> Range<usize> { 3687 let start = self.format_byte_range().end; 3688 start..start + Offset24::RAW_BYTE_LEN 3689 } scale_x_byte_range(&self) -> Range<usize>3690 fn scale_x_byte_range(&self) -> Range<usize> { 3691 let start = self.paint_offset_byte_range().end; 3692 start..start + F2Dot14::RAW_BYTE_LEN 3693 } scale_y_byte_range(&self) -> Range<usize>3694 fn scale_y_byte_range(&self) -> Range<usize> { 3695 let start = self.scale_x_byte_range().end; 3696 start..start + F2Dot14::RAW_BYTE_LEN 3697 } 3698 } 3699 3700 impl<'a> FontRead<'a> for PaintScale<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>3701 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 3702 let mut cursor = data.cursor(); 3703 cursor.advance::<u8>(); 3704 cursor.advance::<Offset24>(); 3705 cursor.advance::<F2Dot14>(); 3706 cursor.advance::<F2Dot14>(); 3707 cursor.finish(PaintScaleMarker {}) 3708 } 3709 } 3710 3711 /// [PaintScale](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table 3712 pub type PaintScale<'a> = TableRef<'a, PaintScaleMarker>; 3713 3714 impl<'a> PaintScale<'a> { 3715 /// Set to 16. format(&self) -> u83716 pub fn format(&self) -> u8 { 3717 let range = self.shape.format_byte_range(); 3718 self.data.read_at(range.start).unwrap() 3719 } 3720 3721 /// Offset to a Paint subtable. paint_offset(&self) -> Offset243722 pub fn paint_offset(&self) -> Offset24 { 3723 let range = self.shape.paint_offset_byte_range(); 3724 self.data.read_at(range.start).unwrap() 3725 } 3726 3727 /// Attempt to resolve [`paint_offset`][Self::paint_offset]. paint(&self) -> Result<Paint<'a>, ReadError>3728 pub fn paint(&self) -> Result<Paint<'a>, ReadError> { 3729 let data = self.data; 3730 self.paint_offset().resolve(data) 3731 } 3732 3733 /// Scale factor in x direction. scale_x(&self) -> F2Dot143734 pub fn scale_x(&self) -> F2Dot14 { 3735 let range = self.shape.scale_x_byte_range(); 3736 self.data.read_at(range.start).unwrap() 3737 } 3738 3739 /// Scale factor in y direction. scale_y(&self) -> F2Dot143740 pub fn scale_y(&self) -> F2Dot14 { 3741 let range = self.shape.scale_y_byte_range(); 3742 self.data.read_at(range.start).unwrap() 3743 } 3744 } 3745 3746 #[cfg(feature = "traversal")] 3747 impl<'a> SomeTable<'a> for PaintScale<'a> { type_name(&self) -> &str3748 fn type_name(&self) -> &str { 3749 "PaintScale" 3750 } get_field(&self, idx: usize) -> Option<Field<'a>>3751 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3752 match idx { 3753 0usize => Some(Field::new("format", self.format())), 3754 1usize => Some(Field::new( 3755 "paint_offset", 3756 FieldType::offset(self.paint_offset(), self.paint()), 3757 )), 3758 2usize => Some(Field::new("scale_x", self.scale_x())), 3759 3usize => Some(Field::new("scale_y", self.scale_y())), 3760 _ => None, 3761 } 3762 } 3763 } 3764 3765 #[cfg(feature = "traversal")] 3766 impl<'a> std::fmt::Debug for PaintScale<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3767 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3768 (self as &dyn SomeTable<'a>).fmt(f) 3769 } 3770 } 3771 3772 impl Format<u8> for PaintVarScaleMarker { 3773 const FORMAT: u8 = 17; 3774 } 3775 3776 /// [PaintVarScale](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table 3777 #[derive(Debug, Clone, Copy)] 3778 #[doc(hidden)] 3779 pub struct PaintVarScaleMarker {} 3780 3781 impl PaintVarScaleMarker { format_byte_range(&self) -> Range<usize>3782 fn format_byte_range(&self) -> Range<usize> { 3783 let start = 0; 3784 start..start + u8::RAW_BYTE_LEN 3785 } paint_offset_byte_range(&self) -> Range<usize>3786 fn paint_offset_byte_range(&self) -> Range<usize> { 3787 let start = self.format_byte_range().end; 3788 start..start + Offset24::RAW_BYTE_LEN 3789 } scale_x_byte_range(&self) -> Range<usize>3790 fn scale_x_byte_range(&self) -> Range<usize> { 3791 let start = self.paint_offset_byte_range().end; 3792 start..start + F2Dot14::RAW_BYTE_LEN 3793 } scale_y_byte_range(&self) -> Range<usize>3794 fn scale_y_byte_range(&self) -> Range<usize> { 3795 let start = self.scale_x_byte_range().end; 3796 start..start + F2Dot14::RAW_BYTE_LEN 3797 } var_index_base_byte_range(&self) -> Range<usize>3798 fn var_index_base_byte_range(&self) -> Range<usize> { 3799 let start = self.scale_y_byte_range().end; 3800 start..start + u32::RAW_BYTE_LEN 3801 } 3802 } 3803 3804 impl<'a> FontRead<'a> for PaintVarScale<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>3805 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 3806 let mut cursor = data.cursor(); 3807 cursor.advance::<u8>(); 3808 cursor.advance::<Offset24>(); 3809 cursor.advance::<F2Dot14>(); 3810 cursor.advance::<F2Dot14>(); 3811 cursor.advance::<u32>(); 3812 cursor.finish(PaintVarScaleMarker {}) 3813 } 3814 } 3815 3816 /// [PaintVarScale](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table 3817 pub type PaintVarScale<'a> = TableRef<'a, PaintVarScaleMarker>; 3818 3819 impl<'a> PaintVarScale<'a> { 3820 /// Set to 17. format(&self) -> u83821 pub fn format(&self) -> u8 { 3822 let range = self.shape.format_byte_range(); 3823 self.data.read_at(range.start).unwrap() 3824 } 3825 3826 /// Offset to a Paint subtable. paint_offset(&self) -> Offset243827 pub fn paint_offset(&self) -> Offset24 { 3828 let range = self.shape.paint_offset_byte_range(); 3829 self.data.read_at(range.start).unwrap() 3830 } 3831 3832 /// Attempt to resolve [`paint_offset`][Self::paint_offset]. paint(&self) -> Result<Paint<'a>, ReadError>3833 pub fn paint(&self) -> Result<Paint<'a>, ReadError> { 3834 let data = self.data; 3835 self.paint_offset().resolve(data) 3836 } 3837 3838 /// Scale factor in x direction. For variation, use varIndexBase + 3839 /// 0. scale_x(&self) -> F2Dot143840 pub fn scale_x(&self) -> F2Dot14 { 3841 let range = self.shape.scale_x_byte_range(); 3842 self.data.read_at(range.start).unwrap() 3843 } 3844 3845 /// Scale factor in y direction. For variation, use varIndexBase + 3846 /// 1. scale_y(&self) -> F2Dot143847 pub fn scale_y(&self) -> F2Dot14 { 3848 let range = self.shape.scale_y_byte_range(); 3849 self.data.read_at(range.start).unwrap() 3850 } 3851 3852 /// Base index into DeltaSetIndexMap. var_index_base(&self) -> u323853 pub fn var_index_base(&self) -> u32 { 3854 let range = self.shape.var_index_base_byte_range(); 3855 self.data.read_at(range.start).unwrap() 3856 } 3857 } 3858 3859 #[cfg(feature = "traversal")] 3860 impl<'a> SomeTable<'a> for PaintVarScale<'a> { type_name(&self) -> &str3861 fn type_name(&self) -> &str { 3862 "PaintVarScale" 3863 } get_field(&self, idx: usize) -> Option<Field<'a>>3864 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3865 match idx { 3866 0usize => Some(Field::new("format", self.format())), 3867 1usize => Some(Field::new( 3868 "paint_offset", 3869 FieldType::offset(self.paint_offset(), self.paint()), 3870 )), 3871 2usize => Some(Field::new("scale_x", self.scale_x())), 3872 3usize => Some(Field::new("scale_y", self.scale_y())), 3873 4usize => Some(Field::new("var_index_base", self.var_index_base())), 3874 _ => None, 3875 } 3876 } 3877 } 3878 3879 #[cfg(feature = "traversal")] 3880 impl<'a> std::fmt::Debug for PaintVarScale<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3881 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3882 (self as &dyn SomeTable<'a>).fmt(f) 3883 } 3884 } 3885 3886 impl Format<u8> for PaintScaleAroundCenterMarker { 3887 const FORMAT: u8 = 18; 3888 } 3889 3890 /// [PaintScaleAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table 3891 #[derive(Debug, Clone, Copy)] 3892 #[doc(hidden)] 3893 pub struct PaintScaleAroundCenterMarker {} 3894 3895 impl PaintScaleAroundCenterMarker { format_byte_range(&self) -> Range<usize>3896 fn format_byte_range(&self) -> Range<usize> { 3897 let start = 0; 3898 start..start + u8::RAW_BYTE_LEN 3899 } paint_offset_byte_range(&self) -> Range<usize>3900 fn paint_offset_byte_range(&self) -> Range<usize> { 3901 let start = self.format_byte_range().end; 3902 start..start + Offset24::RAW_BYTE_LEN 3903 } scale_x_byte_range(&self) -> Range<usize>3904 fn scale_x_byte_range(&self) -> Range<usize> { 3905 let start = self.paint_offset_byte_range().end; 3906 start..start + F2Dot14::RAW_BYTE_LEN 3907 } scale_y_byte_range(&self) -> Range<usize>3908 fn scale_y_byte_range(&self) -> Range<usize> { 3909 let start = self.scale_x_byte_range().end; 3910 start..start + F2Dot14::RAW_BYTE_LEN 3911 } center_x_byte_range(&self) -> Range<usize>3912 fn center_x_byte_range(&self) -> Range<usize> { 3913 let start = self.scale_y_byte_range().end; 3914 start..start + FWord::RAW_BYTE_LEN 3915 } center_y_byte_range(&self) -> Range<usize>3916 fn center_y_byte_range(&self) -> Range<usize> { 3917 let start = self.center_x_byte_range().end; 3918 start..start + FWord::RAW_BYTE_LEN 3919 } 3920 } 3921 3922 impl<'a> FontRead<'a> for PaintScaleAroundCenter<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>3923 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 3924 let mut cursor = data.cursor(); 3925 cursor.advance::<u8>(); 3926 cursor.advance::<Offset24>(); 3927 cursor.advance::<F2Dot14>(); 3928 cursor.advance::<F2Dot14>(); 3929 cursor.advance::<FWord>(); 3930 cursor.advance::<FWord>(); 3931 cursor.finish(PaintScaleAroundCenterMarker {}) 3932 } 3933 } 3934 3935 /// [PaintScaleAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table 3936 pub type PaintScaleAroundCenter<'a> = TableRef<'a, PaintScaleAroundCenterMarker>; 3937 3938 impl<'a> PaintScaleAroundCenter<'a> { 3939 /// Set to 18. format(&self) -> u83940 pub fn format(&self) -> u8 { 3941 let range = self.shape.format_byte_range(); 3942 self.data.read_at(range.start).unwrap() 3943 } 3944 3945 /// Offset to a Paint subtable. paint_offset(&self) -> Offset243946 pub fn paint_offset(&self) -> Offset24 { 3947 let range = self.shape.paint_offset_byte_range(); 3948 self.data.read_at(range.start).unwrap() 3949 } 3950 3951 /// Attempt to resolve [`paint_offset`][Self::paint_offset]. paint(&self) -> Result<Paint<'a>, ReadError>3952 pub fn paint(&self) -> Result<Paint<'a>, ReadError> { 3953 let data = self.data; 3954 self.paint_offset().resolve(data) 3955 } 3956 3957 /// Scale factor in x direction. scale_x(&self) -> F2Dot143958 pub fn scale_x(&self) -> F2Dot14 { 3959 let range = self.shape.scale_x_byte_range(); 3960 self.data.read_at(range.start).unwrap() 3961 } 3962 3963 /// Scale factor in y direction. scale_y(&self) -> F2Dot143964 pub fn scale_y(&self) -> F2Dot14 { 3965 let range = self.shape.scale_y_byte_range(); 3966 self.data.read_at(range.start).unwrap() 3967 } 3968 3969 /// x coordinate for the center of scaling. center_x(&self) -> FWord3970 pub fn center_x(&self) -> FWord { 3971 let range = self.shape.center_x_byte_range(); 3972 self.data.read_at(range.start).unwrap() 3973 } 3974 3975 /// y coordinate for the center of scaling. center_y(&self) -> FWord3976 pub fn center_y(&self) -> FWord { 3977 let range = self.shape.center_y_byte_range(); 3978 self.data.read_at(range.start).unwrap() 3979 } 3980 } 3981 3982 #[cfg(feature = "traversal")] 3983 impl<'a> SomeTable<'a> for PaintScaleAroundCenter<'a> { type_name(&self) -> &str3984 fn type_name(&self) -> &str { 3985 "PaintScaleAroundCenter" 3986 } get_field(&self, idx: usize) -> Option<Field<'a>>3987 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 3988 match idx { 3989 0usize => Some(Field::new("format", self.format())), 3990 1usize => Some(Field::new( 3991 "paint_offset", 3992 FieldType::offset(self.paint_offset(), self.paint()), 3993 )), 3994 2usize => Some(Field::new("scale_x", self.scale_x())), 3995 3usize => Some(Field::new("scale_y", self.scale_y())), 3996 4usize => Some(Field::new("center_x", self.center_x())), 3997 5usize => Some(Field::new("center_y", self.center_y())), 3998 _ => None, 3999 } 4000 } 4001 } 4002 4003 #[cfg(feature = "traversal")] 4004 impl<'a> std::fmt::Debug for PaintScaleAroundCenter<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result4005 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 4006 (self as &dyn SomeTable<'a>).fmt(f) 4007 } 4008 } 4009 4010 impl Format<u8> for PaintVarScaleAroundCenterMarker { 4011 const FORMAT: u8 = 19; 4012 } 4013 4014 /// [PaintVarScaleAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table 4015 #[derive(Debug, Clone, Copy)] 4016 #[doc(hidden)] 4017 pub struct PaintVarScaleAroundCenterMarker {} 4018 4019 impl PaintVarScaleAroundCenterMarker { format_byte_range(&self) -> Range<usize>4020 fn format_byte_range(&self) -> Range<usize> { 4021 let start = 0; 4022 start..start + u8::RAW_BYTE_LEN 4023 } paint_offset_byte_range(&self) -> Range<usize>4024 fn paint_offset_byte_range(&self) -> Range<usize> { 4025 let start = self.format_byte_range().end; 4026 start..start + Offset24::RAW_BYTE_LEN 4027 } scale_x_byte_range(&self) -> Range<usize>4028 fn scale_x_byte_range(&self) -> Range<usize> { 4029 let start = self.paint_offset_byte_range().end; 4030 start..start + F2Dot14::RAW_BYTE_LEN 4031 } scale_y_byte_range(&self) -> Range<usize>4032 fn scale_y_byte_range(&self) -> Range<usize> { 4033 let start = self.scale_x_byte_range().end; 4034 start..start + F2Dot14::RAW_BYTE_LEN 4035 } center_x_byte_range(&self) -> Range<usize>4036 fn center_x_byte_range(&self) -> Range<usize> { 4037 let start = self.scale_y_byte_range().end; 4038 start..start + FWord::RAW_BYTE_LEN 4039 } center_y_byte_range(&self) -> Range<usize>4040 fn center_y_byte_range(&self) -> Range<usize> { 4041 let start = self.center_x_byte_range().end; 4042 start..start + FWord::RAW_BYTE_LEN 4043 } var_index_base_byte_range(&self) -> Range<usize>4044 fn var_index_base_byte_range(&self) -> Range<usize> { 4045 let start = self.center_y_byte_range().end; 4046 start..start + u32::RAW_BYTE_LEN 4047 } 4048 } 4049 4050 impl<'a> FontRead<'a> for PaintVarScaleAroundCenter<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>4051 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 4052 let mut cursor = data.cursor(); 4053 cursor.advance::<u8>(); 4054 cursor.advance::<Offset24>(); 4055 cursor.advance::<F2Dot14>(); 4056 cursor.advance::<F2Dot14>(); 4057 cursor.advance::<FWord>(); 4058 cursor.advance::<FWord>(); 4059 cursor.advance::<u32>(); 4060 cursor.finish(PaintVarScaleAroundCenterMarker {}) 4061 } 4062 } 4063 4064 /// [PaintVarScaleAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table 4065 pub type PaintVarScaleAroundCenter<'a> = TableRef<'a, PaintVarScaleAroundCenterMarker>; 4066 4067 impl<'a> PaintVarScaleAroundCenter<'a> { 4068 /// Set to 19. format(&self) -> u84069 pub fn format(&self) -> u8 { 4070 let range = self.shape.format_byte_range(); 4071 self.data.read_at(range.start).unwrap() 4072 } 4073 4074 /// Offset to a Paint subtable. paint_offset(&self) -> Offset244075 pub fn paint_offset(&self) -> Offset24 { 4076 let range = self.shape.paint_offset_byte_range(); 4077 self.data.read_at(range.start).unwrap() 4078 } 4079 4080 /// Attempt to resolve [`paint_offset`][Self::paint_offset]. paint(&self) -> Result<Paint<'a>, ReadError>4081 pub fn paint(&self) -> Result<Paint<'a>, ReadError> { 4082 let data = self.data; 4083 self.paint_offset().resolve(data) 4084 } 4085 4086 /// Scale factor in x direction. For variation, use varIndexBase + 4087 /// 0. scale_x(&self) -> F2Dot144088 pub fn scale_x(&self) -> F2Dot14 { 4089 let range = self.shape.scale_x_byte_range(); 4090 self.data.read_at(range.start).unwrap() 4091 } 4092 4093 /// Scale factor in y direction. For variation, use varIndexBase + 4094 /// 1. scale_y(&self) -> F2Dot144095 pub fn scale_y(&self) -> F2Dot14 { 4096 let range = self.shape.scale_y_byte_range(); 4097 self.data.read_at(range.start).unwrap() 4098 } 4099 4100 /// x coordinate for the center of scaling. For variation, use 4101 /// varIndexBase + 2. center_x(&self) -> FWord4102 pub fn center_x(&self) -> FWord { 4103 let range = self.shape.center_x_byte_range(); 4104 self.data.read_at(range.start).unwrap() 4105 } 4106 4107 /// y coordinate for the center of scaling. For variation, use 4108 /// varIndexBase + 3. center_y(&self) -> FWord4109 pub fn center_y(&self) -> FWord { 4110 let range = self.shape.center_y_byte_range(); 4111 self.data.read_at(range.start).unwrap() 4112 } 4113 4114 /// Base index into DeltaSetIndexMap. var_index_base(&self) -> u324115 pub fn var_index_base(&self) -> u32 { 4116 let range = self.shape.var_index_base_byte_range(); 4117 self.data.read_at(range.start).unwrap() 4118 } 4119 } 4120 4121 #[cfg(feature = "traversal")] 4122 impl<'a> SomeTable<'a> for PaintVarScaleAroundCenter<'a> { type_name(&self) -> &str4123 fn type_name(&self) -> &str { 4124 "PaintVarScaleAroundCenter" 4125 } get_field(&self, idx: usize) -> Option<Field<'a>>4126 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 4127 match idx { 4128 0usize => Some(Field::new("format", self.format())), 4129 1usize => Some(Field::new( 4130 "paint_offset", 4131 FieldType::offset(self.paint_offset(), self.paint()), 4132 )), 4133 2usize => Some(Field::new("scale_x", self.scale_x())), 4134 3usize => Some(Field::new("scale_y", self.scale_y())), 4135 4usize => Some(Field::new("center_x", self.center_x())), 4136 5usize => Some(Field::new("center_y", self.center_y())), 4137 6usize => Some(Field::new("var_index_base", self.var_index_base())), 4138 _ => None, 4139 } 4140 } 4141 } 4142 4143 #[cfg(feature = "traversal")] 4144 impl<'a> std::fmt::Debug for PaintVarScaleAroundCenter<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result4145 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 4146 (self as &dyn SomeTable<'a>).fmt(f) 4147 } 4148 } 4149 4150 impl Format<u8> for PaintScaleUniformMarker { 4151 const FORMAT: u8 = 20; 4152 } 4153 4154 /// [PaintScaleUniform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table 4155 #[derive(Debug, Clone, Copy)] 4156 #[doc(hidden)] 4157 pub struct PaintScaleUniformMarker {} 4158 4159 impl PaintScaleUniformMarker { format_byte_range(&self) -> Range<usize>4160 fn format_byte_range(&self) -> Range<usize> { 4161 let start = 0; 4162 start..start + u8::RAW_BYTE_LEN 4163 } paint_offset_byte_range(&self) -> Range<usize>4164 fn paint_offset_byte_range(&self) -> Range<usize> { 4165 let start = self.format_byte_range().end; 4166 start..start + Offset24::RAW_BYTE_LEN 4167 } scale_byte_range(&self) -> Range<usize>4168 fn scale_byte_range(&self) -> Range<usize> { 4169 let start = self.paint_offset_byte_range().end; 4170 start..start + F2Dot14::RAW_BYTE_LEN 4171 } 4172 } 4173 4174 impl<'a> FontRead<'a> for PaintScaleUniform<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>4175 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 4176 let mut cursor = data.cursor(); 4177 cursor.advance::<u8>(); 4178 cursor.advance::<Offset24>(); 4179 cursor.advance::<F2Dot14>(); 4180 cursor.finish(PaintScaleUniformMarker {}) 4181 } 4182 } 4183 4184 /// [PaintScaleUniform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table 4185 pub type PaintScaleUniform<'a> = TableRef<'a, PaintScaleUniformMarker>; 4186 4187 impl<'a> PaintScaleUniform<'a> { 4188 /// Set to 20. format(&self) -> u84189 pub fn format(&self) -> u8 { 4190 let range = self.shape.format_byte_range(); 4191 self.data.read_at(range.start).unwrap() 4192 } 4193 4194 /// Offset to a Paint subtable. paint_offset(&self) -> Offset244195 pub fn paint_offset(&self) -> Offset24 { 4196 let range = self.shape.paint_offset_byte_range(); 4197 self.data.read_at(range.start).unwrap() 4198 } 4199 4200 /// Attempt to resolve [`paint_offset`][Self::paint_offset]. paint(&self) -> Result<Paint<'a>, ReadError>4201 pub fn paint(&self) -> Result<Paint<'a>, ReadError> { 4202 let data = self.data; 4203 self.paint_offset().resolve(data) 4204 } 4205 4206 /// Scale factor in x and y directions. scale(&self) -> F2Dot144207 pub fn scale(&self) -> F2Dot14 { 4208 let range = self.shape.scale_byte_range(); 4209 self.data.read_at(range.start).unwrap() 4210 } 4211 } 4212 4213 #[cfg(feature = "traversal")] 4214 impl<'a> SomeTable<'a> for PaintScaleUniform<'a> { type_name(&self) -> &str4215 fn type_name(&self) -> &str { 4216 "PaintScaleUniform" 4217 } get_field(&self, idx: usize) -> Option<Field<'a>>4218 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 4219 match idx { 4220 0usize => Some(Field::new("format", self.format())), 4221 1usize => Some(Field::new( 4222 "paint_offset", 4223 FieldType::offset(self.paint_offset(), self.paint()), 4224 )), 4225 2usize => Some(Field::new("scale", self.scale())), 4226 _ => None, 4227 } 4228 } 4229 } 4230 4231 #[cfg(feature = "traversal")] 4232 impl<'a> std::fmt::Debug for PaintScaleUniform<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result4233 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 4234 (self as &dyn SomeTable<'a>).fmt(f) 4235 } 4236 } 4237 4238 impl Format<u8> for PaintVarScaleUniformMarker { 4239 const FORMAT: u8 = 21; 4240 } 4241 4242 /// [PaintVarScaleUniform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table 4243 #[derive(Debug, Clone, Copy)] 4244 #[doc(hidden)] 4245 pub struct PaintVarScaleUniformMarker {} 4246 4247 impl PaintVarScaleUniformMarker { format_byte_range(&self) -> Range<usize>4248 fn format_byte_range(&self) -> Range<usize> { 4249 let start = 0; 4250 start..start + u8::RAW_BYTE_LEN 4251 } paint_offset_byte_range(&self) -> Range<usize>4252 fn paint_offset_byte_range(&self) -> Range<usize> { 4253 let start = self.format_byte_range().end; 4254 start..start + Offset24::RAW_BYTE_LEN 4255 } scale_byte_range(&self) -> Range<usize>4256 fn scale_byte_range(&self) -> Range<usize> { 4257 let start = self.paint_offset_byte_range().end; 4258 start..start + F2Dot14::RAW_BYTE_LEN 4259 } var_index_base_byte_range(&self) -> Range<usize>4260 fn var_index_base_byte_range(&self) -> Range<usize> { 4261 let start = self.scale_byte_range().end; 4262 start..start + u32::RAW_BYTE_LEN 4263 } 4264 } 4265 4266 impl<'a> FontRead<'a> for PaintVarScaleUniform<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>4267 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 4268 let mut cursor = data.cursor(); 4269 cursor.advance::<u8>(); 4270 cursor.advance::<Offset24>(); 4271 cursor.advance::<F2Dot14>(); 4272 cursor.advance::<u32>(); 4273 cursor.finish(PaintVarScaleUniformMarker {}) 4274 } 4275 } 4276 4277 /// [PaintVarScaleUniform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table 4278 pub type PaintVarScaleUniform<'a> = TableRef<'a, PaintVarScaleUniformMarker>; 4279 4280 impl<'a> PaintVarScaleUniform<'a> { 4281 /// Set to 21. format(&self) -> u84282 pub fn format(&self) -> u8 { 4283 let range = self.shape.format_byte_range(); 4284 self.data.read_at(range.start).unwrap() 4285 } 4286 4287 /// Offset to a Paint subtable. paint_offset(&self) -> Offset244288 pub fn paint_offset(&self) -> Offset24 { 4289 let range = self.shape.paint_offset_byte_range(); 4290 self.data.read_at(range.start).unwrap() 4291 } 4292 4293 /// Attempt to resolve [`paint_offset`][Self::paint_offset]. paint(&self) -> Result<Paint<'a>, ReadError>4294 pub fn paint(&self) -> Result<Paint<'a>, ReadError> { 4295 let data = self.data; 4296 self.paint_offset().resolve(data) 4297 } 4298 4299 /// Scale factor in x and y directions. For variation, use 4300 /// varIndexBase + 0. scale(&self) -> F2Dot144301 pub fn scale(&self) -> F2Dot14 { 4302 let range = self.shape.scale_byte_range(); 4303 self.data.read_at(range.start).unwrap() 4304 } 4305 4306 /// Base index into DeltaSetIndexMap. var_index_base(&self) -> u324307 pub fn var_index_base(&self) -> u32 { 4308 let range = self.shape.var_index_base_byte_range(); 4309 self.data.read_at(range.start).unwrap() 4310 } 4311 } 4312 4313 #[cfg(feature = "traversal")] 4314 impl<'a> SomeTable<'a> for PaintVarScaleUniform<'a> { type_name(&self) -> &str4315 fn type_name(&self) -> &str { 4316 "PaintVarScaleUniform" 4317 } get_field(&self, idx: usize) -> Option<Field<'a>>4318 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 4319 match idx { 4320 0usize => Some(Field::new("format", self.format())), 4321 1usize => Some(Field::new( 4322 "paint_offset", 4323 FieldType::offset(self.paint_offset(), self.paint()), 4324 )), 4325 2usize => Some(Field::new("scale", self.scale())), 4326 3usize => Some(Field::new("var_index_base", self.var_index_base())), 4327 _ => None, 4328 } 4329 } 4330 } 4331 4332 #[cfg(feature = "traversal")] 4333 impl<'a> std::fmt::Debug for PaintVarScaleUniform<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result4334 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 4335 (self as &dyn SomeTable<'a>).fmt(f) 4336 } 4337 } 4338 4339 impl Format<u8> for PaintScaleUniformAroundCenterMarker { 4340 const FORMAT: u8 = 22; 4341 } 4342 4343 /// [PaintScaleUniformAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table 4344 #[derive(Debug, Clone, Copy)] 4345 #[doc(hidden)] 4346 pub struct PaintScaleUniformAroundCenterMarker {} 4347 4348 impl PaintScaleUniformAroundCenterMarker { format_byte_range(&self) -> Range<usize>4349 fn format_byte_range(&self) -> Range<usize> { 4350 let start = 0; 4351 start..start + u8::RAW_BYTE_LEN 4352 } paint_offset_byte_range(&self) -> Range<usize>4353 fn paint_offset_byte_range(&self) -> Range<usize> { 4354 let start = self.format_byte_range().end; 4355 start..start + Offset24::RAW_BYTE_LEN 4356 } scale_byte_range(&self) -> Range<usize>4357 fn scale_byte_range(&self) -> Range<usize> { 4358 let start = self.paint_offset_byte_range().end; 4359 start..start + F2Dot14::RAW_BYTE_LEN 4360 } center_x_byte_range(&self) -> Range<usize>4361 fn center_x_byte_range(&self) -> Range<usize> { 4362 let start = self.scale_byte_range().end; 4363 start..start + FWord::RAW_BYTE_LEN 4364 } center_y_byte_range(&self) -> Range<usize>4365 fn center_y_byte_range(&self) -> Range<usize> { 4366 let start = self.center_x_byte_range().end; 4367 start..start + FWord::RAW_BYTE_LEN 4368 } 4369 } 4370 4371 impl<'a> FontRead<'a> for PaintScaleUniformAroundCenter<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>4372 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 4373 let mut cursor = data.cursor(); 4374 cursor.advance::<u8>(); 4375 cursor.advance::<Offset24>(); 4376 cursor.advance::<F2Dot14>(); 4377 cursor.advance::<FWord>(); 4378 cursor.advance::<FWord>(); 4379 cursor.finish(PaintScaleUniformAroundCenterMarker {}) 4380 } 4381 } 4382 4383 /// [PaintScaleUniformAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table 4384 pub type PaintScaleUniformAroundCenter<'a> = TableRef<'a, PaintScaleUniformAroundCenterMarker>; 4385 4386 impl<'a> PaintScaleUniformAroundCenter<'a> { 4387 /// Set to 22. format(&self) -> u84388 pub fn format(&self) -> u8 { 4389 let range = self.shape.format_byte_range(); 4390 self.data.read_at(range.start).unwrap() 4391 } 4392 4393 /// Offset to a Paint subtable. paint_offset(&self) -> Offset244394 pub fn paint_offset(&self) -> Offset24 { 4395 let range = self.shape.paint_offset_byte_range(); 4396 self.data.read_at(range.start).unwrap() 4397 } 4398 4399 /// Attempt to resolve [`paint_offset`][Self::paint_offset]. paint(&self) -> Result<Paint<'a>, ReadError>4400 pub fn paint(&self) -> Result<Paint<'a>, ReadError> { 4401 let data = self.data; 4402 self.paint_offset().resolve(data) 4403 } 4404 4405 /// Scale factor in x and y directions. scale(&self) -> F2Dot144406 pub fn scale(&self) -> F2Dot14 { 4407 let range = self.shape.scale_byte_range(); 4408 self.data.read_at(range.start).unwrap() 4409 } 4410 4411 /// x coordinate for the center of scaling. center_x(&self) -> FWord4412 pub fn center_x(&self) -> FWord { 4413 let range = self.shape.center_x_byte_range(); 4414 self.data.read_at(range.start).unwrap() 4415 } 4416 4417 /// y coordinate for the center of scaling. center_y(&self) -> FWord4418 pub fn center_y(&self) -> FWord { 4419 let range = self.shape.center_y_byte_range(); 4420 self.data.read_at(range.start).unwrap() 4421 } 4422 } 4423 4424 #[cfg(feature = "traversal")] 4425 impl<'a> SomeTable<'a> for PaintScaleUniformAroundCenter<'a> { type_name(&self) -> &str4426 fn type_name(&self) -> &str { 4427 "PaintScaleUniformAroundCenter" 4428 } get_field(&self, idx: usize) -> Option<Field<'a>>4429 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 4430 match idx { 4431 0usize => Some(Field::new("format", self.format())), 4432 1usize => Some(Field::new( 4433 "paint_offset", 4434 FieldType::offset(self.paint_offset(), self.paint()), 4435 )), 4436 2usize => Some(Field::new("scale", self.scale())), 4437 3usize => Some(Field::new("center_x", self.center_x())), 4438 4usize => Some(Field::new("center_y", self.center_y())), 4439 _ => None, 4440 } 4441 } 4442 } 4443 4444 #[cfg(feature = "traversal")] 4445 impl<'a> std::fmt::Debug for PaintScaleUniformAroundCenter<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result4446 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 4447 (self as &dyn SomeTable<'a>).fmt(f) 4448 } 4449 } 4450 4451 impl Format<u8> for PaintVarScaleUniformAroundCenterMarker { 4452 const FORMAT: u8 = 23; 4453 } 4454 4455 /// [PaintVarScaleUniformAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table 4456 #[derive(Debug, Clone, Copy)] 4457 #[doc(hidden)] 4458 pub struct PaintVarScaleUniformAroundCenterMarker {} 4459 4460 impl PaintVarScaleUniformAroundCenterMarker { format_byte_range(&self) -> Range<usize>4461 fn format_byte_range(&self) -> Range<usize> { 4462 let start = 0; 4463 start..start + u8::RAW_BYTE_LEN 4464 } paint_offset_byte_range(&self) -> Range<usize>4465 fn paint_offset_byte_range(&self) -> Range<usize> { 4466 let start = self.format_byte_range().end; 4467 start..start + Offset24::RAW_BYTE_LEN 4468 } scale_byte_range(&self) -> Range<usize>4469 fn scale_byte_range(&self) -> Range<usize> { 4470 let start = self.paint_offset_byte_range().end; 4471 start..start + F2Dot14::RAW_BYTE_LEN 4472 } center_x_byte_range(&self) -> Range<usize>4473 fn center_x_byte_range(&self) -> Range<usize> { 4474 let start = self.scale_byte_range().end; 4475 start..start + FWord::RAW_BYTE_LEN 4476 } center_y_byte_range(&self) -> Range<usize>4477 fn center_y_byte_range(&self) -> Range<usize> { 4478 let start = self.center_x_byte_range().end; 4479 start..start + FWord::RAW_BYTE_LEN 4480 } var_index_base_byte_range(&self) -> Range<usize>4481 fn var_index_base_byte_range(&self) -> Range<usize> { 4482 let start = self.center_y_byte_range().end; 4483 start..start + u32::RAW_BYTE_LEN 4484 } 4485 } 4486 4487 impl<'a> FontRead<'a> for PaintVarScaleUniformAroundCenter<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>4488 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 4489 let mut cursor = data.cursor(); 4490 cursor.advance::<u8>(); 4491 cursor.advance::<Offset24>(); 4492 cursor.advance::<F2Dot14>(); 4493 cursor.advance::<FWord>(); 4494 cursor.advance::<FWord>(); 4495 cursor.advance::<u32>(); 4496 cursor.finish(PaintVarScaleUniformAroundCenterMarker {}) 4497 } 4498 } 4499 4500 /// [PaintVarScaleUniformAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table 4501 pub type PaintVarScaleUniformAroundCenter<'a> = 4502 TableRef<'a, PaintVarScaleUniformAroundCenterMarker>; 4503 4504 impl<'a> PaintVarScaleUniformAroundCenter<'a> { 4505 /// Set to 23. format(&self) -> u84506 pub fn format(&self) -> u8 { 4507 let range = self.shape.format_byte_range(); 4508 self.data.read_at(range.start).unwrap() 4509 } 4510 4511 /// Offset to a Paint subtable. paint_offset(&self) -> Offset244512 pub fn paint_offset(&self) -> Offset24 { 4513 let range = self.shape.paint_offset_byte_range(); 4514 self.data.read_at(range.start).unwrap() 4515 } 4516 4517 /// Attempt to resolve [`paint_offset`][Self::paint_offset]. paint(&self) -> Result<Paint<'a>, ReadError>4518 pub fn paint(&self) -> Result<Paint<'a>, ReadError> { 4519 let data = self.data; 4520 self.paint_offset().resolve(data) 4521 } 4522 4523 /// Scale factor in x and y directions. For variation, use 4524 /// varIndexBase + 0. scale(&self) -> F2Dot144525 pub fn scale(&self) -> F2Dot14 { 4526 let range = self.shape.scale_byte_range(); 4527 self.data.read_at(range.start).unwrap() 4528 } 4529 4530 /// x coordinate for the center of scaling. For variation, use 4531 /// varIndexBase + 1. center_x(&self) -> FWord4532 pub fn center_x(&self) -> FWord { 4533 let range = self.shape.center_x_byte_range(); 4534 self.data.read_at(range.start).unwrap() 4535 } 4536 4537 /// y coordinate for the center of scaling. For variation, use 4538 /// varIndexBase + 2. center_y(&self) -> FWord4539 pub fn center_y(&self) -> FWord { 4540 let range = self.shape.center_y_byte_range(); 4541 self.data.read_at(range.start).unwrap() 4542 } 4543 4544 /// Base index into DeltaSetIndexMap. var_index_base(&self) -> u324545 pub fn var_index_base(&self) -> u32 { 4546 let range = self.shape.var_index_base_byte_range(); 4547 self.data.read_at(range.start).unwrap() 4548 } 4549 } 4550 4551 #[cfg(feature = "traversal")] 4552 impl<'a> SomeTable<'a> for PaintVarScaleUniformAroundCenter<'a> { type_name(&self) -> &str4553 fn type_name(&self) -> &str { 4554 "PaintVarScaleUniformAroundCenter" 4555 } get_field(&self, idx: usize) -> Option<Field<'a>>4556 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 4557 match idx { 4558 0usize => Some(Field::new("format", self.format())), 4559 1usize => Some(Field::new( 4560 "paint_offset", 4561 FieldType::offset(self.paint_offset(), self.paint()), 4562 )), 4563 2usize => Some(Field::new("scale", self.scale())), 4564 3usize => Some(Field::new("center_x", self.center_x())), 4565 4usize => Some(Field::new("center_y", self.center_y())), 4566 5usize => Some(Field::new("var_index_base", self.var_index_base())), 4567 _ => None, 4568 } 4569 } 4570 } 4571 4572 #[cfg(feature = "traversal")] 4573 impl<'a> std::fmt::Debug for PaintVarScaleUniformAroundCenter<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result4574 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 4575 (self as &dyn SomeTable<'a>).fmt(f) 4576 } 4577 } 4578 4579 impl Format<u8> for PaintRotateMarker { 4580 const FORMAT: u8 = 24; 4581 } 4582 4583 /// [PaintRotate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table 4584 #[derive(Debug, Clone, Copy)] 4585 #[doc(hidden)] 4586 pub struct PaintRotateMarker {} 4587 4588 impl PaintRotateMarker { format_byte_range(&self) -> Range<usize>4589 fn format_byte_range(&self) -> Range<usize> { 4590 let start = 0; 4591 start..start + u8::RAW_BYTE_LEN 4592 } paint_offset_byte_range(&self) -> Range<usize>4593 fn paint_offset_byte_range(&self) -> Range<usize> { 4594 let start = self.format_byte_range().end; 4595 start..start + Offset24::RAW_BYTE_LEN 4596 } angle_byte_range(&self) -> Range<usize>4597 fn angle_byte_range(&self) -> Range<usize> { 4598 let start = self.paint_offset_byte_range().end; 4599 start..start + F2Dot14::RAW_BYTE_LEN 4600 } 4601 } 4602 4603 impl<'a> FontRead<'a> for PaintRotate<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>4604 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 4605 let mut cursor = data.cursor(); 4606 cursor.advance::<u8>(); 4607 cursor.advance::<Offset24>(); 4608 cursor.advance::<F2Dot14>(); 4609 cursor.finish(PaintRotateMarker {}) 4610 } 4611 } 4612 4613 /// [PaintRotate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table 4614 pub type PaintRotate<'a> = TableRef<'a, PaintRotateMarker>; 4615 4616 impl<'a> PaintRotate<'a> { 4617 /// Set to 24. format(&self) -> u84618 pub fn format(&self) -> u8 { 4619 let range = self.shape.format_byte_range(); 4620 self.data.read_at(range.start).unwrap() 4621 } 4622 4623 /// Offset to a Paint subtable. paint_offset(&self) -> Offset244624 pub fn paint_offset(&self) -> Offset24 { 4625 let range = self.shape.paint_offset_byte_range(); 4626 self.data.read_at(range.start).unwrap() 4627 } 4628 4629 /// Attempt to resolve [`paint_offset`][Self::paint_offset]. paint(&self) -> Result<Paint<'a>, ReadError>4630 pub fn paint(&self) -> Result<Paint<'a>, ReadError> { 4631 let data = self.data; 4632 self.paint_offset().resolve(data) 4633 } 4634 4635 /// Rotation angle, 180° in counter-clockwise degrees per 1.0 of 4636 /// value. angle(&self) -> F2Dot144637 pub fn angle(&self) -> F2Dot14 { 4638 let range = self.shape.angle_byte_range(); 4639 self.data.read_at(range.start).unwrap() 4640 } 4641 } 4642 4643 #[cfg(feature = "traversal")] 4644 impl<'a> SomeTable<'a> for PaintRotate<'a> { type_name(&self) -> &str4645 fn type_name(&self) -> &str { 4646 "PaintRotate" 4647 } get_field(&self, idx: usize) -> Option<Field<'a>>4648 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 4649 match idx { 4650 0usize => Some(Field::new("format", self.format())), 4651 1usize => Some(Field::new( 4652 "paint_offset", 4653 FieldType::offset(self.paint_offset(), self.paint()), 4654 )), 4655 2usize => Some(Field::new("angle", self.angle())), 4656 _ => None, 4657 } 4658 } 4659 } 4660 4661 #[cfg(feature = "traversal")] 4662 impl<'a> std::fmt::Debug for PaintRotate<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result4663 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 4664 (self as &dyn SomeTable<'a>).fmt(f) 4665 } 4666 } 4667 4668 impl Format<u8> for PaintVarRotateMarker { 4669 const FORMAT: u8 = 25; 4670 } 4671 4672 /// [PaintVarRotate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table 4673 #[derive(Debug, Clone, Copy)] 4674 #[doc(hidden)] 4675 pub struct PaintVarRotateMarker {} 4676 4677 impl PaintVarRotateMarker { format_byte_range(&self) -> Range<usize>4678 fn format_byte_range(&self) -> Range<usize> { 4679 let start = 0; 4680 start..start + u8::RAW_BYTE_LEN 4681 } paint_offset_byte_range(&self) -> Range<usize>4682 fn paint_offset_byte_range(&self) -> Range<usize> { 4683 let start = self.format_byte_range().end; 4684 start..start + Offset24::RAW_BYTE_LEN 4685 } angle_byte_range(&self) -> Range<usize>4686 fn angle_byte_range(&self) -> Range<usize> { 4687 let start = self.paint_offset_byte_range().end; 4688 start..start + F2Dot14::RAW_BYTE_LEN 4689 } var_index_base_byte_range(&self) -> Range<usize>4690 fn var_index_base_byte_range(&self) -> Range<usize> { 4691 let start = self.angle_byte_range().end; 4692 start..start + u32::RAW_BYTE_LEN 4693 } 4694 } 4695 4696 impl<'a> FontRead<'a> for PaintVarRotate<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>4697 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 4698 let mut cursor = data.cursor(); 4699 cursor.advance::<u8>(); 4700 cursor.advance::<Offset24>(); 4701 cursor.advance::<F2Dot14>(); 4702 cursor.advance::<u32>(); 4703 cursor.finish(PaintVarRotateMarker {}) 4704 } 4705 } 4706 4707 /// [PaintVarRotate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table 4708 pub type PaintVarRotate<'a> = TableRef<'a, PaintVarRotateMarker>; 4709 4710 impl<'a> PaintVarRotate<'a> { 4711 /// Set to 25. format(&self) -> u84712 pub fn format(&self) -> u8 { 4713 let range = self.shape.format_byte_range(); 4714 self.data.read_at(range.start).unwrap() 4715 } 4716 4717 /// Offset to a Paint subtable. paint_offset(&self) -> Offset244718 pub fn paint_offset(&self) -> Offset24 { 4719 let range = self.shape.paint_offset_byte_range(); 4720 self.data.read_at(range.start).unwrap() 4721 } 4722 4723 /// Attempt to resolve [`paint_offset`][Self::paint_offset]. paint(&self) -> Result<Paint<'a>, ReadError>4724 pub fn paint(&self) -> Result<Paint<'a>, ReadError> { 4725 let data = self.data; 4726 self.paint_offset().resolve(data) 4727 } 4728 4729 /// Rotation angle, 180° in counter-clockwise degrees per 1.0 of 4730 /// value. For variation, use varIndexBase + 0. angle(&self) -> F2Dot144731 pub fn angle(&self) -> F2Dot14 { 4732 let range = self.shape.angle_byte_range(); 4733 self.data.read_at(range.start).unwrap() 4734 } 4735 4736 /// Base index into DeltaSetIndexMap. var_index_base(&self) -> u324737 pub fn var_index_base(&self) -> u32 { 4738 let range = self.shape.var_index_base_byte_range(); 4739 self.data.read_at(range.start).unwrap() 4740 } 4741 } 4742 4743 #[cfg(feature = "traversal")] 4744 impl<'a> SomeTable<'a> for PaintVarRotate<'a> { type_name(&self) -> &str4745 fn type_name(&self) -> &str { 4746 "PaintVarRotate" 4747 } get_field(&self, idx: usize) -> Option<Field<'a>>4748 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 4749 match idx { 4750 0usize => Some(Field::new("format", self.format())), 4751 1usize => Some(Field::new( 4752 "paint_offset", 4753 FieldType::offset(self.paint_offset(), self.paint()), 4754 )), 4755 2usize => Some(Field::new("angle", self.angle())), 4756 3usize => Some(Field::new("var_index_base", self.var_index_base())), 4757 _ => None, 4758 } 4759 } 4760 } 4761 4762 #[cfg(feature = "traversal")] 4763 impl<'a> std::fmt::Debug for PaintVarRotate<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result4764 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 4765 (self as &dyn SomeTable<'a>).fmt(f) 4766 } 4767 } 4768 4769 impl Format<u8> for PaintRotateAroundCenterMarker { 4770 const FORMAT: u8 = 26; 4771 } 4772 4773 /// [PaintRotateAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table 4774 #[derive(Debug, Clone, Copy)] 4775 #[doc(hidden)] 4776 pub struct PaintRotateAroundCenterMarker {} 4777 4778 impl PaintRotateAroundCenterMarker { format_byte_range(&self) -> Range<usize>4779 fn format_byte_range(&self) -> Range<usize> { 4780 let start = 0; 4781 start..start + u8::RAW_BYTE_LEN 4782 } paint_offset_byte_range(&self) -> Range<usize>4783 fn paint_offset_byte_range(&self) -> Range<usize> { 4784 let start = self.format_byte_range().end; 4785 start..start + Offset24::RAW_BYTE_LEN 4786 } angle_byte_range(&self) -> Range<usize>4787 fn angle_byte_range(&self) -> Range<usize> { 4788 let start = self.paint_offset_byte_range().end; 4789 start..start + F2Dot14::RAW_BYTE_LEN 4790 } center_x_byte_range(&self) -> Range<usize>4791 fn center_x_byte_range(&self) -> Range<usize> { 4792 let start = self.angle_byte_range().end; 4793 start..start + FWord::RAW_BYTE_LEN 4794 } center_y_byte_range(&self) -> Range<usize>4795 fn center_y_byte_range(&self) -> Range<usize> { 4796 let start = self.center_x_byte_range().end; 4797 start..start + FWord::RAW_BYTE_LEN 4798 } 4799 } 4800 4801 impl<'a> FontRead<'a> for PaintRotateAroundCenter<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>4802 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 4803 let mut cursor = data.cursor(); 4804 cursor.advance::<u8>(); 4805 cursor.advance::<Offset24>(); 4806 cursor.advance::<F2Dot14>(); 4807 cursor.advance::<FWord>(); 4808 cursor.advance::<FWord>(); 4809 cursor.finish(PaintRotateAroundCenterMarker {}) 4810 } 4811 } 4812 4813 /// [PaintRotateAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table 4814 pub type PaintRotateAroundCenter<'a> = TableRef<'a, PaintRotateAroundCenterMarker>; 4815 4816 impl<'a> PaintRotateAroundCenter<'a> { 4817 /// Set to 26. format(&self) -> u84818 pub fn format(&self) -> u8 { 4819 let range = self.shape.format_byte_range(); 4820 self.data.read_at(range.start).unwrap() 4821 } 4822 4823 /// Offset to a Paint subtable. paint_offset(&self) -> Offset244824 pub fn paint_offset(&self) -> Offset24 { 4825 let range = self.shape.paint_offset_byte_range(); 4826 self.data.read_at(range.start).unwrap() 4827 } 4828 4829 /// Attempt to resolve [`paint_offset`][Self::paint_offset]. paint(&self) -> Result<Paint<'a>, ReadError>4830 pub fn paint(&self) -> Result<Paint<'a>, ReadError> { 4831 let data = self.data; 4832 self.paint_offset().resolve(data) 4833 } 4834 4835 /// Rotation angle, 180° in counter-clockwise degrees per 1.0 of 4836 /// value. angle(&self) -> F2Dot144837 pub fn angle(&self) -> F2Dot14 { 4838 let range = self.shape.angle_byte_range(); 4839 self.data.read_at(range.start).unwrap() 4840 } 4841 4842 /// x coordinate for the center of rotation. center_x(&self) -> FWord4843 pub fn center_x(&self) -> FWord { 4844 let range = self.shape.center_x_byte_range(); 4845 self.data.read_at(range.start).unwrap() 4846 } 4847 4848 /// y coordinate for the center of rotation. center_y(&self) -> FWord4849 pub fn center_y(&self) -> FWord { 4850 let range = self.shape.center_y_byte_range(); 4851 self.data.read_at(range.start).unwrap() 4852 } 4853 } 4854 4855 #[cfg(feature = "traversal")] 4856 impl<'a> SomeTable<'a> for PaintRotateAroundCenter<'a> { type_name(&self) -> &str4857 fn type_name(&self) -> &str { 4858 "PaintRotateAroundCenter" 4859 } get_field(&self, idx: usize) -> Option<Field<'a>>4860 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 4861 match idx { 4862 0usize => Some(Field::new("format", self.format())), 4863 1usize => Some(Field::new( 4864 "paint_offset", 4865 FieldType::offset(self.paint_offset(), self.paint()), 4866 )), 4867 2usize => Some(Field::new("angle", self.angle())), 4868 3usize => Some(Field::new("center_x", self.center_x())), 4869 4usize => Some(Field::new("center_y", self.center_y())), 4870 _ => None, 4871 } 4872 } 4873 } 4874 4875 #[cfg(feature = "traversal")] 4876 impl<'a> std::fmt::Debug for PaintRotateAroundCenter<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result4877 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 4878 (self as &dyn SomeTable<'a>).fmt(f) 4879 } 4880 } 4881 4882 impl Format<u8> for PaintVarRotateAroundCenterMarker { 4883 const FORMAT: u8 = 27; 4884 } 4885 4886 /// [PaintVarRotateAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table 4887 #[derive(Debug, Clone, Copy)] 4888 #[doc(hidden)] 4889 pub struct PaintVarRotateAroundCenterMarker {} 4890 4891 impl PaintVarRotateAroundCenterMarker { format_byte_range(&self) -> Range<usize>4892 fn format_byte_range(&self) -> Range<usize> { 4893 let start = 0; 4894 start..start + u8::RAW_BYTE_LEN 4895 } paint_offset_byte_range(&self) -> Range<usize>4896 fn paint_offset_byte_range(&self) -> Range<usize> { 4897 let start = self.format_byte_range().end; 4898 start..start + Offset24::RAW_BYTE_LEN 4899 } angle_byte_range(&self) -> Range<usize>4900 fn angle_byte_range(&self) -> Range<usize> { 4901 let start = self.paint_offset_byte_range().end; 4902 start..start + F2Dot14::RAW_BYTE_LEN 4903 } center_x_byte_range(&self) -> Range<usize>4904 fn center_x_byte_range(&self) -> Range<usize> { 4905 let start = self.angle_byte_range().end; 4906 start..start + FWord::RAW_BYTE_LEN 4907 } center_y_byte_range(&self) -> Range<usize>4908 fn center_y_byte_range(&self) -> Range<usize> { 4909 let start = self.center_x_byte_range().end; 4910 start..start + FWord::RAW_BYTE_LEN 4911 } var_index_base_byte_range(&self) -> Range<usize>4912 fn var_index_base_byte_range(&self) -> Range<usize> { 4913 let start = self.center_y_byte_range().end; 4914 start..start + u32::RAW_BYTE_LEN 4915 } 4916 } 4917 4918 impl<'a> FontRead<'a> for PaintVarRotateAroundCenter<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>4919 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 4920 let mut cursor = data.cursor(); 4921 cursor.advance::<u8>(); 4922 cursor.advance::<Offset24>(); 4923 cursor.advance::<F2Dot14>(); 4924 cursor.advance::<FWord>(); 4925 cursor.advance::<FWord>(); 4926 cursor.advance::<u32>(); 4927 cursor.finish(PaintVarRotateAroundCenterMarker {}) 4928 } 4929 } 4930 4931 /// [PaintVarRotateAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table 4932 pub type PaintVarRotateAroundCenter<'a> = TableRef<'a, PaintVarRotateAroundCenterMarker>; 4933 4934 impl<'a> PaintVarRotateAroundCenter<'a> { 4935 /// Set to 27. format(&self) -> u84936 pub fn format(&self) -> u8 { 4937 let range = self.shape.format_byte_range(); 4938 self.data.read_at(range.start).unwrap() 4939 } 4940 4941 /// Offset to a Paint subtable. paint_offset(&self) -> Offset244942 pub fn paint_offset(&self) -> Offset24 { 4943 let range = self.shape.paint_offset_byte_range(); 4944 self.data.read_at(range.start).unwrap() 4945 } 4946 4947 /// Attempt to resolve [`paint_offset`][Self::paint_offset]. paint(&self) -> Result<Paint<'a>, ReadError>4948 pub fn paint(&self) -> Result<Paint<'a>, ReadError> { 4949 let data = self.data; 4950 self.paint_offset().resolve(data) 4951 } 4952 4953 /// Rotation angle, 180° in counter-clockwise degrees per 1.0 of 4954 /// value. For variation, use varIndexBase + 0. angle(&self) -> F2Dot144955 pub fn angle(&self) -> F2Dot14 { 4956 let range = self.shape.angle_byte_range(); 4957 self.data.read_at(range.start).unwrap() 4958 } 4959 4960 /// x coordinate for the center of rotation. For variation, use 4961 /// varIndexBase + 1. center_x(&self) -> FWord4962 pub fn center_x(&self) -> FWord { 4963 let range = self.shape.center_x_byte_range(); 4964 self.data.read_at(range.start).unwrap() 4965 } 4966 4967 /// y coordinate for the center of rotation. For variation, use 4968 /// varIndexBase + 2. center_y(&self) -> FWord4969 pub fn center_y(&self) -> FWord { 4970 let range = self.shape.center_y_byte_range(); 4971 self.data.read_at(range.start).unwrap() 4972 } 4973 4974 /// Base index into DeltaSetIndexMap. var_index_base(&self) -> u324975 pub fn var_index_base(&self) -> u32 { 4976 let range = self.shape.var_index_base_byte_range(); 4977 self.data.read_at(range.start).unwrap() 4978 } 4979 } 4980 4981 #[cfg(feature = "traversal")] 4982 impl<'a> SomeTable<'a> for PaintVarRotateAroundCenter<'a> { type_name(&self) -> &str4983 fn type_name(&self) -> &str { 4984 "PaintVarRotateAroundCenter" 4985 } get_field(&self, idx: usize) -> Option<Field<'a>>4986 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 4987 match idx { 4988 0usize => Some(Field::new("format", self.format())), 4989 1usize => Some(Field::new( 4990 "paint_offset", 4991 FieldType::offset(self.paint_offset(), self.paint()), 4992 )), 4993 2usize => Some(Field::new("angle", self.angle())), 4994 3usize => Some(Field::new("center_x", self.center_x())), 4995 4usize => Some(Field::new("center_y", self.center_y())), 4996 5usize => Some(Field::new("var_index_base", self.var_index_base())), 4997 _ => None, 4998 } 4999 } 5000 } 5001 5002 #[cfg(feature = "traversal")] 5003 impl<'a> std::fmt::Debug for PaintVarRotateAroundCenter<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result5004 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 5005 (self as &dyn SomeTable<'a>).fmt(f) 5006 } 5007 } 5008 5009 impl Format<u8> for PaintSkewMarker { 5010 const FORMAT: u8 = 28; 5011 } 5012 5013 /// [PaintSkew](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table 5014 #[derive(Debug, Clone, Copy)] 5015 #[doc(hidden)] 5016 pub struct PaintSkewMarker {} 5017 5018 impl PaintSkewMarker { format_byte_range(&self) -> Range<usize>5019 fn format_byte_range(&self) -> Range<usize> { 5020 let start = 0; 5021 start..start + u8::RAW_BYTE_LEN 5022 } paint_offset_byte_range(&self) -> Range<usize>5023 fn paint_offset_byte_range(&self) -> Range<usize> { 5024 let start = self.format_byte_range().end; 5025 start..start + Offset24::RAW_BYTE_LEN 5026 } x_skew_angle_byte_range(&self) -> Range<usize>5027 fn x_skew_angle_byte_range(&self) -> Range<usize> { 5028 let start = self.paint_offset_byte_range().end; 5029 start..start + F2Dot14::RAW_BYTE_LEN 5030 } y_skew_angle_byte_range(&self) -> Range<usize>5031 fn y_skew_angle_byte_range(&self) -> Range<usize> { 5032 let start = self.x_skew_angle_byte_range().end; 5033 start..start + F2Dot14::RAW_BYTE_LEN 5034 } 5035 } 5036 5037 impl<'a> FontRead<'a> for PaintSkew<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>5038 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 5039 let mut cursor = data.cursor(); 5040 cursor.advance::<u8>(); 5041 cursor.advance::<Offset24>(); 5042 cursor.advance::<F2Dot14>(); 5043 cursor.advance::<F2Dot14>(); 5044 cursor.finish(PaintSkewMarker {}) 5045 } 5046 } 5047 5048 /// [PaintSkew](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table 5049 pub type PaintSkew<'a> = TableRef<'a, PaintSkewMarker>; 5050 5051 impl<'a> PaintSkew<'a> { 5052 /// Set to 28. format(&self) -> u85053 pub fn format(&self) -> u8 { 5054 let range = self.shape.format_byte_range(); 5055 self.data.read_at(range.start).unwrap() 5056 } 5057 5058 /// Offset to a Paint subtable. paint_offset(&self) -> Offset245059 pub fn paint_offset(&self) -> Offset24 { 5060 let range = self.shape.paint_offset_byte_range(); 5061 self.data.read_at(range.start).unwrap() 5062 } 5063 5064 /// Attempt to resolve [`paint_offset`][Self::paint_offset]. paint(&self) -> Result<Paint<'a>, ReadError>5065 pub fn paint(&self) -> Result<Paint<'a>, ReadError> { 5066 let data = self.data; 5067 self.paint_offset().resolve(data) 5068 } 5069 5070 /// Angle of skew in the direction of the x-axis, 180° in 5071 /// counter-clockwise degrees per 1.0 of value. x_skew_angle(&self) -> F2Dot145072 pub fn x_skew_angle(&self) -> F2Dot14 { 5073 let range = self.shape.x_skew_angle_byte_range(); 5074 self.data.read_at(range.start).unwrap() 5075 } 5076 5077 /// Angle of skew in the direction of the y-axis, 180° in 5078 /// counter-clockwise degrees per 1.0 of value. y_skew_angle(&self) -> F2Dot145079 pub fn y_skew_angle(&self) -> F2Dot14 { 5080 let range = self.shape.y_skew_angle_byte_range(); 5081 self.data.read_at(range.start).unwrap() 5082 } 5083 } 5084 5085 #[cfg(feature = "traversal")] 5086 impl<'a> SomeTable<'a> for PaintSkew<'a> { type_name(&self) -> &str5087 fn type_name(&self) -> &str { 5088 "PaintSkew" 5089 } get_field(&self, idx: usize) -> Option<Field<'a>>5090 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 5091 match idx { 5092 0usize => Some(Field::new("format", self.format())), 5093 1usize => Some(Field::new( 5094 "paint_offset", 5095 FieldType::offset(self.paint_offset(), self.paint()), 5096 )), 5097 2usize => Some(Field::new("x_skew_angle", self.x_skew_angle())), 5098 3usize => Some(Field::new("y_skew_angle", self.y_skew_angle())), 5099 _ => None, 5100 } 5101 } 5102 } 5103 5104 #[cfg(feature = "traversal")] 5105 impl<'a> std::fmt::Debug for PaintSkew<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result5106 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 5107 (self as &dyn SomeTable<'a>).fmt(f) 5108 } 5109 } 5110 5111 impl Format<u8> for PaintVarSkewMarker { 5112 const FORMAT: u8 = 29; 5113 } 5114 5115 /// [PaintVarSkew](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table 5116 #[derive(Debug, Clone, Copy)] 5117 #[doc(hidden)] 5118 pub struct PaintVarSkewMarker {} 5119 5120 impl PaintVarSkewMarker { format_byte_range(&self) -> Range<usize>5121 fn format_byte_range(&self) -> Range<usize> { 5122 let start = 0; 5123 start..start + u8::RAW_BYTE_LEN 5124 } paint_offset_byte_range(&self) -> Range<usize>5125 fn paint_offset_byte_range(&self) -> Range<usize> { 5126 let start = self.format_byte_range().end; 5127 start..start + Offset24::RAW_BYTE_LEN 5128 } x_skew_angle_byte_range(&self) -> Range<usize>5129 fn x_skew_angle_byte_range(&self) -> Range<usize> { 5130 let start = self.paint_offset_byte_range().end; 5131 start..start + F2Dot14::RAW_BYTE_LEN 5132 } y_skew_angle_byte_range(&self) -> Range<usize>5133 fn y_skew_angle_byte_range(&self) -> Range<usize> { 5134 let start = self.x_skew_angle_byte_range().end; 5135 start..start + F2Dot14::RAW_BYTE_LEN 5136 } var_index_base_byte_range(&self) -> Range<usize>5137 fn var_index_base_byte_range(&self) -> Range<usize> { 5138 let start = self.y_skew_angle_byte_range().end; 5139 start..start + u32::RAW_BYTE_LEN 5140 } 5141 } 5142 5143 impl<'a> FontRead<'a> for PaintVarSkew<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>5144 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 5145 let mut cursor = data.cursor(); 5146 cursor.advance::<u8>(); 5147 cursor.advance::<Offset24>(); 5148 cursor.advance::<F2Dot14>(); 5149 cursor.advance::<F2Dot14>(); 5150 cursor.advance::<u32>(); 5151 cursor.finish(PaintVarSkewMarker {}) 5152 } 5153 } 5154 5155 /// [PaintVarSkew](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table 5156 pub type PaintVarSkew<'a> = TableRef<'a, PaintVarSkewMarker>; 5157 5158 impl<'a> PaintVarSkew<'a> { 5159 /// Set to 29. format(&self) -> u85160 pub fn format(&self) -> u8 { 5161 let range = self.shape.format_byte_range(); 5162 self.data.read_at(range.start).unwrap() 5163 } 5164 5165 /// Offset to a Paint subtable. paint_offset(&self) -> Offset245166 pub fn paint_offset(&self) -> Offset24 { 5167 let range = self.shape.paint_offset_byte_range(); 5168 self.data.read_at(range.start).unwrap() 5169 } 5170 5171 /// Attempt to resolve [`paint_offset`][Self::paint_offset]. paint(&self) -> Result<Paint<'a>, ReadError>5172 pub fn paint(&self) -> Result<Paint<'a>, ReadError> { 5173 let data = self.data; 5174 self.paint_offset().resolve(data) 5175 } 5176 5177 /// Angle of skew in the direction of the x-axis, 180° ┬░ in 5178 /// counter-clockwise degrees per 1.0 of value. For variation, use 5179 /// varIndexBase + 0. x_skew_angle(&self) -> F2Dot145180 pub fn x_skew_angle(&self) -> F2Dot14 { 5181 let range = self.shape.x_skew_angle_byte_range(); 5182 self.data.read_at(range.start).unwrap() 5183 } 5184 5185 /// Angle of skew in the direction of the y-axis, 180° in 5186 /// counter-clockwise degrees per 1.0 of value. For variation, use 5187 /// varIndexBase + 1. y_skew_angle(&self) -> F2Dot145188 pub fn y_skew_angle(&self) -> F2Dot14 { 5189 let range = self.shape.y_skew_angle_byte_range(); 5190 self.data.read_at(range.start).unwrap() 5191 } 5192 5193 /// Base index into DeltaSetIndexMap. var_index_base(&self) -> u325194 pub fn var_index_base(&self) -> u32 { 5195 let range = self.shape.var_index_base_byte_range(); 5196 self.data.read_at(range.start).unwrap() 5197 } 5198 } 5199 5200 #[cfg(feature = "traversal")] 5201 impl<'a> SomeTable<'a> for PaintVarSkew<'a> { type_name(&self) -> &str5202 fn type_name(&self) -> &str { 5203 "PaintVarSkew" 5204 } get_field(&self, idx: usize) -> Option<Field<'a>>5205 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 5206 match idx { 5207 0usize => Some(Field::new("format", self.format())), 5208 1usize => Some(Field::new( 5209 "paint_offset", 5210 FieldType::offset(self.paint_offset(), self.paint()), 5211 )), 5212 2usize => Some(Field::new("x_skew_angle", self.x_skew_angle())), 5213 3usize => Some(Field::new("y_skew_angle", self.y_skew_angle())), 5214 4usize => Some(Field::new("var_index_base", self.var_index_base())), 5215 _ => None, 5216 } 5217 } 5218 } 5219 5220 #[cfg(feature = "traversal")] 5221 impl<'a> std::fmt::Debug for PaintVarSkew<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result5222 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 5223 (self as &dyn SomeTable<'a>).fmt(f) 5224 } 5225 } 5226 5227 impl Format<u8> for PaintSkewAroundCenterMarker { 5228 const FORMAT: u8 = 30; 5229 } 5230 5231 /// [PaintSkewAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table 5232 #[derive(Debug, Clone, Copy)] 5233 #[doc(hidden)] 5234 pub struct PaintSkewAroundCenterMarker {} 5235 5236 impl PaintSkewAroundCenterMarker { format_byte_range(&self) -> Range<usize>5237 fn format_byte_range(&self) -> Range<usize> { 5238 let start = 0; 5239 start..start + u8::RAW_BYTE_LEN 5240 } paint_offset_byte_range(&self) -> Range<usize>5241 fn paint_offset_byte_range(&self) -> Range<usize> { 5242 let start = self.format_byte_range().end; 5243 start..start + Offset24::RAW_BYTE_LEN 5244 } x_skew_angle_byte_range(&self) -> Range<usize>5245 fn x_skew_angle_byte_range(&self) -> Range<usize> { 5246 let start = self.paint_offset_byte_range().end; 5247 start..start + F2Dot14::RAW_BYTE_LEN 5248 } y_skew_angle_byte_range(&self) -> Range<usize>5249 fn y_skew_angle_byte_range(&self) -> Range<usize> { 5250 let start = self.x_skew_angle_byte_range().end; 5251 start..start + F2Dot14::RAW_BYTE_LEN 5252 } center_x_byte_range(&self) -> Range<usize>5253 fn center_x_byte_range(&self) -> Range<usize> { 5254 let start = self.y_skew_angle_byte_range().end; 5255 start..start + FWord::RAW_BYTE_LEN 5256 } center_y_byte_range(&self) -> Range<usize>5257 fn center_y_byte_range(&self) -> Range<usize> { 5258 let start = self.center_x_byte_range().end; 5259 start..start + FWord::RAW_BYTE_LEN 5260 } 5261 } 5262 5263 impl<'a> FontRead<'a> for PaintSkewAroundCenter<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>5264 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 5265 let mut cursor = data.cursor(); 5266 cursor.advance::<u8>(); 5267 cursor.advance::<Offset24>(); 5268 cursor.advance::<F2Dot14>(); 5269 cursor.advance::<F2Dot14>(); 5270 cursor.advance::<FWord>(); 5271 cursor.advance::<FWord>(); 5272 cursor.finish(PaintSkewAroundCenterMarker {}) 5273 } 5274 } 5275 5276 /// [PaintSkewAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table 5277 pub type PaintSkewAroundCenter<'a> = TableRef<'a, PaintSkewAroundCenterMarker>; 5278 5279 impl<'a> PaintSkewAroundCenter<'a> { 5280 /// Set to 30. format(&self) -> u85281 pub fn format(&self) -> u8 { 5282 let range = self.shape.format_byte_range(); 5283 self.data.read_at(range.start).unwrap() 5284 } 5285 5286 /// Offset to a Paint subtable. paint_offset(&self) -> Offset245287 pub fn paint_offset(&self) -> Offset24 { 5288 let range = self.shape.paint_offset_byte_range(); 5289 self.data.read_at(range.start).unwrap() 5290 } 5291 5292 /// Attempt to resolve [`paint_offset`][Self::paint_offset]. paint(&self) -> Result<Paint<'a>, ReadError>5293 pub fn paint(&self) -> Result<Paint<'a>, ReadError> { 5294 let data = self.data; 5295 self.paint_offset().resolve(data) 5296 } 5297 5298 /// Angle of skew in the direction of the x-axis, 180° in 5299 /// counter-clockwise degrees per 1.0 of value. x_skew_angle(&self) -> F2Dot145300 pub fn x_skew_angle(&self) -> F2Dot14 { 5301 let range = self.shape.x_skew_angle_byte_range(); 5302 self.data.read_at(range.start).unwrap() 5303 } 5304 5305 /// Angle of skew in the direction of the y-axis, 180° in 5306 /// counter-clockwise degrees per 1.0 of value. y_skew_angle(&self) -> F2Dot145307 pub fn y_skew_angle(&self) -> F2Dot14 { 5308 let range = self.shape.y_skew_angle_byte_range(); 5309 self.data.read_at(range.start).unwrap() 5310 } 5311 5312 /// x coordinate for the center of rotation. center_x(&self) -> FWord5313 pub fn center_x(&self) -> FWord { 5314 let range = self.shape.center_x_byte_range(); 5315 self.data.read_at(range.start).unwrap() 5316 } 5317 5318 /// y coordinate for the center of rotation. center_y(&self) -> FWord5319 pub fn center_y(&self) -> FWord { 5320 let range = self.shape.center_y_byte_range(); 5321 self.data.read_at(range.start).unwrap() 5322 } 5323 } 5324 5325 #[cfg(feature = "traversal")] 5326 impl<'a> SomeTable<'a> for PaintSkewAroundCenter<'a> { type_name(&self) -> &str5327 fn type_name(&self) -> &str { 5328 "PaintSkewAroundCenter" 5329 } get_field(&self, idx: usize) -> Option<Field<'a>>5330 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 5331 match idx { 5332 0usize => Some(Field::new("format", self.format())), 5333 1usize => Some(Field::new( 5334 "paint_offset", 5335 FieldType::offset(self.paint_offset(), self.paint()), 5336 )), 5337 2usize => Some(Field::new("x_skew_angle", self.x_skew_angle())), 5338 3usize => Some(Field::new("y_skew_angle", self.y_skew_angle())), 5339 4usize => Some(Field::new("center_x", self.center_x())), 5340 5usize => Some(Field::new("center_y", self.center_y())), 5341 _ => None, 5342 } 5343 } 5344 } 5345 5346 #[cfg(feature = "traversal")] 5347 impl<'a> std::fmt::Debug for PaintSkewAroundCenter<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result5348 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 5349 (self as &dyn SomeTable<'a>).fmt(f) 5350 } 5351 } 5352 5353 impl Format<u8> for PaintVarSkewAroundCenterMarker { 5354 const FORMAT: u8 = 31; 5355 } 5356 5357 /// [PaintVarSkewAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table 5358 #[derive(Debug, Clone, Copy)] 5359 #[doc(hidden)] 5360 pub struct PaintVarSkewAroundCenterMarker {} 5361 5362 impl PaintVarSkewAroundCenterMarker { format_byte_range(&self) -> Range<usize>5363 fn format_byte_range(&self) -> Range<usize> { 5364 let start = 0; 5365 start..start + u8::RAW_BYTE_LEN 5366 } paint_offset_byte_range(&self) -> Range<usize>5367 fn paint_offset_byte_range(&self) -> Range<usize> { 5368 let start = self.format_byte_range().end; 5369 start..start + Offset24::RAW_BYTE_LEN 5370 } x_skew_angle_byte_range(&self) -> Range<usize>5371 fn x_skew_angle_byte_range(&self) -> Range<usize> { 5372 let start = self.paint_offset_byte_range().end; 5373 start..start + F2Dot14::RAW_BYTE_LEN 5374 } y_skew_angle_byte_range(&self) -> Range<usize>5375 fn y_skew_angle_byte_range(&self) -> Range<usize> { 5376 let start = self.x_skew_angle_byte_range().end; 5377 start..start + F2Dot14::RAW_BYTE_LEN 5378 } center_x_byte_range(&self) -> Range<usize>5379 fn center_x_byte_range(&self) -> Range<usize> { 5380 let start = self.y_skew_angle_byte_range().end; 5381 start..start + FWord::RAW_BYTE_LEN 5382 } center_y_byte_range(&self) -> Range<usize>5383 fn center_y_byte_range(&self) -> Range<usize> { 5384 let start = self.center_x_byte_range().end; 5385 start..start + FWord::RAW_BYTE_LEN 5386 } var_index_base_byte_range(&self) -> Range<usize>5387 fn var_index_base_byte_range(&self) -> Range<usize> { 5388 let start = self.center_y_byte_range().end; 5389 start..start + u32::RAW_BYTE_LEN 5390 } 5391 } 5392 5393 impl<'a> FontRead<'a> for PaintVarSkewAroundCenter<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>5394 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 5395 let mut cursor = data.cursor(); 5396 cursor.advance::<u8>(); 5397 cursor.advance::<Offset24>(); 5398 cursor.advance::<F2Dot14>(); 5399 cursor.advance::<F2Dot14>(); 5400 cursor.advance::<FWord>(); 5401 cursor.advance::<FWord>(); 5402 cursor.advance::<u32>(); 5403 cursor.finish(PaintVarSkewAroundCenterMarker {}) 5404 } 5405 } 5406 5407 /// [PaintVarSkewAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table 5408 pub type PaintVarSkewAroundCenter<'a> = TableRef<'a, PaintVarSkewAroundCenterMarker>; 5409 5410 impl<'a> PaintVarSkewAroundCenter<'a> { 5411 /// Set to 31. format(&self) -> u85412 pub fn format(&self) -> u8 { 5413 let range = self.shape.format_byte_range(); 5414 self.data.read_at(range.start).unwrap() 5415 } 5416 5417 /// Offset to a Paint subtable. paint_offset(&self) -> Offset245418 pub fn paint_offset(&self) -> Offset24 { 5419 let range = self.shape.paint_offset_byte_range(); 5420 self.data.read_at(range.start).unwrap() 5421 } 5422 5423 /// Attempt to resolve [`paint_offset`][Self::paint_offset]. paint(&self) -> Result<Paint<'a>, ReadError>5424 pub fn paint(&self) -> Result<Paint<'a>, ReadError> { 5425 let data = self.data; 5426 self.paint_offset().resolve(data) 5427 } 5428 5429 /// Angle of skew in the direction of the x-axis, 180° in 5430 /// counter-clockwise degrees per 1.0 of value. For variation, use 5431 /// varIndexBase + 0. x_skew_angle(&self) -> F2Dot145432 pub fn x_skew_angle(&self) -> F2Dot14 { 5433 let range = self.shape.x_skew_angle_byte_range(); 5434 self.data.read_at(range.start).unwrap() 5435 } 5436 5437 /// Angle of skew in the direction of the y-axis, 180° in 5438 /// counter-clockwise degrees per 1.0 of value. For variation, use 5439 /// varIndexBase + 1. y_skew_angle(&self) -> F2Dot145440 pub fn y_skew_angle(&self) -> F2Dot14 { 5441 let range = self.shape.y_skew_angle_byte_range(); 5442 self.data.read_at(range.start).unwrap() 5443 } 5444 5445 /// x coordinate for the center of rotation. For variation, use 5446 /// varIndexBase + 2. center_x(&self) -> FWord5447 pub fn center_x(&self) -> FWord { 5448 let range = self.shape.center_x_byte_range(); 5449 self.data.read_at(range.start).unwrap() 5450 } 5451 5452 /// y coordinate for the center of rotation. For variation, use 5453 /// varIndexBase + 3. center_y(&self) -> FWord5454 pub fn center_y(&self) -> FWord { 5455 let range = self.shape.center_y_byte_range(); 5456 self.data.read_at(range.start).unwrap() 5457 } 5458 5459 /// Base index into DeltaSetIndexMap. var_index_base(&self) -> u325460 pub fn var_index_base(&self) -> u32 { 5461 let range = self.shape.var_index_base_byte_range(); 5462 self.data.read_at(range.start).unwrap() 5463 } 5464 } 5465 5466 #[cfg(feature = "traversal")] 5467 impl<'a> SomeTable<'a> for PaintVarSkewAroundCenter<'a> { type_name(&self) -> &str5468 fn type_name(&self) -> &str { 5469 "PaintVarSkewAroundCenter" 5470 } get_field(&self, idx: usize) -> Option<Field<'a>>5471 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 5472 match idx { 5473 0usize => Some(Field::new("format", self.format())), 5474 1usize => Some(Field::new( 5475 "paint_offset", 5476 FieldType::offset(self.paint_offset(), self.paint()), 5477 )), 5478 2usize => Some(Field::new("x_skew_angle", self.x_skew_angle())), 5479 3usize => Some(Field::new("y_skew_angle", self.y_skew_angle())), 5480 4usize => Some(Field::new("center_x", self.center_x())), 5481 5usize => Some(Field::new("center_y", self.center_y())), 5482 6usize => Some(Field::new("var_index_base", self.var_index_base())), 5483 _ => None, 5484 } 5485 } 5486 } 5487 5488 #[cfg(feature = "traversal")] 5489 impl<'a> std::fmt::Debug for PaintVarSkewAroundCenter<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result5490 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 5491 (self as &dyn SomeTable<'a>).fmt(f) 5492 } 5493 } 5494 5495 impl Format<u8> for PaintCompositeMarker { 5496 const FORMAT: u8 = 32; 5497 } 5498 5499 /// [PaintComposite](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-32-paintcomposite) table 5500 #[derive(Debug, Clone, Copy)] 5501 #[doc(hidden)] 5502 pub struct PaintCompositeMarker {} 5503 5504 impl PaintCompositeMarker { format_byte_range(&self) -> Range<usize>5505 fn format_byte_range(&self) -> Range<usize> { 5506 let start = 0; 5507 start..start + u8::RAW_BYTE_LEN 5508 } source_paint_offset_byte_range(&self) -> Range<usize>5509 fn source_paint_offset_byte_range(&self) -> Range<usize> { 5510 let start = self.format_byte_range().end; 5511 start..start + Offset24::RAW_BYTE_LEN 5512 } composite_mode_byte_range(&self) -> Range<usize>5513 fn composite_mode_byte_range(&self) -> Range<usize> { 5514 let start = self.source_paint_offset_byte_range().end; 5515 start..start + CompositeMode::RAW_BYTE_LEN 5516 } backdrop_paint_offset_byte_range(&self) -> Range<usize>5517 fn backdrop_paint_offset_byte_range(&self) -> Range<usize> { 5518 let start = self.composite_mode_byte_range().end; 5519 start..start + Offset24::RAW_BYTE_LEN 5520 } 5521 } 5522 5523 impl<'a> FontRead<'a> for PaintComposite<'a> { read(data: FontData<'a>) -> Result<Self, ReadError>5524 fn read(data: FontData<'a>) -> Result<Self, ReadError> { 5525 let mut cursor = data.cursor(); 5526 cursor.advance::<u8>(); 5527 cursor.advance::<Offset24>(); 5528 cursor.advance::<CompositeMode>(); 5529 cursor.advance::<Offset24>(); 5530 cursor.finish(PaintCompositeMarker {}) 5531 } 5532 } 5533 5534 /// [PaintComposite](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-32-paintcomposite) table 5535 pub type PaintComposite<'a> = TableRef<'a, PaintCompositeMarker>; 5536 5537 impl<'a> PaintComposite<'a> { 5538 /// Set to 32. format(&self) -> u85539 pub fn format(&self) -> u8 { 5540 let range = self.shape.format_byte_range(); 5541 self.data.read_at(range.start).unwrap() 5542 } 5543 5544 /// Offset to a source Paint table. source_paint_offset(&self) -> Offset245545 pub fn source_paint_offset(&self) -> Offset24 { 5546 let range = self.shape.source_paint_offset_byte_range(); 5547 self.data.read_at(range.start).unwrap() 5548 } 5549 5550 /// Attempt to resolve [`source_paint_offset`][Self::source_paint_offset]. source_paint(&self) -> Result<Paint<'a>, ReadError>5551 pub fn source_paint(&self) -> Result<Paint<'a>, ReadError> { 5552 let data = self.data; 5553 self.source_paint_offset().resolve(data) 5554 } 5555 5556 /// A CompositeMode enumeration value. composite_mode(&self) -> CompositeMode5557 pub fn composite_mode(&self) -> CompositeMode { 5558 let range = self.shape.composite_mode_byte_range(); 5559 self.data.read_at(range.start).unwrap() 5560 } 5561 5562 /// Offset to a backdrop Paint table. backdrop_paint_offset(&self) -> Offset245563 pub fn backdrop_paint_offset(&self) -> Offset24 { 5564 let range = self.shape.backdrop_paint_offset_byte_range(); 5565 self.data.read_at(range.start).unwrap() 5566 } 5567 5568 /// Attempt to resolve [`backdrop_paint_offset`][Self::backdrop_paint_offset]. backdrop_paint(&self) -> Result<Paint<'a>, ReadError>5569 pub fn backdrop_paint(&self) -> Result<Paint<'a>, ReadError> { 5570 let data = self.data; 5571 self.backdrop_paint_offset().resolve(data) 5572 } 5573 } 5574 5575 #[cfg(feature = "traversal")] 5576 impl<'a> SomeTable<'a> for PaintComposite<'a> { type_name(&self) -> &str5577 fn type_name(&self) -> &str { 5578 "PaintComposite" 5579 } get_field(&self, idx: usize) -> Option<Field<'a>>5580 fn get_field(&self, idx: usize) -> Option<Field<'a>> { 5581 match idx { 5582 0usize => Some(Field::new("format", self.format())), 5583 1usize => Some(Field::new( 5584 "source_paint_offset", 5585 FieldType::offset(self.source_paint_offset(), self.source_paint()), 5586 )), 5587 2usize => Some(Field::new("composite_mode", self.composite_mode())), 5588 3usize => Some(Field::new( 5589 "backdrop_paint_offset", 5590 FieldType::offset(self.backdrop_paint_offset(), self.backdrop_paint()), 5591 )), 5592 _ => None, 5593 } 5594 } 5595 } 5596 5597 #[cfg(feature = "traversal")] 5598 impl<'a> std::fmt::Debug for PaintComposite<'a> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result5599 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 5600 (self as &dyn SomeTable<'a>).fmt(f) 5601 } 5602 } 5603 5604 /// [CompositeMode](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-32-paintcomposite) enumeration 5605 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] 5606 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 5607 #[repr(u8)] 5608 #[allow(clippy::manual_non_exhaustive)] 5609 pub enum CompositeMode { 5610 Clear = 0, 5611 Src = 1, 5612 Dest = 2, 5613 #[default] 5614 SrcOver = 3, 5615 DestOver = 4, 5616 SrcIn = 5, 5617 DestIn = 6, 5618 SrcOut = 7, 5619 DestOut = 8, 5620 SrcAtop = 9, 5621 DestAtop = 10, 5622 Xor = 11, 5623 Plus = 12, 5624 Screen = 13, 5625 Overlay = 14, 5626 Darken = 15, 5627 Lighten = 16, 5628 ColorDodge = 17, 5629 ColorBurn = 18, 5630 HardLight = 19, 5631 SoftLight = 20, 5632 Difference = 21, 5633 Exclusion = 22, 5634 Multiply = 23, 5635 HslHue = 24, 5636 HslSaturation = 25, 5637 HslColor = 26, 5638 HslLuminosity = 27, 5639 #[doc(hidden)] 5640 /// If font data is malformed we will map unknown values to this variant 5641 Unknown, 5642 } 5643 5644 impl CompositeMode { 5645 /// Create from a raw scalar. 5646 /// 5647 /// This will never fail; unknown values will be mapped to the `Unknown` variant new(raw: u8) -> Self5648 pub fn new(raw: u8) -> Self { 5649 match raw { 5650 0 => Self::Clear, 5651 1 => Self::Src, 5652 2 => Self::Dest, 5653 3 => Self::SrcOver, 5654 4 => Self::DestOver, 5655 5 => Self::SrcIn, 5656 6 => Self::DestIn, 5657 7 => Self::SrcOut, 5658 8 => Self::DestOut, 5659 9 => Self::SrcAtop, 5660 10 => Self::DestAtop, 5661 11 => Self::Xor, 5662 12 => Self::Plus, 5663 13 => Self::Screen, 5664 14 => Self::Overlay, 5665 15 => Self::Darken, 5666 16 => Self::Lighten, 5667 17 => Self::ColorDodge, 5668 18 => Self::ColorBurn, 5669 19 => Self::HardLight, 5670 20 => Self::SoftLight, 5671 21 => Self::Difference, 5672 22 => Self::Exclusion, 5673 23 => Self::Multiply, 5674 24 => Self::HslHue, 5675 25 => Self::HslSaturation, 5676 26 => Self::HslColor, 5677 27 => Self::HslLuminosity, 5678 _ => Self::Unknown, 5679 } 5680 } 5681 } 5682 5683 impl font_types::Scalar for CompositeMode { 5684 type Raw = <u8 as font_types::Scalar>::Raw; to_raw(self) -> Self::Raw5685 fn to_raw(self) -> Self::Raw { 5686 (self as u8).to_raw() 5687 } from_raw(raw: Self::Raw) -> Self5688 fn from_raw(raw: Self::Raw) -> Self { 5689 let t = <u8>::from_raw(raw); 5690 Self::new(t) 5691 } 5692 } 5693 5694 #[cfg(feature = "traversal")] 5695 impl<'a> From<CompositeMode> for FieldType<'a> { from(src: CompositeMode) -> FieldType<'a>5696 fn from(src: CompositeMode) -> FieldType<'a> { 5697 (src as u8).into() 5698 } 5699 } 5700