]> git.tdb.fi Git - ttf2png.git/commitdiff
Make margin and padding in packed mode controllable
authorMikko Rasa <tdb@tdb.fi>
Tue, 14 Jul 2015 10:08:35 +0000 (13:08 +0300)
committerMikko Rasa <tdb@tdb.fi>
Tue, 14 Jul 2015 10:10:24 +0000 (13:10 +0300)
Readme
ttf2png.c

diff --git a/Readme b/Readme
index 74f4b569d1ebd49fb2026492dedd3d04e871af25..f9effa651f3e30c00b0c70076a1f22c061b6c446 100644 (file)
--- a/Readme
+++ b/Readme
@@ -57,6 +57,14 @@ Command-line options
     definition file is recommended, as the resulting image can seem rather
     messy.
 
+  -m <pixels>
+    Leave a margin around the edges of the generated image.  By default glyphs
+    can touch the edges.  Only used with -p.
+
+  -n <pixels>
+    Control the amount of padding between glyphs.  The default is 1 pixel.
+    Only used with -p.
+
   -d
     File name to write glyph definitions.  See the section below for details.
 
@@ -124,6 +132,10 @@ some fonts, not all of the glyphs fit completely inside the character box.
 
 Changelog
 
+next
+- Controllable margin and padding in packed mode
+- Do not generate overly large images in sequential grid mode
+
 1.0
 - Improve the packing algorithm
 - Non-square cells for grid mode
index f8f465ffd6bf80209032a66475069fe5728c9f44..733453d3c76147896e0acc2b49b437045a2135ff 100644 (file)
--- a/ttf2png.c
+++ b/ttf2png.c
@@ -66,7 +66,7 @@ unsigned round_to_pot(unsigned);
 void *alloc_image_data(size_t, size_t);
 int init_font(Font *, FT_Face, unsigned, unsigned, int);
 int render_grid(Font *, unsigned, unsigned, unsigned, int);
-int render_packed(Font *);
+int render_packed(Font *, unsigned, unsigned);
 int save_defs(const char *, const Font *);
 int save_png(const char *, const Image *, char);
 
@@ -86,6 +86,8 @@ int main(int argc, char **argv)
        char alpha = 0;
        char invert = 0;
        char pack = 0;
+       int  margin = 0;
+       int  padding = 1;
 
        FT_Library freetype;
        FT_Face    face;
@@ -104,7 +106,7 @@ int main(int argc, char **argv)
                return 1;
        }
 
-       while((i = getopt(argc, argv, "r:s:l:c:o:atvh?ed:pi")) != -1)
+       while((i = getopt(argc, argv, "r:s:l:c:o:atvh?ed:pim:n:")) != -1)
        {
                char *ptr;
                int  temp;
@@ -192,6 +194,12 @@ int main(int argc, char **argv)
                case 'i':
                        invert = 1;
                        break;
+               case 'm':
+                       margin = strtol(optarg, NULL, 0);
+                       break;
+               case 'n':
+                       padding = strtol(optarg, NULL, 0);
+                       break;
                }
        }
        if(!strcmp(out_fn, "-"))
@@ -241,7 +249,7 @@ int main(int argc, char **argv)
                return 1;
 
        if(pack)
-               err = render_packed(&font);
+               err = render_packed(&font, margin, padding);
        else
                err = render_grid(&font, cellw, cellh, cpl, seq);
        if(err)
@@ -291,6 +299,8 @@ void usage()
                "  -v  Increase the level of verbosity\n"
                "  -e  Use cells in sequence, without gaps\n"
                "  -p  Pack the glyphs tightly instead of in a grid\n"
+               "  -m  Margin around image edges in packed mode [0]\n"
+               "  -n  Padding between packed glyphs [1]\n"
                "  -d  File name for writing glyph definitions\n"
                "  -h  Print this message\n");
 }
@@ -555,19 +565,19 @@ int render_grid(Font *font, unsigned cellw, unsigned cellh, unsigned cpl, int se
        return 0;
 }
 
