Merge pull request #13 from rdebath/patch-fixes
[congif.git] / mbf.c
blobb576f96ddbe6b172dfe13a34acd1bcd0299489ee
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdint.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
10 #include "mbf.h"
12 Font *
13 load_font(const char *fname)
15 int fd;
16 char sig[4];
17 Header header;
18 int stride;
19 size_t ranges_size, data_size;
20 Font *font;
22 fd = open(fname, O_RDONLY);
23 if (fd == -1)
24 return NULL;
25 read(fd, sig, sizeof(sig));
26 if (memcmp(sig, (char []) {'M', 'B', 'F', 0x01}, sizeof(sig))) {
27 close(fd);
28 return NULL;
30 read(fd, &header, sizeof(header));
31 /* stride = ceil(w / 8) = floor(w / 8) + (w % 8 ? 1 : 0) */
32 stride = (header.w >> 3) + !!(header.w & 7);
33 ranges_size = header.nr * sizeof(Range);
34 data_size = header.ng * stride * header.h;
35 font = malloc(sizeof(Font) + ranges_size + data_size);
36 if (!font) {
37 close(fd);
38 return NULL;
40 font->stride = stride;
41 font->header = header;
42 font->ranges = (Range *) &font[1];
43 read(fd, font->ranges, ranges_size);
44 font->data = (uint8_t *) &font->ranges[header.nr];
45 read(fd, font->data, data_size);
46 close(fd);
47 return font;
50 int
51 search_glyph(Font *font, uint16_t code)
53 int index, i;
54 Range r;
56 index = 0;
57 for (i = 0; i < font->header.nr; i++) {
58 r = font->ranges[i];
59 if (code < r.offset)
60 return -1;
61 if (code < r.offset + r.length)
62 return index + code - r.offset;
63 index += r.length;
65 return -1;
68 int
69 get_index(Font *font, uint16_t code)
71 int index;
72 uint16_t *cur_code;
73 uint16_t codes[] = {code, 0xFFFD, 0x003F, 0x0020, 0};
75 for (cur_code = &codes[0]; *cur_code; cur_code++) {
76 index = search_glyph(font, *cur_code);
77 if (index != -1)
78 break;
80 return index;