| // THIS FILE IS AUTOGENERATED. |
| // Any changes to this file will be overwritten. |
| // For more information about how codegen works, see font-codegen/README.md |
| |
| #[allow(unused_imports)] |
| use crate::codegen_prelude::*; |
| |
| /// [COLR (Color)](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#colr-header) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct ColrMarker { |
| base_glyph_list_offset_byte_start: Option<usize>, |
| layer_list_offset_byte_start: Option<usize>, |
| clip_list_offset_byte_start: Option<usize>, |
| var_index_map_offset_byte_start: Option<usize>, |
| item_variation_store_offset_byte_start: Option<usize>, |
| } |
| |
| impl ColrMarker { |
| pub fn version_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u16::RAW_BYTE_LEN |
| } |
| |
| pub fn num_base_glyph_records_byte_range(&self) -> Range<usize> { |
| let start = self.version_byte_range().end; |
| start..start + u16::RAW_BYTE_LEN |
| } |
| |
| pub fn base_glyph_records_offset_byte_range(&self) -> Range<usize> { |
| let start = self.num_base_glyph_records_byte_range().end; |
| start..start + Offset32::RAW_BYTE_LEN |
| } |
| |
| pub fn layer_records_offset_byte_range(&self) -> Range<usize> { |
| let start = self.base_glyph_records_offset_byte_range().end; |
| start..start + Offset32::RAW_BYTE_LEN |
| } |
| |
| pub fn num_layer_records_byte_range(&self) -> Range<usize> { |
| let start = self.layer_records_offset_byte_range().end; |
| start..start + u16::RAW_BYTE_LEN |
| } |
| |
| pub fn base_glyph_list_offset_byte_range(&self) -> Option<Range<usize>> { |
| let start = self.base_glyph_list_offset_byte_start?; |
| Some(start..start + Offset32::RAW_BYTE_LEN) |
| } |
| |
| pub fn layer_list_offset_byte_range(&self) -> Option<Range<usize>> { |
| let start = self.layer_list_offset_byte_start?; |
| Some(start..start + Offset32::RAW_BYTE_LEN) |
| } |
| |
| pub fn clip_list_offset_byte_range(&self) -> Option<Range<usize>> { |
| let start = self.clip_list_offset_byte_start?; |
| Some(start..start + Offset32::RAW_BYTE_LEN) |
| } |
| |
| pub fn var_index_map_offset_byte_range(&self) -> Option<Range<usize>> { |
| let start = self.var_index_map_offset_byte_start?; |
| Some(start..start + Offset32::RAW_BYTE_LEN) |
| } |
| |
| pub fn item_variation_store_offset_byte_range(&self) -> Option<Range<usize>> { |
| let start = self.item_variation_store_offset_byte_start?; |
| Some(start..start + Offset32::RAW_BYTE_LEN) |
| } |
| } |
| |
| impl MinByteRange for ColrMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.num_layer_records_byte_range().end |
| } |
| } |
| |
| impl TopLevelTable for Colr<'_> { |
| /// `COLR` |
| const TAG: Tag = Tag::new(b"COLR"); |
| } |
| |
| impl<'a> FontRead<'a> for Colr<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| let version: u16 = cursor.read()?; |
| cursor.advance::<u16>(); |
| cursor.advance::<Offset32>(); |
| cursor.advance::<Offset32>(); |
| cursor.advance::<u16>(); |
| let base_glyph_list_offset_byte_start = version |
| .compatible(1u16) |
| .then(|| cursor.position()) |
| .transpose()?; |
| version |
| .compatible(1u16) |
| .then(|| cursor.advance::<Offset32>()); |
| let layer_list_offset_byte_start = version |
| .compatible(1u16) |
| .then(|| cursor.position()) |
| .transpose()?; |
| version |
| .compatible(1u16) |
| .then(|| cursor.advance::<Offset32>()); |
| let clip_list_offset_byte_start = version |
| .compatible(1u16) |
| .then(|| cursor.position()) |
| .transpose()?; |
| version |
| .compatible(1u16) |
| .then(|| cursor.advance::<Offset32>()); |
| let var_index_map_offset_byte_start = version |
| .compatible(1u16) |
| .then(|| cursor.position()) |
| .transpose()?; |
| version |
| .compatible(1u16) |
| .then(|| cursor.advance::<Offset32>()); |
| let item_variation_store_offset_byte_start = version |
| .compatible(1u16) |
| .then(|| cursor.position()) |
| .transpose()?; |
| version |
| .compatible(1u16) |
| .then(|| cursor.advance::<Offset32>()); |
| cursor.finish(ColrMarker { |
| base_glyph_list_offset_byte_start, |
| layer_list_offset_byte_start, |
| clip_list_offset_byte_start, |
| var_index_map_offset_byte_start, |
| item_variation_store_offset_byte_start, |
| }) |
| } |
| } |
| |
| /// [COLR (Color)](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#colr-header) table |
| pub type Colr<'a> = TableRef<'a, ColrMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> Colr<'a> { |
| /// Table version number - set to 0 or 1. |
| pub fn version(&self) -> u16 { |
| let range = self.shape.version_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Number of BaseGlyph records; may be 0 in a version 1 table. |
| pub fn num_base_glyph_records(&self) -> u16 { |
| let range = self.shape.num_base_glyph_records_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to baseGlyphRecords array (may be NULL). |
| pub fn base_glyph_records_offset(&self) -> Nullable<Offset32> { |
| let range = self.shape.base_glyph_records_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`base_glyph_records_offset`][Self::base_glyph_records_offset]. |
| pub fn base_glyph_records(&self) -> Option<Result<&'a [BaseGlyph], ReadError>> { |
| let data = self.data; |
| let args = self.num_base_glyph_records(); |
| self.base_glyph_records_offset() |
| .resolve_with_args(data, &args) |
| } |
| |
| /// Offset to layerRecords array (may be NULL). |
| pub fn layer_records_offset(&self) -> Nullable<Offset32> { |
| let range = self.shape.layer_records_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`layer_records_offset`][Self::layer_records_offset]. |
| pub fn layer_records(&self) -> Option<Result<&'a [Layer], ReadError>> { |
| let data = self.data; |
| let args = self.num_layer_records(); |
| self.layer_records_offset().resolve_with_args(data, &args) |
| } |
| |
| /// Number of Layer records; may be 0 in a version 1 table. |
| pub fn num_layer_records(&self) -> u16 { |
| let range = self.shape.num_layer_records_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to BaseGlyphList table. |
| pub fn base_glyph_list_offset(&self) -> Option<Nullable<Offset32>> { |
| let range = self.shape.base_glyph_list_offset_byte_range()?; |
| Some(self.data.read_at(range.start).unwrap()) |
| } |
| |
| /// Attempt to resolve [`base_glyph_list_offset`][Self::base_glyph_list_offset]. |
| pub fn base_glyph_list(&self) -> Option<Result<BaseGlyphList<'a>, ReadError>> { |
| let data = self.data; |
| self.base_glyph_list_offset().map(|x| x.resolve(data))? |
| } |
| |
| /// Offset to LayerList table (may be NULL). |
| pub fn layer_list_offset(&self) -> Option<Nullable<Offset32>> { |
| let range = self.shape.layer_list_offset_byte_range()?; |
| Some(self.data.read_at(range.start).unwrap()) |
| } |
| |
| /// Attempt to resolve [`layer_list_offset`][Self::layer_list_offset]. |
| pub fn layer_list(&self) -> Option<Result<LayerList<'a>, ReadError>> { |
| let data = self.data; |
| self.layer_list_offset().map(|x| x.resolve(data))? |
| } |
| |
| /// Offset to ClipList table (may be NULL). |
| pub fn clip_list_offset(&self) -> Option<Nullable<Offset32>> { |
| let range = self.shape.clip_list_offset_byte_range()?; |
| Some(self.data.read_at(range.start).unwrap()) |
| } |
| |
| /// Attempt to resolve [`clip_list_offset`][Self::clip_list_offset]. |
| pub fn clip_list(&self) -> Option<Result<ClipList<'a>, ReadError>> { |
| let data = self.data; |
| self.clip_list_offset().map(|x| x.resolve(data))? |
| } |
| |
| /// Offset to DeltaSetIndexMap table (may be NULL). |
| pub fn var_index_map_offset(&self) -> Option<Nullable<Offset32>> { |
| let range = self.shape.var_index_map_offset_byte_range()?; |
| Some(self.data.read_at(range.start).unwrap()) |
| } |
| |
| /// Attempt to resolve [`var_index_map_offset`][Self::var_index_map_offset]. |
| pub fn var_index_map(&self) -> Option<Result<DeltaSetIndexMap<'a>, ReadError>> { |
| let data = self.data; |
| self.var_index_map_offset().map(|x| x.resolve(data))? |
| } |
| |
| /// Offset to ItemVariationStore (may be NULL). |
| pub fn item_variation_store_offset(&self) -> Option<Nullable<Offset32>> { |
| let range = self.shape.item_variation_store_offset_byte_range()?; |
| Some(self.data.read_at(range.start).unwrap()) |
| } |
| |
| /// Attempt to resolve [`item_variation_store_offset`][Self::item_variation_store_offset]. |
| pub fn item_variation_store(&self) -> Option<Result<ItemVariationStore<'a>, ReadError>> { |
| let data = self.data; |
| self.item_variation_store_offset() |
| .map(|x| x.resolve(data))? |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for Colr<'a> { |
| fn type_name(&self) -> &str { |
| "Colr" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| let version = self.version(); |
| match idx { |
| 0usize => Some(Field::new("version", self.version())), |
| 1usize => Some(Field::new( |
| "num_base_glyph_records", |
| self.num_base_glyph_records(), |
| )), |
| 2usize => Some(Field::new( |
| "base_glyph_records_offset", |
| traversal::FieldType::offset_to_array_of_records( |
| self.base_glyph_records_offset(), |
| self.base_glyph_records(), |
| stringify!(BaseGlyph), |
| self.offset_data(), |
| ), |
| )), |
| 3usize => Some(Field::new( |
| "layer_records_offset", |
| traversal::FieldType::offset_to_array_of_records( |
| self.layer_records_offset(), |
| self.layer_records(), |
| stringify!(Layer), |
| self.offset_data(), |
| ), |
| )), |
| 4usize => Some(Field::new("num_layer_records", self.num_layer_records())), |
| 5usize if version.compatible(1u16) => Some(Field::new( |
| "base_glyph_list_offset", |
| FieldType::offset( |
| self.base_glyph_list_offset().unwrap(), |
| self.base_glyph_list(), |
| ), |
| )), |
| 6usize if version.compatible(1u16) => Some(Field::new( |
| "layer_list_offset", |
| FieldType::offset(self.layer_list_offset().unwrap(), self.layer_list()), |
| )), |
| 7usize if version.compatible(1u16) => Some(Field::new( |
| "clip_list_offset", |
| FieldType::offset(self.clip_list_offset().unwrap(), self.clip_list()), |
| )), |
| 8usize if version.compatible(1u16) => Some(Field::new( |
| "var_index_map_offset", |
| FieldType::offset(self.var_index_map_offset().unwrap(), self.var_index_map()), |
| )), |
| 9usize if version.compatible(1u16) => Some(Field::new( |
| "item_variation_store_offset", |
| FieldType::offset( |
| self.item_variation_store_offset().unwrap(), |
| self.item_variation_store(), |
| ), |
| )), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for Colr<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| /// [BaseGlyph](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyph-and-layer-records) record |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] |
| #[repr(C)] |
| #[repr(packed)] |
| pub struct BaseGlyph { |
| /// Glyph ID of the base glyph. |
| pub glyph_id: BigEndian<GlyphId16>, |
| /// Index (base 0) into the layerRecords array. |
| pub first_layer_index: BigEndian<u16>, |
| /// Number of color layers associated with this glyph. |
| pub num_layers: BigEndian<u16>, |
| } |
| |
| impl BaseGlyph { |
| /// Glyph ID of the base glyph. |
| pub fn glyph_id(&self) -> GlyphId16 { |
| self.glyph_id.get() |
| } |
| |
| /// Index (base 0) into the layerRecords array. |
| pub fn first_layer_index(&self) -> u16 { |
| self.first_layer_index.get() |
| } |
| |
| /// Number of color layers associated with this glyph. |
| pub fn num_layers(&self) -> u16 { |
| self.num_layers.get() |
| } |
| } |
| |
| impl FixedSize for BaseGlyph { |
| const RAW_BYTE_LEN: usize = GlyphId16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeRecord<'a> for BaseGlyph { |
| fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { |
| RecordResolver { |
| name: "BaseGlyph", |
| get_field: Box::new(move |idx, _data| match idx { |
| 0usize => Some(Field::new("glyph_id", self.glyph_id())), |
| 1usize => Some(Field::new("first_layer_index", self.first_layer_index())), |
| 2usize => Some(Field::new("num_layers", self.num_layers())), |
| _ => None, |
| }), |
| data, |
| } |
| } |
| } |
| |
| /// [Layer](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyph-and-layer-records) record |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] |
| #[repr(C)] |
| #[repr(packed)] |
| pub struct Layer { |
| /// Glyph ID of the glyph used for a given layer. |
| pub glyph_id: BigEndian<GlyphId16>, |
| /// Index (base 0) for a palette entry in the CPAL table. |
| pub palette_index: BigEndian<u16>, |
| } |
| |
| impl Layer { |
| /// Glyph ID of the glyph used for a given layer. |
| pub fn glyph_id(&self) -> GlyphId16 { |
| self.glyph_id.get() |
| } |
| |
| /// Index (base 0) for a palette entry in the CPAL table. |
| pub fn palette_index(&self) -> u16 { |
| self.palette_index.get() |
| } |
| } |
| |
| impl FixedSize for Layer { |
| const RAW_BYTE_LEN: usize = GlyphId16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeRecord<'a> for Layer { |
| fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { |
| RecordResolver { |
| name: "Layer", |
| get_field: Box::new(move |idx, _data| match idx { |
| 0usize => Some(Field::new("glyph_id", self.glyph_id())), |
| 1usize => Some(Field::new("palette_index", self.palette_index())), |
| _ => None, |
| }), |
| data, |
| } |
| } |
| } |
| |
| /// [BaseGlyphList](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct BaseGlyphListMarker { |
| base_glyph_paint_records_byte_len: usize, |
| } |
| |
| impl BaseGlyphListMarker { |
| pub fn num_base_glyph_paint_records_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| |
| pub fn base_glyph_paint_records_byte_range(&self) -> Range<usize> { |
| let start = self.num_base_glyph_paint_records_byte_range().end; |
| start..start + self.base_glyph_paint_records_byte_len |
| } |
| } |
| |
| impl MinByteRange for BaseGlyphListMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.base_glyph_paint_records_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for BaseGlyphList<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| let num_base_glyph_paint_records: u32 = cursor.read()?; |
| let base_glyph_paint_records_byte_len = (num_base_glyph_paint_records as usize) |
| .checked_mul(BaseGlyphPaint::RAW_BYTE_LEN) |
| .ok_or(ReadError::OutOfBounds)?; |
| cursor.advance_by(base_glyph_paint_records_byte_len); |
| cursor.finish(BaseGlyphListMarker { |
| base_glyph_paint_records_byte_len, |
| }) |
| } |
| } |
| |
| /// [BaseGlyphList](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table |
| pub type BaseGlyphList<'a> = TableRef<'a, BaseGlyphListMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> BaseGlyphList<'a> { |
| pub fn num_base_glyph_paint_records(&self) -> u32 { |
| let range = self.shape.num_base_glyph_paint_records_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| pub fn base_glyph_paint_records(&self) -> &'a [BaseGlyphPaint] { |
| let range = self.shape.base_glyph_paint_records_byte_range(); |
| self.data.read_array(range).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for BaseGlyphList<'a> { |
| fn type_name(&self) -> &str { |
| "BaseGlyphList" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new( |
| "num_base_glyph_paint_records", |
| self.num_base_glyph_paint_records(), |
| )), |
| 1usize => Some(Field::new( |
| "base_glyph_paint_records", |
| traversal::FieldType::array_of_records( |
| stringify!(BaseGlyphPaint), |
| self.base_glyph_paint_records(), |
| self.offset_data(), |
| ), |
| )), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for BaseGlyphList<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| /// [BaseGlyphPaint](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record |
| #[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)] |
| #[repr(C)] |
| #[repr(packed)] |
| pub struct BaseGlyphPaint { |
| /// Glyph ID of the base glyph. |
| pub glyph_id: BigEndian<GlyphId16>, |
| /// Offset to a Paint table, from the beginning of the [`BaseGlyphList`] table. |
| pub paint_offset: BigEndian<Offset32>, |
| } |
| |
| impl BaseGlyphPaint { |
| /// Glyph ID of the base glyph. |
| pub fn glyph_id(&self) -> GlyphId16 { |
| self.glyph_id.get() |
| } |
| |
| /// Offset to a Paint table, from the beginning of the [`BaseGlyphList`] table. |
| pub fn paint_offset(&self) -> Offset32 { |
| self.paint_offset.get() |
| } |
| |
| /// Offset to a Paint table, from the beginning of the [`BaseGlyphList`] table. |
| /// |
| /// The `data` argument should be retrieved from the parent table |
| /// By calling its `offset_data` method. |
| pub fn paint<'a>(&self, data: FontData<'a>) -> Result<Paint<'a>, ReadError> { |
| self.paint_offset().resolve(data) |
| } |
| } |
| |
| impl FixedSize for BaseGlyphPaint { |
| const RAW_BYTE_LEN: usize = GlyphId16::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN; |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeRecord<'a> for BaseGlyphPaint { |
| fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { |
| RecordResolver { |
| name: "BaseGlyphPaint", |
| get_field: Box::new(move |idx, _data| match idx { |
| 0usize => Some(Field::new("glyph_id", self.glyph_id())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint(_data)), |
| )), |
| _ => None, |
| }), |
| data, |
| } |
| } |
| } |
| |
| /// [LayerList](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct LayerListMarker { |
| paint_offsets_byte_len: usize, |
| } |
| |
| impl LayerListMarker { |
| pub fn num_layers_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offsets_byte_range(&self) -> Range<usize> { |
| let start = self.num_layers_byte_range().end; |
| start..start + self.paint_offsets_byte_len |
| } |
| } |
| |
| impl MinByteRange for LayerListMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.paint_offsets_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for LayerList<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| let num_layers: u32 = cursor.read()?; |
| let paint_offsets_byte_len = (num_layers as usize) |
| .checked_mul(Offset32::RAW_BYTE_LEN) |
| .ok_or(ReadError::OutOfBounds)?; |
| cursor.advance_by(paint_offsets_byte_len); |
| cursor.finish(LayerListMarker { |
| paint_offsets_byte_len, |
| }) |
| } |
| } |
| |
| /// [LayerList](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table |
| pub type LayerList<'a> = TableRef<'a, LayerListMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> LayerList<'a> { |
| pub fn num_layers(&self) -> u32 { |
| let range = self.shape.num_layers_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offsets to Paint tables. |
| pub fn paint_offsets(&self) -> &'a [BigEndian<Offset32>] { |
| let range = self.shape.paint_offsets_byte_range(); |
| self.data.read_array(range).unwrap() |
| } |
| |
| /// A dynamically resolving wrapper for [`paint_offsets`][Self::paint_offsets]. |
| pub fn paints(&self) -> ArrayOfOffsets<'a, Paint<'a>, Offset32> { |
| let data = self.data; |
| let offsets = self.paint_offsets(); |
| ArrayOfOffsets::new(offsets, data, ()) |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for LayerList<'a> { |
| fn type_name(&self) -> &str { |
| "LayerList" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("num_layers", self.num_layers())), |
| 1usize => Some({ |
| let data = self.data; |
| Field::new( |
| "paint_offsets", |
| FieldType::array_of_offsets( |
| better_type_name::<Paint>(), |
| self.paint_offsets(), |
| move |off| { |
| let target = off.get().resolve::<Paint>(data); |
| FieldType::offset(off.get(), target) |
| }, |
| ), |
| ) |
| }), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for LayerList<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| /// [ClipList](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct ClipListMarker { |
| clips_byte_len: usize, |
| } |
| |
| impl ClipListMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn num_clips_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| |
| pub fn clips_byte_range(&self) -> Range<usize> { |
| let start = self.num_clips_byte_range().end; |
| start..start + self.clips_byte_len |
| } |
| } |
| |
| impl MinByteRange for ClipListMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.clips_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for ClipList<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| let num_clips: u32 = cursor.read()?; |
| let clips_byte_len = (num_clips as usize) |
| .checked_mul(Clip::RAW_BYTE_LEN) |
| .ok_or(ReadError::OutOfBounds)?; |
| cursor.advance_by(clips_byte_len); |
| cursor.finish(ClipListMarker { clips_byte_len }) |
| } |
| } |
| |
| /// [ClipList](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table |
| pub type ClipList<'a> = TableRef<'a, ClipListMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> ClipList<'a> { |
| /// Set to 1. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Number of Clip records. |
| pub fn num_clips(&self) -> u32 { |
| let range = self.shape.num_clips_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Clip records. Sorted by startGlyphID. |
| pub fn clips(&self) -> &'a [Clip] { |
| let range = self.shape.clips_byte_range(); |
| self.data.read_array(range).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for ClipList<'a> { |
| fn type_name(&self) -> &str { |
| "ClipList" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new("num_clips", self.num_clips())), |
| 2usize => Some(Field::new( |
| "clips", |
| traversal::FieldType::array_of_records( |
| stringify!(Clip), |
| self.clips(), |
| self.offset_data(), |
| ), |
| )), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for ClipList<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| /// [Clip](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record |
| #[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)] |
| #[repr(C)] |
| #[repr(packed)] |
| pub struct Clip { |
| /// First glyph ID in the range. |
| pub start_glyph_id: BigEndian<GlyphId16>, |
| /// Last glyph ID in the range. |
| pub end_glyph_id: BigEndian<GlyphId16>, |
| /// Offset to a ClipBox table, from the beginning of the [`ClipList`] table. |
| pub clip_box_offset: BigEndian<Offset24>, |
| } |
| |
| impl Clip { |
| /// First glyph ID in the range. |
| pub fn start_glyph_id(&self) -> GlyphId16 { |
| self.start_glyph_id.get() |
| } |
| |
| /// Last glyph ID in the range. |
| pub fn end_glyph_id(&self) -> GlyphId16 { |
| self.end_glyph_id.get() |
| } |
| |
| /// Offset to a ClipBox table, from the beginning of the [`ClipList`] table. |
| pub fn clip_box_offset(&self) -> Offset24 { |
| self.clip_box_offset.get() |
| } |
| |
| /// Offset to a ClipBox table, from the beginning of the [`ClipList`] table. |
| /// |
| /// The `data` argument should be retrieved from the parent table |
| /// By calling its `offset_data` method. |
| pub fn clip_box<'a>(&self, data: FontData<'a>) -> Result<ClipBox<'a>, ReadError> { |
| self.clip_box_offset().resolve(data) |
| } |
| } |
| |
| impl FixedSize for Clip { |
| const RAW_BYTE_LEN: usize = |
| GlyphId16::RAW_BYTE_LEN + GlyphId16::RAW_BYTE_LEN + Offset24::RAW_BYTE_LEN; |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeRecord<'a> for Clip { |
| fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { |
| RecordResolver { |
| name: "Clip", |
| get_field: Box::new(move |idx, _data| match idx { |
| 0usize => Some(Field::new("start_glyph_id", self.start_glyph_id())), |
| 1usize => Some(Field::new("end_glyph_id", self.end_glyph_id())), |
| 2usize => Some(Field::new( |
| "clip_box_offset", |
| FieldType::offset(self.clip_box_offset(), self.clip_box(_data)), |
| )), |
| _ => None, |
| }), |
| data, |
| } |
| } |
| } |
| |
| /// [ClipBox](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table |
| #[derive(Clone)] |
| pub enum ClipBox<'a> { |
| Format1(ClipBoxFormat1<'a>), |
| Format2(ClipBoxFormat2<'a>), |
| } |
| |
| impl<'a> ClipBox<'a> { |
| ///Return the `FontData` used to resolve offsets for this table. |
| pub fn offset_data(&self) -> FontData<'a> { |
| match self { |
| Self::Format1(item) => item.offset_data(), |
| Self::Format2(item) => item.offset_data(), |
| } |
| } |
| |
| /// Set to 1. |
| pub fn format(&self) -> u8 { |
| match self { |
| Self::Format1(item) => item.format(), |
| Self::Format2(item) => item.format(), |
| } |
| } |
| |
| /// Minimum x of clip box. |
| pub fn x_min(&self) -> FWord { |
| match self { |
| Self::Format1(item) => item.x_min(), |
| Self::Format2(item) => item.x_min(), |
| } |
| } |
| |
| /// Minimum y of clip box. |
| pub fn y_min(&self) -> FWord { |
| match self { |
| Self::Format1(item) => item.y_min(), |
| Self::Format2(item) => item.y_min(), |
| } |
| } |
| |
| /// Maximum x of clip box. |
| pub fn x_max(&self) -> FWord { |
| match self { |
| Self::Format1(item) => item.x_max(), |
| Self::Format2(item) => item.x_max(), |
| } |
| } |
| |
| /// Maximum y of clip box. |
| pub fn y_max(&self) -> FWord { |
| match self { |
| Self::Format1(item) => item.y_max(), |
| Self::Format2(item) => item.y_max(), |
| } |
| } |
| } |
| |
| impl<'a> FontRead<'a> for ClipBox<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let format: u8 = data.read_at(0usize)?; |
| match format { |
| ClipBoxFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)), |
| ClipBoxFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)), |
| other => Err(ReadError::InvalidFormat(other.into())), |
| } |
| } |
| } |
| |
| impl MinByteRange for ClipBox<'_> { |
| fn min_byte_range(&self) -> Range<usize> { |
| match self { |
| Self::Format1(item) => item.min_byte_range(), |
| Self::Format2(item) => item.min_byte_range(), |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> ClipBox<'a> { |
| fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> { |
| match self { |
| Self::Format1(table) => table, |
| Self::Format2(table) => table, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl std::fmt::Debug for ClipBox<'_> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| self.dyn_inner().fmt(f) |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for ClipBox<'a> { |
| fn type_name(&self) -> &str { |
| self.dyn_inner().type_name() |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| self.dyn_inner().get_field(idx) |
| } |
| } |
| |
| impl Format<u8> for ClipBoxFormat1Marker { |
| const FORMAT: u8 = 1; |
| } |
| |
| /// [ClipBoxFormat1](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct ClipBoxFormat1Marker {} |
| |
| impl ClipBoxFormat1Marker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn x_min_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn y_min_byte_range(&self) -> Range<usize> { |
| let start = self.x_min_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn x_max_byte_range(&self) -> Range<usize> { |
| let start = self.y_min_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn y_max_byte_range(&self) -> Range<usize> { |
| let start = self.x_max_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for ClipBoxFormat1Marker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.y_max_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for ClipBoxFormat1<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.finish(ClipBoxFormat1Marker {}) |
| } |
| } |
| |
| /// [ClipBoxFormat1](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record |
| pub type ClipBoxFormat1<'a> = TableRef<'a, ClipBoxFormat1Marker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> ClipBoxFormat1<'a> { |
| /// Set to 1. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Minimum x of clip box. |
| pub fn x_min(&self) -> FWord { |
| let range = self.shape.x_min_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Minimum y of clip box. |
| pub fn y_min(&self) -> FWord { |
| let range = self.shape.y_min_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Maximum x of clip box. |
| pub fn x_max(&self) -> FWord { |
| let range = self.shape.x_max_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Maximum y of clip box. |
| pub fn y_max(&self) -> FWord { |
| let range = self.shape.y_max_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for ClipBoxFormat1<'a> { |
| fn type_name(&self) -> &str { |
| "ClipBoxFormat1" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new("x_min", self.x_min())), |
| 2usize => Some(Field::new("y_min", self.y_min())), |
| 3usize => Some(Field::new("x_max", self.x_max())), |
| 4usize => Some(Field::new("y_max", self.y_max())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for ClipBoxFormat1<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for ClipBoxFormat2Marker { |
| const FORMAT: u8 = 2; |
| } |
| |
| /// [ClipBoxFormat2](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct ClipBoxFormat2Marker {} |
| |
| impl ClipBoxFormat2Marker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn x_min_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn y_min_byte_range(&self) -> Range<usize> { |
| let start = self.x_min_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn x_max_byte_range(&self) -> Range<usize> { |
| let start = self.y_min_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn y_max_byte_range(&self) -> Range<usize> { |
| let start = self.x_max_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn var_index_base_byte_range(&self) -> Range<usize> { |
| let start = self.y_max_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for ClipBoxFormat2Marker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.var_index_base_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for ClipBoxFormat2<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<u32>(); |
| cursor.finish(ClipBoxFormat2Marker {}) |
| } |
| } |
| |
| /// [ClipBoxFormat2](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record |
| pub type ClipBoxFormat2<'a> = TableRef<'a, ClipBoxFormat2Marker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> ClipBoxFormat2<'a> { |
| /// Set to 2. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Minimum x of clip box. For variation, use varIndexBase + 0. |
| pub fn x_min(&self) -> FWord { |
| let range = self.shape.x_min_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Minimum y of clip box. For variation, use varIndexBase + 1. |
| pub fn y_min(&self) -> FWord { |
| let range = self.shape.y_min_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Maximum x of clip box. For variation, use varIndexBase + 2. |
| pub fn x_max(&self) -> FWord { |
| let range = self.shape.x_max_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Maximum y of clip box. For variation, use varIndexBase + 3. |
| pub fn y_max(&self) -> FWord { |
| let range = self.shape.y_max_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Base index into DeltaSetIndexMap. |
| pub fn var_index_base(&self) -> u32 { |
| let range = self.shape.var_index_base_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for ClipBoxFormat2<'a> { |
| fn type_name(&self) -> &str { |
| "ClipBoxFormat2" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new("x_min", self.x_min())), |
| 2usize => Some(Field::new("y_min", self.y_min())), |
| 3usize => Some(Field::new("x_max", self.x_max())), |
| 4usize => Some(Field::new("y_max", self.y_max())), |
| 5usize => Some(Field::new("var_index_base", self.var_index_base())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for ClipBoxFormat2<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| /// [ColorIndex](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) record |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] |
| #[repr(C)] |
| #[repr(packed)] |
| pub struct ColorIndex { |
| /// Index for a CPAL palette entry. |
| pub palette_index: BigEndian<u16>, |
| /// Alpha value. |
| pub alpha: BigEndian<F2Dot14>, |
| } |
| |
| impl ColorIndex { |
| /// Index for a CPAL palette entry. |
| pub fn palette_index(&self) -> u16 { |
| self.palette_index.get() |
| } |
| |
| /// Alpha value. |
| pub fn alpha(&self) -> F2Dot14 { |
| self.alpha.get() |
| } |
| } |
| |
| impl FixedSize for ColorIndex { |
| const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN; |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeRecord<'a> for ColorIndex { |
| fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { |
| RecordResolver { |
| name: "ColorIndex", |
| get_field: Box::new(move |idx, _data| match idx { |
| 0usize => Some(Field::new("palette_index", self.palette_index())), |
| 1usize => Some(Field::new("alpha", self.alpha())), |
| _ => None, |
| }), |
| data, |
| } |
| } |
| } |
| |
| /// [VarColorIndex](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) record |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] |
| #[repr(C)] |
| #[repr(packed)] |
| pub struct VarColorIndex { |
| /// Index for a CPAL palette entry. |
| pub palette_index: BigEndian<u16>, |
| /// Alpha value. For variation, use varIndexBase + 0. |
| pub alpha: BigEndian<F2Dot14>, |
| /// Base index into DeltaSetIndexMap. |
| pub var_index_base: BigEndian<u32>, |
| } |
| |
| impl VarColorIndex { |
| /// Index for a CPAL palette entry. |
| pub fn palette_index(&self) -> u16 { |
| self.palette_index.get() |
| } |
| |
| /// Alpha value. For variation, use varIndexBase + 0. |
| pub fn alpha(&self) -> F2Dot14 { |
| self.alpha.get() |
| } |
| |
| /// Base index into DeltaSetIndexMap. |
| pub fn var_index_base(&self) -> u32 { |
| self.var_index_base.get() |
| } |
| } |
| |
| impl FixedSize for VarColorIndex { |
| const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN + u32::RAW_BYTE_LEN; |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeRecord<'a> for VarColorIndex { |
| fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { |
| RecordResolver { |
| name: "VarColorIndex", |
| get_field: Box::new(move |idx, _data| match idx { |
| 0usize => Some(Field::new("palette_index", self.palette_index())), |
| 1usize => Some(Field::new("alpha", self.alpha())), |
| 2usize => Some(Field::new("var_index_base", self.var_index_base())), |
| _ => None, |
| }), |
| data, |
| } |
| } |
| } |
| |
| /// [ColorStop](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) record |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] |
| #[repr(C)] |
| #[repr(packed)] |
| pub struct ColorStop { |
| /// Position on a color line. |
| pub stop_offset: BigEndian<F2Dot14>, |
| /// Index for a CPAL palette entry. |
| pub palette_index: BigEndian<u16>, |
| /// Alpha value. |
| pub alpha: BigEndian<F2Dot14>, |
| } |
| |
| impl ColorStop { |
| /// Position on a color line. |
| pub fn stop_offset(&self) -> F2Dot14 { |
| self.stop_offset.get() |
| } |
| |
| /// Index for a CPAL palette entry. |
| pub fn palette_index(&self) -> u16 { |
| self.palette_index.get() |
| } |
| |
| /// Alpha value. |
| pub fn alpha(&self) -> F2Dot14 { |
| self.alpha.get() |
| } |
| } |
| |
| impl FixedSize for ColorStop { |
| const RAW_BYTE_LEN: usize = F2Dot14::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN; |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeRecord<'a> for ColorStop { |
| fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { |
| RecordResolver { |
| name: "ColorStop", |
| get_field: Box::new(move |idx, _data| match idx { |
| 0usize => Some(Field::new("stop_offset", self.stop_offset())), |
| 1usize => Some(Field::new("palette_index", self.palette_index())), |
| 2usize => Some(Field::new("alpha", self.alpha())), |
| _ => None, |
| }), |
| data, |
| } |
| } |
| } |
| |
| /// [VarColorStop](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) record |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] |
| #[repr(C)] |
| #[repr(packed)] |
| pub struct VarColorStop { |
| /// Position on a color line. For variation, use varIndexBase + 0. |
| pub stop_offset: BigEndian<F2Dot14>, |
| /// Index for a CPAL palette entry. |
| pub palette_index: BigEndian<u16>, |
| /// Alpha value. For variation, use varIndexBase + 1. |
| pub alpha: BigEndian<F2Dot14>, |
| /// Base index into DeltaSetIndexMap. |
| pub var_index_base: BigEndian<u32>, |
| } |
| |
| impl VarColorStop { |
| /// Position on a color line. For variation, use varIndexBase + 0. |
| pub fn stop_offset(&self) -> F2Dot14 { |
| self.stop_offset.get() |
| } |
| |
| /// Index for a CPAL palette entry. |
| pub fn palette_index(&self) -> u16 { |
| self.palette_index.get() |
| } |
| |
| /// Alpha value. For variation, use varIndexBase + 1. |
| pub fn alpha(&self) -> F2Dot14 { |
| self.alpha.get() |
| } |
| |
| /// Base index into DeltaSetIndexMap. |
| pub fn var_index_base(&self) -> u32 { |
| self.var_index_base.get() |
| } |
| } |
| |
| impl FixedSize for VarColorStop { |
| const RAW_BYTE_LEN: usize = |
| F2Dot14::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN + u32::RAW_BYTE_LEN; |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeRecord<'a> for VarColorStop { |
| fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { |
| RecordResolver { |
| name: "VarColorStop", |
| get_field: Box::new(move |idx, _data| match idx { |
| 0usize => Some(Field::new("stop_offset", self.stop_offset())), |
| 1usize => Some(Field::new("palette_index", self.palette_index())), |
| 2usize => Some(Field::new("alpha", self.alpha())), |
| 3usize => Some(Field::new("var_index_base", self.var_index_base())), |
| _ => None, |
| }), |
| data, |
| } |
| } |
| } |
| |
| /// [ColorLine](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct ColorLineMarker { |
| color_stops_byte_len: usize, |
| } |
| |
| impl ColorLineMarker { |
| pub fn extend_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + Extend::RAW_BYTE_LEN |
| } |
| |
| pub fn num_stops_byte_range(&self) -> Range<usize> { |
| let start = self.extend_byte_range().end; |
| start..start + u16::RAW_BYTE_LEN |
| } |
| |
| pub fn color_stops_byte_range(&self) -> Range<usize> { |
| let start = self.num_stops_byte_range().end; |
| start..start + self.color_stops_byte_len |
| } |
| } |
| |
| impl MinByteRange for ColorLineMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.color_stops_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for ColorLine<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<Extend>(); |
| let num_stops: u16 = cursor.read()?; |
| let color_stops_byte_len = (num_stops as usize) |
| .checked_mul(ColorStop::RAW_BYTE_LEN) |
| .ok_or(ReadError::OutOfBounds)?; |
| cursor.advance_by(color_stops_byte_len); |
| cursor.finish(ColorLineMarker { |
| color_stops_byte_len, |
| }) |
| } |
| } |
| |
| /// [ColorLine](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) table |
| pub type ColorLine<'a> = TableRef<'a, ColorLineMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> ColorLine<'a> { |
| /// An Extend enum value. |
| pub fn extend(&self) -> Extend { |
| let range = self.shape.extend_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Number of ColorStop records. |
| pub fn num_stops(&self) -> u16 { |
| let range = self.shape.num_stops_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| pub fn color_stops(&self) -> &'a [ColorStop] { |
| let range = self.shape.color_stops_byte_range(); |
| self.data.read_array(range).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for ColorLine<'a> { |
| fn type_name(&self) -> &str { |
| "ColorLine" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("extend", self.extend())), |
| 1usize => Some(Field::new("num_stops", self.num_stops())), |
| 2usize => Some(Field::new( |
| "color_stops", |
| traversal::FieldType::array_of_records( |
| stringify!(ColorStop), |
| self.color_stops(), |
| self.offset_data(), |
| ), |
| )), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for ColorLine<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| /// [VarColorLine](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct VarColorLineMarker { |
| color_stops_byte_len: usize, |
| } |
| |
| impl VarColorLineMarker { |
| pub fn extend_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + Extend::RAW_BYTE_LEN |
| } |
| |
| pub fn num_stops_byte_range(&self) -> Range<usize> { |
| let start = self.extend_byte_range().end; |
| start..start + u16::RAW_BYTE_LEN |
| } |
| |
| pub fn color_stops_byte_range(&self) -> Range<usize> { |
| let start = self.num_stops_byte_range().end; |
| start..start + self.color_stops_byte_len |
| } |
| } |
| |
| impl MinByteRange for VarColorLineMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.color_stops_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for VarColorLine<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<Extend>(); |
| let num_stops: u16 = cursor.read()?; |
| let color_stops_byte_len = (num_stops as usize) |
| .checked_mul(VarColorStop::RAW_BYTE_LEN) |
| .ok_or(ReadError::OutOfBounds)?; |
| cursor.advance_by(color_stops_byte_len); |
| cursor.finish(VarColorLineMarker { |
| color_stops_byte_len, |
| }) |
| } |
| } |
| |
| /// [VarColorLine](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) table |
| pub type VarColorLine<'a> = TableRef<'a, VarColorLineMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> VarColorLine<'a> { |
| /// An Extend enum value. |
| pub fn extend(&self) -> Extend { |
| let range = self.shape.extend_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Number of ColorStop records. |
| pub fn num_stops(&self) -> u16 { |
| let range = self.shape.num_stops_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Allows for variations. |
| pub fn color_stops(&self) -> &'a [VarColorStop] { |
| let range = self.shape.color_stops_byte_range(); |
| self.data.read_array(range).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for VarColorLine<'a> { |
| fn type_name(&self) -> &str { |
| "VarColorLine" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("extend", self.extend())), |
| 1usize => Some(Field::new("num_stops", self.num_stops())), |
| 2usize => Some(Field::new( |
| "color_stops", |
| traversal::FieldType::array_of_records( |
| stringify!(VarColorStop), |
| self.color_stops(), |
| self.offset_data(), |
| ), |
| )), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for VarColorLine<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| /// [Extend](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) enumeration |
| #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| #[repr(u8)] |
| #[allow(clippy::manual_non_exhaustive)] |
| pub enum Extend { |
| #[default] |
| Pad = 0, |
| Repeat = 1, |
| Reflect = 2, |
| #[doc(hidden)] |
| /// If font data is malformed we will map unknown values to this variant |
| Unknown, |
| } |
| |
| impl Extend { |
| /// Create from a raw scalar. |
| /// |
| /// This will never fail; unknown values will be mapped to the `Unknown` variant |
| pub fn new(raw: u8) -> Self { |
| match raw { |
| 0 => Self::Pad, |
| 1 => Self::Repeat, |
| 2 => Self::Reflect, |
| _ => Self::Unknown, |
| } |
| } |
| } |
| |
| impl font_types::Scalar for Extend { |
| type Raw = <u8 as font_types::Scalar>::Raw; |
| fn to_raw(self) -> Self::Raw { |
| (self as u8).to_raw() |
| } |
| fn from_raw(raw: Self::Raw) -> Self { |
| let t = <u8>::from_raw(raw); |
| Self::new(t) |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> From<Extend> for FieldType<'a> { |
| fn from(src: Extend) -> FieldType<'a> { |
| (src as u8).into() |
| } |
| } |
| |
| /// [Paint](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#paint-tables) tables |
| #[derive(Clone)] |
| pub enum Paint<'a> { |
| ColrLayers(PaintColrLayers<'a>), |
| Solid(PaintSolid<'a>), |
| VarSolid(PaintVarSolid<'a>), |
| LinearGradient(PaintLinearGradient<'a>), |
| VarLinearGradient(PaintVarLinearGradient<'a>), |
| RadialGradient(PaintRadialGradient<'a>), |
| VarRadialGradient(PaintVarRadialGradient<'a>), |
| SweepGradient(PaintSweepGradient<'a>), |
| VarSweepGradient(PaintVarSweepGradient<'a>), |
| Glyph(PaintGlyph<'a>), |
| ColrGlyph(PaintColrGlyph<'a>), |
| Transform(PaintTransform<'a>), |
| VarTransform(PaintVarTransform<'a>), |
| Translate(PaintTranslate<'a>), |
| VarTranslate(PaintVarTranslate<'a>), |
| Scale(PaintScale<'a>), |
| VarScale(PaintVarScale<'a>), |
| ScaleAroundCenter(PaintScaleAroundCenter<'a>), |
| VarScaleAroundCenter(PaintVarScaleAroundCenter<'a>), |
| ScaleUniform(PaintScaleUniform<'a>), |
| VarScaleUniform(PaintVarScaleUniform<'a>), |
| ScaleUniformAroundCenter(PaintScaleUniformAroundCenter<'a>), |
| VarScaleUniformAroundCenter(PaintVarScaleUniformAroundCenter<'a>), |
| Rotate(PaintRotate<'a>), |
| VarRotate(PaintVarRotate<'a>), |
| RotateAroundCenter(PaintRotateAroundCenter<'a>), |
| VarRotateAroundCenter(PaintVarRotateAroundCenter<'a>), |
| Skew(PaintSkew<'a>), |
| VarSkew(PaintVarSkew<'a>), |
| SkewAroundCenter(PaintSkewAroundCenter<'a>), |
| VarSkewAroundCenter(PaintVarSkewAroundCenter<'a>), |
| Composite(PaintComposite<'a>), |
| } |
| |
| impl<'a> Paint<'a> { |
| ///Return the `FontData` used to resolve offsets for this table. |
| pub fn offset_data(&self) -> FontData<'a> { |
| match self { |
| Self::ColrLayers(item) => item.offset_data(), |
| Self::Solid(item) => item.offset_data(), |
| Self::VarSolid(item) => item.offset_data(), |
| Self::LinearGradient(item) => item.offset_data(), |
| Self::VarLinearGradient(item) => item.offset_data(), |
| Self::RadialGradient(item) => item.offset_data(), |
| Self::VarRadialGradient(item) => item.offset_data(), |
| Self::SweepGradient(item) => item.offset_data(), |
| Self::VarSweepGradient(item) => item.offset_data(), |
| Self::Glyph(item) => item.offset_data(), |
| Self::ColrGlyph(item) => item.offset_data(), |
| Self::Transform(item) => item.offset_data(), |
| Self::VarTransform(item) => item.offset_data(), |
| Self::Translate(item) => item.offset_data(), |
| Self::VarTranslate(item) => item.offset_data(), |
| Self::Scale(item) => item.offset_data(), |
| Self::VarScale(item) => item.offset_data(), |
| Self::ScaleAroundCenter(item) => item.offset_data(), |
| Self::VarScaleAroundCenter(item) => item.offset_data(), |
| Self::ScaleUniform(item) => item.offset_data(), |
| Self::VarScaleUniform(item) => item.offset_data(), |
| Self::ScaleUniformAroundCenter(item) => item.offset_data(), |
| Self::VarScaleUniformAroundCenter(item) => item.offset_data(), |
| Self::Rotate(item) => item.offset_data(), |
| Self::VarRotate(item) => item.offset_data(), |
| Self::RotateAroundCenter(item) => item.offset_data(), |
| Self::VarRotateAroundCenter(item) => item.offset_data(), |
| Self::Skew(item) => item.offset_data(), |
| Self::VarSkew(item) => item.offset_data(), |
| Self::SkewAroundCenter(item) => item.offset_data(), |
| Self::VarSkewAroundCenter(item) => item.offset_data(), |
| Self::Composite(item) => item.offset_data(), |
| } |
| } |
| |
| /// Set to 1. |
| pub fn format(&self) -> u8 { |
| match self { |
| Self::ColrLayers(item) => item.format(), |
| Self::Solid(item) => item.format(), |
| Self::VarSolid(item) => item.format(), |
| Self::LinearGradient(item) => item.format(), |
| Self::VarLinearGradient(item) => item.format(), |
| Self::RadialGradient(item) => item.format(), |
| Self::VarRadialGradient(item) => item.format(), |
| Self::SweepGradient(item) => item.format(), |
| Self::VarSweepGradient(item) => item.format(), |
| Self::Glyph(item) => item.format(), |
| Self::ColrGlyph(item) => item.format(), |
| Self::Transform(item) => item.format(), |
| Self::VarTransform(item) => item.format(), |
| Self::Translate(item) => item.format(), |
| Self::VarTranslate(item) => item.format(), |
| Self::Scale(item) => item.format(), |
| Self::VarScale(item) => item.format(), |
| Self::ScaleAroundCenter(item) => item.format(), |
| Self::VarScaleAroundCenter(item) => item.format(), |
| Self::ScaleUniform(item) => item.format(), |
| Self::VarScaleUniform(item) => item.format(), |
| Self::ScaleUniformAroundCenter(item) => item.format(), |
| Self::VarScaleUniformAroundCenter(item) => item.format(), |
| Self::Rotate(item) => item.format(), |
| Self::VarRotate(item) => item.format(), |
| Self::RotateAroundCenter(item) => item.format(), |
| Self::VarRotateAroundCenter(item) => item.format(), |
| Self::Skew(item) => item.format(), |
| Self::VarSkew(item) => item.format(), |
| Self::SkewAroundCenter(item) => item.format(), |
| Self::VarSkewAroundCenter(item) => item.format(), |
| Self::Composite(item) => item.format(), |
| } |
| } |
| } |
| |
| impl<'a> FontRead<'a> for Paint<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let format: u8 = data.read_at(0usize)?; |
| match format { |
| PaintColrLayersMarker::FORMAT => Ok(Self::ColrLayers(FontRead::read(data)?)), |
| PaintSolidMarker::FORMAT => Ok(Self::Solid(FontRead::read(data)?)), |
| PaintVarSolidMarker::FORMAT => Ok(Self::VarSolid(FontRead::read(data)?)), |
| PaintLinearGradientMarker::FORMAT => Ok(Self::LinearGradient(FontRead::read(data)?)), |
| PaintVarLinearGradientMarker::FORMAT => { |
| Ok(Self::VarLinearGradient(FontRead::read(data)?)) |
| } |
| PaintRadialGradientMarker::FORMAT => Ok(Self::RadialGradient(FontRead::read(data)?)), |
| PaintVarRadialGradientMarker::FORMAT => { |
| Ok(Self::VarRadialGradient(FontRead::read(data)?)) |
| } |
| PaintSweepGradientMarker::FORMAT => Ok(Self::SweepGradient(FontRead::read(data)?)), |
| PaintVarSweepGradientMarker::FORMAT => { |
| Ok(Self::VarSweepGradient(FontRead::read(data)?)) |
| } |
| PaintGlyphMarker::FORMAT => Ok(Self::Glyph(FontRead::read(data)?)), |
| PaintColrGlyphMarker::FORMAT => Ok(Self::ColrGlyph(FontRead::read(data)?)), |
| PaintTransformMarker::FORMAT => Ok(Self::Transform(FontRead::read(data)?)), |
| PaintVarTransformMarker::FORMAT => Ok(Self::VarTransform(FontRead::read(data)?)), |
| PaintTranslateMarker::FORMAT => Ok(Self::Translate(FontRead::read(data)?)), |
| PaintVarTranslateMarker::FORMAT => Ok(Self::VarTranslate(FontRead::read(data)?)), |
| PaintScaleMarker::FORMAT => Ok(Self::Scale(FontRead::read(data)?)), |
| PaintVarScaleMarker::FORMAT => Ok(Self::VarScale(FontRead::read(data)?)), |
| PaintScaleAroundCenterMarker::FORMAT => { |
| Ok(Self::ScaleAroundCenter(FontRead::read(data)?)) |
| } |
| PaintVarScaleAroundCenterMarker::FORMAT => { |
| Ok(Self::VarScaleAroundCenter(FontRead::read(data)?)) |
| } |
| PaintScaleUniformMarker::FORMAT => Ok(Self::ScaleUniform(FontRead::read(data)?)), |
| PaintVarScaleUniformMarker::FORMAT => Ok(Self::VarScaleUniform(FontRead::read(data)?)), |
| PaintScaleUniformAroundCenterMarker::FORMAT => { |
| Ok(Self::ScaleUniformAroundCenter(FontRead::read(data)?)) |
| } |
| PaintVarScaleUniformAroundCenterMarker::FORMAT => { |
| Ok(Self::VarScaleUniformAroundCenter(FontRead::read(data)?)) |
| } |
| PaintRotateMarker::FORMAT => Ok(Self::Rotate(FontRead::read(data)?)), |
| PaintVarRotateMarker::FORMAT => Ok(Self::VarRotate(FontRead::read(data)?)), |
| PaintRotateAroundCenterMarker::FORMAT => { |
| Ok(Self::RotateAroundCenter(FontRead::read(data)?)) |
| } |
| PaintVarRotateAroundCenterMarker::FORMAT => { |
| Ok(Self::VarRotateAroundCenter(FontRead::read(data)?)) |
| } |
| PaintSkewMarker::FORMAT => Ok(Self::Skew(FontRead::read(data)?)), |
| PaintVarSkewMarker::FORMAT => Ok(Self::VarSkew(FontRead::read(data)?)), |
| PaintSkewAroundCenterMarker::FORMAT => { |
| Ok(Self::SkewAroundCenter(FontRead::read(data)?)) |
| } |
| PaintVarSkewAroundCenterMarker::FORMAT => { |
| Ok(Self::VarSkewAroundCenter(FontRead::read(data)?)) |
| } |
| PaintCompositeMarker::FORMAT => Ok(Self::Composite(FontRead::read(data)?)), |
| other => Err(ReadError::InvalidFormat(other.into())), |
| } |
| } |
| } |
| |
| impl MinByteRange for Paint<'_> { |
| fn min_byte_range(&self) -> Range<usize> { |
| match self { |
| Self::ColrLayers(item) => item.min_byte_range(), |
| Self::Solid(item) => item.min_byte_range(), |
| Self::VarSolid(item) => item.min_byte_range(), |
| Self::LinearGradient(item) => item.min_byte_range(), |
| Self::VarLinearGradient(item) => item.min_byte_range(), |
| Self::RadialGradient(item) => item.min_byte_range(), |
| Self::VarRadialGradient(item) => item.min_byte_range(), |
| Self::SweepGradient(item) => item.min_byte_range(), |
| Self::VarSweepGradient(item) => item.min_byte_range(), |
| Self::Glyph(item) => item.min_byte_range(), |
| Self::ColrGlyph(item) => item.min_byte_range(), |
| Self::Transform(item) => item.min_byte_range(), |
| Self::VarTransform(item) => item.min_byte_range(), |
| Self::Translate(item) => item.min_byte_range(), |
| Self::VarTranslate(item) => item.min_byte_range(), |
| Self::Scale(item) => item.min_byte_range(), |
| Self::VarScale(item) => item.min_byte_range(), |
| Self::ScaleAroundCenter(item) => item.min_byte_range(), |
| Self::VarScaleAroundCenter(item) => item.min_byte_range(), |
| Self::ScaleUniform(item) => item.min_byte_range(), |
| Self::VarScaleUniform(item) => item.min_byte_range(), |
| Self::ScaleUniformAroundCenter(item) => item.min_byte_range(), |
| Self::VarScaleUniformAroundCenter(item) => item.min_byte_range(), |
| Self::Rotate(item) => item.min_byte_range(), |
| Self::VarRotate(item) => item.min_byte_range(), |
| Self::RotateAroundCenter(item) => item.min_byte_range(), |
| Self::VarRotateAroundCenter(item) => item.min_byte_range(), |
| Self::Skew(item) => item.min_byte_range(), |
| Self::VarSkew(item) => item.min_byte_range(), |
| Self::SkewAroundCenter(item) => item.min_byte_range(), |
| Self::VarSkewAroundCenter(item) => item.min_byte_range(), |
| Self::Composite(item) => item.min_byte_range(), |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> Paint<'a> { |
| fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> { |
| match self { |
| Self::ColrLayers(table) => table, |
| Self::Solid(table) => table, |
| Self::VarSolid(table) => table, |
| Self::LinearGradient(table) => table, |
| Self::VarLinearGradient(table) => table, |
| Self::RadialGradient(table) => table, |
| Self::VarRadialGradient(table) => table, |
| Self::SweepGradient(table) => table, |
| Self::VarSweepGradient(table) => table, |
| Self::Glyph(table) => table, |
| Self::ColrGlyph(table) => table, |
| Self::Transform(table) => table, |
| Self::VarTransform(table) => table, |
| Self::Translate(table) => table, |
| Self::VarTranslate(table) => table, |
| Self::Scale(table) => table, |
| Self::VarScale(table) => table, |
| Self::ScaleAroundCenter(table) => table, |
| Self::VarScaleAroundCenter(table) => table, |
| Self::ScaleUniform(table) => table, |
| Self::VarScaleUniform(table) => table, |
| Self::ScaleUniformAroundCenter(table) => table, |
| Self::VarScaleUniformAroundCenter(table) => table, |
| Self::Rotate(table) => table, |
| Self::VarRotate(table) => table, |
| Self::RotateAroundCenter(table) => table, |
| Self::VarRotateAroundCenter(table) => table, |
| Self::Skew(table) => table, |
| Self::VarSkew(table) => table, |
| Self::SkewAroundCenter(table) => table, |
| Self::VarSkewAroundCenter(table) => table, |
| Self::Composite(table) => table, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl std::fmt::Debug for Paint<'_> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| self.dyn_inner().fmt(f) |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for Paint<'a> { |
| fn type_name(&self) -> &str { |
| self.dyn_inner().type_name() |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| self.dyn_inner().get_field(idx) |
| } |
| } |
| |
| impl Format<u8> for PaintColrLayersMarker { |
| const FORMAT: u8 = 1; |
| } |
| |
| /// [PaintColrLayers](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-1-paintcolrlayers) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintColrLayersMarker {} |
| |
| impl PaintColrLayersMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn num_layers_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn first_layer_index_byte_range(&self) -> Range<usize> { |
| let start = self.num_layers_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintColrLayersMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.first_layer_index_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintColrLayers<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<u8>(); |
| cursor.advance::<u32>(); |
| cursor.finish(PaintColrLayersMarker {}) |
| } |
| } |
| |
| /// [PaintColrLayers](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-1-paintcolrlayers) table |
| pub type PaintColrLayers<'a> = TableRef<'a, PaintColrLayersMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintColrLayers<'a> { |
| /// Set to 1. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Number of offsets to paint tables to read from LayerList. |
| pub fn num_layers(&self) -> u8 { |
| let range = self.shape.num_layers_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Index (base 0) into the LayerList. |
| pub fn first_layer_index(&self) -> u32 { |
| let range = self.shape.first_layer_index_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintColrLayers<'a> { |
| fn type_name(&self) -> &str { |
| "PaintColrLayers" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new("num_layers", self.num_layers())), |
| 2usize => Some(Field::new("first_layer_index", self.first_layer_index())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintColrLayers<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintSolidMarker { |
| const FORMAT: u8 = 2; |
| } |
| |
| /// [PaintSolid](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-2-and-3-paintsolid-paintvarsolid) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintSolidMarker {} |
| |
| impl PaintSolidMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn palette_index_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + u16::RAW_BYTE_LEN |
| } |
| |
| pub fn alpha_byte_range(&self) -> Range<usize> { |
| let start = self.palette_index_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintSolidMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.alpha_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintSolid<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<u16>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.finish(PaintSolidMarker {}) |
| } |
| } |
| |
| /// [PaintSolid](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-2-and-3-paintsolid-paintvarsolid) table |
| pub type PaintSolid<'a> = TableRef<'a, PaintSolidMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintSolid<'a> { |
| /// Set to 2. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Index for a CPAL palette entry. |
| pub fn palette_index(&self) -> u16 { |
| let range = self.shape.palette_index_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Alpha value. |
| pub fn alpha(&self) -> F2Dot14 { |
| let range = self.shape.alpha_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintSolid<'a> { |
| fn type_name(&self) -> &str { |
| "PaintSolid" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new("palette_index", self.palette_index())), |
| 2usize => Some(Field::new("alpha", self.alpha())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintSolid<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintVarSolidMarker { |
| const FORMAT: u8 = 3; |
| } |
| |
| /// [PaintVarSolid](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-2-and-3-paintsolid-paintvarsolid) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintVarSolidMarker {} |
| |
| impl PaintVarSolidMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn palette_index_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + u16::RAW_BYTE_LEN |
| } |
| |
| pub fn alpha_byte_range(&self) -> Range<usize> { |
| let start = self.palette_index_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn var_index_base_byte_range(&self) -> Range<usize> { |
| let start = self.alpha_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintVarSolidMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.var_index_base_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintVarSolid<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<u16>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<u32>(); |
| cursor.finish(PaintVarSolidMarker {}) |
| } |
| } |
| |
| /// [PaintVarSolid](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-2-and-3-paintsolid-paintvarsolid) table |
| pub type PaintVarSolid<'a> = TableRef<'a, PaintVarSolidMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintVarSolid<'a> { |
| /// Set to 3. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Index for a CPAL palette entry. |
| pub fn palette_index(&self) -> u16 { |
| let range = self.shape.palette_index_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Alpha value. For variation, use varIndexBase + 0. |
| pub fn alpha(&self) -> F2Dot14 { |
| let range = self.shape.alpha_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Base index into DeltaSetIndexMap. |
| pub fn var_index_base(&self) -> u32 { |
| let range = self.shape.var_index_base_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintVarSolid<'a> { |
| fn type_name(&self) -> &str { |
| "PaintVarSolid" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new("palette_index", self.palette_index())), |
| 2usize => Some(Field::new("alpha", self.alpha())), |
| 3usize => Some(Field::new("var_index_base", self.var_index_base())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintVarSolid<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintLinearGradientMarker { |
| const FORMAT: u8 = 4; |
| } |
| |
| /// [PaintLinearGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-4-and-5-paintlineargradient-paintvarlineargradient) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintLinearGradientMarker {} |
| |
| impl PaintLinearGradientMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn color_line_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn x0_byte_range(&self) -> Range<usize> { |
| let start = self.color_line_offset_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn y0_byte_range(&self) -> Range<usize> { |
| let start = self.x0_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn x1_byte_range(&self) -> Range<usize> { |
| let start = self.y0_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn y1_byte_range(&self) -> Range<usize> { |
| let start = self.x1_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn x2_byte_range(&self) -> Range<usize> { |
| let start = self.y1_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn y2_byte_range(&self) -> Range<usize> { |
| let start = self.x2_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintLinearGradientMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.y2_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintLinearGradient<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.finish(PaintLinearGradientMarker {}) |
| } |
| } |
| |
| /// [PaintLinearGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-4-and-5-paintlineargradient-paintvarlineargradient) table |
| pub type PaintLinearGradient<'a> = TableRef<'a, PaintLinearGradientMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintLinearGradient<'a> { |
| /// Set to 4. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to ColorLine table. |
| pub fn color_line_offset(&self) -> Offset24 { |
| let range = self.shape.color_line_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`color_line_offset`][Self::color_line_offset]. |
| pub fn color_line(&self) -> Result<ColorLine<'a>, ReadError> { |
| let data = self.data; |
| self.color_line_offset().resolve(data) |
| } |
| |
| /// Start point (p₀) x coordinate. |
| pub fn x0(&self) -> FWord { |
| let range = self.shape.x0_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Start point (p₀) y coordinate. |
| pub fn y0(&self) -> FWord { |
| let range = self.shape.y0_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// End point (p₁) x coordinate. |
| pub fn x1(&self) -> FWord { |
| let range = self.shape.x1_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// End point (p₁) y coordinate. |
| pub fn y1(&self) -> FWord { |
| let range = self.shape.y1_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Rotation point (p₂) x coordinate. |
| pub fn x2(&self) -> FWord { |
| let range = self.shape.x2_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Rotation point (p₂) y coordinate. |
| pub fn y2(&self) -> FWord { |
| let range = self.shape.y2_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintLinearGradient<'a> { |
| fn type_name(&self) -> &str { |
| "PaintLinearGradient" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "color_line_offset", |
| FieldType::offset(self.color_line_offset(), self.color_line()), |
| )), |
| 2usize => Some(Field::new("x0", self.x0())), |
| 3usize => Some(Field::new("y0", self.y0())), |
| 4usize => Some(Field::new("x1", self.x1())), |
| 5usize => Some(Field::new("y1", self.y1())), |
| 6usize => Some(Field::new("x2", self.x2())), |
| 7usize => Some(Field::new("y2", self.y2())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintLinearGradient<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintVarLinearGradientMarker { |
| const FORMAT: u8 = 5; |
| } |
| |
| /// [PaintVarLinearGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-4-and-5-paintlineargradient-paintvarlineargradient) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintVarLinearGradientMarker {} |
| |
| impl PaintVarLinearGradientMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn color_line_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn x0_byte_range(&self) -> Range<usize> { |
| let start = self.color_line_offset_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn y0_byte_range(&self) -> Range<usize> { |
| let start = self.x0_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn x1_byte_range(&self) -> Range<usize> { |
| let start = self.y0_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn y1_byte_range(&self) -> Range<usize> { |
| let start = self.x1_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn x2_byte_range(&self) -> Range<usize> { |
| let start = self.y1_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn y2_byte_range(&self) -> Range<usize> { |
| let start = self.x2_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn var_index_base_byte_range(&self) -> Range<usize> { |
| let start = self.y2_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintVarLinearGradientMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.var_index_base_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintVarLinearGradient<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<u32>(); |
| cursor.finish(PaintVarLinearGradientMarker {}) |
| } |
| } |
| |
| /// [PaintVarLinearGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-4-and-5-paintlineargradient-paintvarlineargradient) table |
| pub type PaintVarLinearGradient<'a> = TableRef<'a, PaintVarLinearGradientMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintVarLinearGradient<'a> { |
| /// Set to 5. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to VarColorLine table. |
| pub fn color_line_offset(&self) -> Offset24 { |
| let range = self.shape.color_line_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`color_line_offset`][Self::color_line_offset]. |
| pub fn color_line(&self) -> Result<VarColorLine<'a>, ReadError> { |
| let data = self.data; |
| self.color_line_offset().resolve(data) |
| } |
| |
| /// Start point (p₀) x coordinate. For variation, use |
| /// varIndexBase + 0. |
| pub fn x0(&self) -> FWord { |
| let range = self.shape.x0_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Start point (p₀) y coordinate. For variation, use |
| /// varIndexBase + 1. |
| pub fn y0(&self) -> FWord { |
| let range = self.shape.y0_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// End point (p₁) x coordinate. For variation, use varIndexBase |
| /// + 2. |
| pub fn x1(&self) -> FWord { |
| let range = self.shape.x1_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// End point (p₁) y coordinate. For variation, use varIndexBase |
| /// + 3. |
| pub fn y1(&self) -> FWord { |
| let range = self.shape.y1_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Rotation point (p₂) x coordinate. For variation, use |
| /// varIndexBase + 4. |
| pub fn x2(&self) -> FWord { |
| let range = self.shape.x2_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Rotation point (p₂) y coordinate. For variation, use |
| /// varIndexBase + 5. |
| pub fn y2(&self) -> FWord { |
| let range = self.shape.y2_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Base index into DeltaSetIndexMap. |
| pub fn var_index_base(&self) -> u32 { |
| let range = self.shape.var_index_base_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintVarLinearGradient<'a> { |
| fn type_name(&self) -> &str { |
| "PaintVarLinearGradient" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "color_line_offset", |
| FieldType::offset(self.color_line_offset(), self.color_line()), |
| )), |
| 2usize => Some(Field::new("x0", self.x0())), |
| 3usize => Some(Field::new("y0", self.y0())), |
| 4usize => Some(Field::new("x1", self.x1())), |
| 5usize => Some(Field::new("y1", self.y1())), |
| 6usize => Some(Field::new("x2", self.x2())), |
| 7usize => Some(Field::new("y2", self.y2())), |
| 8usize => Some(Field::new("var_index_base", self.var_index_base())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintVarLinearGradient<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintRadialGradientMarker { |
| const FORMAT: u8 = 6; |
| } |
| |
| /// [PaintRadialGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-6-and-7-paintradialgradient-paintvarradialgradient) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintRadialGradientMarker {} |
| |
| impl PaintRadialGradientMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn color_line_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn x0_byte_range(&self) -> Range<usize> { |
| let start = self.color_line_offset_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn y0_byte_range(&self) -> Range<usize> { |
| let start = self.x0_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn radius0_byte_range(&self) -> Range<usize> { |
| let start = self.y0_byte_range().end; |
| start..start + UfWord::RAW_BYTE_LEN |
| } |
| |
| pub fn x1_byte_range(&self) -> Range<usize> { |
| let start = self.radius0_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn y1_byte_range(&self) -> Range<usize> { |
| let start = self.x1_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn radius1_byte_range(&self) -> Range<usize> { |
| let start = self.y1_byte_range().end; |
| start..start + UfWord::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintRadialGradientMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.radius1_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintRadialGradient<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<UfWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<UfWord>(); |
| cursor.finish(PaintRadialGradientMarker {}) |
| } |
| } |
| |
| /// [PaintRadialGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-6-and-7-paintradialgradient-paintvarradialgradient) table |
| pub type PaintRadialGradient<'a> = TableRef<'a, PaintRadialGradientMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintRadialGradient<'a> { |
| /// Set to 6. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to ColorLine table. |
| pub fn color_line_offset(&self) -> Offset24 { |
| let range = self.shape.color_line_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`color_line_offset`][Self::color_line_offset]. |
| pub fn color_line(&self) -> Result<ColorLine<'a>, ReadError> { |
| let data = self.data; |
| self.color_line_offset().resolve(data) |
| } |
| |
| /// Start circle center x coordinate. |
| pub fn x0(&self) -> FWord { |
| let range = self.shape.x0_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Start circle center y coordinate. |
| pub fn y0(&self) -> FWord { |
| let range = self.shape.y0_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Start circle radius. |
| pub fn radius0(&self) -> UfWord { |
| let range = self.shape.radius0_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// End circle center x coordinate. |
| pub fn x1(&self) -> FWord { |
| let range = self.shape.x1_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// End circle center y coordinate. |
| pub fn y1(&self) -> FWord { |
| let range = self.shape.y1_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// End circle radius. |
| pub fn radius1(&self) -> UfWord { |
| let range = self.shape.radius1_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintRadialGradient<'a> { |
| fn type_name(&self) -> &str { |
| "PaintRadialGradient" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "color_line_offset", |
| FieldType::offset(self.color_line_offset(), self.color_line()), |
| )), |
| 2usize => Some(Field::new("x0", self.x0())), |
| 3usize => Some(Field::new("y0", self.y0())), |
| 4usize => Some(Field::new("radius0", self.radius0())), |
| 5usize => Some(Field::new("x1", self.x1())), |
| 6usize => Some(Field::new("y1", self.y1())), |
| 7usize => Some(Field::new("radius1", self.radius1())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintRadialGradient<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintVarRadialGradientMarker { |
| const FORMAT: u8 = 7; |
| } |
| |
| /// [PaintVarRadialGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-6-and-7-paintradialgradient-paintvarradialgradient) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintVarRadialGradientMarker {} |
| |
| impl PaintVarRadialGradientMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn color_line_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn x0_byte_range(&self) -> Range<usize> { |
| let start = self.color_line_offset_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn y0_byte_range(&self) -> Range<usize> { |
| let start = self.x0_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn radius0_byte_range(&self) -> Range<usize> { |
| let start = self.y0_byte_range().end; |
| start..start + UfWord::RAW_BYTE_LEN |
| } |
| |
| pub fn x1_byte_range(&self) -> Range<usize> { |
| let start = self.radius0_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn y1_byte_range(&self) -> Range<usize> { |
| let start = self.x1_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn radius1_byte_range(&self) -> Range<usize> { |
| let start = self.y1_byte_range().end; |
| start..start + UfWord::RAW_BYTE_LEN |
| } |
| |
| pub fn var_index_base_byte_range(&self) -> Range<usize> { |
| let start = self.radius1_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintVarRadialGradientMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.var_index_base_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintVarRadialGradient<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<UfWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<UfWord>(); |
| cursor.advance::<u32>(); |
| cursor.finish(PaintVarRadialGradientMarker {}) |
| } |
| } |
| |
| /// [PaintVarRadialGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-6-and-7-paintradialgradient-paintvarradialgradient) table |
| pub type PaintVarRadialGradient<'a> = TableRef<'a, PaintVarRadialGradientMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintVarRadialGradient<'a> { |
| /// Set to 7. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to VarColorLine table. |
| pub fn color_line_offset(&self) -> Offset24 { |
| let range = self.shape.color_line_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`color_line_offset`][Self::color_line_offset]. |
| pub fn color_line(&self) -> Result<VarColorLine<'a>, ReadError> { |
| let data = self.data; |
| self.color_line_offset().resolve(data) |
| } |
| |
| /// Start circle center x coordinate. For variation, use |
| /// varIndexBase + 0. |
| pub fn x0(&self) -> FWord { |
| let range = self.shape.x0_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Start circle center y coordinate. For variation, use |
| /// varIndexBase + 1. |
| pub fn y0(&self) -> FWord { |
| let range = self.shape.y0_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Start circle radius. For variation, use varIndexBase + 2. |
| pub fn radius0(&self) -> UfWord { |
| let range = self.shape.radius0_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// End circle center x coordinate. For variation, use varIndexBase |
| /// + 3. |
| pub fn x1(&self) -> FWord { |
| let range = self.shape.x1_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// End circle center y coordinate. For variation, use varIndexBase |
| /// + 4. |
| pub fn y1(&self) -> FWord { |
| let range = self.shape.y1_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// End circle radius. For variation, use varIndexBase + 5. |
| pub fn radius1(&self) -> UfWord { |
| let range = self.shape.radius1_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Base index into DeltaSetIndexMap. |
| pub fn var_index_base(&self) -> u32 { |
| let range = self.shape.var_index_base_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintVarRadialGradient<'a> { |
| fn type_name(&self) -> &str { |
| "PaintVarRadialGradient" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "color_line_offset", |
| FieldType::offset(self.color_line_offset(), self.color_line()), |
| )), |
| 2usize => Some(Field::new("x0", self.x0())), |
| 3usize => Some(Field::new("y0", self.y0())), |
| 4usize => Some(Field::new("radius0", self.radius0())), |
| 5usize => Some(Field::new("x1", self.x1())), |
| 6usize => Some(Field::new("y1", self.y1())), |
| 7usize => Some(Field::new("radius1", self.radius1())), |
| 8usize => Some(Field::new("var_index_base", self.var_index_base())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintVarRadialGradient<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintSweepGradientMarker { |
| const FORMAT: u8 = 8; |
| } |
| |
| /// [PaintSweepGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-8-and-9-paintsweepgradient-paintvarsweepgradient) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintSweepGradientMarker {} |
| |
| impl PaintSweepGradientMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn color_line_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn center_x_byte_range(&self) -> Range<usize> { |
| let start = self.color_line_offset_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn center_y_byte_range(&self) -> Range<usize> { |
| let start = self.center_x_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn start_angle_byte_range(&self) -> Range<usize> { |
| let start = self.center_y_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn end_angle_byte_range(&self) -> Range<usize> { |
| let start = self.start_angle_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintSweepGradientMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.end_angle_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintSweepGradient<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.finish(PaintSweepGradientMarker {}) |
| } |
| } |
| |
| /// [PaintSweepGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-8-and-9-paintsweepgradient-paintvarsweepgradient) table |
| pub type PaintSweepGradient<'a> = TableRef<'a, PaintSweepGradientMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintSweepGradient<'a> { |
| /// Set to 8. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to ColorLine table. |
| pub fn color_line_offset(&self) -> Offset24 { |
| let range = self.shape.color_line_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`color_line_offset`][Self::color_line_offset]. |
| pub fn color_line(&self) -> Result<ColorLine<'a>, ReadError> { |
| let data = self.data; |
| self.color_line_offset().resolve(data) |
| } |
| |
| /// Center x coordinate. |
| pub fn center_x(&self) -> FWord { |
| let range = self.shape.center_x_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Center y coordinate. |
| pub fn center_y(&self) -> FWord { |
| let range = self.shape.center_y_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Start of the angular range of the gradient, 180° in |
| /// counter-clockwise degrees per 1.0 of value. |
| pub fn start_angle(&self) -> F2Dot14 { |
| let range = self.shape.start_angle_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// End of the angular range of the gradient, 180° in |
| /// counter-clockwise degrees per 1.0 of value. |
| pub fn end_angle(&self) -> F2Dot14 { |
| let range = self.shape.end_angle_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintSweepGradient<'a> { |
| fn type_name(&self) -> &str { |
| "PaintSweepGradient" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "color_line_offset", |
| FieldType::offset(self.color_line_offset(), self.color_line()), |
| )), |
| 2usize => Some(Field::new("center_x", self.center_x())), |
| 3usize => Some(Field::new("center_y", self.center_y())), |
| 4usize => Some(Field::new("start_angle", self.start_angle())), |
| 5usize => Some(Field::new("end_angle", self.end_angle())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintSweepGradient<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintVarSweepGradientMarker { |
| const FORMAT: u8 = 9; |
| } |
| |
| /// [PaintVarSweepGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-8-and-9-paintsweepgradient-paintvarsweepgradient) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintVarSweepGradientMarker {} |
| |
| impl PaintVarSweepGradientMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn color_line_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn center_x_byte_range(&self) -> Range<usize> { |
| let start = self.color_line_offset_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn center_y_byte_range(&self) -> Range<usize> { |
| let start = self.center_x_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn start_angle_byte_range(&self) -> Range<usize> { |
| let start = self.center_y_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn end_angle_byte_range(&self) -> Range<usize> { |
| let start = self.start_angle_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn var_index_base_byte_range(&self) -> Range<usize> { |
| let start = self.end_angle_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintVarSweepGradientMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.var_index_base_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintVarSweepGradient<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<u32>(); |
| cursor.finish(PaintVarSweepGradientMarker {}) |
| } |
| } |
| |
| /// [PaintVarSweepGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-8-and-9-paintsweepgradient-paintvarsweepgradient) table |
| pub type PaintVarSweepGradient<'a> = TableRef<'a, PaintVarSweepGradientMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintVarSweepGradient<'a> { |
| /// Set to 9. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to VarColorLine table. |
| pub fn color_line_offset(&self) -> Offset24 { |
| let range = self.shape.color_line_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`color_line_offset`][Self::color_line_offset]. |
| pub fn color_line(&self) -> Result<VarColorLine<'a>, ReadError> { |
| let data = self.data; |
| self.color_line_offset().resolve(data) |
| } |
| |
| /// Center x coordinate. For variation, use varIndexBase + 0. |
| pub fn center_x(&self) -> FWord { |
| let range = self.shape.center_x_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Center y coordinate. For variation, use varIndexBase + 1. |
| pub fn center_y(&self) -> FWord { |
| let range = self.shape.center_y_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Start of the angular range of the gradient, 180° in |
| /// counter-clockwise degrees per 1.0 of value. For variation, use |
| /// varIndexBase + 2. |
| pub fn start_angle(&self) -> F2Dot14 { |
| let range = self.shape.start_angle_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// End of the angular range of the gradient, 180° in |
| /// counter-clockwise degrees per 1.0 of value. For variation, use |
| /// varIndexBase + 3. |
| pub fn end_angle(&self) -> F2Dot14 { |
| let range = self.shape.end_angle_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Base index into DeltaSetIndexMap. |
| pub fn var_index_base(&self) -> u32 { |
| let range = self.shape.var_index_base_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintVarSweepGradient<'a> { |
| fn type_name(&self) -> &str { |
| "PaintVarSweepGradient" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "color_line_offset", |
| FieldType::offset(self.color_line_offset(), self.color_line()), |
| )), |
| 2usize => Some(Field::new("center_x", self.center_x())), |
| 3usize => Some(Field::new("center_y", self.center_y())), |
| 4usize => Some(Field::new("start_angle", self.start_angle())), |
| 5usize => Some(Field::new("end_angle", self.end_angle())), |
| 6usize => Some(Field::new("var_index_base", self.var_index_base())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintVarSweepGradient<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintGlyphMarker { |
| const FORMAT: u8 = 10; |
| } |
| |
| /// [PaintGlyph](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-10-paintglyph) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintGlyphMarker {} |
| |
| impl PaintGlyphMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn glyph_id_byte_range(&self) -> Range<usize> { |
| let start = self.paint_offset_byte_range().end; |
| start..start + GlyphId16::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintGlyphMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.glyph_id_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintGlyph<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<GlyphId16>(); |
| cursor.finish(PaintGlyphMarker {}) |
| } |
| } |
| |
| /// [PaintGlyph](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-10-paintglyph) table |
| pub type PaintGlyph<'a> = TableRef<'a, PaintGlyphMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintGlyph<'a> { |
| /// Set to 10. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a Paint table. |
| pub fn paint_offset(&self) -> Offset24 { |
| let range = self.shape.paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`paint_offset`][Self::paint_offset]. |
| pub fn paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.paint_offset().resolve(data) |
| } |
| |
| /// Glyph ID for the source outline. |
| pub fn glyph_id(&self) -> GlyphId16 { |
| let range = self.shape.glyph_id_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintGlyph<'a> { |
| fn type_name(&self) -> &str { |
| "PaintGlyph" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint()), |
| )), |
| 2usize => Some(Field::new("glyph_id", self.glyph_id())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintGlyph<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintColrGlyphMarker { |
| const FORMAT: u8 = 11; |
| } |
| |
| /// [PaintColrGlyph](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-11-paintcolrglyph) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintColrGlyphMarker {} |
| |
| impl PaintColrGlyphMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn glyph_id_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + GlyphId16::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintColrGlyphMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.glyph_id_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintColrGlyph<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<GlyphId16>(); |
| cursor.finish(PaintColrGlyphMarker {}) |
| } |
| } |
| |
| /// [PaintColrGlyph](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-11-paintcolrglyph) table |
| pub type PaintColrGlyph<'a> = TableRef<'a, PaintColrGlyphMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintColrGlyph<'a> { |
| /// Set to 11. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Glyph ID for a BaseGlyphList base glyph. |
| pub fn glyph_id(&self) -> GlyphId16 { |
| let range = self.shape.glyph_id_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintColrGlyph<'a> { |
| fn type_name(&self) -> &str { |
| "PaintColrGlyph" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new("glyph_id", self.glyph_id())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintColrGlyph<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintTransformMarker { |
| const FORMAT: u8 = 12; |
| } |
| |
| /// [PaintTransform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintTransformMarker {} |
| |
| impl PaintTransformMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn transform_offset_byte_range(&self) -> Range<usize> { |
| let start = self.paint_offset_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintTransformMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.transform_offset_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintTransform<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<Offset24>(); |
| cursor.finish(PaintTransformMarker {}) |
| } |
| } |
| |
| /// [PaintTransform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) table |
| pub type PaintTransform<'a> = TableRef<'a, PaintTransformMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintTransform<'a> { |
| /// Set to 12. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a Paint subtable. |
| pub fn paint_offset(&self) -> Offset24 { |
| let range = self.shape.paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`paint_offset`][Self::paint_offset]. |
| pub fn paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.paint_offset().resolve(data) |
| } |
| |
| /// Offset to an Affine2x3 table. |
| pub fn transform_offset(&self) -> Offset24 { |
| let range = self.shape.transform_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`transform_offset`][Self::transform_offset]. |
| pub fn transform(&self) -> Result<Affine2x3<'a>, ReadError> { |
| let data = self.data; |
| self.transform_offset().resolve(data) |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintTransform<'a> { |
| fn type_name(&self) -> &str { |
| "PaintTransform" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint()), |
| )), |
| 2usize => Some(Field::new( |
| "transform_offset", |
| FieldType::offset(self.transform_offset(), self.transform()), |
| )), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintTransform<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintVarTransformMarker { |
| const FORMAT: u8 = 13; |
| } |
| |
| /// [PaintVarTransform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintVarTransformMarker {} |
| |
| impl PaintVarTransformMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn transform_offset_byte_range(&self) -> Range<usize> { |
| let start = self.paint_offset_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintVarTransformMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.transform_offset_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintVarTransform<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<Offset24>(); |
| cursor.finish(PaintVarTransformMarker {}) |
| } |
| } |
| |
| /// [PaintVarTransform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) table |
| pub type PaintVarTransform<'a> = TableRef<'a, PaintVarTransformMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintVarTransform<'a> { |
| /// Set to 13. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a Paint subtable. |
| pub fn paint_offset(&self) -> Offset24 { |
| let range = self.shape.paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`paint_offset`][Self::paint_offset]. |
| pub fn paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.paint_offset().resolve(data) |
| } |
| |
| /// Offset to a VarAffine2x3 table. |
| pub fn transform_offset(&self) -> Offset24 { |
| let range = self.shape.transform_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`transform_offset`][Self::transform_offset]. |
| pub fn transform(&self) -> Result<VarAffine2x3<'a>, ReadError> { |
| let data = self.data; |
| self.transform_offset().resolve(data) |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintVarTransform<'a> { |
| fn type_name(&self) -> &str { |
| "PaintVarTransform" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint()), |
| )), |
| 2usize => Some(Field::new( |
| "transform_offset", |
| FieldType::offset(self.transform_offset(), self.transform()), |
| )), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintVarTransform<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| /// [Affine2x3](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) record |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct Affine2x3Marker {} |
| |
| impl Affine2x3Marker { |
| pub fn xx_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + Fixed::RAW_BYTE_LEN |
| } |
| |
| pub fn yx_byte_range(&self) -> Range<usize> { |
| let start = self.xx_byte_range().end; |
| start..start + Fixed::RAW_BYTE_LEN |
| } |
| |
| pub fn xy_byte_range(&self) -> Range<usize> { |
| let start = self.yx_byte_range().end; |
| start..start + Fixed::RAW_BYTE_LEN |
| } |
| |
| pub fn yy_byte_range(&self) -> Range<usize> { |
| let start = self.xy_byte_range().end; |
| start..start + Fixed::RAW_BYTE_LEN |
| } |
| |
| pub fn dx_byte_range(&self) -> Range<usize> { |
| let start = self.yy_byte_range().end; |
| start..start + Fixed::RAW_BYTE_LEN |
| } |
| |
| pub fn dy_byte_range(&self) -> Range<usize> { |
| let start = self.dx_byte_range().end; |
| start..start + Fixed::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for Affine2x3Marker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.dy_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for Affine2x3<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<Fixed>(); |
| cursor.advance::<Fixed>(); |
| cursor.advance::<Fixed>(); |
| cursor.advance::<Fixed>(); |
| cursor.advance::<Fixed>(); |
| cursor.advance::<Fixed>(); |
| cursor.finish(Affine2x3Marker {}) |
| } |
| } |
| |
| /// [Affine2x3](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) record |
| pub type Affine2x3<'a> = TableRef<'a, Affine2x3Marker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> Affine2x3<'a> { |
| /// x-component of transformed x-basis vector. |
| pub fn xx(&self) -> Fixed { |
| let range = self.shape.xx_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// y-component of transformed x-basis vector. |
| pub fn yx(&self) -> Fixed { |
| let range = self.shape.yx_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// x-component of transformed y-basis vector. |
| pub fn xy(&self) -> Fixed { |
| let range = self.shape.xy_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// y-component of transformed y-basis vector. |
| pub fn yy(&self) -> Fixed { |
| let range = self.shape.yy_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Translation in x direction. |
| pub fn dx(&self) -> Fixed { |
| let range = self.shape.dx_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Translation in y direction. |
| pub fn dy(&self) -> Fixed { |
| let range = self.shape.dy_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for Affine2x3<'a> { |
| fn type_name(&self) -> &str { |
| "Affine2x3" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("xx", self.xx())), |
| 1usize => Some(Field::new("yx", self.yx())), |
| 2usize => Some(Field::new("xy", self.xy())), |
| 3usize => Some(Field::new("yy", self.yy())), |
| 4usize => Some(Field::new("dx", self.dx())), |
| 5usize => Some(Field::new("dy", self.dy())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for Affine2x3<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| /// [VarAffine2x3](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) record |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct VarAffine2x3Marker {} |
| |
| impl VarAffine2x3Marker { |
| pub fn xx_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + Fixed::RAW_BYTE_LEN |
| } |
| |
| pub fn yx_byte_range(&self) -> Range<usize> { |
| let start = self.xx_byte_range().end; |
| start..start + Fixed::RAW_BYTE_LEN |
| } |
| |
| pub fn xy_byte_range(&self) -> Range<usize> { |
| let start = self.yx_byte_range().end; |
| start..start + Fixed::RAW_BYTE_LEN |
| } |
| |
| pub fn yy_byte_range(&self) -> Range<usize> { |
| let start = self.xy_byte_range().end; |
| start..start + Fixed::RAW_BYTE_LEN |
| } |
| |
| pub fn dx_byte_range(&self) -> Range<usize> { |
| let start = self.yy_byte_range().end; |
| start..start + Fixed::RAW_BYTE_LEN |
| } |
| |
| pub fn dy_byte_range(&self) -> Range<usize> { |
| let start = self.dx_byte_range().end; |
| start..start + Fixed::RAW_BYTE_LEN |
| } |
| |
| pub fn var_index_base_byte_range(&self) -> Range<usize> { |
| let start = self.dy_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for VarAffine2x3Marker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.var_index_base_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for VarAffine2x3<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<Fixed>(); |
| cursor.advance::<Fixed>(); |
| cursor.advance::<Fixed>(); |
| cursor.advance::<Fixed>(); |
| cursor.advance::<Fixed>(); |
| cursor.advance::<Fixed>(); |
| cursor.advance::<u32>(); |
| cursor.finish(VarAffine2x3Marker {}) |
| } |
| } |
| |
| /// [VarAffine2x3](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) record |
| pub type VarAffine2x3<'a> = TableRef<'a, VarAffine2x3Marker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> VarAffine2x3<'a> { |
| /// x-component of transformed x-basis vector. For variation, use |
| /// varIndexBase + 0. |
| pub fn xx(&self) -> Fixed { |
| let range = self.shape.xx_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// y-component of transformed x-basis vector. For variation, use |
| /// varIndexBase + 1. |
| pub fn yx(&self) -> Fixed { |
| let range = self.shape.yx_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// x-component of transformed y-basis vector. For variation, use |
| /// varIndexBase + 2. |
| pub fn xy(&self) -> Fixed { |
| let range = self.shape.xy_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// y-component of transformed y-basis vector. For variation, use |
| /// varIndexBase + 3. |
| pub fn yy(&self) -> Fixed { |
| let range = self.shape.yy_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Translation in x direction. For variation, use varIndexBase + 4. |
| pub fn dx(&self) -> Fixed { |
| let range = self.shape.dx_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Translation in y direction. For variation, use varIndexBase + 5. |
| pub fn dy(&self) -> Fixed { |
| let range = self.shape.dy_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Base index into DeltaSetIndexMap. |
| pub fn var_index_base(&self) -> u32 { |
| let range = self.shape.var_index_base_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for VarAffine2x3<'a> { |
| fn type_name(&self) -> &str { |
| "VarAffine2x3" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("xx", self.xx())), |
| 1usize => Some(Field::new("yx", self.yx())), |
| 2usize => Some(Field::new("xy", self.xy())), |
| 3usize => Some(Field::new("yy", self.yy())), |
| 4usize => Some(Field::new("dx", self.dx())), |
| 5usize => Some(Field::new("dy", self.dy())), |
| 6usize => Some(Field::new("var_index_base", self.var_index_base())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for VarAffine2x3<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintTranslateMarker { |
| const FORMAT: u8 = 14; |
| } |
| |
| /// [PaintTranslate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-14-and-15-painttranslate-paintvartranslate) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintTranslateMarker {} |
| |
| impl PaintTranslateMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn dx_byte_range(&self) -> Range<usize> { |
| let start = self.paint_offset_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn dy_byte_range(&self) -> Range<usize> { |
| let start = self.dx_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintTranslateMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.dy_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintTranslate<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.finish(PaintTranslateMarker {}) |
| } |
| } |
| |
| /// [PaintTranslate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-14-and-15-painttranslate-paintvartranslate) table |
| pub type PaintTranslate<'a> = TableRef<'a, PaintTranslateMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintTranslate<'a> { |
| /// Set to 14. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a Paint subtable. |
| pub fn paint_offset(&self) -> Offset24 { |
| let range = self.shape.paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`paint_offset`][Self::paint_offset]. |
| pub fn paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.paint_offset().resolve(data) |
| } |
| |
| /// Translation in x direction. |
| pub fn dx(&self) -> FWord { |
| let range = self.shape.dx_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Translation in y direction. |
| pub fn dy(&self) -> FWord { |
| let range = self.shape.dy_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintTranslate<'a> { |
| fn type_name(&self) -> &str { |
| "PaintTranslate" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint()), |
| )), |
| 2usize => Some(Field::new("dx", self.dx())), |
| 3usize => Some(Field::new("dy", self.dy())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintTranslate<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintVarTranslateMarker { |
| const FORMAT: u8 = 15; |
| } |
| |
| /// [PaintVarTranslate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-14-and-15-painttranslate-paintvartranslate) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintVarTranslateMarker {} |
| |
| impl PaintVarTranslateMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn dx_byte_range(&self) -> Range<usize> { |
| let start = self.paint_offset_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn dy_byte_range(&self) -> Range<usize> { |
| let start = self.dx_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn var_index_base_byte_range(&self) -> Range<usize> { |
| let start = self.dy_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintVarTranslateMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.var_index_base_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintVarTranslate<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<u32>(); |
| cursor.finish(PaintVarTranslateMarker {}) |
| } |
| } |
| |
| /// [PaintVarTranslate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-14-and-15-painttranslate-paintvartranslate) table |
| pub type PaintVarTranslate<'a> = TableRef<'a, PaintVarTranslateMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintVarTranslate<'a> { |
| /// Set to 15. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a Paint subtable. |
| pub fn paint_offset(&self) -> Offset24 { |
| let range = self.shape.paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`paint_offset`][Self::paint_offset]. |
| pub fn paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.paint_offset().resolve(data) |
| } |
| |
| /// Translation in x direction. For variation, use varIndexBase + 0. |
| pub fn dx(&self) -> FWord { |
| let range = self.shape.dx_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Translation in y direction. For variation, use varIndexBase + 1. |
| pub fn dy(&self) -> FWord { |
| let range = self.shape.dy_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Base index into DeltaSetIndexMap. |
| pub fn var_index_base(&self) -> u32 { |
| let range = self.shape.var_index_base_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintVarTranslate<'a> { |
| fn type_name(&self) -> &str { |
| "PaintVarTranslate" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint()), |
| )), |
| 2usize => Some(Field::new("dx", self.dx())), |
| 3usize => Some(Field::new("dy", self.dy())), |
| 4usize => Some(Field::new("var_index_base", self.var_index_base())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintVarTranslate<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintScaleMarker { |
| const FORMAT: u8 = 16; |
| } |
| |
| /// [PaintScale](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintScaleMarker {} |
| |
| impl PaintScaleMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn scale_x_byte_range(&self) -> Range<usize> { |
| let start = self.paint_offset_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn scale_y_byte_range(&self) -> Range<usize> { |
| let start = self.scale_x_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintScaleMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.scale_y_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintScale<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.finish(PaintScaleMarker {}) |
| } |
| } |
| |
| /// [PaintScale](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table |
| pub type PaintScale<'a> = TableRef<'a, PaintScaleMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintScale<'a> { |
| /// Set to 16. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a Paint subtable. |
| pub fn paint_offset(&self) -> Offset24 { |
| let range = self.shape.paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`paint_offset`][Self::paint_offset]. |
| pub fn paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.paint_offset().resolve(data) |
| } |
| |
| /// Scale factor in x direction. |
| pub fn scale_x(&self) -> F2Dot14 { |
| let range = self.shape.scale_x_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Scale factor in y direction. |
| pub fn scale_y(&self) -> F2Dot14 { |
| let range = self.shape.scale_y_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintScale<'a> { |
| fn type_name(&self) -> &str { |
| "PaintScale" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint()), |
| )), |
| 2usize => Some(Field::new("scale_x", self.scale_x())), |
| 3usize => Some(Field::new("scale_y", self.scale_y())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintScale<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintVarScaleMarker { |
| const FORMAT: u8 = 17; |
| } |
| |
| /// [PaintVarScale](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintVarScaleMarker {} |
| |
| impl PaintVarScaleMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn scale_x_byte_range(&self) -> Range<usize> { |
| let start = self.paint_offset_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn scale_y_byte_range(&self) -> Range<usize> { |
| let start = self.scale_x_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn var_index_base_byte_range(&self) -> Range<usize> { |
| let start = self.scale_y_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintVarScaleMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.var_index_base_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintVarScale<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<u32>(); |
| cursor.finish(PaintVarScaleMarker {}) |
| } |
| } |
| |
| /// [PaintVarScale](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table |
| pub type PaintVarScale<'a> = TableRef<'a, PaintVarScaleMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintVarScale<'a> { |
| /// Set to 17. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a Paint subtable. |
| pub fn paint_offset(&self) -> Offset24 { |
| let range = self.shape.paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`paint_offset`][Self::paint_offset]. |
| pub fn paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.paint_offset().resolve(data) |
| } |
| |
| /// Scale factor in x direction. For variation, use varIndexBase + |
| /// 0. |
| pub fn scale_x(&self) -> F2Dot14 { |
| let range = self.shape.scale_x_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Scale factor in y direction. For variation, use varIndexBase + |
| /// 1. |
| pub fn scale_y(&self) -> F2Dot14 { |
| let range = self.shape.scale_y_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Base index into DeltaSetIndexMap. |
| pub fn var_index_base(&self) -> u32 { |
| let range = self.shape.var_index_base_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintVarScale<'a> { |
| fn type_name(&self) -> &str { |
| "PaintVarScale" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint()), |
| )), |
| 2usize => Some(Field::new("scale_x", self.scale_x())), |
| 3usize => Some(Field::new("scale_y", self.scale_y())), |
| 4usize => Some(Field::new("var_index_base", self.var_index_base())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintVarScale<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintScaleAroundCenterMarker { |
| const FORMAT: u8 = 18; |
| } |
| |
| /// [PaintScaleAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintScaleAroundCenterMarker {} |
| |
| impl PaintScaleAroundCenterMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn scale_x_byte_range(&self) -> Range<usize> { |
| let start = self.paint_offset_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn scale_y_byte_range(&self) -> Range<usize> { |
| let start = self.scale_x_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn center_x_byte_range(&self) -> Range<usize> { |
| let start = self.scale_y_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn center_y_byte_range(&self) -> Range<usize> { |
| let start = self.center_x_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintScaleAroundCenterMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.center_y_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintScaleAroundCenter<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.finish(PaintScaleAroundCenterMarker {}) |
| } |
| } |
| |
| /// [PaintScaleAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table |
| pub type PaintScaleAroundCenter<'a> = TableRef<'a, PaintScaleAroundCenterMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintScaleAroundCenter<'a> { |
| /// Set to 18. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a Paint subtable. |
| pub fn paint_offset(&self) -> Offset24 { |
| let range = self.shape.paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`paint_offset`][Self::paint_offset]. |
| pub fn paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.paint_offset().resolve(data) |
| } |
| |
| /// Scale factor in x direction. |
| pub fn scale_x(&self) -> F2Dot14 { |
| let range = self.shape.scale_x_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Scale factor in y direction. |
| pub fn scale_y(&self) -> F2Dot14 { |
| let range = self.shape.scale_y_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// x coordinate for the center of scaling. |
| pub fn center_x(&self) -> FWord { |
| let range = self.shape.center_x_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// y coordinate for the center of scaling. |
| pub fn center_y(&self) -> FWord { |
| let range = self.shape.center_y_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintScaleAroundCenter<'a> { |
| fn type_name(&self) -> &str { |
| "PaintScaleAroundCenter" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint()), |
| )), |
| 2usize => Some(Field::new("scale_x", self.scale_x())), |
| 3usize => Some(Field::new("scale_y", self.scale_y())), |
| 4usize => Some(Field::new("center_x", self.center_x())), |
| 5usize => Some(Field::new("center_y", self.center_y())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintScaleAroundCenter<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintVarScaleAroundCenterMarker { |
| const FORMAT: u8 = 19; |
| } |
| |
| /// [PaintVarScaleAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintVarScaleAroundCenterMarker {} |
| |
| impl PaintVarScaleAroundCenterMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn scale_x_byte_range(&self) -> Range<usize> { |
| let start = self.paint_offset_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn scale_y_byte_range(&self) -> Range<usize> { |
| let start = self.scale_x_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn center_x_byte_range(&self) -> Range<usize> { |
| let start = self.scale_y_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn center_y_byte_range(&self) -> Range<usize> { |
| let start = self.center_x_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn var_index_base_byte_range(&self) -> Range<usize> { |
| let start = self.center_y_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintVarScaleAroundCenterMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.var_index_base_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintVarScaleAroundCenter<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<u32>(); |
| cursor.finish(PaintVarScaleAroundCenterMarker {}) |
| } |
| } |
| |
| /// [PaintVarScaleAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table |
| pub type PaintVarScaleAroundCenter<'a> = TableRef<'a, PaintVarScaleAroundCenterMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintVarScaleAroundCenter<'a> { |
| /// Set to 19. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a Paint subtable. |
| pub fn paint_offset(&self) -> Offset24 { |
| let range = self.shape.paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`paint_offset`][Self::paint_offset]. |
| pub fn paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.paint_offset().resolve(data) |
| } |
| |
| /// Scale factor in x direction. For variation, use varIndexBase + |
| /// 0. |
| pub fn scale_x(&self) -> F2Dot14 { |
| let range = self.shape.scale_x_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Scale factor in y direction. For variation, use varIndexBase + |
| /// 1. |
| pub fn scale_y(&self) -> F2Dot14 { |
| let range = self.shape.scale_y_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// x coordinate for the center of scaling. For variation, use |
| /// varIndexBase + 2. |
| pub fn center_x(&self) -> FWord { |
| let range = self.shape.center_x_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// y coordinate for the center of scaling. For variation, use |
| /// varIndexBase + 3. |
| pub fn center_y(&self) -> FWord { |
| let range = self.shape.center_y_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Base index into DeltaSetIndexMap. |
| pub fn var_index_base(&self) -> u32 { |
| let range = self.shape.var_index_base_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintVarScaleAroundCenter<'a> { |
| fn type_name(&self) -> &str { |
| "PaintVarScaleAroundCenter" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint()), |
| )), |
| 2usize => Some(Field::new("scale_x", self.scale_x())), |
| 3usize => Some(Field::new("scale_y", self.scale_y())), |
| 4usize => Some(Field::new("center_x", self.center_x())), |
| 5usize => Some(Field::new("center_y", self.center_y())), |
| 6usize => Some(Field::new("var_index_base", self.var_index_base())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintVarScaleAroundCenter<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintScaleUniformMarker { |
| const FORMAT: u8 = 20; |
| } |
| |
| /// [PaintScaleUniform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintScaleUniformMarker {} |
| |
| impl PaintScaleUniformMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn scale_byte_range(&self) -> Range<usize> { |
| let start = self.paint_offset_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintScaleUniformMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.scale_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintScaleUniform<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.finish(PaintScaleUniformMarker {}) |
| } |
| } |
| |
| /// [PaintScaleUniform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table |
| pub type PaintScaleUniform<'a> = TableRef<'a, PaintScaleUniformMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintScaleUniform<'a> { |
| /// Set to 20. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a Paint subtable. |
| pub fn paint_offset(&self) -> Offset24 { |
| let range = self.shape.paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`paint_offset`][Self::paint_offset]. |
| pub fn paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.paint_offset().resolve(data) |
| } |
| |
| /// Scale factor in x and y directions. |
| pub fn scale(&self) -> F2Dot14 { |
| let range = self.shape.scale_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintScaleUniform<'a> { |
| fn type_name(&self) -> &str { |
| "PaintScaleUniform" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint()), |
| )), |
| 2usize => Some(Field::new("scale", self.scale())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintScaleUniform<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintVarScaleUniformMarker { |
| const FORMAT: u8 = 21; |
| } |
| |
| /// [PaintVarScaleUniform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintVarScaleUniformMarker {} |
| |
| impl PaintVarScaleUniformMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn scale_byte_range(&self) -> Range<usize> { |
| let start = self.paint_offset_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn var_index_base_byte_range(&self) -> Range<usize> { |
| let start = self.scale_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintVarScaleUniformMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.var_index_base_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintVarScaleUniform<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<u32>(); |
| cursor.finish(PaintVarScaleUniformMarker {}) |
| } |
| } |
| |
| /// [PaintVarScaleUniform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table |
| pub type PaintVarScaleUniform<'a> = TableRef<'a, PaintVarScaleUniformMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintVarScaleUniform<'a> { |
| /// Set to 21. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a Paint subtable. |
| pub fn paint_offset(&self) -> Offset24 { |
| let range = self.shape.paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`paint_offset`][Self::paint_offset]. |
| pub fn paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.paint_offset().resolve(data) |
| } |
| |
| /// Scale factor in x and y directions. For variation, use |
| /// varIndexBase + 0. |
| pub fn scale(&self) -> F2Dot14 { |
| let range = self.shape.scale_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Base index into DeltaSetIndexMap. |
| pub fn var_index_base(&self) -> u32 { |
| let range = self.shape.var_index_base_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintVarScaleUniform<'a> { |
| fn type_name(&self) -> &str { |
| "PaintVarScaleUniform" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint()), |
| )), |
| 2usize => Some(Field::new("scale", self.scale())), |
| 3usize => Some(Field::new("var_index_base", self.var_index_base())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintVarScaleUniform<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintScaleUniformAroundCenterMarker { |
| const FORMAT: u8 = 22; |
| } |
| |
| /// [PaintScaleUniformAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintScaleUniformAroundCenterMarker {} |
| |
| impl PaintScaleUniformAroundCenterMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn scale_byte_range(&self) -> Range<usize> { |
| let start = self.paint_offset_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn center_x_byte_range(&self) -> Range<usize> { |
| let start = self.scale_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn center_y_byte_range(&self) -> Range<usize> { |
| let start = self.center_x_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintScaleUniformAroundCenterMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.center_y_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintScaleUniformAroundCenter<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.finish(PaintScaleUniformAroundCenterMarker {}) |
| } |
| } |
| |
| /// [PaintScaleUniformAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table |
| pub type PaintScaleUniformAroundCenter<'a> = TableRef<'a, PaintScaleUniformAroundCenterMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintScaleUniformAroundCenter<'a> { |
| /// Set to 22. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a Paint subtable. |
| pub fn paint_offset(&self) -> Offset24 { |
| let range = self.shape.paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`paint_offset`][Self::paint_offset]. |
| pub fn paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.paint_offset().resolve(data) |
| } |
| |
| /// Scale factor in x and y directions. |
| pub fn scale(&self) -> F2Dot14 { |
| let range = self.shape.scale_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// x coordinate for the center of scaling. |
| pub fn center_x(&self) -> FWord { |
| let range = self.shape.center_x_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// y coordinate for the center of scaling. |
| pub fn center_y(&self) -> FWord { |
| let range = self.shape.center_y_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintScaleUniformAroundCenter<'a> { |
| fn type_name(&self) -> &str { |
| "PaintScaleUniformAroundCenter" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint()), |
| )), |
| 2usize => Some(Field::new("scale", self.scale())), |
| 3usize => Some(Field::new("center_x", self.center_x())), |
| 4usize => Some(Field::new("center_y", self.center_y())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintScaleUniformAroundCenter<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintVarScaleUniformAroundCenterMarker { |
| const FORMAT: u8 = 23; |
| } |
| |
| /// [PaintVarScaleUniformAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintVarScaleUniformAroundCenterMarker {} |
| |
| impl PaintVarScaleUniformAroundCenterMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn scale_byte_range(&self) -> Range<usize> { |
| let start = self.paint_offset_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn center_x_byte_range(&self) -> Range<usize> { |
| let start = self.scale_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn center_y_byte_range(&self) -> Range<usize> { |
| let start = self.center_x_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn var_index_base_byte_range(&self) -> Range<usize> { |
| let start = self.center_y_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintVarScaleUniformAroundCenterMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.var_index_base_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintVarScaleUniformAroundCenter<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<u32>(); |
| cursor.finish(PaintVarScaleUniformAroundCenterMarker {}) |
| } |
| } |
| |
| /// [PaintVarScaleUniformAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table |
| pub type PaintVarScaleUniformAroundCenter<'a> = |
| TableRef<'a, PaintVarScaleUniformAroundCenterMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintVarScaleUniformAroundCenter<'a> { |
| /// Set to 23. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a Paint subtable. |
| pub fn paint_offset(&self) -> Offset24 { |
| let range = self.shape.paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`paint_offset`][Self::paint_offset]. |
| pub fn paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.paint_offset().resolve(data) |
| } |
| |
| /// Scale factor in x and y directions. For variation, use |
| /// varIndexBase + 0. |
| pub fn scale(&self) -> F2Dot14 { |
| let range = self.shape.scale_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// x coordinate for the center of scaling. For variation, use |
| /// varIndexBase + 1. |
| pub fn center_x(&self) -> FWord { |
| let range = self.shape.center_x_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// y coordinate for the center of scaling. For variation, use |
| /// varIndexBase + 2. |
| pub fn center_y(&self) -> FWord { |
| let range = self.shape.center_y_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Base index into DeltaSetIndexMap. |
| pub fn var_index_base(&self) -> u32 { |
| let range = self.shape.var_index_base_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintVarScaleUniformAroundCenter<'a> { |
| fn type_name(&self) -> &str { |
| "PaintVarScaleUniformAroundCenter" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint()), |
| )), |
| 2usize => Some(Field::new("scale", self.scale())), |
| 3usize => Some(Field::new("center_x", self.center_x())), |
| 4usize => Some(Field::new("center_y", self.center_y())), |
| 5usize => Some(Field::new("var_index_base", self.var_index_base())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintVarScaleUniformAroundCenter<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintRotateMarker { |
| const FORMAT: u8 = 24; |
| } |
| |
| /// [PaintRotate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintRotateMarker {} |
| |
| impl PaintRotateMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn angle_byte_range(&self) -> Range<usize> { |
| let start = self.paint_offset_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintRotateMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.angle_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintRotate<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.finish(PaintRotateMarker {}) |
| } |
| } |
| |
| /// [PaintRotate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table |
| pub type PaintRotate<'a> = TableRef<'a, PaintRotateMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintRotate<'a> { |
| /// Set to 24. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a Paint subtable. |
| pub fn paint_offset(&self) -> Offset24 { |
| let range = self.shape.paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`paint_offset`][Self::paint_offset]. |
| pub fn paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.paint_offset().resolve(data) |
| } |
| |
| /// Rotation angle, 180° in counter-clockwise degrees per 1.0 of |
| /// value. |
| pub fn angle(&self) -> F2Dot14 { |
| let range = self.shape.angle_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintRotate<'a> { |
| fn type_name(&self) -> &str { |
| "PaintRotate" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint()), |
| )), |
| 2usize => Some(Field::new("angle", self.angle())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintRotate<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintVarRotateMarker { |
| const FORMAT: u8 = 25; |
| } |
| |
| /// [PaintVarRotate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintVarRotateMarker {} |
| |
| impl PaintVarRotateMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn angle_byte_range(&self) -> Range<usize> { |
| let start = self.paint_offset_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn var_index_base_byte_range(&self) -> Range<usize> { |
| let start = self.angle_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintVarRotateMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.var_index_base_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintVarRotate<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<u32>(); |
| cursor.finish(PaintVarRotateMarker {}) |
| } |
| } |
| |
| /// [PaintVarRotate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table |
| pub type PaintVarRotate<'a> = TableRef<'a, PaintVarRotateMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintVarRotate<'a> { |
| /// Set to 25. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a Paint subtable. |
| pub fn paint_offset(&self) -> Offset24 { |
| let range = self.shape.paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`paint_offset`][Self::paint_offset]. |
| pub fn paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.paint_offset().resolve(data) |
| } |
| |
| /// Rotation angle, 180° in counter-clockwise degrees per 1.0 of |
| /// value. For variation, use varIndexBase + 0. |
| pub fn angle(&self) -> F2Dot14 { |
| let range = self.shape.angle_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Base index into DeltaSetIndexMap. |
| pub fn var_index_base(&self) -> u32 { |
| let range = self.shape.var_index_base_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintVarRotate<'a> { |
| fn type_name(&self) -> &str { |
| "PaintVarRotate" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint()), |
| )), |
| 2usize => Some(Field::new("angle", self.angle())), |
| 3usize => Some(Field::new("var_index_base", self.var_index_base())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintVarRotate<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintRotateAroundCenterMarker { |
| const FORMAT: u8 = 26; |
| } |
| |
| /// [PaintRotateAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintRotateAroundCenterMarker {} |
| |
| impl PaintRotateAroundCenterMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn angle_byte_range(&self) -> Range<usize> { |
| let start = self.paint_offset_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn center_x_byte_range(&self) -> Range<usize> { |
| let start = self.angle_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn center_y_byte_range(&self) -> Range<usize> { |
| let start = self.center_x_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintRotateAroundCenterMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.center_y_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintRotateAroundCenter<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.finish(PaintRotateAroundCenterMarker {}) |
| } |
| } |
| |
| /// [PaintRotateAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table |
| pub type PaintRotateAroundCenter<'a> = TableRef<'a, PaintRotateAroundCenterMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintRotateAroundCenter<'a> { |
| /// Set to 26. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a Paint subtable. |
| pub fn paint_offset(&self) -> Offset24 { |
| let range = self.shape.paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`paint_offset`][Self::paint_offset]. |
| pub fn paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.paint_offset().resolve(data) |
| } |
| |
| /// Rotation angle, 180° in counter-clockwise degrees per 1.0 of |
| /// value. |
| pub fn angle(&self) -> F2Dot14 { |
| let range = self.shape.angle_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// x coordinate for the center of rotation. |
| pub fn center_x(&self) -> FWord { |
| let range = self.shape.center_x_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// y coordinate for the center of rotation. |
| pub fn center_y(&self) -> FWord { |
| let range = self.shape.center_y_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintRotateAroundCenter<'a> { |
| fn type_name(&self) -> &str { |
| "PaintRotateAroundCenter" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint()), |
| )), |
| 2usize => Some(Field::new("angle", self.angle())), |
| 3usize => Some(Field::new("center_x", self.center_x())), |
| 4usize => Some(Field::new("center_y", self.center_y())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintRotateAroundCenter<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintVarRotateAroundCenterMarker { |
| const FORMAT: u8 = 27; |
| } |
| |
| /// [PaintVarRotateAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintVarRotateAroundCenterMarker {} |
| |
| impl PaintVarRotateAroundCenterMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn angle_byte_range(&self) -> Range<usize> { |
| let start = self.paint_offset_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn center_x_byte_range(&self) -> Range<usize> { |
| let start = self.angle_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn center_y_byte_range(&self) -> Range<usize> { |
| let start = self.center_x_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn var_index_base_byte_range(&self) -> Range<usize> { |
| let start = self.center_y_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintVarRotateAroundCenterMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.var_index_base_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintVarRotateAroundCenter<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<u32>(); |
| cursor.finish(PaintVarRotateAroundCenterMarker {}) |
| } |
| } |
| |
| /// [PaintVarRotateAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table |
| pub type PaintVarRotateAroundCenter<'a> = TableRef<'a, PaintVarRotateAroundCenterMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintVarRotateAroundCenter<'a> { |
| /// Set to 27. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a Paint subtable. |
| pub fn paint_offset(&self) -> Offset24 { |
| let range = self.shape.paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`paint_offset`][Self::paint_offset]. |
| pub fn paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.paint_offset().resolve(data) |
| } |
| |
| /// Rotation angle, 180° in counter-clockwise degrees per 1.0 of |
| /// value. For variation, use varIndexBase + 0. |
| pub fn angle(&self) -> F2Dot14 { |
| let range = self.shape.angle_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// x coordinate for the center of rotation. For variation, use |
| /// varIndexBase + 1. |
| pub fn center_x(&self) -> FWord { |
| let range = self.shape.center_x_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// y coordinate for the center of rotation. For variation, use |
| /// varIndexBase + 2. |
| pub fn center_y(&self) -> FWord { |
| let range = self.shape.center_y_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Base index into DeltaSetIndexMap. |
| pub fn var_index_base(&self) -> u32 { |
| let range = self.shape.var_index_base_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintVarRotateAroundCenter<'a> { |
| fn type_name(&self) -> &str { |
| "PaintVarRotateAroundCenter" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint()), |
| )), |
| 2usize => Some(Field::new("angle", self.angle())), |
| 3usize => Some(Field::new("center_x", self.center_x())), |
| 4usize => Some(Field::new("center_y", self.center_y())), |
| 5usize => Some(Field::new("var_index_base", self.var_index_base())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintVarRotateAroundCenter<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintSkewMarker { |
| const FORMAT: u8 = 28; |
| } |
| |
| /// [PaintSkew](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintSkewMarker {} |
| |
| impl PaintSkewMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn x_skew_angle_byte_range(&self) -> Range<usize> { |
| let start = self.paint_offset_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn y_skew_angle_byte_range(&self) -> Range<usize> { |
| let start = self.x_skew_angle_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintSkewMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.y_skew_angle_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintSkew<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.finish(PaintSkewMarker {}) |
| } |
| } |
| |
| /// [PaintSkew](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table |
| pub type PaintSkew<'a> = TableRef<'a, PaintSkewMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintSkew<'a> { |
| /// Set to 28. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a Paint subtable. |
| pub fn paint_offset(&self) -> Offset24 { |
| let range = self.shape.paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`paint_offset`][Self::paint_offset]. |
| pub fn paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.paint_offset().resolve(data) |
| } |
| |
| /// Angle of skew in the direction of the x-axis, 180° in |
| /// counter-clockwise degrees per 1.0 of value. |
| pub fn x_skew_angle(&self) -> F2Dot14 { |
| let range = self.shape.x_skew_angle_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Angle of skew in the direction of the y-axis, 180° in |
| /// counter-clockwise degrees per 1.0 of value. |
| pub fn y_skew_angle(&self) -> F2Dot14 { |
| let range = self.shape.y_skew_angle_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintSkew<'a> { |
| fn type_name(&self) -> &str { |
| "PaintSkew" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint()), |
| )), |
| 2usize => Some(Field::new("x_skew_angle", self.x_skew_angle())), |
| 3usize => Some(Field::new("y_skew_angle", self.y_skew_angle())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintSkew<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintVarSkewMarker { |
| const FORMAT: u8 = 29; |
| } |
| |
| /// [PaintVarSkew](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintVarSkewMarker {} |
| |
| impl PaintVarSkewMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn x_skew_angle_byte_range(&self) -> Range<usize> { |
| let start = self.paint_offset_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn y_skew_angle_byte_range(&self) -> Range<usize> { |
| let start = self.x_skew_angle_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn var_index_base_byte_range(&self) -> Range<usize> { |
| let start = self.y_skew_angle_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintVarSkewMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.var_index_base_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintVarSkew<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<u32>(); |
| cursor.finish(PaintVarSkewMarker {}) |
| } |
| } |
| |
| /// [PaintVarSkew](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table |
| pub type PaintVarSkew<'a> = TableRef<'a, PaintVarSkewMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintVarSkew<'a> { |
| /// Set to 29. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a Paint subtable. |
| pub fn paint_offset(&self) -> Offset24 { |
| let range = self.shape.paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`paint_offset`][Self::paint_offset]. |
| pub fn paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.paint_offset().resolve(data) |
| } |
| |
| /// Angle of skew in the direction of the x-axis, 180° ┬░ in |
| /// counter-clockwise degrees per 1.0 of value. For variation, use |
| /// varIndexBase + 0. |
| pub fn x_skew_angle(&self) -> F2Dot14 { |
| let range = self.shape.x_skew_angle_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Angle of skew in the direction of the y-axis, 180° in |
| /// counter-clockwise degrees per 1.0 of value. For variation, use |
| /// varIndexBase + 1. |
| pub fn y_skew_angle(&self) -> F2Dot14 { |
| let range = self.shape.y_skew_angle_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Base index into DeltaSetIndexMap. |
| pub fn var_index_base(&self) -> u32 { |
| let range = self.shape.var_index_base_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintVarSkew<'a> { |
| fn type_name(&self) -> &str { |
| "PaintVarSkew" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint()), |
| )), |
| 2usize => Some(Field::new("x_skew_angle", self.x_skew_angle())), |
| 3usize => Some(Field::new("y_skew_angle", self.y_skew_angle())), |
| 4usize => Some(Field::new("var_index_base", self.var_index_base())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintVarSkew<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintSkewAroundCenterMarker { |
| const FORMAT: u8 = 30; |
| } |
| |
| /// [PaintSkewAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintSkewAroundCenterMarker {} |
| |
| impl PaintSkewAroundCenterMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn x_skew_angle_byte_range(&self) -> Range<usize> { |
| let start = self.paint_offset_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn y_skew_angle_byte_range(&self) -> Range<usize> { |
| let start = self.x_skew_angle_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn center_x_byte_range(&self) -> Range<usize> { |
| let start = self.y_skew_angle_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn center_y_byte_range(&self) -> Range<usize> { |
| let start = self.center_x_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintSkewAroundCenterMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.center_y_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintSkewAroundCenter<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.finish(PaintSkewAroundCenterMarker {}) |
| } |
| } |
| |
| /// [PaintSkewAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table |
| pub type PaintSkewAroundCenter<'a> = TableRef<'a, PaintSkewAroundCenterMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintSkewAroundCenter<'a> { |
| /// Set to 30. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a Paint subtable. |
| pub fn paint_offset(&self) -> Offset24 { |
| let range = self.shape.paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`paint_offset`][Self::paint_offset]. |
| pub fn paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.paint_offset().resolve(data) |
| } |
| |
| /// Angle of skew in the direction of the x-axis, 180° in |
| /// counter-clockwise degrees per 1.0 of value. |
| pub fn x_skew_angle(&self) -> F2Dot14 { |
| let range = self.shape.x_skew_angle_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Angle of skew in the direction of the y-axis, 180° in |
| /// counter-clockwise degrees per 1.0 of value. |
| pub fn y_skew_angle(&self) -> F2Dot14 { |
| let range = self.shape.y_skew_angle_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// x coordinate for the center of rotation. |
| pub fn center_x(&self) -> FWord { |
| let range = self.shape.center_x_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// y coordinate for the center of rotation. |
| pub fn center_y(&self) -> FWord { |
| let range = self.shape.center_y_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintSkewAroundCenter<'a> { |
| fn type_name(&self) -> &str { |
| "PaintSkewAroundCenter" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint()), |
| )), |
| 2usize => Some(Field::new("x_skew_angle", self.x_skew_angle())), |
| 3usize => Some(Field::new("y_skew_angle", self.y_skew_angle())), |
| 4usize => Some(Field::new("center_x", self.center_x())), |
| 5usize => Some(Field::new("center_y", self.center_y())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintSkewAroundCenter<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintVarSkewAroundCenterMarker { |
| const FORMAT: u8 = 31; |
| } |
| |
| /// [PaintVarSkewAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintVarSkewAroundCenterMarker {} |
| |
| impl PaintVarSkewAroundCenterMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn x_skew_angle_byte_range(&self) -> Range<usize> { |
| let start = self.paint_offset_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn y_skew_angle_byte_range(&self) -> Range<usize> { |
| let start = self.x_skew_angle_byte_range().end; |
| start..start + F2Dot14::RAW_BYTE_LEN |
| } |
| |
| pub fn center_x_byte_range(&self) -> Range<usize> { |
| let start = self.y_skew_angle_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn center_y_byte_range(&self) -> Range<usize> { |
| let start = self.center_x_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn var_index_base_byte_range(&self) -> Range<usize> { |
| let start = self.center_y_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintVarSkewAroundCenterMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.var_index_base_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintVarSkewAroundCenter<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<F2Dot14>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<u32>(); |
| cursor.finish(PaintVarSkewAroundCenterMarker {}) |
| } |
| } |
| |
| /// [PaintVarSkewAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table |
| pub type PaintVarSkewAroundCenter<'a> = TableRef<'a, PaintVarSkewAroundCenterMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintVarSkewAroundCenter<'a> { |
| /// Set to 31. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a Paint subtable. |
| pub fn paint_offset(&self) -> Offset24 { |
| let range = self.shape.paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`paint_offset`][Self::paint_offset]. |
| pub fn paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.paint_offset().resolve(data) |
| } |
| |
| /// Angle of skew in the direction of the x-axis, 180° in |
| /// counter-clockwise degrees per 1.0 of value. For variation, use |
| /// varIndexBase + 0. |
| pub fn x_skew_angle(&self) -> F2Dot14 { |
| let range = self.shape.x_skew_angle_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Angle of skew in the direction of the y-axis, 180° in |
| /// counter-clockwise degrees per 1.0 of value. For variation, use |
| /// varIndexBase + 1. |
| pub fn y_skew_angle(&self) -> F2Dot14 { |
| let range = self.shape.y_skew_angle_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// x coordinate for the center of rotation. For variation, use |
| /// varIndexBase + 2. |
| pub fn center_x(&self) -> FWord { |
| let range = self.shape.center_x_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// y coordinate for the center of rotation. For variation, use |
| /// varIndexBase + 3. |
| pub fn center_y(&self) -> FWord { |
| let range = self.shape.center_y_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Base index into DeltaSetIndexMap. |
| pub fn var_index_base(&self) -> u32 { |
| let range = self.shape.var_index_base_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintVarSkewAroundCenter<'a> { |
| fn type_name(&self) -> &str { |
| "PaintVarSkewAroundCenter" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "paint_offset", |
| FieldType::offset(self.paint_offset(), self.paint()), |
| )), |
| 2usize => Some(Field::new("x_skew_angle", self.x_skew_angle())), |
| 3usize => Some(Field::new("y_skew_angle", self.y_skew_angle())), |
| 4usize => Some(Field::new("center_x", self.center_x())), |
| 5usize => Some(Field::new("center_y", self.center_y())), |
| 6usize => Some(Field::new("var_index_base", self.var_index_base())), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintVarSkewAroundCenter<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| impl Format<u8> for PaintCompositeMarker { |
| const FORMAT: u8 = 32; |
| } |
| |
| /// [PaintComposite](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-32-paintcomposite) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PaintCompositeMarker {} |
| |
| impl PaintCompositeMarker { |
| pub fn format_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + u8::RAW_BYTE_LEN |
| } |
| |
| pub fn source_paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.format_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| |
| pub fn composite_mode_byte_range(&self) -> Range<usize> { |
| let start = self.source_paint_offset_byte_range().end; |
| start..start + CompositeMode::RAW_BYTE_LEN |
| } |
| |
| pub fn backdrop_paint_offset_byte_range(&self) -> Range<usize> { |
| let start = self.composite_mode_byte_range().end; |
| start..start + Offset24::RAW_BYTE_LEN |
| } |
| } |
| |
| impl MinByteRange for PaintCompositeMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.backdrop_paint_offset_byte_range().end |
| } |
| } |
| |
| impl<'a> FontRead<'a> for PaintComposite<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| cursor.advance::<u8>(); |
| cursor.advance::<Offset24>(); |
| cursor.advance::<CompositeMode>(); |
| cursor.advance::<Offset24>(); |
| cursor.finish(PaintCompositeMarker {}) |
| } |
| } |
| |
| /// [PaintComposite](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-32-paintcomposite) table |
| pub type PaintComposite<'a> = TableRef<'a, PaintCompositeMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> PaintComposite<'a> { |
| /// Set to 32. |
| pub fn format(&self) -> u8 { |
| let range = self.shape.format_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a source Paint table. |
| pub fn source_paint_offset(&self) -> Offset24 { |
| let range = self.shape.source_paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`source_paint_offset`][Self::source_paint_offset]. |
| pub fn source_paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.source_paint_offset().resolve(data) |
| } |
| |
| /// A CompositeMode enumeration value. |
| pub fn composite_mode(&self) -> CompositeMode { |
| let range = self.shape.composite_mode_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Offset to a backdrop Paint table. |
| pub fn backdrop_paint_offset(&self) -> Offset24 { |
| let range = self.shape.backdrop_paint_offset_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Attempt to resolve [`backdrop_paint_offset`][Self::backdrop_paint_offset]. |
| pub fn backdrop_paint(&self) -> Result<Paint<'a>, ReadError> { |
| let data = self.data; |
| self.backdrop_paint_offset().resolve(data) |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for PaintComposite<'a> { |
| fn type_name(&self) -> &str { |
| "PaintComposite" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| match idx { |
| 0usize => Some(Field::new("format", self.format())), |
| 1usize => Some(Field::new( |
| "source_paint_offset", |
| FieldType::offset(self.source_paint_offset(), self.source_paint()), |
| )), |
| 2usize => Some(Field::new("composite_mode", self.composite_mode())), |
| 3usize => Some(Field::new( |
| "backdrop_paint_offset", |
| FieldType::offset(self.backdrop_paint_offset(), self.backdrop_paint()), |
| )), |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for PaintComposite<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |
| |
| /// [CompositeMode](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-32-paintcomposite) enumeration |
| #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| #[repr(u8)] |
| #[allow(clippy::manual_non_exhaustive)] |
| pub enum CompositeMode { |
| Clear = 0, |
| Src = 1, |
| Dest = 2, |
| #[default] |
| SrcOver = 3, |
| DestOver = 4, |
| SrcIn = 5, |
| DestIn = 6, |
| SrcOut = 7, |
| DestOut = 8, |
| SrcAtop = 9, |
| DestAtop = 10, |
| Xor = 11, |
| Plus = 12, |
| Screen = 13, |
| Overlay = 14, |
| Darken = 15, |
| Lighten = 16, |
| ColorDodge = 17, |
| ColorBurn = 18, |
| HardLight = 19, |
| SoftLight = 20, |
| Difference = 21, |
| Exclusion = 22, |
| Multiply = 23, |
| HslHue = 24, |
| HslSaturation = 25, |
| HslColor = 26, |
| HslLuminosity = 27, |
| #[doc(hidden)] |
| /// If font data is malformed we will map unknown values to this variant |
| Unknown, |
| } |
| |
| impl CompositeMode { |
| /// Create from a raw scalar. |
| /// |
| /// This will never fail; unknown values will be mapped to the `Unknown` variant |
| pub fn new(raw: u8) -> Self { |
| match raw { |
| 0 => Self::Clear, |
| 1 => Self::Src, |
| 2 => Self::Dest, |
| 3 => Self::SrcOver, |
| 4 => Self::DestOver, |
| 5 => Self::SrcIn, |
| 6 => Self::DestIn, |
| 7 => Self::SrcOut, |
| 8 => Self::DestOut, |
| 9 => Self::SrcAtop, |
| 10 => Self::DestAtop, |
| 11 => Self::Xor, |
| 12 => Self::Plus, |
| 13 => Self::Screen, |
| 14 => Self::Overlay, |
| 15 => Self::Darken, |
| 16 => Self::Lighten, |
| 17 => Self::ColorDodge, |
| 18 => Self::ColorBurn, |
| 19 => Self::HardLight, |
| 20 => Self::SoftLight, |
| 21 => Self::Difference, |
| 22 => Self::Exclusion, |
| 23 => Self::Multiply, |
| 24 => Self::HslHue, |
| 25 => Self::HslSaturation, |
| 26 => Self::HslColor, |
| 27 => Self::HslLuminosity, |
| _ => Self::Unknown, |
| } |
| } |
| } |
| |
| impl font_types::Scalar for CompositeMode { |
| type Raw = <u8 as font_types::Scalar>::Raw; |
| fn to_raw(self) -> Self::Raw { |
| (self as u8).to_raw() |
| } |
| fn from_raw(raw: Self::Raw) -> Self { |
| let t = <u8>::from_raw(raw); |
| Self::new(t) |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> From<CompositeMode> for FieldType<'a> { |
| fn from(src: CompositeMode) -> FieldType<'a> { |
| (src as u8).into() |
| } |
| } |