blob: 03e18919daa36f2602f27aa96843bcc80db1c275 [file] [log] [blame]
Daniel Stenberg93b231c2002-09-12 13:33:59 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (c) 2002 by Greg Haerr <greg@censoft.com>
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
Daniel Stenberg93b231c2002-09-12 13:33:59 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21/*
22 * Rockbox startup font initialization
23 * This file specifies which fonts get compiled-in and
24 * loaded at startup, as well as their mapping into
25 * the FONT_SYSFIXED, FONT_UI and FONT_MP3 ids.
26 */
27#include "config.h"
28
29#if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR)
30
31#include <stdio.h>
32#include <string.h>
Nils Wallméniusdf155c82007-06-30 17:54:02 +000033#include "inttypes.h"
Daniel Stenberg93b231c2002-09-12 13:33:59 +000034#include "lcd.h"
35#include "font.h"
Björn Stenbergbed3d3f2002-09-20 08:07:51 +000036#include "file.h"
Daniel Stenberg93b231c2002-09-12 13:33:59 +000037#include "debug.h"
38#include "panic.h"
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +000039#include "rbunicode.h"
40/* Font cache includes */
41#include "font_cache.h"
42#include "lru.h"
Daniel Stenberg93b231c2002-09-12 13:33:59 +000043
Björn Stenbergbed3d3f2002-09-20 08:07:51 +000044#ifndef O_BINARY
45#define O_BINARY 0
Daniel Stenberg93b231c2002-09-12 13:33:59 +000046#endif
Daniel Stenberg0a1c2212002-09-13 06:37:49 +000047
Björn Stenbergbed3d3f2002-09-20 08:07:51 +000048/* compiled-in font */
49extern struct font sysfont;
50
51/* structure filled in by font_load */
52static struct font font_ui;
53
54/* system font table, in order of FONT_xxx definition */
Jens Arnold2b0694c2004-08-03 05:58:46 +000055static struct font* const sysfonts[MAXFONTS] = { &sysfont, &font_ui };
Björn Stenbergbed3d3f2002-09-20 08:07:51 +000056
57/* static buffer allocation structures */
58static unsigned char mbuf[MAX_FONT_SIZE];
59static unsigned char *freeptr = mbuf;
60static unsigned char *fileptr;
61static unsigned char *eofptr;
62
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +000063/* Font cache structures */
64static struct font_cache font_cache_ui;
65static int fnt_file = -1; /* >=0 if font is cached */
Bertrik Sikkendb2d61f2008-04-20 10:24:15 +000066static uint32_t file_width_offset; /* offset to file width data */
67static uint32_t file_offset_offset; /* offset to file offset data */
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +000068static void cache_create(int maxwidth, int height);
69static int long_offset = 0;
70static int glyph_file;
71/* End Font cache structures */
72
Nils Wallméniusdf155c82007-06-30 17:54:02 +000073static void glyph_cache_load(void);
74
Björn Stenbergbed3d3f2002-09-20 08:07:51 +000075void font_init(void)
76{
Björn Stenbergbed3d3f2002-09-20 08:07:51 +000077 memset(&font_ui, 0, sizeof(struct font));
78}
79
Dave Chapmane10f4552007-04-13 19:51:19 +000080/* Check if we have x bytes left in the file buffer */
81#define HAVEBYTES(x) (fileptr + (x) <= eofptr)
82
83/* Helper functions to read big-endian unaligned short or long from
84 the file buffer. Bounds-checking must be done in the calling
85 function.
86 */
87
88static short readshort(void)
Björn Stenbergbed3d3f2002-09-20 08:07:51 +000089{
90 unsigned short s;
91
92 s = *fileptr++ & 0xff;
Dave Chapmane10f4552007-04-13 19:51:19 +000093 s |= (*fileptr++ << 8);
94 return s;
Björn Stenbergbed3d3f2002-09-20 08:07:51 +000095}
96
Nils Wallméniusdf155c82007-06-30 17:54:02 +000097static int32_t readlong(void)
Björn Stenbergbed3d3f2002-09-20 08:07:51 +000098{
Nils Wallméniusdf155c82007-06-30 17:54:02 +000099 uint32_t l;
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000100
101 l = *fileptr++ & 0xff;
102 l |= *fileptr++ << 8;
Nils Wallméniusdf155c82007-06-30 17:54:02 +0000103 l |= ((uint32_t)(*fileptr++)) << 16;
104 l |= ((uint32_t)(*fileptr++)) << 24;
Dave Chapmane10f4552007-04-13 19:51:19 +0000105 return l;
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000106}
107
108/* read count bytes*/
Dave Chapmane10f4552007-04-13 19:51:19 +0000109static void readstr(char *buf, int count)
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000110{
Dave Chapmane10f4552007-04-13 19:51:19 +0000111 while (count--)
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000112 *buf++ = *fileptr++;
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000113}
114
Björn Stenberg227253c2002-10-09 23:13:25 +0000115void font_reset(void)
116{
117 memset(&font_ui, 0, sizeof(struct font));
118}
119
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000120static struct font* font_load_header(struct font *pf)
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000121{
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000122 char version[4+1];
Dave Chapmane10f4552007-04-13 19:51:19 +0000123
124 /* Check we have enough data */
125 if (!HAVEBYTES(28))
126 return NULL;
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000127
128 /* read magic and version #*/
129 memset(version, 0, sizeof(version));
Dave Chapmane10f4552007-04-13 19:51:19 +0000130 readstr(version, 4);
131
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000132 if (strcmp(version, VERSION) != 0)
133 return NULL;
134
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000135 /* font info*/
Dave Chapmane10f4552007-04-13 19:51:19 +0000136 pf->maxwidth = readshort();
137 pf->height = readshort();
138 pf->ascent = readshort();
139 fileptr += 2; /* Skip padding */
140 pf->firstchar = readlong();
141 pf->defaultchar = readlong();
142 pf->size = readlong();
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000143
144 /* get variable font data sizes*/
145 /* # words of bitmap_t*/
Dave Chapmane10f4552007-04-13 19:51:19 +0000146 pf->bits_size = readlong();
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000147
148 return pf;
149}
150/* Load memory font */
Nils Wallméniusdf155c82007-06-30 17:54:02 +0000151static struct font* font_load_in_memory(struct font* pf)
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000152{
Nils Wallméniusdf155c82007-06-30 17:54:02 +0000153 int32_t i, noffset, nwidth;
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000154
Dave Chapmane10f4552007-04-13 19:51:19 +0000155 if (!HAVEBYTES(4))
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000156 return NULL;
157
Dave Chapmane10f4552007-04-13 19:51:19 +0000158 /* # longs of offset*/
159 noffset = readlong();
160
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000161 /* # bytes of width*/
Dave Chapmane10f4552007-04-13 19:51:19 +0000162 nwidth = readlong();
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000163
164 /* variable font data*/
Jörg Hohensohn5d36aaf2004-08-26 21:15:07 +0000165 pf->bits = (unsigned char *)fileptr;
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000166 fileptr += pf->bits_size*sizeof(unsigned char);
Jörg Hohensohn5d36aaf2004-08-26 21:15:07 +0000167
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000168 if ( pf->bits_size < 0xFFDB )
169 {
170 /* pad to 16-bit boundary */
Nils Wallménius9789acc2007-06-30 18:09:46 +0000171 fileptr = (unsigned char *)(((intptr_t)fileptr + 1) & ~1);
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000172 }
173 else
174 {
175 /* pad to 32-bit boundary*/
Nils Wallménius9789acc2007-06-30 18:09:46 +0000176 fileptr = (unsigned char *)(((intptr_t)fileptr + 3) & ~3);
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000177 }
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000178
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000179 if (noffset)
180 {
181 if ( pf->bits_size < 0xFFDB )
Jörg Hohensohn5d36aaf2004-08-26 21:15:07 +0000182 {
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000183 long_offset = 0;
184 pf->offset = (unsigned short *)fileptr;
Dave Chapmane10f4552007-04-13 19:51:19 +0000185
186 /* Check we have sufficient buffer */
187 if (!HAVEBYTES(noffset * sizeof(short)))
188 return NULL;
189
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000190 for (i=0; i<noffset; ++i)
191 {
Dave Chapmane10f4552007-04-13 19:51:19 +0000192 ((unsigned short*)(pf->offset))[i] = (unsigned short)readshort();
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000193 }
194 }
195 else
196 {
197 long_offset = 1;
198 pf->offset = (unsigned short *)fileptr;
Dave Chapmane10f4552007-04-13 19:51:19 +0000199
200 /* Check we have sufficient buffer */
Nils Wallméniusdf155c82007-06-30 17:54:02 +0000201 if (!HAVEBYTES(noffset * sizeof(int32_t)))
Dave Chapmane10f4552007-04-13 19:51:19 +0000202 return NULL;
203
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000204 for (i=0; i<noffset; ++i)
205 {
Nils Wallméniusdf155c82007-06-30 17:54:02 +0000206 ((uint32_t*)(pf->offset))[i] = (uint32_t)readlong();
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000207 }
Jörg Hohensohn5d36aaf2004-08-26 21:15:07 +0000208 }
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000209 }
210 else
211 pf->offset = NULL;
212
213 if (nwidth) {
214 pf->width = (unsigned char *)fileptr;
215 fileptr += nwidth*sizeof(unsigned char);
216 }
217 else
218 pf->width = NULL;
219
220 if (fileptr > eofptr)
221 return NULL;
222
Jens Arnold6dc88dc2004-05-14 23:08:08 +0000223 return pf; /* success!*/
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000224}
225
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000226/* Load cached font */
Nils Wallméniusdf155c82007-06-30 17:54:02 +0000227static struct font* font_load_cached(struct font* pf)
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000228{
Nils Wallméniusdf155c82007-06-30 17:54:02 +0000229 uint32_t noffset, nwidth;
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000230 unsigned char* oldfileptr = fileptr;
231
Nils Wallméniusdf155c82007-06-30 17:54:02 +0000232 if (!HAVEBYTES(2 * sizeof(int32_t)))
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000233 return NULL;
234
Dave Chapmane10f4552007-04-13 19:51:19 +0000235 /* # longs of offset*/
236 noffset = readlong();
237
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000238 /* # bytes of width*/
Dave Chapmane10f4552007-04-13 19:51:19 +0000239 nwidth = readlong();
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000240
241 /* We are now at the bitmap data, this is fixed at 36.. */
242 pf->bits = NULL;
243
244 /* Calculate offset to offset data */
245 fileptr += pf->bits_size * sizeof(unsigned char);
246
247 if ( pf->bits_size < 0xFFDB )
248 {
249 long_offset = 0;
250 /* pad to 16-bit boundary */
Nils Wallménius9789acc2007-06-30 18:09:46 +0000251 fileptr = (unsigned char *)(((intptr_t)fileptr + 1) & ~1);
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000252 }
253 else
254 {
255 long_offset = 1;
256 /* pad to 32-bit boundary*/
Nils Wallménius9789acc2007-06-30 18:09:46 +0000257 fileptr = (unsigned char *)(((intptr_t)fileptr + 3) & ~3);
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000258 }
259
260 if (noffset)
Nils Wallméniusdf155c82007-06-30 17:54:02 +0000261 file_offset_offset = (uint32_t)(fileptr - freeptr);
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000262 else
263 file_offset_offset = 0;
264
265 /* Calculate offset to widths data */
266 if ( pf->bits_size < 0xFFDB )
267 fileptr += noffset * sizeof(unsigned short);
268 else
Nils Wallméniusdf155c82007-06-30 17:54:02 +0000269 fileptr += noffset * sizeof(uint32_t);
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000270
271 if (nwidth)
Nils Wallméniusdf155c82007-06-30 17:54:02 +0000272 file_width_offset = (uint32_t)(fileptr - freeptr);
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000273 else
274 file_width_offset = 0;
275
276 fileptr = oldfileptr;
277
278 /* Create the cache */
279 cache_create(pf->maxwidth, pf->height);
280
281 return pf;
282}
283
284/* read and load font into incore font structure*/
285struct font* font_load(const char *path)
286{
Frank Dischnerbf64c452006-04-24 16:02:44 +0000287 int size;
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000288 struct font* pf = &font_ui;
289
290 /* save loaded glyphs */
291 glyph_cache_save();
292
293 /* Close font file handle */
294 if (fnt_file >= 0)
295 close(fnt_file);
296
297 /* open and read entire font file*/
298 fnt_file = open(path, O_RDONLY|O_BINARY);
299
300 if (fnt_file < 0) {
301 DEBUGF("Can't open font: %s\n", path);
302 return NULL;
303 }
304
305 /* Check file size */
Frank Dischnerbf64c452006-04-24 16:02:44 +0000306 size = filesize(fnt_file);
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000307
308 font_reset();
309
310 /* currently, font loading replaces earlier font allocation*/
Jens Arnold8ab2cb52007-10-02 17:04:56 +0000311 freeptr = (unsigned char *)(((intptr_t)mbuf + 3) & ~3);
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000312 fileptr = freeptr;
313
314
Frank Dischnerbf64c452006-04-24 16:02:44 +0000315 if (size > MAX_FONT_SIZE)
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000316 {
317 read(fnt_file, fileptr, FONT_HEADER_SIZE);
318 eofptr = fileptr + FONT_HEADER_SIZE;
319
320 if (!font_load_header(pf))
321 {
322 DEBUGF("Failed font header load");
323 return NULL;
324 }
325
326 if (!font_load_cached(pf))
327 {
328 DEBUGF("Failed font cache load");
329 return NULL;
330 }
331
332 glyph_cache_load();
333 }
334 else
335 {
336 read(fnt_file, fileptr, MAX_FONT_SIZE);
Frank Dischnerbf64c452006-04-24 16:02:44 +0000337 eofptr = fileptr + size;
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000338 close(fnt_file);
339 fnt_file = -1;
340
341 if (!font_load_header(pf))
342 {
343 DEBUGF("Failed font header load");
344 return NULL;
345 }
346
347 if (!font_load_in_memory(pf))
348 {
349 DEBUGF("Failed mem load");
350 return NULL;
351 }
352 }
353
354 /* no need for multiple font loads currently*/
355 /*freeptr += filesize;*/
356 /*freeptr = (unsigned char *)(freeptr + 3) & ~3;*/ /* pad freeptr*/
357
358 return pf; /* success!*/
359}
360
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000361/*
362 * Return a pointer to an incore font structure.
363 * If the requested font isn't loaded/compiled-in,
364 * decrement the font number and try again.
365 */
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000366struct font* font_get(int font)
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000367{
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000368 struct font* pf;
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000369
Eric Linenberg038df5c2002-09-16 03:18:49 +0000370 if (font >= MAXFONTS)
371 font = 0;
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000372
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000373 while (1) {
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000374 pf = sysfonts[font];
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000375 if (pf && pf->height)
376 return pf;
377 if (--font < 0)
378 panicf("No font!");
379 }
380}
Christian Gmeinerc6ec0f42005-04-19 12:47:16 +0000381/*
382 * Returns the stringsize of a given string.
383 */
384int font_getstringsize(const unsigned char *str, int *w, int *h, int fontnumber)
385{
386 struct font* pf = font_get(fontnumber);
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000387 unsigned short ch;
Christian Gmeinerc6ec0f42005-04-19 12:47:16 +0000388 int width = 0;
389
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000390 for (str = utf8decode(str, &ch); ch != 0 ; str = utf8decode(str, &ch))
391 {
Christian Gmeinerc6ec0f42005-04-19 12:47:16 +0000392
393 /* get proportional width and glyph bits*/
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000394 width += font_get_width(pf,ch);
Christian Gmeinerc6ec0f42005-04-19 12:47:16 +0000395 }
396 if ( w )
397 *w = width;
398 if ( h )
399 *h = pf->height;
400 return width;
401}
402
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000403/*
404 * Reads an entry into cache entry
405 */
406static void
407load_cache_entry(struct font_cache_entry* p, void* callback_data)
408{
409 struct font* pf = callback_data;
410 unsigned short char_code = p->_char_code;
411 unsigned char tmp[2];
412
413 if (file_width_offset)
414 {
415 int width_offset = file_width_offset + char_code;
416 lseek(fnt_file, width_offset, SEEK_SET);
417 read(fnt_file, &(p->width), 1);
418 }
419 else
420 {
421 p->width = pf->maxwidth;
422 }
423
Nils Wallméniusdf155c82007-06-30 17:54:02 +0000424 int32_t bitmap_offset = 0;
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000425
426 if (file_offset_offset)
427 {
Nils Wallméniusdf155c82007-06-30 17:54:02 +0000428 int32_t offset = file_offset_offset + char_code * (long_offset ? sizeof(int32_t) : sizeof(short));
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000429 lseek(fnt_file, offset, SEEK_SET);
430 read (fnt_file, tmp, 2);
431 bitmap_offset = tmp[0] | (tmp[1] << 8);
432 if (long_offset) {
433 read (fnt_file, tmp, 2);
434 bitmap_offset |= (tmp[0] << 16) | (tmp[1] << 24);
435 }
436 }
437 else
438 {
439 bitmap_offset = ((pf->height + 7) / 8) * p->width * char_code;
440 }
441
Nils Wallméniusdf155c82007-06-30 17:54:02 +0000442 int32_t file_offset = FONT_HEADER_SIZE + bitmap_offset;
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000443 lseek(fnt_file, file_offset, SEEK_SET);
444
445 int src_bytes = p->width * ((pf->height + 7) / 8);
446 read(fnt_file, p->bitmap, src_bytes);
447}
448
449/*
450 * Converts cbuf into a font cache
451 */
452static void cache_create(int maxwidth, int height)
453{
454 /* maximum size of rotated bitmap */
455 int bitmap_size = maxwidth * ((height + 7) / 8);
456
457 /* Initialise cache */
458 font_cache_create(&font_cache_ui, mbuf, MAX_FONT_SIZE, bitmap_size);
459}
460
461/*
462 * Returns width of character
463 */
464int font_get_width(struct font* pf, unsigned short char_code)
465{
Marcoen Hirschbergd2576832006-03-22 09:53:27 +0000466 /* check input range*/
467 if (char_code < pf->firstchar || char_code >= pf->firstchar+pf->size)
468 char_code = pf->defaultchar;
469 char_code -= pf->firstchar;
470
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000471 return (fnt_file >= 0 && pf != &sysfont)?
472 font_cache_get(&font_cache_ui,char_code,load_cache_entry,pf)->width:
473 pf->width? pf->width[char_code]: pf->maxwidth;
474}
475
476const unsigned char* font_get_bits(struct font* pf, unsigned short char_code)
477{
478 const unsigned char* bits;
Marcoen Hirschbergd2576832006-03-22 09:53:27 +0000479
480 /* check input range*/
481 if (char_code < pf->firstchar || char_code >= pf->firstchar+pf->size)
482 char_code = pf->defaultchar;
483 char_code -= pf->firstchar;
484
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000485 if (fnt_file >= 0 && pf != &sysfont)
486 {
487 bits =
488 (unsigned char*)font_cache_get(&font_cache_ui,char_code,load_cache_entry,pf)->bitmap;
489 }
490 else
491 {
492 bits = pf->bits + (pf->offset?
493 pf->offset[char_code]:
494 (((pf->height + 7) / 8) * pf->maxwidth * char_code));
495 }
496
497 return bits;
498}
499
Nils Wallméniusdf155c82007-06-30 17:54:02 +0000500static void glyph_file_write(void* data)
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000501{
502 struct font_cache_entry* p = data;
Marcoen Hirschbergd2576832006-03-22 09:53:27 +0000503 struct font* pf = &font_ui;
504 unsigned short ch;
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000505 unsigned char tmp[2];
506
Marcoen Hirschbergd2576832006-03-22 09:53:27 +0000507 ch = p->_char_code + pf->firstchar;
508
509 if (ch != 0xffff && glyph_file >= 0) {
510 tmp[0] = ch >> 8;
511 tmp[1] = ch & 0xff;
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000512 if (write(glyph_file, tmp, 2) != 2) {
513 close(glyph_file);
514 glyph_file = -1;
515 }
516 }
517 return;
518}
519
520/* save the char codes of the loaded glyphs to a file */
521void glyph_cache_save(void)
522{
523
524 if (fnt_file >= 0) {
525
Jens Arnold67eb1542007-02-01 23:08:15 +0000526 glyph_file = creat(GLYPH_CACHE_FILE);
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000527
528 if (glyph_file < 0) return;
529
530 lru_traverse(&font_cache_ui._lru, glyph_file_write);
531
532 if (glyph_file >= 0)
533 close(glyph_file);
534 }
535 return;
536}
537
Nils Wallméniusdf155c82007-06-30 17:54:02 +0000538static void glyph_cache_load(void)
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000539{
540 if (fnt_file >= 0) {
541
542 int fd;
543 unsigned char tmp[2];
544 unsigned short ch;
545 struct font* pf = &font_ui;
546
547 fd = open(GLYPH_CACHE_FILE, O_RDONLY|O_BINARY);
548
549 if (fd >= 0) {
550
551 while (read(fd, tmp, 2) == 2) {
552 ch = (tmp[0] << 8) | tmp[1];
553 font_get_bits(pf, ch);
554 }
555
556 close(fd);
557 } else {
558 /* load latin1 chars into cache */
Marcoen Hirschbergd2576832006-03-22 09:53:27 +0000559 ch = 256;
560 while (ch-- > 32)
Marcoen Hirschbergb0fee172005-12-06 13:27:15 +0000561 font_get_bits(pf, ch);
562 }
563 }
564 return;
565}
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000566
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000567#endif /* HAVE_LCD_BITMAP */
568
569/* -----------------------------------------------------------------
Eric Linenberg038df5c2002-09-16 03:18:49 +0000570 * vim: et sw=4 ts=8 sts=4 tw=78
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000571 */