mkfont update, now supports variable width fonts.

This commit is contained in:
Marisa the Magician 2022-09-22 17:24:02 +02:00
commit 7e47305aa4

View file

@ -27,10 +27,12 @@
/*
Known bugs/limitations:
- There is currently no handling of proportional fonts whatsoever, this
expects monospaced fonts where all glyphs have the same size. Dunno
if I'd ever bother with that in the future.
- Non-bitmap fonts might sometimes spew lots of (out of bounds) drawing
- There is no handling of proportional fonts where glyphs are wider
than their advance length. As this isn't supported by GZDoom itself,
it's not a priority either. There's no way to encode the "real width"
of a glyph into the PNG. Also, glyphs might end up rendered with
cropped sides.
- Non-bitmap fonts might sometimes spew lots of "out of bounds" drawing
warnings. This is mainly due to the peculiarities of antialiasing.
- Doesn't handle unicode blocks beyond the basic multilingual plane,
might actually be an issue with freetype itself, or the fonts I use,
@ -116,9 +118,10 @@ FT_Library ftlib;
FT_Face fnt;
int iw, ih;
int w, h, pxsiz;
int w, h, pxsiz, datsiz;
uint8_t *idata;
int autosize = 0;
int gradient = 0;
int upshift = 0;
@ -353,11 +356,7 @@ int main( int argc, char **argv )
}
uint32_t range[2] = {0x0000,0x00FF};
sscanf(argv[2],"%d",&pxsiz);
if ( !strcmp(argv[3],"auto") )
{
w = -1;
h = -1;
}
if ( !strcmp(argv[3],"auto") ) autosize = 1;
else sscanf(argv[3],"%dx%d",&w,&h);
sscanf(argv[4],"%x-%x",&range[0],&range[1]);
if ( argc > 5 ) sscanf(argv[5],"%d",&gradient);
@ -372,7 +371,7 @@ int main( int argc, char **argv )
{
if ( fnt->num_fixed_sizes <= 0 )
{
fprintf(stderr,"error: font pixel size of '%d' not available\n",pxsiz);
fprintf(stderr,"error: font pixel size of '%d' not available.\n",pxsiz);
return 8;
}
fprintf(stderr,"warning: failed to set pixel size '%d', trying fixed sizes.\n",pxsiz);
@ -442,35 +441,19 @@ int main( int argc, char **argv )
}
if ( rightshift )
fprintf(stderr,"info: right shift detected, grAb X offset %d will be used.\n",rightshift);
// third pass to compute the "real" cell size
if ( w == -1 )
// third pass to compute the maximum cell size (for memory allocation)
if ( autosize )
{
h = pxsiz+1; // should be fine
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 gw = fnt->glyph->bitmap_left+rightshift;
int gh = (upshift+xupshift+1)+(pxsiz-fnt->glyph->bitmap_top);
int mw = 0;
int mh = 0;
for ( unsigned j=0; j<fnt->glyph->bitmap.rows; j++ )
{
if ( !valid_row(&fnt->glyph->bitmap,j) ) continue;
int rw = row_width(&fnt->glyph->bitmap,j);
if ( rw > mw ) mw = rw;
mh = j;
}
gw += mw+1;
gh += mh+1;
if ( gw > w ) w = gw;
if ( gh > h ) h = gh;
int adv = fnt->glyph->linearHoriAdvance>>16;
if ( adv > w ) w = adv;
}
fprintf(stderr,"info: guessed cell size is %dx%d.\n",w,h);
fprintf(stderr,"info: max cell size is %dx%d.\n",w,h);
}
iw = w+1;
ih = h+1;
@ -480,17 +463,29 @@ int main( int argc, char **argv )
iw++;
ih++;
}
datsiz = palsize?(iw*ih*4):(iw*ih*2);
fprintf(stderr,"info: gradient selected is '%s'.\n",grads[gradient&7]);
idata = calloc(iw*ih,palsize?4:2);
idata = calloc(datsiz,1);
uint32_t drawn = 0;
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;
if ( autosize )
{
// readjust cell width (but not height) for this character
int adv = fnt->glyph->linearHoriAdvance>>16;
w = adv;
iw = w+((gradient&4)?2:1);
}
int xx = rightshift;
int yy = upshift+xupshift+1;
int valid;
valid = 0;
oob = 0;
if ( gradient&4 )
{
@ -519,7 +514,7 @@ int main( int argc, char **argv )
writepng(fname,idata,iw,ih,palsize?(iw*4):(iw*2));
drawn++;
}
memset(idata,0,palsize?(iw*ih*4):(iw*ih*2));
memset(idata,0,datsiz);
}
fprintf(stderr,"info: %u glyphs drawn.\n",drawn);
free(idata);