Skip to main content

harfrust/hb/
glyph_names.rs

1use read_fonts::{
2    ps::cff::charset::Charset,
3    tables::{cff::Cff, post::Post},
4    TableProvider,
5};
6
7use crate::hb::face::FontKind;
8
9#[derive(Clone)]
10pub enum GlyphNames<'a> {
11    None,
12    Cff(Cff<'a>, Charset<'a>),
13    Post(Post<'a>),
14}
15
16impl<'a> GlyphNames<'a> {
17    pub fn new(font: &FontKind<'a>) -> Self {
18        match font {
19            FontKind::FontRef(font) => Self::from_tables(&font.font),
20            FontKind::FontInstance(instance, _) => Self::from_tables(&instance.tables()),
21        }
22    }
23
24    pub(crate) fn from_tables(font: &impl TableProvider<'a>) -> Self {
25        if let Some((cff, charset)) = font
26            .cff()
27            .ok()
28            .and_then(|cff| Some((cff.clone(), cff.charset(0).ok()??)))
29        {
30            Self::Cff(cff, charset)
31        } else if let Ok(post) = font.post() {
32            Self::Post(post)
33        } else {
34            Self::None
35        }
36    }
37
38    pub fn get(&self, glyph_id: u32) -> Option<&str> {
39        let name = match self {
40            Self::Cff(cff, charset) => {
41                let sid = charset.string_id(glyph_id.into()).ok()?;
42                core::str::from_utf8(cff.string(sid)?).ok()
43            }
44            Self::Post(post) => {
45                let gid: u16 = glyph_id.try_into().ok()?;
46                post.glyph_name(gid.into())
47            }
48            Self::None => None,
49        }?;
50        (!name.is_empty()).then_some(name)
51    }
52}