Index: tools/convbdf.c
===================================================================
--- tools/convbdf.c	(revision 27911)
+++ tools/convbdf.c	(working copy)
@@ -46,6 +46,7 @@
     int     ascent;     /* ascent (baseline) height */
     int     firstchar;  /* first character in bitmap */
     int     size;       /* font size in glyphs ('holes' included) */
+    int     depth;      /* depth of the font, 0=1bit 1=4bit */
     bitmap_t*   bits;       /* 16-bit right-padded bitmap data */
     int*    offset;     /* offsets into bitmap data */
     unsigned char* width;   /* character widths or NULL if fixed */
@@ -1220,6 +1221,7 @@
         "   size: %d\n"
         "   ascent: %d\n"
         "   descent: %d\n"
+        "   depth: %d\n"
         "   first char: %d (0x%02x)\n"
         "   last char: %d (0x%02x)\n"
         "   default char: %d (0x%02x)\n"
@@ -1245,7 +1247,7 @@
             pf->facename? pf->facename: "",
             pf->maxwidth, pf->height,
             pf->size,
-            pf->ascent, pf->descent,
+            pf->ascent, pf->descent, pf->depth,
             pf->firstchar, pf->firstchar,
             pf->firstchar+pf->size-1, pf->firstchar+pf->size-1,
             pf->defaultchar, pf->defaultchar,
@@ -1392,6 +1394,7 @@
             "  %d,  /* ascent */\n"
             "  %d,  /* firstchar */\n"
             "  %d,  /* size */\n"
+            "  %d,  /* depth */\n"
             "  _font_bits, /* bits */\n"
             "  %s  /* offset */\n"
             "  %s\n"
@@ -1411,7 +1414,7 @@
             pf->maxwidth, pf->height,
             pf->ascent,
             pf->firstchar,
-            pf->size,
+            pf->size, 0,
             obuf,
             buf,
             pf->defaultchar,
@@ -1436,7 +1439,8 @@
         "#define SYSFONT_WIDTH          %d\n"
         "#define SYSFONT_HEIGHT         %d\n"
         "#define SYSFONT_SIZE           %d\n"
-        "#define SYSFONT_ASCENT         %d\n";
+        "#define SYSFONT_ASCENT         %d\n"
+        "#define SYSFONT_DEPTH          %d\n";
     char *hdr2 =
         "#define SYSFONT_DESCENT        %d\n"
         "#define SYSFONT_FIRST_CHAR     %d\n"
@@ -1463,7 +1467,8 @@
             pf->maxwidth,
             pf->height,
             pf->size,
-            pf->ascent);
+            pf->ascent,
+            pf->depth);
 
     fprintf(ofp, hdr2, 
             pf->descent,
@@ -1546,7 +1551,7 @@
     writeshort(ofp, pf->maxwidth);
     writeshort(ofp, pf->height);
     writeshort(ofp, pf->ascent);
-    writeshort(ofp, 0);
+    writeshort(ofp, 0); /* depth = 0 for bdffonts */
     writeint(ofp, pf->firstchar);
     writeint(ofp, pf->defaultchar);
     writeint(ofp, pf->size);
Index: tools/Makefile
===================================================================
--- tools/Makefile	(revision 27911)
+++ tools/Makefile	(working copy)
@@ -13,10 +13,10 @@
 
 CLEANALL := scramble descramble iriver sh2d bmp2rb rdf2binary convbdf \
     generate_rocklatin mkboot ipod_fw codepages uclpack mi4 gigabeat lngdump \
-    telechips gigabeats creative hmac-sha1 rbspeexenc mkzenboot mk500boot
+    telechips gigabeats creative hmac-sha1 rbspeexenc mkzenboot mk500boot convttf
 
 all: scramble descramble sh2d rdf2binary mkboot mkzenboot convbdf codepages \
-	uclpack rbspeexenc voicefont mk500boot
+	uclpack rbspeexenc voicefont mk500boot convttf
 
 scramble: scramble.o iriver.o mi4.o gigabeat.o gigabeats.o telechips.o \
 	iaudio_bl_flash.o creative.o hmac-sha1.o
@@ -97,6 +97,11 @@
 usb_benchmark: usb_benchmark.c
 	$(SILENT)$(CC) $(CFLAGS) -lusb $+ -o $@
 
+convttf: convttf.c
+	$(call PRINTS,CC $(@F))
+	$(SILENT)$(CC) $(CFLAGS) -lm -std=c99 -O2 -Wall -g $+ -o $@ \
+		`freetype-config --libs` `freetype-config --cflags`
+
 clean:
 	@echo "Cleaning tools"
 	$(SILENT)rm -f $(CLEANALL) $(shell for f in $(CLEANALL) ; do \
Index: tools/root.make
===================================================================
--- tools/root.make	(revision 27911)
+++ tools/root.make	(working copy)
@@ -20,7 +20,7 @@
 TOOLS = $(TOOLSDIR)/rdf2binary $(TOOLSDIR)/convbdf \
 	$(TOOLSDIR)/codepages $(TOOLSDIR)/scramble $(TOOLSDIR)/bmp2rb \
 	$(TOOLSDIR)/uclpack $(TOOLSDIR)/mkboot $(TOOLSDIR)/iaudio_bl_flash.c \
-	$(TOOLSDIR)/iaudio_bl_flash.h
+	$(TOOLSDIR)/iaudio_bl_flash.h $(TOOLSDIR)/convttf
 
 
 ifeq (,$(PREFIX))
Index: tools/tools.make
===================================================================
--- tools/tools.make	(revision 27911)
+++ tools/tools.make	(working copy)
@@ -33,6 +33,11 @@
 	$(call PRINTS,CC $(@F))$(HOSTCC) $(TOOLSCFLAGS) -I$(TOOLSDIR)/ucl \
 		-I$(TOOLSDIR)/ucl/include -o $@ $^
 
+$(TOOLSDIR)/convttf: $(TOOLSDIR)/convttf.c
+	$(call PRINTS,CC $(@F))
+	$(SILENT)$(HOSTCC) $(TOOLSFLAGS) -lm -O2 -Wall -g $+ -o $@ \
+		`freetype-config --libs` `freetype-config --cflags`
+
 # implicit rule for simple tools
 $(TOOLSDIR)/%: $(TOOLSDIR)/%.c
 	$(call PRINTS,CC $(subst $(ROOTDIR)/,,$@))
Index: apps/plugins/rockpaint.c
===================================================================
--- apps/plugins/rockpaint.c	(revision 27911)
+++ apps/plugins/rockpaint.c	(working copy)
@@ -515,6 +515,180 @@
     } while( src < src_end );
 }
 
