diff --git a/apps/gui/skin_engine/skin_fonts.c b/apps/gui/skin_engine/skin_fonts.c
index a89b762..ed888db 100644
--- a/apps/gui/skin_engine/skin_fonts.c
+++ b/apps/gui/skin_engine/skin_fonts.c
@@ -31,10 +31,8 @@
 #include "skin_fonts.h"
 
 static struct skin_font_info {
-    struct font font;
     int font_id;
     char name[MAX_PATH];
-    char *buffer;
     int ref_count; /* how many times has this font been loaded? */
 } font_table[MAXUSERFONTS];
 
@@ -49,8 +47,6 @@ void skin_font_init(void)
         if (!first_load)
             font_unload(font_table[i].font_id);
         font_table[i].font_id = -1;
-        font_table[i].name[0] = '\0';
-        font_table[i].buffer = NULL;
         font_table[i].ref_count = 0;
     }
     first_load = false;
@@ -61,7 +57,7 @@ int skin_font_load(char* font_name, int glyphs)
 {
     int i;
     int skin_font_size = 0;
-    struct font *pf;
+    struct font *pf = 0xffffffff;
     struct skin_font_info *font = NULL;
     char filename[MAX_PATH];
     
@@ -88,7 +84,7 @@ int skin_font_load(char* font_name, int glyphs)
     }
     if (!font)
         return -1; /* too many fonts loaded */
-    
+#if 0
     pf = &font->font;
     if (!font->buffer)
     {
@@ -113,6 +109,7 @@ int skin_font_load(char* font_name, int glyphs)
     }
     
     pf->fd = -1;
+#endif
     font->font_id = font_load(pf, filename);
     
     if (font->font_id < 0)
diff --git a/firmware/export/font.h b/firmware/export/font.h
index a85f95e..08e10fd 100644
--- a/firmware/export/font.h
+++ b/firmware/export/font.h
@@ -22,6 +22,7 @@
 #define _FONT_H
 
 #include "inttypes.h"
+#include "stdbool.h"
 
 /*
  * Incore font and image definitions
@@ -105,7 +106,8 @@ struct font {
     unsigned char *buffer_start;    /* buffer to store the font in */       
     unsigned char *buffer_position; /* position in the buffer */    
     unsigned char *buffer_end;      /* end of the buffer */
-    int          buffer_size;       /* size of the buffer in bytes */
+    int            buffer_size;     /* size of the buffer in bytes */
+    bool           handle_locked;   /* is the buflib handle currently locked? */
 #ifndef __PCTOOL__    
     struct font_cache cache;
     uint32_t file_width_offset;    /* offset to file width data    */
diff --git a/firmware/font.c b/firmware/font.c
index 0f9f453..99fcdfd 100644
--- a/firmware/font.c
+++ b/firmware/font.c
@@ -34,6 +34,7 @@
 #include "system.h"
 #include "font.h"
 #include "file.h"
+#include "core_alloc.h"
 #include "debug.h"
 #include "panic.h"
 #include "rbunicode.h"
@@ -74,19 +75,35 @@ extern struct font sysfont;
 
 #ifndef BOOTLOADER
 
-/* structure filled in by font_load */
-static struct font font_ui;
-/* static buffer allocation structures */
-static unsigned char main_buf[MAX_FONT_SIZE] CACHEALIGN_ATTR;
-#ifdef HAVE_REMOTE_LCD
-#define REMOTE_FONT_SIZE 10000
-static struct font remote_font_ui;
-static unsigned char remote_buf[REMOTE_FONT_SIZE] CACHEALIGN_ATTR;
-#endif
-
-/* system font table, in order of FONT_xxx definition */
-static struct font* sysfonts[MAXFONTS] = { &sysfont, &font_ui, NULL};
+struct buflib_alloc_data {
+    struct font font;
+    unsigned char buffer[MAX_FONT_SIZE] CACHEALIGN_ATTR;
+};
+static int buflib_allocations[MAXFONTS];
+#define ID_TO_INDEX(id) ((id)-FONT_UI) 
+static int buflibmove_callback(int handle, void* current, void* new)
+{
+    (void)handle;
+    struct buflib_alloc_data *alloc = (struct buflib_alloc_data*)current;
+    size_t diff = new - current;
+
+    if (alloc->font.handle_locked)
+        return BUFLIB_CB_CANNOT_MOVE;
+    alloc->font.bits += diff;
+    alloc->font.offset += diff;
+
+    alloc->font.buffer_start += diff;
+    alloc->font.buffer_end += diff;
+    alloc->font.buffer_position += diff;
+    return BUFLIB_CB_OK;
+}
+static void lock_font_handle(int handle, bool lock)
+{
+    struct buflib_alloc_data *alloc = core_get_data(handle);
+    alloc->font.handle_locked = lock;
+}
 
