swash/
charmap.rs

1/*!
2Mapping characters to nominal glyph identifiers.
3*/
4
5use super::internal::cmap;
6use super::{FontRef, GlyphId};
7
8/// Proxy for rematerializing a character map.
9#[derive(Copy, Clone, Default, Debug)]
10pub struct CharmapProxy(u32, u8, bool);
11
12impl CharmapProxy {
13    /// Creates character map proxy from the specified font.
14    pub fn from_font(font: &FontRef) -> Self {
15        if let Some((offset, format, symbol)) = cmap::subtable(font) {
16            Self(offset, format, symbol)
17        } else {
18            Self(0, 0, false)
19        }
20    }
21
22    /// Materializes a character map from the specified font. This proxy must
23    /// have been created from the same font.
24    pub fn materialize<'a>(&self, font: &FontRef<'a>) -> Charmap<'a> {
25        Charmap {
26            data: font.data,
27            proxy: *self,
28        }
29    }
30}
31
32/// Maps characters to nominal glyph identifiers.
33#[derive(Copy, Clone)]
34pub struct Charmap<'a> {
35    data: &'a [u8],
36    proxy: CharmapProxy,
37}
38
39impl<'a> Charmap<'a> {
40    /// Creates a character map from the specified font.
41    pub fn from_font(font: &FontRef<'a>) -> Self {
42        let proxy = CharmapProxy::from_font(font);
43        Self {
44            data: font.data,
45            proxy,
46        }
47    }
48
49    /// Returns the associated proxy.
50    pub fn proxy(&self) -> CharmapProxy {
51        self.proxy
52    }
53
54    /// Returns a nominal glyph identifier for the specified codepoint.
55    pub fn map(&self, codepoint: impl Into<u32>) -> GlyphId {
56        let codepoint = codepoint.into();
57        let mut glyph_id = cmap::map(self.data, self.proxy.0, self.proxy.1, codepoint).unwrap_or(0);
58        // Remap U+0000..=U+00FF to U+F000..=U+F0FF for symbol encodings
59        if glyph_id == 0 && self.proxy.2 && codepoint <= 0x00FF {
60            glyph_id =
61                cmap::map(self.data, self.proxy.0, self.proxy.1, codepoint + 0xF000).unwrap_or(0);
62        }
63        glyph_id
64    }
65
66    /// Invokes the specified closure with all codepoint/glyph identifier
67    /// pairs in the character map.
68    pub fn enumerate(&self, f: impl FnMut(u32, GlyphId)) {
69        cmap::enumerate(self.data, self.proxy.0, f);
70    }
71}