summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/gui/skin_engine/skin_parser.c6
-rw-r--r--apps/lang/english.lang14
-rw-r--r--apps/menus/settings_menu.c9
-rw-r--r--apps/settings.c2
-rw-r--r--apps/settings.h1
-rw-r--r--apps/settings_list.c6
-rw-r--r--firmware/export/font.h4
-rw-r--r--firmware/font.c455
-rw-r--r--manual/advanced_topics/main.tex3
-rw-r--r--manual/configure_rockbox/system_options.tex10
-rw-r--r--tools/convbdf.c1
11 files changed, 247 insertions, 264 deletions
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index ad10689107..c4a96d0e9b 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -78,7 +78,6 @@
78 78
79#define WPS_ERROR_INVALID_PARAM -1 79#define WPS_ERROR_INVALID_PARAM -1
80 80
81#define GLYPHS_TO_CACHE 256
82static char* skin_buffer = NULL; 81static char* skin_buffer = NULL;
83void skinparser_set_buffer(char* pointer) 82void skinparser_set_buffer(char* pointer)
84{ 83{
@@ -468,7 +467,7 @@ static int parse_font_load(struct skin_element *element,
468 if(element->params_count > 2) 467 if(element->params_count > 2)
469 glyphs = get_param(element, 2)->data.number; 468 glyphs = get_param(element, 2)->data.number;
470 else 469 else
471 glyphs = GLYPHS_TO_CACHE; 470 glyphs = global_settings.glyphs;
472 if (id < 2) 471 if (id < 2)
473 { 472 {
474 DEBUGF("font id must be >= 2\n"); 473 DEBUGF("font id must be >= 2\n");
@@ -1742,8 +1741,7 @@ static bool skin_load_fonts(struct wps_data *data)
1742 char path[MAX_PATH]; 1741 char path[MAX_PATH];
1743 snprintf(path, sizeof path, FONT_DIR "/%s", font->name); 1742 snprintf(path, sizeof path, FONT_DIR "/%s", font->name);
1744#ifndef __PCTOOL__ 1743#ifndef __PCTOOL__
1745 font->id = font_load_ex(path, 1744 font->id = font_load_ex(path, 0, skinfonts[font_id-2].glyphs);
1746 font_glyphs_to_bufsize(path, skinfonts[font_id-2].glyphs));
1747 1745
1748#else 1746#else
1749 font->id = font_load(path); 1747 font->id = font_load(path);
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index a228a78f7f..29e6205729 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -12951,3 +12951,17 @@
12951 hardware_click: "Speaker Keyclick" 12951 hardware_click: "Speaker Keyclick"
12952 </voice> 12952 </voice>
12953</phrase> 12953</phrase>
12954<phrase>
12955 id: LANG_GLYPHS
12956 desc: in settings_menu
12957 user: core
12958 <source>
12959 *: "Glyphs To Cache"
12960 </source>
12961 <dest>
12962 *: "Glyphs To Cache"
12963 </dest>
12964 <voice>
12965 *: "Glyphs To Cache"
12966 </voice>
12967</phrase>
diff --git a/apps/menus/settings_menu.c b/apps/menus/settings_menu.c
index 079e86616d..4ea98efd95 100644
--- a/apps/menus/settings_menu.c
+++ b/apps/menus/settings_menu.c
@@ -221,8 +221,15 @@ MENUITEM_SETTING(poweroff, &global_settings.poweroff, NULL);
221/* Limits menu */ 221/* Limits menu */
222MENUITEM_SETTING(max_files_in_dir, &global_settings.max_files_in_dir, NULL); 222MENUITEM_SETTING(max_files_in_dir, &global_settings.max_files_in_dir, NULL);
223MENUITEM_SETTING(max_files_in_playlist, &global_settings.max_files_in_playlist, NULL); 223MENUITEM_SETTING(max_files_in_playlist, &global_settings.max_files_in_playlist, NULL);
224#ifdef HAVE_LCD_BITMAP
225MENUITEM_SETTING(default_glyphs, &global_settings.glyphs, NULL);
226#endif
224MAKE_MENU(limits_menu, ID2P(LANG_LIMITS_MENU), 0, Icon_NOICON, 227MAKE_MENU(limits_menu, ID2P(LANG_LIMITS_MENU), 0, Icon_NOICON,
225 &max_files_in_dir, &max_files_in_playlist); 228 &max_files_in_dir, &max_files_in_playlist
229#ifdef HAVE_LCD_BITMAP
230 ,&default_glyphs
231#endif
232 );
226 233
227 234
228/* Keyclick menu */ 235/* Keyclick menu */
diff --git a/apps/settings.c b/apps/settings.c
index fbfa438ab5..c22fa50f17 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -886,7 +886,7 @@ void settings_apply(bool read_disk)
886 CHART2(">font_load ", global_settings.font_file); 886 CHART2(">font_load ", global_settings.font_file);
887 if (font_ui >= 0) 887 if (font_ui >= 0)
888 font_unload(font_ui); 888 font_unload(font_ui);
889 rc = font_load(buf); 889 rc = font_load_ex(buf, 0, global_settings.glyphs);
890 CHART2("<font_load ", global_settings.font_file); 890 CHART2("<font_load ", global_settings.font_file);
891 screens[SCREEN_MAIN].setuifont(rc); 891 screens[SCREEN_MAIN].setuifont(rc);
892 screens[SCREEN_MAIN].setfont(rc); 892 screens[SCREEN_MAIN].setfont(rc);
diff --git a/apps/settings.h b/apps/settings.h
index 06eba76e3c..6608df6111 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -672,6 +672,7 @@ struct user_settings
672 unsigned char icon_file[MAX_FILENAME+1]; 672 unsigned char icon_file[MAX_FILENAME+1];
673 unsigned char viewers_icon_file[MAX_FILENAME+1]; 673 unsigned char viewers_icon_file[MAX_FILENAME+1];
674 unsigned char font_file[MAX_FILENAME+1]; /* last font */ 674 unsigned char font_file[MAX_FILENAME+1]; /* last font */
675 int glyphs;
675#ifdef HAVE_REMOTE_LCD 676#ifdef HAVE_REMOTE_LCD
676 unsigned char remote_font_file[MAX_FILENAME+1]; /* last font */ 677 unsigned char remote_font_file[MAX_FILENAME+1]; /* last font */
677#endif 678#endif
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 9232811ada..305edd93ba 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -222,6 +222,9 @@ static const char graphic_numeric[] = "graphic,numeric";
222#else 222#else
223 #define DEFAULT_FONTNAME "35-Adobe-Helvetica" 223 #define DEFAULT_FONTNAME "35-Adobe-Helvetica"
224#endif 224#endif
225#define DEFAULT_GLYPHS 250
226#define MIN_GLYPHS 50
227#define MAX_GLYPHS 65540
225 228
226#else 229#else
227 #define DEFAULT_FONTNAME "" 230 #define DEFAULT_FONTNAME ""
@@ -1622,6 +1625,9 @@ const struct settings_list settings[] = {
1622#ifdef HAVE_LCD_BITMAP 1625#ifdef HAVE_LCD_BITMAP
1623 TEXT_SETTING(F_THEMESETTING, font_file, "font", 1626 TEXT_SETTING(F_THEMESETTING, font_file, "font",
1624 DEFAULT_FONTNAME, FONT_DIR "/", ".fnt"), 1627 DEFAULT_FONTNAME, FONT_DIR "/", ".fnt"),
1628 INT_SETTING(0, glyphs, LANG_GLYPHS, DEFAULT_GLYPHS,
1629 "glyphs", UNIT_INT, MIN_GLYPHS, MAX_GLYPHS, 10,
1630 NULL, NULL, NULL),
1625#endif 1631#endif
1626#ifdef HAVE_REMOTE_LCD 1632#ifdef HAVE_REMOTE_LCD
1627 TEXT_SETTING(F_THEMESETTING, remote_font_file, "remote font", 1633 TEXT_SETTING(F_THEMESETTING, remote_font_file, "remote font",
diff --git a/firmware/export/font.h b/firmware/export/font.h
index 914d3aa2ff..faa10391f8 100644
--- a/firmware/export/font.h
+++ b/firmware/export/font.h
@@ -102,6 +102,7 @@ struct font {
102 int fd; /* fd for the font file. >= 0 if cached */ 102 int fd; /* fd for the font file. >= 0 if cached */
103 int fd_width; /* fd for the font file. >= 0 if cached */ 103 int fd_width; /* fd for the font file. >= 0 if cached */
104 int fd_offset; /* fd for the font file. >= 0 if cached */ 104 int fd_offset; /* fd for the font file. >= 0 if cached */
105 int handle; /* core_allocator handle */
105 unsigned char *buffer_start; /* buffer to store the font in */ 106 unsigned char *buffer_start; /* buffer to store the font in */
106 unsigned char *buffer_position; /* position in the buffer */ 107 unsigned char *buffer_position; /* position in the buffer */
107 unsigned char *buffer_end; /* end of the buffer */ 108 unsigned char *buffer_end; /* end of the buffer */
@@ -119,8 +120,7 @@ struct font {
119void font_init(void) INIT_ATTR; 120void font_init(void) INIT_ATTR;
120const char* font_filename(int font_id); 121const char* font_filename(int font_id);
121int font_load(const char *path); 122int font_load(const char *path);
122int font_load_ex(const char *path, size_t buffer_size); 123int font_load_ex(const char *path, size_t buffer_size, int glyphs);
123int font_glyphs_to_bufsize(const char *path, int glyphs);
124void font_unload(int font_id); 124void font_unload(int font_id);
125void font_unload_all(void); 125void font_unload_all(void);
126void font_lock(int font_id, bool lock); 126void font_lock(int font_id, bool lock);
diff --git a/firmware/font.c b/firmware/font.c
index ff5bc4b008..5dd080b89c 100644
--- a/firmware/font.c
+++ b/firmware/font.c
@@ -55,6 +55,11 @@
55#define MAX_FONT_SIZE 4000 55#define MAX_FONT_SIZE 4000
56#endif 56#endif
57#endif 57#endif
58#define GLYPHS_TO_CACHE 256
59
60#if MEMORYSIZE < 4
61#define FONT_HARD_LIMIT
62#endif
58 63
59#ifndef FONT_HEADER_SIZE 64#ifndef FONT_HEADER_SIZE
60#define FONT_HEADER_SIZE 36 65#define FONT_HEADER_SIZE 36
@@ -117,6 +122,8 @@ static int buflibmove_callback(int handle, void* current, void* new)
117} 122}
118static void lock_font_handle(int handle, bool lock) 123static void lock_font_handle(int handle, bool lock)
119{ 124{
125 if ( handle < 0 )
126 return;
120 struct buflib_alloc_data *alloc = core_get_data(handle); 127 struct buflib_alloc_data *alloc = core_get_data(handle);
121 if ( lock ) 128 if ( lock )
122 alloc->handle_locks++; 129 alloc->handle_locks++;
@@ -150,7 +157,7 @@ static inline unsigned char *buffer_from_handle(int handle)
150 157
151/* Font cache structures */ 158/* Font cache structures */
152static void cache_create(struct font* pf); 159static void cache_create(struct font* pf);
153static void glyph_cache_load(int fond_id); 160static void glyph_cache_load(const char *font_path, struct font *pf);
154/* End Font cache structures */ 161/* End Font cache structures */
155 162
156void font_init(void) 163void font_init(void)
@@ -199,48 +206,14 @@ static int glyph_bytes( struct font *pf, int width )
199 return (ret + 1) & ~1; 206 return (ret + 1) & ~1;
200} 207}
201 208
202static struct font* font_load_header(struct font *pf)
203{
204 /* Check we have enough data */
205 if (!HAVEBYTES(28))
206 return NULL;
207
208 /* read magic and version #*/
209 if (memcmp(pf->buffer_position, VERSION, 4) != 0)
210 return NULL;
211
212 pf->buffer_position += 4;
213
214 /* font info*/
215 pf->maxwidth = readshort(pf);
216 pf->height = readshort(pf);
217 pf->ascent = readshort(pf);
218 pf->depth = readshort(pf);
219 pf->firstchar = readlong(pf);
220 pf->defaultchar = readlong(pf);
221 pf->size = readlong(pf);
222
223 /* get variable font data sizes*/
224 /* # words of bitmap_t*/
225 pf->bits_size = readlong(pf);
226
227 return pf;
228}
229/* Load memory font */ 209/* Load memory font */
230static struct font* font_load_in_memory(struct font* pf) 210static struct font* font_load_in_memory(struct font* pf,
211 int32_t noffset,
212 int32_t nwidth )
231{ 213{
232 int32_t i, noffset, nwidth; 214 int i;
233
234 if (!HAVEBYTES(4))
235 return NULL;
236
237 /* # longs of offset*/
238 noffset = readlong(pf);
239
240 /* # bytes of width*/
241 nwidth = readlong(pf);
242
243 /* variable font data*/ 215 /* variable font data*/
216 pf->buffer_position = pf->buffer_start + 36;
244 pf->bits = (unsigned char *)pf->buffer_position; 217 pf->bits = (unsigned char *)pf->buffer_position;
245 pf->buffer_position += pf->bits_size*sizeof(unsigned char); 218 pf->buffer_position += pf->bits_size*sizeof(unsigned char);
246 219
@@ -303,20 +276,10 @@ static struct font* font_load_in_memory(struct font* pf)
303} 276}
304 277
305/* Load cached font */ 278/* Load cached font */
306static struct font* font_load_cached(struct font* pf) 279static struct font* font_load_cached(struct font* pf,
280 int32_t nwidth,
281 int32_t noffset)
307{ 282{
308 uint32_t noffset, nwidth;
309 unsigned char* oldfileptr = pf->buffer_position;
310
311 if (!HAVEBYTES(2 * sizeof(int32_t)))
312 return NULL;
313
314 /* # longs of offset*/
315 noffset = readlong(pf);
316
317 /* # bytes of width*/
318 nwidth = readlong(pf);
319
320 /* We are now at the bitmap data, this is fixed at 36.. */ 283 /* We are now at the bitmap data, this is fixed at 36.. */
321 pf->bits = NULL; 284 pf->bits = NULL;
322 285
@@ -352,96 +315,12 @@ static struct font* font_load_cached(struct font* pf)
352 else 315 else
353 pf->file_width_offset = 0; 316 pf->file_width_offset = 0;
354 317
355 pf->buffer_position = oldfileptr;
356
357 /* Create the cache */ 318 /* Create the cache */
358 cache_create(pf); 319 cache_create(pf);
359 320
360 return pf; 321 return pf;
361} 322}
362 323
363static bool internal_load_font(int font_id, const char *path, char *buf,
364 size_t buf_size, int handle)
365{
366 size_t size;
367 struct font* pf = pf_from_handle(handle);
368
369 /* open and read entire font file*/
370 pf->fd = open(path, O_RDONLY|O_BINARY);
371
372 if (pf->fd < 0) {
373 DEBUGF("Can't open font: %s\n", path);
374 return false;
375 }
376
377 /* Check file size */
378 size = filesize(pf->fd);
379 pf->buffer_start = buf;
380 pf->buffer_size = buf_size;
381
382 pf->buffer_position = buf;
383
384 if (size > pf->buffer_size)
385 {
386 read(pf->fd, pf->buffer_position, FONT_HEADER_SIZE);
387 pf->buffer_end = pf->buffer_position + FONT_HEADER_SIZE;
388
389 if (!font_load_header(pf))
390 {
391 DEBUGF("Failed font header load");
392 close(pf->fd);
393 pf->fd = -1;
394 return false;
395 }
396
397 if (!font_load_cached(pf))
398 {
399 DEBUGF("Failed font cache load");
400 close(pf->fd);
401 pf->fd = -1;
402 return false;
403 }
404
405 /* Cheat to get sector cache for different parts of font *
406 * file while preloading glyphs. Without this the disk head *
407 * thrashes between the width, offset, and bitmap data *
408 * in glyph_cache_load(). */
409 pf->fd_width = open(path, O_RDONLY|O_BINARY);
410 pf->fd_offset = open(path, O_RDONLY|O_BINARY);
411
412 glyph_cache_load(font_id);
413
414 if(pf->fd_width >= 0)
415 close(pf->fd_width);
416 pf->fd_width = -1;
417
418 if(pf->fd_offset >= 0)
419 close(pf->fd_offset);
420 pf->fd_offset = -1;
421 }
422 else
423 {
424 read(pf->fd, pf->buffer_position, pf->buffer_size);
425 pf->buffer_end = pf->buffer_position + size;
426 close(pf->fd);
427 pf->fd = -1;
428 pf->fd_width = -1;
429 pf->fd_offset = -1;
430
431 if (!font_load_header(pf))
432 {
433 DEBUGF("Failed font header load");
434 return false;
435 }
436
437 if (!font_load_in_memory(pf))
438 {
439 DEBUGF("Failed mem load");
440 return false;
441 }
442 }
443 return true;
444}
445 324
446static int find_font_index(const char* path) 325static int find_font_index(const char* path)
447{ 326{
@@ -457,30 +336,6 @@ static int find_font_index(const char* path)
457 return FONT_SYSFIXED; 336 return FONT_SYSFIXED;
458} 337}
459 338
460static int alloc_and_init(int font_idx, const char* name, size_t size)
461{
462 int *phandle = &buflib_allocations[font_idx];
463 int handle = *phandle;
464 struct buflib_alloc_data *pdata;
465 struct font *pf;
466 size_t alloc_size = size + sizeof(struct buflib_alloc_data);
467 if (handle > 0)
468 return handle;
469 *phandle = core_alloc_ex(name, alloc_size, &buflibops);
470 handle = *phandle;
471 if (handle < 0)
472 return handle;
473 pdata = core_get_data(handle);
474 pf = &pdata->font;
475 pdata->handle_locks = 0;
476 pdata->refcount = 1;
477 pf->buffer_position = pf->buffer_start = buffer_from_handle(handle);
478 pf->buffer_size = size;
479 pf->fd_width = -1;
480 pf->fd_offset = -1;
481 return handle;
482}
483
484const char* font_filename(int font_id) 339const char* font_filename(int font_id)
485{ 340{
486 int handle = buflib_allocations[font_id]; 341 int handle = buflib_allocations[font_id];
@@ -488,22 +343,118 @@ const char* font_filename(int font_id)
488 return core_get_name(handle); 343 return core_get_name(handle);
489 return NULL; 344 return NULL;
490} 345}
491 346
492/* read and load font into incore font structure, 347size_t font_glyphs_to_bufsize(struct font *pf, int glyphs)
493 * returns the font number on success, -1 on failure */ 348{
494int font_load_ex(const char *path, size_t buffer_size) 349 size_t bufsize;
350
351 /* LRU bytes per glyph */
352 bufsize = LRU_SLOT_OVERHEAD + sizeof(struct font_cache_entry) +
353 sizeof( unsigned short);
354 /* Image bytes per glyph */
355 bufsize += glyph_bytes(pf, pf->maxwidth);
356 bufsize *= glyphs;
357
358 return bufsize;
359}
360
361static struct font* font_load_header(int fd, struct font *pheader,
362 struct font *pf,
363 uint32_t *nwidth, uint32_t *noffset)
364{
365 /* Load the header. Readshort() and readlong() *
366 * update buffer_position address as they read */
367 pheader->buffer_start = pheader->buffer_position = (char *)pheader;
368 pheader->buffer_size = FONT_HEADER_SIZE;
369 pheader->buffer_end = pheader->buffer_start + pheader->buffer_size;
370
371 if (read(fd, pheader, FONT_HEADER_SIZE) != FONT_HEADER_SIZE)
372 return NULL;
373
374 /* read magic and version #*/
375 if (memcmp(pheader->buffer_position, VERSION, 4) != 0)
376 return NULL;
377
378 pheader->buffer_position += 4;
379
380 /* font info*/
381 pf->maxwidth = readshort(pheader);
382 pf->height = readshort(pheader);
383 pf->ascent = readshort(pheader);
384 pf->depth = readshort(pheader);
385 pf->firstchar = readlong(pheader);
386 pf->defaultchar = readlong(pheader);
387 pf->size = readlong(pheader);
388
389 /* get variable font data sizes*/
390 /* # words of bitmap_t*/
391 pf->bits_size = readlong(pheader);
392 *noffset = readlong(pheader);
393 *nwidth = readlong(pheader);
394
395 return pf;
396}
397
398/* load a font with room for glyphs, limited to bufsize if not zero */
399int font_load_ex( const char *path, size_t buf_size, int glyphs )
495{ 400{
401 //printf("\nfont_load_ex(%s, %d, %d)\n", path, buf_size, glyphs);
402 int fd = open(path, O_RDONLY|O_BINARY);
403 if ( fd < 0 )
404 return -1;
405
406 /* load font struct f with file header */
407 int file_size = filesize( fd );
408 struct font header;
409 struct font *pheader = &header;
410 struct font f;
411
412 uint32_t nwidth, noffset;
413 if ( !font_load_header( fd, pheader, &f, &nwidth, &noffset )
414#if LCD_DEPTH < 16
415 || f.depth
416#endif
417 )
418 {
419 close(fd);
420 return -1;
421 }
422
423 /* examine f and calc buffer size */
424 bool cached = false;
425 size_t bufsize = buf_size;
426 size_t glyph_buf_size = font_glyphs_to_bufsize( &f, glyphs );
427
428 if ( bufsize && glyphs && bufsize > glyph_buf_size)
429 bufsize = glyph_buf_size;
430 else
431 {
432 if ( glyphs )
433 bufsize = glyph_buf_size;
434 else
435 bufsize = MAX_FONT_SIZE;
436 }
437#ifdef FONT_HARD_LIMIT
438 if ( bufsize > MAX_FONT_SIZE )
439 bufsize = MAX_FONT_SIZE;
440#endif
441 if ( bufsize < (size_t) file_size )
442 cached = true;
443 else
444 bufsize = file_size;
445
446 /* check already loaded */
496 int font_id = find_font_index(path); 447 int font_id = find_font_index(path);
497 char *buffer;
498 int handle;
499 448
500 if (font_id > FONT_SYSFIXED) 449 if (font_id > FONT_SYSFIXED)
501 { 450 {
502 /* already loaded, no need to reload */ 451 /* already loaded, no need to reload */
503 struct buflib_alloc_data *pd = core_get_data(buflib_allocations[font_id]); 452 struct buflib_alloc_data *pd = core_get_data(buflib_allocations[font_id]);
504 if (pd->font.buffer_size < buffer_size) 453 if (pd->font.buffer_size < bufsize)
505 { 454 {
506 int old_refcount, old_id; 455 int old_refcount, old_id;
456 size_t old_bufsize = pd->font.buffer_size;
457 bool failed = false;
507 /* reload the font: 458 /* reload the font:
508 * 1) save of refcont and id 459 * 1) save of refcont and id
509 * 2) force unload (set refcount to 1 to make sure it get unloaded) 460 * 2) force unload (set refcount to 1 to make sure it get unloaded)
@@ -514,11 +465,14 @@ int font_load_ex(const char *path, size_t buffer_size)
514 old_refcount = pd->refcount; 465 old_refcount = pd->refcount;
515 pd->refcount = 1; 466 pd->refcount = 1;
516 font_unload(font_id); 467 font_unload(font_id);
517 font_id = font_load_ex(path, buffer_size); 468 font_id = font_load_ex(path, bufsize, glyphs);
518 if (font_id < 0) 469 if (font_id < 0)
519 { 470 {
520 // not much we can do here, maybe try reloading with the small buffer again 471 failed = true;
521 return -1; 472 font_id = font_load_ex(path, old_bufsize, 0);
473 /* we couldn't even get the old size, this shouldn't happen */
474 if ( font_id < 0 )
475 return -1;
522 } 476 }
523 if (old_id != font_id) 477 if (old_id != font_id)
524 { 478 {
@@ -528,51 +482,100 @@ int font_load_ex(const char *path, size_t buffer_size)
528 } 482 }
529 pd = core_get_data(buflib_allocations[font_id]); 483 pd = core_get_data(buflib_allocations[font_id]);
530 pd->refcount = old_refcount; 484 pd->refcount = old_refcount;
485 if(failed)
486 /* return error because we didn't satisfy the new buffer size */
487 return -1;
531 } 488 }
532 pd->refcount++; 489 pd->refcount++;
533 //printf("reusing handle %d for %s (count: %d)\n", font_id, path, pd->refcount); 490 //printf("reusing handle %d for %s (count: %d)\n", font_id, path, pd->refcount);
491 close(fd);
534 return font_id; 492 return font_id;
535 } 493 }
536 494
495 int open_slot = -1;
496
537 for (font_id = FONT_FIRSTUSERFONT; font_id < MAXFONTS; font_id++) 497 for (font_id = FONT_FIRSTUSERFONT; font_id < MAXFONTS; font_id++)
538 { 498 {
539 handle = buflib_allocations[font_id]; 499 if (buflib_allocations[ font_id ] < 0)
540 if (handle < 0)
541 { 500 {
501 open_slot = font_id;
542 break; 502 break;
543 } 503 }
544 } 504 }
545 handle = alloc_and_init(font_id, path, buffer_size); 505 if ( open_slot == -1 )
546 if (handle < 0)
547 return -1; 506 return -1;
507 font_id = open_slot;
548 508
549 buffer = buffer_from_handle(handle); 509 /* allocate mem */
550 lock_font_handle(handle, true); 510 int handle = core_alloc_ex( path,
551 511 bufsize + sizeof( struct buflib_alloc_data ),
552 if (!internal_load_font(font_id, path, buffer, buffer_size, handle)) 512 &buflibops );
513 if ( handle < 0 )
553 { 514 {
554 lock_font_handle(handle, false);
555 core_free(handle);
556 buflib_allocations[font_id] = -1;
557 return -1; 515 return -1;
558 } 516 }
559 517 struct buflib_alloc_data *pdata;
560 lock_font_handle(handle, false); 518 pdata = core_get_data(handle);
519 pdata->handle_locks = 1;
520 pdata->refcount = 1;
521
522 /* load and init */
523 struct font *pf = pf_from_handle( handle );
524 memcpy(pf, &f, sizeof( struct font) );
525
526 pf->fd = fd;
527 pf->fd_width = pf->fd_offset = -1;
528 pf->handle = handle;
529
530 pf->buffer_start = buffer_from_handle( pf->handle );
531 pf->buffer_position = pf->buffer_start + FONT_HEADER_SIZE;
532 pf->buffer_size = bufsize;
533 pf->buffer_end = pf->buffer_start + bufsize;
534
535 if ( cached )
536 {
537 if ( ! font_load_cached( pf, nwidth, noffset ) )
538 {
539 core_free( handle );
540 return -1;
541 }
542
543 /* trick to get a small cache for each file section *
544 * during glyph_cache_load() */
545 pf->fd_width = open( path, O_RDONLY|O_BINARY );
546 pf->fd_offset = open( path, O_RDONLY|O_BINARY );
547
548 glyph_cache_load( path, pf );
549
550 /* cached font: pf->fd stays open until the font is unloaded */
551 close( pf->fd_width );
552 pf->fd_width = -1;
553 close( pf->fd_offset );
554 pf->fd_offset = -1;
555 }
556 else
557 {
558 lseek( fd, 0, SEEK_SET);
559 read(fd, pf->buffer_start, pf->buffer_size);
560
561 close( fd );
562 pf->fd = -1;
563
564 if ( ! font_load_in_memory( pf, nwidth, noffset ) )
565 {
566 core_free( handle );
567 return -1;
568 }
569 }
561 buflib_allocations[font_id] = handle; 570 buflib_allocations[font_id] = handle;
562 //printf("%s -> [%d] -> %d\n", path, font_id, *handle); 571 //printf("%s -> [%d] -> %d\n", path, font_id, *handle);
572 lock_font_handle( handle, false );
563 return font_id; /* success!*/ 573 return font_id; /* success!*/
564} 574}
575
565int font_load(const char *path) 576int font_load(const char *path)
566{ 577{
567 int size; 578 return font_load_ex(path, MAX_FONT_SIZE, GLYPHS_TO_CACHE);
568 int fd = open( path, O_RDONLY );
569 if ( fd < 0 )
570 return -1;
571 size = filesize(fd);
572 if (size > MAX_FONT_SIZE)
573 size = MAX_FONT_SIZE;
574 close(fd);
575 return font_load_ex(path, size);
576} 579}
577 580
578void font_unload(int font_id) 581void font_unload(int font_id)
@@ -640,22 +643,6 @@ struct font* font_get(int font)
640 } 643 }
641} 644}
642 645
643static int pf_to_handle(struct font* pf)
644{
645 int i;
646 for (i=0; i<MAXFONTS; i++)
647 {
648 int handle = buflib_allocations[i];
649 if (handle > 0)
650 {
651 struct buflib_alloc_data *pdata = core_get_data(handle);
652 if (pf == &pdata->font)
653 return handle;
654 }
655 }
656 return -1;
657}
658
659/* 646/*
660 * Reads an entry into cache entry 647 * Reads an entry into cache entry
661 */ 648 */
@@ -663,13 +650,12 @@ static void
663load_cache_entry(struct font_cache_entry* p, void* callback_data) 650load_cache_entry(struct font_cache_entry* p, void* callback_data)
664{ 651{
665 struct font* pf = callback_data; 652 struct font* pf = callback_data;
666 int handle = pf_to_handle(pf); 653
667 unsigned short char_code = p->_char_code; 654 unsigned short char_code = p->_char_code;
668 unsigned char tmp[2]; 655 unsigned char tmp[2];
669 int fd; 656 int fd;
670 657
671 if (handle > 0) 658 lock_font_handle(pf->handle, true);
672 lock_font_handle(handle, true);
673 if (pf->file_width_offset) 659 if (pf->file_width_offset)
674 { 660 {
675 int width_offset = pf->file_width_offset + char_code; 661 int width_offset = pf->file_width_offset + char_code;
@@ -714,8 +700,7 @@ load_cache_entry(struct font_cache_entry* p, void* callback_data)
714 int src_bytes = glyph_bytes(pf, p->width); 700 int src_bytes = glyph_bytes(pf, p->width);
715 read(pf->fd, p->bitmap, src_bytes); 701 read(pf->fd, p->bitmap, src_bytes);
716 702
717 if (handle > 0) 703 lock_font_handle(pf->handle, false);
718 lock_font_handle(handle, false);
719} 704}
720 705
721/* 706/*
@@ -756,7 +741,7 @@ const unsigned char* font_get_bits(struct font* pf, unsigned short char_code)
756 741
757 if (pf->fd >= 0 && pf != &sysfont) 742 if (pf->fd >= 0 && pf != &sysfont)
758 { 743 {
759 bits = 744 bits =
760 (unsigned char*)font_cache_get(&pf->cache,char_code,load_cache_entry, pf)->bitmap; 745 (unsigned char*)font_cache_get(&pf->cache,char_code,load_cache_entry, pf)->bitmap;
761 } 746 }
762 else 747 else
@@ -850,49 +835,13 @@ void glyph_cache_save(int font_id)
850 return; 835 return;
851} 836}
852 837
853int font_glyphs_to_bufsize(const char *path, int glyphs)
854{
855 struct font f;
856 int bufsize;
857 char buf[FONT_HEADER_SIZE];
858
859 f.buffer_start = buf;
860 f.buffer_size = sizeof(buf);
861 f.buffer_position = buf;
862
863 f.fd = open(path, O_RDONLY|O_BINARY);
864 if(f.fd < 0)
865 return 0;
866
867 read(f.fd, f.buffer_position, FONT_HEADER_SIZE);
868 f.buffer_end = f.buffer_position + FONT_HEADER_SIZE;
869
870 if( !font_load_header(&f) )
871 {
872 close(f.fd);
873 return 0;
874 }
875 close(f.fd);
876
877 bufsize = LRU_SLOT_OVERHEAD + sizeof(struct font_cache_entry) +
878 sizeof( unsigned short);
879 bufsize += glyph_bytes(&f, f.maxwidth);
880 bufsize *= glyphs;
881 if ( bufsize < FONT_HEADER_SIZE )
882 bufsize = FONT_HEADER_SIZE;
883 return bufsize;
884}
885 838
886static int ushortcmp(const void *a, const void *b) 839static int ushortcmp(const void *a, const void *b)
887{ 840{
888 return ((int)(*(unsigned short*)a - *(unsigned short*)b)); 841 return ((int)(*(unsigned short*)a - *(unsigned short*)b));
889} 842}
890static void glyph_cache_load(int font_id) 843static void glyph_cache_load(const char *font_path, struct font *pf)
891{ 844{
892 int handle = buflib_allocations[font_id];
893 if (handle < 0)
894 return;
895 struct font *pf = pf_from_handle(handle);
896#define MAX_SORT 256 845#define MAX_SORT 256
897 if (pf->fd >= 0) { 846 if (pf->fd >= 0) {
898 int i, size, fd; 847 int i, size, fd;
@@ -907,7 +856,7 @@ static void glyph_cache_load(int font_id)
907 sort_size = MAX_SORT; 856 sort_size = MAX_SORT;
908 857
909 char filename[MAX_PATH]; 858 char filename[MAX_PATH];
910 font_path_to_glyph_path(font_filename(font_id), filename); 859 font_path_to_glyph_path(font_path, filename);
911 860
912 fd = open(filename, O_RDONLY|O_BINARY); 861 fd = open(filename, O_RDONLY|O_BINARY);
913#ifdef TRY_DEFAULT_GLYPHCACHE 862#ifdef TRY_DEFAULT_GLYPHCACHE
diff --git a/manual/advanced_topics/main.tex b/manual/advanced_topics/main.tex
index 17e72cd51a..3503e5851d 100644
--- a/manual/advanced_topics/main.tex
+++ b/manual/advanced_topics/main.tex
@@ -342,7 +342,8 @@ and the WPS, but you can use multiple fonts in each of the individual screens.\\
342 \item `filename' is the font filename to load. Fonts should be stored in 342 \item `filename' is the font filename to load. Fonts should be stored in
343 \fname{/.rockbox/fonts/} 343 \fname{/.rockbox/fonts/}
344 \item `glyphs' is an optional specification of how many unique glyphs to 344 \item `glyphs' is an optional specification of how many unique glyphs to
345 store in memory. Default is 256. 345 store in memory. Default is from the system setting
346 \setting{Glyphs To Load}.
346 \end{itemize} 347 \end{itemize}
347 348
348 An example would be: \config{\%Fl(2,12-Nimbus.fnt,100)} 349 An example would be: \config{\%Fl(2,12-Nimbus.fnt,100)}
diff --git a/manual/configure_rockbox/system_options.tex b/manual/configure_rockbox/system_options.tex
index 41b487164d..b61c55a5f2 100644
--- a/manual/configure_rockbox/system_options.tex
+++ b/manual/configure_rockbox/system_options.tex
@@ -136,9 +136,15 @@ This sub menu relates to limits in the Rockbox operating system.
136 in steps of 1,000 (default is 10,000). Higher values will shorten the 136 in steps of 1,000 (default is 10,000). Higher values will shorten the
137 music buffer, so you should increase this setting \emph{only} if you 137 music buffer, so you should increase this setting \emph{only} if you
138 have very large playlists. 138 have very large playlists.
139
140 \item [Glyphs To Cache.] This sets the default memory allocation size
141 for fonts in unique glyphs. This should be set to the number of unique
142 language glyphs and punctuation marks that are frequently displayed.
143 The default is 250.
139 \end{description} 144 \end{description}
140 \note{You will need to restart your player for changes to these options 145 \note{You will need to restart your player for changes to \setting{Max
141 to take effect.} 146 Entries in File Browser} or \setting{Max Playlist Size} to take effect
147 while \setting{Glyphs To Cache} will affect the next font load.}
142% TODO: this needs to be rewritten in another style, it lets you mix sound from another source into the music 148% TODO: this needs to be rewritten in another style, it lets you mix sound from another source into the music
143\opt{player}{ 149\opt{player}{
144 \subsection{Line In} This option activates the line-in port on \dap, which is 150 \subsection{Line In} This option activates the line-in port on \dap, which is
diff --git a/tools/convbdf.c b/tools/convbdf.c
index 4ae358e833..4cc7ec9983 100644
--- a/tools/convbdf.c
+++ b/tools/convbdf.c
@@ -1413,6 +1413,7 @@ int gen_c_source(struct font* pf, char *path)
1413 fprintf(ofp, " -1, /* font fd */\n" 1413 fprintf(ofp, " -1, /* font fd */\n"
1414 " -1, /* font fd width */\n" 1414 " -1, /* font fd width */\n"
1415 " -1, /* font fd offset */\n" 1415 " -1, /* font fd offset */\n"
1416 " -1, /* font handle */\n"
1416 " 0, /* buffer start */\n" 1417 " 0, /* buffer start */\n"
1417 " 0, /* ^ position */\n" 1418 " 0, /* ^ position */\n"
1418 " 0, /* ^ end */\n" 1419 " 0, /* ^ end */\n"