+static struct buflib_callbacks buflibops = {buflibmove_callback, NULL };
 
 /* Font cache structures */
 static void cache_create(struct font* pf);
@@ -95,13 +112,9 @@ static void glyph_cache_load(struct font* pf);
 
 void font_init(void)
 {
-    int i = SYSTEMFONTCOUNT;
+    int i = 0;
     while (i<MAXFONTS)
-        sysfonts[i++] = NULL;
-    font_reset(NULL);
-#ifdef HAVE_REMOTE_LCD
-    font_reset(&remote_font_ui);
-#endif
+        buflib_allocations[i++] = -1;
 }
 
 /* Check if we have x bytes left in the file buffer */
@@ -141,22 +154,9 @@ static int glyph_bytes( struct font *pf, int width )
 
 void font_reset(struct font *pf)
 {
-    unsigned char* buffer = NULL;
-    size_t buf_size = 0;
-    if (pf == NULL)
-        pf = &font_ui;
-    else
-    {
-        buffer = pf->buffer_start;
-        buf_size = pf->buffer_size;
-    }
+    // fixme
     memset(pf, 0, sizeof(struct font));
     pf->fd = -1;
-    if (buffer)
-    {
-        pf->buffer_start = buffer;
-        pf->buffer_size = buf_size;
-    }
 }
 
 static struct font* font_load_header(struct font *pf)
@@ -415,6 +415,31 @@ int font_load_remoteui(const char* path)
     return FONT_UI_REMOTE;
 }
 #endif
+static inline struct font *pf_from_handle(int handle)
+{
+    struct buflib_alloc_data *alloc = core_get_data(handle);
+    struct font *pf = &alloc->font;
+    return pf;
+}
+static inline unsigned char *buffer_from_handle(int handle)
+{
+    struct buflib_alloc_data *alloc = core_get_data(handle);
+    unsigned char* buffer = alloc->buffer;
+    return buffer;
+}
+
+static int alloc_and_init(const char* name)
+{
+    int handle = core_alloc_ex(name, sizeof(struct buflib_alloc_data), &buflibops);
+    struct font *pf = pf_from_handle(handle);
+    if (handle < 0)
+        return handle;
+    font_reset(pf);
+    pf->handle_locked = false;
+    pf->buffer_position = pf->buffer_start = buffer_from_handle(handle);
+    pf->buffer_size = MAX_FONT_SIZE;
+    return handle;
+}
 
 /* read and load font into incore font structure,
  * returns the font number on success, -1 on failure */
@@ -423,51 +448,61 @@ int font_load(struct font* pf, const char *path)
     int font_id = -1;
     char *buffer;
     size_t buffer_size;
+    int *handle;
     if (pf == NULL)
     {
-        pf = &font_ui;
+        handle = &buflib_allocations[ID_TO_INDEX(FONT_UI)];
+        if (*handle < 0)
+        {
+            *handle = alloc_and_init("ui font");
+        }
+        if (*handle < 0)
+            return -1;
         font_id = FONT_UI;
     }
     else
     {
         for (font_id = SYSTEMFONTCOUNT; font_id < MAXFONTS; font_id++)
         {
-            if (sysfonts[font_id] == NULL)
+            handle = &buflib_allocations[ID_TO_INDEX(font_id)];            
+            if (*handle < 0)
+            {
+                *handle = alloc_and_init(path);
+                if (*handle < 0)
+                    return -1;
                 break;
+            }
         }
         if (font_id == MAXFONTS)
             return -1; /* too many fonts */
     }
