]> git.tdb.fi Git - ttf2png.git/commitdiff
Include kerning information in definition file
authorMikko Rasa <tdb@tdb.fi>
Fri, 23 Nov 2012 18:02:51 +0000 (20:02 +0200)
committerMikko Rasa <tdb@tdb.fi>
Fri, 23 Nov 2012 18:16:00 +0000 (20:16 +0200)
Readme
ttf2png.c

diff --git a/Readme b/Readme
index b8abf114e3ad83d4b8ac4110057b45a764ddc5e3..36728d7d2fcc2c25097da4c4ac9958feaa3d1e72 100644 (file)
--- a/Readme
+++ b/Readme
@@ -70,17 +70,17 @@ information, called font metrics.  To that end, ttf2png can write a definition
 file alongside the image.
 
 The basic format is line-based.  Empty lines, or those starting with a hash
-sign (#), should be ignored.  Data lines consist of fields separated with
-spaces.
+sign (#), should be ignored.  Data lines consist of a keyword followed by
+space-separated fields.
 
-The first data line contains five fields with overall information about the
-image and the font:
+The keyword "font" is followed by five fields with overall information about
+the image and the font:
 
   Fields 1-2: width and height of the image
   Field 3: nominal size of the font
   Fields 4-5: ascent and descent of the font
 
-Subsequent data lines each describe a single glyph and contain eight fields:
+The keyword "glyph" is followed by eight fields describing a single glyph:
 
   Field 1: the code point of the glyph
   Fields 2-3: x and y position of the glyph in the image
@@ -88,6 +88,13 @@ Subsequent data lines each describe a single glyph and contain eight fields:
   Fields 6-7: x and y offset of the glyph from its base point
   Field 8: advance from this glyph to the next
 
+The keyword "kern" is followed by three fields describing kerning between two
+glyphs:
+
+  Field 1: the code point of the left-hand glyph
+  Field 2: the code point of the right-hand glyph
+  Field 3: kerning distance between the glyphs
+
 The following ASCII art image illustrates most of these metrics.  Note that in
 some fonts, not all of the glyphs fit completely inside the character box.
 
@@ -120,6 +127,7 @@ next
 - Improve the packing algorithm
 - Non-square cells for grid mode
 - Option to invert colors
+- Include kerning information in definition file
 
 0.3
 - Restructure the code
index b8f48a816c712612049dd21b0ee2b41fc3e83c16..e702c9fe9446859a99a45c209511f192da00c495 100644 (file)
--- a/ttf2png.c
+++ b/ttf2png.c
@@ -33,6 +33,7 @@ typedef struct sImage
 
 typedef struct sGlyph
 {
+       unsigned index;
        unsigned code;
        Image    image;
        unsigned x, y;
@@ -41,6 +42,13 @@ typedef struct sGlyph
        int      advance;
 } Glyph;
 
+typedef struct sKerning
+{
+       unsigned left_code;
+       unsigned right_code;
+       int distance;
+} Kerning;
+
 typedef struct sFont
 {
        unsigned size;
@@ -48,6 +56,8 @@ typedef struct sFont
        int      descent;
        unsigned n_glyphs;
        Glyph    *glyphs;
+       unsigned n_kerning;
+       Kerning  *kerning;
        Image    image;
 } Font;
 
@@ -284,7 +294,7 @@ void usage()
 
 void init_font(Font *font, FT_Face face, unsigned first, unsigned last, int autohinter)
 {
-       unsigned i;
+       unsigned i, j;
        unsigned size = 0;
 
        font->ascent = (face->size->metrics.ascender+63)>>6;
@@ -331,6 +341,7 @@ void init_font(Font *font, FT_Face face, unsigned first, unsigned last, int auto
                }
 
                glyph = &font->glyphs[font->n_glyphs++];
+               glyph->index = n;
                glyph->code = i;
                glyph->image.w = bmp->width;
                glyph->image.h = bmp->rows;
@@ -356,6 +367,37 @@ void init_font(Font *font, FT_Face face, unsigned first, unsigned last, int auto
 
        if(verbose>=1)
                printf("Loaded %u glyphs\n", font->n_glyphs);
+
+       size = 0;
+       font->n_kerning = 0;
+       font->kerning = NULL;
+       for(i=0; i<font->n_glyphs; ++i) for(j=0; j<font->n_glyphs; ++j)
+               if(j!=i)
+               {
+                       FT_Vector kerning;
+                       FT_Get_Kerning(face, font->glyphs[i].index, font->glyphs[j].index, FT_KERNING_DEFAULT, &kerning);
+
+                       /* FreeType documentation says that vertical kerning is practically
+                       never used, so we ignore it. */
+                       if(kerning.x)
+                       {
+                               Kerning *kern;
+
+                               if(font->n_kerning>=size)
+                               {
+                                       size += 16;
+                                       font->kerning = (Kerning *)realloc(font->kerning, size*sizeof(Kerning));
+                               }
+
+                               kern = &font->kerning[font->n_kerning++];
+                               kern->left_code = font->glyphs[i].code;
+                               kern->right_code = font->glyphs[j].code;
+                               kern->distance = kerning.x/64;
+                       }
+               }
+
+       if(verbose>=1)
+               printf("Loaded %d kerning pairs\n", font->n_kerning);
 }
 
 void render_grid(Font *font, unsigned cellw, unsigned cellh, unsigned cpl, int seq)
@@ -592,13 +634,20 @@ int save_defs(const char *fn, const Font *font)
 
        fprintf(out, "# Image/font info:\n");
        fprintf(out, "# width height size ascent descent\n");
-       fprintf(out, "%d %d %d %d %d\n", font->image.w, font->image.h, font->size, font->ascent, font->descent);
+       fprintf(out, "font %d %d %d %d %d\n", font->image.w, font->image.h, font->size, font->ascent, font->descent);
        fprintf(out, "\n# Glyph info:\n");
        fprintf(out, "# code x y width height offset_x offset_y advance\n");
        for(i=0; i<font->n_glyphs; ++i)
        {
                const Glyph *g = &font->glyphs[i];
-               fprintf(out, "%u %u %u %u %u %d %d %d\n", g->code, g->x, g->y, g->image.w, g->image.h, g->offset_x, g->offset_y, g->advance);
+               fprintf(out, "glyph %u %u %u %u %u %d %d %d\n", g->code, g->x, g->y, g->image.w, g->image.h, g->offset_x, g->offset_y, g->advance);
+       }
+       fprintf(out, "\n# Kerning info:\n");
+       fprintf(out, "# left right distance\n");
+       for(i=0; i<font->n_kerning; ++i)
+       {
+               const Kerning *k = &font->kerning[i];
+               fprintf(out, "kern %u %u %d\n", k->left_code, k->right_code, k->distance);
        }
 
        fclose(out);