summaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
authorFred Bauer <fred.w.bauer@gmail.com>2011-10-16 13:18:46 +0000
committerFred Bauer <fred.w.bauer@gmail.com>2011-10-16 13:18:46 +0000
commit100974162d20b259ee7145404ee74acd01f483b7 (patch)
tree8bd27074de8423e600905a3395689916fe0ee984 /firmware
parent50ac7ca7742e1bec2dd4d66ddffe7b1fe39535dd (diff)
downloadrockbox-100974162d20b259ee7145404ee74acd01f483b7.tar.gz
rockbox-100974162d20b259ee7145404ee74acd01f483b7.tar.bz2
rockbox-100974162d20b259ee7145404ee74acd01f483b7.zip
FS:12299 Font glyph cache is no longer saved. Each font will now have its own glyph cache file with the extension '.gc' Includes a temporary fix that delays saving the file to prevent the creation of multiple gc files with same name. Mostly JD Gordon's code.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30760 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/export/font.h2
-rw-r--r--firmware/font.c155
-rw-r--r--firmware/powermgmt.c2
3 files changed, 108 insertions, 51 deletions
diff --git a/firmware/export/font.h b/firmware/export/font.h
index 582c08f209..da8c85155c 100644
--- a/firmware/export/font.h
+++ b/firmware/export/font.h
@@ -126,7 +126,7 @@ 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);
#else /* HAVE_LCD_BITMAP */
diff --git a/firmware/font.c b/firmware/font.c
index 0f977c7059..8b70a7dcb9 100644
--- a/firmware/font.c
+++ b/firmware/font.c
@@ -70,6 +70,11 @@
#define O_BINARY 0
#endif
+/* Define this to try loading /.rockbox/.glyphcache *
+ * when a font specific file fails. This requires the *
+ * user to copy and rename a font glyph cache file */
+//#define TRY_DEFAULT_GLYPHCACHE
+
/* compiled-in font */
extern struct font sysfont;
@@ -82,7 +87,9 @@ struct buflib_alloc_data {
unsigned char buffer[];
};
static int buflib_allocations[MAXFONTS];
-static int handle_for_glyphcache;
+
+static int cache_fd;
+static struct font* cache_pf;
static int buflibmove_callback(int handle, void* current, void* new)
{
@@ -135,15 +142,15 @@ static inline unsigned char *buffer_from_handle(int handle)
/* Font cache structures */
static void cache_create(struct font* pf);
-static void glyph_cache_load(struct font* pf);
+static void glyph_cache_load(int fond_id);
/* End Font cache structures */
void font_init(void)
{
int i = 0;
+ cache_fd = -1;
while (i<MAXFONTS)
buflib_allocations[i++] = -1;
- handle_for_glyphcache = -1;
}
/* Check if we have x bytes left in the file buffer */
@@ -345,7 +352,7 @@ static struct font* font_load_cached(struct font* pf)
return pf;
}
-static bool internal_load_font(const char *path, char *buf,
+static bool internal_load_font(int font_id, const char *path, char *buf,
size_t buf_size, int handle)
{
size_t size;
@@ -387,7 +394,7 @@ static bool internal_load_font(const char *path, char *buf,
return false;
}
- glyph_cache_load(pf);
+ glyph_cache_load(font_id);
}
else
{
@@ -512,13 +519,10 @@ int font_load_ex(const char *path, size_t buffer_size)
if (handle < 0)
return -1;
- if (handle_for_glyphcache < 0)
- handle_for_glyphcache = handle;
-
buffer = buffer_from_handle(handle);
lock_font_handle(handle, true);
- if (!internal_load_font(path, buffer, buffer_size, handle))
+ if (!internal_load_font(font_id, path, buffer, buffer_size, handle))
{
lock_font_handle(handle, false);
core_free(handle);
@@ -546,20 +550,40 @@ int font_load(const char *path)
void font_unload(int font_id)
{
- int *handle = &buflib_allocations[font_id];
- struct buflib_alloc_data *pdata = core_get_data(*handle);
+ if ( font_id == FONT_SYSFIXED )
+ return;
+ 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<MAXFONTS; i++)
+ {
+ if (buflib_allocations[i] > 0)
+ {
+ struct buflib_alloc_data *alloc = core_get_data(buflib_allocations[i]);
+ alloc->refcount = 1; /* force unload */
+ font_unload(i);
+ }
}
}
@@ -713,45 +737,74 @@ const unsigned char* font_get_bits(struct font* pf, unsigned short char_code)
return bits;
}
-static int cache_fd;
+
+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, ".gc");
+}
+
+/* call with NULL to flush */
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];
+ static int buffer_pos = 0;
+#define WRITE_BUFFER 256
+ static unsigned char buffer[WRITE_BUFFER];
+ /* flush buffer & reset */
+ if ( data == NULL || buffer_pos >= WRITE_BUFFER)
+ {
+ write(cache_fd, buffer, buffer_pos);
+ buffer_pos = 0;
+ if ( data == NULL )
+ return;
+ }
if ( p->_char_code == 0xffff )
return;
ch = p->_char_code + pf->firstchar;
-
- if ( cache_fd >= 0) {
- tmp[0] = ch >> 8;
- tmp[1] = ch & 0xff;
- if (write(cache_fd, tmp, 2) != 2) {
- close(cache_fd);
- cache_fd = -1;
- }
- }
+ buffer[buffer_pos] = ch >> 8;
+ buffer[buffer_pos+1] = ch & 0xff;
+ buffer_pos += 2;
return;
}
/* 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 fd;
+
+ if( font_id < 0 )
return;
- if (pf->fd >= 0)
+ int handle = buflib_allocations[font_id];
+ if ( handle < 0 )
+ return;
+
+ 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)
+ /* FIXME: This sleep should not be necessary but without it *
+ * unloading multiple fonts and saving glyphcache files *
+ * quickly in succession creates multiple glyphcache files *
+ * with the same name. */
+ sleep(HZ/10);
+ char filename[MAX_PATH];
+ font_path_to_glyph_path(font_filename(font_id), filename);
+ fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666);
+ if (fd < 0)
return;
- lru_traverse(&pf->cache._lru, glyph_file_write);
-
- if (cache_fd >= 0)
+ cache_pf = pf;
+ cache_fd = fd;
+ lru_traverse(&cache_pf->cache._lru, glyph_file_write);
+ glyph_file_write(NULL);
+ if (cache_fd >= 0)
{
close(cache_fd);
cache_fd = -1;
@@ -797,14 +850,15 @@ static int ushortcmp(const void *a, const void *b)
{
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)) {
- int fd;
- int i, size;
+ if (pf->fd >= 0) {
+ int i, size, fd;
unsigned char tmp[2];
unsigned short ch;
unsigned short glyphs[MAX_SORT];
@@ -815,9 +869,16 @@ static void glyph_cache_load(struct font* pf)
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 ) {
@@ -840,12 +901,8 @@ static void glyph_cache_load(struct font* pf)
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++)
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c
index 79a7a90a2b..76322d65a3 100644
--- a/firmware/powermgmt.c
+++ b/firmware/powermgmt.c
@@ -656,7 +656,7 @@ void shutdown_hw(void)
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,