read_fonts/tables/
ankr.rs1use super::aat::LookupU16;
4
5include!("../../generated/generated_ankr.rs");
6
7impl<'a> Ankr<'a> {
8 pub fn anchor_points(&self, glyph_id: GlyphId) -> Result<&'a [AnchorPoint], ReadError> {
10 let glyph_id: GlyphId16 = glyph_id.try_into().map_err(|_| ReadError::OutOfBounds)?;
11 let entry_offset = self.lookup_table()?.value(glyph_id.to_u16())?;
12 let full_offset = (self.glyph_data_table_offset() as usize)
13 .checked_add(entry_offset as usize)
14 .ok_or(ReadError::OutOfBounds)?;
15 let data = self
16 .offset_data()
17 .split_off(full_offset)
18 .ok_or(ReadError::OutOfBounds)?;
19 Ok(GlyphDataEntry::read(data)?.anchor_points())
20 }
21}
22
23#[cfg(test)]
24mod tests {
25 use font_test_data::bebuffer::BeBuffer;
26
27 use super::*;
28
29 #[test]
30 fn anchor_points() {
31 let mut buf = BeBuffer::new();
32 #[rustfmt::skip]
34 let lookup = [
35 0_u16, 0, 8, 24, 32 ];
38 let lookup_size = lookup.len() as u32 * 2;
39 buf = buf.extend([0u32, 0x0000000C, 12 + lookup_size]);
41 buf = buf.extend(lookup);
42 #[rustfmt::skip]
44 let expected_anchor_points: [&[(i16, i16)]; 4] = [
45 &[(-20, 20)],
46 &[(42, -10), (-200, 300), (i16::MIN, i16::MAX)],
47 &[(0, 4)],
48 &[(0, 0), (64, -64)],
49 ];
50 for entry in &expected_anchor_points {
51 buf = buf
52 .push(entry.len() as u32)
53 .extend(entry.iter().flat_map(|x| [x.0, x.1]));
54 }
55 let ankr = Ankr::read(buf.data().into()).unwrap();
56 let anchor_points = (0..4)
57 .map(|gid| {
58 let points = ankr.anchor_points(GlyphId::new(gid)).unwrap();
59 points
60 .iter()
61 .map(|point| (point.x(), point.y()))
62 .collect::<Vec<_>>()
63 })
64 .collect::<Vec<_>>();
65 assert!(expected_anchor_points.iter().eq(anchor_points.iter()));
66 }
67}