+/* draw alpha bitmap for anti-alias font */
+#define ALPHA_COLOR_FONT_DEPTH 2
+#define ALPHA_COLOR_LOOKUP_SHIFT (1 << ALPHA_COLOR_FONT_DEPTH)
+#define ALPHA_COLOR_LOOKUP_SIZE ((1 << ALPHA_COLOR_LOOKUP_SHIFT) - 1)
+#define ALPHA_COLOR_PIXEL_PER_BYTE (8 >> ALPHA_COLOR_FONT_DEPTH)
+#define ALPHA_COLOR_PIXEL_PER_WORD (32 >> ALPHA_COLOR_FONT_DEPTH)
+#ifdef CPU_ARM
+#define BLEND_INIT do {} while (0)
+#define BLEND_START(acc, color, alpha) \
+    asm volatile("mul %0, %1, %2" : "=&r" (acc) : "r" (color), "r" (alpha))
+#define BLEND_CONT(acc, color, alpha) \
+    asm volatile("mla %0, %1, %2, %0" : "+&r" (acc) : "r" (color), "r" (alpha))
+#define BLEND_OUT(acc) do {} while (0)
+#elif defined(CPU_COLDFIRE)
+#define ALPHA_BITMAP_READ_WORDS
+#define BLEND_INIT coldfire_set_macsr(EMAC_UNSIGNED)
+#define BLEND_START(acc, color, alpha) \
+    asm volatile("mac.l %0, %1, %%acc0" :: "%d" (color), "d" (alpha))
+#define BLEND_CONT BLEND_START
+#define BLEND_OUT(acc) asm volatile("movclr.l %%acc0, %0" : "=d" (acc))
+#else
+#define BLEND_INIT do {} while (0)
+#define BLEND_START(acc, color, alpha) ((acc) = (color) * (alpha))
+#define BLEND_CONT(acc, color, alpha) ((acc) += (color) * (alpha))
+#define BLEND_OUT(acc) do {} while (0)
+#endif
+
+/* Blend the given two colors */
+static inline unsigned blend_two_colors(unsigned c1, unsigned c2, unsigned a)
+{
+    a += a >> (ALPHA_COLOR_LOOKUP_SHIFT - 1);
+#if (LCD_PIXELFORMAT == RGB565SWAPPED)
+    c1 = swap16(c1);
+    c2 = swap16(c2);
+#endif
+    unsigned c1l = (c1 | (c1 << 16)) & 0x07e0f81f;
+    unsigned c2l = (c2 | (c2 << 16)) & 0x07e0f81f;
+    unsigned p;
+    BLEND_START(p, c1l, a);
+    BLEND_CONT(p, c2l, ALPHA_COLOR_LOOKUP_SIZE + 1 - a);
+    BLEND_OUT(p);
+    p = (p >> ALPHA_COLOR_LOOKUP_SHIFT) & 0x07e0f81f;
+    p |= (p >> 16);
+#if (LCD_PIXELFORMAT == RGB565SWAPPED)
+    return swap16(p);
+#else
+    return p;
+#endif
+}
+
+static void buffer_alpha_bitmap_part(
+                              fb_data *buf, int buf_width, int buf_height,
+                              const unsigned char *src, int src_x, int src_y,
+                              int stride, int x, int y, int width, int height )
+{
+    fb_data *dst;
+    unsigned fg_pattern = rb->lcd_get_foreground();
+
+    /* nothing to draw? */
+    if ((width <= 0) || (height <= 0) || (x >= buf_width) ||
+         (y >= buf_height) || (x + width <= 0) || (y + height <= 0))
+        return;
+
+    /* initialize blending */
+    BLEND_INIT;
+
+    /* clipping */
+    if (x < 0)
+    {
+        width += x;
+        src_x -= x;
+        x = 0;
+    }
+    if (y < 0)
+    {
+        height += y;
+        src_y -= y;
+        y = 0;
+    }
+    if (x + width > buf_width)
+        width = buf_width - x;
+    if (y + height > buf_height)
+        height = buf_height - y;
+
+    dst = buf + y*buf_width + x;
+
+    int col, row = height;
+    unsigned data, pixels;
+    unsigned skip_end = (stride - width);
+    unsigned skip_start = src_y * stride + src_x;
+
+#ifdef ALPHA_BITMAP_READ_WORDS
+    uint32_t *src_w = (uint32_t *)((uintptr_t)src & ~3);
+    skip_start += ALPHA_COLOR_PIXEL_PER_BYTE * ((uintptr_t)src & 3);
+    src_w += skip_start / ALPHA_COLOR_PIXEL_PER_WORD;
+    data = letoh32(*src_w++);
+#else
+    src += skip_start / ALPHA_COLOR_PIXEL_PER_BYTE;
+    data = *src;
+#endif
+    pixels = skip_start % ALPHA_COLOR_PIXEL_PER_WORD;
+    data >>= pixels * ALPHA_COLOR_LOOKUP_SHIFT;
+#ifdef ALPHA_BITMAP_READ_WORDS
+    pixels = 8 - pixels;
+#endif
+
+    do
+    {
+        col = width;
+#ifdef ALPHA_BITMAP_READ_WORDS
+#define UPDATE_SRC_ALPHA    do { \
+            if (--pixels) \
+                data >>= ALPHA_COLOR_LOOKUP_SHIFT; \
+            else \
+            { \
+                data = letoh32(*src_w++); \
+                pixels = ALPHA_COLOR_PIXEL_PER_WORD; \
+            } \
+        } while (0)
+#elif ALPHA_COLOR_PIXEL_PER_BYTE == 2
+#define UPDATE_SRC_ALPHA    do { \
+            if (pixels ^= 1) \
+                data >>= ALPHA_COLOR_LOOKUP_SHIFT; \
+            else \
+                data = *(++src); \
+        } while (0)
+#else
+#define UPDATE_SRC_ALPHA    do { \
+            if (pixels = (++pixels % ALPHA_COLOR_PIXEL_PER_BYTE)) \
+                data >>= ALPHA_COLOR_LOOKUP_SHIFT; \
+            else \
+                data = *(++src); \
+        } while (0)
+#endif
+
+        do
+        {
+            *dst=blend_two_colors(*dst, fg_pattern,
+                                  data & ALPHA_COLOR_LOOKUP_SIZE );
+            dst++;
+            UPDATE_SRC_ALPHA;
+        }
+        while (--col);
+#ifdef ALPHA_BITMAP_READ_WORDS
+        if (skip_end < pixels)
+        {
+            pixels -= skip_end;
+            data >>= skip_end * ALPHA_COLOR_LOOKUP_SHIFT;
+        } else {
+            pixels = skip_end - pixels;
+            src_w += pixels / ALPHA_COLOR_PIXEL_PER_WORD;
+            pixels %= ALPHA_COLOR_PIXEL_PER_WORD;
+            data = letoh32(*src_w++);
+            data >>= pixels * ALPHA_COLOR_LOOKUP_SHIFT;
+            pixels = 8 - pixels;
+        }
+#else
+        if (skip_end)
+        {
+            pixels += skip_end;
+            if (pixels >= ALPHA_COLOR_PIXEL_PER_BYTE)
+            {
+                src += pixels / ALPHA_COLOR_PIXEL_PER_BYTE;
+                pixels %= ALPHA_COLOR_PIXEL_PER_BYTE;
+                data = *src;
+                data >>= pixels * ALPHA_COLOR_LOOKUP_SHIFT;
+            } else
+                data >>= skip_end * ALPHA_COLOR_LOOKUP_SHIFT;
+        }
+#endif
+        dst += LCD_WIDTH - width;
+    } while (--row);
+}
+
 static void buffer_putsxyofs( fb_data *buf, int buf_width, int buf_height,
                               int x, int y, int ofs, const unsigned char *str )
 {
@@ -542,8 +716,12 @@
 
         bits = rb->font_get_bits( pf, ch );
 
-        buffer_mono_bitmap_part( buf, buf_width, buf_height, bits, ofs, 0,
-                                 width, x, y, width - ofs, pf->height);
+        if (pf->depth)
+            buffer_alpha_bitmap_part( buf, buf_width, buf_height, bits, ofs, 0,
+                                      width, x, y, width - ofs, pf->height);
+        else
+            buffer_mono_bitmap_part( buf, buf_width, buf_height, bits, ofs, 0,
+                                     width, x, y, width - ofs, pf->height);
 
         x += width - ofs;
         ofs = 0;
Index: apps/plugins/mpegplayer/mpegplayer.c
===================================================================
--- apps/plugins/mpegplayer/mpegplayer.c	(revision 27911)
+++ apps/plugins/mpegplayer/mpegplayer.c	(working copy)
@@ -616,6 +616,172 @@
     while (src < src_end);
 }
 
