ttf_parser/tables/
loca.rs1use core::num::NonZeroU16;
5use core::ops::Range;
6
7use crate::{GlyphId, IndexToLocationFormat};
8use crate::parser::{Stream, LazyArray16, NumFrom};
9
10#[derive(Clone, Copy, Debug)]
12pub enum Table<'a> {
13 Short(LazyArray16<'a, u16>),
15 Long(LazyArray16<'a, u32>),
17}
18
19impl<'a> Table<'a> {
20 pub fn parse(
25 number_of_glyphs: NonZeroU16,
26 format: IndexToLocationFormat,
27 data: &'a [u8],
28 ) -> Option<Self> {
29 let total = if number_of_glyphs.get() == core::u16::MAX {
33 number_of_glyphs.get()
34 } else {
35 number_of_glyphs.get() + 1
36 };
37
38 let mut s = Stream::new(data);
39 match format {
40 IndexToLocationFormat::Short => {
41 Some(Table::Short(s.read_array16::<u16>(total)?))
42 }
43 IndexToLocationFormat::Long => {
44 Some(Table::Long(s.read_array16::<u32>(total)?))
45 }
46 }
47 }
48
49 #[inline]
51 pub fn len(&self) -> u16 {
52 match self {
53 Table::Short(ref array) => array.len(),
54 Table::Long(ref array) => array.len(),
55 }
56 }
57
58 #[inline]
60 pub fn glyph_range(&self, glyph_id: GlyphId) -> Option<Range<usize>> {
61 let glyph_id = glyph_id.0;
62 if glyph_id == core::u16::MAX {
63 return None;
64 }
65
66 if glyph_id + 1 >= self.len() {
68 return None;
69 }
70
71 let range = match self {
72 Table::Short(ref array) => {
73 usize::from(array.get(glyph_id)?) * 2 .. usize::from(array.get(glyph_id + 1)?) * 2
75 }
76 Table::Long(ref array) => {
77 usize::num_from(array.get(glyph_id)?) .. usize::num_from(array.get(glyph_id + 1)?)
78 }
79 };
80
81 if range.start >= range.end {
82 None
85 } else {
86 Some(range)
87 }
88 }
89}