ab_glyph/
font_arc.rs

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