README: mention how to create tinyfont files briefly
[fbpad.git] / font.c
blob61641347b5c9d8f44d0d7e13440d9629acd8e04a
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 fd;
12 int rows;
13 int cols;
14 int n;
15 int *glyphs;
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 struct font *font_open(char *path)
39 struct font *font;
40 struct tinyfont head;
41 font = malloc(sizeof(*font));
42 font->fd = open(path, O_RDONLY);
43 if (font->fd == -1)
44 return NULL;
45 fcntl(font->fd, F_SETFD, fcntl(font->fd, F_GETFD) | FD_CLOEXEC);
46 if (read(font->fd, &head, sizeof(head)) != sizeof(head))
47 return NULL;
48 font->n = head.n;
49 font->rows = head.rows;
50 font->cols = head.cols;
51 font->glyphs = malloc(font->n * sizeof(int));
52 if (read(font->fd, font->glyphs, font->n * sizeof(int)) != font->n * sizeof(int))
53 return NULL;
54 return font;
57 static int find_glyph(struct font *font, int c)
59 int l = 0;
60 int h = font->n;
61 while (l < h) {
62 int m = (l + h) / 2;
63 if (font->glyphs[m] == c)
64 return m;
65 if (c < font->glyphs[m])
66 h = m;
67 else
68 l = m + 1;
70 return -1;
73 int font_bitmap(struct font *font, void *dst, int c)
75 int i = find_glyph(font, c);
76 if (i < 0)
77 return 1;
78 lseek(font->fd, sizeof(struct tinyfont) + font->n * sizeof(int) +
79 i * font->rows * font->cols, 0);
80 read(font->fd, dst, font->rows * font->cols);
81 return 0;
84 void font_free(struct font *font)
86 free(font->glyphs);
87 close(font->fd);
88 free(font);
91 int font_rows(struct font *font)
93 return font->rows;
96 int font_cols(struct font *font)
98 return font->cols;