23 glyph_t glyph = { .encoding = -1, .bytes = (int[...]){}, .width = 0 };
25 while (!File::end(f)) {
28 string[*] tokens = String::split(l, " ");
34 glyph.encoding = atoi(tokens[1]);
37 glyph.advance = atoi(tokens[1]);
40 glyph.width = atoi(tokens[1]);
41 glyph.height = atoi(tokens[2]);
42 glyph.x_off = atoi(tokens[3]);
43 glyph.y_off = glyph.height + atoi(tokens[4]);
48 int byte_stride = ceil(glyph.width/8);
49 for (int y = 0; y < glyph.height; y++) {
51 for (int x = 0; x < byte_stride; x++) {
52 string v = String::substr(l, x * 2, 2);
53 glyph.bytes[dim(glyph.bytes)] = atoi(v, 16);
62 font_t read_font(file f) {
63 font_t font = { .glyphs = {}, .default_char = -1 };
66 while (in_head && !File::end(f)) {
67 string l = File::fgets(f);
69 string[*] tokens = String::split(l, " ");
72 font.default_char = atoi(tokens[1]);
75 font.ascent = atoi(tokens[1]);
82 while (!File::end(f)) {
83 glyph_t glyph = read_glyph(f);
84 if (glyph.encoding == -1)
86 font.glyphs[dim(font.glyphs)] = glyph;
96 for (int i = 0; i < 8; i++)
97 dest |= ((x >> (7 - i)) & 1) << i;
101 void print_font(font_t font, string font_name) {
102 int width = font.glyphs[0].width;
103 int height = font.glyphs[0].height;
104 int max_width = width;
105 int max_height = height;
106 int[256] pos = { -1 ... };
108 bool fixed_size = true;
110 for (int i = 1; i < dim(font.glyphs); i++) {
111 if (font.glyphs[i].width != width ||
112 font.glyphs[i].height != height)
116 max_width = max(max_width, font.glyphs[i].width);
117 max_height = max(max_height, font.glyphs[i].height);
120 if (font.default_char == -1)
121 font.default_char = font.glyphs[0].encoding;
123 /* build byte array */
124 for (int i = 0; i < dim(font.glyphs); i++) {
125 pos[font.glyphs[i].encoding] = dim(bytes);
126 for (int b = 0; b < dim(font.glyphs[i].bytes); b++)
127 bytes[dim(bytes)] = font.glyphs[i].bytes[b];
130 /* Fill in default glyph */
131 for (int i = 0; i < dim(pos); i++)
133 pos[i] = pos[font.default_char];
135 printf("#include \"ao_draw.h\"\n");
136 printf("static const uint8_t %s_bytes[%d] = {", font_name, dim(bytes));
137 for (int b = 0; b < dim(bytes); b++) {
142 printf("0x%02x,", flip_byte(bytes[b]));
146 printf("static const uint16_t %s_pos[%d] = {", font_name, dim(pos));
147 for (int i = 0; i < dim(pos); i++) {
152 printf("%6d,", pos[i]);
156 printf("#define GLYPH_WIDTH_MAX %d\n", max_width);
157 printf("#define GLYPH_HEIGHT_MAX %d\n", max_height);
159 printf("#define GLYPH_WIDTH %d\n", width);
160 printf("#define GLYPH_HEIGHT %d\n", height);
161 printf("#define GLYPH_ASCENT %d\n", font.ascent);
163 printf("static const struct ao_glyph_metrics %s_metrics[%d] = {\n", font_name, dim(pos));
164 for (int i = 0; i < dim(pos); i++) {
166 for (int j = 0; j < dim(font.glyphs); j++) {
167 if (font.glyphs[j].encoding == i) {
173 if (' ' <= i && i <= '~')
174 c = sprintf("%c", i);
176 c = sprintf("%02x", i);
177 printf(" { .width = %d, .height = %d, .x_off = %d, .y_off = %d, .advance = %d }, /* %s */\n",
178 font.glyphs[g].width, font.glyphs[g].height,
179 font.glyphs[g].x_off, font.glyphs[g].y_off, font.glyphs[g].advance, c);
183 printf("const struct ao_font %s_font = {\n", font_name);
184 printf("\t.bytes = %s_bytes,\n", font_name);
185 printf("\t.pos = %s_pos,\n", font_name);
187 printf("\t.metrics = %s_metrics,\n", font_name);
188 printf("\t.max_width = %d,\n", max_width);
189 printf("\t.max_height = %d,\n", max_height);
190 printf("\t.ascent = %d,\n", font.ascent);
198 for (int i = String::rindex(a, "/") + 1; i < String::length(a); i++) {
202 if (!(Ctype::isalnum(c) || c == '_'))
206 if (!Ctype::isalpha(r[0]))
214 twixt (file f = File::open(name, "r"); File::close(f)) {
215 font_t font = read_font(f);
216 print_font(font, to_c(name));