raster_fonts/lib.rs
1//! De-/Serializable runtime representation of bitmap font metadata.
2//!
3//! # Usage
4//! ## RON
5//! ```
6//! # fn test() -> Result<(), ron::Error> {
7//! // Requires Cargo feature `serde-deserialize` and the `ron` crate:
8//! const FONT_METADATA: &'static str = include_str!("../font-metadata.ron");
9//! let font: raster_fonts::BitmapFont = ron::from_str(FONT_METADATA)?;
10//! # Ok(())
11//! # }
12//! # test().unwrap();
13//! ```
14//!
15//! ## JSON
16//! ```
17//! # fn test() -> Result<(), serde_json::Error> {
18//! // Requires Cargo feature `serde-deserialize` and the `serde_json` crate:
19//! const FONT_METADATA: &'static str = include_str!("../font-metadata.json");
20//! let font: raster_fonts::BitmapFont = serde_json::from_str(FONT_METADATA)?;
21//! # Ok(())
22//! # }
23//! # test().unwrap();
24//! ```
25//!
26//! ## RKYV
27//! ```
28//! // `rkyv` requires the data to be aligned for zero-copy deserialization,
29//! // which in turn requires some trickery to achieve in a `const` context:
30//! const FONT_METADATA: &'static [u8] = {
31//! #[repr(C)]
32//! struct Aligned<T: ?Sized> {
33//! _align: [usize; 0],
34//! bytes: T,
35//! }
36//!
37//! const ALIGNED: &'static Aligned<[u8]> = &Aligned {
38//! _align: [],
39//! bytes: *include_bytes!("../font-metadata.rkyv"),
40//! };
41//!
42//! &ALIGNED.bytes
43//! };
44//!
45//! // Using the unsafe API for maximum performance:
46//! use raster_fonts::BitmapFont;
47//! let archived_font = unsafe { rkyv::archived_root::<BitmapFont>(FONT_METADATA) };
48//! // Optionally, unpack the archived metadata before use:
49//! use rkyv::Deserialize;
50//! let deserialized_font: BitmapFont = archived_font.deserialize(&mut rkyv::Infallible).unwrap();
51//! ```
52
53#![cfg_attr(docs_rs, feature(doc_cfg))]
54#![deny(missing_docs)]
55#![warn(clippy::pedantic)]
56
57use std::collections::HashMap;
58use std::num::NonZeroU8;
59
60/// Coordinates and size of a rendered glyph in a packed bitmap.
61#[cfg_attr(feature = "serde-serialize", derive(serde::Serialize))]
62#[cfg_attr(feature = "serde-deserialize", derive(serde::Deserialize))]
63#[cfg_attr(feature = "rkyv", derive(rkyv::Archive))]
64#[cfg_attr(feature = "rkyv-serialize", derive(rkyv::Serialize))]
65#[cfg_attr(feature = "rkyv-deserialize", derive(rkyv::Deserialize))]
66pub struct SourceRect {
67 /// Horizontal position in the bitmap in pixels.
68 pub x: u16,
69 /// Vertical position in the bitmap in pixels.
70 pub y: u16,
71 /// Horizontal extent in pixels.
72 pub width: NonZeroU8,
73 /// Vertical extent in pixels.
74 pub height: NonZeroU8,
75}
76
77/// [`SourceRect`] and horizontal metrics of a glyph required for text layout.
78#[cfg_attr(feature = "serde-serialize", derive(serde::Serialize))]
79#[cfg_attr(feature = "serde-deserialize", derive(serde::Deserialize))]
80#[cfg_attr(feature = "rkyv", derive(rkyv::Archive))]
81#[cfg_attr(feature = "rkyv-serialize", derive(rkyv::Serialize))]
82#[cfg_attr(feature = "rkyv-deserialize", derive(rkyv::Deserialize))]
83pub struct BitmapGlyph {
84 /// The bounding box of the rendered glyph in the bitmap.
85 ///
86 /// None for whitespace characters.
87 pub bitmap_source: Option<SourceRect>,
88 /// The horizontal offset that the origin of the next glyph should be from the origin of this glyph.
89 pub advance_width: f32,
90 /// The horizontal offset between the origin of this glyph and the leftmost point of the glyph.
91 pub left_side_bearing: f32,
92 /// The vertical offset between the origin of this glyph and the baseline. Typhically positive.
93 pub ascent: f32,
94}
95
96/// Runtime representation of all metadata for a single bitmap font.
97///
98/// Does not own or even reference the bitmap itself.
99#[cfg_attr(feature = "serde-serialize", derive(serde::Serialize))]
100#[cfg_attr(feature = "serde-deserialize", derive(serde::Deserialize))]
101#[cfg_attr(feature = "rkyv", derive(rkyv::Archive))]
102#[cfg_attr(feature = "rkyv-serialize", derive(rkyv::Serialize))]
103#[cfg_attr(feature = "rkyv-deserialize", derive(rkyv::Deserialize))]
104pub struct BitmapFont {
105 /// Map of unicode codepoints to glyphs in the font.
106 pub glyphs: HashMap<char, BitmapGlyph>,
107 /// Additional kerning to apply as well as that given by [`BitmapGlyph`] metrics to a pair of glyphs.
108 pub kerning_table: Option<HashMap<(char, char), f32>>,
109 /// The highest point that any glyph in the font extends above the baseline. Typically positive.
110 pub ascent: f32,
111 /// The lowest point that any glyph in the font extends below the baseline. Typically negative.
112 pub descent: f32,
113 /// The gap to leave between the descent of one line and the ascent of the next.
114 ///
115 /// This is of course only a guideline given by the font's designers.
116 pub line_gap: f32,
117 /// The distance from the true pixel bounding box of any given glyph to the bounding box given by [`BitmapGlyph.bitmap_source`](BitmapGlyph).
118 pub padding: u32,
119}