Skip to main content
← PSoXide SDK guides and examples · SDK f2fec1c301f1 · All Cargo features enabled; check feature gates before use.

psx_font/fonts/
spleen_5x8.rs

1// Spleen 5x8 by Frederic Cambus. BSD-2-Clause.
2// https://github.com/fcambus/spleen  (see vendor/spleen-LICENSE)
3// Generated from spleen-5x8.bdf; MSB = leftmost pixel.
4
5use crate::{BitOrder, BitmapFont};
6
7/// ASCII U+0020..U+007E, 5x8 px, 1bpp, MSB = leftmost.
8pub const SPLEEN_5X8_BITMAP: [u8; 760] = [
9    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0020 ' '
10    0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x20, 0x00, // U+0021 '!'
11    0x50, 0x50, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0022 '"'
12    0x00, 0x50, 0xf8, 0x50, 0x50, 0xf8, 0x50, 0x00, // U+0023 '#'
13    0x20, 0x70, 0xa0, 0x60, 0x30, 0x30, 0xe0, 0x20, // U+0024 '$'
14    0x10, 0x90, 0xa0, 0x20, 0x40, 0x50, 0x90, 0x80, // U+0025 '%'
15    0x20, 0x50, 0x50, 0x60, 0xa8, 0x90, 0x68, 0x00, // U+0026 '&'
16    0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0027 '''
17    0x10, 0x20, 0x40, 0x40, 0x40, 0x40, 0x20, 0x10, // U+0028 '('
18    0x40, 0x20, 0x10, 0x10, 0x10, 0x10, 0x20, 0x40, // U+0029 ')'
19    0x00, 0x00, 0x90, 0x60, 0xf0, 0x60, 0x90, 0x00, // U+002A '*'
20    0x00, 0x00, 0x20, 0x20, 0xf8, 0x20, 0x20, 0x00, // U+002B '+'
21    0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x40, // U+002C ','
22    0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, // U+002D '-'
23    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, // U+002E '.'
24    0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, // U+002F '/'
25    0x00, 0x60, 0x90, 0xb0, 0xd0, 0x90, 0x60, 0x00, // U+0030 '0'
26    0x00, 0x20, 0x60, 0x20, 0x20, 0x20, 0x70, 0x00, // U+0031 '1'
27    0x00, 0x60, 0x90, 0x10, 0x60, 0x80, 0xf0, 0x00, // U+0032 '2'
28    0x00, 0x60, 0x90, 0x20, 0x10, 0x90, 0x60, 0x00, // U+0033 '3'
29    0x00, 0x80, 0xa0, 0xa0, 0xf0, 0x20, 0x20, 0x00, // U+0034 '4'
30    0x00, 0xf0, 0x80, 0xe0, 0x10, 0x10, 0xe0, 0x00, // U+0035 '5'
31    0x00, 0x60, 0x80, 0xe0, 0x90, 0x90, 0x60, 0x00, // U+0036 '6'
32    0x00, 0xf0, 0x90, 0x10, 0x20, 0x40, 0x40, 0x00, // U+0037 '7'
33    0x00, 0x60, 0x90, 0x60, 0x90, 0x90, 0x60, 0x00, // U+0038 '8'
34    0x00, 0x60, 0x90, 0x90, 0x70, 0x10, 0x60, 0x00, // U+0039 '9'
35    0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, // U+003A ':'
36    0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x20, 0x40, // U+003B ';'
37    0x00, 0x10, 0x20, 0x40, 0x40, 0x20, 0x10, 0x00, // U+003C '<'
38    0x00, 0x00, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0x00, // U+003D '='
39    0x00, 0x40, 0x20, 0x10, 0x10, 0x20, 0x40, 0x00, // U+003E '>'
40    0x60, 0x90, 0x10, 0x20, 0x40, 0x00, 0x40, 0x00, // U+003F '?'
41    0x00, 0x60, 0x90, 0xb0, 0xb0, 0x80, 0x70, 0x00, // U+0040 '@'
42    0x00, 0x60, 0x90, 0x90, 0xf0, 0x90, 0x90, 0x00, // U+0041 'A'
43    0x00, 0xe0, 0x90, 0xe0, 0x90, 0x90, 0xe0, 0x00, // U+0042 'B'
44    0x00, 0x70, 0x80, 0x80, 0x80, 0x80, 0x70, 0x00, // U+0043 'C'
45    0x00, 0xe0, 0x90, 0x90, 0x90, 0x90, 0xe0, 0x00, // U+0044 'D'
46    0x00, 0x70, 0x80, 0xe0, 0x80, 0x80, 0x70, 0x00, // U+0045 'E'
47    0x00, 0x70, 0x80, 0x80, 0xe0, 0x80, 0x80, 0x00, // U+0046 'F'
48    0x00, 0x70, 0x80, 0xb0, 0x90, 0x90, 0x70, 0x00, // U+0047 'G'
49    0x00, 0x90, 0x90, 0xf0, 0x90, 0x90, 0x90, 0x00, // U+0048 'H'
50    0x00, 0x70, 0x20, 0x20, 0x20, 0x20, 0x70, 0x00, // U+0049 'I'
51    0x00, 0x70, 0x20, 0x20, 0x20, 0x20, 0xc0, 0x00, // U+004A 'J'
52    0x00, 0x90, 0x90, 0xe0, 0x90, 0x90, 0x90, 0x00, // U+004B 'K'
53    0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x70, 0x00, // U+004C 'L'
54    0x00, 0x90, 0xf0, 0xf0, 0x90, 0x90, 0x90, 0x00, // U+004D 'M'
55    0x00, 0x90, 0xd0, 0xd0, 0xb0, 0xb0, 0x90, 0x00, // U+004E 'N'
56    0x00, 0x60, 0x90, 0x90, 0x90, 0x90, 0x60, 0x00, // U+004F 'O'
57    0x00, 0xe0, 0x90, 0x90, 0xe0, 0x80, 0x80, 0x00, // U+0050 'P'
58    0x00, 0x60, 0x90, 0x90, 0x90, 0x90, 0x60, 0x30, // U+0051 'Q'
59    0x00, 0xe0, 0x90, 0x90, 0xe0, 0x90, 0x90, 0x00, // U+0052 'R'
60    0x00, 0x70, 0x80, 0x60, 0x10, 0x10, 0xe0, 0x00, // U+0053 'S'
61    0x00, 0xf8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, // U+0054 'T'
62    0x00, 0x90, 0x90, 0x90, 0x90, 0x90, 0x70, 0x00, // U+0055 'U'
63    0x00, 0x90, 0x90, 0x90, 0x90, 0x60, 0x60, 0x00, // U+0056 'V'
64    0x00, 0x90, 0x90, 0x90, 0xf0, 0xf0, 0x90, 0x00, // U+0057 'W'
65    0x00, 0x90, 0x90, 0x60, 0x60, 0x90, 0x90, 0x00, // U+0058 'X'
66    0x00, 0x90, 0x90, 0x90, 0x70, 0x10, 0xe0, 0x00, // U+0059 'Y'
67    0x00, 0xf0, 0x10, 0x20, 0x40, 0x80, 0xf0, 0x00, // U+005A 'Z'
68    0x70, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x70, // U+005B '['
69    0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, // U+005C '\\'
70    0x70, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x70, // U+005D ']'
71    0x00, 0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00, // U+005E '^'
72    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, // U+005F '_'
73    0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0060 '`'
74    0x00, 0x00, 0x60, 0x10, 0x70, 0x90, 0x70, 0x00, // U+0061 'a'
75    0x80, 0x80, 0xe0, 0x90, 0x90, 0x90, 0xe0, 0x00, // U+0062 'b'
76    0x00, 0x00, 0x70, 0x80, 0x80, 0x80, 0x70, 0x00, // U+0063 'c'
77    0x10, 0x10, 0x70, 0x90, 0x90, 0x90, 0x70, 0x00, // U+0064 'd'
78    0x00, 0x00, 0x70, 0x90, 0xf0, 0x80, 0x70, 0x00, // U+0065 'e'
79    0x30, 0x40, 0x40, 0xe0, 0x40, 0x40, 0x40, 0x00, // U+0066 'f'
80    0x00, 0x00, 0x70, 0x90, 0x90, 0x60, 0x10, 0xe0, // U+0067 'g'
81    0x80, 0x80, 0xe0, 0x90, 0x90, 0x90, 0x90, 0x00, // U+0068 'h'
82    0x00, 0x20, 0x00, 0x60, 0x20, 0x20, 0x30, 0x00, // U+0069 'i'
83    0x00, 0x20, 0x00, 0x20, 0x20, 0x20, 0x20, 0xc0, // U+006A 'j'
84    0x80, 0x80, 0x90, 0xa0, 0xc0, 0xa0, 0x90, 0x00, // U+006B 'k'
85    0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x30, 0x00, // U+006C 'l'
86    0x00, 0x00, 0x90, 0xf0, 0xf0, 0x90, 0x90, 0x00, // U+006D 'm'
87    0x00, 0x00, 0xe0, 0x90, 0x90, 0x90, 0x90, 0x00, // U+006E 'n'
88    0x00, 0x00, 0x60, 0x90, 0x90, 0x90, 0x60, 0x00, // U+006F 'o'
89    0x00, 0x00, 0xe0, 0x90, 0x90, 0xe0, 0x80, 0x80, // U+0070 'p'
90    0x00, 0x00, 0x70, 0x90, 0x90, 0x70, 0x10, 0x10, // U+0071 'q'
91    0x00, 0x00, 0x70, 0x90, 0x80, 0x80, 0x80, 0x00, // U+0072 'r'
92    0x00, 0x00, 0x70, 0x80, 0x60, 0x10, 0xe0, 0x00, // U+0073 's'
93    0x40, 0x40, 0xe0, 0x40, 0x40, 0x40, 0x30, 0x00, // U+0074 't'
94    0x00, 0x00, 0x90, 0x90, 0x90, 0x90, 0x70, 0x00, // U+0075 'u'
95    0x00, 0x00, 0x90, 0x90, 0x90, 0x60, 0x60, 0x00, // U+0076 'v'
96    0x00, 0x00, 0x90, 0x90, 0xf0, 0xf0, 0x90, 0x00, // U+0077 'w'
97    0x00, 0x00, 0x90, 0x60, 0x60, 0x90, 0x90, 0x00, // U+0078 'x'
98    0x00, 0x00, 0x90, 0x90, 0x90, 0x70, 0x10, 0xe0, // U+0079 'y'
99    0x00, 0x00, 0xf0, 0x10, 0x20, 0x40, 0xf0, 0x00, // U+007A 'z'
100    0x30, 0x40, 0x40, 0xc0, 0xc0, 0x40, 0x40, 0x30, // U+007B '{'
101    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, // U+007C '|'
102    0xc0, 0x20, 0x20, 0x30, 0x30, 0x20, 0x20, 0xc0, // U+007D '}'
103    0x00, 0x00, 0x00, 0x48, 0xb0, 0x00, 0x00, 0x00, // U+007E '~'
104];
105
106/// [`BitmapFont`] descriptor for the Spleen 5x8 bitmap above.
107pub const SPLEEN_5X8: BitmapFont = BitmapFont {
108    glyph_w: 5,
109    glyph_h: 8,
110    first_char: 0x0020,
111    glyph_count: 95,
112    bitmap: &SPLEEN_5X8_BITMAP,
113    glyph_advances: None,
114    advance_x: 5,
115    line_height: 8,
116    bit_order: BitOrder::Msb,
117};
118
119/// Shear the upper half of each 5x8 glyph one pixel to the right.
120///
121/// The result occupies a 6x8 cell but keeps the original five-pixel advance,
122/// so it reads as a compact italic face rather than a wider font. The one-pixel
123/// overhang is intentional and costs no extra runtime geometry.
124const fn italicize_spleen_5x8() -> [u8; 760] {
125    let mut italic = SPLEEN_5X8_BITMAP;
126    let mut glyph = 0;
127    while glyph < 95 {
128        let mut row = 0;
129        while row < 4 {
130            let offset = glyph * 8 + row;
131            italic[offset] >>= 1;
132            row += 1;
133        }
134        glyph += 1;
135    }
136    italic
137}
138
139/// ASCII U+0020..U+007E using Spleen's 5x8 forms with a one-pixel italic
140/// overhang. Pixels remain MSB-first; the sixth column contains the shear.
141pub const SPLEEN_5X8_ITALIC_BITMAP: [u8; 760] = italicize_spleen_5x8();
142
143/// Compact italic Spleen descriptor. Glyph cells are 6x8 to preserve the
144/// sheared edge, while the five-pixel advance keeps text metrics unchanged.
145pub const SPLEEN_5X8_ITALIC: BitmapFont = BitmapFont {
146    glyph_w: 6,
147    glyph_h: 8,
148    first_char: 0x0020,
149    glyph_count: 95,
150    bitmap: &SPLEEN_5X8_ITALIC_BITMAP,
151    glyph_advances: None,
152    advance_x: 5,
153    line_height: 8,
154    bit_order: BitOrder::Msb,
155};
156
157#[cfg(test)]
158mod tests {
159    use super::*;
160
161    #[test]
162    fn italic_face_shears_the_upper_half_without_widening_text_metrics() {
163        let h = ('H' as usize - 0x20) * 8;
164        assert_eq!(SPLEEN_5X8_ITALIC_BITMAP[h + 1], SPLEEN_5X8_BITMAP[h + 1] >> 1);
165        assert_eq!(SPLEEN_5X8_ITALIC_BITMAP[h + 4], SPLEEN_5X8_BITMAP[h + 4]);
166        assert_eq!(SPLEEN_5X8_ITALIC.glyph_w, 6);
167        assert_eq!(SPLEEN_5X8_ITALIC.text_width("HORIZON"), 35);
168    }
169}