+/* draw alpha bitmap for anti-alias font */
+#define ALPHA_COLOR_FONT_DEPTH 2
+#define ALPHA_COLOR_LOOKUP_SHIFT (1 << ALPHA_COLOR_FONT_DEPTH)
+#define ALPHA_COLOR_LOOKUP_SIZE ((1 << ALPHA_COLOR_LOOKUP_SHIFT) - 1)
+#define ALPHA_COLOR_PIXEL_PER_BYTE (8 >> ALPHA_COLOR_FONT_DEPTH)
+#define ALPHA_COLOR_PIXEL_PER_WORD (32 >> ALPHA_COLOR_FONT_DEPTH)
+#ifdef CPU_ARM
+#define BLEND_INIT do {} while (0)
+#define BLEND_START(acc, color, alpha) \
+    asm volatile("mul %0, %1, %2" : "=&r" (acc) : "r" (color), "r" (alpha))
+#define BLEND_CONT(acc, color, alpha) \
+    asm volatile("mla %0, %1, %2, %0" : "+&r" (acc) : "r" (color), "r" (alpha))
+#define BLEND_OUT(acc) do {} while (0)
+#elif defined(CPU_COLDFIRE)
+#define ALPHA_BITMAP_READ_WORDS
+#define BLEND_INIT coldfire_set_macsr(EMAC_UNSIGNED)
+#define BLEND_START(acc, color, alpha) \
+    asm volatile("mac.l %0, %1, %%acc0" :: "%d" (color), "d" (alpha))
+#define BLEND_CONT BLEND_START
+#define BLEND_OUT(acc) asm volatile("movclr.l %%acc0, %0" : "=d" (acc))
+#else
+#define BLEND_INIT do {} while (0)
+#define BLEND_START(acc, color, alpha) ((acc) = (color) * (alpha))
+#define BLEND_CONT(acc, color, alpha) ((acc) += (color) * (alpha))
+#define BLEND_OUT(acc) do {} while (0)
+#endif
+
+/* Blend the given two colors */
+static inline unsigned blend_two_colors(unsigned c1, unsigned c2, unsigned a)
+{
+    a += a >> (ALPHA_COLOR_LOOKUP_SHIFT - 1);
+#if (LCD_PIXELFORMAT == RGB565SWAPPED)
+    c1 = swap16(c1);
+    c2 = swap16(c2);
+#endif
+    unsigned c1l = (c1 | (c1 << 16)) & 0x07e0f81f;
+    unsigned c2l = (c2 | (c2 << 16)) & 0x07e0f81f;
+    unsigned p;
+    BLEND_START(p, c1l, a);
+    BLEND_CONT(p, c2l, ALPHA_COLOR_LOOKUP_SIZE + 1 - a);
+    BLEND_OUT(p);
+    p = (p >> ALPHA_COLOR_LOOKUP_SHIFT) & 0x07e0f81f;
+    p |= (p >> 16);
+#if (LCD_PIXELFORMAT == RGB565SWAPPED)
+    return swap16(p);
+#else
+    return p;
+#endif
+}
+
+static void draw_oriented_alpha_bitmap_part(const unsigned char *src,
+                                            int src_x, int src_y,
+                                            int stride, int x, int y,
+                                            int width, int height)
+{
+    fb_data *dst, *dst_start;
+    unsigned fg_pattern, bg_pattern;
+
+    if (x + width > SCREEN_WIDTH)
+        width = SCREEN_WIDTH - x; /* Clip right */
+    if (x < 0)
+        width += x, x = 0; /* Clip left */
+    if (width <= 0)
+        return; /* nothing left to do */
+
+    if (y + height > SCREEN_HEIGHT)
+        height = SCREEN_HEIGHT - y; /* Clip bottom */
+    if (y < 0)
+        height += y, y = 0; /* Clip top */
+    if (height <= 0)
+        return; /* nothing left to do */
+
+    /* initialize blending */
+    BLEND_INIT;
+
+    fg_pattern = rb->lcd_get_foreground();
+    bg_pattern = rb->lcd_get_background();
+
+    dst_start = rb->lcd_framebuffer + (LCD_WIDTH - y - 1) + x*LCD_WIDTH;
+    int col, row = height;
+    unsigned data, pixels;
+    unsigned skip_end = (stride - width);
+    unsigned skip_start = src_y * stride + src_x;
+
+#ifdef ALPHA_BITMAP_READ_WORDS
+    uint32_t *src_w = (uint32_t *)((uintptr_t)src & ~3);
+    skip_start += ALPHA_COLOR_PIXEL_PER_BYTE * ((uintptr_t)src & 3);
+    src_w += skip_start / ALPHA_COLOR_PIXEL_PER_WORD;
+    data = letoh32(*src_w++);
+#else
+    src += skip_start / ALPHA_COLOR_PIXEL_PER_BYTE;
+    data = *src;
+#endif
+    pixels = skip_start % ALPHA_COLOR_PIXEL_PER_WORD;
+    data >>= pixels * ALPHA_COLOR_LOOKUP_SHIFT;
+#ifdef ALPHA_BITMAP_READ_WORDS
+    pixels = 8 - pixels;
+#endif
+
+    do
+    {
+        col = width;
+        dst = dst_start--;
+#ifdef ALPHA_BITMAP_READ_WORDS
+#define UPDATE_SRC_ALPHA    do { \
+            if (--pixels) \
+                data >>= ALPHA_COLOR_LOOKUP_SHIFT; \
+            else \
+            { \
+                data = letoh32(*src_w++); \
+                pixels = ALPHA_COLOR_PIXEL_PER_WORD; \
+            } \
+        } while (0)
+#elif ALPHA_COLOR_PIXEL_PER_BYTE == 2
+#define UPDATE_SRC_ALPHA    do { \
+            if (pixels ^= 1) \
+                data >>= ALPHA_COLOR_LOOKUP_SHIFT; \
+            else \
+                data = *(++src); \
+        } while (0)
+#else
+#define UPDATE_SRC_ALPHA    do { \
+            if (pixels = (++pixels % ALPHA_COLOR_PIXEL_PER_BYTE)) \
+                data >>= ALPHA_COLOR_LOOKUP_SHIFT; \
+            else \
+                data = *(++src); \
+        } while (0)
+#endif
+        do
+        {
+            *dst=blend_two_colors(*dst, fg_pattern,
+                        data & ALPHA_COLOR_LOOKUP_SIZE );
+            dst += LCD_WIDTH;
+            UPDATE_SRC_ALPHA;
+        }
+        while (--col);
+#ifdef ALPHA_BITMAP_READ_WORDS
+        if (skip_end < pixels)
+        {
+            pixels -= skip_end;
+            data >>= skip_end * ALPHA_COLOR_LOOKUP_SHIFT;
+        } else {
+            pixels = skip_end - pixels;
+            src_w += pixels / ALPHA_COLOR_PIXEL_PER_WORD;
+            pixels %= ALPHA_COLOR_PIXEL_PER_WORD;
+            data = letoh32(*src_w++);
+            data >>= pixels * ALPHA_COLOR_LOOKUP_SHIFT;
+            pixels = 8 - pixels;
+        }
+#else
+        if (skip_end)
+        {
+            pixels += skip_end;
+            if (pixels >= ALPHA_COLOR_PIXEL_PER_BYTE)
+            {
+                src += pixels / ALPHA_COLOR_PIXEL_PER_BYTE;
+                pixels %= ALPHA_COLOR_PIXEL_PER_BYTE;
+                data = *src;
+                data >>= pixels * ALPHA_COLOR_LOOKUP_SHIFT;
+            } else
+                data >>= skip_end * ALPHA_COLOR_LOOKUP_SHIFT;
+        }
+#endif
+    } while (--row);
+}
+
 static void draw_putsxy_oriented(int x, int y, const char *str)
 {
     unsigned short ch;
@@ -643,8 +809,12 @@
 
         bits = rb->font_get_bits(pf, ch);
 
-        draw_oriented_mono_bitmap_part(bits, ofs, 0, width, x, y,
-                                       width - ofs, pf->height);
+        if (pf->depth)
+            draw_oriented_alpha_bitmap_part(bits, ofs, 0, width, x, y,
+                                            width - ofs, pf->height);
+        else
+            draw_oriented_mono_bitmap_part(bits, ofs, 0, width, x, y,
+                                           width - ofs, pf->height);
 
         x += width - ofs;
         ofs = 0;
Index: firmware/export/font.h
===================================================================
--- firmware/export/font.h	(revision 27911)
+++ firmware/export/font.h	(working copy)
@@ -68,7 +68,7 @@
  * USHORT maxwidth               2   font max width in pixels
  * USHORT height                 2   font height in pixels
  * USHORT ascent                 2   font ascent (baseline) in pixels
- * USHORT pad                    2   unused, pad to 32-bit boundary
+ * USHORT depth                  2   depth of the font, 0=1bit and 1=4bit
  * ULONG firstchar               4   first character code in font
  * ULONG defaultchar             4   default character code in font
  * ULONG size                    4   # characters in font
@@ -92,6 +92,7 @@
     int          ascent;          /* ascent (baseline) height*/
     int          firstchar;       /* first character in bitmap*/
     int          size;            /* font size in glyphs*/
+    int          depth;           /* depth of the font, 0=1bit and 1=4bit */
     const unsigned char *bits;    /* 8-bit column bitmap data*/
     const void *offset;           /* offsets into bitmap data,
                                      uint16_t if bits_size < 0xFFDB else uint32_t*/
Index: firmware/font.c
===================================================================
--- firmware/font.c	(revision 27911)
+++ firmware/font.c	(working copy)
@@ -88,7 +88,7 @@
 
 
 /* Font cache structures */
-static void cache_create(struct font* pf, int maxwidth, int height);
+static void cache_create(struct font* pf);
 static void glyph_cache_load(struct font* pf);
 /* End Font cache structures */
 
@@ -131,6 +131,13 @@
     return l;
 }
 
