font: load font glyphs into memory
[fbpad.git] / font.c
blob6a0aa00cd1a6415d2cc69ce1fc24fbeac1da7d3a
1 #include <fcntl.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5 #include <string.h>
6 #include "config.h"
7 #include "font.h"
8 #include "util.h"
10 struct font {
11 int rows;
12 int cols;
13 int n;
14 int *glyphs;
15 char *data;
19 * tinyfont format:
21 * sig[8] "tinyfont"
22 * ver 0
23 * n number of glyphs
24 * rows glyph rows
25 * cols glyph cols
27 * glyphs[n] unicode character numbers (int)
28 * bitmaps[n] character bitmaps (char[rows * cols])
30 struct tinyfont {
31 char sig[8];
32 int ver;
33 int n;
34 int rows, cols;
37 static void *xread(int fd, int len)
39 void *buf = malloc(len);
40 if (buf && read(fd, buf, len) == len)
41 return buf;
42 free(buf);
43 return NULL;
46 struct font *font_open(char *path)
48 struct font *font;
49 struct tinyfont head;
50 int fd = open(path, O_RDONLY);
51 if (fd < 0 || read(fd, &head, sizeof(head)) != sizeof(head)) {
52 close(fd);
53 return NULL;
55 font = malloc(sizeof(*font));
56 font->n = head.n;
57 font->rows = head.rows;
58 font->cols = head.cols;
59 font->glyphs = xread(fd, font->n * sizeof(int));
60 font->data = xread(fd, font->n * font->rows * font->cols);
61 close(fd);
62 if (!font->glyphs || !font->data) {
63 font_free(font);
64 return NULL;
66 return font;
69 static int find_glyph(struct font *font, int c)
71 int l = 0;
72 int h = font->n;
73 while (l < h) {
74 int m = (l + h) / 2;
75 if (font->glyphs[m] == c)
76 return m;
77 if (c < font->glyphs[m])
78 h = m;
79 else
80 l = m + 1;
82 return -1;
85 int font_bitmap(struct font *font, void *dst, int c)
87 int i = find_glyph(font, c);
88 int len = font->rows * font->cols;
89 if (i < 0)
90 return 1;
91 memcpy(dst, font->data + i * len, len);
92 return 0;
95 void font_free(struct font *font)
97 if (font->data)
98 free(font->data);
99 if (font->glyphs)
100 free(font->glyphs);
101 free(font);
104 int font_rows(struct font *font)
106 return font->rows;
109 int font_cols(struct font *font)
111 return font->cols;