Index: tools/convbdf.c
===================================================================
--- tools/convbdf.c	(revision 27631)
+++ 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/convttf.c
===================================================================
--- tools/convttf.c	(revision 0)
+++ tools/convttf.c	(revision 0)
@@ -0,0 +1,1046 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2007 Jonas Hurrelmann
+ *
+ * A command-line tool to convert ttf file to bitmap fonts
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#define BITMAP_WORDS(x)         (((x)+15)/16)   /* image size in words*/
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_GLYPH_H
+
+#include <stdio.h>
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <stdlib.h>
+#include <unistd.h>
+#endif
+#include FT_SFNT_NAMES_H
+#include FT_TRUETYPE_TABLES_H
+
+#include <string.h>
+/*
+ * Set the default values used to generate a BDF font.
+ */
+#ifndef DEFAULT_PLATFORM_ID
+#define DEFAULT_PLATFORM_ID 3
+#endif
+
+#ifndef DEFAULT_ENCODING_ID
+#define DEFAULT_ENCODING_ID 1
+#endif
+
+/*
+ * nameID macros for getting strings from the OT font.
+ */
+enum {
+    BDFOTF_COPYRIGHT_STRING = 0,
+    BDFOTF_FAMILY_STRING,
+    BDFOTF_SUBFAMILY_STRING,
+    BDFOTF_UNIQUEID_STRING,
+    BDFOTF_FULLNAME_STRING,
+    BDFOTF_VENDOR_STRING,
+    BDFOTF_POSTSCRIPT_STRING,
+    BDFOTF_TRADEMARK_STRING,
+};
+/*
+ * String names for the string indexes. Used for error messages.
+ */
+static char *string_names[] = {
+    "\"Copyright\"",
+    "\"Family\"",
+    "\"SubFamily\"",
+    "\"Unique ID\"",
+    "\"Full Name\"",
+    "\"Vendor\"",
+    "\"Postscript Name\"",
+    "\"Trademark\""
+};
+
+
+/*
+ * The default platform and encoding ID's.
+ */
+static int pid = DEFAULT_PLATFORM_ID;
+static int eid = DEFAULT_ENCODING_ID;
+
+
+/*
+ * A flag indicating if a CMap was found or not.
+ */
+static FT_UShort nocmap;
+
+int pct                     = 0; /* display ttc table if it is not zero. */
+unsigned long   max_char    = 65535;
+int             pixel_size  = 15;
+unsigned long   start_char  = 0;
+unsigned long   limit_char; 
+unsigned long   firstchar   = 0;
+unsigned long   lastchar;
+FT_Long         ttc_index   = -1;
+int             flg_all_ttc = 0;
+const int       depth       = 2;
+short           antialias   = 1; /* smooth fonts with gray levels  */
+int             oflag       = 0;
+char            outfile[1024];
+int             between_chr = 0;
+int             between_row = 0;
+
+struct font_header_struct {
+    char header[4];                 /* magic number and version bytes */
+    unsigned short maxwidth;        /* max width in pixels */
+    unsigned short height;          /* height in pixels */
+    unsigned short ascent;          /* ascent (baseline) height */
+    unsigned short depth;           /* depth 0=1-bit, 1=4-bit */
+    unsigned long firstchar;        /* first character in font */
+    unsigned long defaultchar;      /* default character in font */
+    unsigned long size;             /* # characters in font */
+    unsigned long nbits;            /* # bytes imagebits data in file */ /* = bits_size */
+
+    FT_Long noffset;          /* # longs offset data in file */
+    FT_Long nwidth;           /* # bytes width data in file */
+};
+
+struct font_struct {
+    struct font_header_struct header;
+    unsigned char *chars_data;
+    unsigned short *offset;
+    FT_Long *offset_long;
+    unsigned char *width;
+};
+
+struct ttc_table{
+    FT_Long     ttc_count;
+    char        **ttf_name;
+};
+/* exit the program with given message */
+static void
+panic( const char*  message )
+{
+    fprintf( stderr, "%s\n", message );
+    exit( 1 );
+}
+
+/* print usage information */
+void usage(void)
+{
+    char help[] = {
+        "Usage: convttf [options] [input-files]\n"
+        "       convttf [options] [-o output-file] [single-input-file]\n\n"
+        "       Default output-file : 'input-files name removed extension'_'font-size'_['depth'].fnt.\n"
+        "                              When '-ta' or '-tc' is specified in command line,\n "
+        "                               default output-file is \n"
+        "                             'internal postscript-name of input-file'_'font-size'_['depth'].fnt.\n" 
+        "Options:\n"
+        "    -s N   Start output at character encodings >= N\n"
+        "    -l N   Limit output to character encodings <= N\n"
+        "    -p N   Font size N in pixel (default N=15)\n"
+        "    -c N   Character separation in pixel.Insert space between lines.\n"
+        "    -r N   Row separation in pixel.Insert space between characters\n"
+        "    -tt    Display the True Type Collection tables available in the font\n"
+        "    -t N   Index of true type collection. It must be start from 0.(default N=0).\n"
+        "    -ta    Convert all fonts in ttc\n"
+        "           \"-o output-file\" specified is ignored when \"-ta\" is specified.\n"
+    };
+    fprintf(stderr, help);
+    exit( 1 );
+}
+
+/* remove directory prefix and file suffix from full path*/
+char *basename(char *path)
+{
+    char *p, *b;
+    static char base[256];
+
+    /* remove prepended path and extension*/
+    b = path;
+    for (p=path; *p; ++p) {
+        if (*p == '/')
+            b = p + 1;
+    }
+    strcpy(base, b);
+    for (p=base; *p; ++p) {
+        if (*p == '.') {
+            *p = 0;
+            break;
+        }
+    }
+    return base;
+}
+
+
+void setcharmap(FT_Face face)
+{
+    FT_Long i;
+
+    /*
+     * Get the requested cmap.
+     */
+    for (i = 0; i < face->num_charmaps; i++) {
+        if (face->charmaps[i]->platform_id == pid &&
+            face->charmaps[i]->encoding_id == eid)
+          break;
+    }
+
+    if (i == face->num_charmaps && pid == 3 && eid == 1) {
+        /*
+         * Make a special case when this fails with pid == 3 and eid == 1.
+         * Change to eid == 0 and try again.  This captures the two possible
+         * cases for MS fonts.  Some other method should be used to cycle
+         * through all the alternatives later.
+         */
+        for (i = 0; i < face->num_charmaps; i++) {
+        if (face->charmaps[i]->platform_id == pid &&
+            face->charmaps[i]->encoding_id == 0)
+              break;
+        }
+        if (i < face->num_charmaps) {
+            pid = 3;
+            eid = 1;
+            FT_Set_Charmap(face, face->charmaps[i]);
+        } else {
+            /*
+             * No CMAP was found.
+             */
+            nocmap = 1;
+            pid = eid = -1;
+        }
+    } else {
+        FT_Set_Charmap(face, face->charmaps[i]);
+        nocmap = 0;
+    }
+
+}
+
+/*
+ * quote in otf2bdf.
+ * A generic routine to get a name from the OT name table.  This routine
+ * always looks for English language names and checks three possibilities:
+ * 1. English names with the MS Unicode encoding ID.
+ * 2. English names with the MS unknown encoding ID.
+ * 3. English names with the Apple Unicode encoding ID.
+ *
+ * The particular name ID mut be provided (e.g. nameID = 0 for copyright
+ * string, nameID = 6 for Postscript name, nameID = 1 for typeface name.
+ *
+ * If the `dash_to_space' flag is non-zero, all dashes (-) in the name will be
+ * replaced with the character passed.
+ *
+ * Returns the number of bytes added.
+ */
+static int
+otf_get_english_string(FT_Face face, int nameID, int dash_to_space,
+                       char *name, int name_size)
+{
+
+    int j, encid;
+    FT_UInt i, nrec;
+    FT_SfntName sfntName;
+    unsigned char *s;
+    unsigned short slen;
+
+    nrec = FT_Get_Sfnt_Name_Count(face);
+
+    for (encid = 1, j = 0; j < 2; j++, encid--) {
+        /*
+         * Locate one of the MS English font names.
+         */
+        for (i = 0; i < nrec; i++) {
+           FT_Get_Sfnt_Name(face, i, &sfntName);
+           if (sfntName.platform_id == 3 &&
+               sfntName.encoding_id == encid &&
+               sfntName.name_id == nameID &&
+               (sfntName.language_id == 0x0409 ||
+                sfntName.language_id == 0x0809 ||
+                sfntName.language_id == 0x0c09 ||
+                sfntName.language_id == 0x1009 ||
+                sfntName.language_id == 0x1409 ||
+                sfntName.language_id == 0x1809)) {
+               s = sfntName.string;
+               slen = sfntName.string_len;
+               break;
+           }
+        }
+
+        if (i < nrec) {
+            if (slen >> 1 >= name_size) {
+                fprintf(stderr, "warning: %s string longer than buffer. Truncating to %d bytes.\n", string_names[nameID], name_size);
+                slen = name_size << 1;
+            }
+
+            /*
+             * Found one of the MS English font names.  The name is by
+             * definition encoded in Unicode, so copy every second byte into
+             * the `name' parameter, assuming there is enough space.
+             */
+            for (i = 1; i < slen; i += 2) {
+                if (dash_to_space)
+                  *name++ = (s[i] != '-') ? s[i] : ' ';
+                else if (s[i] == '\r' || s[i] == '\n') {
+                    if (s[i] == '\r' && i + 2 < slen && s[i + 2] == '\n')
+                      i += 2;
+                    *name++ = ' ';
+                    *name++ = ' ';
+                } else
+                  *name++ = s[i];
+            }
+            *name = 0;
+            return (slen >> 1);
+        }
+    }
+
+    /*
+     * No MS English name found, attempt to find an Apple Unicode English
+     * name.
+     */
+    for (i = 0; i < nrec; i++) {
+        FT_Get_Sfnt_Name(face, i, &sfntName);
+        if (sfntName.platform_id == 0 && sfntName.language_id == 0 &&
+            sfntName.name_id == nameID) {
+            s = sfntName.string;
+            slen = sfntName.string_len;
+            break;
+        }
+    }
+
+    if (i < nrec) {
+        if (slen >> 1 >= name_size) {
+            fprintf(stderr, "warning: %s string longer than buffer. Truncating to %d bytes.\n", string_names[nameID], name_size);
+            slen = name_size << 1;
+        }
+
+        /*
+         * Found the Apple Unicode English name.  The name is by definition
+         * encoded in Unicode, so copy every second byte into the `name'
+         * parameter, assuming there is enough space.
+         */
+        for (i = 1; i < slen; i += 2) {
+            if (dash_to_space)
+              *name++ = (s[i] != '-') ? s[i] : ' ';
+            else if (s[i] == '\r' || s[i] == '\n') {
+                if (s[i] == '\r' && i + 2 < slen && s[i + 2] == '\n')
+                  i += 2;
+                *name++ = ' ';
+                *name++ = ' ';
+            } else
+              *name++ = s[i];
+        }
+        *name = 0;
+        return (slen >> 1);
+    }
+
+    return 0;
+}
+
+
+int get_ttc_table(char *path, struct ttc_table *ttcname )
+{
+
+
+    FT_Error    error;
+    FT_Library  library;
+    FT_Face     face;
+    FT_Long     i;
+    char        xlfd[BUFSIZ];
+
+    /* init number of ttf in ttc */
+    ttcname->ttc_count = 0;
+
+    /* Initialize engine */
+    if ( ( error = FT_Init_FreeType( &library ) ) != 0 ) 
+    {
+        panic( "Error while initializing engine" );
+        return error;
+    }
+
+
+    /* Load face */
+    error = FT_New_Face( library, path, (FT_Long) 0, &face );
+    if ( error == FT_Err_Cannot_Open_Stream )
+    {
+        panic( "Could not find/open font resource" );
+        return error;
+    }
+
+    ttcname->ttc_count = face->num_faces;
+    ttcname->ttf_name = malloc( sizeof(char*) * ttcname->ttc_count);
+
+    for(i = 0; i < ttcname->ttc_count; i++)
+    {
+        error = FT_New_Face( library, path, i, &face );
+        if ( error == FT_Err_Cannot_Open_Stream )
+            panic( "Could not find/open font resource\n" );
+        otf_get_english_string(face, BDFOTF_POSTSCRIPT_STRING, 0, xlfd,
+                                  sizeof(xlfd));
+        ttcname->ttf_name[i] = malloc(sizeof(char) * (strlen(xlfd) + 1 ));
+        strcpy(ttcname->ttf_name[i], xlfd);
+    }
+    return 0;
+}
+
+void print_ttc_table(char* path)
+{
+    struct ttc_table ttcname;
+    FT_Long     i;
+
+    get_ttc_table(path, &ttcname);
+    printf("ttc header count = %ld \n\n", ttcname.ttc_count);
+    printf("Encoding tables available in the true type collection\n\n");
+    printf("INDEX\tPOSTSCRIPT NAME\n");
+    printf("-----------------------------------------------------\n");
+    for(i = 0; i < ttcname.ttc_count; i++)
+    {
+        printf("%ld\t%s\n", i, ttcname.ttf_name[i]);
+    }
+    for(i = 0; i < ttcname.ttc_count; i++)
+    {
+        free(ttcname.ttf_name[i]);
+    }
+    printf("\n\n");
+    free(ttcname.ttf_name);
+
+    return;
+}
+
+FT_Long getcharindex(FT_Face face, FT_Long code)
+{
+    FT_Long idx;
+    if (nocmap) {
+        if (code >= face->num_glyphs)
+            idx = 0;
+        else
+            idx = code;
+    } else
+        idx = FT_Get_Char_Index( face, code);
+
+    if ( idx <= 0 || idx > face->num_glyphs)
+        return 0;
+    else
+        return idx;
+}
+
+void convttf(char* path, FT_Long face_index)
+{
+    FT_Error    error;
+    FT_Library  library;
+    FT_Face     face;
+    int         w,w1,h,w_half;
+    char        w_is_odd;
+    int         row,col;
+    FT_Long     charindex;
+    FT_Long     index = 0;
+    FT_Long     code;
+
+    unsigned char bit_shift = 1 << depth;
+    unsigned char pixel_per_byte = 8 >> depth;
+
+    /* Initialize engine */
+    if ( ( error = FT_Init_FreeType( &library ) ) != 0 )
+        panic( "Error while initializing engine" );
+
+    /* Load face */
+    error = FT_New_Face( library, path, (FT_Long) face_index, &face );
+    if ( error == FT_Err_Cannot_Open_Stream )
+        panic( "Could not find/open font resource" );
+    else if ( error )
+        panic( "Error while opening font resource" );
+
+
+    setcharmap( face );
+    /* create size */
+    error = FT_Set_Pixel_Sizes( face, pixel_size, pixel_size );
+    if ( error )
+        panic( "Could not reset instance" );
+
+    printf("Please wait, converting %s to %s:\n",path,outfile);
+
+    if ( limit_char == 0 ) limit_char = max_char; /* "face->num_glyphs" is NG.; */
+    if ( limit_char > max_char ) limit_char = max_char;
+
+    FT_Long char_count = 0;
+
+    /* Set font header data */
+    struct font_struct export_font;
+    export_font.header.header[0] = 'R';
+    export_font.header.header[1] = 'B';
+    export_font.header.header[2] = '1';
+    export_font.header.header[3] = '2';
+
+    export_font.header.maxwidth = face->size->metrics.max_advance >> 6;
+    export_font.header.height = ((face->size->metrics.ascender - face->size->metrics.descender + (2 << 6)) >> 6)
+                                + between_row;
+    export_font.header.ascent = face->size->metrics.ascender >> 6;
+    export_font.header.depth = depth;
+    firstchar = limit_char;
+    lastchar  = start_char;
+
+    /* calculate memory usage */
+    for(code = start_char; code <= limit_char ; code++ )
+    {
+        charindex = getcharindex( face, code);
+        if ( !(charindex) ) continue;
+        error = FT_Load_Glyph( face, charindex, (FT_LOAD_RENDER | FT_LOAD_NO_BITMAP) );
+        if ( error ) continue;
+
+
+        w = face->glyph->bitmap.pitch;
+        if (w == 0)
+            w = face->glyph->metrics.horiAdvance >> 6;
+        w1 = (face->glyph->metrics.width) >> 6;
+        if(w < w1) w = w1;
+        if (w == 0) continue;
+
+        int start_x = face->glyph->metrics.horiBearingX >> 6;
+        w += abs(start_x);
+        w += between_chr;
+
+        if (export_font.header.maxwidth < face->glyph->metrics.width >>6) 
+            export_font.header.maxwidth = face->glyph->metrics.width >>6;
+        char_count++;
+        h = export_font.header.height;
+        int numbits = pixel_per_byte;
+
+        /* we could use a closed form here */
+        for(row=0; row < h; row++)
+        {
+            for(col=0; col < w; col++)
+            {
+                if (--numbits == 0)
+                {
+                    numbits = pixel_per_byte;
+                    index++;
+                }
+            }
+        }
+        if (numbits != pixel_per_byte)
+            index++;
+
+        if (code >= lastchar)
+            lastchar = code;
+
+        if (code <= firstchar)
+            firstchar = code;
+    }
+    export_font.header.defaultchar = firstchar;
+    export_font.header.firstchar = firstchar;
+    export_font.header.size = lastchar - firstchar + 1;
+    export_font.header.nbits = index;
+    export_font.header.noffset = export_font.header.size;
+    export_font.header.nwidth  = export_font.header.size;
+
+    /* check if we need to use long offsets */
+    char long_offset = (export_font.header.nbits >= 0xFFDB );
+
+    /* allocate memory */
+    if (long_offset)
+        export_font.offset_long = malloc( sizeof(FT_Long)* export_font.header.noffset );
+    else
+        export_font.offset = malloc( sizeof(unsigned short)* export_font.header.noffset );
+
+    export_font.width = malloc( sizeof(unsigned char) * export_font.header.nwidth );
+    export_font.chars_data = malloc( sizeof(unsigned char) * export_font.header.nbits );
+    /* for now we use the full height for each character */
+    h = export_font.header.height;
+
+    index = 0;
+    int done = 0;
+    char char_name[1024];
+    int converted_char_count = 0;
+    int failed_char_count = 0;
+
+    for( code = firstchar; code <= lastchar; code++ )
+    {
+        /* Get gylph index from the char and render it */
+        charindex = getcharindex( face, code);
+        if ( !charindex ) 
+        {
+            if ( long_offset )
+                export_font.offset_long[code - firstchar] = export_font.offset_long[0];
+            else
+                export_font.offset[code - firstchar] = export_font.offset[0];
+            export_font.width[code - firstchar] = export_font.width[0];
+            continue;
+        }
+        error = FT_Load_Glyph( face, charindex , (FT_LOAD_RENDER | FT_LOAD_NO_BITMAP) );
+
+        if ( error ) {
+            continue;
+        }
+        if FT_HAS_GLYPH_NAMES( face )
+            FT_Get_Glyph_Name( face, charindex, char_name, 16);
+        else
+            char_name[0] = '\0';
+
+        FT_GlyphSlot slot = face->glyph;
+        FT_Glyph_Metrics glyph_metrics = slot->metrics;
+        FT_Bitmap* source = &slot->bitmap;
+
+        w = face->glyph->bitmap.pitch;
+        if (w == 0)
+            w = face->glyph->metrics.horiAdvance >> 6;
+        w1 = (face->glyph->metrics.width) >> 6;
+        if(w < w1) w = w1;
+        if (w == 0) continue;
+
+        int start_x = glyph_metrics.horiBearingX >> 6;
+        w += abs(start_x);
+        w += between_chr;
+
+        w_is_odd = ( w % 2 == 1 );
+        w_half = w_is_odd ? (w - 1) >> 1 : w >> 1;
+
+        if ( long_offset )
+            export_font.offset_long[code - firstchar] = index;
+        else
+            export_font.offset[code - firstchar] = index;
+
+        export_font.width[code - firstchar] = w;
+
+        /* copy the glyph bitmap to a full sized glyph bitmap */
+        unsigned char* src = source->buffer;
+        unsigned char* tmpbuf = malloc(sizeof(unsigned char) * w * h);
+        memset(tmpbuf, 0xff, w*h);
+        int start_y =  export_font.header.ascent - slot->bitmap_top;
+        int glyph_height = glyph_metrics.height  >> 6;
+        int glyph_width = glyph_metrics.width >>6;
+        unsigned char* buf = tmpbuf;
+        if ( start_y > 0 ) 
+            buf += w * start_y;
+
+        unsigned char* endbuf = tmpbuf + w*h;
+
+        for(row=0; row < glyph_height; row++) {
+            if ( row + start_y < 0 || row > h ) {
+                src += glyph_width;
+            }
+            else {
+                if (start_x > 0) buf += start_x;
+                for(col=0; col < glyph_width; col++) {
+                    /* if ( col + start_x < 0 ) { buf++; src++; } */
+                    if ( col <= w && buf < endbuf && buf >= tmpbuf ) (*buf++)= 0xff - ( *src++ );
+                    else src++;
+                }
+                if (start_x < 0 && col <= w) buf += w - col; /* almost same as start_x = w - col */
+            }
+        }
+
+        buf = tmpbuf;
+        int numbits;
+        unsigned int field;
+        field = 0;
+        numbits = pixel_per_byte;
+
+        for(row=0; row < h; row++) 
+        {
+            for(col=0; col < w; col++)
+            {
+                /* TODO: find a more sophisticated dithering than just using the upper bits */
+                unsigned int cur_col = *(buf) >> (8-bit_shift);
+                buf++;
+                field = field | (cur_col <<  (bit_shift*(pixel_per_byte-numbits)));
+                if (--numbits == 0)
+                {
+                    export_font.chars_data[index++] = (unsigned char)field;
+                    numbits = pixel_per_byte;
+                    field = 0;
+                }
+            }
+        }
+
+
+        /* Pad last byte */
+        if (numbits != pixel_per_byte)
+        {
+            export_font.chars_data[index++] = (unsigned char)field;
+        }
+
+#if 0
+        /* debug: dump char */
+        unsigned char bit_max = (1 << bit_shift) - 1;
+        if ( code > 32 && code < 255 ) {
+            row = h;
+            buf =  &(export_font.chars_data[export_font.offset_long[code - firstchar]]);
+            unsigned char current_data;
+            unsigned char font_bits;
+            numbits = pixel_per_byte;
+            current_data = *buf;
+            do
+            {
+                col =  w;
+                do
+                {
+                    font_bits = current_data & bit_max;
+                    if (font_bits==bit_max)
+                        printf(" ");
+                    else
+                        printf("%x",font_bits);
+                    if (--numbits == 0)
+                    {
+                        current_data = *(++buf);
+                        numbits = pixel_per_byte;
+                    }
+                    else
+                    {
+                        current_data >>= bit_shift;
+                    }
+                } while (--col);
+                printf("\n");
+            } while (--row);
+        }
+        buf = NULL;
+#endif 
+        free(tmpbuf);
+        converted_char_count++;
+        done = (100*(converted_char_count))/char_count;
+        printf("Converted %s %d (%d%%)\e[K\r",char_name,converted_char_count,done); fflush(stdout);
+    }
+
+    int n;
+    FILE *file = fopen(outfile, "w");
+    n = fwrite(&export_font.header, 1, sizeof(struct font_header_struct), file);
+    n = fwrite( (char*)export_font.chars_data, 1, export_font.header.nbits, file);
+
+    free(export_font.chars_data);
+    int skip;
+    char pad[] = {0,0,0,0};
+    if ( long_offset ) 
+    {
+        skip = ((export_font.header.nbits + 3) & ~3) - export_font.header.nbits;
+        n = fwrite(pad, 1, skip, file); /* pad */
+        n = fwrite( (char*)export_font.offset_long, 1, sizeof(FT_Long) * export_font.header.noffset, file );
+    }
+    else 
+    {
+        skip = ((export_font.header.nbits + 1) & ~1) - export_font.header.nbits;
+        n = fwrite(pad, 1, skip, file); /* pad */
+        n = fwrite( (char*)export_font.offset, 1, sizeof(unsigned short)*export_font.header.noffset, file );
+    }
+
+    n = fwrite((char*)export_font.width, 1, export_font.header.nwidth, file);
+    free(export_font.width);
+    if ( long_offset ) 
+        free(export_font.offset_long);
+    else 
+        free(export_font.offset);
+
+    fclose(file);
+    FT_Done_Face( face );
+    FT_Done_FreeType( library );
+    printf("done (converted %d glyphs, %d errors).\e[K\n\n",converted_char_count, failed_char_count);
+
+}
+
+void convttc(char* path)
+{
+    struct ttc_table ttcname;
+    FT_Long          i;
+    char ext_str[20];
+
+    get_ttc_table(path, &ttcname);
+
+    if (ttcname.ttc_count == 0) 
+    {
+        printf("This file is a not true type font.\n");
+        return;
+    }
+
+    /* defalut */
+    if (!flg_all_ttc &&
+        ttc_index    == -1) 
+    {
+        if (!oflag)
+        {
+            strcpy(outfile, basename(path));
+            sprintf(ext_str, "_%d.fnt", pixel_size);
+            strcat(outfile, ext_str);
+        }
+        convttf(path, (FT_Long) 0);
+    }
+
+    /* set face_index of ttc */
+    else if (!flg_all_ttc)
+    {
+        print_ttc_table(path);
+        if ( !oflag ) 
+        {
+            if (ttc_index >= 0 && 
+                ttc_index <  ttcname.ttc_count)
+            {
+                if (strcmp(ttcname.ttf_name[ttc_index], "") != 0) 
+                {
+                    strcpy(outfile, ttcname.ttf_name[ttc_index]);
+                    sprintf(ext_str, "_%d.fnt", pixel_size);
+                }
+                else
+                {
+                    strcpy(outfile, basename(path));
+                    sprintf(ext_str, "%ld_%d.fnt", ttc_index,pixel_size);
+                }
+
+                strcat(outfile, ext_str);
+            }
+            else
+            {
+                printf("illegal face index of ttc.\n");
+            }
+        }
+        convttf(path, ttc_index);
+    }
+    else { /* convert all fonts */
+        print_ttc_table(path);
+        for(i = 0; i < ttcname.ttc_count; i++)
+        {
+            strcpy(outfile, ttcname.ttf_name[i]);
+            sprintf(ext_str, "_%d.fnt", pixel_size);
+            strcat(outfile, ext_str);
+            convttf(path, i);
+        }
+    }
+
+    for(i = 0; i < ttcname.ttc_count; i++)
+    {
+        free(ttcname.ttf_name[i]);
+    }
+    free(ttcname.ttf_name);
+}
+
+
+
+/* parse command line options*/
+void getopts(int *pac, char ***pav)
+{
+    char *p;
+    char **av;
+    int ac;
+    ac = *pac;
+    av = *pav;
+
+    limit_char  = max_char;
+    start_char  = 0;
+
+    while (ac > 0 && av[0][0] == '-') {
+        p = &av[0][1]; 
+        while( *p)
+            switch(*p++) {
+            case 'h':case 'H':
+                usage();
+                break;
+            case ' ':           /* multiple -args on av[]*/
+                while( *p && *p == ' ')
+                    p++;
+                if( *p++ != '-')    /* next option must have dash*/
+                    p = "";
+                break;          /* proceed to next option*/
+            case 'o':case 'O':       /* set output file*/
+                oflag = 1;
+                if (*p) {
+                    strcpy(outfile, p);
+                    while (*p && *p != ' ')
+                        p++;
+                }
+                else {
+                    av++; ac--;
+                    if (ac > 0)
+                        strcpy(outfile, av[0]);
+                }
+                break;
+            case 'l':case 'L':       /* set encoding limit*/
+                if (*p) {
+                    limit_char = atoi(p);
+                    while (*p && *p != ' ')
+                        p++;
+                }
+                else {
+                    av++; ac--;
+                    if (ac > 0)
+                        limit_char = atoi(av[0]);
+                }
+                break;
+            case 's':case 'S':       /* set encoding start*/
+                if (*p) {
+                    start_char = atol(p);
+                    while (*p && *p != ' ')
+                        p++;
+                }
+                else {
+                    av++; ac--;
+                    if (ac > 0)
+                        start_char = atol(av[0]);
+                }
+                break;
+            case 'p':case 'P':       /* set pixel size*/
+                if (*p) {
+                    pixel_size = atoi(p);
+                    while (*p && *p != ' ')
+                        p++;
+                }
+                else {
+                    av++; ac--;
+                    if (ac > 0)
+                        pixel_size = atoi(av[0]);
+                }
+                break;
+            case 'c':case 'C':       /* set spaece between characters */
+                if (*p) {
+                    between_chr = atoi(p);
+                    while (*p && *p != ' ')
+                        p++;
+                }
+                else {
+                    av++; ac--;
+                    if (ac > 0)
+                        between_chr = atoi(av[0]);
+                }
+                break;
+            case 'r':case 'R':       /* set spaece between rows */
+                if (*p) {
+                    between_row = atoi(p);
+                    while (*p && *p != ' ')
+                        p++;
+                }
+                else {
+                    av++; ac--;
+                    if (ac > 0)
+                        between_row = atoi(av[0]);
+                }
+                break;
+            case 't':case 'T':     /* display ttc table */
+                if (*p == 't' || *p == 'T') {
+                    pct = 1;
+                    while (*p && *p != ' ')
+                        p++;
+                }
+
+                else if (*p == 'a' || *p == 'A') {
+                    flg_all_ttc = 1;
+                    while (*p && *p != ' ')
+                        p++;
+                }
+
+                else if (*p) {
+                    ttc_index = atoi(p);
+                    while (*p && *p != ' ')
+                        p++;
+                }
+                else {
+                    av++; ac--;
+                    if (ac > 0)
+                        ttc_index = atoi(av[0]);
+                }
+                break;
+
+            default:
+                fprintf(stderr, "Unknown option ignored: %c\r\n", *(p-1));
+            }
+        ++av; --ac;
+    }
+    *pac = ac;
+    *pav = av;
+}
+
+
+int main(int ac, char **av)
+{
+    int ret = 0;
+
+    ++av; --ac;     /* skip av[0]*/
+
+    getopts(&ac, &av);  /* read command line options*/
+
+    if (ac < 1) 
+    {
+        usage();
+    }
+    if (oflag) 
+    {
+        if (ac > 1) 
+        {
+            usage();
+        }
+    }
+
+    if (limit_char < start_char)
+    {
+        usage();
+        exit(0);
+    }
+
+    while (pct && ac > 0) 
+    {
+        print_ttc_table(av[0]);
+        ++av; --ac;
+        exit(0);
+    }
+
+    while (ac > 0) 
+    {
+        convttc(av[0]);
+        ++av; --ac;
+    }
+
+    exit(ret);
+}
+
+
+
+/*
+ * Trie node structure.
+ */
+typedef struct {
+    unsigned short key; /* Key value.                   */
+    unsigned short val; /* Data for the key.                */
+    unsigned long sibs; /* Offset of siblings from trie beginning.  */
+    unsigned long kids; /* Offset of children from trie beginning.  */
+} node_t;
+
+/*
+ * The trie used for remapping codes.
+ */
+static node_t *nodes;
+static unsigned long nodes_used = 0;
+
+int 
+otf2bdf_remap(unsigned short *code)
+{
+    unsigned long i, n, t;
+    unsigned short c, codes[2];
+
+    /*
+     * If no mapping table was loaded, then simply return the code.
+     */
+    if (nodes_used == 0)
+      return 1;
+
+    c = *code;
+    codes[0] = (c >> 8) & 0xff;
+    codes[1] = c & 0xff;
+
+    for (i = n = 0; i < 2; i++) {
+        t = nodes[n].kids;
+        if (t == 0)
+          return 0;
+        for (; nodes[t].sibs && nodes[t].key != codes[i]; t = nodes[t].sibs);
+        if (nodes[t].key != codes[i])
+          return 0;
+        n = t;
+    }
+
+    *code = nodes[n].val;
+    return 1;
+}

