ab_glyph/
glyph.rs

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    ///
62    /// This point, relative to the glyph, is to the left before applying
63    /// `h_advance` or `h_side_bearing` & vertically at the "baseline".
64    /// See [glyph layout concepts](trait.Font.html#glyph-layout-concepts).
65    pub position: Point,
66}
67
68/// Old version of [`v2::GlyphImage`].
69#[deprecated(since = "0.2.22", note = "Deprecated in favor of `v2::GlyphImage`")]
70#[derive(Debug, Clone)]
71pub struct GlyphImage<'a> {
72    /// Offset of the image from the normal origin (top at the baseline plus
73    /// ascent), measured in pixels at the image's current scale.
74    pub origin: Point,
75    /// Current scale of the image in pixels per em.
76    pub scale: f32,
77    /// Raw image data, not a bitmap in the case of [`GlyphImageFormat::Png`] format.
78    pub data: &'a [u8],
79    /// Format of the raw data.
80    pub format: GlyphImageFormat,
81}
82
83#[derive(Debug, Clone)]
84#[non_exhaustive]
85pub struct GlyphSvg<'a> {
86    /// Raw image data, it should be rendered or decompressed (in case of SVGZ)
87    /// by the caller.. Note that the data includes records for multiple Glyphs.
88    pub data: &'a [u8],
89    /// The first glyph ID for the range covered by this record.
90    pub start_glyph_id: GlyphId,
91    /// The last glyph ID, *inclusive*, for the range covered by this record.
92    pub end_glyph_id: GlyphId,
93}
94
95pub mod v2 {
96    use crate::{GlyphImageFormat, Point};
97
98    /// A pre-rendered image of a glyph, usually used for emojis or other glyphs
99    /// that can't be represented only using an outline.
100    #[non_exhaustive]
101    #[derive(Debug, Clone)]
102    pub struct GlyphImage<'a> {
103        /// Offset of the image from the normal origin (top at the baseline plus
104        /// ascent), measured in pixels at the image's current scale.
105        pub origin: Point,
106        /// Image width.
107        ///
108        /// It doesn't guarantee that this value is the same as set in the `data` in the case of
109        /// [`GlyphImageFormat::Png`] format.
110        pub width: u16,
111        /// Image height.
112        ///
113        /// It doesn't guarantee that this value is the same as set in the `data` in the case of
114        /// [`GlyphImageFormat::Png`] format.
115        pub height: u16,
116        /// Pixels per em of the selected strike.
117        pub pixels_per_em: u16,
118        /// Raw image data, see [`format`](GlyphImageFormat).
119        pub data: &'a [u8],
120        /// Format of the raw [`data`](Self::data).
121        pub format: GlyphImageFormat,
122    }
123}
124
125/// Valid formats for a [`GlyphImage`].
126// Possible future formats: SVG, JPEG, TIFF
127#[non_exhaustive]
128#[derive(Debug, Clone)]
129pub enum GlyphImageFormat {
130    Png,
131
132    /// A monochrome bitmap.
133    ///
134    /// The most significant bit of the first byte corresponds to the top-left pixel, proceeding
135    /// through succeeding bits moving left to right. The data for each row is padded to a byte
136    /// boundary, so the next row begins with the most significant bit of a new byte. 1 corresponds
137    /// to black, and 0 to white.
138    BitmapMono,
139
140    /// A packed monochrome bitmap.
141    ///
142    /// The most significant bit of the first byte corresponds to the top-left pixel, proceeding
143    /// through succeeding bits moving left to right. Data is tightly packed with no padding. 1
144    /// corresponds to black, and 0 to white.
145    BitmapMonoPacked,
146
147    /// A grayscale bitmap with 2 bits per pixel.
148    ///
149    /// The most significant bits of the first byte corresponds to the top-left pixel, proceeding
150    /// through succeeding bits moving left to right. The data for each row is padded to a byte
151    /// boundary, so the next row begins with the most significant bit of a new byte.
152    BitmapGray2,
153
154    /// A packed grayscale bitmap with 2 bits per pixel.
155    ///
156    /// The most significant bits of the first byte corresponds to the top-left pixel, proceeding
157    /// through succeeding bits moving left to right. Data is tightly packed with no padding.
158    BitmapGray2Packed,
159
160    /// A grayscale bitmap with 4 bits per pixel.
161    ///
162    /// The most significant bits of the first byte corresponds to the top-left pixel, proceeding
163    /// through succeeding bits moving left to right. The data for each row is padded to a byte
164    /// boundary, so the next row begins with the most significant bit of a new byte.
165    BitmapGray4,
166
167    /// A packed grayscale bitmap with 4 bits per pixel.
168    ///
169    /// The most significant bits of the first byte corresponds to the top-left pixel, proceeding
170    /// through succeeding bits moving left to right. Data is tightly packed with no padding.
171    BitmapGray4Packed,
172
173    /// A grayscale bitmap with 8 bits per pixel.
174    ///
175    /// The first byte corresponds to the top-left pixel, proceeding through succeeding bytes
176    /// moving left to right.
177    BitmapGray8,
178
179    /// A color bitmap with 32 bits per pixel.
180    ///
181    /// The first group of four bytes corresponds to the top-left pixel, proceeding through
182    /// succeeding pixels moving left to right. Each byte corresponds to a color channel and the
183    /// channels within a pixel are in blue, green, red, alpha order. Color values are
184    /// pre-multiplied by the alpha. For example, the color "full-green with half translucency"
185    /// is encoded as `\x00\x80\x00\x80`, and not `\x00\xFF\x00\x80`.
186    BitmapPremulBgra32,
187}