+static int glyph_bytes( struct font *pf, int width )
+{
+    return pf->depth ?
+        (pf->height * width + 1) / 2:
+        width * ((pf->height + 7) / 8);
+}
+
 void font_reset(struct font *pf)
 {
     unsigned char* buffer = NULL;
@@ -167,7 +174,7 @@
     pf->maxwidth = readshort(pf);
     pf->height = readshort(pf);
     pf->ascent = readshort(pf);
-    pf->buffer_position += 2; /* Skip padding */
+    pf->depth = readshort(pf);
     pf->firstchar = readlong(pf);
     pf->defaultchar = readlong(pf);
     pf->size = readlong(pf);
@@ -307,7 +314,7 @@
     pf->buffer_position = oldfileptr;
 
     /* Create the cache */
-    cache_create(pf, pf->maxwidth, pf->height);
+    cache_create(pf);
 
     return pf;
 }
@@ -435,7 +442,8 @@
     {
         /* currently, font loading replaces earlier font allocation*/
         buffer = (unsigned char *)(((intptr_t)main_buf + 3) & ~3);
-        buffer_size = MAX_FONT_SIZE;
+        /* make sure above doesn't exceed */
+        buffer_size = MAX_FONT_SIZE-3; 
     }
     else
     {
@@ -515,24 +523,23 @@
     }
     else
     {
-        bitmap_offset = ((pf->height + 7) / 8) * p->width * char_code;
+        bitmap_offset = char_code * glyph_bytes(pf, p->width);
     }
 
     int32_t file_offset = FONT_HEADER_SIZE + bitmap_offset;
     lseek(pf->fd, file_offset, SEEK_SET);
