From ed66e1448f0b4a291d411339c50d7688b6485b3d Mon Sep 17 00:00:00 2001 From: glenda Date: Sun, 23 Nov 2025 02:08:54 +0000 Subject: [PATCH] lotta refactoring --- ufx2font.c | 202 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 123 insertions(+), 79 deletions(-) diff --git a/ufx2font.c b/ufx2font.c index 0ff846b9906c663c8b8c3792090a05717578e181..9903fadebeb353a0ebbcb5550f29798deb6af53d 100644 --- a/ufx2font.c +++ b/ufx2font.c @@ -7,6 +7,7 @@ #define ufxlen(n) ((n)*(n)*8) #define max(a, b) ((a) > (b) ? (a) : (b)) #define min(a, b) ((a) < (b) ? (a) : (b)) +#define warn(fmt, ...) fprint(2, "%s: " fmt "\n", argv0, __VA_ARGS__) enum{ @@ -50,8 +51,7 @@ struct MapFile *mapfiles, *lastmf; uchar wasmferr, wasreaderr; -uchar *gbitmaps; -struct GlyphInfo *ginfo; +struct GlyphInfo *glyphs; void @@ -120,7 +120,7 @@ _parsemapfile(Biobuf *b, struct MapFile *mf) line = Brdline(b, '\n'); if(line == nil){ if(!wasreaderr) - fprint(2, "%s: warn: %s: empty file\n", argv0, mf->file); + warn("warn: %s: empty file\n", mf->file); return; } @@ -285,64 +285,92 @@ printmapfile(struct MapFile *mf) } } } +void +addmapfile(char *file) +{ + if(lastmf == nil) + mapfiles = lastmf = malloc(sizeof(struct MapFile)); + else + lastmf = lastmf->next = malloc(sizeof(struct MapFile)); + lastmf->file = file; + lastmf->next = nil; + lastmf->mappings = nil; + + parsemapfile(lastmf); +} +void +checkmapfiles(void) +{ + if(wasmferr) + exits("mapfile"); +} void -sniffdims(char *file) +guesswidth(char *file) { uint len; - Dir *d; char c; len = strlen(file); + c = file[len-1]; - if(fwidth < 1){ - c = file[len-1]; - if('1' <= c && c <= '8' && strncmp(file+len-4, ".uf", 3) == 0){ - fwidth = c - '0'; - } + if('1' <= c && c <= '8' && strncmp(file+len-4, ".uf", 3) == 0){ + fwidth = c - '0'; } +} +void +guesslength(char *file, Dir *d) +{ + if(nglyphs == 0){ + if(d->length % (1+glyphlen) != 0) + sysfatal("%s: can't determine file dimensions", file); + nglyphs = d->length / (1+glyphlen); + }else if(nglyphs * (1+glyphlen) > d->length) + sysfatal("%s: file too short", file); +} +void +guessdims(char *file) +{ + Dir *d; + + if(fwidth < 1) + guesswidth(file); if(fwidth < 1) sysfatal("%s: can't determine glyph width", file); glyphlen = ufxlen(fwidth); glyphedge = fwidth * 8; + d = dirstat(file); if(d == nil) sysfatal("%r"); - - if(nglyphs == 0){ - if(d->length % (1+glyphlen) != 0) - sysfatal("%s: can't determine file dimensions", file); - nglyphs = d->length / (1+glyphlen); - }else if(nglyphs * (1+glyphlen) > d->length) - sysfatal("%s: file too short", file); + guesslength(file, d); + free(d); } + + void -loadufx(char *infile) +loadwidths(Biobuf *b, char *file) { - Biobuf *b; - uint i, len; + uint i; int n; - len = nglyphs * glyphlen; - gbitmaps = malloc(len); - ginfo = malloc(nglyphs * sizeof(struct GlyphInfo)); - b = Bopen(infile, OREAD); - for(i = 0; i < nglyphs; i++){ n = Bgetc(b); if(n < 0) sysfatal("%r"); - ginfo[i].width = n; - } - - if(Bread(b, gbitmaps, len) != len) - sysfatal("%r"); + + if(n > glyphedge){ + warn("%s: 0x%02x: bad width %d, truncating\n", file, i, n); + n = glyphedge; + } - Bterm(b); + glyphs[i].width = n; + } } + uchar testscanline(uchar *bitmap, int rowlen) { @@ -357,40 +385,52 @@ testscanline(uchar *bitmap, int rowlen) return 0; } void -parseglyphs(char *file) +parseglyph(uchar *bitmap, struct GlyphInfo *ginfo, uint *botfreqs) { - uint i, y, top, bot, *botfreqs = nil, bestfreq; - int rowlen; + uint top, bot; + int rowlen = ginfo->width; + + for(top = 0; top < glyphedge; top++) + if(testscanline(bitmap+top, rowlen)) + break; + for(bot = glyphedge-1; bot >= top; bot--) + if(testscanline(bitmap+bot, rowlen)) + break; + + if(botfreqs != nil && top <= bot) /* don't count empty glyphs */ + botfreqs[bot]++; + ginfo->top = top; ginfo->bottom = bot; +} +void +readglyphs(Biobuf *b, uint *botfreqs) +{ + uint i; uchar *bitmap; + long n; - if(baseline < 1) - botfreqs = calloc(glyphedge, sizeof(uint)); + bitmap = malloc(glyphlen); for(i = 0; i < nglyphs; i++){ - rowlen = ginfo[i].width; - if(rowlen == 0) - continue; - if(rowlen > glyphedge){ - 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]++; + n = Bread(b, bitmap, glyphlen); + if(n < 0) + sysfatal("%r"); + if(n != glyphlen) + sysfatal("unexpected eof"); + parseglyph(bitmap, glyphs+i, botfreqs); } + free(bitmap); +} +void +loadglyphs(Biobuf *b) +{ + uint i, *botfreqs, bestfreq; + if(baseline < 1){ + botfreqs = calloc(glyphedge, sizeof(uint)); + + readglyphs(b, botfreqs); + bestfreq = 0; for(i = 0; i < glyphedge; i++){ if(botfreqs[i] > bestfreq){ @@ -398,14 +438,32 @@ parseglyphs(char *file) bestfreq = botfreqs[i]; } } - } + }else + readglyphs(b, nil); +} + +void +loadufx(char *infile) +{ + Biobuf *b; + + glyphs = malloc(nglyphs * sizeof(struct GlyphInfo)); + b = Bopen(infile, OREAD); + + loadwidths(b, infile); + loadglyphs(b); + + Bterm(b); } void usage(void) { - fprint(2, "usage: %s [-nh] [-b baseline] [-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"); } @@ -413,7 +471,6 @@ void main(int argc, char **argv) { char *infile, *outdir; - struct MapFile *mf; ARGBEGIN{ case 'l': @@ -434,13 +491,7 @@ main(int argc, char **argv) break; case 'm': setconv = 1; - if(lastmf == nil) - mapfiles = lastmf = malloc(sizeof(struct MapFile)); - else - lastmf = lastmf->next = malloc(sizeof(struct MapFile)); - lastmf->file = EARGF(usage()); - lastmf->next = nil; - lastmf->mappings = nil; + addmapfile(EARGF(usage())); break; case 'b': baseline = atoi(EARGF(usage())); @@ -451,28 +502,21 @@ main(int argc, char **argv) usage(); }ARGEND; + checkmapfiles(); + + if(argv0 == nil) argv0 = "ufx2font"; - if(argc != 2) usage(); + infile = argv[0]; outdir = argv[1]; - sniffdims(infile); + guessdims(infile); if(baseline >= glyphedge) sysfatal("-b: baseline must be in range 1-width*8"); - for(mf = mapfiles; mf != nil; mf = mf->next) - parsemapfile(mf); - if(wasmferr) - exits("mapfile"); - for(mf = mapfiles; mf != nil; mf = mf->next) - printmapfile(mf); - loadufx(infile); - parseglyphs(infile); - - print("baseline=%ud\n", baseline); }