#[allow(unused_imports)]
use crate::codegen_prelude::*;
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct BitmapSize {
pub index_subtable_list_offset: BigEndian<u32>,
pub index_subtable_list_size: BigEndian<u32>,
pub number_of_index_subtables: BigEndian<u32>,
pub color_ref: BigEndian<u32>,
pub hori: SbitLineMetrics,
pub vert: SbitLineMetrics,
pub start_glyph_index: BigEndian<GlyphId16>,
pub end_glyph_index: BigEndian<GlyphId16>,
pub ppem_x: u8,
pub ppem_y: u8,
pub bit_depth: u8,
pub flags: BigEndian<BitmapFlags>,
}
impl BitmapSize {
pub fn index_subtable_list_offset(&self) -> u32 {
self.index_subtable_list_offset.get()
}
pub fn index_subtable_list_size(&self) -> u32 {
self.index_subtable_list_size.get()
}
pub fn number_of_index_subtables(&self) -> u32 {
self.number_of_index_subtables.get()
}
pub fn color_ref(&self) -> u32 {
self.color_ref.get()
}
pub fn hori(&self) -> &SbitLineMetrics {
&self.hori
}
pub fn vert(&self) -> &SbitLineMetrics {
&self.vert
}
pub fn start_glyph_index(&self) -> GlyphId16 {
self.start_glyph_index.get()
}
pub fn end_glyph_index(&self) -> GlyphId16 {
self.end_glyph_index.get()
}
pub fn ppem_x(&self) -> u8 {
self.ppem_x
}
pub fn ppem_y(&self) -> u8 {
self.ppem_y
}
pub fn bit_depth(&self) -> u8 {
self.bit_depth
}
pub fn flags(&self) -> BitmapFlags {
self.flags.get()
}
}
impl FixedSize for BitmapSize {
const RAW_BYTE_LEN: usize = u32::RAW_BYTE_LEN
+ u32::RAW_BYTE_LEN
+ u32::RAW_BYTE_LEN
+ u32::RAW_BYTE_LEN
+ SbitLineMetrics::RAW_BYTE_LEN
+ SbitLineMetrics::RAW_BYTE_LEN
+ GlyphId16::RAW_BYTE_LEN
+ GlyphId16::RAW_BYTE_LEN
+ u8::RAW_BYTE_LEN
+ u8::RAW_BYTE_LEN
+ u8::RAW_BYTE_LEN
+ BitmapFlags::RAW_BYTE_LEN;
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct SbitLineMetrics {
pub ascender: BigEndian<i8>,
pub descender: BigEndian<i8>,
pub width_max: u8,
pub caret_slope_numerator: BigEndian<i8>,
pub caret_slope_denominator: u8,
pub caret_offset: BigEndian<i8>,
pub min_origin_sb: BigEndian<i8>,
pub min_advance_sb: BigEndian<i8>,
pub max_before_bl: BigEndian<i8>,
pub min_after_bl: BigEndian<i8>,
pub pad1: BigEndian<i8>,
pub pad2: BigEndian<i8>,
}
impl SbitLineMetrics {
pub fn ascender(&self) -> i8 {
self.ascender.get()
}
pub fn descender(&self) -> i8 {
self.descender.get()
}
pub fn width_max(&self) -> u8 {
self.width_max
}
pub fn caret_slope_numerator(&self) -> i8 {
self.caret_slope_numerator.get()
}
pub fn caret_slope_denominator(&self) -> u8 {
self.caret_slope_denominator
}
pub fn caret_offset(&self) -> i8 {
self.caret_offset.get()
}
pub fn min_origin_sb(&self) -> i8 {
self.min_origin_sb.get()
}
pub fn min_advance_sb(&self) -> i8 {
self.min_advance_sb.get()
}
pub fn max_before_bl(&self) -> i8 {
self.max_before_bl.get()
}
pub fn min_after_bl(&self) -> i8 {
self.min_after_bl.get()
}
pub fn pad1(&self) -> i8 {
self.pad1.get()
}
pub fn pad2(&self) -> i8 {
self.pad2.get()
}
}
impl FixedSize for SbitLineMetrics {
const RAW_BYTE_LEN: usize = i8::RAW_BYTE_LEN
+ i8::RAW_BYTE_LEN
+ u8::RAW_BYTE_LEN
+ i8::RAW_BYTE_LEN
+ u8::RAW_BYTE_LEN
+ i8::RAW_BYTE_LEN
+ i8::RAW_BYTE_LEN
+ i8::RAW_BYTE_LEN
+ i8::RAW_BYTE_LEN
+ i8::RAW_BYTE_LEN
+ i8::RAW_BYTE_LEN
+ i8::RAW_BYTE_LEN;
}
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck :: AnyBitPattern)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(transparent)]
pub struct BitmapFlags {
bits: u8,
}
impl BitmapFlags {
pub const HORIZONTAL_METRICS: Self = Self { bits: 0x01 };
pub const VERTICAL_METRICS: Self = Self { bits: 0x02 };
}
impl BitmapFlags {
#[inline]
pub const fn empty() -> Self {
Self { bits: 0 }
}
#[inline]
pub const fn all() -> Self {
Self {
bits: Self::HORIZONTAL_METRICS.bits | Self::VERTICAL_METRICS.bits,
}
}
#[inline]
pub const fn bits(&self) -> u8 {
self.bits
}
#[inline]
pub const fn from_bits(bits: u8) -> Option<Self> {
if (bits & !Self::all().bits()) == 0 {
Some(Self { bits })
} else {
None
}
}
#[inline]
pub const fn from_bits_truncate(bits: u8) -> Self {
Self {
bits: bits & Self::all().bits,
}
}
#[inline]
pub const fn is_empty(&self) -> bool {
self.bits() == Self::empty().bits()
}
#[inline]
pub const fn intersects(&self, other: Self) -> bool {
!(Self {
bits: self.bits & other.bits,
})
.is_empty()
}
#[inline]
pub const fn contains(&self, other: Self) -> bool {
(self.bits & other.bits) == other.bits
}
#[inline]
pub fn insert(&mut self, other: Self) {
self.bits |= other.bits;
}
#[inline]
pub fn remove(&mut self, other: Self) {
self.bits &= !other.bits;
}
#[inline]
pub fn toggle(&mut self, other: Self) {
self.bits ^= other.bits;
}
#[inline]
#[must_use]
pub const fn intersection(self, other: Self) -> Self {
Self {
bits: self.bits & other.bits,
}
}
#[inline]
#[must_use]
pub const fn union(self, other: Self) -> Self {
Self {
bits: self.bits | other.bits,
}
}
#[inline]
#[must_use]
pub const fn difference(self, other: Self) -> Self {
Self {
bits: self.bits & !other.bits,
}
}
}
impl std::ops::BitOr for BitmapFlags {
type Output = Self;
#[inline]
fn bitor(self, other: BitmapFlags) -> Self {
Self {
bits: self.bits | other.bits,
}
}
}
impl std::ops::BitOrAssign for BitmapFlags {
#[inline]
fn bitor_assign(&mut self, other: Self) {
self.bits |= other.bits;
}
}
impl std::ops::BitXor for BitmapFlags {
type Output = Self;
#[inline]
fn bitxor(self, other: Self) -> Self {
Self {
bits: self.bits ^ other.bits,
}
}
}
impl std::ops::BitXorAssign for BitmapFlags {
#[inline]
fn bitxor_assign(&mut self, other: Self) {
self.bits ^= other.bits;
}
}
impl std::ops::BitAnd for BitmapFlags {
type Output = Self;
#[inline]
fn bitand(self, other: Self) -> Self {
Self {
bits: self.bits & other.bits,
}
}
}
impl std::ops::BitAndAssign for BitmapFlags {
#[inline]
fn bitand_assign(&mut self, other: Self) {
self.bits &= other.bits;
}
}
impl std::ops::Sub for BitmapFlags {
type Output = Self;
#[inline]
fn sub(self, other: Self) -> Self {
Self {
bits: self.bits & !other.bits,
}
}
}
impl std::ops::SubAssign for BitmapFlags {
#[inline]
fn sub_assign(&mut self, other: Self) {
self.bits &= !other.bits;
}
}
impl std::ops::Not for BitmapFlags {
type Output = Self;
#[inline]
fn not(self) -> Self {
Self { bits: !self.bits } & Self::all()
}
}
impl std::fmt::Debug for BitmapFlags {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let members: &[(&str, Self)] = &[
("HORIZONTAL_METRICS", Self::HORIZONTAL_METRICS),
("VERTICAL_METRICS", Self::VERTICAL_METRICS),
];
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 BitmapFlags {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::Binary::fmt(&self.bits, f)
}
}
impl std::fmt::Octal for BitmapFlags {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::Octal::fmt(&self.bits, f)
}
}
impl std::fmt::LowerHex for BitmapFlags {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::LowerHex::fmt(&self.bits, f)
}
}
impl std::fmt::UpperHex for BitmapFlags {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::UpperHex::fmt(&self.bits, f)
}
}
impl font_types::Scalar for BitmapFlags {
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)
}
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct BigGlyphMetrics {
pub height: u8,
pub width: u8,
pub hori_bearing_x: BigEndian<i8>,
pub hori_bearing_y: BigEndian<i8>,
pub hori_advance: u8,
pub vert_bearing_x: BigEndian<i8>,
pub vert_bearing_y: BigEndian<i8>,
pub vert_advance: u8,
}
impl BigGlyphMetrics {
pub fn height(&self) -> u8 {
self.height
}
pub fn width(&self) -> u8 {
self.width
}
pub fn hori_bearing_x(&self) -> i8 {
self.hori_bearing_x.get()
}
pub fn hori_bearing_y(&self) -> i8 {
self.hori_bearing_y.get()
}
pub fn hori_advance(&self) -> u8 {
self.hori_advance
}
pub fn vert_bearing_x(&self) -> i8 {
self.vert_bearing_x.get()
}
pub fn vert_bearing_y(&self) -> i8 {
self.vert_bearing_y.get()
}
pub fn vert_advance(&self) -> u8 {
self.vert_advance
}
}
impl FixedSize for BigGlyphMetrics {
const RAW_BYTE_LEN: usize = u8::RAW_BYTE_LEN
+ u8::RAW_BYTE_LEN
+ i8::RAW_BYTE_LEN
+ i8::RAW_BYTE_LEN
+ u8::RAW_BYTE_LEN
+ i8::RAW_BYTE_LEN
+ i8::RAW_BYTE_LEN
+ u8::RAW_BYTE_LEN;
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct SmallGlyphMetrics {
pub height: u8,
pub width: u8,
pub bearing_x: BigEndian<i8>,
pub bearing_y: BigEndian<i8>,
pub advance: u8,
}
impl SmallGlyphMetrics {
pub fn height(&self) -> u8 {
self.height
}
pub fn width(&self) -> u8 {
self.width
}
pub fn bearing_x(&self) -> i8 {
self.bearing_x.get()
}
pub fn bearing_y(&self) -> i8 {
self.bearing_y.get()
}
pub fn advance(&self) -> u8 {
self.advance
}
}
impl FixedSize for SmallGlyphMetrics {
const RAW_BYTE_LEN: usize = u8::RAW_BYTE_LEN
+ u8::RAW_BYTE_LEN
+ i8::RAW_BYTE_LEN
+ i8::RAW_BYTE_LEN
+ u8::RAW_BYTE_LEN;
}
impl<'a> MinByteRange<'a> for IndexSubtableList<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.index_subtable_records_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.data.as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for IndexSubtableList<'_> {
type Args = u32;
}
impl<'a> FontRead<'a> for IndexSubtableList<'a> {
fn read_with_args(data: FontData<'a>, args: u32) -> Result<Self, ReadError> {
let number_of_index_subtables = args;
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
Ok(Self {
data,
number_of_index_subtables,
})
}
}
impl<'a> IndexSubtableList<'a> {
pub fn read(data: FontData<'a>, number_of_index_subtables: u32) -> Result<Self, ReadError> {
let args = number_of_index_subtables;
Self::read_with_args(data, args)
}
}
#[derive(Clone)]
pub struct IndexSubtableList<'a> {
data: FontData<'a>,
number_of_index_subtables: u32,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> IndexSubtableList<'a> {
pub const MIN_SIZE: usize = 0;
basic_table_impls!(impl_the_methods);
pub fn index_subtable_records(&self) -> &'a [IndexSubtableRecord] {
let range = self.index_subtable_records_byte_range();
self.data.read_array(range).ok().unwrap_or_default()
}
pub(crate) fn number_of_index_subtables(&self) -> u32 {
self.number_of_index_subtables
}
pub fn index_subtable_records_byte_range(&self) -> Range<usize> {
let number_of_index_subtables = self.number_of_index_subtables();
let start = 0;
let end = start
+ (transforms::to_usize(number_of_index_subtables))
.saturating_mul(IndexSubtableRecord::RAW_BYTE_LEN);
start..end
}
}
#[allow(clippy::absurd_extreme_comparisons)]
const _: () = assert!(FontData::default_data_long_enough(
IndexSubtableList::MIN_SIZE
));
impl Default for IndexSubtableList<'_> {
fn default() -> Self {
Self {
data: FontData::default_table_data(),
number_of_index_subtables: Default::default(),
}
}
}
#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct IndexSubtableRecord {
pub first_glyph_index: BigEndian<GlyphId16>,
pub last_glyph_index: BigEndian<GlyphId16>,
pub index_subtable_offset: BigEndian<Offset32>,
}
impl IndexSubtableRecord {
pub fn first_glyph_index(&self) -> GlyphId16 {
self.first_glyph_index.get()
}
pub fn last_glyph_index(&self) -> GlyphId16 {
self.last_glyph_index.get()
}
pub fn index_subtable_offset(&self) -> Offset32 {
self.index_subtable_offset.get()
}
pub fn index_subtable<'a>(&self, data: FontData<'a>) -> Result<IndexSubtable<'a>, ReadError> {
let args = (self.last_glyph_index(), self.first_glyph_index());
self.index_subtable_offset().resolve_with_args(data, args)
}
}
impl FixedSize for IndexSubtableRecord {
const RAW_BYTE_LEN: usize =
GlyphId16::RAW_BYTE_LEN + GlyphId16::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN;
}
impl Format<u16> for IndexSubtable1<'_> {
const FORMAT: u16 = 1;
}
impl<'a> MinByteRange<'a> for IndexSubtable1<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.sbit_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.data.as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for IndexSubtable1<'_> {
type Args = (GlyphId16, GlyphId16);
}
impl<'a> FontRead<'a> for IndexSubtable1<'a> {
fn read_with_args(data: FontData<'a>, args: (GlyphId16, GlyphId16)) -> Result<Self, ReadError> {
let (last_glyph_index, first_glyph_index) = args;
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
Ok(Self {
data,
last_glyph_index,
first_glyph_index,
})
}
}
impl<'a> IndexSubtable1<'a> {
pub fn read(
data: FontData<'a>,
last_glyph_index: GlyphId16,
first_glyph_index: GlyphId16,
) -> Result<Self, ReadError> {
let args = (last_glyph_index, first_glyph_index);
Self::read_with_args(data, args)
}
}
#[derive(Clone)]
pub struct IndexSubtable1<'a> {
data: FontData<'a>,
last_glyph_index: GlyphId16,
first_glyph_index: GlyphId16,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> IndexSubtable1<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn index_format(&self) -> u16 {
let range = self.index_format_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn image_format(&self) -> u16 {
let range = self.image_format_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn image_data_offset(&self) -> u32 {
let range = self.image_data_offset_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn sbit_offsets(&self) -> &'a [BigEndian<u32>] {
let range = self.sbit_offsets_byte_range();
self.data.read_array(range).ok().unwrap_or_default()
}
pub(crate) fn last_glyph_index(&self) -> GlyphId16 {
self.last_glyph_index
}
pub(crate) fn first_glyph_index(&self) -> GlyphId16 {
self.first_glyph_index
}
pub fn index_format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn image_format_byte_range(&self) -> Range<usize> {
let start = self.index_format_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn image_data_offset_byte_range(&self) -> Range<usize> {
let start = self.image_format_byte_range().end;
let end = start + u32::RAW_BYTE_LEN;
start..end
}
pub fn sbit_offsets_byte_range(&self) -> Range<usize> {
let last_glyph_index = self.last_glyph_index();
let first_glyph_index = self.first_glyph_index();
let start = self.image_data_offset_byte_range().end;
let end = start
+ (transforms::subtract_add_two(last_glyph_index, first_glyph_index))
.saturating_mul(u32::RAW_BYTE_LEN);
start..end
}
}
const _: () = assert!(FontData::default_data_long_enough(IndexSubtable1::MIN_SIZE));
impl Default for IndexSubtable1<'_> {
fn default() -> Self {
Self {
data: FontData::default_format_1_u16_table_data(),
last_glyph_index: Default::default(),
first_glyph_index: Default::default(),
}
}
}
impl Format<u16> for IndexSubtable2<'_> {
const FORMAT: u16 = 2;
}
impl<'a> MinByteRange<'a> for IndexSubtable2<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.big_metrics_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.data.as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for IndexSubtable2<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for IndexSubtable2<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
Ok(Self { data })
}
}
#[derive(Clone)]
pub struct IndexSubtable2<'a> {
data: FontData<'a>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> IndexSubtable2<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN
+ u16::RAW_BYTE_LEN
+ u32::RAW_BYTE_LEN
+ u32::RAW_BYTE_LEN
+ BigGlyphMetrics::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn index_format(&self) -> u16 {
let range = self.index_format_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn image_format(&self) -> u16 {
let range = self.image_format_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn image_data_offset(&self) -> u32 {
let range = self.image_data_offset_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn image_size(&self) -> u32 {
let range = self.image_size_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn big_metrics(&self) -> &'a BigGlyphMetrics {
let range = self.big_metrics_byte_range();
self.data.read_ref_at(range.start).ok().unwrap()
}
pub fn index_format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn image_format_byte_range(&self) -> Range<usize> {
let start = self.index_format_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn image_data_offset_byte_range(&self) -> Range<usize> {
let start = self.image_format_byte_range().end;
let end = start + u32::RAW_BYTE_LEN;
start..end
}
pub fn image_size_byte_range(&self) -> Range<usize> {
let start = self.image_data_offset_byte_range().end;
let end = start + u32::RAW_BYTE_LEN;
start..end
}
pub fn big_metrics_byte_range(&self) -> Range<usize> {
let start = self.image_size_byte_range().end;
let end = start + BigGlyphMetrics::RAW_BYTE_LEN;
start..end
}
}
impl Format<u16> for IndexSubtable3<'_> {
const FORMAT: u16 = 3;
}
impl<'a> MinByteRange<'a> for IndexSubtable3<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.sbit_offsets_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.data.as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for IndexSubtable3<'_> {
type Args = (GlyphId16, GlyphId16);
}
impl<'a> FontRead<'a> for IndexSubtable3<'a> {
fn read_with_args(data: FontData<'a>, args: (GlyphId16, GlyphId16)) -> Result<Self, ReadError> {
let (last_glyph_index, first_glyph_index) = args;
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
Ok(Self {
data,
last_glyph_index,
first_glyph_index,
})
}
}
impl<'a> IndexSubtable3<'a> {
pub fn read(
data: FontData<'a>,
last_glyph_index: GlyphId16,
first_glyph_index: GlyphId16,
) -> Result<Self, ReadError> {
let args = (last_glyph_index, first_glyph_index);
Self::read_with_args(data, args)
}
}
#[derive(Clone)]
pub struct IndexSubtable3<'a> {
data: FontData<'a>,
last_glyph_index: GlyphId16,
first_glyph_index: GlyphId16,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> IndexSubtable3<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn index_format(&self) -> u16 {
let range = self.index_format_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn image_format(&self) -> u16 {
let range = self.image_format_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn image_data_offset(&self) -> u32 {
let range = self.image_data_offset_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn sbit_offsets(&self) -> &'a [BigEndian<u16>] {
let range = self.sbit_offsets_byte_range();
self.data.read_array(range).ok().unwrap_or_default()
}
pub(crate) fn last_glyph_index(&self) -> GlyphId16 {
self.last_glyph_index
}
pub(crate) fn first_glyph_index(&self) -> GlyphId16 {
self.first_glyph_index
}
pub fn index_format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn image_format_byte_range(&self) -> Range<usize> {
let start = self.index_format_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn image_data_offset_byte_range(&self) -> Range<usize> {
let start = self.image_format_byte_range().end;
let end = start + u32::RAW_BYTE_LEN;
start..end
}
pub fn sbit_offsets_byte_range(&self) -> Range<usize> {
let last_glyph_index = self.last_glyph_index();
let first_glyph_index = self.first_glyph_index();
let start = self.image_data_offset_byte_range().end;
let end = start
+ (transforms::subtract_add_two(last_glyph_index, first_glyph_index))
.saturating_mul(u16::RAW_BYTE_LEN);
start..end
}
}
impl Format<u16> for IndexSubtable4<'_> {
const FORMAT: u16 = 4;
}
impl<'a> MinByteRange<'a> for IndexSubtable4<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.glyph_array_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.data.as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for IndexSubtable4<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for IndexSubtable4<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
Ok(Self { data })
}
}
#[derive(Clone)]
pub struct IndexSubtable4<'a> {
data: FontData<'a>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> IndexSubtable4<'a> {
pub const MIN_SIZE: usize =
(u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn index_format(&self) -> u16 {
let range = self.index_format_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn image_format(&self) -> u16 {
let range = self.image_format_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn image_data_offset(&self) -> u32 {
let range = self.image_data_offset_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn num_glyphs(&self) -> u32 {
let range = self.num_glyphs_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn glyph_array(&self) -> &'a [GlyphIdOffsetPair] {
let range = self.glyph_array_byte_range();
self.data.read_array(range).ok().unwrap_or_default()
}
pub fn index_format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn image_format_byte_range(&self) -> Range<usize> {
let start = self.index_format_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn image_data_offset_byte_range(&self) -> Range<usize> {
let start = self.image_format_byte_range().end;
let end = start + u32::RAW_BYTE_LEN;
start..end
}
pub fn num_glyphs_byte_range(&self) -> Range<usize> {
let start = self.image_data_offset_byte_range().end;
let end = start + u32::RAW_BYTE_LEN;
start..end
}
pub fn glyph_array_byte_range(&self) -> Range<usize> {
let num_glyphs = self.num_glyphs();
let start = self.num_glyphs_byte_range().end;
let end = start
+ (transforms::add(num_glyphs, 1_usize))
.saturating_mul(GlyphIdOffsetPair::RAW_BYTE_LEN);
start..end
}
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct GlyphIdOffsetPair {
pub glyph_id: BigEndian<GlyphId16>,
pub sbit_offset: BigEndian<u16>,
}
impl GlyphIdOffsetPair {
pub fn glyph_id(&self) -> GlyphId16 {
self.glyph_id.get()
}
pub fn sbit_offset(&self) -> u16 {
self.sbit_offset.get()
}
}
impl FixedSize for GlyphIdOffsetPair {
const RAW_BYTE_LEN: usize = GlyphId16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
}
impl Format<u16> for IndexSubtable5<'_> {
const FORMAT: u16 = 5;
}
impl<'a> MinByteRange<'a> for IndexSubtable5<'a> {
fn min_byte_range(&self) -> Range<usize> {
0..self.glyph_array_byte_range().end
}
fn min_table_bytes(&self) -> &'a [u8] {
let range = self.min_byte_range();
self.data.as_bytes().get(range).unwrap_or_default()
}
}
impl ReadArgs for IndexSubtable5<'_> {
type Args = ();
}
impl<'a> FontRead<'a> for IndexSubtable5<'a> {
fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
#[allow(clippy::absurd_extreme_comparisons)]
if data.len() < Self::MIN_SIZE {
return Err(ReadError::OutOfBounds);
}
Ok(Self { data })
}
}
#[derive(Clone)]
pub struct IndexSubtable5<'a> {
data: FontData<'a>,
}
#[allow(clippy::needless_lifetimes)]
impl<'a> IndexSubtable5<'a> {
pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN
+ u16::RAW_BYTE_LEN
+ u32::RAW_BYTE_LEN
+ u32::RAW_BYTE_LEN
+ BigGlyphMetrics::RAW_BYTE_LEN
+ u32::RAW_BYTE_LEN);
basic_table_impls!(impl_the_methods);
pub fn index_format(&self) -> u16 {
let range = self.index_format_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn image_format(&self) -> u16 {
let range = self.image_format_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn image_data_offset(&self) -> u32 {
let range = self.image_data_offset_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn image_size(&self) -> u32 {
let range = self.image_size_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn big_metrics(&self) -> &'a BigGlyphMetrics {
let range = self.big_metrics_byte_range();
self.data.read_ref_at(range.start).ok().unwrap()
}
pub fn num_glyphs(&self) -> u32 {
let range = self.num_glyphs_byte_range();
self.data.read_at(range.start).ok().unwrap()
}
pub fn glyph_array(&self) -> &'a [BigEndian<GlyphId16>] {
let range = self.glyph_array_byte_range();
self.data.read_array(range).ok().unwrap_or_default()
}
pub fn index_format_byte_range(&self) -> Range<usize> {
let start = 0;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn image_format_byte_range(&self) -> Range<usize> {
let start = self.index_format_byte_range().end;
let end = start + u16::RAW_BYTE_LEN;
start..end
}
pub fn image_data_offset_byte_range(&self) -> Range<usize> {
let start = self.image_format_byte_range().end;
let end = start + u32::RAW_BYTE_LEN;
start..end
}
pub fn image_size_byte_range(&self) -> Range<usize> {
let start = self.image_data_offset_byte_range().end;
let end = start + u32::RAW_BYTE_LEN;
start..end
}
pub fn big_metrics_byte_range(&self) -> Range<usize> {
let start = self.image_size_byte_range().end;
let end = start + BigGlyphMetrics::RAW_BYTE_LEN;
start..end
}
pub fn num_glyphs_byte_range(&self) -> Range<usize> {
let start = self.big_metrics_byte_range().end;
let end = start + u32::RAW_BYTE_LEN;
start..end
}
pub fn glyph_array_byte_range(&self) -> Range<usize> {
let num_glyphs = self.num_glyphs();
let start = self.num_glyphs_byte_range().end;
let end =
start + (transforms::to_usize(num_glyphs)).saturating_mul(GlyphId16::RAW_BYTE_LEN);
start..end
}
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct BdtComponent {
pub glyph_id: BigEndian<GlyphId16>,
pub x_offset: BigEndian<i8>,
pub y_offset: BigEndian<i8>,
}
impl BdtComponent {
pub fn glyph_id(&self) -> GlyphId16 {
self.glyph_id.get()
}
pub fn x_offset(&self) -> i8 {
self.x_offset.get()
}
pub fn y_offset(&self) -> i8 {
self.y_offset.get()
}
}
impl FixedSize for BdtComponent {
const RAW_BYTE_LEN: usize = GlyphId16::RAW_BYTE_LEN + i8::RAW_BYTE_LEN + i8::RAW_BYTE_LEN;
}