Fixed red build
[kugel-rb.git] / firmware / font.c
blob2fe43b5fd3e52a78bd2d514a4d1b0cf9eba5a452
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (c) 2002 by Greg Haerr <greg@censoft.com>
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 * Rockbox startup font initialization
21 * This file specifies which fonts get compiled-in and
22 * loaded at startup, as well as their mapping into
23 * the FONT_SYSFIXED, FONT_UI and FONT_MP3 ids.
25 #include "config.h"
27 #if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR)
29 #include <stdio.h>
30 #include <string.h>
31 #include "lcd.h"
32 #include "font.h"
33 #include "file.h"
34 #include "debug.h"
35 #include "panic.h"
37 #ifndef O_BINARY
38 #define O_BINARY 0
39 #endif
41 /* compiled-in font */
42 extern struct font sysfont;
44 /* structure filled in by font_load */
45 static struct font font_ui;
47 /* system font table, in order of FONT_xxx definition */
48 static struct font* sysfonts[MAXFONTS] = { &sysfont, &font_ui };
50 /* static buffer allocation structures */
51 static unsigned char mbuf[MAX_FONT_SIZE];
52 static unsigned char *freeptr = mbuf;
53 static unsigned char *fileptr;
54 static unsigned char *eofptr;
56 static void rotate_font_bits(struct font* pf);
57 static void rotleft(unsigned char *dst,
58 bitmap_t *src,
59 unsigned int width,
60 unsigned int height);
62 void font_init(void)
64 rotate_font_bits(&sysfont);
65 memset(&font_ui, 0, sizeof(struct font));
68 static int readshort(unsigned short *sp)
70 unsigned short s;
72 s = *fileptr++ & 0xff;
73 *sp = (*fileptr++ << 8) | s;
74 return (fileptr <= eofptr);
77 static int readlong(unsigned long *lp)
79 unsigned long l;
81 l = *fileptr++ & 0xff;
82 l |= *fileptr++ << 8;
83 l |= *fileptr++ << 16;
84 *lp = (*fileptr++ << 24) | l;
85 return (fileptr <= eofptr);
88 /* read count bytes*/
89 static int readstr(char *buf, int count)
91 int n = count;
93 while (--n >= 0)
94 *buf++ = *fileptr++;
95 return (fileptr <= eofptr)? count: 0;
98 /* read totlen bytes, return NUL terminated string*/
99 /* may write 1 past buf[totlen]; removes blank pad*/
100 static int readstrpad(char *buf, int totlen)
102 char *p = buf;
103 int n = totlen;
105 while (--n >= 0)
106 *p++ = *fileptr++;
107 if (fileptr > eofptr)
108 return 0;
110 p = &buf[totlen];
111 *p-- = 0;
112 while (*p == ' ' && p >= buf)
113 *p-- = '\0';
114 return totlen;
117 void font_reset(void)
119 memset(&font_ui, 0, sizeof(struct font));
122 /* read and load font into incore font structure*/
123 struct font* font_load(char *path)
125 int fd, filesize;
126 unsigned short maxwidth, height, ascent, pad;
127 unsigned long firstchar, defaultchar, size;
128 unsigned long i, nbits, noffset, nwidth;
129 char version[4+1];
130 char copyright[256+1];
131 struct font* pf = &font_ui;
133 /* open and read entire font file*/
134 fd = open(path, O_RDONLY|O_BINARY);
135 if (fd < 0) {
136 DEBUGF("Can't open font: %s\n", path);
137 return NULL;
140 font_reset();
142 /* currently, font loading replaces earlier font allocation*/
143 freeptr = (unsigned char *)(((int)mbuf + 3) & ~3);
145 fileptr = freeptr;
146 filesize = read(fd, fileptr, MAX_FONT_SIZE);
147 eofptr = fileptr + filesize;
149 /* no need for multiple font loads currently*/
150 /*freeptr += filesize;*/
151 /*freeptr = (unsigned char *)(freeptr + 3) & ~3;*/ /* pad freeptr*/
153 close(fd);
154 if (filesize == MAX_FONT_SIZE) {
155 DEBUGF("Font %s too large: %d\n", path, filesize);
156 return NULL;
159 /* read magic and version #*/
160 memset(version, 0, sizeof(version));
161 if (readstr(version, 4) != 4)
162 return NULL;
163 if (strcmp(version, VERSION) != 0)
164 return NULL;
166 /* internal font name*/
167 pf->name = fileptr;
168 if (readstrpad(pf->name, 64) != 64)
169 return NULL;
171 /* copyright, not currently stored*/
172 if (readstrpad(copyright, 256) != 256)
173 return NULL;
175 /* font info*/
176 if (!readshort(&maxwidth))
177 return NULL;
178 pf->maxwidth = maxwidth;
179 if (!readshort(&height))
180 return NULL;
181 pf->height = height;
182 if (!readshort(&ascent))
183 return NULL;
184 pf->ascent = ascent;
185 if (!readshort(&pad))
186 return NULL;
187 if (!readlong(&firstchar))
188 return NULL;
189 pf->firstchar = firstchar;
190 if (!readlong(&defaultchar))
191 return NULL;
192 pf->defaultchar = defaultchar;
193 if (!readlong(&size))
194 return NULL;
195 pf->size = size;
197 /* get variable font data sizes*/
198 /* # words of bitmap_t*/
199 if (!readlong(&nbits))
200 return NULL;
201 pf->bits_size = nbits;
203 /* # longs of offset*/
204 if (!readlong(&noffset))
205 return NULL;
207 /* # bytes of width*/
208 if (!readlong(&nwidth))
209 return NULL;
211 /* variable font data*/
212 pf->bits = (bitmap_t *)fileptr;
213 for (i=0; i<nbits; ++i)
214 if (!readshort(&pf->bits[i]))
215 return NULL;
216 /* pad to longword boundary*/
217 fileptr = (unsigned char *)(((int)fileptr + 3) & ~3);
219 if (noffset) {
220 pf->offset = (unsigned long *)fileptr;
221 for (i=0; i<noffset; ++i)
222 if (!readlong(&pf->offset[i]))
223 return NULL;
225 else
226 pf->offset = NULL;
228 if (nwidth) {
229 pf->width = (unsigned char *)fileptr;
230 fileptr += nwidth*sizeof(unsigned char);
232 else
233 pf->width = NULL;
235 if (fileptr > eofptr)
236 return NULL;
238 /* one-time rotate font bits to rockbox format*/
239 rotate_font_bits(pf);
241 return pf; /* success!*/
245 * Return a pointer to an incore font structure.
246 * If the requested font isn't loaded/compiled-in,
247 * decrement the font number and try again.
249 struct font* font_get(int font)
251 struct font* pf;
253 if (font >= MAXFONTS)
254 font = 0;
256 while (1) {
257 pf = sysfonts[font];
258 if (pf && pf->height)
259 return pf;
260 if (--font < 0)
261 panicf("No font!");
265 /* convert font bitmap data inplace to rockbox format*/
266 static void rotate_font_bits(struct font* pf)
268 int i;
269 unsigned long defaultchar = pf->defaultchar - pf->firstchar;
270 bool did_defaultchar = false;
271 unsigned char buf[256];
273 for (i=0; i<pf->size; ++i) {
274 bitmap_t *bits = pf->bits +
275 (pf->offset ? pf->offset[i] : (pf->height * i));
276 int width = pf->width? pf->width[i]: pf->maxwidth;
277 int src_bytes = BITMAP_BYTES(width) * pf->height;
280 * Due to the way the offset map works,
281 * non-mapped characters are mapped to the default
282 * character, and shouldn't be rotated twice.
285 if (pf->offset && pf->offset[i] == defaultchar) {
286 if (did_defaultchar)
287 continue;
288 did_defaultchar = true;
291 /* rotate left for lcd_bitmap function input*/
292 rotleft(buf, bits, width, pf->height);
294 /* copy back into original location*/
295 memcpy(bits, buf, src_bytes);
300 * Take an bitmap_t bitmap and convert to Rockbox format.
301 * Used for converting font glyphs for the time being.
302 * Can use for standard X11 and Win32 images as well.
304 * Doing it this way keeps fonts in standard formats,
305 * as well as keeping Rockbox hw bitmap format.
307 static void rotleft(unsigned char *dst, bitmap_t *src, unsigned int width,
308 unsigned int height)
310 unsigned int i,j;
311 unsigned int dst_col = 0; /* destination column*/
312 unsigned int dst_shift = 0; /* destination shift amount*/
313 unsigned int dst_linelen; /* # bytes per output row*/
314 unsigned int src_words; /* # words of input image*/
316 /* calc bytes per output row*/
317 dst_linelen = (height-1)/8+1;
319 /* calc words of input image*/
320 src_words = BITMAP_WORDS(width) * height;
322 /* clear background*/
323 memset(dst, 0, dst_linelen*width);
325 for (i=0; i < src_words; i++) {
326 bitmap_t srcmap; /* current src input bit*/
327 bitmap_t dstmap; /* current dst output bit*/
329 /* calc src input bit*/
330 srcmap = 1 << (sizeof(bitmap_t)*8-1);
332 /* calc dst output bit*/
333 if (i>0 && (i%8==0)) {
334 ++dst_col;
335 dst_shift = 0;
337 dstmap = 1 << dst_shift++;
339 /* for each input column...*/
340 for(j=0; j < width; j++) {
342 /* calc input bitmask*/
343 bitmap_t bit = srcmap >> j;
344 if (bit==0) {
345 srcmap = 1 << (sizeof(bitmap_t)*8-1);
346 bit = srcmap >> (j % 16);
349 /* if set in input, set in rotated output*/
350 if (bit & src[i]) {
351 /* input column j becomes output row*/
352 dst[j*dst_linelen + dst_col] |= dstmap;
354 /*debugf((bit & src[i])? "*": ".");*/
356 /*debugf("\n");*/
359 #endif /* HAVE_LCD_BITMAP */
361 /* -----------------------------------------------------------------
362 * local variables:
363 * eval: (load-file "rockbox-mode.el")
364 * vim: et sw=4 ts=8 sts=4 tw=78
365 * end: