read_fonts/tables/
ankr.rsuse super::aat::LookupU16;
include!("../../generated/generated_ankr.rs");
impl<'a> Ankr<'a> {
pub fn anchor_points(&self, glyph_id: GlyphId) -> Result<&'a [AnchorPoint], ReadError> {
let glyph_id: GlyphId16 = glyph_id.try_into().map_err(|_| ReadError::OutOfBounds)?;
let entry_offset = self.lookup_table()?.value(glyph_id.to_u16())?;
let full_offset = (self.glyph_data_table_offset() as usize)
.checked_add(entry_offset as usize)
.ok_or(ReadError::OutOfBounds)?;
let data = self
.offset_data()
.split_off(full_offset)
.ok_or(ReadError::OutOfBounds)?;
Ok(GlyphDataEntry::read(data)?.anchor_points())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::test_helpers::BeBuffer;
#[test]
fn anchor_points() {
let mut buf = BeBuffer::new();
#[rustfmt::skip]
let lookup = [
0_u16, 0, 8, 24, 32 ];
let lookup_size = lookup.len() as u32 * 2;
buf = buf.extend([0u32, 0x0000000C, 12 + lookup_size]);
buf = buf.extend(lookup);
#[rustfmt::skip]
let expected_anchor_points: [&[(i16, i16)]; 4] = [
&[(-20, 20)],
&[(42, -10), (-200, 300), (i16::MIN, i16::MAX)],
&[(0, 4)],
&[(0, 0), (64, -64)],
];
for entry in &expected_anchor_points {
buf = buf
.push(entry.len() as u32)
.extend(entry.iter().flat_map(|x| [x.0, x.1]));
}
let ankr = Ankr::read(buf.font_data()).unwrap();
let anchor_points = (0..4)
.map(|gid| {
let points = ankr.anchor_points(GlyphId::new(gid)).unwrap();
points
.iter()
.map(|point| (point.x(), point.y()))
.collect::<Vec<_>>()
})
.collect::<Vec<_>>();
assert!(expected_anchor_points.iter().eq(anchor_points.iter()));
}
}