1 | use crate::{Point, PxScale}; |
2 | |
3 | /// Glyph id. |
4 | /// |
5 | /// # Example |
6 | /// ``` |
7 | /// use ab_glyph::{Font, FontRef, GlyphId}; |
8 | /// # fn main() -> Result<(), ab_glyph::InvalidFont> { |
9 | /// let font = FontRef::try_from_slice(include_bytes!("../../dev/fonts/Exo2-Light.otf" ))?; |
10 | /// |
11 | /// let q_id: GlyphId = font.glyph_id('q' ); |
12 | /// # Ok(()) } |
13 | /// ``` |
14 | #[derive (Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
15 | pub struct GlyphId(pub u16); |
16 | |
17 | impl GlyphId { |
18 | /// Construct a `Glyph` with given scale & position. |
19 | /// |
20 | /// # Example |
21 | /// ``` |
22 | /// # use ab_glyph::*; |
23 | /// # let font = FontRef::try_from_slice(include_bytes!("../../dev/fonts/Exo2-Light.otf" )).unwrap(); |
24 | /// let glyph = font.glyph_id('z' ).with_scale_and_position(24.0, point(100.0, 0.0)); |
25 | /// ``` |
26 | #[inline ] |
27 | pub fn with_scale_and_position<S: Into<PxScale>, P: Into<Point>>( |
28 | self, |
29 | scale: S, |
30 | position: P, |
31 | ) -> Glyph { |
32 | Glyph { |
33 | id: self, |
34 | scale: scale.into(), |
35 | position: position.into(), |
36 | } |
37 | } |
38 | |
39 | /// Construct a `Glyph` with given scale and position `point(0.0, 0.0)`. |
40 | /// |
41 | /// # Example |
42 | /// ``` |
43 | /// # use ab_glyph::*; |
44 | /// # let font = FontRef::try_from_slice(include_bytes!("../../dev/fonts/Exo2-Light.otf" )).unwrap(); |
45 | /// let glyph = font.glyph_id('w' ).with_scale(48.0); |
46 | /// ``` |
47 | #[inline ] |
48 | pub fn with_scale<S: Into<PxScale>>(self, scale: S) -> Glyph { |
49 | self.with_scale_and_position(scale, Point::default()) |
50 | } |
51 | } |
52 | |
53 | /// A glyph with pixel scale & position. |
54 | #[derive (Clone, Debug, PartialEq, PartialOrd)] |
55 | pub struct Glyph { |
56 | /// Glyph id. |
57 | pub id: GlyphId, |
58 | /// Pixel scale of this glyph. |
59 | pub scale: PxScale, |
60 | /// Position of this glyph. |
61 | pub position: Point, |
62 | } |
63 | |
64 | /// Old version of [`v2::GlyphImage`]. |
65 | #[deprecated (since = "0.2.22" , note = "Deprecated in favor of `v2::GlyphImage`" )] |
66 | #[derive (Debug, Clone)] |
67 | pub struct GlyphImage<'a> { |
68 | /// Offset of the image from the normal origin (top at the baseline plus |
69 | /// ascent), measured in pixels at the image's current scale. |
70 | pub origin: Point, |
71 | /// Current scale of the image in pixels per em. |
72 | pub scale: f32, |
73 | /// Raw image data, not a bitmap in the case of [`GlyphImageFormat::Png`] format. |
74 | pub data: &'a [u8], |
75 | /// Format of the raw data. |
76 | pub format: GlyphImageFormat, |
77 | } |
78 | |
79 | pub mod v2 { |
80 | use crate::{GlyphImageFormat, Point}; |
81 | |
82 | /// A pre-rendered image of a glyph, usually used for emojis or other glyphs |
83 | /// that can't be represented only using an outline. |
84 | #[non_exhaustive ] |
85 | #[derive (Debug, Clone)] |
86 | pub struct GlyphImage<'a> { |
87 | /// Offset of the image from the normal origin (top at the baseline plus |
88 | /// ascent), measured in pixels at the image's current scale. |
89 | pub origin: Point, |
90 | /// Image width. |
91 | /// |
92 | /// It doesn't guarantee that this value is the same as set in the `data` in the case of |
93 | /// [`GlyphImageFormat::Png`] format. |
94 | pub width: u16, |
95 | /// Image height. |
96 | /// |
97 | /// It doesn't guarantee that this value is the same as set in the `data` in the case of |
98 | /// [`GlyphImageFormat::Png`] format. |
99 | pub height: u16, |
100 | /// Pixels per em of the selected strike. |
101 | pub pixels_per_em: u16, |
102 | /// Raw image data, see [`format`](GlyphImageFormat). |
103 | pub data: &'a [u8], |
104 | /// Format of the raw [`data`](Self::data). |
105 | pub format: GlyphImageFormat, |
106 | } |
107 | } |
108 | |
109 | /// Valid formats for a [`GlyphImage`]. |
110 | // Possible future formats: SVG, JPEG, TIFF |
111 | #[non_exhaustive ] |
112 | #[derive (Debug, Clone)] |
113 | pub enum GlyphImageFormat { |
114 | Png, |
115 | |
116 | /// A monochrome bitmap. |
117 | /// |
118 | /// The most significant bit of the first byte corresponds to the top-left pixel, proceeding |
119 | /// through succeeding bits moving left to right. The data for each row is padded to a byte |
120 | /// boundary, so the next row begins with the most significant bit of a new byte. 1 corresponds |
121 | /// to black, and 0 to white. |
122 | BitmapMono, |
123 | |
124 | /// A packed monochrome bitmap. |
125 | /// |
126 | /// The most significant bit of the first byte corresponds to the top-left pixel, proceeding |
127 | /// through succeeding bits moving left to right. Data is tightly packed with no padding. 1 |
128 | /// corresponds to black, and 0 to white. |
129 | BitmapMonoPacked, |
130 | |
131 | /// A grayscale bitmap with 2 bits per pixel. |
132 | /// |
133 | /// The most significant bits of the first byte corresponds to the top-left pixel, proceeding |
134 | /// through succeeding bits moving left to right. The data for each row is padded to a byte |
135 | /// boundary, so the next row begins with the most significant bit of a new byte. |
136 | BitmapGray2, |
137 | |
138 | /// A packed grayscale bitmap with 2 bits per pixel. |
139 | /// |
140 | /// The most significant bits of the first byte corresponds to the top-left pixel, proceeding |
141 | /// through succeeding bits moving left to right. Data is tightly packed with no padding. |
142 | BitmapGray2Packed, |
143 | |
144 | /// A grayscale bitmap with 4 bits per pixel. |
145 | /// |
146 | /// The most significant bits of the first byte corresponds to the top-left pixel, proceeding |
147 | /// through succeeding bits moving left to right. The data for each row is padded to a byte |
148 | /// boundary, so the next row begins with the most significant bit of a new byte. |
149 | BitmapGray4, |
150 | |
151 | /// A packed grayscale bitmap with 4 bits per pixel. |
152 | /// |
153 | /// The most significant bits of the first byte corresponds to the top-left pixel, proceeding |
154 | /// through succeeding bits moving left to right. Data is tightly packed with no padding. |
155 | BitmapGray4Packed, |
156 | |
157 | /// A grayscale bitmap with 8 bits per pixel. |
158 | /// |
159 | /// The first byte corresponds to the top-left pixel, proceeding through succeeding bytes |
160 | /// moving left to right. |
161 | BitmapGray8, |
162 | |
163 | /// A color bitmap with 32 bits per pixel. |
164 | /// |
165 | /// The first group of four bytes corresponds to the top-left pixel, proceeding through |
166 | /// succeeding pixels moving left to right. Each byte corresponds to a color channel and the |
167 | /// channels within a pixel are in blue, green, red, alpha order. Color values are |
168 | /// pre-multiplied by the alpha. For example, the color "full-green with half translucency" |
169 | /// is encoded as `\x00\x80\x00\x80`, and not `\x00\xFF\x00\x80`. |
170 | BitmapPremulBgra32, |
171 | } |
172 | |