Property changes on: tools/convttf.c
___________________________________________________________________
Added: svn:executable
   + *

Index: tools/Makefile
===================================================================
--- tools/Makefile	(revision 27631)
+++ 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) -std=c99 -O -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 27631)
+++ 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 27631)
+++ 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) -std=c99 -O -Wall -g $+ -o $@ \
+		`freetype-config --libs` `freetype-config --cflags`
+
 # implicit rule for simple tools
 $(TOOLSDIR)/%: $(TOOLSDIR)/%.c
 	$(call PRINTS,CC $(subst $(ROOTDIR)/,,$@))
Index: firmware/export/font.h
===================================================================
--- firmware/export/font.h	(revision 27631)
+++ 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 27631)
+++ 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, int maxwidth, int height, int depth);
 static void glyph_cache_load(struct font* pf);
 /* End Font cache structures */
 
@@ -167,7 +167,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);
@@ -175,7 +175,6 @@
     /* get variable font data sizes*/
     /* # words of bitmap_t*/
     pf->bits_size = readlong(pf);
-
     return pf;
 }
 /* Load memory font */
@@ -307,7 +306,7 @@
     pf->buffer_position = oldfileptr;
 
     /* Create the cache */
-    cache_create(pf, pf->maxwidth, pf->height);
+    cache_create(pf, pf->maxwidth, pf->height, pf->depth);
 
     return pf;
 }
