]> git.tdb.fi Git - ttf2png.git/commitdiff
Version 0.2 0.2
authorMikko Rasa <tdb@tdb.fi>
Tue, 19 Sep 2006 11:44:49 +0000 (14:44 +0300)
committerMikko Rasa <tdb@tdb.fi>
Thu, 22 Nov 2012 07:48:37 +0000 (09:48 +0200)
Makefile
Readme
ttf2png.c

index b1dbdd255efabc2c9edcc1b56c34e0fe71073b4b..c20184729724ec7c6b08f51c223cc3dba2acf66b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 ttf2png: ttf2png.c
        gcc -Wall $^ -o $@ $(shell freetype-config --cflags --libs) $(shell pkg-config --cflags --libs libpng12)
 
-VER=0.1.1
+VER=0.2
 
 .PHONY: tarball
 tarball: ttf2png-$(VER).tar.gz
diff --git a/Readme b/Readme
index bbd8b59ae579d4d3f934246a184ff9fa611a11ba..c387b106f9c4ac853e2738640a3df234394cf4bc 100644 (file)
--- a/Readme
+++ b/Readme
@@ -9,6 +9,22 @@ libpng 1.2
 C compiler (preferably GCC)
 
 
+Changes
+
+0.2
+- Added output to stdout
+- Clean up code a bit
+- Added sequential mode
+- Added definition file writing
+
+0.1.1
+- Added more verbosity
+- Added transparency mode
+
+0.1
+- Initial release
+
+
 License
 
 This program is free software; you can redistribute it and/or
index dfdde4b789c6428c14223c43bec4287a5a5646ea..4fbe990ca3ae550aba62d1367ee79435064e9b40 100644 (file)
--- a/ttf2png.c
+++ b/ttf2png.c
@@ -24,33 +24,36 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #include <ft2build.h>
 #include FT_FREETYPE_H
 
+unsigned round_to_pot(unsigned);
 void usage();
 int save_png(char *, char *, int, int);
 
-char   verbose=0;
-char   alpha=0;
+char verbose=0;
+char alpha=0;
 
 int main(int argc, char **argv)
 {
-       FT_Library      freetype;
-       FT_Face         face;
-       int     err;
-       int     o;
-       int     begin=0;
-       int     end=255;
-       char    *fn;
-       int     size=10;
-       int     cpl=16;
-       int     w,h;
-       int     i;
-       char    *data;
-       int     ch,cw;
-       int     cell=16;
-       int     ascent;
-       char    *out="font.png";
-       const char      *name;
-       char    autohinter=0;
-       int     count;
+       FT_Library freetype;
+       FT_Face    face;
+       int  err;
+       int  o;
+       int  begin=0;
+       int  end=255;
+       char *fn;
+       int  size=10;
+       int  cpl=16;
+       int  w,h;
+       int  i;
+       char *data;
+       int  ch,cw;
+       int  cell=16;
+       int  ascent;
+       char *out="font.png";
+       char autohinter=0;
+       int  count;
+       char *def_fn=NULL;
+       char seq=0;
+       FILE *def=NULL;
 
        if(argc<2)
        {
@@ -58,35 +61,45 @@ int main(int argc, char **argv)
                return 1;
        }
 
-       while((o=getopt(argc,argv,"r:s:l:c:o:atvh?"))!=-1)
+       while((o=getopt(argc, argv, "r:s:l:c:o:atvh?ed:"))!=-1)
        {
-               char    *ptr;
-               int     temp;
+               char *ptr;
+               int  temp;
                switch(o)
                {
                case 'r':
-                       if(!isdigit(optarg[0])) temp=-1;
-                       else
+                       if(!strcmp(optarg, "all"))
                        {
-                               temp=strtol(optarg,&ptr,0);
-                               if(ptr[0]!=',' || !isdigit(ptr[1])) temp=-1;
+                               begin=0;
+                               end=0x110000;
                        }
-                       if(temp<0)
-                               printf("Not a valid range: %s\n",optarg);
                        else
                        {
-                               begin=temp;
-                               end=strtol(ptr+1,NULL,0);
+                               if(!isdigit(optarg[0]))
+                                       temp=-1;
+                               else
+                               {
+                                       temp=strtol(optarg, &ptr, 0);
+                                       if(ptr[0]!=',' || !isdigit(ptr[1]))
+                                               temp=-1;
+                               }
+                               if(temp<0)
+                                       printf("Not a valid range: %s\n", optarg);
+                               else
+                               {
+                                       begin=temp;
+                                       end=strtol(ptr+1, NULL, 0);
+                               }
                        }
                        break;
                case 's':
-                       size=strtol(optarg,NULL,0);
+                       size=strtol(optarg, NULL, 0);
                        break;
                case 'l':
-                       cpl=strtol(optarg,NULL,0);
+                       cpl=strtol(optarg, NULL, 0);
                        break;
                case 'c':
-                       cell=strtol(optarg,NULL,0);
+                       cell=strtol(optarg, NULL, 0);
                        break;
                case 'o':
                        out=optarg;
@@ -104,43 +117,52 @@ int main(int argc, char **argv)
                case '?':
                        usage();
                        return 0;
+               case 'e':
+                       seq=1;
+                       break;
+               case 'd':
+                       def_fn=optarg;
+                       break;
                }
        }
+       if(!strcmp(out,"-"))
+               verbose=0;
 
-       if(optind>=argc)
+       if(optind!=argc-1)
        {
                usage();
                return 1;
        }
+       
        fn=argv[optind];
 
        err=FT_Init_FreeType(&freetype);
        if(err)
        {
-               fprintf(stderr,"Couldn't initialize FreeType library\n");
+               fprintf(stderr, "Couldn't initialize FreeType library\n");
                return 1;
        }
 
-       err=FT_New_Face(freetype,fn,0,&face);
+       err=FT_New_Face(freetype, fn, 0, &face);
        if(err)
        {
-               fprintf(stderr,"Couldn't load font file\n");
+               fprintf(stderr, "Couldn't load font file\n");
                if(err==FT_Err_Unknown_File_Format)
-                       fprintf(stderr,"Unknown file format\n");
+                       fprintf(stderr, "Unknown file format\n");
                return 1;
        }
 
-       name=FT_Get_Postscript_Name(face);
        if(verbose)
        {
-               printf("Font name: %s\n",name);
-               printf("Glyphs: %ld\n",face->num_glyphs);
+               const char *name=FT_Get_Postscript_Name(face);
+               printf("Font name: %s\n", name);
+               printf("Glyphs: %ld\n", face->num_glyphs);
        }
 
-       err=FT_Set_Pixel_Sizes(face,0,size);
+       err=FT_Set_Pixel_Sizes(face, 0, size);
        if(err)
        {
-               fprintf(stderr,"Couldn't set size\n");
+               fprintf(stderr, "Couldn't set size\n");
                return 1;
        }
        ascent=(face->bbox.yMax*face->size->metrics.x_scale)>>16;
@@ -158,54 +180,100 @@ int main(int argc, char **argv)
        }
        if(verbose>=1 && (ch>cell || cw>cell)) fprintf(stderr,"Warning: character size exceeds cell size\n");
 
