/*
ttf2png - True Type Font to PNG converter
-Copyright (c) 2004 Mikkosoft Productions
+Copyright (c) 2004-2006 Mikkosoft Productions
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <ft2build.h>
#include FT_FREETYPE_H
+typedef struct sGlyphDef
+{
+ int code;
+ int x,y;
+ int w,h;
+ int ascent;
+ int advance;
+} GlyphDef;
+
unsigned round_to_pot(unsigned);
void usage();
-int save_png(char *, char *, int, int);
+int save_defs(const char *, const GlyphDef *, int, int, int, int);
+int save_png(const char *, const char *, int, int, char);
char verbose=0;
-char alpha=0;
int main(int argc, char **argv)
{
- FT_Library freetype;
- FT_Face face;
- int err;
- int o;
+ char *fn;
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;
+ char seq=0;
+ char alpha=0;
+
+ FT_Library freetype;
+ FT_Face face;
+ int ch,cw;
+ int ascent;
+
+ int err;
+ int i;
int count;
+
+ int w,h;
+ char *data;
+ char *out_fn="font.png";
+
char *def_fn=NULL;
- char seq=0;
- FILE *def=NULL;
+ GlyphDef *defs=NULL;
if(argc<2)
{
return 1;
}
- while((o=getopt(argc, argv, "r:s:l:c:o:atvh?ed:"))!=-1)
+ while((i=getopt(argc, argv, "r:s:l:c:o:atvh?ed:"))!=-1)
{
char *ptr;
int temp;
- switch(o)
+ switch(i)
{
case 'r':
if(!strcmp(optarg, "all"))
temp=-1;
}
if(temp<0)
+ {
printf("Not a valid range: %s\n", optarg);
+ exit(1);
+ }
else
{
begin=temp;
cell=strtol(optarg, NULL, 0);
break;
case 'o':
- out=optarg;
+ out_fn=optarg;
break;
case 'a':
autohinter=1;
break;
}
}
- if(!strcmp(out,"-"))
+ if(!strcmp(out_fn, "-"))
verbose=0;
if(optind!=argc-1)
if(verbose>=1 && (ch>cell || cw>cell)) fprintf(stderr,"Warning: character size exceeds cell size\n");
w=round_to_pot(cpl*cell);
- if(seq)
+ if(seq && face->num_glyphs<end-begin)
h=(face->num_glyphs+cpl-1)/cpl*cell;
else
h=(end-begin+cpl-1)/cpl*cell;
memset(data, 255, w*h);
if(def_fn)
- def=fopen(def_fn, "w");
-
- if(def)
- fprintf(def, "%d %d %d\n", w, h, size);
+ {
+ if(face->num_glyphs<end-begin)
+ count=face->num_glyphs;
+ else
+ count=end-begin;
+
+ defs=(GlyphDef *)malloc(count*sizeof(GlyphDef));
+ }
count=0;
for(i=begin; i<=end; ++i)
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);
+ if(def_fn)
+ {
+ defs[count].code=i;
+ defs[count].x=cx;
+ defs[count].y=cy;
+ defs[count].w=bmp->width;
+ defs[count].h=bmp->rows;
+ defs[count].ascent=face->glyph->bitmap_top-bmp->rows;
+ defs[count].advance=(int)(face->glyph->advance.x+32)/64;
+ }
++count;
}
- if(def)
- fclose(def);
+ while(seq && h/2>=(count+cpl-1)/cpl*cell)
+ h/=2;
- save_png(out, data, w, h);
+ if(def_fn)
+ save_defs(def_fn, defs, count, w, h, size);
+ save_png(out_fn, data, w, h, alpha);
- if(verbose) printf("Converted %d glyphs\n",count);
+ if(verbose) printf("Converted %d glyphs\n", count);
return 0;
}
" -h Print this message\n");
}
-int save_png(char *fn, char *data, int w, int h)
+int save_defs(const char *fn, const GlyphDef *defs, int count, int w, int h, int size)
+{
+ FILE *out;
+ int i;
+
+ out=fopen(fn, "w");
+ if(!out)
+ {
+ fprintf(stderr, "Couldn't open %s\n",fn);
+ return -1;
+ }
+
+ fprintf(out, "%d %d %d\n", w, h, size);
+ for(i=0; i<count; ++i)
+ {
+ const GlyphDef *d=defs+i;
+ fprintf(out, "%d %d %d %d %d %d %d\n", d->code, d->x, d->y, d->w, d->h, d->ascent, d->advance);
+ }
+
+ fclose(out);
+
+ return 0;
+}
+
+int save_png(const char *fn, const char *data, int w, int h, char alpha)
{
FILE *out;
png_struct *pngs;
out=fopen(fn, "wb");
if(!out)
{
- fprintf(stderr, "Couldn't open output file\n");
+ fprintf(stderr, "Couldn't open %s\n",fn);
return -1;
}
}