@@ -438,7 +437,7 @@
         buffer = pf->buffer_start;
         buffer_size = pf->buffer_size;
     }
-    
+
     if (!internal_load_font(pf, path, buffer, buffer_size))
         return -1;
         
@@ -511,24 +510,31 @@
     }
     else
     {
-        bitmap_offset = ((pf->height + 7) / 8) * p->width * char_code;
+        bitmap_offset = pf->depth
+            ? (pf->height * p->width + 1) / 2 * char_code
+            : ((pf->height + 7) / 8) * p->width * char_code;
+        
     }
 
     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 = pf->depth
+        ? (pf->height * p->width + 1) / 2
+        : p->width * ((pf->height + 7) / 8);
     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, int maxwidth, int height, int depth)
 {
     /* maximum size of rotated bitmap */
-    int bitmap_size = maxwidth * ((height + 7) / 8);
-    
+    int bitmap_size = depth
+        ? (maxwidth * height + 1) / 2
+        : maxwidth * ((height + 7) / 8);
+        
     /* Initialise cache */
     font_cache_create(&pf->cache, pf->buffer_start, pf->buffer_size, bitmap_size);
 }
Index: firmware/drivers/lcd-bitmap-common.c
===================================================================
--- firmware/drivers/lcd-bitmap-common.c	(revision 27631)
+++ 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, MAX(x + base_ofs, 0), y,
+                                  width - ofs, pf->height);
+        else
+#endif
+            LCDFN(mono_bitmap_part)(bits, ofs, 0, width, MAX(x + base_ofs, 0),
+                                    y, width - ofs, pf->height);
         if (is_diac)
         {
             current_vp->drawmode = drawmode;
Index: firmware/drivers/lcd-16bit.c
===================================================================
--- firmware/drivers/lcd-16bit.c	(revision 27631)
+++ firmware/drivers/lcd-16bit.c	(working copy)
@@ -902,6 +902,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,
Index: apps/plugins/mpegplayer/mpegplayer.c
===================================================================
--- apps/plugins/mpegplayer/mpegplayer.c	(revision 27631)
+++ 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: apps/plugins/rockpaint.c
===================================================================
--- apps/plugins/rockpaint.c	(revision 27631)
+++ 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;