-
-    int src_bytes = p->width * ((pf->height + 7) / 8);
+    int src_bytes = glyph_bytes(pf, p->width);
     read(pf->fd, p->bitmap, src_bytes);
 }
 
 /*
  * Converts cbuf into a font cache
  */
-static void cache_create(struct font* pf, int maxwidth, int height)
+static void cache_create(struct font* pf)
 {
     /* maximum size of rotated bitmap */
-    int bitmap_size = maxwidth * ((height + 7) / 8);
-    
+    int bitmap_size = glyph_bytes( pf, pf->maxwidth);
+  
     /* Initialise cache */
     font_cache_create(&pf->cache, pf->buffer_start, pf->buffer_size, bitmap_size);
 }
@@ -577,7 +584,7 @@
                 bits += ((uint32_t*)(pf->offset))[char_code];
         }
         else
-            bits += ((pf->height + 7) / 8) * pf->maxwidth * char_code;
+            bits += char_code * glyph_bytes(pf, pf->maxwidth);
     }
 
     return bits;
@@ -658,7 +665,7 @@
     
     bufsize = LRU_SLOT_OVERHEAD + sizeof(struct font_cache_entry) + 
         sizeof( unsigned short);
-    bufsize += f.maxwidth * ((f.height + 7) / 8);
+    bufsize += glyph_bytes(&f, f.maxwidth);
     bufsize *= glyphs;
     if ( bufsize < FONT_HEADER_SIZE )
         bufsize = FONT_HEADER_SIZE;
