-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpsf.hh
79 lines (66 loc) · 2.36 KB
/
psf.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#pragma once
#include <stdint.h>
namespace {
namespace psf {
class font {
public:
uint_fast32_t headersize;
uint_fast32_t flags;
uint_fast32_t nglyphs;
uint_fast32_t bytesperglyph;
uint_fast32_t height;
uint_fast32_t width;
uint8_t *bytes;
constexpr inline font(uint8_t *_bytes) : bytes(_bytes) {}
private:
constexpr inline bool parse_psf1() {
flags = bytes[2];
height = bytesperglyph = bytes[3];
// 512 if flag bit 1 is set, 256 otherwise
nglyphs = (flags & 1) << 8 | 0xff;
headersize = 4;
width = 8;
return (flags & ~3);
}
constexpr inline uint_fast32_t lsbint32(uint_fast16_t i) {
i *= 4;
// I checked the C++ Operator Precedence and this works
return bytes[i] | bytes[i + 1] << 8 | bytes[i + 2] << 16 | bytes[i + 3] << 24;
}
constexpr inline bool parse_psf2() {
// check version
if(bytes[4] || bytes[5] || bytes[6] || bytes[7]) return true;
headersize = lsbint32(2);
flags = lsbint32(3);
nglyphs = lsbint32(4);
bytesperglyph = lsbint32(5);
height = lsbint32(6);
width = lsbint32(7);
// only valid flag is 1 aka PSF2_HAS_UNICODE_TABLE
// and it isnt obvious to me how to parse that table
// TODO: support the unicode table
if(flags) return true;
return bytesperglyph != height * ((width + 7) / 8);
}
public:
/**
* Parses the PSF 1 or 2 header.
*
* Doesn't support all modes/flags yet.
*
* Returns `true` on error.
*/
constexpr inline bool parse() {
if(bytes[0] == 0x36 && bytes[1] == 0x04) return parse_psf1();
else if(bytes[0] == 0x72 && bytes[1] == 0xb5 && bytes[2] == 0x4a &&
bytes[3] == 0x86)
return parse_psf1();
else
return true;
}
constexpr inline uint8_t *operator[](uint32_t c) {
return &bytes[headersize + c * bytesperglyph];
}
};
}
}