-int render_packed(Font *font)
+int render_packed(Font *font, unsigned margin, unsigned padding)
 {
        unsigned i;
        size_t   area = 0;
        char     *used_glyphs;
        unsigned *used_pixels;
-       unsigned cx = 0, cy;
+       unsigned cx = margin, cy;
        unsigned used_h = 0;
 
        /* Compute the total area occupied by glyphs and padding. */
        for(i=0; i<font->n_glyphs; ++i)
        {
-               size_t a = area+(font->glyphs[i].image.w+1)*(font->glyphs[i].image.h+1);
+               size_t a = area+(font->glyphs[i].image.w+padding)*(font->glyphs[i].image.h+padding);
                if(a<area)
                {
                        fprintf(stderr, "Overflow in counting total glyph area\n");
@@ -580,7 +590,9 @@ int render_packed(Font *font)
        imperfections in the packing. */
        for(font->image.w=1;; font->image.w<<=1)
        {
-               font->image.h = (area*5/4)/font->image.w;
+               if(font->image.w<=margin*2)
+                       continue;
+               font->image.h = (area*5/4)/(font->image.w-margin*2)+margin*2;
                if(font->image.h<=font->image.w)
                        break;
        }
@@ -599,7 +611,7 @@ int render_packed(Font *font)
        used_glyphs = (char *)malloc(font->n_glyphs);
        memset(used_glyphs, 0, font->n_glyphs);
 
-       for(cy=0; cy<font->image.h;)
+       for(cy=margin; cy+margin<font->image.h;)
        {
                unsigned w;
                unsigned x, y;
@@ -609,19 +621,19 @@ int render_packed(Font *font)
 
                /* Find the leftmost free pixel on this row.    Also record the lowest extent of glyphs
                to the left of the free position. */
-               for(; (cx<font->image.w && used_pixels[cx]>cy); ++cx)
-                       if(used_pixels[cx]-cy-1>target_h)
-                               target_h = used_pixels[cx]-cy-1;
+               for(; (cx+margin<font->image.w && used_pixels[cx]>cy); ++cx)
+                       if(used_pixels[cx]-cy-padding>target_h)
+                               target_h = used_pixels[cx]-cy-padding;
 
-               if(cx>=font->image.w)
+               if(cx+margin>=font->image.w)
                {
-                       cx = 0;
+                       cx = margin;
                        ++cy;
                        continue;
                }
 
                /* Count the free pixel at this position. */
-               for(w=0; (cx+w<font->image.w && used_pixels[cx+w]<=cy); ++w) ;
+               for(w=0; (cx+w+margin<font->image.w && used_pixels[cx+w]<=cy); ++w) ;
 
                /* Find a suitable glyph to put here. */
                for(i=0; i<font->n_glyphs; ++i)
@@ -636,7 +648,7 @@ int render_packed(Font *font)
                                /* Prefer glyphs that would reach exactly as low as the ones left
                                of here.  This aims to create a straight edge at the bottom for
                                lining up further glyphs. */
-                               score = g->image.h+1;
+                               score = g->image.h+padding;
                                if(g->image.h==target_h)
                                        score *= g->image.w;
                                else
@@ -666,16 +678,16 @@ int render_packed(Font *font)
                                continue;
                        font->image.data[cx+x+(cy+y)*font->image.w] = 255-glyph->image.data[x+y*glyph->image.w];
                }
-               for(x=0; x<glyph->image.w+2; ++x)
+               for(x=0; x<glyph->image.w+2*padding; ++x)
                {
-                       if(cx+x<1 || cx+x>font->image.w)
+                       if(cx+x<padding || cx+x>=font->image.w+padding)
                                continue;
-                       if(used_pixels[cx+x-1]<cy+glyph->image.h+1)
-                               used_pixels[cx+x-1] = cy+glyph->image.h+1;
+                       if(used_pixels[cx+x-padding]<cy+glyph->image.h+padding)
+                               used_pixels[cx+x-padding] = cy+glyph->image.h+padding;
                }
 
-               if(cy+glyph->image.h>used_h)
-                       used_h = cy+glyph->image.h;
+               if(cy+glyph->image.h+margin>used_h)
+                       used_h = cy+glyph->image.h+margin;
        }
 
        /* Trim the image to the actually used size, in case the original estimate