-       w=cpl*cell;
-       h=(end-begin+cpl-1)/cpl*cell;
+       w=round_to_pot(cpl*cell);
+       if(seq)
+               h=(face->num_glyphs+cpl-1)/cpl*cell;
+       else
+               h=(end-begin+cpl-1)/cpl*cell;
+       h=round_to_pot(h);
+       
        data=(char *)malloc(w*h);
-       memset(data,255,w*h);
+       memset(data, 255, w*h);
+
+       if(def_fn)
+               def=fopen(def_fn, "w");
+
+       if(def)
+               fprintf(def, "%d %d %d\n", w, h, size);
 
        count=0;
-       for(i=begin;i<=end;++i)
+       for(i=begin; i<=end; ++i)
        {
-               int                     glyph=FT_Get_Char_Index(face,i);
-               FT_Bitmap       *bmp=&face->glyph->bitmap;
-               int                     x,y;
-               int                     cx=(i%cpl)*cell;
-               int                     cy=(i/cpl)*cell;
-               int                     flags=0;
-               int                     dy;
+               int       glyph=FT_Get_Char_Index(face,i);
+               FT_Bitmap *bmp=&face->glyph->bitmap;
+               int       x,y;
+               int       cx,cy;
+               int       flags=0;
+               int       dy;
+
                if(!glyph) continue;
-               fflush(stdout);
-               if(autohinter) flags|=FT_LOAD_FORCE_AUTOHINT;
-               FT_Load_Glyph(face,glyph,flags);
-               FT_Render_Glyph(face->glyph,FT_RENDER_MODE_NORMAL);
-               if(cell>bmp->width) cx+=(cell-bmp->width)/2;
+               
+               if(seq)
+               {
+                       cx=(count%cpl)*cell;
+                       cy=(count/cpl)*cell;
+               }
+               else
+               {
+                       cx=(i%cpl)*cell;
+                       cy=(i/cpl)*cell;
+               }
+
+               if(autohinter)
+                       flags|=FT_LOAD_FORCE_AUTOHINT;
+               FT_Load_Glyph(face, glyph, flags);
+               FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
+               if(cell>bmp->width)
+                       cx+=(cell-bmp->width)/2;
                dy=ascent-face->glyph->bitmap_top;
                cy+=dy;
+               
                if(verbose>=2)
                {
-                       printf("  Char %d: glyph %d, size %dx%d\n",i,glyph,bmp->width,bmp->rows);
-                       if(bmp->width>cell || dy+bmp->rows>cell || dy<0) printf("  Warning: Character %d does not fit in cell\n",i);
+                       printf("  Char %d: glyph %d, size %dx%d\n", i, glyph, bmp->width, bmp->rows);
+                       if(bmp->width>cell || dy+bmp->rows>cell || dy<0) printf("  Warning: Character %d does not fit in cell\n", i);
                }
+               
                if(bmp->pitch<0)
                {
-                       fprintf(stderr,"Warning: Character %d not rendered (can't handle reversed bitmaps)\n",i);
+                       fprintf(stderr, "Warning: Character %d not rendered (can't handle reversed bitmaps)\n", i);
                        continue;
                }
-               for(y=0;y<bmp->rows;++y) for(x=0;x<bmp->width;++x)
+               
+               for(y=0; y<bmp->rows; ++y) for(x=0; x<bmp->width; ++x)
                {
                        if(cx+x<0 || cx+x>=w || cy+y<0 || cy+y>=h) continue;
                        data[cx+x+(cy+y)*w]=255-bmp->buffer[x+y*bmp->pitch];
                }
+
+               if(def)
+                       fprintf(def, "%d %d %d %d %d %d %d\n",i, cx, cy, bmp->width, bmp->rows, face->glyph->bitmap_top-bmp->rows, (int)(face->glyph->advance.x+32)/64);
+
                ++count;
        }
 
