#include #include #include #include #include #include #include #include #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(const char *path, struct font_info *into) { struct file *f = open_file(path); if (!f) PANIC("Can't open font file sent by get_font."); read_line_from_file(f, line_buf, LINE_BUF_SIZE - 1); if (!strequ(line_buf, "STARTFONT 2.1")) { close_file(f); 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; } } } close_file(f); f = 0; 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: if (f) close_file(f); for (uint16_t i = 0; i < 256; ++i) if (into->bitmaps[i]) free_block(into->bitmaps[i]); return false; }