Index: firmware/export/font.h =================================================================== --- firmware/export/font.h (Revision 30740) +++ firmware/export/font.h (Arbeitskopie) @@ -120,13 +120,15 @@ int font_load_ex(const char *path, size_t buffer_size); int font_glyphs_to_bufsize(const char *path, int glyphs); void font_unload(int font_id); +void font_unload_all(void); struct font* font_get(int font); int font_getstringsize(const unsigned char *str, int *w, int *h, int fontnumber); int font_get_width(struct font* ft, unsigned short ch); const unsigned char * font_get_bits(struct font* ft, unsigned short ch); -void glyph_cache_save(struct font* pf); +void glyph_cache_save(int font_id); +void glyph_cache_save_all(void); #else /* HAVE_LCD_BITMAP */ Index: firmware/font.c =================================================================== --- firmware/font.c (Revision 30740) +++ firmware/font.c (Arbeitskopie) @@ -40,6 +40,7 @@ #include "rbunicode.h" #include "diacritic.h" #include "rbpaths.h" +#include "strlcpy.h" #define MAX_FONTSIZE_FOR_16_BIT_OFFSETS 0xFFDB @@ -70,6 +71,10 @@ #define O_BINARY 0 #endif +/* Define this to try loading /.rockbox/.glyphcache * + * when a font specific file fails. */ +//#define TRY_DEFAULT_GLYPHCACHE + /* compiled-in font */ extern struct font sysfont; @@ -82,7 +87,6 @@ unsigned char buffer[]; }; static int buflib_allocations[MAXFONTS]; -static int handle_for_glyphcache; static int buflibmove_callback(int handle, void* current, void* new) { @@ -132,7 +136,7 @@ /* Font cache structures */ static void cache_create(struct font* pf); -static void glyph_cache_load(struct font* pf); +static void glyph_cache_load(int font_id); /* End Font cache structures */ void font_init(void) @@ -140,7 +144,6 @@ int i = 0; while (ifd >= 0) - close(pf->fd); - font_reset(font_id); - /* open and read entire font file*/ pf->fd = open(path, O_RDONLY|O_BINARY); @@ -400,7 +396,7 @@ return false; } - glyph_cache_load(pf); + glyph_cache_load(font_id); } else { @@ -527,9 +523,6 @@ if (*handle < 0) return -1; - if (handle_for_glyphcache < 0) - handle_for_glyphcache = *handle; - buffer = buffer_from_handle(*handle); lock_font_handle(*handle, true); @@ -560,23 +553,40 @@ void font_unload(int font_id) { - int *handle = &buflib_allocations[font_id]; - struct buflib_alloc_data *pdata = core_get_data(*handle); + int handle = buflib_allocations[font_id]; + if ( handle < 0 ) + return; + struct buflib_alloc_data *pdata = core_get_data(handle); struct font* pf = &pdata->font; pdata->refcount--; if (pdata->refcount < 1) { //printf("freeing id: %d %s\n", font_id, core_get_name(*handle)); if (pf && pf->fd >= 0) + { + glyph_cache_save(font_id); close(pf->fd); - if (*handle > 0) - core_free(*handle); - if (handle_for_glyphcache == *handle) - handle_for_glyphcache = -1; // should find the next available handle - *handle = -1; + } + if (handle > 0) + core_free(handle); + buflib_allocations[font_id] = -1; } } +void font_unload_all(void) +{ + int i; + for (i=0; i 0) + { + struct buflib_alloc_data *alloc = core_get_data(buflib_allocations[i]); + alloc->refcount = 1; /* force unload */ + font_unload(i); + } + } +} + /* * Return a pointer to an incore font structure. * If the requested font isn't loaded/compiled-in, @@ -728,11 +738,11 @@ return bits; } static int cache_fd; +static struct font* cache_pf; static void glyph_file_write(void* data) { struct font_cache_entry* p = data; - int handle = handle_for_glyphcache; - struct font* pf = pf_from_handle(handle); + struct font* pf = cache_pf; unsigned short ch; unsigned char tmp[2]; @@ -752,26 +762,54 @@ return; } +void glyph_cache_save_all() +{ + int i; + for ( i = FONT_FIRSTUSERFONT ; i < MAXUSERFONTS ; i++ ) + { + glyph_cache_save( i ); + } +} + +void font_path_to_glyph_path( const char *font_path, char *glyph_path) +{ + /* take full file name, cut extension, and add .glyphcache */ + strlcpy(glyph_path, font_path, MAX_PATH); + glyph_path[strlen(glyph_path)-4] = '\0'; + strcat(glyph_path, ".glyphcache"); +} + /* save the char codes of the loaded glyphs to a file */ -void glyph_cache_save(struct font* pf) +void glyph_cache_save(int font_id) { - if (pf != pf_from_handle(handle_for_glyphcache)) + int handle = buflib_allocations[font_id]; + if ( handle < 0 ) return; - if (pf->fd >= 0) + struct font *pf = pf_from_handle(handle); + if (pf && pf->fd >= 0) { - cache_fd = open(GLYPH_CACHE_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0666); - if (cache_fd < 0) - return; + char filename[MAX_PATH]; + font_path_to_glyph_path(font_filename(font_id), filename); - lru_traverse(&pf->cache._lru, glyph_file_write); - - if (cache_fd >= 0) + cache_fd = open(filename, O_RDONLY|O_BINARY); + if (cache_fd >= 0) /* File exists, abort. */ { close(cache_fd); cache_fd = -1; + return; } - } - return; + + cache_fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666); + if (cache_fd < 0) + return; + cache_pf = pf; + lru_traverse(&cache_pf->cache._lru, glyph_file_write); + if (cache_fd >= 0) + { + close(cache_fd); + cache_fd = -1; + } + } } int font_glyphs_to_bufsize(const char *path, int glyphs) @@ -811,12 +849,14 @@ { return ((int)(*(unsigned short*)a - *(unsigned short*)b)); } -static void glyph_cache_load(struct font* pf) +static void glyph_cache_load(int font_id) { - if (handle_for_glyphcache <= 0) + int handle = buflib_allocations[font_id]; + if (handle < 0) return; + struct font* pf = pf_from_handle(handle); #define MAX_SORT 256 - if (pf->fd >= 0 && pf == pf_from_handle(handle_for_glyphcache)) { + if (pf->fd >= 0) { int fd; int i, size; unsigned char tmp[2]; @@ -829,9 +869,15 @@ if ( sort_size > MAX_SORT ) sort_size = MAX_SORT; - fd = open(GLYPH_CACHE_FILE, O_RDONLY|O_BINARY); + char filename[MAX_PATH]; + font_path_to_glyph_path(font_filename(font_id), filename); + fd = open(filename, O_RDONLY|O_BINARY); +#ifdef TRY_DEFAULT_GLYPHCACHE + /* if font specific file fails, try default */ + if (fd < 0) + fd = open(GLYPH_CACHE_FILE, O_RDONLY|O_BINARY); +#endif if (fd >= 0) { - /* only read what fits */ glyph_file_size = filesize( fd ); if ( glyph_file_size > 2*pf->cache._capacity ) { @@ -854,12 +900,8 @@ ushortcmp ); /* load font bitmaps */ - i = 0; - font_get_bits(pf, glyphs[i]); - for ( i = 1; i < size ; i++) { - if ( glyphs[i] != glyphs[i-1] ) + for ( i = 0; i < size ; i++) font_get_bits(pf, glyphs[i]); - } /* redo to fix lru order */ for ( i = 0; i < size ; i++) @@ -948,7 +990,3 @@ *h = pf->height; return width; } - -/* ----------------------------------------------------------------- - * vim: et sw=4 ts=8 sts=4 tw=78 - */ Index: firmware/powermgmt.c =================================================================== --- firmware/powermgmt.c (Revision 30740) +++ firmware/powermgmt.c (Arbeitskopie) @@ -656,7 +656,7 @@ if (battery_level_safe()) { /* do not save on critical battery */ #ifdef HAVE_LCD_BITMAP - glyph_cache_save(NULL); + font_unload_all(); #endif /* Commit pending writes if needed. Even though we don't do write caching,