From b2a3b5063b366885da34c446da401a4bb07ec9f0 Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Mon, 11 Apr 2022 14:03:30 +0200 Subject: [PATCH] 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 --- cropng.c | 33 +++++++++++++++++++++++++++--- fuzz.c | 5 ++++- mkfont.c | 62 +++++++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 82 insertions(+), 18 deletions(-) diff --git a/cropng.c b/cropng.c index 51446da..0ece865 100644 --- a/cropng.c +++ b/cropng.c @@ -207,6 +207,8 @@ int savepng( const char *fname, uint8_t *odata, uint32_t w, uint32_t h, int32_t return 1; } +int nocropx = 0, nocropy = 0; + void processpic( const char *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); cropw -= cropx-1; croph -= cropy-1; + if ( nocropx ) + { + cropx = 0; + cropw = w; + } + if ( nocropy ) + { + cropy = 0; + croph = h; + } uint8_t *odata = calloc(cropw*croph,pxsize); uint32_t ow = cropw, oh = croph; int32_t ox = x-cropx, oy = y-cropy; @@ -291,14 +303,29 @@ void processpic( const char *fname ) 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, -"usage: cropng ...\n" +"usage: cropng [-nx] [-ny] ...\n" "\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" "\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" "\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; } - for ( int i=1; ibuffer ) return 0; int drawn = 0; unsigned i, j; for ( j=0; jrows; 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; iwidth; 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; iwidth; 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; inum_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; inum_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; jglyph->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; jglyph->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; jglyph->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; jglyph->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;