-
Notifications
You must be signed in to change notification settings - Fork 0
/
d_fnt.h
135 lines (111 loc) · 2.65 KB
/
d_fnt.h
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// TODO: u16 #chars
// TODO: utf8
// dirty bitmap font format
// -----------------------------------
// | magic u8[9] (d1Rtyf0Nt) |
// -----------------------------------
// | w u8 |
// -----------------------------------
// | h u8 |
// -----------------------------------
// | #chars u8 |
// -----------------------------------
// | chars u8[#chars] |
// -----------------------------------
// | bitmap u8[#chars * w * h / 8] |
// -----------------------------------
#ifndef D_FNT_H
#define D_FNT_H
void d_fnt_decode_to_png(uint8_t* bytes, char* path);
uint8_t* d_fnt_encode_from_png(
char* path,
uint8_t gw,
uint8_t gh,
char* chars,
size_t* osize
);
#endif
#ifdef D_IMPL
#define D_FNT_IMPL
#endif
#ifdef D_FNT_IMPL
#ifndef D_FNT_IMPL_ONCE
#define D_FNT_IMPL_ONCE
// impl
void d_fnt_decode_to_png(
uint8_t* bytes,
char* path
) {
uint8_t gw = bytes[9];
uint8_t gh = bytes[10];
uint8_t chars_size = bytes[11];
size_t bitmap_size = ceil(chars_size * gw * gh / 8.0f);
uint8_t* bitmap_buf = bytes + 9 + 1 + 1 + 1 + chars_size;
uint8_t* pixels = calloc(chars_size * gw * gh * 4, 1);
// TODO: support multiple columns
for (int i = 0; i < bitmap_size; i++) {
for (int j = 0; j < 8; j++) {
if (bitmap_buf[i] & (1 << (7 - j))) {
pixels[(i * 8 + j) * 4 + 3] = 255;
}
}
}
stbi_write_png(
path,
gw,
gh * chars_size,
4,
pixels,
gw * 4
);
}
uint8_t* d_fnt_encode_from_png(
char* path,
uint8_t gw,
uint8_t gh,
char* chars,
size_t* osize
) {
int w, h;
uint8_t* pixels = stbi_load(path, &w, &h, NULL, 4);
uint8_t num_cols = w / gw;
uint8_t num_rows = h / gh;
size_t chars_size = strlen(chars);
size_t bitmap_size = ceil(chars_size * gw * gh / 8.0f);
size_t total_size =
9 // magic
+ 1 // w
+ 1 // h
+ 1 // #chars
+ chars_size // chars
+ bitmap_size; // bitmap
if (osize) {
*osize = total_size;
}
uint8_t* buf = malloc(total_size);
uint8_t* chars_buf = buf + 9 + 1 + 1 + 1;
uint8_t* bitmap_buf = chars_buf + chars_size;
memcpy(buf, "d1Rtyf0Nt", 9);
buf[9] = gw;
buf[10] = gh;
buf[11] = chars_size;
memcpy(chars_buf, chars, chars_size);
memset(bitmap_buf, 0, bitmap_size);
int cursor = 0;
for (int row = 0; row < num_rows; row++) {
for (int col = 0; col < num_cols; col++) {
for (int y = 0; y < gh; y++) {
for (int x = 0; x < gw; x++) {
int i = (row * gh + y) * w + col * gw + x;
if (pixels[i * 4 + 3] > 0) {
bitmap_buf[cursor / 8] |= (1 << (7 - cursor % 8));
}
cursor++;
}
}
}
}
return buf;
}
#endif
#endif