term: more efficient management of scrolling history
[fbpad.git] / font.c
bloba661e58bc592ee7391a69cf6156e93347bc0c421
1 #include <fcntl.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5 #include <string.h>
6 #include "fbpad.h"
8 struct font {
9 int rows;
10 int cols;
11 int n;
12 int *glyphs;
13 char *data;
17 * tinyfont format:
19 * sig[8] "tinyfont"
20 * ver 0
21 * n number of glyphs
22 * rows glyph rows
23 * cols glyph cols
25 * glyphs[n] unicode character numbers (int)
26 * bitmaps[n] character bitmaps (char[rows * cols])
28 struct tinyfont {
29 char sig[8];
30 int ver;
31 int n;
32 int rows, cols;
35 static void *xread(int fd, int len)
37 void *buf = malloc(len);
38 if (buf && read(fd, buf, len) == len)
39 return buf;
40 free(buf);
41 return NULL;
44 struct font *font_open(char *path)
46 struct font *font;
47 struct tinyfont head;
48 int fd = open(path, O_RDONLY);
49 if (fd < 0 || read(fd, &head, sizeof(head)) != sizeof(head)) {
50 close(fd);
51 return NULL;
53 font = malloc(sizeof(*font));
54 font->n = head.n;
55 font->rows = head.rows;
56 font->cols = head.cols;
57 font->glyphs = xread(fd, font->n * sizeof(int));
58 font->data = xread(fd, font->n * font->rows * font->cols);
59 close(fd);
60 if (!font->glyphs || !font->data) {
61 font_free(font);
62 return NULL;
64 return font;
67 static int find_glyph(struct font *font, int c)
69 int l = 0;
70 int h = font->n;
71 while (l < h) {
72 int m = (l + h) / 2;
73 if (font->glyphs[m] == c)
74 return m;
75 if (c < font->glyphs[m])
76 h = m;
77 else
78 l = m + 1;
80 return -1;
83 int font_bitmap(struct font *font, void *dst, int c)
85 int i = find_glyph(font, c);
86 int len = font->rows * font->cols;
87 if (i < 0)
88 return 1;
89 memcpy(dst, font->data + i * len, len);
90 return 0;
93 void font_free(struct font *font)
95 if (font->data)
96 free(font->data);
97 if (font->glyphs)
98 free(font->glyphs);
99 free(font);
102 int font_rows(struct font *font)
104 return font->rows;
107 int font_cols(struct font *font)
109 return font->cols;