summaryrefslogtreecommitdiff
path: root/src/user/libfont/bdf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/user/libfont/bdf.c')
-rw-r--r--src/user/libfont/bdf.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/src/user/libfont/bdf.c b/src/user/libfont/bdf.c
new file mode 100644
index 0000000..2c19a15
--- /dev/null
+++ b/src/user/libfont/bdf.c
@@ -0,0 +1,99 @@
+#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(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, &current))
+ 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;
+} \ No newline at end of file