-       save_png(out,data,w,h);
+       if(def)
+               fclose(def);
+
+       save_png(out, data, w, h);
 
        if(verbose) printf("Converted %d glyphs\n",count);
 
        return 0;
 }
 
+unsigned round_to_pot(unsigned n)
+{
+       n-=1;
+       n|=n>>1;
+       n|=n>>2;
+       n|=n>>4;
+       n|=n>>8;
+       n|=n>>16;
+
+       return n+1;
+}
+       
 void usage()
 {
        printf("ttf2png - True Type Font to PNG converter\n"
@@ -217,70 +285,77 @@ void usage()
                "  -s  Font size to use, in pixels [10]\n"
                "  -l  Number of characters to put in one line [16]\n"
                "  -c  Character cell size, in pixels [16]\n"
-               "  -o  Output file name [font.png]\n"
+               "  -o  Output file name (or - for stdout) [font.png]\n"
                "  -a  Force autohinter\n"
                "  -t  Render font to alpha channel\n"
                "  -v  Increase the level of verbosity\n"
+               "  -e  Use cells in sequence, rather than by code\n"
+               "  -d  Write a definition to the given file\n"
                "  -h  Print this message\n");
 }
 
 int save_png(char *fn, char *data, int w, int h)
 {
-       FILE                    *out;
-       png_struct      *pngs;
-       png_info                *pngi;
-       png_byte                *rows[h];
-       int                     i;
-       png_byte                *data2;
-       int                     color;
-
-       out=fopen(fn,"wb");
-       if(!out)
+       FILE       *out;
+       png_struct *pngs;
+       png_info   *pngi;
+       png_byte   *rows[h];
+       int        i;
+       png_byte   *data2;
+       int        color;
+
+       if(!strcmp(fn, "-"))
+               out=stdout;
+       else
        {
-               fprintf(stderr,"Couldn't open output file\n");
-               return -1;
+               out=fopen(fn, "wb");
+               if(!out)
+               {
+                       fprintf(stderr, "Couldn't open output file\n");
+                       return -1;
+               }
        }
 
-       pngs=png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
+       pngs=png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
        if(!pngs)
        {
-               fprintf(stderr,"Error writing PNG file\n");
+               fprintf(stderr, "Error writing PNG file\n");
                return -1;
        }
        pngi=png_create_info_struct(pngs);
        if(!pngi)
        {
-               png_destroy_write_struct(&pngs,NULL);
-               fprintf(stderr,"Error writing PNG file\n");
+               png_destroy_write_struct(&pngs, NULL);
+               fprintf(stderr, "Error writing PNG file\n");
                return -1;
        }
 
-       png_init_io(pngs,out);
+       png_init_io(pngs, out);
        if(alpha)
        {
                data2=(png_byte *)malloc(w*h*2);
-               for(i=0;i<w*h;++i)
+               for(i=0; i<w*h; ++i)
                {
                        data2[i*2]=255;
                        data2[i*2+1]=255-data[i];
                }
-               for(i=0;i<h;++i)
+               for(i=0; i<h; ++i)
                        rows[i]=(png_byte *)(data2+i*w*2);
                color=PNG_COLOR_TYPE_GRAY_ALPHA;
        }
        else
        {
-               for(i=0;i<h;++i)
+               for(i=0; i<h; ++i)
                        rows[i]=(png_byte *)(data+i*w);
                color=PNG_COLOR_TYPE_GRAY;
        }
-       png_set_IHDR(pngs,pngi,w,h,8,color,PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
-       png_set_rows(pngs,pngi,rows);
-       png_write_png(pngs,pngi,PNG_TRANSFORM_IDENTITY,NULL);
-       png_destroy_write_struct(&pngs,&pngi);
+       png_set_IHDR(pngs, pngi, w, h, 8, color, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+       png_set_rows(pngs, pngi, rows);
+       png_write_png(pngs, pngi, PNG_TRANSFORM_IDENTITY, NULL);
+       png_destroy_write_struct(&pngs, &pngi);
        if(alpha) free(data2);
 
-       if(verbose) printf("Saved %dx%d PNG image to %s\n",w,h,fn);
+       if(verbose) printf("Saved %dx%d PNG image to %s\n", w, h, fn);
 
        return 0;
 }