From df42e8d73c6cc5ddd7de73a1af1c64b71da94198 Mon Sep 17 00:00:00 2001 From: glenda Date: Sun, 23 Nov 2025 22:38:33 +0000 Subject: [PATCH] =?UTF-8?q?generate=20=E2=85=94=20of=20the=20fonts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ufx2font.c | 229 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 219 insertions(+), 10 deletions(-) diff --git a/ufx2font.c b/ufx2font.c index 72ba980afbba42013389e4a2cfee84363a4aa521..1583913b42a286b33239b9a363dc3faf04f7f3cd 100644 --- a/ufx2font.c +++ b/ufx2font.c @@ -48,6 +48,7 @@ struct GlyphInfo{ }; struct RawSubfont{ + Memimage *img; char n[12], height[12], ascent[12]; uchar entries[][6]; }; @@ -534,6 +535,7 @@ parseglyph(uchar *bitmap, struct GlyphInfo *ginfo, uint *botfreqs) for(bot = glyphedge-1; bot >= top; bot--) if(testscanline(bitmap+bot, rowlen)) break; + bot++; if(botfreqs != nil && top <= bot) /* don't count empty glyphs */ botfreqs[bot]++; @@ -612,12 +614,220 @@ loadufx(char *infile) Bterm(b); } +struct RawSubfont * +allocrawsubfont(uint n, uint width) +{ + char buf[13]; + struct RawSubfont *ret; + + ret = malloc(sizeof(struct RawSubfont)+n*6+6); + + ret->img = allocmemimage(Rect(0,0, width,glyphedge), strtochan("k1")); + if(ret->img == nil) + sysfatal("%r"); + + snprint(buf, 13, "%11ud ", n); + memcpy(ret->n, buf, 12); + snprint(buf, 13, "%11ud ", glyphedge); + memcpy(ret->height, buf, 12); + snprint(buf, 13, "%11ud ", baseline); + memcpy(ret->ascent, buf, 12); + + return ret; +} +void +setsubfontparams(struct RawSubfont *s, uint x, uint src, uint dst) +{ + s->entries[dst][0] = x &0xff; + s->entries[dst][1] = (x>>8)&0xff; + + if(glyphs[src].top >= glyphs[src].bottom){ + s->entries[dst][2] = 0; + s->entries[dst][3] = glyphedge; + }else{ + s->entries[dst][2] = glyphs[src].top; + s->entries[dst][3] = glyphs[src].bottom; + } + + s->entries[dst][4] = 0; + + s->entries[dst][5] = glyphs[src].width; +} +void +copyglyph(uint i, uint *x, Memimage *img) +{ + Point dstcorner, srccorner, offset; + Rectangle dst; + + offset = Pt(glyphs[i].width,glyphedge); + dstcorner = Pt(*x,0); + srccorner = Pt(i*glyphedge,0); + + dst = Rpt(dstcorner, addpt(dstcorner, offset)); + + memimagedraw(img, dst, glyphimg, srccorner, nil, Pt(0,0), SoverD); + + *x += glyphs[i].width; +} +char * +saverawsubfont(char *base, Rune r1, Rune r2, struct RawSubfont *s) +{ + char *file; + uchar *sfdata; + ulong sfdlen; + uint n; + int fd; + + n = r2 - r1; + sfdata = (uchar *)s + sizeof(Memimage *); + sfdlen = sizeof(struct RawSubfont)-sizeof(Memimage *)+n*6+6; + + file = smprint("%s.%04uX-%04uX", base, r1, r2-1); + + fd = create(file, OWRITE, 0644); + if(fd < 0) + sysfatal("%r"); + + + if(writememimage(fd, s->img) != 0) + sysfatal("memimage"); + + if(write(fd, sfdata, sfdlen) != sfdlen) + sysfatal("%r"); + + + close(fd); + + return file; +} +void +freerawsubfont(struct RawSubfont *s) +{ + freememimage(s->img); + free(s); +} + +int +createfont(char *file) +{ + int fd, err; + + fd = create(file, OWRITE, 0644); + if(fd < 0) + sysfatal("%r"); + + err = fprint(fd, "%ud %ud\n", glyphedge, baseline); + if(err < 0) + sysfatal("%r"); + + return fd; +} +void +appendfont(int fd, Rune r1, Rune r2, uint off, char *file) +{ + int err; + + if(off > 0) + err = fprint(fd, "0x%04ux\t0x%04ux\t0x%04ux\t%s\n", r1, r2, off, file); + else + err = fprint(fd, "0x%04ux\t0x%04ux\t%s\n", r1, r2, file); + + if(err < 0) + sysfatal("%r"); +} + +void +savenaivefont(char *file) +{ + int fd; + + fd = createfont("naive.font"); + appendfont(fd, 0, nglyphs-1, 0, file); + close(fd); +} void makenaive(void) { + uint width = 0, x = 0, i; + struct RawSubfont *s; + char *file; + + for(i = 0; i < nglyphs; i++) + width += glyphs[i].width; + + s = allocrawsubfont(nglyphs, width); + + + for(i = 0; i < nglyphs; i++){ + setsubfontparams(s, x, i, i); + copyglyph(i, &x, s->img); + } + setsubfontparams(s, x, 0, i); + + file = saverawsubfont("naive", 0, nglyphs, s); + savenaivefont(file); + + freerawsubfont(s); + free(file); +} + +char * +makenoholessubfont(void) +{ + uint width = 0, x = 0, n = 0, i, j; + struct RawSubfont *s; + char *file; + + for(i = 0; i < nglyphs; i++){ + width += glyphs[i].width; + n++; + } + + s = allocrawsubfont(n, width); + + j = 0; + for(i = 0; i < nglyphs; i++){ + if(glyphs[i].width == 0) + continue; + setsubfontparams(s, x, i, j); + copyglyph(i, &x, s->img); + + j++; + } + setsubfontparams(s, x, 0, i); + file = saverawsubfont("noholes", 0, n, s); + freerawsubfont(s); + + return file; +} +void +makenoholes(void) +{ + char *subfont; int fd; - struct RawSubfont s; + uint i, j = 0, n = 0; + + subfont = makenoholessubfont(); + fd = createfont("noholes.font"); + + for(i = 0; i < nglyphs; i++){ + if(glyphs[i].width == 0){ + if(n != 0){ + appendfont(fd, i-n, i-1, j, subfont); + j += n; + n = 0; + } + continue; + } + + n++; + } + if(n != 0) + appendfont(fd, i-n, i-1, j, subfont); + + free(subfont); + close(fd); } @@ -635,7 +845,7 @@ void main(int argc, char **argv) { char *infile, *outdir; - int fd; + int fd, err; ARGBEGIN{ case 'l': @@ -683,6 +893,8 @@ main(int argc, char **argv) checkmapfiles(); + if(memimageinit() != 0) + sysfatal("%r"); loadufx(infile); @@ -690,15 +902,12 @@ main(int argc, char **argv) if(fd < 0) sysfatal("%r"); close(fd); - chdir(outdir); - - fd = create("test", OWRITE, 0777); - writememimage(fd, glyphimg); - close(fd); + if(chdir(outdir) != 0) + sysfatal("%r"); if(!setconv || donaive) makenaive(); -/* if(!setconv || doholes) - makeholes(); - makemapped();*/ + if(!setconv || doholes) + makenoholes(); +/* makemapped();*/ }