6253 lines
205 KiB
Rust
6253 lines
205 KiB
Rust
// 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()
|
|
}
|
|
}
|