-    
-    if (font_id == FONT_UI)
-    {
-        /* currently, font loading replaces earlier font allocation*/
-        buffer = (unsigned char *)(((intptr_t)main_buf + 3) & ~3);
-        /* make sure above doesn't exceed */
-        buffer_size = MAX_FONT_SIZE-3; 
-    }
-    else
-    {
-        buffer = pf->buffer_start;
-        buffer_size = pf->buffer_size;
-    }
-    
+    pf = pf_from_handle(*handle);
+    buffer = buffer_from_handle(*handle);
+    buffer_size = MAX_FONT_SIZE; //FIXME
+    lock_font_handle(*handle, true);
+
     if (!internal_load_font(pf, path, buffer, buffer_size))
+    {
+        lock_font_handle(*handle, false);
+        core_free(*handle);
+        *handle = -1;
         return -1;
+    }
         
-    sysfonts[font_id] = pf;
+    lock_font_handle(*handle, false);
+    //printf("%s -> [%d] -> %d\n", path, font_id, *handle);
     return font_id; /* success!*/
 }
 
 void font_unload(int font_id)
 {
-    struct font* pf = sysfonts[font_id];
-    if (font_id >= SYSTEMFONTCOUNT && pf)
-    {
-        if (pf->fd >= 0)
-            close(pf->fd);
-        sysfonts[font_id] = NULL;
-    }
+    int *handle = &buflib_allocations[ID_TO_INDEX(font_id)];
+    struct font* pf = pf_from_handle(*handle);
+    if (pf && pf->fd >= 0)
+        close(pf->fd);
+    if (*handle > 0)
+        core_free(*handle);
+    *handle = -1;
 }
 
 /*
@@ -480,7 +515,10 @@ struct font* font_get(int font)
     struct font* pf;
 
     while (1) {
-        pf = sysfonts[font];
+        if (font == FONT_SYSFIXED)
+            return &sysfont;
+        struct buflib_alloc_data *alloc = core_get_data(buflib_allocations[ID_TO_INDEX(font)]);
+        pf = &alloc->font;
         if (pf && pf->height)
             return pf;
         if (--font < 0)
@@ -594,7 +632,8 @@ static int cache_fd;
 static void glyph_file_write(void* data)
 {
     struct font_cache_entry* p = data;
-    struct font* pf = &font_ui;
+    int handle = buflib_allocations[ID_TO_INDEX(FONT_UI)];
+    struct font* pf = pf_from_handle(handle);
     unsigned short ch;
     unsigned char tmp[2];
 
@@ -603,6 +642,7 @@ static void glyph_file_write(void* data)
     
     ch = p->_char_code + pf->firstchar;
 
+    lock_font_handle(handle, true);
     if ( cache_fd >= 0) {
         tmp[0] = ch >> 8;
         tmp[1] = ch & 0xff;
@@ -611,15 +651,20 @@ static void glyph_file_write(void* data)
             cache_fd = -1;
         }
     }
+    lock_font_handle(handle, false);
     return;
 }
 
 /* save the char codes of the loaded glyphs to a file */
 void glyph_cache_save(struct font* pf)
 {
+    int handle = buflib_allocations[ID_TO_INDEX(FONT_UI)]; // fixme
     if (!pf)
-        pf = &font_ui;
-    if (pf->fd >= 0 && pf == &font_ui) 
+    {
+        //fixme: int handle = buflib_allocations[ID_TO_INDEX(FONT_UI)];
+        pf = pf_from_handle(handle);
+    }
+    if (pf->fd >= 0 && pf == pf_from_handle(buflib_allocations[ID_TO_INDEX(FONT_UI)])) 
     {
         cache_fd = open(GLYPH_CACHE_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0666);
         if (cache_fd < 0)
@@ -677,7 +722,7 @@ static void glyph_cache_load(struct font* pf)
 {
 
 #define MAX_SORT 256
-    if (pf->fd >= 0) {
+    if (pf->fd >= 0 && pf == pf_from_handle(buflib_allocations[ID_TO_INDEX(FONT_UI)])) {
         int fd;
         int i, size;
         unsigned char tmp[2];