Index: firmware/drivers/lcd-bitmap-common.c
===================================================================
--- firmware/drivers/lcd-bitmap-common.c	(revision 27911)
+++ firmware/drivers/lcd-bitmap-common.c	(working copy)
@@ -187,9 +187,15 @@
         }
 
         bits = font_get_bits(pf, *ucs);
-        LCDFN(mono_bitmap_part)(bits, ofs, 0, width, x + base_ofs, y,
-                width - ofs, pf->height);
 
+#if defined(MAIN_LCD) && defined(HAVE_LCD_COLOR)
+        if (pf->depth)
+            lcd_alpha_bitmap_part(bits, ofs, 0, width, x + base_ofs, y,
+                                  width - ofs, pf->height);
+        else
+#endif
+            LCDFN(mono_bitmap_part)(bits, ofs, 0, width, x + base_ofs,
+                                    y, width - ofs, pf->height);
         if (is_diac)
         {
             current_vp->drawmode = drawmode;
Index: firmware/drivers/lcd-16bit.c
===================================================================
--- firmware/drivers/lcd-16bit.c	(revision 27911)
+++ firmware/drivers/lcd-16bit.c	(working copy)
@@ -901,6 +901,258 @@
     lcd_mono_bitmap_part(src, 0, 0, width, x, y, width, height);
 }
 
