ttf_parser/tables/
mvar.rsuse crate::{Tag, NormalizedCoordinate};
use crate::parser::{Stream, FromData, Offset, Offset16, LazyArray16};
use crate::var_store::ItemVariationStore;
#[derive(Clone, Copy)]
struct ValueRecord {
value_tag: Tag,
delta_set_outer_index: u16,
delta_set_inner_index: u16,
}
impl FromData for ValueRecord {
const SIZE: usize = 8;
#[inline]
fn parse(data: &[u8]) -> Option<Self> {
let mut s = Stream::new(data);
Some(ValueRecord {
value_tag: s.read::<Tag>()?,
delta_set_outer_index: s.read::<u16>()?,
delta_set_inner_index: s.read::<u16>()?,
})
}
}
#[derive(Clone, Copy)]
pub(crate) struct Table<'a> {
variation_store: ItemVariationStore<'a>,
records: LazyArray16<'a, ValueRecord>,
}
impl<'a> Table<'a> {
pub fn parse(data: &'a [u8]) -> Option<Self> {
let mut s = Stream::new(data);
let version: u32 = s.read()?;
if version != 0x00010000 {
return None;
}
s.skip::<u16>(); let value_record_size: u16 = s.read()?;
if usize::from(value_record_size) != ValueRecord::SIZE {
return None;
}
let count: u16 = s.read()?;
if count == 0 {
return None;
}
let var_store_offset = s.read::<Option<Offset16>>()??.to_usize();
let records = s.read_array16::<ValueRecord>(count)?;
let variation_store = ItemVariationStore::parse(Stream::new_at(data, var_store_offset)?)?;
Some(Table {
variation_store,
records,
})
}
pub fn metrics_offset(&self, tag: Tag, coordinates: &[NormalizedCoordinate]) -> Option<f32> {
let (_, record) = self.records.binary_search_by(|r| r.value_tag.cmp(&tag))?;
self.variation_store.parse_delta(
record.delta_set_outer_index,
record.delta_set_inner_index,
coordinates
)
}
}