]> git.tdb.fi Git - ttf2png.git/commitdiff
Rework the definition file format
authorMikko Rasa <tdb@tdb.fi>
Sat, 5 May 2018 19:27:22 +0000 (22:27 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 5 May 2018 19:27:22 +0000 (22:27 +0300)
Distance fields threw off the metrics because the field extends past the
actual glyph area.  The definitions are now split to abstract metrics and
glyph images to allow acccurate metrics to be obtained.  A mapping from
code points to glyphs was also added to allow later support for glyphs
without a dedicated code point such as ligatures.

Readme
ttf2png.c

diff --git a/Readme b/Readme
index c4fc9d05cbfb2ca7fd07a412ca1c2d6000291586..026833055418900ea2c133ecd0a8ba38f5d2ca8c 100644 (file)
--- a/Readme
+++ b/Readme
@@ -108,23 +108,24 @@ the image and the font:
   Field 3: nominal size of the font
   Fields 4-5: ascent and descent of the font
 
-The keyword "glyph" is followed by eight fields describing a single glyph:
+The keyword "code" is followed by two fields establishing a code point to
+glyph mapping:
 
-  Field 1: the code point of the glyph
-  Fields 2-3: x and y position of the glyph in the image
-  Fields 4-5: width and height of the glyph
-  Fields 6-7: x and y offset of the glyph from its base point
-  Field 8: advance from this glyph to the next
+  Field 1: Unicode code point
+  Field 2: Glyph index
 
-The keyword "kern" is followed by three fields describing kerning between two
-glyphs:
+The keyword "metrics" is followed by six fields describing the metrics of a
+glyph:
 
-  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
+  Field 1: the index of the glyph
+  Fields 2-3: width and height of the glyph
+  Fields 4-5: x and y offset of the glyph from its base point
+  Field 6: advance from this glyph to the next
 
-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 the basic metrics.  The character
+box is a conceptual rectangle in which most of the glyphs in the font fit.
+Some fonts may contain glyphs that extend outside of the nominal character
+box.
 
                 - - - - - - - -     ^
                | character box |    |
@@ -148,6 +149,27 @@ some fonts, not all of the glyphs fit completely inside the character box.
                |--------------->
                advance
 
+The keyword "glyph" is followed by six field describing the area of the image
+used for the glyph:
+
+  Field 1: the index of the glyph
+  Fields 2-3: x and y position of the glyph in the image
+  Fields 4-5: width and height of the glyph
+  Field 6: border zone included in the image
+
+The border zone is used with distance field textures to allow the distance
+field to extend past the actual glyph.  If a glyph has a border, the origin
+point in the metrics refers to the glyph's lower left corner.  Subtract the
+border width from both coordinates to obtain the correct rendering position
+for the image.
+
+The keyword "kern" is followed by three fields describing kerning between two
+glyphs:
+
+  Field 1: the index of the left-hand glyph
+  Field 2: the index of the right-hand glyph
+  Field 3: kerning distance between the glyphs
+
 
 Changelog
 
index 93576c1eb4daec90ec7db69f8ad3efac83060302..f8db322032d725f88b646b329b7cf42753c44fc4 100644 (file)
--- a/ttf2png.c
+++ b/ttf2png.c
@@ -29,6 +29,7 @@ typedef struct sImage
 {
        unsigned w, h;
        unsigned char *data;
+       unsigned border;
 } Image;
 
 typedef struct sGlyph
@@ -44,8 +45,8 @@ typedef struct sGlyph
 
 typedef struct sKerning
 {
-       unsigned left_code;
-       unsigned right_code;
+       Glyph *left_glyph;
+       Glyph *right_glyph;
        int distance;
 } Kerning;
 
@@ -494,6 +495,7 @@ int init_image(Image *image, size_t w, size_t h)
        image->w = w;
        image->h = h;
        image->data = NULL;
+       image->border = 0;
 
        if(!image->w || !image->h)
                return 0;
@@ -560,8 +562,8 @@ int init_font(Font *font, FT_Face face, const Range *ranges, unsigned n_ranges,
                                }
 
                                kern = &font->kerning[font->n_kerning++];
-                               kern->left_code = font->glyphs[i].code;
-                               kern->right_code = font->glyphs[j].code;
+                               kern->left_glyph = &font->glyphs[i];
+                               kern->right_glyph = &font->glyphs[j];
                                kern->distance = (kerning.x/scale+32)/64;
                        }
                }
@@ -748,6 +750,7 @@ int create_distance_field(const FT_Bitmap *bmp, Image *image, unsigned scale, un
        if(copy_bitmap(bmp, &base_image))
                return -1;
 
+       image->border = margin;
        for(y=0; y<image->h; ++y) for(x=0; x<image->w; ++x)
        {
                int bx = (x-margin)*scale+scale/2;
@@ -1021,19 +1024,38 @@ 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, "font %d %d %d %d %d\n", font->image.w, font->image.h, font->size, font->ascent, font->descent);
+
+       fprintf(out, "\n# Code point mapping:\n");
+       fprintf(out, "# code index\n");
+       for(i=0; i<font->n_glyphs; ++i)
+       {
+               const Glyph *g = &font->glyphs[i];
+               fprintf(out, "code %u %u\n", g->code, g->index);
+       }
+
+       fprintf(out, "\n# Metrics info:\n");
+       fprintf(out, "# index width height offset_x offset_y advance\n");
+       for(i=0; i<font->n_glyphs; ++i)
+       {
+               const Glyph *g = &font->glyphs[i];
+               int b = g->image.border;
+               fprintf(out, "metrics %u %u %u %d %d %d\n", g->index, g->image.w-2*b, g->image.h-2*b, g->offset_x+b, g->offset_y+b, g->advance);
+       }
+
        fprintf(out, "\n# Glyph info:\n");
-       fprintf(out, "# code x y width height offset_x offset_y advance\n");
+       fprintf(out, "# index x y width height border\n");
        for(i=0; i<font->n_glyphs; ++i)
        {
                const Glyph *g = &font->glyphs[i];
-               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, "glyph %u %u %u %u %u %u\n", g->index, g->x, g->y, g->image.w, g->image.h, g->image.border);
        }
+
        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);
+               fprintf(out, "kern %u %u %d\n", k->left_glyph->index, k->right_glyph->index, k->distance);
        }
 
        fclose(out);