diff --git a/mkfont.c b/mkfont.c index c5c2f33..8597461 100644 --- a/mkfont.c +++ b/mkfont.c @@ -49,10 +49,13 @@ uint8_t pal[768]; int palsize = 0; -int xupshift = 0; -int rightshift = 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 ) { // 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_INTERLACE_NONE,PNG_COMPRESSION_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 = { .name = "grAb", @@ -118,10 +121,10 @@ FT_Library ftlib; FT_Face fnt; int iw, ih; -int w, h, pxsiz, datsiz; +int w, h, datsiz; uint8_t *idata; -int autosize = 0; +int calcsize = 1; int gradient = 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 ) { float a; - int ofs = j+oy+(upshift+1); + int ofs = j+oy+(upshift+tewi_hotfix+miniwi_hotfix); 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); else if ( (gradient&3) == 2 ) rv = lerpg(a); 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 ) { - if ( argc < 4 ) + if ( argc < 3 ) { - fprintf(stderr,"usage: mkfontsingle " - " [gradient type] [color palette] [-palinv]\n"); + fprintf(stderr,"usage: mkfont " + " [gradient type] [color palette] [-palinv]\n"); return 1; } if ( FT_Init_FreeType(&ftlib) ) @@ -355,18 +358,20 @@ int main( int argc, char **argv ) return 2; } uint32_t range[2] = {0x0000,0x00FF}; + int pxsiz; sscanf(argv[2],"%d",&pxsiz); - 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); - if ( argc > 7 ) palinv = !strcmp(argv[7],"-palinv"); - if ( argc > 6 ) loadpalette(argv[6]); + sscanf(argv[3],"%x-%x",&range[0],&range[1]); + if ( argc > 4 ) sscanf(argv[4],"%d",&gradient); + if ( argc > 6 ) palinv = !strcmp(argv[6],"-palinv"); + if ( argc > 5 ) loadpalette(argv[5]); if ( FT_New_Face(ftlib,argv[1],0,&fnt) ) { fprintf(stderr,"error: failed to open font '%s'\n",argv[1]); 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 ( fnt->num_fixed_sizes <= 0 ) @@ -391,10 +396,11 @@ int main( int argc, char **argv ) return 8; } } + h = (fnt->size->metrics.height>>6)-tewi_hotfix-miniwi_hotfix; 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++ ) + for ( uint32_t i=0; i<=0xFFFF; i++ ) { FT_UInt glyph = FT_Get_Char_Index(fnt,i); if ( !glyph || FT_Load_Glyph(fnt,glyph,LOADFLAGS) ) continue; @@ -407,48 +413,13 @@ int main( int argc, char **argv ) if ( gshift < upshift ) upshift = gshift; } 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++ ) + // second pass to compute the maximum cell size (for memory allocation) + if ( calcsize ) { - 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++ ) - { - 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) ) { 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++ ) { @@ -457,8 +428,8 @@ int main( int argc, char **argv ) FT_Render_Glyph(fnt->glyph,RENDERMODE); int adv = fnt->glyph->linearHoriAdvance>>16; int adv2 = fnt->glyph->advance.x>>6; - if ( !adv ) adv = adv2; - if ( (adv+rightshift) > w ) w = adv+rightshift; + if ( adv2 ) adv = adv2; + if ( adv > w ) w = adv; } 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; jglyph->bitmap.rows; j++ ) valid |= valid_row(&fnt->glyph->bitmap,j); if ( !valid ) continue; - if ( autosize ) + if ( calcsize ) { // readjust cell width (but not height) for this character int adv = fnt->glyph->linearHoriAdvance>>16; int adv2 = fnt->glyph->advance.x>>6; - if ( !adv ) adv = adv2; - w = adv+rightshift; + if ( adv2 ) adv = adv2; + w = adv; iw = w+((gradient&4)?2:1); } - int xx = rightshift; - int yy = upshift+xupshift+1; + int xx = 0; + 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; oob = 0; if ( gradient&4 ) { // 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+1,yy,fnt->glyph->bitmap_left,pxsiz-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,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,pxsiz-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+1,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,pxsiz-fnt->glyph->bitmap_top); - valid = draw_glyph(&fnt->glyph->bitmap,255,xx+1,yy+1,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,h-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,h-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,h-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,h-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 { // draw drop shadow first - draw_glyph(&fnt->glyph->bitmap,0,xx+1,yy+1,fnt->glyph->bitmap_left,pxsiz-fnt->glyph->bitmap_top); - valid = draw_glyph(&fnt->glyph->bitmap,255,xx,yy,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,h-fnt->glyph->bitmap_top); } if ( valid ) {