ab_glyph/
font_arc.rs

1use crate::{v2, Font, FontRef, FontVec, GlyphId, InvalidFont, Outline};
2use alloc::sync::Arc;
3use core::fmt;
4
5/// `Font` implementor that wraps another concrete `Font + 'static` type storing in an `Arc`.
6///
7/// Provides convenient type erasure & cheap clones (particularly for `FontVec`).
8///
9/// # Example
10/// ```
11/// use ab_glyph::{Font, FontArc};
12///
13/// # fn main() -> Result<(), ab_glyph::InvalidFont> {
14/// let font = FontArc::try_from_slice(include_bytes!("../../dev/fonts/Exo2-Light.otf"))?;
15///
16/// assert_eq!(font.glyph_id('s'), ab_glyph::GlyphId(56));
17/// # Ok(()) }
18/// ```
19#[derive(Clone)]
20pub struct FontArc(Arc<dyn Font + Send + Sync + 'static>);
21
22impl FontArc {
23    /// # Example
24    /// ```
25    /// # use ab_glyph::*;
26    /// # fn main() -> Result<(), ab_glyph::InvalidFont> {
27    /// # let font_data = include_bytes!("../../dev/fonts/Exo2-Light.otf").to_vec();
28    /// # let font_vec = FontVec::try_from_vec(font_data)?;
29    /// let font_arc = FontArc::new(font_vec);
30    /// # Ok(()) }
31    /// ```
32    #[inline]
33    pub fn new<F: Font + Send + Sync + 'static>(font: F) -> Self {
34        Self(Arc::new(font))
35    }
36
37    /// Creates an `FontArc` from owned data.
38    ///
39    /// # Example
40    /// ```
41    /// # use ab_glyph::*;
42    /// # fn main() -> Result<(), InvalidFont> {
43    /// # let owned_font_data = include_bytes!("../../dev/fonts/Exo2-Light.otf").to_vec();
44    /// let font = FontArc::try_from_vec(owned_font_data)?;
45    /// # Ok(()) }
46    /// ```
47    #[inline]
48    pub fn try_from_vec(data: Vec<u8>) -> Result<Self, InvalidFont> {
49        Ok(FontVec::try_from_vec(data)?.into())
50    }
51
52    /// Creates an `FontArc` from a byte-slice.
53    ///
54    /// # Example
55    /// ```
56    /// # use ab_glyph::*;
57    /// # fn main() -> Result<(), InvalidFont> {
58    /// let font = FontArc::try_from_slice(include_bytes!("../../dev/fonts/Exo2-Light.otf"))?;
59    /// # Ok(()) }
60    /// ```
61    #[inline]
62    pub fn try_from_slice(data: &'static [u8]) -> Result<Self, InvalidFont> {
63        Ok(FontRef::try_from_slice(data)?.into())
64    }
65}
66
67impl fmt::Debug for FontArc {
68    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69        write!(f, "FontArc")
70    }
71}
72
73impl Font for FontArc {
74    #[inline]
75    fn units_per_em(&self) -> Option<f32> {
76        self.0.units_per_em()
77    }
78
79    #[inline]
80    fn ascent_unscaled(&self) -> f32 {
81        self.0.ascent_unscaled()
82    }
83
84    #[inline]
85    fn descent_unscaled(&self) -> f32 {
86        self.0.descent_unscaled()
87    }
88
89    #[inline]
90    fn line_gap_unscaled(&self) -> f32 {
91        self.0.line_gap_unscaled()
92    }
93
94    #[inline]
95    fn italic_angle(&self) -> f32 {
96        self.0.italic_angle()
97    }
98
99    #[inline]
100    fn glyph_id(&self, c: char) -> GlyphId {
101        self.0.glyph_id(c)
102    }
103
104    #[inline]
105    fn h_advance_unscaled(&self, id: GlyphId) -> f32 {
106        self.0.h_advance_unscaled(id)
107    }
108
109    #[inline]
110    fn h_side_bearing_unscaled(&self, id: GlyphId) -> f32 {
111        self.0.h_side_bearing_unscaled(id)
112    }
113
114    #[inline]
115    fn v_advance_unscaled(&self, id: GlyphId) -> f32 {
116        self.0.v_advance_unscaled(id)
117    }
118
119    #[inline]
120    fn v_side_bearing_unscaled(&self, id: GlyphId) -> f32 {
121        self.0.v_side_bearing_unscaled(id)
122    }
123
124    #[inline]
125    fn kern_unscaled(&self, first: GlyphId, second: GlyphId) -> f32 {
126        self.0.kern_unscaled(first, second)
127    }
128
129    #[inline]
130    fn outline(&self, glyph: GlyphId) -> Option<Outline> {
131        self.0.outline(glyph)
132    }
133
134    #[inline]
135    fn glyph_count(&self) -> usize {
136        self.0.glyph_count()
137    }
138
139    #[inline]
140    fn codepoint_ids(&self) -> crate::CodepointIdIter<'_> {
141        self.0.codepoint_ids()
142    }
143
144    #[inline]
145    fn glyph_raster_image2(&self, id: GlyphId, size: u16) -> Option<v2::GlyphImage> {
146        self.0.glyph_raster_image2(id, size)
147    }
148
149    #[inline]
150    fn glyph_svg_image(&self, id: GlyphId) -> Option<crate::GlyphSvg> {
151        self.0.glyph_svg_image(id)
152    }
153
154    #[inline]
155    fn font_data(&self) -> &[u8] {
156        self.0.font_data()
157    }
158}
159
160impl From<FontVec> for FontArc {
161    #[inline]
162    fn from(font: FontVec) -> Self {
163        Self::new(font)
164    }
165}
166impl From<FontRef<'static>> for FontArc {
167    #[inline]
168    fn from(font: FontRef<'static>) -> Self {
169        Self::new(font)
170    }
171}
172impl From<Arc<dyn Font + Send + Sync + 'static>> for FontArc {
173    #[inline]
174    fn from(font: Arc<dyn Font + Send + Sync + 'static>) -> Self {
175        Self(font)
176    }
177}