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
80
81
82
83
84
85
86
87
88
|
#include <libfont/fonts.h>
#include <knob/format.h>
#include <knob/panic.h>
#include <knob/block.h>
#include <knob/heap.h>
#include <knob/file.h>
#include <stdbool.h>
#include <stdint.h>
#define LINE_BUF_SIZE 1000
char line_buf[LINE_BUF_SIZE];
static inline uint8_t hex_to_n(char ch) {
return ch - (ch >= 'A' ? 'A' - 10 : '0');
}
//very minimal implementation
bool try_load_bdf(struct file *f, struct font_info *into) {
read_line_from_file(f, line_buf, LINE_BUF_SIZE - 1);
if (!strequ(line_buf, "STARTFONT 2.1"))
return false;
for (uint16_t i = 0; i < 256; ++i)
into->bitmaps[i] = 0;
into->space_height = -1;
into->space_width = -1;
into->char_height = -1;
into->char_width = -1;
uint32_t current = 0;
while (read_line_from_file(f, line_buf, LINE_BUF_SIZE - 1)) {
if (blockequ(line_buf, "FONTBOUNDINGBOX ", 16)) {
uint32_t n;
uint32_t l = try_swtou(line_buf + 16, &n);
if (!l)
goto bad_format;
into->space_width = n;
into->char_width = n;
l = try_swtou(line_buf + 16 + l, &n);
if (!l)
goto bad_format;
into->space_height = n;
into->char_height = n;
}
else if (blockequ(line_buf, "ENCODING ", 9)) {
if (!try_swtou(line_buf + 9, ¤t))
goto bad_format;
}
else if (strequ(line_buf, "BITMAP")) {
if (current >= 256)
continue;
bool *bm = get_block(into->char_height * into->char_width);
if (!bm)
PANIC("could not allocate memory for font character bitmap");
into->bitmaps[current] = bm;
for (uint32_t y = 0; y < into->char_height; ++y) {
read_line_from_file(f, line_buf, LINE_BUF_SIZE - 1);
for (uint32_t x = 0; x < into->char_width; ++x)
bm[y * into->char_width + x] = (hex_to_n(line_buf[x / 4]) >> (3 - x % 4)) & 1;
}
}
}
if ((into->char_height == -1) ||
(into->char_width == -1) ||
(into->space_height == -1) ||
(into->space_width == -1))
goto bad_format;
if (!into->bitmaps[0]) {
const uint32_t bytes = (into->char_height * into->char_width - 1) / 8 + 1;
into->bitmaps[0] = get_block(bytes);
for (uint32_t i = 0; i < bytes; ++i)
into->bitmaps[0][i] = 0b01011010;
}
return true;
bad_format:
for (uint16_t i = 0; i < 256; ++i)
if (into->bitmaps[i])
free_block(into->bitmaps[i]);
return false;
}
|