+/* draw alpha bitmap for anti-alias font */
+#define ALPHA_COLOR_FONT_DEPTH 2
+#define ALPHA_COLOR_LOOKUP_SHIFT (1 << ALPHA_COLOR_FONT_DEPTH)
+#define ALPHA_COLOR_LOOKUP_SIZE ((1 << ALPHA_COLOR_LOOKUP_SHIFT) - 1)
+#define ALPHA_COLOR_PIXEL_PER_BYTE (8 >> ALPHA_COLOR_FONT_DEPTH)
+#define ALPHA_COLOR_PIXEL_PER_WORD (32 >> ALPHA_COLOR_FONT_DEPTH)
+#ifdef CPU_ARM
+#define BLEND_INIT do {} while (0)
+#define BLEND_START(acc, color, alpha) \
+    asm volatile("mul %0, %1, %2" : "=&r" (acc) : "r" (color), "r" (alpha))
+#define BLEND_CONT(acc, color, alpha) \
+    asm volatile("mla %0, %1, %2, %0" : "+&r" (acc) : "r" (color), "r" (alpha))
+#define BLEND_OUT(acc) do {} while (0)
+#elif defined(CPU_COLDFIRE)
+#define ALPHA_BITMAP_READ_WORDS
+#define BLEND_INIT coldfire_set_macsr(EMAC_UNSIGNED)
+#define BLEND_START(acc, color, alpha) \
+    asm volatile("mac.l %0, %1, %%acc0" :: "%d" (color), "d" (alpha))
+#define BLEND_CONT BLEND_START
+#define BLEND_OUT(acc) asm volatile("movclr.l %%acc0, %0" : "=d" (acc))
+#else
+#define BLEND_INIT do {} while (0)
+#define BLEND_START(acc, color, alpha) ((acc) = (color) * (alpha))
+#define BLEND_CONT(acc, color, alpha) ((acc) += (color) * (alpha))
+#define BLEND_OUT(acc) do {} while (0)
+#endif
+
+/* Blend the given two colors */
+static inline unsigned blend_two_colors(unsigned c1, unsigned c2, unsigned a)
+{
+    a += a >> (ALPHA_COLOR_LOOKUP_SHIFT - 1);
+#if (LCD_PIXELFORMAT == RGB565SWAPPED)
+    c1 = swap16(c1);
+    c2 = swap16(c2);
+#endif
+    unsigned c1l = (c1 | (c1 << 16)) & 0x07e0f81f;
+    unsigned c2l = (c2 | (c2 << 16)) & 0x07e0f81f;
+    unsigned p;
+    BLEND_START(p, c1l, a);
+    BLEND_CONT(p, c2l, ALPHA_COLOR_LOOKUP_SIZE + 1 - a);
+    BLEND_OUT(p);
+    p = (p >> ALPHA_COLOR_LOOKUP_SHIFT) & 0x07e0f81f;
+    p |= (p >> 16);
+#if (LCD_PIXELFORMAT == RGB565SWAPPED)
+    return swap16(p);
+#else
+    return p;
+#endif
+}
+
+/* Blend the given color with the value from the alpha_color_lookup table */
+static inline unsigned blend_color(unsigned c, unsigned a)
+{
+    return blend_two_colors(c, current_vp->fg_pattern, a);
+}
+
+void ICODE_ATTR lcd_alpha_bitmap_part(const unsigned char *src, int src_x,
+                                      int src_y, int stride, int x, int y,
+                                      int width, int height)
+{
+    fb_data *dst, *backdrop;
+    unsigned dmask = 0x00000000;
+    int drmode = current_vp->drawmode;
+    /* nothing to draw? */
+    if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
+         (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+        return;
+    /* initialize blending */
+    BLEND_INIT;
+
+    /* clipping */
+    if (x < 0)
+    {
+        width += x;
+        src_x -= x;
+        x = 0;
+    }
+    if (y < 0)
+    {
+        height += y;
+        src_y -= y;
+        y = 0;
+    }
+    if (x + width > current_vp->width)
+        width = current_vp->width - x;
+    if (y + height > current_vp->height)
+        height = current_vp->height - y;
+
+    if (drmode & DRMODE_INVERSEVID)
+    {
+        dmask = 0xffffffff;
+        drmode &= DRMODE_SOLID; /* mask out inversevid */
+    }
+    if (drmode == DRMODE_BG)
+    {
+        dmask = ~dmask;
+    }
+
+    dst = LCDADDR(current_vp->x + x, current_vp->y + y);
+
+    int col, row = height;
+    unsigned data, pixels;
+    unsigned skip_end = (stride - width);
+    unsigned skip_start = src_y * stride + src_x;
+
+#ifdef ALPHA_BITMAP_READ_WORDS
+    uint32_t *src_w = (uint32_t *)((uintptr_t)src & ~3);
+    skip_start += ALPHA_COLOR_PIXEL_PER_BYTE * ((uintptr_t)src & 3);
+    src_w += skip_start / ALPHA_COLOR_PIXEL_PER_WORD;
+    data = letoh32(*src_w++) ^ dmask;
+    pixels = skip_start % ALPHA_COLOR_PIXEL_PER_WORD;
+#else
+    src += skip_start / ALPHA_COLOR_PIXEL_PER_BYTE;
+    data = *src ^ dmask;
+    pixels = skip_start % ALPHA_COLOR_PIXEL_PER_BYTE;
+#endif
+    data >>= pixels * ALPHA_COLOR_LOOKUP_SHIFT;
+#ifdef ALPHA_BITMAP_READ_WORDS
+    pixels = 8 - pixels;
+#endif
+
+    do
+    {
+        col = width;
+#ifdef ALPHA_BITMAP_READ_WORDS
+#define UPDATE_SRC_ALPHA    do { \
+            if (--pixels) \
+                data >>= ALPHA_COLOR_LOOKUP_SHIFT; \
+            else \
+            { \
+                data = letoh32(*src_w++) ^ dmask; \
+                pixels = ALPHA_COLOR_PIXEL_PER_WORD; \
+            } \
+        } while (0)
+#elif ALPHA_COLOR_PIXEL_PER_BYTE == 2
+#define UPDATE_SRC_ALPHA    do { \
+            if (pixels ^= 1) \
+                data >>= ALPHA_COLOR_LOOKUP_SHIFT; \
+            else \
+                data = *(++src) ^ dmask; \
+        } while (0)
+#else
+#define UPDATE_SRC_ALPHA    do { \
+            if (pixels = (++pixels % ALPHA_COLOR_PIXEL_PER_BYTE)) \
+                data >>= ALPHA_COLOR_LOOKUP_SHIFT; \
+            else \
+                data = *(++src) ^ dmask; \
+        } while (0)
+#endif
+        /* we don't want to have this in our inner
+         * loop and the codesize increase is minimal */
+        switch (drmode)
+        {
+            case DRMODE_COMPLEMENT:
+                do
+                {
+                    *dst=blend_two_colors(*dst, ~(*dst),
+                                data & ALPHA_COLOR_LOOKUP_SIZE );
+                    dst++;
+                    UPDATE_SRC_ALPHA;
+                }
+                while (--col);
+                break;
+            case DRMODE_BG:
+                if(lcd_backdrop)
+                {
+                    backdrop = (fb_data *)((long)dst+lcd_backdrop_offset);
+                    do
+                    {
+                        *dst=blend_two_colors(*dst, *(backdrop++),
+                                    data & ALPHA_COLOR_LOOKUP_SIZE );
+                        dst++;
+                        UPDATE_SRC_ALPHA;
+                    }
+                    while (--col);
+                }
+                else
+                {
+                    do
+                    {
+                        *dst=blend_two_colors(*dst, current_vp->bg_pattern,
+                                    data & ALPHA_COLOR_LOOKUP_SIZE );
+                        dst++;
+                        UPDATE_SRC_ALPHA;
+                    }
+                    while (--col);
+                }
+                break;
+            case DRMODE_FG:
+                do
+                {
+                    *dst=blend_color(*dst, data & ALPHA_COLOR_LOOKUP_SIZE );
+                    dst++;
+                    UPDATE_SRC_ALPHA;
+                }
+                while (--col);
+                break;
+            case DRMODE_SOLID:
+                if(lcd_backdrop)
+                {
+                    backdrop = (fb_data *)((long)dst+lcd_backdrop_offset);
+                    do
+                    {
+                        *(dst++)=blend_color(*(backdrop++),
+                                        data & ALPHA_COLOR_LOOKUP_SIZE );
+                        UPDATE_SRC_ALPHA;
+                    }
+                    while (--col);
+                }
+                else
+                {
+                    do
+                    {
+                        *(dst++)=blend_color(current_vp->bg_pattern,
+                                        data & ALPHA_COLOR_LOOKUP_SIZE );
+                        UPDATE_SRC_ALPHA;
+                    }
+                    while (--col);
+                }
+                break;
+        }
+#ifdef ALPHA_BITMAP_READ_WORDS
+        if (skip_end < pixels)
+        {
+            pixels -= skip_end;
+            data >>= skip_end * ALPHA_COLOR_LOOKUP_SHIFT;
+        } else {
+            pixels = skip_end - pixels;
+            src_w += pixels / ALPHA_COLOR_PIXEL_PER_WORD;
+            pixels %= ALPHA_COLOR_PIXEL_PER_WORD;
+            data = letoh32(*src_w++) ^ dmask;
+            data >>= pixels * ALPHA_COLOR_LOOKUP_SHIFT;
+            pixels = 8 - pixels;
+        }
+#else
+        if (skip_end)
+        {
+            pixels += skip_end;
+            if (pixels >= ALPHA_COLOR_PIXEL_PER_BYTE)
+            {
+                src += pixels / ALPHA_COLOR_PIXEL_PER_BYTE;
+                pixels %= ALPHA_COLOR_PIXEL_PER_BYTE;
+                data = *src ^ dmask;
+                data >>= pixels * ALPHA_COLOR_LOOKUP_SHIFT;
+            } else
+                data >>= skip_end * ALPHA_COLOR_LOOKUP_SHIFT;
+        }
+#endif
+        dst += LCD_WIDTH - width;
+    } while (--row);
+}
+
 /* Draw a partial native bitmap */
 void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
                                 int stride, int x, int y, int width,
