cropng: switches for toggling horizontal/vertical cropping

mkfont: auto-offset by 1,1 when full outline is enabled
mkfont: better handling of glyph offsets
fuzz: added Child of Ash palette
This commit is contained in:
Marisa the Magician 2022-04-11 14:03:30 +02:00
commit b2a3b5063b
3 changed files with 82 additions and 18 deletions

View file

@ -30,9 +30,8 @@
- 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.
- While non-bitmap fonts are technically supported, they will
oftentimes act extremely weirdly (e.g.: some glyphs will have REALLY
broken offsets).
- 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,
though I CAN see that the glyphs are there if I use a character map
@ -49,6 +48,8 @@
uint8_t pal[768];
int palsize = 0;
int xupshift = 0;
int rightshift = 0;
int bordshift = 0;
uint32_t endianswap( uint32_t n )
{
@ -91,9 +92,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_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
if ( xupshift )
if ( xupshift || rightshift || bordshift )
{
uint32_t grabs[2] = {0,endianswap(xupshift)};
uint32_t grabs[2] = {endianswap(rightshift+bordshift),endianswap(xupshift+bordshift)};
png_unknown_chunk grab =
{
.name = "grAb",
@ -175,8 +176,9 @@ uint8_t lerpg( float a )
return (uint8_t)(a*191+64);
}
int draw_glyph( FT_Bitmap *bmp, uint8_t v, uint32_t px, uint32_t py, uint8_t ox, uint8_t oy )
int draw_glyph( FT_Bitmap *bmp, uint8_t v, int px, int py, int ox, int oy )
{
if ( !bmp->buffer ) return 0;
int drawn = 0;
unsigned i, j;
for ( j=0; j<bmp->rows; j++ )
@ -217,6 +219,7 @@ int draw_glyph( FT_Bitmap *bmp, uint8_t v, uint32_t px, uint32_t py, uint8_t ox,
int valid_row( FT_Bitmap *bmp, unsigned j )
{
if ( !bmp->buffer ) return 0;
int drawn = 0;
for ( unsigned i=0; i<bmp->width; i++ )
{
@ -239,6 +242,7 @@ int valid_row( FT_Bitmap *bmp, unsigned j )
unsigned row_width( FT_Bitmap *bmp, unsigned j )
{
if ( !bmp->buffer ) return 0;
unsigned dw = 0;
for ( unsigned i=0; i<bmp->width; i++ )
{
@ -331,7 +335,7 @@ const char grads[8][20] =
"Centered (Border)"
};
#define LOADFLAGS FT_LOAD_DEFAULT
#define LOADFLAGS FT_LOAD_PEDANTIC
#define RENDERMODE FT_RENDER_MODE_NORMAL
int main( int argc, char **argv )
@ -366,16 +370,36 @@ int main( int argc, char **argv )
}
if ( FT_Set_Pixel_Sizes(fnt,0,pxsiz) )
{
fprintf(stderr,"error: font pixel size of '%d' not available\n",pxsiz);
return 8;
if ( fnt->num_fixed_sizes <= 0 )
{
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);
int match = -1;
for ( int i=0; i<fnt->num_fixed_sizes; i++ )
{
if ( fnt->available_sizes[i].height == pxsiz ) continue;
match = i;
break;
}
if ( (match == -1) || FT_Select_Size(fnt,match) )
{
fprintf(stderr,"error: font fixed size of '%d' not available\n",pxsiz);
fprintf(stderr,"available size(s): ");
for ( int i=0; i<fnt->num_fixed_sizes; i++ )
fprintf(stderr,"%u%s",fnt->available_sizes[i].height,(i<(fnt->num_fixed_sizes-1))?", ":".\n");
return 8;
}
}
FT_Select_Charmap(fnt,FT_ENCODING_UNICODE);
// first pass to compute baseline upshift
upshift = 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); // also render it while we're at it
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);
@ -385,14 +409,19 @@ int main( int argc, char **argv )
}
fprintf(stderr,"info: estimated baseline upshift is %d.\n",upshift);
// second pass to compute "real" upshift, which is used for the grAb Y offset
// as well as the "rightshift" for the X offset
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++ )
{
@ -402,15 +431,17 @@ int main( int argc, char **argv )
if ( yy < 0 )
{
int xup = -yy;
printf("%04X - top: %d upshift: %d yy: %d xup: %d\n",i,fnt->glyph->bitmap_top,upshift,yy,xup);
if ( xup > xupshift ) xupshift = xup;
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 "real" cell size
if ( w == -1 )
{
@ -418,11 +449,12 @@ int main( int argc, char **argv )
{
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;
int gw = fnt->glyph->bitmap_left+rightshift;
int gh = (upshift+xupshift+1)+(pxsiz-fnt->glyph->bitmap_top);
int mw = 0;
int mh = 0;
@ -444,6 +476,7 @@ int main( int argc, char **argv )
ih = h+1;
if ( gradient&4 )
{
bordshift = 1;
iw++;
ih++;
}
@ -454,7 +487,8 @@ int main( int argc, char **argv )
{
FT_UInt glyph = FT_Get_Char_Index(fnt,i);
if ( !glyph || FT_Load_Glyph(fnt,glyph,LOADFLAGS) ) continue;
int xx = 0;
FT_Render_Glyph(fnt->glyph,RENDERMODE);
int xx = rightshift;
int yy = upshift+xupshift+1;
int valid;
oob = 0;