Index: firmware/export/font.h
===================================================================
--- firmware/export/font.h	(revision 30755)
+++ firmware/export/font.h	(working copy)
@@ -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 30755)
+++ firmware/font.c	(working copy)
@@ -70,6 +70,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,8 +86,10 @@
     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)
 {
     (void)handle;
@@ -135,15 +141,15 @@
 
 /* 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 +351,7 @@
     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 +393,7 @@
             return false;
         }
 
-        glyph_cache_load(pf);
+        glyph_cache_load(font_id);
     }
     else
     {
@@ -512,13 +518,10 @@
     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,23 +549,41 @@
 
 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<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);
+        }
+    }
+}
+
 /*
  * Return a pointer to an incore font structure.
  * If the requested font isn't loaded/compiled-in,
@@ -713,12 +734,20 @@
 
     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, ".glyphcache");
+}
+
 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];
 
@@ -739,19 +768,25 @@
 }
 
 /* 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) 
+    while( cache_fd >= 0 )
+        yield();
+    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);
+        char filename[MAX_PATH];
+        font_path_to_glyph_path(font_filename(font_id), filename);
+        cache_fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666);
         if (cache_fd < 0)
             return;
 
-        lru_traverse(&pf->cache._lru, glyph_file_write);
-
-        if (cache_fd >= 0)
+        cache_pf = pf;
+        lru_traverse(&cache_pf->cache._lru, glyph_file_write);
+        if (cache_fd >= 0) 
         {
             close(cache_fd);
             cache_fd = -1;
@@ -760,6 +795,15 @@
     return;
 }
 
+void glyph_cache_save_all()
+{
+    int i;
+    for ( i = FONT_FIRSTUSERFONT ; i < MAXUSERFONTS ; i++ )
+    {
+        glyph_cache_save( i );
+    }
+}
+
 int font_glyphs_to_bufsize(const char *path, int glyphs)
 {
     struct font f;
@@ -797,13 +841,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)) {
-        int fd;
+    if (pf->fd >= 0) {
         int i, size;
         unsigned char tmp[2];
         unsigned short ch;
@@ -815,20 +860,28 @@
         if ( sort_size > MAX_SORT )
              sort_size = MAX_SORT;
 
-        fd = open(GLYPH_CACHE_FILE, O_RDONLY|O_BINARY);
-        if (fd >= 0) {
-            
+        char filename[MAX_PATH];
+        font_path_to_glyph_path(font_filename(font_id), filename);
+        while ( cache_fd >= 0 )
+            yield();
+        cache_fd = open(filename, O_RDONLY|O_BINARY);
+#ifdef TRY_DEFAULT_GLYPHCACHE
+        /* if font specific file fails, try default */
+        if (cache_fd < 0)
+            cache_fd = open(GLYPH_CACHE_FILE, O_RDONLY|O_BINARY);
+#endif
+        if (cache_fd >= 0) {
             /* only read what fits */
-            glyph_file_size = filesize( fd );
+            glyph_file_size = filesize( cache_fd );
             if ( glyph_file_size > 2*pf->cache._capacity ) {
                 glyph_file_skip = glyph_file_size - 2*pf->cache._capacity;
-                lseek( fd, glyph_file_skip, SEEK_SET );
+                lseek( cache_fd, glyph_file_skip, SEEK_SET );
             }
 
             while(1) {
 
                 for ( size = 0;
-                      read( fd, tmp, 2 ) == 2 && size < sort_size;
+                      read( cache_fd, tmp, 2 ) == 2 && size < sort_size;
                       size++ ) 
                 {
                     glyphs[size] = (tmp[0] << 8) | tmp[1];
@@ -840,12 +893,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++)
@@ -855,7 +904,8 @@
                     break;
             }
 
-            close(fd);
+            close(cache_fd);
+            cache_fd = -1;
         } else {
             /* load latin1 chars into cache */
             for ( ch = 32 ; ch < 256  && ch < pf->cache._capacity + 32; ch++ )
Index: firmware/powermgmt.c
===================================================================
--- firmware/powermgmt.c	(revision 30755)
+++ firmware/powermgmt.c	(working copy)
@@ -656,7 +656,8 @@
 
     if (battery_level_safe()) { /* do not save on critical battery */
 #ifdef HAVE_LCD_BITMAP
-        glyph_cache_save(NULL);
+        //glyph_cache_save_all();
+        font_unload_all();
 #endif
 
 /* Commit pending writes if needed. Even though we don't do write caching,
