1use 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)]
15pub struct GlyphId(pub u16);
16
17impl 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)]
55pub 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)]
67pub 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
79pub 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)]
113pub 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