Files
another-boids-in-rust/vendor/read-fonts/generated/generated_variations.rs

1321 lines
43 KiB
Rust
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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::*;
/// [TupleVariationHeader](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader)
#[derive(Debug, Clone, Copy)]
#[doc(hidden)]
pub struct TupleVariationHeaderMarker {
peak_tuple_byte_len: usize,
intermediate_start_tuple_byte_len: usize,
intermediate_end_tuple_byte_len: usize,
}
impl TupleVariationHeaderMarker {
pub fn variation_data_size_byte_range(&self) -> Range<usize> {
let start = 0;
start..start + u16::RAW_BYTE_LEN
}
pub fn tuple_index_byte_range(&self) -> Range<usize> {
let start = self.variation_data_size_byte_range().end;
start..start + TupleIndex::RAW_BYTE_LEN
}
pub fn peak_tuple_byte_range(&self) -> Range<usize> {
let start = self.tuple_index_byte_range().end;
start..start + self.peak_tuple_byte_len
}
pub fn intermediate_start_tuple_byte_range(&self) -> Range<usize> {
let start = self.peak_tuple_byte_range().end;
start..start + self.intermediate_start_tuple_byte_len
}
pub fn intermediate_end_tuple_byte_range(&self) -> Range<usize> {
let start = self.intermediate_start_tuple_byte_range().end;
start..start + self.intermediate_end_tuple_byte_len
}
}
impl MinByteRange for TupleVariationHeaderMarker {
fn min_byte_range(&self) -> Range<usize> {
0..self.intermediate_end_tuple_byte_range().end
}
}
impl ReadArgs for TupleVariationHeader<'_> {
type Args = u16;
}
impl<'a> FontReadWithArgs<'a> for TupleVariationHeader<'a> {
fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> {
let axis_count = *args;
let mut cursor = data.cursor();
cursor.advance::<u16>();
let tuple_index: TupleIndex = cursor.read()?;
let peak_tuple_byte_len = (TupleIndex::tuple_len(tuple_index, axis_count, 0_usize))
.checked_mul(F2Dot14::RAW_BYTE_LEN)
.ok_or(ReadError::OutOfBounds)?;
cursor.advance_by(peak_tuple_byte_len);
let intermediate_start_tuple_byte_len =
(TupleIndex::tuple_len(tuple_index, axis_count, 1_usize))
.checked_mul(F2Dot14::RAW_BYTE_LEN)
.ok_or(ReadError::OutOfBounds)?;
cursor.advance_by(intermediate_start_tuple_byte_len);
let intermediate_end_tuple_byte_len =
(TupleIndex::tuple_len(tuple_index, axis_count, 1_usize))
.checked_mul(F2Dot14::RAW_BYTE_LEN)
.ok_or(ReadError::OutOfBounds)?;
cursor.advance_by(intermediate_end_tuple_byte_len);
cursor.finish(TupleVariationHeaderMarker {
peak_tuple_byte_len,
intermediate_start_tuple_byte_len,
intermediate_end_tuple_byte_len,
})
}
}
impl<'a> TupleVariationHeader<'a> {
/// A constructor that requires additional arguments.
///
/// This type requires some external state in order to be
/// parsed.
pub fn read(data: FontData<'a>, axis_count: u16) -> Result<Self, ReadError> {
let args = axis_count;
Self::read_with_args(data, &args)
}
}
/// [TupleVariationHeader](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader)
pub type TupleVariationHeader<'a> = TableRef<'a, TupleVariationHeaderMarker>;
#[allow(clippy::needless_lifetimes)]
impl<'a> TupleVariationHeader<'a> {
/// The size in bytes of the serialized data for this tuple
/// variation table.
pub fn variation_data_size(&self) -> u16 {
let range = self.shape.variation_data_size_byte_range();
self.data.read_at(range.start).unwrap()
}
/// A packed field. The high 4 bits are flags (see below). The low
/// 12 bits are an index into a shared tuple records array.
pub fn tuple_index(&self) -> TupleIndex {
let range = self.shape.tuple_index_byte_range();
self.data.read_at(range.start).unwrap()
}
}
#[cfg(feature = "experimental_traverse")]
impl<'a> SomeTable<'a> for TupleVariationHeader<'a> {
fn type_name(&self) -> &str {
"TupleVariationHeader"
}
fn get_field(&self, idx: usize) -> Option<Field<'a>> {
match idx {
0usize => Some(Field::new(
"variation_data_size",
self.variation_data_size(),
)),
1usize => Some(Field::new("tuple_index", self.traverse_tuple_index())),
_ => None,
}
}
}
#[cfg(feature = "experimental_traverse")]
#[allow(clippy::needless_lifetimes)]
impl<'a> std::fmt::Debug for TupleVariationHeader<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
(self as &dyn SomeTable<'a>).fmt(f)
}
}
/// A [Tuple Record](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuple-records)
///
/// The tuple variation store formats reference regions within the fonts
/// variation space using tuple records. A tuple record identifies a position
/// in terms of normalized coordinates, which use F2DOT14 values.
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Tuple<'a> {
/// Coordinate array specifying a position within the fonts variation space.
///
/// The number of elements must match the axisCount specified in the
/// 'fvar' table.
pub values: &'a [BigEndian<F2Dot14>],
}
impl<'a> Tuple<'a> {
/// Coordinate array specifying a position within the fonts variation space.
///
/// The number of elements must match the axisCount specified in the
/// 'fvar' table.
pub fn values(&self) -> &'a [BigEndian<F2Dot14>] {
self.values
}
}
impl ReadArgs for Tuple<'_> {
type Args = u16;
}
impl ComputeSize for Tuple<'_> {
#[allow(clippy::needless_question_mark)]
fn compute_size(args: &u16) -> Result<usize, ReadError> {
let axis_count = *args;
Ok((axis_count as usize)
.checked_mul(F2Dot14::RAW_BYTE_LEN)
.ok_or(ReadError::OutOfBounds)?)
}
}
impl<'a> FontReadWithArgs<'a> for Tuple<'a> {
fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> {
let mut cursor = data.cursor();
let axis_count = *args;
Ok(Self {
values: cursor.read_array(axis_count as usize)?,
})
}
}
#[allow(clippy::needless_lifetimes)]
impl<'a> Tuple<'a> {
/// A constructor that requires additional arguments.
///
/// This type requires some external state in order to be
/// parsed.
pub fn read(data: FontData<'a>, axis_count: u16) -> Result<Self, ReadError> {
let args = axis_count;
Self::read_with_args(data, &args)
}
}
#[cfg(feature = "experimental_traverse")]
impl<'a> SomeRecord<'a> for Tuple<'a> {
fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
RecordResolver {
name: "Tuple",
get_field: Box::new(move |idx, _data| match idx {
0usize => Some(Field::new("values", self.values())),
_ => None,
}),
data,
}
}
}
impl Format<u8> for DeltaSetIndexMapFormat0Marker {
const FORMAT: u8 = 0;
}
/// The [DeltaSetIndexMap](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#associating-target-items-to-variation-data) table format 0
#[derive(Debug, Clone, Copy)]
#[doc(hidden)]
pub struct DeltaSetIndexMapFormat0Marker {
map_data_byte_len: usize,
}
impl DeltaSetIndexMapFormat0Marker {
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
start..start + u8::RAW_BYTE_LEN
}
pub fn entry_format_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
start..start + EntryFormat::RAW_BYTE_LEN
}
pub fn map_count_byte_range(&self) -> Range<usize> {
let start = self.entry_format_byte_range().end;
start..start + u16::RAW_BYTE_LEN
}
pub fn map_data_byte_range(&self) -> Range<usize> {
let start = self.map_count_byte_range().end;
start..start + self.map_data_byte_len
}
}
impl MinByteRange for DeltaSetIndexMapFormat0Marker {
fn min_byte_range(&self) -> Range<usize> {
0..self.map_data_byte_range().end
}
}
impl<'a> FontRead<'a> for DeltaSetIndexMapFormat0<'a> {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
let mut cursor = data.cursor();
cursor.advance::<u8>();
let entry_format: EntryFormat = cursor.read()?;
let map_count: u16 = cursor.read()?;
let map_data_byte_len = (EntryFormat::map_size(entry_format, map_count))
.checked_mul(u8::RAW_BYTE_LEN)
.ok_or(ReadError::OutOfBounds)?;
cursor.advance_by(map_data_byte_len);
cursor.finish(DeltaSetIndexMapFormat0Marker { map_data_byte_len })
}
}
/// The [DeltaSetIndexMap](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#associating-target-items-to-variation-data) table format 0
pub type DeltaSetIndexMapFormat0<'a> = TableRef<'a, DeltaSetIndexMapFormat0Marker>;
#[allow(clippy::needless_lifetimes)]
impl<'a> DeltaSetIndexMapFormat0<'a> {
/// DeltaSetIndexMap format: set to 0.
pub fn format(&self) -> u8 {
let range = self.shape.format_byte_range();
self.data.read_at(range.start).unwrap()
}
/// A packed field that describes the compressed representation of
/// delta-set indices. See details below.
pub fn entry_format(&self) -> EntryFormat {
let range = self.shape.entry_format_byte_range();
self.data.read_at(range.start).unwrap()
}
/// The number of mapping entries.
pub fn map_count(&self) -> u16 {
let range = self.shape.map_count_byte_range();
self.data.read_at(range.start).unwrap()
}
/// The delta-set index mapping data. See details below.
pub fn map_data(&self) -> &'a [u8] {
let range = self.shape.map_data_byte_range();
self.data.read_array(range).unwrap()
}
}
#[cfg(feature = "experimental_traverse")]
impl<'a> SomeTable<'a> for DeltaSetIndexMapFormat0<'a> {
fn type_name(&self) -> &str {
"DeltaSetIndexMapFormat0"
}
fn get_field(&self, idx: usize) -> Option<Field<'a>> {
match idx {
0usize => Some(Field::new("format", self.format())),
1usize => Some(Field::new("entry_format", self.entry_format())),
2usize => Some(Field::new("map_count", self.map_count())),
3usize => Some(Field::new("map_data", self.map_data())),
_ => None,
}
}
}
#[cfg(feature = "experimental_traverse")]
#[allow(clippy::needless_lifetimes)]
impl<'a> std::fmt::Debug for DeltaSetIndexMapFormat0<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
(self as &dyn SomeTable<'a>).fmt(f)
}
}
impl Format<u8> for DeltaSetIndexMapFormat1Marker {
const FORMAT: u8 = 1;
}
/// The [DeltaSetIndexMap](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#associating-target-items-to-variation-data) table format 1
#[derive(Debug, Clone, Copy)]
#[doc(hidden)]
pub struct DeltaSetIndexMapFormat1Marker {
map_data_byte_len: usize,
}
impl DeltaSetIndexMapFormat1Marker {
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
start..start + u8::RAW_BYTE_LEN
}
pub fn entry_format_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
start..start + EntryFormat::RAW_BYTE_LEN
}
pub fn map_count_byte_range(&self) -> Range<usize> {
let start = self.entry_format_byte_range().end;
start..start + u32::RAW_BYTE_LEN
}
pub fn map_data_byte_range(&self) -> Range<usize> {
let start = self.map_count_byte_range().end;
start..start + self.map_data_byte_len
}
}
impl MinByteRange for DeltaSetIndexMapFormat1Marker {
fn min_byte_range(&self) -> Range<usize> {
0..self.map_data_byte_range().end
}
}
impl<'a> FontRead<'a> for DeltaSetIndexMapFormat1<'a> {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
let mut cursor = data.cursor();
cursor.advance::<u8>();
let entry_format: EntryFormat = cursor.read()?;
let map_count: u32 = cursor.read()?;
let map_data_byte_len = (EntryFormat::map_size(entry_format, map_count))
.checked_mul(u8::RAW_BYTE_LEN)
.ok_or(ReadError::OutOfBounds)?;
cursor.advance_by(map_data_byte_len);
cursor.finish(DeltaSetIndexMapFormat1Marker { map_data_byte_len })
}
}
/// The [DeltaSetIndexMap](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#associating-target-items-to-variation-data) table format 1
pub type DeltaSetIndexMapFormat1<'a> = TableRef<'a, DeltaSetIndexMapFormat1Marker>;
#[allow(clippy::needless_lifetimes)]
impl<'a> DeltaSetIndexMapFormat1<'a> {
/// DeltaSetIndexMap format: set to 1.
pub fn format(&self) -> u8 {
let range = self.shape.format_byte_range();
self.data.read_at(range.start).unwrap()
}
/// A packed field that describes the compressed representation of
/// delta-set indices. See details below.
pub fn entry_format(&self) -> EntryFormat {
let range = self.shape.entry_format_byte_range();
self.data.read_at(range.start).unwrap()
}
/// The number of mapping entries.
pub fn map_count(&self) -> u32 {
let range = self.shape.map_count_byte_range();
self.data.read_at(range.start).unwrap()
}
/// The delta-set index mapping data. See details below.
pub fn map_data(&self) -> &'a [u8] {
let range = self.shape.map_data_byte_range();
self.data.read_array(range).unwrap()
}
}
#[cfg(feature = "experimental_traverse")]
impl<'a> SomeTable<'a> for DeltaSetIndexMapFormat1<'a> {
fn type_name(&self) -> &str {
"DeltaSetIndexMapFormat1"
}
fn get_field(&self, idx: usize) -> Option<Field<'a>> {
match idx {
0usize => Some(Field::new("format", self.format())),
1usize => Some(Field::new("entry_format", self.entry_format())),
2usize => Some(Field::new("map_count", self.map_count())),
3usize => Some(Field::new("map_data", self.map_data())),
_ => None,
}
}
}
#[cfg(feature = "experimental_traverse")]
#[allow(clippy::needless_lifetimes)]
impl<'a> std::fmt::Debug for DeltaSetIndexMapFormat1<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
(self as &dyn SomeTable<'a>).fmt(f)
}
}
/// The [DeltaSetIndexMap](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#associating-target-items-to-variation-data) table
#[derive(Clone)]
pub enum DeltaSetIndexMap<'a> {
Format0(DeltaSetIndexMapFormat0<'a>),
Format1(DeltaSetIndexMapFormat1<'a>),
}
impl<'a> DeltaSetIndexMap<'a> {
///Return the `FontData` used to resolve offsets for this table.
pub fn offset_data(&self) -> FontData<'a> {
match self {
Self::Format0(item) => item.offset_data(),
Self::Format1(item) => item.offset_data(),
}
}
/// DeltaSetIndexMap format: set to 0.
pub fn format(&self) -> u8 {
match self {
Self::Format0(item) => item.format(),
Self::Format1(item) => item.format(),
}
}
/// A packed field that describes the compressed representation of
/// delta-set indices. See details below.
pub fn entry_format(&self) -> EntryFormat {
match self {
Self::Format0(item) => item.entry_format(),
Self::Format1(item) => item.entry_format(),
}
}
/// The delta-set index mapping data. See details below.
pub fn map_data(&self) -> &'a [u8] {
match self {
Self::Format0(item) => item.map_data(),
Self::Format1(item) => item.map_data(),
}
}
}
impl<'a> FontRead<'a> for DeltaSetIndexMap<'a> {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
let format: u8 = data.read_at(0usize)?;
match format {
DeltaSetIndexMapFormat0Marker::FORMAT => Ok(Self::Format0(FontRead::read(data)?)),
DeltaSetIndexMapFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)),
other => Err(ReadError::InvalidFormat(other.into())),
}
}
}
impl MinByteRange for DeltaSetIndexMap<'_> {
fn min_byte_range(&self) -> Range<usize> {
match self {
Self::Format0(item) => item.min_byte_range(),
Self::Format1(item) => item.min_byte_range(),
}
}
}
#[cfg(feature = "experimental_traverse")]
impl<'a> DeltaSetIndexMap<'a> {
fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> {
match self {
Self::Format0(table) => table,
Self::Format1(table) => table,
}
}
}
#[cfg(feature = "experimental_traverse")]
impl std::fmt::Debug for DeltaSetIndexMap<'_> {
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 DeltaSetIndexMap<'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)
}
}
/// Entry format for a [DeltaSetIndexMap].
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck :: AnyBitPattern)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(transparent)]
pub struct EntryFormat {
bits: u8,
}
impl EntryFormat {
/// Mask for the low 4 bits, which give the count of bits minus one that are used in each entry for the inner-level index.
pub const INNER_INDEX_BIT_COUNT_MASK: Self = Self { bits: 0x0F };
/// Mask for bits that indicate the size in bytes minus one of each entry.
pub const MAP_ENTRY_SIZE_MASK: Self = Self { bits: 0x30 };
}
impl EntryFormat {
/// Returns an empty set of flags.
#[inline]
pub const fn empty() -> Self {
Self { bits: 0 }
}
/// Returns the set containing all flags.
#[inline]
pub const fn all() -> Self {
Self {
bits: Self::INNER_INDEX_BIT_COUNT_MASK.bits | Self::MAP_ENTRY_SIZE_MASK.bits,
}
}
/// Returns the raw value of the flags currently stored.
#[inline]
pub const fn bits(&self) -> u8 {
self.bits
}
/// Convert from underlying bit representation, unless that
/// representation contains bits that do not correspond to a flag.
#[inline]
pub const fn from_bits(bits: u8) -> Option<Self> {
if (bits & !Self::all().bits()) == 0 {
Some(Self { bits })
} else {
None
}
}
/// Convert from underlying bit representation, dropping any bits
/// that do not correspond to flags.
#[inline]
pub const fn from_bits_truncate(bits: u8) -> Self {
Self {
bits: bits & Self::all().bits,
}
}
/// Returns `true` if no flags are currently stored.
#[inline]
pub const fn is_empty(&self) -> bool {
self.bits() == Self::empty().bits()
}
/// Returns `true` if there are flags common to both `self` and `other`.
#[inline]
pub const fn intersects(&self, other: Self) -> bool {
!(Self {
bits: self.bits & other.bits,
})
.is_empty()
}
/// Returns `true` if all of the flags in `other` are contained within `self`.
#[inline]
pub const fn contains(&self, other: Self) -> bool {
(self.bits & other.bits) == other.bits
}
/// Inserts the specified flags in-place.
#[inline]
pub fn insert(&mut self, other: Self) {
self.bits |= other.bits;
}
/// Removes the specified flags in-place.
#[inline]
pub fn remove(&mut self, other: Self) {
self.bits &= !other.bits;
}
/// Toggles the specified flags in-place.
#[inline]
pub fn toggle(&mut self, other: Self) {
self.bits ^= other.bits;
}
/// Returns the intersection between the flags in `self` and
/// `other`.
///
/// Specifically, the returned set contains only the flags which are
/// present in *both* `self` *and* `other`.
///
/// This is equivalent to using the `&` operator (e.g.
/// [`ops::BitAnd`]), as in `flags & other`.
///
/// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
#[inline]
#[must_use]
pub const fn intersection(self, other: Self) -> Self {
Self {
bits: self.bits & other.bits,
}
}
/// Returns the union of between the flags in `self` and `other`.
///
/// Specifically, the returned set contains all flags which are
/// present in *either* `self` *or* `other`, including any which are
/// present in both.
///
/// This is equivalent to using the `|` operator (e.g.
/// [`ops::BitOr`]), as in `flags | other`.
///
/// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
#[inline]
#[must_use]
pub const fn union(self, other: Self) -> Self {
Self {
bits: self.bits | other.bits,
}
}
/// Returns the difference between the flags in `self` and `other`.
///
/// Specifically, the returned set contains all flags present in
/// `self`, except for the ones present in `other`.
///
/// It is also conceptually equivalent to the "bit-clear" operation:
/// `flags & !other` (and this syntax is also supported).
///
/// This is equivalent to using the `-` operator (e.g.
/// [`ops::Sub`]), as in `flags - other`.
///
/// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
#[inline]
#[must_use]
pub const fn difference(self, other: Self) -> Self {
Self {
bits: self.bits & !other.bits,
}
}
}
impl std::ops::BitOr for EntryFormat {
type Output = Self;
/// Returns the union of the two sets of flags.
#[inline]
fn bitor(self, other: EntryFormat) -> Self {
Self {
bits: self.bits | other.bits,
}
}
}
impl std::ops::BitOrAssign for EntryFormat {
/// Adds the set of flags.
#[inline]
fn bitor_assign(&mut self, other: Self) {
self.bits |= other.bits;
}
}
impl std::ops::BitXor for EntryFormat {
type Output = Self;
/// Returns the left flags, but with all the right flags toggled.
#[inline]
fn bitxor(self, other: Self) -> Self {
Self {
bits: self.bits ^ other.bits,
}
}
}
impl std::ops::BitXorAssign for EntryFormat {
/// Toggles the set of flags.
#[inline]
fn bitxor_assign(&mut self, other: Self) {
self.bits ^= other.bits;
}
}
impl std::ops::BitAnd for EntryFormat {
type Output = Self;
/// Returns the intersection between the two sets of flags.
#[inline]
fn bitand(self, other: Self) -> Self {
Self {
bits: self.bits & other.bits,
}
}
}
impl std::ops::BitAndAssign for EntryFormat {
/// Disables all flags disabled in the set.
#[inline]
fn bitand_assign(&mut self, other: Self) {
self.bits &= other.bits;
}
}
impl std::ops::Sub for EntryFormat {
type Output = Self;
/// Returns the set difference of the two sets of flags.
#[inline]
fn sub(self, other: Self) -> Self {
Self {
bits: self.bits & !other.bits,
}
}
}
impl std::ops::SubAssign for EntryFormat {
/// Disables all flags enabled in the set.
#[inline]
fn sub_assign(&mut self, other: Self) {
self.bits &= !other.bits;
}
}
impl std::ops::Not for EntryFormat {
type Output = Self;
/// Returns the complement of this set of flags.
#[inline]
fn not(self) -> Self {
Self { bits: !self.bits } & Self::all()
}
}
impl std::fmt::Debug for EntryFormat {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let members: &[(&str, Self)] = &[
(
"INNER_INDEX_BIT_COUNT_MASK",
Self::INNER_INDEX_BIT_COUNT_MASK,
),
("MAP_ENTRY_SIZE_MASK", Self::MAP_ENTRY_SIZE_MASK),
];
let mut first = true;
for (name, value) in members {
if self.contains(*value) {
if !first {
f.write_str(" | ")?;
}
first = false;
f.write_str(name)?;
}
}
if first {
f.write_str("(empty)")?;
}
Ok(())
}
}
impl std::fmt::Binary for EntryFormat {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::Binary::fmt(&self.bits, f)
}
}
impl std::fmt::Octal for EntryFormat {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::Octal::fmt(&self.bits, f)
}
}
impl std::fmt::LowerHex for EntryFormat {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::LowerHex::fmt(&self.bits, f)
}
}
impl std::fmt::UpperHex for EntryFormat {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::UpperHex::fmt(&self.bits, f)
}
}
impl font_types::Scalar for EntryFormat {
type Raw = <u8 as font_types::Scalar>::Raw;
fn to_raw(self) -> Self::Raw {
self.bits().to_raw()
}
fn from_raw(raw: Self::Raw) -> Self {
let t = <u8>::from_raw(raw);
Self::from_bits_truncate(t)
}
}
#[cfg(feature = "experimental_traverse")]
impl<'a> From<EntryFormat> for FieldType<'a> {
fn from(src: EntryFormat) -> FieldType<'a> {
src.bits().into()
}
}
/// The [VariationRegionList](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#variation-regions) table
#[derive(Debug, Clone, Copy)]
#[doc(hidden)]
pub struct VariationRegionListMarker {
variation_regions_byte_len: usize,
}
impl VariationRegionListMarker {
pub fn axis_count_byte_range(&self) -> Range<usize> {
let start = 0;
start..start + u16::RAW_BYTE_LEN
}
pub fn region_count_byte_range(&self) -> Range<usize> {
let start = self.axis_count_byte_range().end;
start..start + u16::RAW_BYTE_LEN
}
pub fn variation_regions_byte_range(&self) -> Range<usize> {
let start = self.region_count_byte_range().end;
start..start + self.variation_regions_byte_len
}
}
impl MinByteRange for VariationRegionListMarker {
fn min_byte_range(&self) -> Range<usize> {
0..self.variation_regions_byte_range().end
}
}
impl<'a> FontRead<'a> for VariationRegionList<'a> {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
let mut cursor = data.cursor();
let axis_count: u16 = cursor.read()?;
let region_count: u16 = cursor.read()?;
let variation_regions_byte_len = (region_count as usize)
.checked_mul(<VariationRegion as ComputeSize>::compute_size(&axis_count)?)
.ok_or(ReadError::OutOfBounds)?;
cursor.advance_by(variation_regions_byte_len);
cursor.finish(VariationRegionListMarker {
variation_regions_byte_len,
})
}
}
/// The [VariationRegionList](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#variation-regions) table
pub type VariationRegionList<'a> = TableRef<'a, VariationRegionListMarker>;
#[allow(clippy::needless_lifetimes)]
impl<'a> VariationRegionList<'a> {
/// The number of variation axes for this font. This must be the
/// same number as axisCount in the 'fvar' table.
pub fn axis_count(&self) -> u16 {
let range = self.shape.axis_count_byte_range();
self.data.read_at(range.start).unwrap()
}
/// The number of variation region tables in the variation region
/// list. Must be less than 32,768.
pub fn region_count(&self) -> u16 {
let range = self.shape.region_count_byte_range();
self.data.read_at(range.start).unwrap()
}
/// Array of variation regions.
pub fn variation_regions(&self) -> ComputedArray<'a, VariationRegion<'a>> {
let range = self.shape.variation_regions_byte_range();
self.data.read_with_args(range, &self.axis_count()).unwrap()
}
}
#[cfg(feature = "experimental_traverse")]
impl<'a> SomeTable<'a> for VariationRegionList<'a> {
fn type_name(&self) -> &str {
"VariationRegionList"
}
fn get_field(&self, idx: usize) -> Option<Field<'a>> {
match idx {
0usize => Some(Field::new("axis_count", self.axis_count())),
1usize => Some(Field::new("region_count", self.region_count())),
2usize => Some(Field::new(
"variation_regions",
traversal::FieldType::computed_array(
"VariationRegion",
self.variation_regions(),
self.offset_data(),
),
)),
_ => None,
}
}
}
#[cfg(feature = "experimental_traverse")]
#[allow(clippy::needless_lifetimes)]
impl<'a> std::fmt::Debug for VariationRegionList<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
(self as &dyn SomeTable<'a>).fmt(f)
}
}
/// The [VariationRegion](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#variation-regions) record
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct VariationRegion<'a> {
/// Array of region axis coordinates records, in the order of axes
/// given in the 'fvar' table.
pub region_axes: &'a [RegionAxisCoordinates],
}
impl<'a> VariationRegion<'a> {
/// Array of region axis coordinates records, in the order of axes
/// given in the 'fvar' table.
pub fn region_axes(&self) -> &'a [RegionAxisCoordinates] {
self.region_axes
}
}
impl ReadArgs for VariationRegion<'_> {
type Args = u16;
}
impl ComputeSize for VariationRegion<'_> {
#[allow(clippy::needless_question_mark)]
fn compute_size(args: &u16) -> Result<usize, ReadError> {
let axis_count = *args;
Ok((axis_count as usize)
.checked_mul(RegionAxisCoordinates::RAW_BYTE_LEN)
.ok_or(ReadError::OutOfBounds)?)
}
}
impl<'a> FontReadWithArgs<'a> for VariationRegion<'a> {
fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> {
let mut cursor = data.cursor();
let axis_count = *args;
Ok(Self {
region_axes: cursor.read_array(axis_count as usize)?,
})
}
}
#[allow(clippy::needless_lifetimes)]
impl<'a> VariationRegion<'a> {
/// A constructor that requires additional arguments.
///
/// This type requires some external state in order to be
/// parsed.
pub fn read(data: FontData<'a>, axis_count: u16) -> Result<Self, ReadError> {
let args = axis_count;
Self::read_with_args(data, &args)
}
}
#[cfg(feature = "experimental_traverse")]
impl<'a> SomeRecord<'a> for VariationRegion<'a> {
fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
RecordResolver {
name: "VariationRegion",
get_field: Box::new(move |idx, _data| match idx {
0usize => Some(Field::new(
"region_axes",
traversal::FieldType::array_of_records(
stringify!(RegionAxisCoordinates),
self.region_axes(),
_data,
),
)),
_ => None,
}),
data,
}
}
}
/// The [RegionAxisCoordinates](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#variation-regions) record
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct RegionAxisCoordinates {
/// The region start coordinate value for the current axis.
pub start_coord: BigEndian<F2Dot14>,
/// The region peak coordinate value for the current axis.
pub peak_coord: BigEndian<F2Dot14>,
/// The region end coordinate value for the current axis.
pub end_coord: BigEndian<F2Dot14>,
}
impl RegionAxisCoordinates {
/// The region start coordinate value for the current axis.
pub fn start_coord(&self) -> F2Dot14 {
self.start_coord.get()
}
/// The region peak coordinate value for the current axis.
pub fn peak_coord(&self) -> F2Dot14 {
self.peak_coord.get()
}
/// The region end coordinate value for the current axis.
pub fn end_coord(&self) -> F2Dot14 {
self.end_coord.get()
}
}
impl FixedSize for RegionAxisCoordinates {
const RAW_BYTE_LEN: usize =
F2Dot14::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN;
}
#[cfg(feature = "experimental_traverse")]
impl<'a> SomeRecord<'a> for RegionAxisCoordinates {
fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
RecordResolver {
name: "RegionAxisCoordinates",
get_field: Box::new(move |idx, _data| match idx {
0usize => Some(Field::new("start_coord", self.start_coord())),
1usize => Some(Field::new("peak_coord", self.peak_coord())),
2usize => Some(Field::new("end_coord", self.end_coord())),
_ => None,
}),
data,
}
}
}
/// The [ItemVariationStore](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#item-variation-store-header-and-item-variation-data-subtables) table
#[derive(Debug, Clone, Copy)]
#[doc(hidden)]
pub struct ItemVariationStoreMarker {
item_variation_data_offsets_byte_len: usize,
}
impl ItemVariationStoreMarker {
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
start..start + u16::RAW_BYTE_LEN
}
pub fn variation_region_list_offset_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
start..start + Offset32::RAW_BYTE_LEN
}
pub fn item_variation_data_count_byte_range(&self) -> Range<usize> {
let start = self.variation_region_list_offset_byte_range().end;
start..start + u16::RAW_BYTE_LEN
}
pub fn item_variation_data_offsets_byte_range(&self) -> Range<usize> {
let start = self.item_variation_data_count_byte_range().end;
start..start + self.item_variation_data_offsets_byte_len
}
}
impl MinByteRange for ItemVariationStoreMarker {
fn min_byte_range(&self) -> Range<usize> {
0..self.item_variation_data_offsets_byte_range().end
}
}
impl<'a> FontRead<'a> for ItemVariationStore<'a> {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
let mut cursor = data.cursor();
cursor.advance::<u16>();
cursor.advance::<Offset32>();
let item_variation_data_count: u16 = cursor.read()?;
let item_variation_data_offsets_byte_len = (item_variation_data_count as usize)
.checked_mul(Offset32::RAW_BYTE_LEN)
.ok_or(ReadError::OutOfBounds)?;
cursor.advance_by(item_variation_data_offsets_byte_len);
cursor.finish(ItemVariationStoreMarker {
item_variation_data_offsets_byte_len,
})
}
}
/// The [ItemVariationStore](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#item-variation-store-header-and-item-variation-data-subtables) table
pub type ItemVariationStore<'a> = TableRef<'a, ItemVariationStoreMarker>;
#[allow(clippy::needless_lifetimes)]
impl<'a> ItemVariationStore<'a> {
/// Format— set to 1
pub fn format(&self) -> u16 {
let range = self.shape.format_byte_range();
self.data.read_at(range.start).unwrap()
}
/// Offset in bytes from the start of the item variation store to
/// the variation region list.
pub fn variation_region_list_offset(&self) -> Offset32 {
let range = self.shape.variation_region_list_offset_byte_range();
self.data.read_at(range.start).unwrap()
}
/// Attempt to resolve [`variation_region_list_offset`][Self::variation_region_list_offset].
pub fn variation_region_list(&self) -> Result<VariationRegionList<'a>, ReadError> {
let data = self.data;
self.variation_region_list_offset().resolve(data)
}
/// The number of item variation data subtables.
pub fn item_variation_data_count(&self) -> u16 {
let range = self.shape.item_variation_data_count_byte_range();
self.data.read_at(range.start).unwrap()
}
/// Offsets in bytes from the start of the item variation store to
/// each item variation data subtable.
pub fn item_variation_data_offsets(&self) -> &'a [BigEndian<Nullable<Offset32>>] {
let range = self.shape.item_variation_data_offsets_byte_range();
self.data.read_array(range).unwrap()
}
/// A dynamically resolving wrapper for [`item_variation_data_offsets`][Self::item_variation_data_offsets].
pub fn item_variation_data(
&self,
) -> ArrayOfNullableOffsets<'a, ItemVariationData<'a>, Offset32> {
let data = self.data;
let offsets = self.item_variation_data_offsets();
ArrayOfNullableOffsets::new(offsets, data, ())
}
}
#[cfg(feature = "experimental_traverse")]
impl<'a> SomeTable<'a> for ItemVariationStore<'a> {
fn type_name(&self) -> &str {
"ItemVariationStore"
}
fn get_field(&self, idx: usize) -> Option<Field<'a>> {
match idx {
0usize => Some(Field::new("format", self.format())),
1usize => Some(Field::new(
"variation_region_list_offset",
FieldType::offset(
self.variation_region_list_offset(),
self.variation_region_list(),
),
)),
2usize => Some(Field::new(
"item_variation_data_count",
self.item_variation_data_count(),
)),
3usize => Some({
let data = self.data;
Field::new(
"item_variation_data_offsets",
FieldType::array_of_offsets(
better_type_name::<ItemVariationData>(),
self.item_variation_data_offsets(),
move |off| {
let target = off.get().resolve::<ItemVariationData>(data);
FieldType::offset(off.get(), target)
},
),
)
}),
_ => None,
}
}
}
#[cfg(feature = "experimental_traverse")]
#[allow(clippy::needless_lifetimes)]
impl<'a> std::fmt::Debug for ItemVariationStore<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
(self as &dyn SomeTable<'a>).fmt(f)
}
}
/// The [ItemVariationData](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#item-variation-store-header-and-item-variation-data-subtables) subtable
#[derive(Debug, Clone, Copy)]
#[doc(hidden)]
pub struct ItemVariationDataMarker {
region_indexes_byte_len: usize,
delta_sets_byte_len: usize,
}
impl ItemVariationDataMarker {
pub fn item_count_byte_range(&self) -> Range<usize> {
let start = 0;
start..start + u16::RAW_BYTE_LEN
}
pub fn word_delta_count_byte_range(&self) -> Range<usize> {
let start = self.item_count_byte_range().end;
start..start + u16::RAW_BYTE_LEN
}
pub fn region_index_count_byte_range(&self) -> Range<usize> {
let start = self.word_delta_count_byte_range().end;
start..start + u16::RAW_BYTE_LEN
}
pub fn region_indexes_byte_range(&self) -> Range<usize> {
let start = self.region_index_count_byte_range().end;
start..start + self.region_indexes_byte_len
}
pub fn delta_sets_byte_range(&self) -> Range<usize> {
let start = self.region_indexes_byte_range().end;
start..start + self.delta_sets_byte_len
}
}
impl MinByteRange for ItemVariationDataMarker {
fn min_byte_range(&self) -> Range<usize> {
0..self.delta_sets_byte_range().end
}
}
impl<'a> FontRead<'a> for ItemVariationData<'a> {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
let mut cursor = data.cursor();
let item_count: u16 = cursor.read()?;
let word_delta_count: u16 = cursor.read()?;
let region_index_count: u16 = cursor.read()?;
let region_indexes_byte_len = (region_index_count as usize)
.checked_mul(u16::RAW_BYTE_LEN)
.ok_or(ReadError::OutOfBounds)?;
cursor.advance_by(region_indexes_byte_len);
let delta_sets_byte_len =
(ItemVariationData::delta_sets_len(item_count, word_delta_count, region_index_count))
.checked_mul(u8::RAW_BYTE_LEN)
.ok_or(ReadError::OutOfBounds)?;
cursor.advance_by(delta_sets_byte_len);
cursor.finish(ItemVariationDataMarker {
region_indexes_byte_len,
delta_sets_byte_len,
})
}
}
/// The [ItemVariationData](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#item-variation-store-header-and-item-variation-data-subtables) subtable
pub type ItemVariationData<'a> = TableRef<'a, ItemVariationDataMarker>;
#[allow(clippy::needless_lifetimes)]
impl<'a> ItemVariationData<'a> {
/// The number of delta sets for distinct items.
pub fn item_count(&self) -> u16 {
let range = self.shape.item_count_byte_range();
self.data.read_at(range.start).unwrap()
}
/// A packed field: the high bit is a flag—see details below.
pub fn word_delta_count(&self) -> u16 {
let range = self.shape.word_delta_count_byte_range();
self.data.read_at(range.start).unwrap()
}
/// The number of variation regions referenced.
pub fn region_index_count(&self) -> u16 {
let range = self.shape.region_index_count_byte_range();
self.data.read_at(range.start).unwrap()
}
/// Array of indices into the variation region list for the regions
/// referenced by this item variation data table.
pub fn region_indexes(&self) -> &'a [BigEndian<u16>] {
let range = self.shape.region_indexes_byte_range();
self.data.read_array(range).unwrap()
}
/// Delta-set rows.
pub fn delta_sets(&self) -> &'a [u8] {
let range = self.shape.delta_sets_byte_range();
self.data.read_array(range).unwrap()
}
}
#[cfg(feature = "experimental_traverse")]
impl<'a> SomeTable<'a> for ItemVariationData<'a> {
fn type_name(&self) -> &str {
"ItemVariationData"
}
fn get_field(&self, idx: usize) -> Option<Field<'a>> {
match idx {
0usize => Some(Field::new("item_count", self.item_count())),
1usize => Some(Field::new("word_delta_count", self.word_delta_count())),
2usize => Some(Field::new("region_index_count", self.region_index_count())),
3usize => Some(Field::new("region_indexes", self.region_indexes())),
4usize => Some(Field::new("delta_sets", self.delta_sets())),
_ => None,
}
}
}
#[cfg(feature = "experimental_traverse")]
#[allow(clippy::needless_lifetimes)]
impl<'a> std::fmt::Debug for ItemVariationData<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
(self as &dyn SomeTable<'a>).fmt(f)
}
}