Oh boy, this is a mess.
This commit is contained in:
parent
c5b1bb0430
commit
5ff8bd2367
1 changed files with 49 additions and 74 deletions
123
mkfont.c
123
mkfont.c
|
|
@ -49,10 +49,13 @@
|
||||||
|
|
||||||
uint8_t pal[768];
|
uint8_t pal[768];
|
||||||
int palsize = 0;
|
int palsize = 0;
|
||||||
int xupshift = 0;
|
|
||||||
int rightshift = 0;
|
|
||||||
int bordshift = 0;
|
int bordshift = 0;
|
||||||
|
|
||||||
|
int tewi_hotfix = 0; // U+0309 and U+030A glyphs are offset incorrectly
|
||||||
|
// and the entire font height needs to be cropped
|
||||||
|
int miniwi_hotfix = 0; // U+01C2 glyph is offset incorrect
|
||||||
|
// this font's height also needs a crop
|
||||||
|
|
||||||
uint32_t endianswap( uint32_t n )
|
uint32_t endianswap( uint32_t n )
|
||||||
{
|
{
|
||||||
// if we're in a big endian system, we don't need this
|
// if we're in a big endian system, we don't need this
|
||||||
|
|
@ -94,9 +97,9 @@ int writepng( const char *filename, uint8_t *fdata, int w, int h, int p )
|
||||||
png_set_IHDR(pngp,infp,w,h,8,palsize?PNG_COLOR_TYPE_RGBA:PNG_COLOR_TYPE_GA,
|
png_set_IHDR(pngp,infp,w,h,8,palsize?PNG_COLOR_TYPE_RGBA:PNG_COLOR_TYPE_GA,
|
||||||
PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,
|
PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,
|
||||||
PNG_FILTER_TYPE_DEFAULT);
|
PNG_FILTER_TYPE_DEFAULT);
|
||||||
if ( xupshift || rightshift || bordshift )
|
if ( bordshift )
|
||||||
{
|
{
|
||||||
uint32_t grabs[2] = {endianswap(rightshift+bordshift),endianswap(xupshift+bordshift)};
|
uint32_t grabs[2] = {endianswap(bordshift),endianswap(bordshift)};
|
||||||
png_unknown_chunk grab =
|
png_unknown_chunk grab =
|
||||||
{
|
{
|
||||||
.name = "grAb",
|
.name = "grAb",
|
||||||
|
|
@ -118,10 +121,10 @@ FT_Library ftlib;
|
||||||
FT_Face fnt;
|
FT_Face fnt;
|
||||||
|
|
||||||
int iw, ih;
|
int iw, ih;
|
||||||
int w, h, pxsiz, datsiz;
|
int w, h, datsiz;
|
||||||
uint8_t *idata;
|
uint8_t *idata;
|
||||||
|
|
||||||
int autosize = 0;
|
int calcsize = 1;
|
||||||
int gradient = 0;
|
int gradient = 0;
|
||||||
int upshift = 0;
|
int upshift = 0;
|
||||||
|
|
||||||
|
|
@ -191,9 +194,9 @@ int draw_glyph( FT_Bitmap *bmp, uint8_t v, int px, int py, int ox, int oy )
|
||||||
if ( v == 255 )
|
if ( v == 255 )
|
||||||
{
|
{
|
||||||
float a;
|
float a;
|
||||||
int ofs = j+oy+(upshift+1);
|
int ofs = j+oy+(upshift+tewi_hotfix+miniwi_hotfix);
|
||||||
if ( ofs < 0 ) a = 0.;
|
if ( ofs < 0 ) a = 0.;
|
||||||
else a = ofs/(float)(h+upshift+1);
|
else a = ofs/(float)(h-1);
|
||||||
if ( (gradient&3) == 1 ) rv = lerpg(1.-a);
|
if ( (gradient&3) == 1 ) rv = lerpg(1.-a);
|
||||||
else if ( (gradient&3) == 2 ) rv = lerpg(a);
|
else if ( (gradient&3) == 2 ) rv = lerpg(a);
|
||||||
else if ( (gradient&3) == 3 ) rv = lerpg((a>.5)?((1.-a)*2.):(a*2.));
|
else if ( (gradient&3) == 3 ) rv = lerpg((a>.5)?((1.-a)*2.):(a*2.));
|
||||||
|
|
@ -343,10 +346,10 @@ const char grads[8][20] =
|
||||||
|
|
||||||
int main( int argc, char **argv )
|
int main( int argc, char **argv )
|
||||||
{
|
{
|
||||||
if ( argc < 4 )
|
if ( argc < 3 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"usage: mkfontsingle <font name> <pxsize> <wxh|auto>"
|
fprintf(stderr,"usage: mkfont <font name> <pxsize> <unicode range (hex)>"
|
||||||
" <unicode range (hex)> [gradient type] [color palette] [-palinv]\n");
|
" [gradient type] [color palette] [-palinv]\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if ( FT_Init_FreeType(&ftlib) )
|
if ( FT_Init_FreeType(&ftlib) )
|
||||||
|
|
@ -355,18 +358,20 @@ int main( int argc, char **argv )
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
uint32_t range[2] = {0x0000,0x00FF};
|
uint32_t range[2] = {0x0000,0x00FF};
|
||||||
|
int pxsiz;
|
||||||
sscanf(argv[2],"%d",&pxsiz);
|
sscanf(argv[2],"%d",&pxsiz);
|
||||||
if ( !strcmp(argv[3],"auto") ) autosize = 1;
|
sscanf(argv[3],"%x-%x",&range[0],&range[1]);
|
||||||
else sscanf(argv[3],"%dx%d",&w,&h);
|
if ( argc > 4 ) sscanf(argv[4],"%d",&gradient);
|
||||||
sscanf(argv[4],"%x-%x",&range[0],&range[1]);
|
if ( argc > 6 ) palinv = !strcmp(argv[6],"-palinv");
|
||||||
if ( argc > 5 ) sscanf(argv[5],"%d",&gradient);
|
if ( argc > 5 ) loadpalette(argv[5]);
|
||||||
if ( argc > 7 ) palinv = !strcmp(argv[7],"-palinv");
|
|
||||||
if ( argc > 6 ) loadpalette(argv[6]);
|
|
||||||
if ( FT_New_Face(ftlib,argv[1],0,&fnt) )
|
if ( FT_New_Face(ftlib,argv[1],0,&fnt) )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"error: failed to open font '%s'\n",argv[1]);
|
fprintf(stderr,"error: failed to open font '%s'\n",argv[1]);
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
fprintf(stderr,"info: loaded font \'%s %s\'.\n",fnt->family_name,fnt->style_name);
|
||||||
|
if ( !strcmp(fnt->family_name,"tewi") ) tewi_hotfix = 1;
|
||||||
|
else if ( !strcmp(fnt->family_name,"miniwi") ) miniwi_hotfix = 1;
|
||||||
if ( FT_Set_Pixel_Sizes(fnt,0,pxsiz) )
|
if ( FT_Set_Pixel_Sizes(fnt,0,pxsiz) )
|
||||||
{
|
{
|
||||||
if ( fnt->num_fixed_sizes <= 0 )
|
if ( fnt->num_fixed_sizes <= 0 )
|
||||||
|
|
@ -391,10 +396,11 @@ int main( int argc, char **argv )
|
||||||
return 8;
|
return 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
h = (fnt->size->metrics.height>>6)-tewi_hotfix-miniwi_hotfix;
|
||||||
FT_Select_Charmap(fnt,FT_ENCODING_UNICODE);
|
FT_Select_Charmap(fnt,FT_ENCODING_UNICODE);
|
||||||
// first pass to compute baseline upshift
|
// first pass to compute baseline upshift
|
||||||
upshift = 65535;
|
upshift = 65535;
|
||||||
for ( uint32_t i=range[0]; i<=range[1]; i++ )
|
for ( uint32_t i=0; i<=0xFFFF; i++ )
|
||||||
{
|
{
|
||||||
FT_UInt glyph = FT_Get_Char_Index(fnt,i);
|
FT_UInt glyph = FT_Get_Char_Index(fnt,i);
|
||||||
if ( !glyph || FT_Load_Glyph(fnt,glyph,LOADFLAGS) ) continue;
|
if ( !glyph || FT_Load_Glyph(fnt,glyph,LOADFLAGS) ) continue;
|
||||||
|
|
@ -407,48 +413,13 @@ int main( int argc, char **argv )
|
||||||
if ( gshift < upshift ) upshift = gshift;
|
if ( gshift < upshift ) upshift = gshift;
|
||||||
}
|
}
|
||||||
fprintf(stderr,"info: estimated baseline upshift is %d.\n",upshift);
|
fprintf(stderr,"info: estimated baseline upshift is %d.\n",upshift);
|
||||||
// second pass to compute "real" upshift, which is used for the grAb Y offset
|
// second pass to compute the maximum cell size (for memory allocation)
|
||||||
// as well as the "rightshift" for the X offset
|
if ( calcsize )
|
||||||
xupshift = 65535;
|
|
||||||
for ( uint32_t i=range[0]; i<=range[1]; i++ )
|
|
||||||
{
|
{
|
||||||
FT_UInt glyph = FT_Get_Char_Index(fnt,i);
|
|
||||||
if ( !glyph || FT_Load_Glyph(fnt,glyph,LOADFLAGS) ) continue;
|
|
||||||
FT_Render_Glyph(fnt->glyph,RENDERMODE);
|
|
||||||
int valid = 0;
|
|
||||||
for ( unsigned j=0; j<fnt->glyph->bitmap.rows; j++ )
|
|
||||||
valid |= valid_row(&fnt->glyph->bitmap,j);
|
|
||||||
if ( !valid ) continue;
|
|
||||||
int xx = fnt->glyph->bitmap_left;
|
|
||||||
if ( -xx > rightshift ) rightshift = -xx;
|
|
||||||
int yy = upshift+1+(pxsiz-fnt->glyph->bitmap_top);
|
|
||||||
for ( unsigned j=0; j<fnt->glyph->bitmap.rows; j++ )
|
|
||||||
{
|
|
||||||
if ( !valid_row(&fnt->glyph->bitmap,j) ) yy++;
|
|
||||||
else break;
|
|
||||||
}
|
|
||||||
if ( yy < 0 )
|
|
||||||
{
|
|
||||||
int xup = -yy;
|
|
||||||
if ( xup < xupshift ) xupshift = xup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( xupshift == 65535 ) xupshift = 0;
|
|
||||||
if ( xupshift )
|
|
||||||
{
|
|
||||||
fprintf(stderr,"info: real upshift is %d.\n",upshift+xupshift);
|
|
||||||
fprintf(stderr,"info: grAb Y offset %d will be used.\n",xupshift);
|
|
||||||
}
|
|
||||||
if ( rightshift )
|
|
||||||
fprintf(stderr,"info: right shift detected, grAb X offset %d will be used.\n",rightshift);
|
|
||||||
// third pass to compute the maximum cell size (for memory allocation)
|
|
||||||
if ( autosize )
|
|
||||||
{
|
|
||||||
h = (fnt->size->metrics.height>>6)+1;
|
|
||||||
if ( FT_IS_FIXED_WIDTH(fnt) )
|
if ( FT_IS_FIXED_WIDTH(fnt) )
|
||||||
{
|
{
|
||||||
w = fnt->size->metrics.max_advance>>6;
|
w = fnt->size->metrics.max_advance>>6;
|
||||||
autosize = 0; // don't readjust per-glyph
|
calcsize = 0; // don't readjust per-glyph
|
||||||
}
|
}
|
||||||
else for ( uint32_t i=range[0]; i<=range[1]; i++ )
|
else for ( uint32_t i=range[0]; i<=range[1]; i++ )
|
||||||
{
|
{
|
||||||
|
|
@ -457,8 +428,8 @@ int main( int argc, char **argv )
|
||||||
FT_Render_Glyph(fnt->glyph,RENDERMODE);
|
FT_Render_Glyph(fnt->glyph,RENDERMODE);
|
||||||
int adv = fnt->glyph->linearHoriAdvance>>16;
|
int adv = fnt->glyph->linearHoriAdvance>>16;
|
||||||
int adv2 = fnt->glyph->advance.x>>6;
|
int adv2 = fnt->glyph->advance.x>>6;
|
||||||
if ( !adv ) adv = adv2;
|
if ( adv2 ) adv = adv2;
|
||||||
if ( (adv+rightshift) > w ) w = adv+rightshift;
|
if ( adv > w ) w = adv;
|
||||||
}
|
}
|
||||||
fprintf(stderr,"info: max cell size is %dx%d.\n",w,h);
|
fprintf(stderr,"info: max cell size is %dx%d.\n",w,h);
|
||||||
}
|
}
|
||||||
|
|
@ -483,37 +454,41 @@ int main( int argc, char **argv )
|
||||||
for ( unsigned j=0; j<fnt->glyph->bitmap.rows; j++ )
|
for ( unsigned j=0; j<fnt->glyph->bitmap.rows; j++ )
|
||||||
valid |= valid_row(&fnt->glyph->bitmap,j);
|
valid |= valid_row(&fnt->glyph->bitmap,j);
|
||||||
if ( !valid ) continue;
|
if ( !valid ) continue;
|
||||||
if ( autosize )
|
if ( calcsize )
|
||||||
{
|
{
|
||||||
// readjust cell width (but not height) for this character
|
// readjust cell width (but not height) for this character
|
||||||
int adv = fnt->glyph->linearHoriAdvance>>16;
|
int adv = fnt->glyph->linearHoriAdvance>>16;
|
||||||
int adv2 = fnt->glyph->advance.x>>6;
|
int adv2 = fnt->glyph->advance.x>>6;
|
||||||
if ( !adv ) adv = adv2;
|
if ( adv2 ) adv = adv2;
|
||||||
w = adv+rightshift;
|
w = adv;
|
||||||
iw = w+((gradient&4)?2:1);
|
iw = w+((gradient&4)?2:1);
|
||||||
}
|
}
|
||||||
int xx = rightshift;
|
int xx = 0;
|
||||||
int yy = upshift+xupshift+1;
|
int yy = upshift+tewi_hotfix+miniwi_hotfix;
|
||||||
|
if ( tewi_hotfix && ((i != 0x0309) && (i != 0x030A)) )
|
||||||
|
fnt->glyph->bitmap_top++;
|
||||||
|
if ( miniwi_hotfix && (i == 0x01C2) )
|
||||||
|
fnt->glyph->bitmap_top++;
|
||||||
valid = 0;
|
valid = 0;
|
||||||
oob = 0;
|
oob = 0;
|
||||||
if ( gradient&4 )
|
if ( gradient&4 )
|
||||||
{
|
{
|
||||||
// draw outline first
|
// draw outline first
|
||||||
draw_glyph(&fnt->glyph->bitmap,0,xx,yy,fnt->glyph->bitmap_left,pxsiz-fnt->glyph->bitmap_top);
|
draw_glyph(&fnt->glyph->bitmap,0,xx,yy,fnt->glyph->bitmap_left,h-fnt->glyph->bitmap_top);
|
||||||
draw_glyph(&fnt->glyph->bitmap,0,xx+1,yy,fnt->glyph->bitmap_left,pxsiz-fnt->glyph->bitmap_top);
|
draw_glyph(&fnt->glyph->bitmap,0,xx+1,yy,fnt->glyph->bitmap_left,h-fnt->glyph->bitmap_top);
|
||||||
draw_glyph(&fnt->glyph->bitmap,0,xx+2,yy,fnt->glyph->bitmap_left,pxsiz-fnt->glyph->bitmap_top);
|
draw_glyph(&fnt->glyph->bitmap,0,xx+2,yy,fnt->glyph->bitmap_left,h-fnt->glyph->bitmap_top);
|
||||||
draw_glyph(&fnt->glyph->bitmap,0,xx,yy+1,fnt->glyph->bitmap_left,pxsiz-fnt->glyph->bitmap_top);
|
draw_glyph(&fnt->glyph->bitmap,0,xx,yy+1,fnt->glyph->bitmap_left,h-fnt->glyph->bitmap_top);
|
||||||
draw_glyph(&fnt->glyph->bitmap,0,xx+2,yy+1,fnt->glyph->bitmap_left,pxsiz-fnt->glyph->bitmap_top);
|
draw_glyph(&fnt->glyph->bitmap,0,xx+2,yy+1,fnt->glyph->bitmap_left,h-fnt->glyph->bitmap_top);
|
||||||
draw_glyph(&fnt->glyph->bitmap,0,xx,yy+2,fnt->glyph->bitmap_left,pxsiz-fnt->glyph->bitmap_top);
|
draw_glyph(&fnt->glyph->bitmap,0,xx,yy+2,fnt->glyph->bitmap_left,h-fnt->glyph->bitmap_top);
|
||||||
draw_glyph(&fnt->glyph->bitmap,0,xx+1,yy+2,fnt->glyph->bitmap_left,pxsiz-fnt->glyph->bitmap_top);
|
draw_glyph(&fnt->glyph->bitmap,0,xx+1,yy+2,fnt->glyph->bitmap_left,h-fnt->glyph->bitmap_top);
|
||||||
draw_glyph(&fnt->glyph->bitmap,0,xx+2,yy+2,fnt->glyph->bitmap_left,pxsiz-fnt->glyph->bitmap_top);
|
draw_glyph(&fnt->glyph->bitmap,0,xx+2,yy+2,fnt->glyph->bitmap_left,h-fnt->glyph->bitmap_top);
|
||||||
valid = draw_glyph(&fnt->glyph->bitmap,255,xx+1,yy+1,fnt->glyph->bitmap_left,pxsiz-fnt->glyph->bitmap_top);
|
valid = draw_glyph(&fnt->glyph->bitmap,255,xx+1,yy+1,fnt->glyph->bitmap_left,h-fnt->glyph->bitmap_top);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// draw drop shadow first
|
// draw drop shadow first
|
||||||
draw_glyph(&fnt->glyph->bitmap,0,xx+1,yy+1,fnt->glyph->bitmap_left,pxsiz-fnt->glyph->bitmap_top);
|
draw_glyph(&fnt->glyph->bitmap,0,xx+1,yy+1,fnt->glyph->bitmap_left,h-fnt->glyph->bitmap_top);
|
||||||
valid = draw_glyph(&fnt->glyph->bitmap,255,xx,yy,fnt->glyph->bitmap_left,pxsiz-fnt->glyph->bitmap_top);
|
valid = draw_glyph(&fnt->glyph->bitmap,255,xx,yy,fnt->glyph->bitmap_left,h-fnt->glyph->bitmap_top);
|
||||||
}
|
}
|
||||||
if ( valid )
|
if ( valid )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue