use core::ops::Range;
use crate::parser::{Stream, LazyArray};
use crate::{Font, GlyphId, TableName, Result, Error};
impl<'a> Font<'a> {
pub(crate) fn glyph_range(&self, glyph_id: GlyphId) -> Result<Range<usize>> {
use crate::head::IndexToLocationFormat as Format;
if self.number_of_glyphs() == core::u16::MAX {
return Err(Error::NoGlyph);
}
let glyph_id = glyph_id.0;
if glyph_id == core::u16::MAX {
return Err(Error::NoGlyph);
}
let total = self.number_of_glyphs() + 1;
if glyph_id + 1 >= total {
return Err(Error::NoGlyph);
}
let format = self.index_to_location_format().ok_or(Error::NoGlyph)?;
let data = self.loca.ok_or_else(|| Error::TableMissing(TableName::IndexToLocation))?;
let mut s = Stream::new(data);
let range = match format {
Format::Short => {
let array: LazyArray<u16> = s.read_array(total)?;
array.at(glyph_id) as usize * 2 .. array.at(glyph_id + 1) as usize * 2
}
Format::Long => {
let array: LazyArray<u32> = s.read_array(total)?;
array.at(glyph_id) as usize .. array.at(glyph_id + 1) as usize
}
};
if range.start == range.end {
Err(Error::NoOutline)
} else if range.start > range.end {
Err(Error::NoGlyph)
} else {
Ok(range)
}
}
}