### Eclipse Workspace Patch 1.0
#P rockbox
Index: apps/gui/gwps-common.c
===================================================================
--- apps/gui/gwps-common.c.orig
+++ apps/gui/gwps-common.c
@@ -2327,7 +2327,8 @@ bool gui_wps_refresh(struct gui_wps *gwp
         return false;
     }
 #ifdef HAVE_LCD_BITMAP
-    int h = font_get(FONT_UI)->height;
+    display->setfont(FONT_WPS);
+    int h = font_get(FONT_WPS)->height;
     int offset = 0;
     gui_wps_statusbar_draw(gwps, true);
     if(data->wps_sb_tag && data->show_sb_on_wps)
Index: apps/gui/gwps.c
===================================================================
--- apps/gui/gwps.c.orig
+++ apps/gui/gwps.c
@@ -94,6 +94,11 @@ static void gui_wps_set_margin(struct gu
 }
 #endif
 
+static void gui_wps_set_font(struct gui_wps *gwps)
+{
+    gwps->display->setfont(FONT_WPS);
+}
+
 long gui_wps_show(void)
 {
     long button = 0;
@@ -108,6 +113,12 @@ long gui_wps_show(void)
     
     wps_state_init();
 
+    /* Set WPS display font */
+    FOR_NB_SCREENS(i)
+    {
+        gui_wps_set_font(&gui_wps[i]);
+    }
+    
 #ifdef HAVE_LCD_CHARCELLS
     status_set_audio(true);
     status_set_param(false);
@@ -777,6 +788,7 @@ bool wps_data_load(struct wps_data *wps_
             wps_data->img_buf_ptr = wps_data->img_buf; /* where in image buffer */
 
             wps_data->img_buf_free = IMG_BUFSIZE; /* free space in image buffer */
+            DEBUGF("image buffer=%d\n",wps_data->img_buf_free);
 #endif
             while( ( read_line(fd, &wps_data->format_buffer[start],
                     sizeof(wps_data->format_buffer)-start) ) > 0 )
Index: apps/gui/buttonbar.c
===================================================================
--- apps/gui/buttonbar.c.orig
+++ apps/gui/buttonbar.c
@@ -116,7 +116,8 @@ void gui_buttonbar_draw(struct gui_butto
         gui_buttonbar_draw_button(buttonbar, i);
     display->update_rect(0, display->height - BUTTONBAR_HEIGHT,
                          display->width, BUTTONBAR_HEIGHT);
-    display->setfont(FONT_UI);
+    // MWE ?
+	display->setfont(FONT_BROWSER);
 }
 
 bool gui_buttonbar_isset(struct gui_buttonbar * buttonbar)
Index: apps/gui/quickscreen.c
===================================================================
--- apps/gui/quickscreen.c.orig
+++ apps/gui/quickscreen.c
@@ -122,7 +122,6 @@ static void gui_quickscreen_draw(struct 
                          PUTSXY_BOTTOM-font_h, 7, 8);
 
     gui_textarea_update(display);
-    display->setfont(FONT_UI);
 }
 
 /*
Index: apps/gui/statusbar.c
===================================================================
--- apps/gui/statusbar.c.orig
+++ apps/gui/statusbar.c
@@ -383,6 +383,7 @@ static void gui_statusbar_icon_battery(s
 #if LCD_DEPTH > 1
     unsigned int prevfg = 0;
 #endif
+    int oldfont;
 
 #if CONFIG_CHARGING
     if (batt_charge_step >= 0)
@@ -407,16 +408,20 @@ static void gui_statusbar_icon_battery(s
 #else /* all others */
     if (global_settings.battery_display && (percent > -1)) {
 #endif
-        /* Numeric display */
-        display->setfont(FONT_SYSFIXED);
+        /* Numeric display */        			
         snprintf(buffer, sizeof(buffer), "%3d", percent);
+
+ 		/* remember to set back if font changed */ 
+		oldfont=display->getcurfont();
+
+	    display->setfont(FONT_SYSFIXED);
         display->getstringsize(buffer, &width, &height);
         if (height <= STATUSBAR_HEIGHT)
             display->putsxy(STATUSBAR_BATTERY_X_POS
                              + STATUSBAR_BATTERY_WIDTH / 2
                              - width/2, STATUSBAR_Y_POS, buffer);
-        display->setfont(FONT_UI);
-
+        /* set back previous font */
+    	display->setfont(oldfont);
     }
     else {
         /* draw battery */
@@ -442,12 +447,16 @@ static void gui_statusbar_icon_battery(s
     }
 
     if (percent == -1) {
+ 		/* remember to set back if font changed */ 
+		oldfont=display->getcurfont();
+
         display->setfont(FONT_SYSFIXED);
         display->putsxy(STATUSBAR_BATTERY_X_POS + STATUSBAR_BATTERY_WIDTH / 2
                          - 4, STATUSBAR_Y_POS, "?");
-        display->setfont(FONT_UI);
+        /* set back previous font */
+    	display->setfont(oldfont);                  
     }
-}
+ }
 
 /*
  * Print volume gauge to status bar
@@ -490,8 +499,11 @@ static bool gui_statusbar_icon_volume(st
         /* display volume level numerical? */
         if (type)
         {
+			snprintf(buffer, sizeof(buffer), "%2d", volume);
+            /* remember to set back if font changed */ 
+			int oldFont=display->getcurfont();
+        	
             display->setfont(FONT_SYSFIXED);
-            snprintf(buffer, sizeof(buffer), "%2d", volume);
             display->getstringsize(buffer, &width, &height);
             if (height <= STATUSBAR_HEIGHT)
             {
@@ -499,7 +511,7 @@ static bool gui_statusbar_icon_volume(st
                                  + STATUSBAR_VOLUME_WIDTH / 2
                                  - width/2, STATUSBAR_Y_POS, buffer);
             }
-            display->setfont(FONT_UI);
+            display->setfont(oldFont);
         } else {
             /* display volume bar */
             vol = (volume - minvol) * 14 / (maxvol - minvol);
@@ -588,6 +600,7 @@ static void gui_statusbar_time(struct sc
 {
     unsigned char buffer[6];
     unsigned int width, height;
+ 
     if ( hour >= 0 &&
          hour <= 23 &&
          minute >= 0 &&
@@ -603,13 +616,16 @@ static void gui_statusbar_time(struct sc
     else {
         strncpy(buffer, "--:--", sizeof buffer);
     }
+	/* remember to set back if font changed */ 
+	int oldfont=display->getcurfont();
+	
     display->setfont(FONT_SYSFIXED);
     display->getstringsize(buffer, &width, &height);
     if (height <= STATUSBAR_HEIGHT) {
         display->putsxy(STATUSBAR_TIME_X_END(display->width) - width,
                         STATUSBAR_Y_POS, buffer);
     }
-    display->setfont(FONT_UI);
+    display->setfont(oldfont);
 
 }
 #endif
@@ -712,6 +728,9 @@ static void gui_statusbar_write_samplera
 
 static void gui_statusbar_icon_recording_info(struct screen * display)
 {
+	/* remember to set back if font changed */ 
+	int oldfont=display->getcurfont();
+		
 #if CONFIG_CODEC != SWCODEC
     char buffer[3];
     int width, height;
@@ -774,6 +793,7 @@ static void gui_statusbar_icon_recording
                              STATUSBAR_RECCHANNELS_X_POS, STATUSBAR_Y_POS,
                              STATUSBAR_RECCHANNELS_WIDTH, STATUSBAR_HEIGHT);
     }
+	display->setfont(oldfont);
 }
 #endif /* HAVE_RECORDING */
 
Index: apps/gui/list.h
===================================================================
--- apps/gui/list.h.orig
+++ apps/gui/list.h
@@ -103,6 +103,13 @@ struct gui_list
     ICON title_icon;
 };
 
+/* gui_list can have two contexts, LIST_MENU and LIST_BROWSER. Contexts are used to determine display font. */
+#ifdef HAVE_LCD_BITMAP
+extern short gui_list_context;
+#define GUI_LIST_CONTEXT_MENU  0
+#define GUI_LIST_CONTEXT_BRWSR 1
+#endif
+
 /*
  * Sets the numbers of items the list can currently display
  * note that the list's context like the currently pointed item is resetted
Index: apps/gui/list.c
===================================================================
--- apps/gui/list.c.orig
+++ apps/gui/list.c
@@ -25,6 +25,7 @@
 #include "string.h"
 #include "settings.h"
 #include "kernel.h"
+#include "debug.h"
 
 #include "action.h"
 #include "screen_access.h"
@@ -46,6 +47,10 @@
 #define FRAMEDROP_TRIGGER 6
 
 #ifdef HAVE_LCD_BITMAP
+/* gui_list can have two contexts, MENU and BROWSER. Contexts are used to determine display font. */
+short gui_list_context = -1;
+#define GUI_LIST_CONTEXT_MENU  0
+#define GUI_LIST_CONTEXT_BRWSR 1
 static int offset_step = 16; /* pixels per screen scroll step */
 /* should lines scroll out of the screen */
 static bool offset_out_of_view = false;
@@ -162,8 +167,20 @@ static void gui_list_put_selection_in_sc
                                       bool put_from_end)
 {
 #ifdef HAVE_LCD_BITMAP
-    gui_list->display->setfont(FONT_UI);
+	// MWE do it before gui_textarea_update_nblines
+	switch (gui_list_context)   /* Set appropriate font */
+	{
+		case GUI_LIST_CONTEXT_MENU:
+			gui_list->display->setfont(FONT_MENU);
+			break;
+		case GUI_LIST_CONTEXT_BRWSR:
+			gui_list->display->setfont(FONT_BROWSER);
+			break;
+		default:
+			debugf("gui_list_put_selection_in_screen(): unknown font context: %i\n", gui_list_context);
+	}
 #endif
+
     gui_textarea_update_nblines(gui_list->display);
     int nb_lines=gui_list->display->nb_lines;
     if (SHOW_LIST_TITLE)
@@ -244,6 +261,24 @@ static void gui_list_draw_smart(struct g
 #endif
     int start, end;
     bool partial_draw = false;
+	
+#ifdef HAVE_LCD_BITMAP
+    // MWE do it before drawing title and gui_textarea_update_nblines
+	switch (gui_list_context)   /* Set appropriate font */
+	{
+		case GUI_LIST_CONTEXT_MENU:
+			display->setfont(FONT_MENU);
+			break;
+		case GUI_LIST_CONTEXT_BRWSR:
+			display->setfont(FONT_BROWSER);
+			break;
+		default:
+			debugf("gui_list_draw(): unknown font context: %i\n", gui_list_context);
+	}
+#endif
+      
+	// MWE do it before accessing nb_lines
+	gui_textarea_update_nblines(display);    
 
     /* Speed up UI by drawing the changed contents only. */
     if (gui_list == last_list_displayed[gui_list->display->screen_type]
@@ -316,8 +351,7 @@ static void gui_list_draw_smart(struct g
 
     /* Adjust the position of icon, cursor, text for the list */
 #ifdef HAVE_LCD_BITMAP
-    display->setfont(FONT_UI);
-    gui_textarea_update_nblines(display);
+    
     bool draw_scrollbar;
 
     draw_scrollbar = (global_settings.scrollbar &&
Index: firmware/drivers/lcd-16bit.c
===================================================================
--- firmware/drivers/lcd-16bit.c.orig
+++ firmware/drivers/lcd-16bit.c
@@ -174,6 +174,11 @@ void lcd_setfont(int newfont)
     curfont = newfont;
 }
 
+int lcd_getcurfont()
+{
+    return curfont;
+}
+
 int lcd_getstringsize(const unsigned char *str, int *w, int *h)
 {
     return font_getstringsize(str, w, h, curfont);
@@ -790,7 +795,7 @@ static void lcd_putsxyofs(int x, int y, 
         const unsigned char *bits;
 
         /* get proportional width and glyph bits */
-        width = font_get_width(pf,ch);
+        width = font_get_width(pf,ch,curfont);
 
         if (ofs > width)
         {
@@ -798,7 +803,7 @@ static void lcd_putsxyofs(int x, int y, 
             continue;
         }
 
-        bits = font_get_bits(pf, ch);
+        bits = font_get_bits(pf, ch, curfont);
 
         lcd_mono_bitmap_part(bits, ofs, 0, width, x, y, 
             (x+width > used_rightmargin?used_rightmargin-x:width) - ofs, pf->height);
Index: firmware/drivers/lcd-2bit-horz.c
===================================================================
--- firmware/drivers/lcd-2bit-horz.c.orig
+++ firmware/drivers/lcd-2bit-horz.c
@@ -149,6 +149,11 @@ void lcd_setfont(int newfont)
     curfont = newfont;
 }
 
+int lcd_getcurfont()
+{
+    return curfont;
+}
+
 int lcd_getstringsize(const unsigned char *str, int *w, int *h)
 {
     return font_getstringsize(str, w, h, curfont);
@@ -817,7 +822,7 @@ static void lcd_putsxyofs(int x, int y, 
         const unsigned char *bits;
 
         /* get proportional width and glyph bits */
-        width = font_get_width(pf,ch);
+        width = font_get_width(pf,ch,curfont);
 
         if (ofs > width)
         {
@@ -825,7 +830,7 @@ static void lcd_putsxyofs(int x, int y, 
             continue;
         }
 
-        bits = font_get_bits(pf, ch);
+        bits = font_get_bits(pf, ch, curfont);
 
         lcd_mono_bitmap_part(bits, ofs, 0, width, x, y, width - ofs,
                              pf->height);
Index: apps/filetree.c
===================================================================
--- apps/filetree.c.orig
+++ apps/filetree.c
@@ -514,8 +514,33 @@ int ft_enter(struct tree_context* c)
 #ifdef HAVE_LCD_BITMAP
             case TREE_ATTR_FONT:
                 gui_syncsplash(0, str(LANG_WAIT));
-                font_load(buf);
-                set_file(buf, (char *)global_settings.font_file, MAX_FILENAME);
+                /* If a font is chosen it overrides all theme settings */
+                font_load(buf, FONT_BROWSER);
+               
+                /* set_file will change buf!!! 
+                 * so make a copy */
+                char buf_copy[MAX_PATH];
+                strcpy(buf_copy, buf);
+                set_file(buf_copy, (char *)global_settings.browserfont, MAX_FILENAME);
+               
+                font_load(buf, FONT_WPS);
+                strcpy(buf_copy, buf);
+                set_file(buf_copy, (char *)global_settings.wpsfont, MAX_FILENAME);
+               
+                font_load(buf, FONT_MENU);
+                strcpy(buf_copy, buf);
+                set_file(buf_copy, (char *)global_settings.menufont, MAX_FILENAME);
+               
+#ifdef CONFIG_TUNER
+                font_load(buf, FONT_TUNER);
+                strcpy(buf_copy, buf);
+                set_file(buf_copy, (char *)global_settings.tunerfont, MAX_FILENAME);
+#endif
+#ifdef HAVE_RECORDING
+                font_load(buf, FONT_RECORD);
+                strcpy(buf_copy, buf);
+                set_file(buf_copy, (char *)global_settings.recordfont, MAX_FILENAME);
+#endif
                 break;
 
             case TREE_ATTR_KBD:
Index: apps/settings.h
===================================================================
--- apps/settings.h.orig
+++ apps/settings.h
@@ -423,7 +423,18 @@ struct user_settings
 #if CONFIG_TUNER
     unsigned char fmr_file[MAX_FILENAME+1]; /* last fmr preset */
 #endif
-    unsigned char font_file[MAX_FILENAME+1]; /* last font */
+    unsigned char font_file[MAX_FILENAME+1]; /* backward comp */
+    
+    unsigned char browserfont[MAX_FILENAME+1]; /* UI fonts */
+    unsigned char wpsfont[MAX_FILENAME+1];
+    unsigned char menufont[MAX_FILENAME+1];
+#ifdef CONFIG_TUNER
+    unsigned char tunerfont[MAX_FILENAME+1];
+#endif
+#ifdef HAVE_RECORDING
+    unsigned char recordfont[MAX_FILENAME+1];
+#endif
+
     unsigned char wps_file[MAX_FILENAME+1];  /* last wps */
     unsigned char lang_file[MAX_FILENAME+1]; /* last language */
 
Index: apps/settings.c
===================================================================
--- apps/settings.c.orig
+++ apps/settings.c
@@ -295,6 +295,32 @@ static bool cfg_string_to_int(int settin
     return false;
 }
 
+/** reset some settings when loading a wps file
+ * to keep backward compatibility **/
+void theme_settings_reset(void)
+{
+	/* multifont settings */
+    global_settings.font_file[0] = '\0';
+    global_settings.browserfont[0] = '\0';
+    global_settings.wpsfont[0] = '\0';
+    global_settings.menufont[0] = '\0';
+#ifdef CONFIG_TUNER
+    global_settings.tunerfont[0] = '\0';
+#endif
+#ifdef HAVE_RECORDING
+    global_settings.recordfont[0] = '\0';
+#endif
+    /* reset rpws setting */
+#ifdef HAVE_REMOTE_LCD
+	global_settings.rwps_file[0]='\0';
+#endif
+	/* reset color settings */
+#ifdef HAVE_LCD_COLOR
+	global_settings.fg_color=LCD_DEFAULT_FG;
+	global_settings.bg_color=LCD_DEFAULT_BG;
+#endif
+}
+
 bool settings_load_config(const char* file, bool apply)
 {
     int fd;
@@ -305,6 +331,11 @@ bool settings_load_config(const char* fi
     fd = open(file, O_RDONLY);
     if (fd < 0)
         return false;
+    
+    /* if loading a theme reset some settings for backward compatibility */
+    if(strncmp(file, THEME_DIR, strlen(THEME_DIR))==0){
+    	theme_settings_reset();
+    }
 
     while (read_line(fd, line, sizeof line) > 0)
     {
@@ -675,7 +706,9 @@ void settings_apply(void)
 #if CONFIG_CODEC == SWCODEC
     int i;
 #endif
-
+    /** backward comp **/
+    bool useMultifont=false;
+    
     DEBUGF( "settings_apply()\n" );
     sound_settings_apply();
 
@@ -783,13 +816,89 @@ void settings_apply(void)
 #endif
 
 #ifdef HAVE_LCD_BITMAP
-    if ( global_settings.font_file[0]) {
-        snprintf(buf, sizeof buf, FONT_DIR "/%s.fnt",
-                 global_settings.font_file);
-        font_load(buf);
+     /* Load all the fonts */
+     if ( global_settings.browserfont[0] &&
+          global_settings.browserfont[0] != 0xff ) {
+    	 useMultifont=true;
+         snprintf(buf, sizeof buf, FONT_DIR "/%s.fnt",
+                  global_settings.browserfont);
+         font_load(buf, FONT_BROWSER);
+     }
+     else
+         font_reset(FONT_BROWSER);
+ 
+     if ( global_settings.wpsfont[0] &&
+          global_settings.wpsfont[0] != 0xff ) {
+    	  useMultifont=true;
+		  snprintf(buf, sizeof buf, FONT_DIR "/%s.fnt",
+                  global_settings.wpsfont);
+         font_load(buf, FONT_WPS);
+	  }
+	  else
+         font_reset(FONT_WPS);
+  
+     if ( global_settings.menufont[0] &&
+          global_settings.menufont[0] != 0xff ) {
+         useMultifont=true;
+         snprintf(buf, sizeof buf, FONT_DIR "/%s.fnt",
+                  global_settings.menufont);
+         font_load(buf, FONT_MENU);
+     }
+     else
+         font_reset(FONT_MENU);
+ 
+#ifdef CONFIG_TUNER
+     if ( global_settings.tunerfont[0] &&
+          global_settings.tunerfont[0] != 0xff ) {
+         useMultifont=true;
+         snprintf(buf, sizeof buf, FONT_DIR "/%s.fnt",
+                  global_settings.tunerfont);
+         font_load(buf, FONT_TUNER);
+     }
+     else
+         font_reset(FONT_TUNER);
+#endif /* CONFIG_TUNER */
+ 
+#ifdef HAVE_RECORDING
+     if ( global_settings.recordfont[0] &&
+          global_settings.recordfont[0] != 0xff ) {
+         useMultifont=true;
+         snprintf(buf, sizeof buf, FONT_DIR "/%s.fnt",
+                  global_settings.recordfont);
+         font_load(buf, FONT_RECORD);
+     }
+     else
+         font_reset(FONT_RECORD);
+#endif /* HAVE_RECORDING */
+
+    /** backward comp **/
+    if(!useMultifont){
+        if ( global_settings.font_file[0] &&
+                global_settings.font_file[0] != 0xff ) {
+                snprintf(buf, sizeof buf, FONT_DIR "/%s.fnt",
+                        global_settings.font_file);
+               font_load(buf, FONT_BROWSER);
+               font_load(buf, FONT_WPS);
+               font_load(buf, FONT_MENU);
+#ifdef CONFIG_TUNER
+               font_load(buf, FONT_TUNER);
+#endif
+#ifdef HAVE_RECORDING
+               font_load(buf, FONT_RECORD);
+#endif
+           }
+           else {
+               font_reset(FONT_BROWSER);
+               font_reset(FONT_WPS);
+               font_reset(FONT_MENU);
+#ifdef CONFIG_TUNER
+               font_reset(FONT_TUNER);
+#endif
+#ifdef HAVE_RECORDING
+               font_reset(FONT_RECORD);
+#endif
+           }
     }
-    else
-        font_reset();
 
     if ( global_settings.kbd_file[0]) {
         snprintf(buf, sizeof buf, ROCKBOX_DIR "/%s.kbd",
@@ -1276,14 +1385,15 @@ bool set_option(const char* string, void
 
 void set_file(char* filename, char* setting, int maxlen)
 {
-    char* fptr = strrchr(filename,'/');
+    char *fptr = strrchr(filename,'/');
     int len;
     int extlen = 0;
-    char* ptr;
+    char *ptr, *oldptr;
 
     if (!fptr)
         return;
 
+    oldptr = fptr;
     *fptr = 0;
     fptr++;
 
Index: apps/menu.c
===================================================================
--- apps/menu.c.orig
+++ apps/menu.c
@@ -660,6 +660,9 @@ int menu_init(const struct menu_item* mi
 void menu_exit(int m)
 {
     inuse[m] = false;
+#ifdef HAVE_LCD_BITMAP
+    gui_list_context = GUI_LIST_CONTEXT_BRWSR; /* If returning to WPS, gui_wps_refresh() will set the font */
+#endif
 }
 
 
@@ -721,6 +724,11 @@ int menu_show(int m)
                  MENU_ITEM_COUNT(menus[m].count);
     menu.value = m;
     menu.menu_get_name_and_icon = &menu_info;
+    
+#ifdef HAVE_LCD_BITMAP
+    gui_list_context = GUI_LIST_CONTEXT_MENU; /* Set menu font */
+#endif
+    
     value = do_menu(&menu, &menus[m].current_selection);
     switch (value)
     {
Index: apps/screens.c
===================================================================
--- apps/screens.c.orig
+++ apps/screens.c
@@ -617,7 +617,6 @@ bool pitch_screen(void)
 #if CONFIG_CODEC == SWCODEC
     pcmbuf_set_low_latency(false);
 #endif
-    lcd_setfont(FONT_UI);
     action_signalscreenchange();
     return 0;
 }
Index: apps/tree.c
===================================================================
--- apps/tree.c.orig
+++ apps/tree.c
@@ -258,7 +258,11 @@ void browse_root(void)
 
     filetype_init();
     check_rockboxdir();
-
+    
+#ifdef HAVE_LCD_BITMAP
+    gui_list_context = GUI_LIST_CONTEXT_BRWSR;   /* Set browser font */
+#endif
+    
     strcpy(tc.currdir, "/");
 
 #ifdef HAVE_LCD_CHARCELLS
@@ -1014,6 +1018,7 @@ static int dirbrowse()
         }
     }
     action_signalscreenchange();
+    
     return true;
 }
 
@@ -1159,6 +1164,10 @@ int rockbox_browse(const char *root, int
     int *last_filter = tc.dirfilter;
     tc.dirfilter = &dirfilter;
     
+#ifdef HAVE_LCD_BITMAP
+    gui_list_context = GUI_LIST_CONTEXT_BRWSR;   /* Set browser font */
+#endif
+    
     reload_dir = true;
     if (dirfilter >= NUM_FILTER_MODES)
     {
@@ -1186,6 +1195,11 @@ int rockbox_browse(const char *root, int
         ret_val = dirbrowse();
     }
     tc.dirfilter = last_filter;
+    
+#ifdef HAVE_LCD_BITMAP
+    gui_list_context = GUI_LIST_CONTEXT_MENU; /* Set menu font */
+#endif
+    
     return ret_val;
 }
 
Index: apps/screen_access.c
===================================================================
--- apps/screen_access.c.orig
+++ apps/screen_access.c
@@ -48,7 +48,7 @@
             screen->getymargin=&lcd_remote_getymargin;
             screen->getxmargin=&lcd_remote_getxmargin;
             screen->setfont=&lcd_remote_setfont;
-            screen->setfont(FONT_UI);
+			screen->getcurfont=&lcd_remote_getcurfont;
             screen->getstringsize=&lcd_remote_getstringsize;
             screen->putsxy=&lcd_remote_putsxy;
             screen->mono_bitmap=&lcd_remote_mono_bitmap;
@@ -129,7 +129,7 @@ void screen_init(struct screen * screen,
             screen->getleftmargin=&lcd_getleftmargin;
             screen->getrightmargin=&lcd_getrightmargin;
             screen->setfont=&lcd_setfont;
-            screen->setfont(FONT_UI);
+            screen->getcurfont=&lcd_getcurfont;
             screen->getstringsize=&lcd_getstringsize;
             screen->putsxy=&lcd_putsxy;
             screen->mono_bitmap=&lcd_mono_bitmap;
Index: apps/plugins/mp3_encoder.c
===================================================================
--- apps/plugins/mp3_encoder.c.orig
+++ apps/plugins/mp3_encoder.c
@@ -2475,7 +2475,7 @@ enum plugin_status plugin_start(struct p
         rb->sleep(5*HZ);
     }
 
-    rb->lcd_setfont(FONT_UI);
+    rb->lcd_setfont(FONT_PLUGIN);
 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
     rb->cpu_boost(false);
 #endif
Index: apps/plugins/viewer.c
===================================================================
--- apps/plugins/viewer.c.orig
+++ apps/plugins/viewer.c
@@ -290,7 +290,7 @@ int glyph_width(int ch)
         ch = ' ';
 
 #ifdef HAVE_LCD_BITMAP
-    return rb->font_get_width(pf, ch);
+    return rb->font_get_width(pf, ch, FONT_BROWSER);
 #else
     return 1;
 #endif
@@ -987,8 +987,9 @@ static void init_need_scrollbar(void) {
 static bool viewer_init(void)
 {
 #ifdef HAVE_LCD_BITMAP
-
-    pf = rb->font_get(FONT_UI);
+	// MWE
+	rb->lcd_setfont(FONT_BROWSER);
+    pf = rb->font_get(FONT_BROWSER);
 
     display_lines = LCD_HEIGHT / pf->height;
     draw_columns = display_columns = LCD_WIDTH;
Index: apps/plugins/xobox.c
===================================================================
--- apps/plugins/xobox.c.orig
+++ apps/plugins/xobox.c
@@ -724,7 +724,7 @@ static int game_menu (void)
     int button, selection = 0, sw, sh, i;
     bool quit = false;
 
-    rb->lcd_setfont(FONT_UI);
+    rb->lcd_setfont(FONT_PLUGIN);
     rb->lcd_getstringsize("A", &sw, &sh);
     if(sw*20 > LCD_WIDTH || sh*4 > LCD_HEIGHT)
         rb->lcd_setfont(FONT_SYSFIXED);
@@ -884,7 +884,7 @@ enum plugin_status plugin_start (struct 
     }
 
     rb->backlight_set_timeout (rb->global_settings->backlight_timeout);
-    rb->lcd_setfont (FONT_UI);
+    rb->lcd_setfont (FONT_PLUGIN);
 
     return ret;
 }
Index: apps/plugins/jewels.c
===================================================================
--- apps/plugins/jewels.c.orig
+++ apps/plugins/jewels.c
@@ -1615,7 +1615,7 @@ enum plugin_status plugin_start(struct p
                 break;
 
             case BJ_USB:
-                rb->lcd_setfont(FONT_UI);
+                rb->lcd_setfont(FONT_PLUGIN);
                 return PLUGIN_USB_CONNECTED;
 
             case BJ_QUIT:
@@ -1645,7 +1645,7 @@ enum plugin_status plugin_start(struct p
         }
     }
 
-    rb->lcd_setfont(FONT_UI);
+    rb->lcd_setfont(FONT_PLUGIN);
     return PLUGIN_OK;
 }
 
Index: apps/plugins/rockpaint.c
===================================================================
--- apps/plugins/rockpaint.c.orig
+++ apps/plugins/rockpaint.c
@@ -398,10 +398,13 @@ static void buffer_putsxyofs( fb_data *b
 {
     unsigned short ch;
     unsigned short *ucs;
-
-    struct font *pf = rb->font_get( FONT_UI );
-    if( !pf ) pf = rb->font_get( FONT_SYSFIXED );
-
+	int curfont=FONT_PLUGIN;
+	
+    struct font *pf = rb->font_get( FONT_PLUGIN );
+    if( !pf ) {
+    	pf = rb->font_get( FONT_SYSFIXED );
+		curfont=FONT_SYSFIXED;
+    }
     ucs = rb->bidi_l2v( str, 1 );
 
     while( (ch = *ucs++) != 0 && x < buf_width )
@@ -410,7 +413,7 @@ static void buffer_putsxyofs( fb_data *b
         const unsigned char *bits;
 
         /* get proportional width and glyph bits */
-        width = rb->font_get_width( pf, ch );
+        width = rb->font_get_width( pf, ch, curfont );
 
         if( ofs > width )
         {
@@ -418,7 +421,7 @@ static void buffer_putsxyofs( fb_data *b
             continue;
         }
 
-        bits = rb->font_get_bits( pf, ch );
+        bits = rb->font_get_bits( pf, ch, curfont );
 
         buffer_mono_bitmap_part( buf, buf_width, buf_height, bits, ofs, 0, width, x, y, width - ofs, pf->height);
 
@@ -839,7 +842,7 @@ static bool browse_fonts( char *dst, int
 
     rb->snprintf( old_font, MAX_PATH,
                   FONT_DIR "/%s.fnt",
-                  rb->global_settings->font_file );
+                  rb->global_settings->browserfont );
 
     while( 1 )
     {
@@ -893,8 +896,8 @@ static bool browse_fonts( char *dst, int
                     continue;
                 rb->snprintf( bbuf, MAX_PATH, FONT_DIR "/%s",
                               de->d_name );
-                rb->font_load( bbuf );
-                rb->font_getstringsize( de->d_name, &fw, &fh, FONT_UI );
+                rb->font_load( bbuf, FONT_PLUGIN );
+                rb->font_getstringsize( de->d_name, &fw, &fh, FONT_PLUGIN );
                 if( nvih > 0 )
                 {
                     nvih -= fh;
@@ -928,12 +931,12 @@ static bool browse_fonts( char *dst, int
                 {
                     rb->snprintf( bbuf, MAX_PATH, FONT_DIR "/%s",
                           de->d_name );
-                    rb->font_load( bbuf );
-                    rb->font_getstringsize( de->d_name, NULL, &fh, FONT_UI );
+                    rb->font_load( bbuf, FONT_PLUGIN );
+                    rb->font_getstringsize( de->d_name, NULL, &fh, FONT_PLUGIN );
                     nvih = fh;
                 }
             }
-            rb->font_load( old_font );
+            rb->font_load( old_font, FONT_PLUGIN );
             rb->PREFIX(closedir)( d );
         }
 
@@ -1079,7 +1082,7 @@ static unsigned int color_chooser( unsig
         rb->lcd_putsxy( left + 117, top + 60, str );
         rb->snprintf( str, 6, "%d", blue );
         rb->lcd_putsxy( left + 117, top + 70, str );
-        rb->lcd_setfont( FONT_UI );
+        rb->lcd_setfont( FONT_PLUGIN );
 
 #define CURSOR( l ) \
         rb->lcd_bitmap_transparent_part( rockpaint_hsvrgb, 1, 1, 16, left+l+1, top+20, 6, 58 ); \
@@ -1475,7 +1478,7 @@ static void draw_text( int x, int y )
     buffer.text.text[0] = '\0';
     rb->snprintf( buffer.text.old_font, MAX_PATH,
                   FONT_DIR "/%s.fnt",
-                  rb->global_settings->font_file );
+                  rb->global_settings->browserfont );
     while( 1 )
     {
         int m = TEXT_MENU_TEXT;
@@ -1489,7 +1492,7 @@ static void draw_text( int x, int y )
             case TEXT_MENU_FONT:
                 if( browse_fonts( buffer.text.font, MAX_PATH ) )
                 {
-                    rb->font_load( buffer.text.font );
+                    rb->font_load( buffer.text.font, FONT_PLUGIN );
                 }
                 break;
 
@@ -1541,7 +1544,7 @@ static void draw_text( int x, int y )
                                   buffer.text.text );
             case TEXT_MENU_CANCEL:
                 restore_screen();
-                rb->font_load( buffer.text.old_font );
+                rb->font_load( buffer.text.old_font, FONT_PLUGIN );
                 return;
         }
     }
@@ -2301,7 +2304,7 @@ static void draw_toolbars(bool update)
 
     rb->lcd_setfont( FONT_SYSFIXED );
     rb->lcd_putsxy( TB_MENU_LEFT, TOP+TB_MENU_TOP, "Menu" );
-    rb->lcd_setfont( FONT_UI );
+    rb->lcd_setfont( FONT_PLUGIN );
 #undef TOP
 
     if( update ) rb->lcd_update();
Index: apps/plugins/stopwatch.c
===================================================================
--- apps/plugins/stopwatch.c.orig
+++ apps/plugins/stopwatch.c
@@ -166,7 +166,7 @@ enum plugin_status plugin_start(struct p
     rb = api;
 
 #ifdef HAVE_LCD_BITMAP
-    rb->lcd_setfont(FONT_UI);
+    rb->lcd_setfont(FONT_PLUGIN);
 #endif
 
     rb->lcd_clear_display();
Index: apps/plugins/brickmania.c
===================================================================
--- apps/plugins/brickmania.c.orig
+++ apps/plugins/brickmania.c
@@ -2024,7 +2024,7 @@ enum plugin_status plugin_start(struct p
     configfile_save(HIGH_SCORE,config,1,0);
 
     /* Restore user's original backlight setting */
-    rb->lcd_setfont(FONT_UI);
+    rb->lcd_setfont(FONT_PLUGIN);
     rb->backlight_set_timeout(rb->global_settings->backlight_timeout);
 
     return PLUGIN_OK;
Index: apps/plugins/credits.c
===================================================================
--- apps/plugins/credits.c.orig
+++ apps/plugins/credits.c
@@ -150,7 +150,7 @@ void roll_credits(void)
     int numnames = (sizeof(credits)/sizeof(char*));
     char name[40], elapsednames[20];
 
-    rb->lcd_setfont(FONT_UI);
+    rb->lcd_setfont(FONT_PLUGIN);
     rb->lcd_clear_display();
     rb->lcd_update();
 
Index: apps/plugins/bounce.c
===================================================================
--- apps/plugins/bounce.c.orig
+++ apps/plugins/bounce.c
@@ -527,7 +527,7 @@ enum plugin_status plugin_start(struct p
     } while(h > 0);
     
     rb->lcd_set_drawmode(DRMODE_SOLID);
-    rb->lcd_setfont(FONT_UI);
+    rb->lcd_setfont(FONT_PLUGIN);
 
     return (h == 0) ? PLUGIN_OK : PLUGIN_USB_CONNECTED;
 }
Index: apps/plugins/spacerocks.c
===================================================================
--- apps/plugins/spacerocks.c.orig
+++ apps/plugins/spacerocks.c
@@ -1952,7 +1952,7 @@ enum plugin_status plugin_start(struct p
     iohiscore();
     retval = start_game();  
     iohiscore();
-    rb->lcd_setfont(FONT_UI);
+    rb->lcd_setfont(FONT_PLUGIN);
     /* restore normal backlight setting*/
     rb->backlight_set_timeout(rb->global_settings->backlight_timeout);
     
Index: apps/plugins/bubbles.c
===================================================================
--- apps/plugins/bubbles.c.orig
+++ apps/plugins/bubbles.c
@@ -2701,7 +2701,7 @@ enum plugin_status plugin_start(struct p
                 break;
 
             case BB_USB:
-                rb->lcd_setfont(FONT_UI);
+                rb->lcd_setfont(FONT_PLUGIN);
                 return PLUGIN_USB_CONNECTED;
 
             case BB_QUIT:
@@ -2717,7 +2717,7 @@ enum plugin_status plugin_start(struct p
         }
     }
 
-    rb->lcd_setfont(FONT_UI);
+    rb->lcd_setfont(FONT_PLUGIN);
     return PLUGIN_OK;
 }
 
Index: apps/plugins/jpeg.c
===================================================================
--- apps/plugins/jpeg.c.orig
+++ apps/plugins/jpeg.c
@@ -2649,7 +2649,7 @@ int load_and_show(char* filename)
                 rb->lcd_puts(0,3,"Left/Right: Skip File.");
             rb->lcd_puts(0,4,"Off: Quit.");
             rb->lcd_update();
-            rb->lcd_setfont(FONT_UI);
+            rb->lcd_setfont(FONT_PLUGIN);
 
             rb->button_clear_queue();
 
Index: apps/recorder/recording.c
===================================================================
--- apps/recorder/recording.c.orig
+++ apps/recorder/recording.c
@@ -853,7 +853,7 @@ bool recording_screen(bool no_source)
 
     FOR_NB_SCREENS(i)
     {
-        screens[i].setfont(FONT_SYSFIXED);
+        screens[i].setfont(FONT_RECORD);
         screens[i].getstringsize("M", &w, &h);
         screens[i].setmargins(global_settings.invert_cursor ? 0 : w, screens[i].width, 8);
         filename_offset[i] = ((screens[i].height >= 80) ? 1 : 0);
@@ -1249,7 +1249,7 @@ bool recording_screen(bool no_source)
 
                         FOR_NB_SCREENS(i)
                         {
-                            screens[i].setfont(FONT_SYSFIXED);
+                            screens[i].setfont(FONT_RECORD);
                             screens[i].setmargins(
                                 global_settings.invert_cursor ? 0 : w, screens[i].width, 8);
                         }
@@ -1332,7 +1332,7 @@ bool recording_screen(bool no_source)
 #endif
 
             FOR_NB_SCREENS(i)       
-                screens[i].setfont(FONT_SYSFIXED);
+                screens[i].setfont(FONT_RECORD);
 
         seconds = audio_recorded_time() / HZ;
         
@@ -1784,9 +1784,6 @@ bool recording_screen(bool no_source)
     in_screen = false;
     sound_settings_apply();
 
-    FOR_NB_SCREENS(i)
-        screens[i].setfont(FONT_UI);
-
     if (have_recorded)
         reload_directory();
 
@@ -1818,7 +1815,7 @@ static bool f2_rec_screen(void)
 
     FOR_NB_SCREENS(i)
     {
-        screens[i].setfont(FONT_SYSFIXED);
+        screens[i].setfont(FONT_RECORD);
         screens[i].getstringsize("A",&w,&h);
     }
 
@@ -1931,8 +1928,6 @@ static bool f2_rec_screen(void)
     set_gain();
     
     settings_save();
-    FOR_NB_SCREENS(i)
-        screens[i].setfont(FONT_UI);
 
     return false;
 }
@@ -1953,7 +1948,7 @@ static bool f3_rec_screen(void)
 
     FOR_NB_SCREENS(i)
     {
-        screens[i].setfont(FONT_SYSFIXED);
+        screens[i].setfont(FONT_RECORD);
         screens[i].getstringsize("A",&w,&h);
     }
     
@@ -2028,8 +2023,6 @@ static bool f3_rec_screen(void)
     set_gain();
 
     settings_save();
-    FOR_NB_SCREENS(i)
-        screens[i].setfont(FONT_UI);
 
     return false;
 }
Index: apps/recorder/keyboard.c
===================================================================
--- apps/recorder/keyboard.c.orig
+++ apps/recorder/keyboard.c
@@ -350,7 +350,7 @@ int kbd_input(char* text, int buflen)
         }
         else
         {
-            pm->curfont = FONT_UI;
+            pm->curfont = FONT_MENU;
         }
     }
 
@@ -375,14 +375,14 @@ int kbd_input(char* text, int buflen)
         /* find max width of keyboard glyphs */
         for (i = 0; i < pm->nchars; i++)
         {
-            w = font_get_width(pm->font, pm->kbd_buf[i]);
+            w = font_get_width(pm->font, pm->kbd_buf[i], param[l].curfont);
             if (w > pm->font_w)
                 pm->font_w = w;
         }
 
         /* Since we're going to be adding spaces, make sure that we check
          * their width too */
-        w = font_get_width( pm->font, ' ' );
+        w = font_get_width( pm->font, ' ', param[l].curfont );
         if ( w > pm->font_w )
             pm->font_w = w;
     }
@@ -450,7 +450,7 @@ int kbd_input(char* text, int buflen)
 
         while (*utf8)
         {
-            int w = font_get_width(pm->font, ch);
+            int w = font_get_width(pm->font, ch, param[l].curfont);
             utf8 = (unsigned char*)utf8decode(utf8, &ch);
 
             if (w > text_w)
@@ -745,8 +745,6 @@ int kbd_input(char* text, int buflen)
         switch ( button )
         {
             case ACTION_KBD_ABORT:
-                FOR_NB_SCREENS(l)
-                    screens[l].setfont(FONT_UI);
 
 #ifdef HAS_BUTTONBAR
                 global_settings.buttonbar=buttonbar_config;
Index: apps/recorder/radio.c
===================================================================
--- apps/recorder/radio.c.orig
+++ apps/recorder/radio.c
@@ -440,13 +440,14 @@ int radio_screen(void)
     global_settings.statusbar = true;
     FOR_NB_SCREENS(i)
     {
+        screens[i].setfont(FONT_TUNER);
         gui_textarea_clear(&screens[i]);
         screen_set_xmargin(&screens[i],0);
     }
     
     gui_syncstatusbar_draw(&statusbars,true);
 
-    fh = font_get(FONT_UI)->height;
+    fh = font_get(FONT_TUNER)->height;
     
     /* Adjust for font size, trying to center the information vertically */
     if(fh < 10)
@@ -548,8 +549,7 @@ int radio_screen(void)
         {
              case ACTION_FM_STOP:
 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
-                if(audio_status() == AUDIO_STATUS_RECORD)
-                {
+                if(audio_status() == AUDIO_STATUS_RECORD)                {
                     audio_stop();
                 }
                 else
@@ -853,7 +853,7 @@ int radio_screen(void)
                 int freq;
 
                 FOR_NB_SCREENS(i)
-                    screens[i].setfont(FONT_UI);
+                    screens[i].setfont(FONT_TUNER);
                 
                 snprintf(buf, 128, curr_preset >= 0 ? "%d. %s" : " ",
                          curr_preset + 1, presets[curr_preset].name);
Index: firmware/lru.c
===================================================================
--- firmware/lru.c.orig
+++ firmware/lru.c
@@ -57,7 +57,7 @@ void lru_create(struct lru* pl, void *bu
 /*******************************************************************************
  * lru_traverse
  ******************************************************************************/
-void lru_traverse(struct lru* pl, void (*callback)(void* data))
+void lru_traverse(struct lru* pl, void (*callback)(void* data, int font), int font)
 {
     short i;
     struct lru_node* slot;
@@ -66,7 +66,7 @@ void lru_traverse(struct lru* pl, void (
     for (i = 0; i < pl->_size; i++)
     {
         slot = lru_node_p(pl, loc);
-        callback(slot->data);
+        callback(slot->data, font);
         loc = slot->_next;
     }
 }
Index: firmware/font.c
===================================================================
--- firmware/font.c.orig
+++ firmware/font.c
@@ -19,8 +19,8 @@
 /*
  * Rockbox startup font initialization
  * This file specifies which fonts get compiled-in and
- * loaded at startup, as well as their mapping into
- * the FONT_SYSFIXED, FONT_UI and FONT_MP3 ids.
+ * loaded at runtime, as well as their mapping into
+ * the various FONT_* ids
  */
 #include "config.h"
 
@@ -45,70 +45,105 @@
 /* compiled-in font */
 extern struct font sysfont;
 
-/* structure filled in by font_load */
-static struct font font_ui;
+/* font structures filled in by font_load */
+static struct font browserfont;
+static struct font wpsfont;
+static struct font menufont;
+#ifdef CONFIG_TUNER
+static struct font tunerfont;
+#endif
+#ifdef HAVE_RECORDING
+static struct font recordfont;
+#endif
 
 /* system font table, in order of FONT_xxx definition */
-static struct font* const sysfonts[MAXFONTS] = { &sysfont, &font_ui };
+static struct font* sysfonts[MAXFONTS] = {
+    &sysfont,
+    &browserfont,
+    &wpsfont,
+    &menufont,
+#ifdef CONFIG_TUNER
+    &tunerfont,
+#endif
+#ifdef HAVE_RECORDING
+    &recordfont
+#endif
+ };
 
 /* static buffer allocation structures */
-static unsigned char mbuf[MAX_FONT_SIZE];
-static unsigned char *freeptr = mbuf;
-static unsigned char *fileptr;
-static unsigned char *eofptr;
+static unsigned char font_membuf[MAXCACHEFONTS][MAX_FONT_SIZE]; /* Sysfont is compiled-in, no need for buffer */
 
 /* Font cache structures */
-static struct font_cache font_cache_ui;
-static int fnt_file = -1;           /* >=0 if font is cached   */
-unsigned long file_width_offset;    /* offset to file width data    */
-unsigned long file_offset_offset;   /* offset to file offset data   */
-static void cache_create(int maxwidth, int height);
-static int long_offset = 0;
-static int glyph_file;
+static struct font_cache sys_font_cache[MAXCACHEFONTS];
+static struct font_file_info fntfile[MAXCACHEFONTS];
+static void cache_create(int maxwidth, int height, int font);
+static void font_cache_init(void);
 /* End Font cache structures */
 
+/* Zero out all font structures */
 void font_init(void)
 {
-    memset(&font_ui, 0, sizeof(struct font));
+    int i = FONT_BROWSER; /* Skip sysfont */
+    
+    while (i < MAXFONTS)
+    {
+        memset(sysfonts[i], 0, sizeof(struct font));
+        i++;
+    }
+    
+    font_cache_init();
+}
+
+void font_cache_init(void)
+{
+    int i = 0;
+
+    while (i < MAXCACHEFONTS)
+    {
+        fntfile[i].font_fd = -1;
+        i++;
+    }
+    return;
 }
 
-static int readshort(unsigned short *sp)
+static int readshort(unsigned short *sp, int font)
 {
     unsigned short s;
 
-    s = *fileptr++ & 0xff;
-    *sp = (*fileptr++ << 8) | s;
-    return (fileptr <= eofptr);
+    s = *fntfile[font].fileptr++ & 0xff;
+    *sp = (*fntfile[font].fileptr++ << 8) | s;
+    return (fntfile[font].fileptr <= fntfile[font].eofptr);
 }
 
-static long readlong(unsigned long *lp)
+static long readlong(unsigned long *lp, int font)
 {
     unsigned long l;
 
-    l = *fileptr++ & 0xff;
-    l |= *fileptr++ << 8;
-    l |= ((unsigned long)(*fileptr++)) << 16;
-    l |= ((unsigned long)(*fileptr++)) << 24;
+    l = *fntfile[font].fileptr++ & 0xff;
+    l |= *fntfile[font].fileptr++ << 8;
+    l |= ((unsigned long)(*fntfile[font].fileptr++)) << 16;
+    l |= ((unsigned long)(*fntfile[font].fileptr++)) << 24;
     *lp = l;
-    return (fileptr <= eofptr);
+    return (fntfile[font].fileptr <= fntfile[font].eofptr);
 }
 
 /* read count bytes*/
-static int readstr(char *buf, int count)
+static int readstr(char *buf, int count, int font)
 {
     int n = count;
 
     while (--n >= 0)
-        *buf++ = *fileptr++;
-    return (fileptr <= eofptr)? count: 0;
+        *buf++ = *fntfile[font].fileptr++;
+
+    return (fntfile[font].fileptr <= fntfile[font].eofptr)? count: 0;
 }
 
-void font_reset(void)
+void font_reset(int font)
 {
-    memset(&font_ui, 0, sizeof(struct font));
+    memset(sysfonts[font], 0, sizeof(struct font));
 }
 
-static struct font*  font_load_header(struct font *pf)
+static struct font*  font_load_header(struct font *pf, int font)
 {
     char version[4+1];
     unsigned short maxwidth, height, ascent, pad;
@@ -117,91 +152,98 @@ static struct font*  font_load_header(st
 
     /* read magic and version #*/
     memset(version, 0, sizeof(version));
-    if (readstr(version, 4) != 4)
+    if (readstr(version, 4, font) != 4)
         return NULL;
+
     if (strcmp(version, VERSION) != 0)
         return NULL;
 
     /* font info*/
-    if (!readshort(&maxwidth))
+    if (!readshort(&maxwidth, font))
         return NULL;
     pf->maxwidth = maxwidth;
-    if (!readshort(&height))
+    
+    if (!readshort(&height, font))
         return NULL;
     pf->height = height;
-    if (!readshort(&ascent))
+    
+    if (!readshort(&ascent, font))
         return NULL;
     pf->ascent = ascent;
-    if (!readshort(&pad))
+    
+    if (!readshort(&pad, font))
         return NULL;
-    if (!readlong(&firstchar))
+
+    if (!readlong(&firstchar, font))
         return NULL;
     pf->firstchar = firstchar;
-    if (!readlong(&defaultchar))
+    
+    if (!readlong(&defaultchar, font))
         return NULL;
     pf->defaultchar = defaultchar;
-    if (!readlong(&size))
+    
+    if (!readlong(&size, font))
         return NULL;
     pf->size = size;
 
     /* get variable font data sizes*/
     /* # words of bitmap_t*/
-    if (!readlong(&nbits))
+    if (!readlong(&nbits, font))
         return NULL;
     pf->bits_size = nbits;
 
     return pf;
 }
 /* Load memory font */
-struct font* font_load_in_memory(struct font* pf)
+struct font* font_load_in_memory(struct font* pf, int font)
 {
     long i, noffset, nwidth;
 
     /* # longs of offset*/
-    if (!readlong(&noffset))
+    if (!readlong(&noffset, font))
         return NULL;
 
     /* # bytes of width*/
-    if (!readlong(&nwidth))
+    if (!readlong(&nwidth, font))
         return NULL;
 
     /* variable font data*/
-    pf->bits = (unsigned char *)fileptr;
-    fileptr += pf->bits_size*sizeof(unsigned char);
+    pf->bits = (unsigned char *)fntfile[font].fileptr;
+    fntfile[font].fileptr += pf->bits_size*sizeof(unsigned char);
 
     if ( pf->bits_size < 0xFFDB )
     {
         /* pad to 16-bit boundary */
-        fileptr = (unsigned char *)(((long)fileptr + 1) & ~1);
+        fntfile[font].fileptr = (unsigned char *)(((long)fntfile[font].fileptr + 1) & ~1);
     }
     else
     {
         /* pad to 32-bit boundary*/
-        fileptr = (unsigned char *)(((long)fileptr + 3) & ~3);
+        fntfile[font].fileptr = (unsigned char *)(((long)fntfile[font].fileptr + 3) & ~3);
     }
 
     if (noffset)
     {
         if ( pf->bits_size < 0xFFDB )
         {
-            long_offset = 0;
-            pf->offset = (unsigned short *)fileptr;
+            fntfile[font].long_offset = 0;
+            pf->offset = (unsigned short *)fntfile[font].fileptr;
             for (i=0; i<noffset; ++i)
             {
                 unsigned short offset;
-                if (!readshort(&offset))
+                if (!readshort(&offset, font))
                     return NULL;
                 ((unsigned short*)(pf->offset))[i] = (unsigned short)offset;
             }
         }
         else
         {
-            long_offset = 1;
-            pf->offset = (unsigned short *)fileptr;
+            fntfile[font].long_offset = 1;
+            pf->offset = (unsigned short *)fntfile[font].fileptr;
             for (i=0; i<noffset; ++i)
             {
                 unsigned long offset;
-                if (!readlong(&offset))
+                if (!readlong(&offset, font))
                     return NULL;
                 ((unsigned long*)(pf->offset))[i] = (unsigned long)offset;
             }
@@ -211,139 +253,140 @@ struct font* font_load_in_memory(struct 
         pf->offset = NULL;
 
     if (nwidth) {
-        pf->width = (unsigned char *)fileptr;
-        fileptr += nwidth*sizeof(unsigned char);
+        pf->width = (unsigned char *)fntfile[font].fileptr;
+        fntfile[font].fileptr += nwidth*sizeof(unsigned char);
     }
     else
         pf->width = NULL;
 
-    if (fileptr > eofptr)
+    if (fntfile[font].fileptr > fntfile[font].eofptr)
         return NULL;
 
     return pf;    /* success!*/
 }
 
 /* Load cached font */
-struct font* font_load_cached(struct font* pf)
+struct font* font_load_cached(struct font* pf, int font)
 {
     unsigned long noffset, nwidth;
-    unsigned char* oldfileptr = fileptr;
+    unsigned char* oldfileptr = fntfile[font].fileptr;
 
     /* # longs of offset*/
-    if (!readlong(&noffset))
+    if (!readlong(&noffset, font))
         return NULL;
 
     /* # bytes of width*/
-    if (!readlong(&nwidth))
+    if (!readlong(&nwidth, font))
         return NULL;
 
     /* We are now at the bitmap data, this is fixed at 36.. */
     pf->bits = NULL;
 
     /* Calculate offset to offset data */
-    fileptr += pf->bits_size * sizeof(unsigned char);
+    fntfile[font].fileptr += pf->bits_size * sizeof(unsigned char);
 
     if ( pf->bits_size < 0xFFDB )
     {
-        long_offset = 0;
+        fntfile[font].long_offset = 0;
         /* pad to 16-bit boundary */
-        fileptr = (unsigned char *)(((long)fileptr + 1) & ~1);
+        fntfile[font].fileptr = (unsigned char *)(((long)fntfile[font].fileptr + 1) & ~1);
     }
     else
     {
-        long_offset = 1;
+        fntfile[font].long_offset = 1;
         /* pad to 32-bit boundary*/
-        fileptr = (unsigned char *)(((long)fileptr + 3) & ~3);
+        fntfile[font].fileptr = (unsigned char *)(((long)fntfile[font].fileptr + 3) & ~3);
     }
 
     if (noffset)
-        file_offset_offset = (unsigned long)(fileptr - freeptr);
+        fntfile[font].file_offset_offset = (unsigned long)(fntfile[font].fileptr - fntfile[font].freeptr);
     else
-        file_offset_offset = 0;
+        fntfile[font].file_offset_offset = 0;
 
     /* Calculate offset to widths data */
     if ( pf->bits_size < 0xFFDB )
-        fileptr += noffset * sizeof(unsigned short);
+        fntfile[font].fileptr += noffset * sizeof(unsigned short);
     else
-        fileptr += noffset * sizeof(unsigned long);
+        fntfile[font].fileptr += noffset * sizeof(unsigned long);
 
     if (nwidth)
-        file_width_offset = (unsigned long)(fileptr - freeptr);
+        fntfile[font].file_width_offset = (unsigned long)(fntfile[font].fileptr - fntfile[font].freeptr);
     else
-        file_width_offset = 0;
+        fntfile[font].file_width_offset = 0;
 
-    fileptr = oldfileptr;
+    fntfile[font].fileptr = oldfileptr;
 
     /* Create the cache */
-    cache_create(pf->maxwidth, pf->height);
+    cache_create(pf->maxwidth, pf->height, font);
 
     return pf;
 }
 
 /* read and load font into incore font structure*/
-struct font* font_load(const char *path)
+struct font* font_load(const char *path, int _font)
 {
     int size;
-    struct font* pf = &font_ui;
+    int font = _font - 1; /*  cache index vs global font index */
+    struct font* pf = sysfonts[_font];
 
     /* save loaded glyphs */
-    glyph_cache_save();
+    glyph_cache_save(font);
 
     /* Close font file handle */
-    if (fnt_file >= 0)
-        close(fnt_file);
+    if (fntfile[font].font_fd >= 0)
+        close(fntfile[font].font_fd);
 
     /* open and read entire font file*/
-    fnt_file = open(path, O_RDONLY|O_BINARY);
+    fntfile[font].font_fd = open(path, O_RDONLY|O_BINARY);
 
-    if (fnt_file < 0) {
+    if (fntfile[font].font_fd < 0) {
         DEBUGF("Can't open font: %s\n", path);
         return NULL;
     }
 
     /* Check file size */
-    size = filesize(fnt_file);
+    size = filesize(fntfile[font].font_fd);
 
-    font_reset();
+    font_reset(_font);
 
     /* currently, font loading replaces earlier font allocation*/
-    freeptr = (unsigned char *)(((int)mbuf + 3) & ~3);
-    fileptr = freeptr;
+    fntfile[font].freeptr = (unsigned char *)(((int)font_membuf[font] + 3) & ~3);
+    fntfile[font].fileptr = fntfile[font].freeptr;
 
 
     if (size > MAX_FONT_SIZE)
     {
-        read(fnt_file, fileptr, FONT_HEADER_SIZE);
-        eofptr = fileptr + FONT_HEADER_SIZE;
+        read(fntfile[font].font_fd, fntfile[font].fileptr, FONT_HEADER_SIZE);
+        fntfile[font].eofptr = fntfile[font].fileptr + FONT_HEADER_SIZE;
 
-        if (!font_load_header(pf))
+        if (!font_load_header(pf, font))
         {
             DEBUGF("Failed font header load");
             return NULL;
         }
 
-        if (!font_load_cached(pf))
+        if (!font_load_cached(pf, font))
         {
             DEBUGF("Failed font cache load");
             return NULL;
         }
 
-        glyph_cache_load();
+        glyph_cache_load(font);
     }
     else
     {
-        read(fnt_file, fileptr, MAX_FONT_SIZE);
-        eofptr = fileptr + size;
-        close(fnt_file);
-        fnt_file = -1;
+        read(fntfile[font].font_fd, fntfile[font].fileptr, MAX_FONT_SIZE);
+        fntfile[font].eofptr = fntfile[font].fileptr + size;
+        close(fntfile[font].font_fd);
+        fntfile[font].font_fd = -1;
 
-        if (!font_load_header(pf))
+        if (!font_load_header(pf, font))
         {
             DEBUGF("Failed font header load");
             return NULL;
         }
 
-        if (!font_load_in_memory(pf))
+        if (!font_load_in_memory(pf, font))
         {
             DEBUGF("Failed mem load");
             return NULL;
@@ -360,13 +403,25 @@ struct font* font_load(const char *path)
 /*
  * Return a pointer to an incore font structure.
  * If the requested font isn't loaded/compiled-in,
- * decrement the font number and try again.
+ * (decrement the font number and try again)
+ * MWE return sysfont instead
+ * 
  */
-struct font* font_get(int font)
+struct font *font_get(int font)
 {
-    struct font* pf;
+    struct font *pf;
+
+	if (font >= MAXFONTS){
+		return &sysfont;
+	}
+
+	pf = sysfonts[font];
+	if (pf && pf->height)
+		return pf;
+		
+	return &sysfont;
 
-    if (font >= MAXFONTS)
+/*    if (font >= MAXFONTS)
         font = 0;
 
     while (1) {
@@ -375,14 +430,14 @@ struct font* font_get(int font)
             return pf;
         if (--font < 0)
             panicf("No font!");
-    }
+    }*/
 }
 /*
  * Returns the stringsize of a given string. 
  */
-int font_getstringsize(const unsigned char *str, int *w, int *h, int fontnumber)
+int font_getstringsize(const unsigned char *str, int *w, int *h, int font)
 {
-    struct font* pf = font_get(fontnumber);
+    struct font* pf = font_get(font);
     unsigned short ch;
     int width = 0;
 
@@ -390,7 +445,7 @@ int font_getstringsize(const unsigned ch
     {
 
         /* get proportional width and glyph bits*/
-        width += font_get_width(pf,ch);
+        width += font_get_width(pf, ch, font);
     }
     if ( w )
         *w = width;
@@ -403,17 +458,17 @@ int font_getstringsize(const unsigned ch
  * Reads an entry into cache entry
  */
 static void
-load_cache_entry(struct font_cache_entry* p, void* callback_data)
+load_cache_entry(struct font_cache_entry* p, void* callback_data, int font)
 {
     struct font* pf = callback_data;
     unsigned short char_code = p->_char_code;
     unsigned char tmp[2];
  
-    if (file_width_offset)
+    if (fntfile[font].file_width_offset)
     {
-        int width_offset = file_width_offset + char_code;
-        lseek(fnt_file, width_offset, SEEK_SET);
-        read(fnt_file, &(p->width), 1);
+        int width_offset = fntfile[font].file_width_offset + char_code;
+        lseek(fntfile[font].font_fd, width_offset, SEEK_SET);
+        read(fntfile[font].font_fd, &(p->width), 1);
     }
     else
     {
@@ -422,14 +477,14 @@ load_cache_entry(struct font_cache_entry
  
     long bitmap_offset = 0;
 
-    if (file_offset_offset)
+    if (fntfile[font].file_offset_offset)
     {
-        long offset = file_offset_offset + char_code * (long_offset ? sizeof(long) : sizeof(short));
-        lseek(fnt_file, offset, SEEK_SET);
-        read (fnt_file, tmp, 2);
+        long offset = fntfile[font].file_offset_offset + char_code * (fntfile[font].long_offset ? sizeof(long) : sizeof(short));
+        lseek(fntfile[font].font_fd, offset, SEEK_SET);
+        read (fntfile[font].font_fd, tmp, 2);
         bitmap_offset = tmp[0] | (tmp[1] << 8);
-        if (long_offset) {
-            read (fnt_file, tmp, 2);
+        if (fntfile[font].long_offset) {
+            read (fntfile[font].font_fd, tmp, 2);
             bitmap_offset |= (tmp[0] << 16) | (tmp[1] << 24);
         }
     }
@@ -439,125 +494,171 @@ load_cache_entry(struct font_cache_entry
     }
 
     long file_offset = FONT_HEADER_SIZE + bitmap_offset;
-    lseek(fnt_file, file_offset, SEEK_SET);
+    lseek(fntfile[font].font_fd, file_offset, SEEK_SET);
 
     int src_bytes = p->width * ((pf->height + 7) / 8);
-    read(fnt_file, p->bitmap, src_bytes);
+    read(fntfile[font].font_fd, p->bitmap, src_bytes);
 }
 
 /*
  * Converts cbuf into a font cache
  */
-static void cache_create(int maxwidth, int height)
+static void cache_create(int maxwidth, int height, int font)
 {
     /* maximum size of rotated bitmap */
     int bitmap_size = maxwidth * ((height + 7) / 8);
     
     /* Initialise cache */
-    font_cache_create(&font_cache_ui, mbuf, MAX_FONT_SIZE, bitmap_size);
+    font_cache_create(&sys_font_cache[font], &font_membuf[font], MAX_FONT_SIZE, bitmap_size);
 }
 
 /*
  * Returns width of character
  */
-int font_get_width(struct font* pf, unsigned short char_code)
+int font_get_width(struct font* pf, unsigned short char_code, int font)
 {
     /* check input range*/
     if (char_code < pf->firstchar || char_code >= pf->firstchar+pf->size)
         char_code = pf->defaultchar;
     char_code -= pf->firstchar;
-
-    return (fnt_file >= 0 && pf != &sysfont)?
-        font_cache_get(&font_cache_ui,char_code,load_cache_entry,pf)->width:
-        pf->width? pf->width[char_code]: pf->maxwidth;
+    
+    if (pf == &sysfont || fntfile[font-1].font_fd < 0) /* sysfont or loaded into mem */
+    {
+	if (pf->width)
+	    return pf->width[char_code];
+	else
+	    return pf->maxwidth;
+    }
+    else /* cached */
+	return font_cache_get(&sys_font_cache[font-1], char_code, load_cache_entry, pf, font-1)->width;
 }
  
-const unsigned char* font_get_bits(struct font* pf, unsigned short char_code)
+const unsigned char* font_get_bits(struct font* pf, unsigned short char_code, int font)
 {
     const unsigned char* bits;
 
     /* check input range*/
     if (char_code < pf->firstchar || char_code >= pf->firstchar+pf->size)
         char_code = pf->defaultchar;
-    char_code -= pf->firstchar;
-
-    if (fnt_file >= 0 && pf != &sysfont)
-    {
-        bits =
-            (unsigned char*)font_cache_get(&font_cache_ui,char_code,load_cache_entry,pf)->bitmap;
+        char_code -= pf->firstchar;
+    
+        if (font <= 0 || fntfile[font-1].font_fd < 0) /* sysfont */
+	        bits = pf->bits + (pf->offset?pf->offset[char_code]:(((pf->height + 7) / 8) * pf->maxwidth * char_code));
+        else
+	        bits = (unsigned char*)font_cache_get(&sys_font_cache[font-1], char_code, load_cache_entry, pf, font-1)->bitmap;
+            
+        return bits;
     }
-    else
+    
+void glyph_file_write(void* data, int font)
     {
-        bits = pf->bits + (pf->offset?
-            pf->offset[char_code]:
-            (((pf->height + 7) / 8) * pf->maxwidth * char_code));
-    }
-        
-    return bits;
-}
-
-void glyph_file_write(void* data)
-{
-    struct font_cache_entry* p = data;
-    struct font* pf = &font_ui;
-    unsigned short ch;
-    unsigned char tmp[2];
-
-    ch = p->_char_code + pf->firstchar;
-
-    if (ch != 0xffff && glyph_file >= 0) {
-        tmp[0] = ch >> 8;
-        tmp[1] = ch & 0xff;
-        if (write(glyph_file, tmp, 2) != 2) {
-            close(glyph_file);
-            glyph_file = -1;
+        struct font_cache_entry* p = data;
+        struct font* pf = sysfonts[font];
+        unsigned short ch;
+        unsigned char tmp[2];
+    
+        ch = p->_char_code + pf->firstchar;
+    
+        if (p->_char_code != 0xffff && fntfile[font].glyph_fd >= 0) {
+	       tmp[0] = p->_char_code >> 8;
+	       tmp[1] = p->_char_code & 0xff;
+	
+	        if (write(fntfile[font].glyph_fd, tmp, 2) != 2) {
+	            close(fntfile[font].glyph_fd);
+	            fntfile[font].glyph_fd = -1;
+            }
         }
+        return;
     }
-    return;
-}
-
-/* save the char codes of the loaded glyphs to a file */
-void glyph_cache_save(void)
-{
-
-    if (fnt_file >= 0) {
-
-        glyph_file = creat(GLYPH_CACHE_FILE);
-
-        if (glyph_file < 0) return;
-
-        lru_traverse(&font_cache_ui._lru, glyph_file_write);
-
-        if (glyph_file >= 0)
-            close(glyph_file);
+    
+    /* save the char codes of the loaded glyphs to a file */
+void glyph_cache_save(int font)
+    {
+    
+    if (fntfile[font].font_fd >= 0) {
+    
+		switch (font)
+		{
+		    case 0:
+			fntfile[font].glyph_fd = creat(GLYPH_CACHE_FILE_BRWSR);
+			break;
+		    case 1:
+			fntfile[font].glyph_fd = creat(GLYPH_CACHE_FILE_WPS);
+			break;
+		    case 2:
+			fntfile[font].glyph_fd = creat(GLYPH_CACHE_FILE_MENU);
+			break;
+#ifdef CONFIG_TUNER
+		    case 3:
+			fntfile[font].glyph_fd = creat(GLYPH_CACHE_FILE_TUNER);
+			break;
+#endif
+#ifdef HAVE_RECORDING
+		    case 4:
+			fntfile[font].glyph_fd = creat(GLYPH_CACHE_FILE_RECORD);
+			break;
+#endif
+		    default:
+			return;
+		}
+	
+	    if (fntfile[font].glyph_fd < 0) return;
+	
+	    lru_traverse(&sys_font_cache[font]._lru, glyph_file_write, font);
+	
+	    if (fntfile[font].glyph_fd >= 0)
+	        close(fntfile[font].glyph_fd);
+        }
+        return;
     }
-    return;
-}
-
-void glyph_cache_load(void)
-{
-    if (fnt_file >= 0) {
-
+    
+void glyph_cache_load(int font)
+    {
+    if (fntfile[font].font_fd >= 0) {
+    
         int fd;
         unsigned char tmp[2];
         unsigned short ch;
-        struct font* pf = &font_ui;
-
-        fd = open(GLYPH_CACHE_FILE, O_RDONLY|O_BINARY);
-
+        struct font* pf = sysfonts[font];
+    
+		switch (font)
+		{
+		    case 0:
+			fd = open(GLYPH_CACHE_FILE_BRWSR, O_RDONLY|O_BINARY);
+			break;
+		    case 1:
+			fd = open(GLYPH_CACHE_FILE_WPS, O_RDONLY|O_BINARY);
+			break;
+		    case 2:
+			fd = open(GLYPH_CACHE_FILE_MENU, O_RDONLY|O_BINARY);
+			break;
+	#ifdef CONFIG_TUNER
+		    case 3:
+			fd = open(GLYPH_CACHE_FILE_TUNER, O_RDONLY|O_BINARY);
+			break;
+	#endif
+	#ifdef HAVE_RECORDING
+		    case 4:
+			fd = open(GLYPH_CACHE_FILE_RECORD, O_RDONLY|O_BINARY);
+			break;
+	#endif
+		    default:
+			return;
+		}
+	
         if (fd >= 0) {
 
             while (read(fd, tmp, 2) == 2) {
                 ch = (tmp[0] << 8) | tmp[1];
-                font_get_bits(pf, ch);
+                font_get_bits(pf, ch, font);
             }
-
+    
             close(fd);
         } else {
             /* load latin1 chars into cache */
             ch = 256;
             while (ch-- > 32)
-                font_get_bits(pf, ch);
+                font_get_bits(pf, ch, font);
         }
     }
     return;
Index: firmware/font_cache.c
===================================================================
--- firmware/font_cache.c.orig
+++ firmware/font_cache.c
@@ -23,8 +23,9 @@
 /*******************************************************************************
  * font_cache_lru_init
  ******************************************************************************/
-void font_cache_lru_init(void* data)
+void font_cache_lru_init(void* data, int font)
 {
+    font = 0; /* Kill gcc warning */
     struct font_cache_entry* p = data;
     p->_char_code = 0xffff;   /* assume invalid char */
 }
@@ -60,7 +61,7 @@ void font_cache_create(
     lru_create(&fcache->_lru, lru_buf, cache_size, font_cache_entry_size);
 
     /* initialise cache */
-    lru_traverse(&fcache->_lru, font_cache_lru_init);
+    lru_traverse(&fcache->_lru, font_cache_lru_init, NULL);  /* font parameter not needed for callback */
     short i;
     for (i = 0; i < cache_size; i++)
         fcache->_index[i] = i; /* small cheat here */
@@ -158,8 +159,8 @@ int font_cache_insertion_point(
 struct font_cache_entry* font_cache_get(
     struct font_cache* fcache,
     unsigned short char_code,
-    void (*callback) (struct font_cache_entry* p, void *callback_data),
-    void *callback_data)
+    void (*callback) (struct font_cache_entry* p, void *callback_data, int font),
+    void *callback_data, int font)
 {
     int insertion_point = font_cache_insertion_point(fcache, char_code);
     if (insertion_point >= 0)
@@ -207,7 +208,7 @@ struct font_cache_entry* font_cache_get(
         fcache->_size++;
 
     p->_char_code = char_code;
-    callback(p, callback_data);
+    callback(p, callback_data, font);
 
     return p;
 }
Index: firmware/export/font.h
===================================================================
--- firmware/export/font.h.orig
+++ firmware/export/font.h
@@ -44,7 +44,16 @@
 #define FONT_HEADER_SIZE 36
 #endif
 
-#define GLYPH_CACHE_FILE "/.rockbox/.glyphcache"
+
+#define GLYPH_CACHE_FILE_BRWSR "/.rockbox/.glyphcache-brwsr"
+#define GLYPH_CACHE_FILE_WPS "/.rockbox/.glyphcache-wps"
+#define GLYPH_CACHE_FILE_MENU "/.rockbox/.glyphcache-menu"
+#ifdef CONFIG_TUNER
+#define GLYPH_CACHE_FILE_TUNER "/.rockbox/.glyphcache-tuner"
+#endif
+#ifdef HAVE_RECORDING
+#define GLYPH_CACHE_FILE_RECORD "/.rockbox/.glyphcache-record"
+#endif
 
 /*
  * Fonts are specified by number, and used for display
@@ -58,10 +67,22 @@
  */
 enum {
     FONT_SYSFIXED, /* system fixed pitch font*/
-    FONT_UI,       /* system porportional font*/
+    FONT_BROWSER,  /* Browser font */
+    FONT_WPS,      /* WPS font */
+    FONT_MENU,     /* Settings/menu font */
+#ifdef CONFIG_TUNER
+    FONT_TUNER,    /* FM/radio font */
+#endif
+#ifdef HAVE_RECORDING
+    FONT_RECORD,   /* Recording font */
+#endif
     MAXFONTS
 };
 
+/* FIXME: Hack to keep things compiling for now */
+#define FONT_PLUGIN FONT_SYSFIXED
+#define FONT_UI FONT_SYSFIXED
+
 /*
  * .fnt loadable font file format definition
  *
@@ -104,14 +125,14 @@ struct font {
 
 /* font routines*/
 void font_init(void);
-struct font* font_load(const char *path);
+struct font* font_load(const char *path, int font);
 struct font* font_get(int font);
-void font_reset(void);
-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(void);
-void glyph_cache_load(void);
+void font_reset(int font);
+int font_getstringsize(const unsigned char *str, int *w, int *h, int font);
+int font_get_width(struct font* ft, unsigned short ch, int font);
+const unsigned char * font_get_bits(struct font* ft, unsigned short ch, int font);
+void glyph_cache_save(int font);
+void glyph_cache_load(int font);
 
 #else /* HAVE_LCD_BITMAP */
 
Index: tools/convbdf.c
===================================================================
--- tools/convbdf.c.orig
+++ tools/convbdf.c
@@ -354,7 +354,7 @@ int bdf_read_header(FILE *fp, struct fon
             continue;
         }
         if (isprefix(buf, "COPYRIGHT ")) {	/* not required*/
-            if (sscanf(buf, "COPYRIGHT \"%[^\"]", copyright) != 1) {
+            if (sscanf(buf, "COPYRIGHT \"%s\"", copyright) != 1) {
                 fprintf(stderr, "Error: bad 'COPYRIGHT'\n");
                 return 0;
             }
Index: firmware/include/lru.h
===================================================================
--- firmware/include/lru.h.orig
+++ firmware/include/lru.h
@@ -40,7 +40,7 @@ void lru_touch(struct lru* pl, short han
 /* Data */
 void *lru_data(struct lru* pl, short handle);
 /* Traverse lru-wise */
-void lru_traverse(struct lru* pl, void (*callback)(void* data));
+void lru_traverse(struct lru* pl, void (*callback)(void* data, int font), int font);
 
 #endif /* LRU_H */
 
Index: firmware/include/font_cache.h
===================================================================
--- firmware/include/font_cache.h.orig
+++ firmware/include/font_cache.h
@@ -21,6 +21,10 @@
 /*******************************************************************************
  * 
  ******************************************************************************/
+ 
+/* Maximum loadable/cacheable fonts. Exclude sysfont since it's compiled in */
+#define MAXCACHEFONTS MAXFONTS-1
+
 struct font_cache
 {
     struct lru _lru;
@@ -36,6 +40,19 @@ struct font_cache_entry
     unsigned char bitmap[1]; /* place holder */
 };
 
+/* Per-font internal cache struct */
+struct font_file_info
+{
+    unsigned long file_width_offset;    /* offset to file width data    */
+    unsigned long file_offset_offset;   /* offset to file offset data   */
+    int long_offset;
+    int glyph_fd;
+    unsigned char *freeptr;
+    unsigned char *fileptr;
+    unsigned char *eofptr;
+    int font_fd;                        /* >=0 if font is cached */
+};
+
 /* void (*f) (void*, struct font_cache_entry*); */
 /* Create an auto sized font cache from buf */
 void font_cache_create(
@@ -44,5 +61,5 @@ void font_cache_create(
 struct font_cache_entry* font_cache_get(
     struct font_cache* fcache,
     unsigned short char_code,
-    void (*callback) (struct font_cache_entry* p, void *callback_data),
-    void *callback_data);
+    void (*callback) (struct font_cache_entry* p, void *callback_data, int font),
+    void *callback_data, int font);
Index: apps/plugins/chessbox/chessbox.c
===================================================================
--- apps/plugins/chessbox/chessbox.c.orig
+++ apps/plugins/chessbox/chessbox.c
@@ -734,7 +734,8 @@ enum plugin_status plugin_start(struct p
     }
     
     cb_saveposition();
-    rb->lcd_setfont(FONT_UI);
+    rb->lcd_setfont(FONT_PLUGIN);
+
     return PLUGIN_OK;
 }
 
Index: firmware/drivers/lcd-remote-2bit-vi.c
===================================================================
--- firmware/drivers/lcd-remote-2bit-vi.c	(revision 12887)
+++ firmware/drivers/lcd-remote-2bit-vi.c	(working copy)
@@ -149,6 +149,11 @@
     curfont = newfont;
 }
 
+int lcd_remote_getcurfont(void)
+{
+	return curfont;
+}
+
 int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h)
 {
     return font_getstringsize(str, w, h, curfont);
@@ -949,7 +954,7 @@
         const unsigned char *bits;
 
         /* get proportional width and glyph bits */
-        width = font_get_width(pf, ch);
+        width = font_get_width(pf, ch, curfont);
 
         if (ofs > width)
         {
@@ -957,7 +962,7 @@
             continue;
         }
 
-        bits = font_get_bits(pf, ch);
+        bits = font_get_bits(pf, ch, curfont);
 
         lcd_remote_mono_bitmap_part(bits, ofs, 0, width, x, y, width - ofs,
                                     pf->height);
Index: apps/screen_access.h
===================================================================
--- apps/screen_access.h	(revision 12887)
+++ apps/screen_access.h	(working copy)
@@ -67,6 +69,8 @@
     int (*getymargin)(void);
 
     void (*setfont)(int newfont);
+    int (*getcurfont)(void);
+    
     int (*getstringsize)(const unsigned char *str, int *w, int *h);
     void (*putsxy)(int x, int y, const unsigned char *str);
 
Index: firmware/export/lcd.h
===================================================================
--- firmware/export/lcd.h.orig
+++ firmware/export/lcd.h
@@ -314,6 +314,7 @@ extern void  lcd_set_custom_width(int wi
 #endif
 
 extern void lcd_setfont(int font);
+extern int lcd_getcurfont(void);
 extern int  lcd_getstringsize(const unsigned char *str, int *w, int *h);
 
 extern void lcd_puts_offset(int x, int y, const unsigned char *str, int offset);
Index: apps/plugin.h
===================================================================
--- apps/plugin.h.orig
+++ apps/plugin.h
@@ -152,6 +152,7 @@ struct plugin_api {
     void (*lcd_set_drawmode)(int mode);
     int  (*lcd_get_drawmode)(void);
     void (*lcd_setfont)(int font);
+	int (*lcd_getcurfont)(void);
     int  (*lcd_getstringsize)(const unsigned char *str, int *w, int *h);
     void (*lcd_drawpixel)(int x, int y);
     void (*lcd_drawline)(int x1, int y1, int x2, int y2);
@@ -182,8 +183,8 @@ struct plugin_api {
             int width, int height);
 #endif
     unsigned short *(*bidi_l2v)( const unsigned char *str, int orientation );
-    const unsigned char *(*font_get_bits)( struct font *pf, unsigned short char_code );
-    struct font* (*font_load)(const char *path);
+    const unsigned char *(*font_get_bits)( struct font *pf, unsigned short char_code, int font );
+    struct font* (*font_load)(const char *path, int font);
     void (*lcd_putsxy)(int x, int y, const unsigned char *string);
     void (*lcd_puts_style)(int x, int y, const unsigned char *str, int style);
     void (*lcd_puts_scroll_style)(int x, int y, const unsigned char* string,
@@ -200,7 +201,7 @@ struct plugin_api {
     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* pf, unsigned short char_code);
+    int (*font_get_width)(struct font* pf, unsigned short char_code, int font);
 #endif
     void (*backlight_on)(void);
     void (*backlight_off)(void);
@@ -217,6 +218,7 @@ struct plugin_api {
     void (*lcd_remote_set_drawmode)(int mode);
     int  (*lcd_remote_get_drawmode)(void);
     void (*lcd_remote_setfont)(int font);
+	int (*lcd_remote_getcurfont)(void);
     int  (*lcd_remote_getstringsize)(const unsigned char *str, int *w, int *h);
     void (*lcd_remote_drawpixel)(int x, int y);
     void (*lcd_remote_drawline)(int x1, int y1, int x2, int y2);
Index: apps/plugins/zxbox/zxbox_keyb.c
===================================================================
--- apps/plugins/zxbox/zxbox_keyb.c.orig
+++ apps/plugins/zxbox/zxbox_keyb.c
@@ -195,13 +195,13 @@ int zx_kbd_input(char* text/*, int bufle
         rb->screens[l]->setfont(param[l].curfont);
         /* find max width of keyboard glyphs */
         for (i=0; i<param[l].nchars; i++) {
-            w = rb->font_get_width(param[l].font, param[l].kbd_buf[i]);
+            w = rb->font_get_width(param[l].font, param[l].kbd_buf[i], FONT_PLUGIN);
             if (w > param[l].font_w)
                 param[l].font_w = w;
         }
         /* Since we're going to be adding spaces, make sure that we check
          * their width too */
-        w = rb->font_get_width( param[l].font, ' ' );
+        w = rb->font_get_width( param[l].font, ' ', FONT_PLUGIN );
         if( w > param[l].font_w )
             param[l].font_w = w;
     }
@@ -253,7 +253,7 @@ int zx_kbd_input(char* text/*, int bufle
         text_w = param[l].font_w;
         while (*utf8) {
             utf8 = (unsigned char*)rb->utf8decode(utf8, &ch);
-            w = rb->font_get_width(param[l].font, ch);
+            w = rb->font_get_width(param[l].font, ch, FONT_SYSFIXED);
             if (w > text_w)
                 text_w = w;
         }
@@ -384,7 +384,7 @@ int zx_kbd_input(char* text/*, int bufle
 
             case KBD_ABORT:
                 FOR_NB_SCREENS(l)
-                    rb->screens[l]->setfont(FONT_UI);
+                    rb->screens[l]->setfont(FONT_SYSFIXED);
 
                 return -1;
                 break;
@@ -503,6 +503,6 @@ int zx_kbd_input(char* text/*, int bufle
         }
     }
     FOR_NB_SCREENS(l)
-        rb->screens[l]->setfont(FONT_UI);
+        rb->screens[l]->setfont(FONT_SYSFIXED);
     return 0;
 }
Index: firmware/export/lcd-remote.h
===================================================================
--- firmware/export/lcd-remote.h.orig
+++ firmware/export/lcd-remote.h
@@ -149,6 +149,8 @@ extern int  lcd_remote_getymargin(void);
 extern void lcd_remote_set_custom_width(int width);
 extern int lcd_remote_get_custom_width(void);
 extern void lcd_remote_setfont(int font);
+extern int lcd_remote_getcurfont(void);
+extern void lcd_remote_setfont(int font);
 extern int  lcd_remote_getstringsize(const unsigned char *str, int *w, int *h);
 
 /* low level drawing function pointer arrays */
Index: apps/gui/splash.c
===================================================================
--- apps/gui/splash.c.orig
+++ apps/gui/splash.c
@@ -22,6 +22,7 @@
 #include "stdio.h"
 #include "kernel.h"
 #include "screen_access.h"
+#include "font.h"
 
 #ifndef MAX
 #define MAX(a, b) (((a)>(b))?(a):(b))
@@ -54,10 +55,12 @@ static void splash(struct screen * scree
     int space_w, w, h;
 #ifdef HAVE_LCD_BITMAP
     int maxw = 0;
+	int oldFont=screen->getcurfont();
 #if LCD_DEPTH > 1
     unsigned prevfg = 0;
 #endif
 
+	screen->setfont(FONT_MENU);
     screen->getstringsize(" ", &space_w, &h);
 #else /* HAVE_LCD_CHARCELLS */
 
@@ -72,9 +75,13 @@ static void splash(struct screen * scree
     /* break splash string into display lines, doing proper word wrap */
 
     next = strtok_r(splash_buf, " ", &store);
-    if (!next)
+    if (!next){
+#ifdef HAVE_LCD_BITMAP
+		screen->setfont(oldFont);
+#endif
         return;  /* nothing to display */
-
+    }
+	
     lines[0] = next;
     while (true)
     {
@@ -124,6 +131,7 @@ static void splash(struct screen * scree
     screen->stop_scroll();
 
 #ifdef HAVE_LCD_BITMAP
+
     /* If we center the display, then just clear the box we need and put
        a nice little frame and put the text in there! */
     y = (screen->height - y) / 2;  /* height => y start position */
@@ -177,6 +185,7 @@ static void splash(struct screen * scree
         screen->set_foreground(prevfg);
         screen->set_drawmode(DRMODE_SOLID);
     }
+	screen->setfont(oldFont);
 #endif
 #if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR)
     screen->update();
Index: apps/plugins/rockblox.c
===================================================================
--- apps/plugins/rockblox.c.orig
+++ apps/plugins/rockblox.c
@@ -1037,7 +1037,7 @@ enum plugin_status plugin_start (struct 
     ret = rockblox_loop ();
 
 #ifdef HAVE_LCD_BITMAP
-    rb->lcd_setfont (FONT_UI);
+    rb->lcd_setfont (FONT_BROWSER);
 #else
     pgfx_release();
 #endif
Index: apps/gui/color_picker.c
===================================================================
--- apps/gui/color_picker.c.orig
+++ apps/gui/color_picker.c
@@ -270,6 +270,7 @@ static void draw_screen(struct screen *d
     } /* end for */
 
     /* Draw color value in system font */
+	int oldFont=display->getcurfont();
     display->setfont(FONT_SYSFIXED);
 
     /* Format RGB: #rrggbb */
@@ -322,7 +323,7 @@ static void draw_screen(struct screen *d
         }
     }
 
-    display->setfont(FONT_UI);
+	display->setfont(oldFont);
 
     display->update();
     /* Be sure screen mode is reset */
Index: apps/plugin.c
===================================================================
--- apps/plugin.c.orig
+++ apps/plugin.c
@@ -84,6 +84,7 @@ static const struct plugin_api rockbox_a
     lcd_set_drawmode,
     lcd_get_drawmode,
     lcd_setfont,
+	lcd_getcurfont,
     lcd_getstringsize,
     lcd_drawpixel,
     lcd_drawline,
@@ -135,6 +136,7 @@ static const struct plugin_api rockbox_a
     lcd_remote_set_drawmode,
     lcd_remote_get_drawmode,
     lcd_remote_setfont,
+	lcd_remote_getcurfont,
     lcd_remote_getstringsize,
     lcd_remote_drawpixel,
     lcd_remote_drawline,
Index: firmware/powermgmt.c
===================================================================
--- firmware/powermgmt.c.orig
+++ firmware/powermgmt.c
@@ -1297,7 +1297,12 @@ void shutdown_hw(void)
     audio_stop();
     if (!battery_level_critical()) { /* do not save on critical battery */
 #ifdef HAVE_LCD_BITMAP
-        glyph_cache_save();
+		int i = FONT_BROWSER;   /* Skip sysfont, even though glyph_cache_save() would ignore it */
+		while (i < MAXFONTS)
+		{
+		    glyph_cache_save(i);
+		    i++;
+		}
 #endif
         if(ata_disk_is_active())
             ata_spindown(1);
Index: firmware/drivers/lcd-2bit-vert.c
===================================================================
--- firmware/drivers/lcd-2bit-vert.c.orig
+++ firmware/drivers/lcd-2bit-vert.c
@@ -163,6 +163,11 @@ void lcd_setfont(int newfont)
     curfont = newfont;
 }
 
+int lcd_getcurfont()
+{
+	return curfont;
+}
+
 int lcd_getstringsize(const unsigned char *str, int *w, int *h)
 {
     return font_getstringsize(str, w, h, curfont);
@@ -965,7 +970,7 @@ static void lcd_putsxyofs(int x, int y, 
         const unsigned char *bits;
 
         /* get proportional width and glyph bits */
-        width = font_get_width(pf,ch);
+        width = font_get_width(pf,ch, curfont);
 
         if (ofs > width)
         {
@@ -973,7 +978,7 @@ static void lcd_putsxyofs(int x, int y, 
             continue;
         }
 
-        bits = font_get_bits(pf, ch);
+        bits = font_get_bits(pf, ch, curfont);
 
         lcd_mono_bitmap_part(bits, ofs, 0, width, x, y, 
 			(x+width > used_rightmargin?used_rightmargin-x:width) - ofs, pf->height);
Index: apps/settings_list.c
===================================================================
--- apps/settings_list.c.orig
+++ apps/settings_list.c
@@ -1096,8 +1096,20 @@ const struct settings_list settings[] = 
     FILENAME_SETTING(0, fmr_file, "fmr",
         "", FMPRESET_PATH "/", ".fmr", MAX_FILENAME+1),
 #endif
-    FILENAME_SETTING(F_THEMESETTING, font_file, "font",
-        "", FONT_DIR "/", ".fnt", MAX_FILENAME+1),
+ 
+    /** backward comp **/
+    FILENAME_SETTING(F_THEMESETTING,font_file,"font","",FONT_DIR "/",".fnt",MAX_FILENAME+1),
+
+    FILENAME_SETTING(F_THEMESETTING,browserfont,"browserfont","",FONT_DIR "/",".fnt",MAX_FILENAME+1),
+    FILENAME_SETTING(F_THEMESETTING,wpsfont,"wpsfont","",FONT_DIR "/",".fnt",MAX_FILENAME+1),
+    FILENAME_SETTING(F_THEMESETTING,menufont,"menufont","",FONT_DIR "/",".fnt",MAX_FILENAME+1),
+#ifdef HAVE_RECORDING
+    FILENAME_SETTING(F_THEMESETTING,recordfont,"recordfont","",FONT_DIR "/",".fnt",MAX_FILENAME+1),
+#endif    
+#ifdef CONFIG_TUNER
+    FILENAME_SETTING(F_THEMESETTING,tunerfont,"tunerfont","",FONT_DIR "/",".fnt",MAX_FILENAME+1),
+#endif
+        
     FILENAME_SETTING(F_THEMESETTING,wps_file, "wps",
         "", WPS_DIR "/", ".wps", MAX_FILENAME+1),
     FILENAME_SETTING(0,lang_file,"lang","",LANG_DIR "/",".lng",MAX_FILENAME+1),
Index: apps/root_menu.c
===================================================================
--- apps/root_menu.c.orig
+++ apps/root_menu.c
@@ -387,7 +387,11 @@ static int get_selection(int last_screen
 }
 
 void root_menu(void)
-{
+{	
+#ifdef HAVE_LCD_BITMAP
+	gui_list_context = GUI_LIST_CONTEXT_MENU;   /* Set menu font */
+#endif
+
     int previous_browser = GO_TO_FILEBROWSER;
     int previous_music = GO_TO_WPS;
     int ret_val = GO_TO_ROOT;
@@ -428,7 +432,10 @@ void root_menu(void)
         switch (ret_val)
         {
             case GO_TO_ROOT:
-                if (last_screen != GO_TO_ROOT)
+#ifdef HAVE_LCD_BITMAP
+        		gui_list_context = GUI_LIST_CONTEXT_MENU;   /* Set menu font */
+#endif
+            	if (last_screen != GO_TO_ROOT)
                     selected = get_selection(last_screen);
                 ret_val = do_menu(&root_menu_, &selected);
                 /* As long as MENU_ATTACHED_USB == GO_TO_ROOT this works */
Index: apps/gui/yesno.c
===================================================================
--- apps/gui/yesno.c.orig
+++ apps/gui/yesno.c
@@ -23,6 +23,7 @@
 #include "misc.h"
 #include "lang.h"
 #include "action.h"
+#include "font.h"
 
 /*
  * Initializes the yesno asker
@@ -105,8 +106,14 @@ enum yesno_res gui_syncyesno_run(struct 
     int result=-1;
     bool result_displayed;
     struct gui_yesno yn[NB_SCREENS];
+	int old_font[NB_SCREENS];
+
     FOR_NB_SCREENS(i)
     {
+#ifdef HAVE_LCD_BITMAP
+    	old_font[i]=screens[i].getcurfont();
+        screens[i].setfont(FONT_MENU);
+#endif
         gui_yesno_init(&(yn[i]), main_message, yes_message, no_message);
         gui_yesno_set_display(&(yn[i]), &(screens[i]));
         gui_yesno_draw(&(yn[i]));
@@ -123,8 +130,15 @@ enum yesno_res gui_syncyesno_run(struct 
             case ACTION_NONE:
                 continue;
             default:
-                if(default_event_handler(button) == SYS_USB_CONNECTED)
+                if(default_event_handler(button) == SYS_USB_CONNECTED){
+#ifdef HAVE_LCD_BITMAP
+                	FOR_NB_SCREENS(i)
+                    {
+                        screens[i].setfont(old_font[i]);
+                    }
+#endif
                     return(YESNO_USB);
+                }
                 result = YESNO_NO;
         }
     }
@@ -133,5 +147,13 @@ enum yesno_res gui_syncyesno_run(struct 
         result_displayed=gui_yesno_draw_result(&(yn[i]), result);
     if(result_displayed)
         sleep(HZ);
+    
+#ifdef HAVE_LCD_BITMAP
+    FOR_NB_SCREENS(i)
+    {
+        screens[i].setfont(old_font[i]);
+    }
+#endif
+    
     return(result);
 }
