@@ 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);
}