Ignore:
Timestamp:
May 9, 2006, 5:52:15 PM (14 years ago)
Author:
Sam Hocevar
Message:
  • Optimise similar glyphs when generating a font. Given how many glyphs are unavailable, this is a significant gain.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcaca/trunk/tools/makefont.c

    r940 r948  
    5656};
    5757
     58struct glyph
     59{
     60    uint32_t unicode;
     61    char buf[10];
     62    unsigned int same_as;
     63    unsigned int data_index;
     64};
     65
    5866static void fix_glyph(FT_Bitmap *, uint32_t, unsigned int, unsigned int);
     67static int printf_unicode(struct glyph *);
    5968static int printf_hex(char const *, uint8_t *, int);
    6069static int printf_u32(char const *, uint32_t);
     
    7079
    7180    FT_Bitmap img;
    72     int width, height, b, i, n, blocks, glyphs;
    73     unsigned int glyph_size, control_size, data_size;
     81    int width, height, b, i, blocks, glyphs;
     82    unsigned int n, index, glyph_size, control_size, data_size;
    7483    uint8_t *glyph_data;
     84    struct glyph *gtab;
    7585
    7686    unsigned int bpp, dpi;
     
    129139    height = PANGO_PIXELS(r.height);
    130140    glyph_size = ((width * height) + (8 / bpp) - 1) / (8 / bpp);
    131     glyph_data = malloc(glyph_size);
    132141
    133142    /* Compute blocks and glyphs count */
     
    142151    control_size = 24 + 12 * blocks + 8 * glyphs;
    143152    data_size = glyph_size * glyphs;
     153
     154    gtab = malloc(glyphs * sizeof(struct glyph));
     155    glyph_data = malloc(data_size);
    144156
    145157    /* Let's go! */
     
    184196    printf("\n");
    185197
    186     printf("/* glyph_info: */\n");
    187     n = 0;
     198    /* Render all glyphs, so that we can know their offset */
     199    n = index = 0;
    188200    for(b = 0; blocklist[b + 1]; b += 2)
    189201    {
    190202        for(i = blocklist[b]; i < blocklist[b + 1]; i++)
    191203        {
    192             printf_u16("\"%s", width);
    193             printf_u16("%s", height);
    194             printf_u32("%s\"\n", n * glyph_size);
    195             n++;
    196         }
    197     }
    198     printf("\n");
    199 
    200     printf("/* font_data: */\n");
    201     for(b = 0; blocklist[b + 1]; b += 2)
    202     {
    203         for(i = blocklist[b]; i < blocklist[b + 1]; i++)
    204         {
    205             unsigned int ch = i;
    206             char buf[10];
    207204            int x, y, bytes;
    208 
    209             bytes = _cucul_utf32_to_utf8(buf, ch);
    210             buf[bytes] = '\0';
    211 
    212             /* Print glyph value in comment */
    213             printf("/* U+%.04X: \"", i);
    214 
    215             if(i < 0x20 || (i >= 0x80 && i <= 0xa0))
    216                 printf("\\x%.02x\" */", i);
    217             else
    218                 printf("%s\" */ ", buf);
     205            unsigned int k;
     206
     207            gtab[n].unicode = i;
     208            bytes = _cucul_utf32_to_utf8(gtab[n].buf, gtab[n].unicode);
     209            gtab[n].buf[bytes] = '\0';
    219210
    220211            /* Render glyph on a bitmap */
    221             pango_layout_set_text(l, buf, -1);
    222             memset(glyph_data, 0, glyph_size);
     212            pango_layout_set_text(l, gtab[n].buf, -1);
    223213            memset(img.buffer, 0, img.pitch * height);
    224214            pango_ft2_render_layout(&img, l, 0, 0);
    225215
    226216            /* Fix glyphs that we know how to handle better */
    227             fix_glyph(&img, ch, width, height);
     217            fix_glyph(&img, gtab[n].unicode, width, height);
    228218
    229219            /* Write bitmap as an escaped C string */
    230             n = 0;
     220            memset(glyph_data + n * glyph_size, 0, glyph_size);
     221            k = 0;
    231222            for(y = 0; y < height; y++)
    232223            {
     
    236227
    237228                    pixel >>= (8 - bpp);
    238                     glyph_data[n / 8] |= pixel << (8 - bpp - (n % 8));
    239                     n += bpp;
     229                    glyph_data[n * glyph_size + k / 8]
     230                        |= pixel << (8 - bpp - (k % 8));
     231                    k += bpp;
    240232                }
    241233            }
    242             printf_hex("\"%s\"\n", glyph_data, glyph_size);
     234
     235            /* Check whether this is the same glyph as another one. Please
     236             * don't bullshit me about sorting, hashing and stuff like that,
     237             * our data is small enough for this to work. */
     238            for(k = 0; k < n; k++)
     239            {
     240                if(!memcmp(glyph_data + k * glyph_size,
     241                           glyph_data + n * glyph_size, glyph_size))
     242                    break;
     243            }
     244
     245            gtab[n].data_index = index;
     246            gtab[n].same_as = k;
     247
     248            if(k == n)
     249                index++;
     250
     251            n++;
     252        }
     253    }
     254
     255    printf("/* glyph_info: */\n");
     256    n = 0;
     257    for(b = 0; blocklist[b + 1]; b += 2)
     258    {
     259        for(i = blocklist[b]; i < blocklist[b + 1]; i++)
     260        {
     261            printf_u16("\"%s", width);
     262            printf_u16("%s", height);
     263            printf_u32("%s\"\n", gtab[gtab[n].same_as].data_index * glyph_size);
     264            n++;
     265        }
     266    }
     267    printf("\n");
     268
     269    printf("/* font_data: */\n");
     270    n = 0;
     271    for(b = 0; blocklist[b + 1]; b += 2)
     272    {
     273        for(i = blocklist[b]; i < blocklist[b + 1]; i++)
     274        {
     275            /* Print glyph value in comment */
     276            printf("/* ");
     277            printf_unicode(&gtab[n]);
     278
     279            if(gtab[n].same_as == n)
     280                printf_hex(" */ \"%s\"\n",
     281                           glyph_data + n * glyph_size, glyph_size);
     282            else
     283            {
     284                printf(" is ");
     285                printf_unicode(&gtab[gtab[n].same_as]);
     286                printf(" */\n");
     287            }
     288
     289            n++;
    243290        }
    244291    }
     
    247294
    248295    free(img.buffer);
     296    free(gtab);
     297    free(glyph_data);
    249298    g_object_unref(l);
    250299    g_object_unref(cx);
     
    329378}
    330379
     380static int printf_unicode(struct glyph *g)
     381{
     382    int written = 0;
     383
     384    written += printf("U+%.04X: \"", g->unicode);
     385
     386    if(g->unicode < 0x20 || (g->unicode >= 0x7f && g->unicode <= 0xa0))
     387        written += printf("\\x%.02x\"", g->unicode);
     388    else
     389        written += printf("%s\"", g->buf);
     390
     391    return written;
     392}
     393
    331394static int printf_u32(char const *fmt, uint32_t i)
    332395{
Note: See TracChangeset for help on using the changeset viewer.