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

@ -207,6 +207,8 @@ int savepng( const char *fname, uint8_t *odata, uint32_t w, uint32_t h, int32_t
return 1; return 1;
} }
int nocropx = 0, nocropy = 0;
void processpic( const char *fname ) void processpic( const char *fname )
{ {
printf("Processing '%s'...\n",fname); printf("Processing '%s'...\n",fname);
@ -266,6 +268,16 @@ void processpic( const char *fname )
printf(" Crop region: (%u,%u) (%u,%u).\n",cropx,cropy,cropw,croph); printf(" Crop region: (%u,%u) (%u,%u).\n",cropx,cropy,cropw,croph);
cropw -= cropx-1; cropw -= cropx-1;
croph -= cropy-1; croph -= cropy-1;
if ( nocropx )
{
cropx = 0;
cropw = w;
}
if ( nocropy )
{
cropy = 0;
croph = h;
}
uint8_t *odata = calloc(cropw*croph,pxsize); uint8_t *odata = calloc(cropw*croph,pxsize);
uint32_t ow = cropw, oh = croph; uint32_t ow = cropw, oh = croph;
int32_t ox = x-cropx, oy = y-cropy; int32_t ox = x-cropx, oy = y-cropy;
@ -291,14 +303,29 @@ void processpic( const char *fname )
int main( int argc, char **argv ) int main( int argc, char **argv )
{ {
if ( argc < 2 ) int ac = 1;
if ( (argc > ac) && !strcmp(argv[ac],"-nx") )
{
nocropx = 1;
ac++;
}
if ( (argc > ac) && !strcmp(argv[ac],"-ny") )
{
nocropy = 1;
ac++;
}
if ( argc <= ac )
{ {
fprintf(stderr, fprintf(stderr,
"usage: cropng <file> ...\n" "usage: cropng [-nx] [-ny] <file> ...\n"
"\n" "\n"
"cropng will trim excess transparency from PNG images while updating grAb\n" "cropng will trim excess transparency from PNG images while updating grAb\n"
"offsets to compensate (existing ones will be re-used as a base)\n" "offsets to compensate (existing ones will be re-used as a base)\n"
"\n" "\n"
"if the -nx argument is passed, it won't trim the width.\n"
"if the -ny argument is passed, it won't trim the height.\n"
"(if both arguments are passed, the program will not alter the image data)\n"
"\n"
"files are updated in-place, but a backup will be kept in case errors happen.\n" "files are updated in-place, but a backup will be kept in case errors happen.\n"
"\n" "\n"
"cropng supports paletted, color and grayscale PNGs at both 8bpc and 16bpc.\n" "cropng supports paletted, color and grayscale PNGs at both 8bpc and 16bpc.\n"
@ -308,6 +335,6 @@ int main( int argc, char **argv )
); );
return 1; return 1;
} }
for ( int i=1; i<argc; i++ ) processpic(argv[i]); for ( int i=ac; i<argc; i++ ) processpic(argv[i]);
return 0; return 0;
} }

5
fuzz.c
View file

@ -63,7 +63,10 @@ rgbfpx_t layers[3] =
//{1.31f,0.87f,1.25f,1.f}, //{1.31f,0.87f,1.25f,1.f},
//{0.76f,0.64f,0.63f,1.f}, //{0.76f,0.64f,0.63f,1.f},
//{1.25f,1.13f,0.21f,1.f} //{1.25f,1.13f,0.21f,1.f}
// CHILD OF ASH
//{0.71f,0.97f,1.05f,1.f},
//{0.96f,0.74f,0.63f,1.f},
//{0.95f,0.93f,1.21f,1.f}
}; };
float speed[3] = float speed[3] =
{ {

View file

@ -30,9 +30,8 @@
- There is currently no handling of proportional fonts whatsoever, this - There is currently no handling of proportional fonts whatsoever, this
expects monospaced fonts where all glyphs have the same size. Dunno expects monospaced fonts where all glyphs have the same size. Dunno
if I'd ever bother with that in the future. if I'd ever bother with that in the future.
- While non-bitmap fonts are technically supported, they will - Non-bitmap fonts might sometimes spew lots of (out of bounds) drawing
oftentimes act extremely weirdly (e.g.: some glyphs will have REALLY warnings. This is mainly due to the peculiarities of antialiasing.
broken offsets).
- Doesn't handle unicode blocks beyond the basic multilingual plane, - Doesn't handle unicode blocks beyond the basic multilingual plane,
might actually be an issue with freetype itself, or the fonts I use, 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 though I CAN see that the glyphs are there if I use a character map
@ -49,6 +48,8 @@
uint8_t pal[768]; uint8_t pal[768];
int palsize = 0; int palsize = 0;
int xupshift = 0; int xupshift = 0;
int rightshift = 0;
int bordshift = 0;
uint32_t endianswap( uint32_t n ) 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_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 ) 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 = png_unknown_chunk grab =
{ {
.name = "grAb", .name = "grAb",
@ -175,8 +176,9 @@ uint8_t lerpg( float a )
return (uint8_t)(a*191+64); 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; int drawn = 0;
unsigned i, j; unsigned i, j;
for ( j=0; j<bmp->rows; 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 ) int valid_row( FT_Bitmap *bmp, unsigned j )
{ {
if ( !bmp->buffer ) return 0;
int drawn = 0; int drawn = 0;
for ( unsigned i=0; i<bmp->width; i++ ) 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 ) unsigned row_width( FT_Bitmap *bmp, unsigned j )
{ {
if ( !bmp->buffer ) return 0;
unsigned dw = 0; unsigned dw = 0;
for ( unsigned i=0; i<bmp->width; i++ ) for ( unsigned i=0; i<bmp->width; i++ )
{ {
@ -331,7 +335,7 @@ const char grads[8][20] =
"Centered (Border)" "Centered (Border)"
}; };
#define LOADFLAGS FT_LOAD_DEFAULT #define LOADFLAGS FT_LOAD_PEDANTIC
#define RENDERMODE FT_RENDER_MODE_NORMAL #define RENDERMODE FT_RENDER_MODE_NORMAL
int main( int argc, char **argv ) int main( int argc, char **argv )
@ -366,16 +370,36 @@ int main( int argc, char **argv )
} }
if ( FT_Set_Pixel_Sizes(fnt,0,pxsiz) ) if ( FT_Set_Pixel_Sizes(fnt,0,pxsiz) )
{ {
fprintf(stderr,"error: font pixel size of '%d' not available\n",pxsiz); if ( fnt->num_fixed_sizes <= 0 )
return 8; {
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); FT_Select_Charmap(fnt,FT_ENCODING_UNICODE);
// first pass to compute baseline upshift // first pass to compute baseline upshift
upshift = 65535;
for ( uint32_t i=range[0]; i<=range[1]; i++ ) for ( uint32_t i=range[0]; i<=range[1]; 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;
FT_Render_Glyph(fnt->glyph,RENDERMODE); // also render it while we're at it FT_Render_Glyph(fnt->glyph,RENDERMODE);
int valid = 0; int valid = 0;
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);
@ -385,14 +409,19 @@ int main( int argc, char **argv )
} }
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 "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++ ) for ( uint32_t i=range[0]; i<=range[1]; 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;
FT_Render_Glyph(fnt->glyph,RENDERMODE);
int valid = 0; int valid = 0;
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;
int xx = fnt->glyph->bitmap_left;
if ( -xx > rightshift ) rightshift = -xx;
int yy = upshift+1+(pxsiz-fnt->glyph->bitmap_top); int yy = upshift+1+(pxsiz-fnt->glyph->bitmap_top);
for ( unsigned j=0; j<fnt->glyph->bitmap.rows; j++ ) for ( unsigned j=0; j<fnt->glyph->bitmap.rows; j++ )
{ {
@ -402,15 +431,17 @@ int main( int argc, char **argv )
if ( yy < 0 ) if ( yy < 0 )
{ {
int xup = -yy; 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 ) if ( xupshift )
{ {
fprintf(stderr,"info: real upshift is %d.\n",upshift+xupshift); fprintf(stderr,"info: real upshift is %d.\n",upshift+xupshift);
fprintf(stderr,"info: grAb Y offset %d will be used.\n",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 // third pass to compute the "real" cell size
if ( w == -1 ) if ( w == -1 )
{ {
@ -418,11 +449,12 @@ int main( int argc, char **argv )
{ {
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;
FT_Render_Glyph(fnt->glyph,RENDERMODE);
int valid = 0; int valid = 0;
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;
int gw = fnt->glyph->bitmap_left; int gw = fnt->glyph->bitmap_left+rightshift;
int gh = (upshift+xupshift+1)+(pxsiz-fnt->glyph->bitmap_top); int gh = (upshift+xupshift+1)+(pxsiz-fnt->glyph->bitmap_top);
int mw = 0; int mw = 0;
int mh = 0; int mh = 0;
@ -444,6 +476,7 @@ int main( int argc, char **argv )
ih = h+1; ih = h+1;
if ( gradient&4 ) if ( gradient&4 )
{ {
bordshift = 1;
iw++; iw++;
ih++; ih++;
} }
@ -454,7 +487,8 @@ int main( int argc, char **argv )
{ {
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;
int xx = 0; FT_Render_Glyph(fnt->glyph,RENDERMODE);
int xx = rightshift;
int yy = upshift+xupshift+1; int yy = upshift+xupshift+1;
int valid; int valid;
oob = 0; oob = 0;