[simulator] Kill Cocoa and Console, move Qt4 one level up
[wikipediardware.git] / gui-lib / fontfile.c
blob759578ca42f61518169e355bd32df3b4c33678a7
1 /*
2 * guilib - a minimal pixel framework
3 * Copyright (c) 2008, 2009 Daniel Mack <daniel@caiaq.de>
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <stdlib.h>
20 #include <wikilib.h>
21 #include <msg.h>
22 #include <file-io.h>
23 #include <malloc.h>
24 #include <wl-endian.h>
25 #include <decompress.h>
27 /* gui-lib includes */
28 #include "glyph.h"
29 #include "fontfile.h"
31 /* reads the file described in glyphs/fonts/README */
33 struct glyph_spacing {
34 unsigned short next_glyph;
35 unsigned char x, y;
36 } __attribute__((packed));
38 unsigned char *file_buf;
39 unsigned int *font_index;
40 unsigned int file_size;
41 unsigned int n_fonts;
43 unsigned int guilib_nr_fonts (void)
45 return n_fonts;
48 int glyph_spacing (struct glyph *first, unsigned short second,
49 unsigned char *x, unsigned char *y)
51 unsigned int i;
52 char *tmp = (char *) first;
53 /* jump over fixed members and bitmap data */
54 struct glyph_spacing *space = (struct glyph_spacing *)
55 (tmp + sizeof(*first) +
56 ((first->width * first->height) + 7) / 8);
58 for (i = 0; i < first->n_spacing_hints; i++, space++)
59 if (space->next_glyph == second) {
60 *x = space->x;
61 *y = space->y;
62 return 1;
65 return 0;
68 unsigned int read_u32(const unsigned char* start, unsigned int offset)
70 if (offset % 4 != 0) {
71 #if BYTE_ORDER == LITTLE_ENDIAN
72 return (start+offset)[3] << 24 |
73 (start+offset)[2] << 16 |
74 (start+offset)[1] << 8 |
75 (start+offset)[0] << 0;
76 #else
77 return (start+offset)[0] << 24 |
78 (start+offset)[1] << 16 |
79 (start+offset)[2] << 8 |
80 (start+offset)[3] << 0;
81 #endif
82 } else {
83 return *(unsigned int *)(start + offset);
87 const struct glyph *get_glyph(unsigned int font, unsigned int glyph)
89 unsigned int font_start, n_glyphs, glyph_index, *glyph_table;
91 /* the entry in the font_index table points to the position in our
92 * file where the font definition starts */
93 font_start = WL_LTONL(font_index[font]);
95 if (font_start > file_size)
96 return NULL;
98 /* the first integer at this position is the numbers of glyphs */
99 n_glyphs = WL_LTONL(read_u32(file_buf, font_start));
100 if (glyph >= n_glyphs)
101 return NULL;
103 /* subsequent indices are relative to the beginning of the
104 * glyph table */
105 font_start += sizeof(n_glyphs);
107 /* look up our glyph and cast the struct */
108 glyph_table = (unsigned int *) (file_buf + font_start);
109 glyph_index = WL_LTONL(read_u32(file_buf, font_start + 4 * glyph));
111 return (struct glyph *) (file_buf + font_start + glyph_index);
114 int read_font_file(const char *filename)
116 void *buf;
118 buf = decompress(filename, &file_size);
119 if (!buf)
120 return -1;
122 file_buf = buf;
124 n_fonts = *(unsigned int *) file_buf;
126 msg(MSG_INFO, "font file has %d fonts in %d bytes, buf %p\n", n_fonts, file_size, file_buf);
127 file_buf += sizeof(n_fonts);
129 font_index = WL_LTONL((unsigned int *) file_buf);
130 return 0;