root/tools/font_8x16_pack.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. font_make_lookuptable
  2. font_find_matching_glyph
  3. font_find_offset
  4. font_init_data
  5. check_used
  6. main

   1 #include "stdio.h"
   2 #include "string.h"
   3 #include "../lib/font/font_8x16_uni.h"
   4 #include "../lib/font/codepages.h"
   5 
   6 //
   7 // Tool to generate run-time font and codepage data
   8 //
   9 // Creates compressed font_data array and run-time codepage tables
  10 // Avoids generating static tables at startup of CHDK.
  11 //
  12 
  13 //-------------------------------------------------------------------
  14 #define DEFAULT_SYMBOL          0xFFFD
  15 
  16 //-------------------------------------------------------------------
  17 // Packed font data
  18 unsigned char font_data[16384];
  19 unsigned short char_codes[4096];    // List of used charcodes
  20 unsigned short font_offsets[4096];  // Offsets into font_data for each charcode
  21 unsigned char fontdata_lookup[256]; // Lookup table (bytes actually used in font data)
  22 int fontdata_ltlength = 0;
  23 
  24 //-------------------------------------------------------------------
  25 // Helper
  26 unsigned char fdata_usage[256];
  27 
  28 //-------------------------------------------------------------------
  29 static int font_make_lookuptable()
  30 {
  31     int i, j;
  32     unsigned char k;
  33 
  34     memset(fdata_usage,0,256);
  35 
  36     // determine if a byte is used
  37     for (i=0; orig_font_data[i].charcode != -1; i++)
  38     {
  39         if (orig_font_data[i].isUsed > 0)
  40         {
  41             for (j=0; j<16; j++)
  42             {
  43                 k = orig_font_data[i].data[j];
  44                 fdata_usage[k] = 1;
  45             }
  46         }
  47     }
  48 
  49     memset(fontdata_lookup, 0, 256);
  50     for (i=0, j=0; j<256; j++)
  51     {
  52         if (fdata_usage[j] != 0)
  53         {
  54             fontdata_lookup[i] = j;
  55             fdata_usage[j] = i; // store index
  56             i++;
  57         }
  58     }
  59 
  60     fontdata_ltlength = i;
  61     return i;
  62 }
  63 
  64 //-------------------------------------------------------------------
  65 static unsigned short font_find_matching_glyph(int index)
  66 {
  67     int i;
  68     int j;
  69 
  70     for (i=0; orig_font_data[i].charcode != -1; i++)
  71     {
  72         if (i >= index)
  73         {
  74             break;
  75         }
  76         j = memcmp(&orig_font_data[i].data[0], &orig_font_data[index].data[0], 16);
  77         if ((j == 0) && (orig_font_data[i].isUsed))
  78         {
  79             return i;
  80         }
  81     }
  82     return 0xffff;
  83 }
  84 
  85 //-------------------------------------------------------------------
  86 static unsigned short font_find_offset(unsigned short charcode)
  87 {
  88     int i=0;
  89 
  90     for (i=0; char_codes[i] != 0xFFFF; i++)
  91     {
  92         if (char_codes[i] == charcode)
  93             return font_offsets[i];
  94     }
  95     return 0xFFFF;
  96 }
  97 
  98 //-------------------------------------------------------------------
  99 static void font_init_data(unsigned short *src, int st, int num)
 100 {
 101     int i;
 102     unsigned short f;
 103 
 104     for (i=0; i<num; ++i)
 105     {
 106         f = font_find_offset(src[i]);
 107         if (f == 0xFFFF)
 108             f = font_find_offset(DEFAULT_SYMBOL);
 109         src[st+i] = f;
 110     }
 111 }
 112 
 113 //-------------------------------------------------------------------
 114 static void check_used(unsigned short *cp)
 115 {
 116     int i;
 117     for (i=0; i<128; i++)
 118     {
 119         unsigned short c = cp[i];
 120         int j;
 121         for (j=0; orig_font_data[j].charcode != -1; j++)
 122         {
 123             if (orig_font_data[j].charcode == c)
 124             {
 125                 orig_font_data[j].isUsed++;
 126             }
 127         }
 128     }
 129 }
 130 
 131 //-------------------------------------------------------------------
 132 
 133 int main(int argc, char **argv)
 134 {
 135     int i, j, f = 0, cc = 0, r;
 136     unsigned char uc;
 137     unsigned short matches;
 138 
 139     int ncp = sizeof(codepages)/(sizeof(unsigned short*));
 140 
 141     int lte = 0; // encoding via lookup-table, if true
 142 
 143     // Check if chars in font are used in any codepages
 144     check_used(cp_common);
 145     for (j=0; j<ncp; j++)
 146     {
 147         check_used(codepages[j]);
 148     }
 149 
 150     // make lookup-table, return number of distinct bytes in font data
 151     lte = (font_make_lookuptable() < 128);
 152 
 153     printf("#ifndef GET_FONT_COMPRESSION_MODE\n\n");
 154     printf("// This is a compressed version of font_8x16_uni.h produced by the tools/font_8x16_pack program\n\n");
 155     printf("// Format of each character is 'FontData' structure, followed by FontData.size bytes of character data.\n\n");
 156     printf("static unsigned char font_data[] = {\n");
 157 
 158     for (i=0; orig_font_data[i].charcode != -1; i++)
 159     {
 160         if (orig_font_data[i].isUsed > 0)
 161         {
 162             int top = 0;
 163             int bottom = 0;
 164             for (j=0; j<16 && orig_font_data[i].data[j] == 0; j++) { top++; }
 165             for (j=15; j>=top && orig_font_data[i].data[j] == 0; j--) { bottom++; }
 166             if (top == 16)  // Blank character
 167             {
 168                 // Fix values to fit into 4 bits each (sorted out in draw_char function)
 169                 top--;
 170                 bottom++;
 171             }
 172 
 173             char_codes[cc] = orig_font_data[i].charcode;
 174             font_offsets[cc] = f;
 175             cc++;
 176             matches = font_find_matching_glyph(i);
 177             if (matches != 65535)
 178             {
 179                 printf("/*%04x == %04x*/", orig_font_data[i].charcode, orig_font_data[matches].charcode);
 180                 font_offsets[cc-1] = font_find_offset(orig_font_data[matches].charcode);
 181             }
 182             else
 183             {
 184 
 185                 font_data[f++] = (top << 4) | bottom;
 186 
 187                 printf("/*%04x*/ 0x%02x,", orig_font_data[i].charcode, (top << 4) | bottom);
 188                 r = f;
 189                 for (j=top; j<16-bottom; j++)
 190                 {
 191                     if (!lte)
 192                     {
 193                         font_data[f++] = orig_font_data[i].data[j] & 0xFF;
 194                         printf(" 0x%02x,",orig_font_data[i].data[j] & 0xFF);
 195                     }
 196                     else
 197                     {
 198                         // lookup-table based encoding
 199                         uc = orig_font_data[i].data[j] & 0xFF;
 200                         font_data[f] = fdata_usage[uc]; // byte's index in lookup table
 201                         if ( (j > top) && (font_data[f] == font_data[f-1]) )
 202                         {
 203                             // repetition found inside glyph data, set bit7 of previous byte
 204                             font_data[f-1] = font_data[f-1] | 0x80;
 205                         }
 206                         else
 207                         {
 208                             f++;
 209                         }
 210                     }
 211                 }
 212                 if (lte)
 213                 {
 214                     for (j=r; j<f; j++)
 215                     {
 216                         printf(" 0x%02x,",font_data[j]);
 217                     }
 218                 }
 219             }
 220             printf("\n");
 221         }
 222     }
 223 
 224     char_codes[cc] = 0xFFFF;
 225 
 226     printf("};\n\n");
 227     printf("// font_data length: %d bytes\n", f);
 228 
 229     if (lte)
 230     {
 231         printf("unsigned char fontdata_lookup[] = {\n    ");
 232         for (i=0; i<fontdata_ltlength; i++)
 233         {
 234             printf("0x%02x,", fontdata_lookup[i]);
 235             if ( ((i+1) & 0xf) == 0 )
 236             {
 237                 printf("\n    ");
 238             }
 239         }
 240         printf("};\n");
 241         printf("// lookup table length: %d bytes\n\n", fontdata_ltlength);
 242 #if 0
 243         printf("    /* font data byte distribution\n    ");
 244         for (i=0; i<256; i++)
 245         {
 246             printf("0x%02x,", fdata_usage[i]);
 247             if ( ((i+1) & 0xf) == 0 )
 248             {
 249                 printf("\n    ");
 250             }
 251         }
 252         printf("*/\n\n");
 253 #endif
 254     }
 255 
 256     // Set up codepage entries, and save to file
 257     font_init_data(cp_common, 0, 128);
 258 
 259     printf("// Offsets to font character data stored in the font_data array.\n\n");
 260     printf("static unsigned short cp_common[] =\n{\n");
 261     for (i=0; i<128; i++)
 262     {
 263         if ((i & 15) == 0) printf("    ");
 264         printf("0x%04x,", cp_common[i]);
 265         if ((i & 15) == 15) printf("\n");
 266     }
 267     printf("};\n");
 268 
 269     for (j=0; j<ncp; j++)
 270     {
 271         font_init_data(codepages[j], 0, 128);
 272         printf("static unsigned short cp_win_%s[] =\n{\n", cp_names[j]);
 273         for (i=0; i<128; i++)
 274         {
 275             if ((i & 15) == 0) printf("    ");
 276             printf("0x%04x,", codepages[j][i]);
 277             if ((i & 15) == 15) printf("\n");
 278         }
 279         printf("};\n");
 280     }
 281 
 282     printf("\n// Array of pointers to codepage tables.\n\n");
 283     printf("static unsigned short* codepages[] =\n{\n");
 284     for (j=0; j<ncp; j++)
 285     {
 286         printf("    cp_win_%s,\n", cp_names[j]);
 287     }
 288     printf("};\n");
 289 
 290     printf("\n// Codepage names for menu UI in gui.c (gui_font_enum).\n\n");
 291     printf("int num_codepages = %d;\n",ncp);
 292     printf("char* codepage_names[] =\n{\n");
 293     for (j=0; j<ncp; j++)
 294     {
 295         printf("    \"Win%s\",\n", cp_names[j]);
 296     }
 297     printf("};\n\n");
 298     printf("#endif // !GET_FONT_COMPRESSION_MODE\n\n");
 299 
 300     if (lte)
 301     {
 302         printf("#define BUILTIN_FONT_RLE_COMPRESSED 1\n\n");
 303     }
 304 
 305     return 0;
 306 }

/* [<][>][^][v][top][bottom][index][help] */