]> 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
 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
 
 
   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
 
   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
 
   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.
 
 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
 - 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
 
 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
 {
 
 typedef struct sGlyph
 {
+       unsigned index;
        unsigned code;
        Image    image;
        unsigned x, y;
        unsigned code;
        Image    image;
        unsigned x, y;
@@ -41,6 +42,13 @@ typedef struct sGlyph
        int      advance;
 } Glyph;
 
        int      advance;
 } Glyph;
 
+typedef struct sKerning
+{
+       unsigned left_code;
+       unsigned right_code;
+       int distance;
+} Kerning;
+
 typedef struct sFont
 {
        unsigned size;
 typedef struct sFont
 {
        unsigned size;
@@ -48,6 +56,8 @@ typedef struct sFont
        int      descent;
        unsigned n_glyphs;
        Glyph    *glyphs;
        int      descent;
        unsigned n_glyphs;
        Glyph    *glyphs;
+       unsigned n_kerning;
+       Kerning  *kerning;
        Image    image;
 } Font;
 
        Image    image;
 } Font;
 
@@ -284,7 +294,7 @@ void usage()
 
 void init_font(Font *font, FT_Face face, unsigned first, unsigned last, int autohinter)
 {
 
 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;
        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 = &font->glyphs[font->n_glyphs++];
+               glyph->index = n;
                glyph->code = i;
                glyph->image.w = bmp->width;
                glyph->image.h = bmp->rows;
                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);
 
        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)
 }
 
 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, "# 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, "\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);
        }
 
        fclose(out);