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 glyph_id(&self, c: char) -> GlyphId {
96 self.0.glyph_id(c)
97 }
98
99 #[inline]
100 fn h_advance_unscaled(&self, id: GlyphId) -> f32 {
101 self.0.h_advance_unscaled(id)
102 }
103
104 #[inline]
105 fn h_side_bearing_unscaled(&self, id: GlyphId) -> f32 {
106 self.0.h_side_bearing_unscaled(id)
107 }
108
109 #[inline]
110 fn v_advance_unscaled(&self, id: GlyphId) -> f32 {
111 self.0.v_advance_unscaled(id)
112 }
113
114 #[inline]
115 fn v_side_bearing_unscaled(&self, id: GlyphId) -> f32 {
116 self.0.v_side_bearing_unscaled(id)
117 }
118
119 #[inline]
120 fn kern_unscaled(&self, first: GlyphId, second: GlyphId) -> f32 {
121 self.0.kern_unscaled(first, second)
122 }
123
124 #[inline]
125 fn outline(&self, glyph: GlyphId) -> Option<Outline> {
126 self.0.outline(glyph)
127 }
128
129 #[inline]
130 fn glyph_count(&self) -> usize {
131 self.0.glyph_count()
132 }
133
134 #[inline]
135 fn codepoint_ids(&self) -> crate::CodepointIdIter<'_> {
136 self.0.codepoint_ids()
137 }
138
139 #[inline]
140 fn glyph_raster_image2(&self, id: GlyphId, size: u16) -> Option<v2::GlyphImage> {
141 self.0.glyph_raster_image2(id, size)
142 }
143}
144
145impl From<FontVec> for FontArc {
146 #[inline]
147 fn from(font: FontVec) -> Self {
148 Self::new(font)
149 }
150}
151impl From<FontRef<'static>> for FontArc {
152 #[inline]
153 fn from(font: FontRef<'static>) -> Self {
154 Self::new(font)
155 }
156}
157impl From<Arc<dyn Font + Send + Sync + 'static>> for FontArc {
158 #[inline]
159 fn from(font: Arc<dyn Font + Send + Sync + 'static>) -> Self {
160 Self(font)
161 }
162}
163