1 | use crate::{v2, Font, FontRef, FontVec, GlyphId, InvalidFont, Outline}; |
2 | use alloc::sync::Arc; |
3 | use 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)] |
20 | pub struct FontArc(Arc<dyn Font + Send + Sync + 'static>); |
21 | |
22 | impl 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 | |
67 | impl fmt::Debug for FontArc { |
68 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
69 | write!(f, "FontArc" ) |
70 | } |
71 | } |
72 | |
73 | impl 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 | |
145 | impl From<FontVec> for FontArc { |
146 | #[inline ] |
147 | fn from(font: FontVec) -> Self { |
148 | Self::new(font) |
149 | } |
150 | } |
151 | impl From<FontRef<'static>> for FontArc { |
152 | #[inline ] |
153 | fn from(font: FontRef<'static>) -> Self { |
154 | Self::new(font) |
155 | } |
156 | } |
157 | impl 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 | |