diff --git a/apps/misc.c b/apps/misc.c
index 66273b6..644763b 100644
--- a/apps/misc.c
+++ b/apps/misc.c
@@ -333,6 +333,7 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter)
 #if defined(HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
             audio_close_recording();
 #endif
+            font_unload_all();
 
             if(global_settings.talk_menu)
             {
diff --git a/apps/settings.c b/apps/settings.c
index a698606..a1ebf29 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -880,7 +880,7 @@ void settings_apply(bool read_disk)
             
             snprintf(buf, sizeof buf, FONT_DIR "/%s.fnt",
                      global_settings.font_file);
-            if (!loaded_font || strcmp(loaded_font, buf))
+            if (!loaded_font || strcmp(loaded_font, global_settings.font_file))
             {
                 CHART2(">font_load ", global_settings.font_file);
                 if (global_status.font_id[SCREEN_MAIN] >= 0)
@@ -897,7 +897,7 @@ void settings_apply(bool read_disk)
             const char* loaded_font = font_filename(global_status.font_id[SCREEN_REMOTE]);
             snprintf(buf, sizeof buf, FONT_DIR "/%s.fnt",
                      global_settings.remote_font_file);
-            if (!loaded_font || strcmp(loaded_font, buf))
+            if (!loaded_font || strcmp(loaded_font, global_settings.remote_font_file))
             {
                 CHART2(">font_load_remoteui ", global_settings.remote_font_file);
                 if (global_status.font_id[SCREEN_REMOTE] >= 0)
diff --git a/firmware/export/font.h b/firmware/export/font.h
index 582c08f..a0d3b10 100644
--- a/firmware/export/font.h
+++ b/firmware/export/font.h
@@ -120,18 +120,20 @@ int font_load(const char *path);
 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);
 
 #else /* HAVE_LCD_BITMAP */
 
 #define font_init()
 #define font_load(x)
+#define font_unload_all()
 
 #endif
 
diff --git a/firmware/font.c b/firmware/font.c
index f00ff0e..05cc1a6 100644
--- a/firmware/font.c
+++ b/firmware/font.c
@@ -82,7 +82,6 @@ struct buflib_alloc_data {
     unsigned char buffer[];
 };
 static int buflib_allocations[MAXFONTS];
-static int handle_for_glyphcache;
 
 static int buflibmove_callback(int handle, void* current, void* new)
 {
@@ -135,7 +134,7 @@ 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 font_id);
 /* End Font cache structures */
 
 void font_init(void)
@@ -143,7 +142,6 @@ void font_init(void)
     int i = 0;
     while (i<MAXFONTS)
         buflib_allocations[i++] = -1;
-    handle_for_glyphcache = -1;
 }
 
 /* Check if we have x bytes left in the file buffer */
@@ -360,7 +358,7 @@ static bool internal_load_font(int font_id, const char *path,
     size_t size;
     struct font* pf = pf_from_handle(buflib_allocations[font_id]);
     /* save loaded glyphs */
-    glyph_cache_save(pf);
+    glyph_cache_save(font_id);
     /* Close font file handle */
     if (pf->fd >= 0)
         close(pf->fd);
@@ -403,7 +401,7 @@ static bool internal_load_font(int font_id, const char *path,
             return false;
         }
 
-        glyph_cache_load(pf);
+        glyph_cache_load(font_id);
     }
     else
     {
@@ -427,14 +425,28 @@ static bool internal_load_font(int font_id, const char *path,
     return true;
 }
 
+static const char* font_shrinkfilename(const char* path)
+{
+    static char filename[MAX_PATH];
+    char *end = strrchr(path, '/');
+    if (!end)
+        return NULL;
+    strlcpy(filename, end+1, MAX_PATH);
+    end = strrchr(filename, '.');
+    if (end)
+        *end = '\0';
+    return filename;
+}
+
 static int find_font_index(const char* path)
 {
     int index = 0, handle;
+    const char* shortname = font_shrinkfilename(path);
 
     while (index < MAXFONTS)
     {
         handle = buflib_allocations[index];
-        if (handle > 0 && !strcmp(core_get_name(handle), path))
+        if (handle > 0 && !strcmp(core_get_name(handle), shortname))
             return index;
         index++;
     }
@@ -450,7 +462,7 @@ static int alloc_and_init(int font_idx, const char* name, size_t size)
     size_t alloc_size = size + sizeof(struct buflib_alloc_data);
     if (handle > 0)
         return handle;
-    *phandle = core_alloc_ex(name, alloc_size, &buflibops);
+    *phandle = core_alloc_ex(font_shrinkfilename(name), alloc_size, &buflibops);
     handle = *phandle;
     if (handle < 0)
         return handle;
@@ -530,9 +542,6 @@ 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);
 
@@ -570,16 +579,25 @@ void font_unload(int font_id)
     if (pdata->refcount < 1)
     {
         //printf("freeing id: %d %s\n", font_id, core_get_name(*handle));
+        glyph_cache_save(font_id);
         if (pf && pf->fd >= 0)
             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;
     }
 }
 
+void font_unload_all(void)
+{
+    int i;
+    for (i=0; i<MAXFONTS; i++)
+    {
+        if (buflib_allocations[i] > 0)
+            font_unload(i);
+    }
+}
+
 /*
  * Return a pointer to an incore font structure.
  * If the requested font isn't loaded/compiled-in,
@@ -601,7 +619,7 @@ struct font* font_get(int font)
         if (--font < 0)
             return &sysfont;
     }
-}
+}     
 
 static int pf_to_handle(struct font* pf)
 {
@@ -728,11 +746,11 @@ const unsigned char* font_get_bits(struct font* pf, unsigned short char_code)
     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];
 
@@ -753,16 +771,19 @@ static void glyph_file_write(void* data)
 }
 
 /* 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))
-        return;
+    struct font *pf = pf_from_handle(buflib_allocations[font_id]);
     if (pf->fd >= 0) 
     {
-        cache_fd = open(GLYPH_CACHE_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0666);
+        char filename[MAX_PATH];
+        snprintf(filename, MAX_PATH, ROCKBOX_DIR "/%s.glyphcache",
+                font_filename(font_id));
+        cache_fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666);
         if (cache_fd < 0)
             return;
 
+        cache_pf = pf;
         lru_traverse(&pf->cache._lru, glyph_file_write);
 
         if (cache_fd >= 0)
@@ -811,12 +832,11 @@ 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)
-        return;
+    struct font* pf = pf_from_handle(buflib_allocations[font_id]);
 #define MAX_SORT 256
-    if (pf->fd >= 0 && pf == pf_from_handle(handle_for_glyphcache)) {
+    if (pf && pf->fd >= 0) {
         int fd;
         int i, size;
         unsigned char tmp[2];
@@ -829,7 +849,10 @@ 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];
+        snprintf(filename, MAX_PATH, ROCKBOX_DIR "/%s.glyphcache",
+                font_filename(font_id));
+        fd = open(filename, O_RDONLY|O_BINARY);
         if (fd >= 0) {
             
             /* only read what fits */
