~aleteoryx/9c

fc5841aa95872eddc403b9618747d07ca9a92c91 — glenda 12 days ago 4a9ae0e
glyph metrics
1 files changed, 48 insertions(+), 59 deletions(-)

M ufx2font.c
M ufx2font.c => ufx2font.c +48 -59
@@ 5,6 5,8 @@

/* entry has 1 byte in widtab + 8 bytes per tile */
#define ufxlen(n) ((n)*(n)*8)
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))


enum{


@@ 41,7 43,7 @@ struct GlyphInfo{
};


uint fwidth, nglyphs, glyphlen, glyphedge;
uint fwidth, nglyphs, glyphlen, glyphedge, baseline;

uchar setconv, donaive, doholes;
struct MapFile *mapfiles, *lastmf;


@@ 341,49 343,28 @@ loadufx(char *infile)

	Bterm(b);
}
void
testcol(uchar len, uint offset, uchar *top, uchar *bot)
{
	uchar mask;

	if(len > 8)
		len = 8;
	mask = 0xff<<(8-len);

	for(*top = 0; *top < glyphedge; (*top)++){
		print("gbitmaps[off+top]=%2ux; mask=%2ux\n", gbitmaps[offset + *top], mask);
		if(gbitmaps[offset + *top] & mask != 0)
			break;
	}
	
	for(*bot = (glyphedge - 1); *bot >= *top; (*bot)--)
		if(gbitmaps[offset + *bot] & mask != 0)
			break;
}
/*
uchar
highbit(uchar b)
testscanline(uchar *bitmap, int rowlen)
{
	uchar i = 0;
	while(b != 0){
		i++;
		b >>= 1;
	uchar mask, x;
	for(x = 0; x <= (rowlen-1)/8; x++){
		/* ignore the right edge of the last byte */
		mask = 0xff << (8-min(8, rowlen-x*8));
		if((bitmap[x*glyphedge] & mask) != 0)
			return 1;
	}

	return 8 - i;	// returns 8 if b == 0
	return 0;	
}
uchar
findleft(uint offset)
{
	uchar left = 0;
}
*/
void
parseglyphs(char *file)
{
	uint i, offset;
	uint i, y, top, bot, *botfreqs = nil, bestfreq;
	int rowlen;
	uchar top, bot;
	uchar *bitmap;

	if(baseline < 1)
		botfreqs = calloc(glyphedge, sizeof(uint));

	for(i = 0; i < nglyphs; i++){
		rowlen = ginfo[i].width;


@@ 393,31 374,30 @@ parseglyphs(char *file)
			fprint(2, "%s: %s: 0x%2x: bad width %dpx, truncating\n", argv0, file, i, rowlen);
			rowlen = glyphedge;
		}
		bitmap = gbitmaps+i*glyphlen;

		for(y = 0; y < glyphedge; y++)
			if(testscanline(bitmap+y, rowlen))
				break;
		top = y;
		for(y = glyphedge-1; y >= top; y--)
			if(testscanline(bitmap+y, rowlen))
				break;
		bot = y;

		ginfo[i].top = top; ginfo[i].bottom = bot;
		if(baseline < 1 && top <= bot)	/* don't count empty glyphs */
			botfreqs[bot]++;
	}

		offset = glyphlen * i;
		ginfo[i].top = glyphedge;
		ginfo[i].bottom = 0;

		while(rowlen > 0){
			testcol(rowlen, offset, &top, &bot);
			if(top < ginfo[i].top)
				ginfo[i].top = top;
			if(bot > ginfo[i].bottom)
				ginfo[i].bottom = bot;

			// TODO: calculate .left, maybe?

			offset += glyphedge;
			rowlen -= 8;
		}

		if(ginfo[i].top == glyphedge){
			// blank glyph
			ginfo[i].top = 0;
			ginfo[i].bottom = glyphedge - 1;
	if(baseline < 1){
		bestfreq = 0;
		for(i = 0; i < glyphedge; i++){
			if(botfreqs[i] > bestfreq){
				baseline = i;
				bestfreq = botfreqs[i];
			}
		}

		print("glyphs[%2x]: rowlen=%02d top=%02d bottom=%02d\n", i, ginfo[i].width, ginfo[i].top, ginfo[i].bottom);
	}
}



@@ 425,7 405,7 @@ parseglyphs(char *file)
void
usage(void)
{
	fprint(2, "usage: %s [-nh] [-m mapfile] [-l length] [-x width] in.ufx out/\n", argv0);
	fprint(2, "usage: %s [-nh] [-b baseline] [-m mapfile] [-l length] [-x width] in.ufx out/\n", argv0);
	exits("usage");
}



@@ 462,6 442,11 @@ main(int argc, char **argv)
		lastmf->next = nil;
		lastmf->mappings = nil;
		break;
	case 'b':
		baseline = atoi(EARGF(usage()));
		if(baseline < 1)
			sysfatal("-b: baseline must be in range 1-width*8");
		break;
	default:
		usage();
	}ARGEND;


@@ 476,6 461,8 @@ main(int argc, char **argv)


	sniffdims(infile);
	if(baseline >= glyphedge)
		sysfatal("-b: baseline must be in range 1-width*8");

	for(mf = mapfiles; mf != nil; mf = mf->next)
		parsemapfile(mf);


@@ 486,4 473,6 @@ main(int argc, char **argv)

	loadufx(infile);
	parseglyphs(infile);

	print("baseline=%ud\n", baseline);
}