commit 77f23268f7073b254e91748d4764768bab6d6f1f from: Russ Cox date: Tue Feb 17 05:58:37 2015 UTC libdraw: add 2*font syntax for scaled fonts An experiment. Change-Id: I40660a211b8372701597d80f7e86917e94cccbaa Reviewed-on: https://plan9port-review.googlesource.com/1161 Reviewed-by: Russ Cox commit - 32dc15fa62d94c88f0b62bfe4d64ba60fe1733a6 commit + 77f23268f7073b254e91748d4764768bab6d6f1f blob - d5f2ca693974461ddbb80a82b79825efd6092659 blob + ff760dd7609a921c1c8912cf5585f71d118706b8 --- include/draw.h +++ include/draw.h @@ -314,6 +314,7 @@ struct Font int maxdepth; /* maximum depth of all loaded subfonts */ int ncache; /* size of cache */ int nsubf; /* size of subfont list */ + int scale; /* pixel scaling to apply */ Cacheinfo *cache; Cachesubf *subf; Cachefont **sub; /* as read from file */ @@ -482,7 +483,7 @@ extern int runestringnwidth(Font*, Rune*, int); extern Point strsubfontwidth(Subfont*, char*); extern int loadchar(Font*, Rune, Cacheinfo*, int, int, char**); extern char* subfontname(char*, char*, int); -extern Subfont* _getsubfont(Display*, char*); +extern Subfont* _getsubfont(Display*, Font*, char*); extern Subfont* getdefont(Display*); extern void lockdisplay(Display*); extern void unlockdisplay(Display*); blob - 75b59b11914e1f6bcff3757971c35b25b74425a8 blob + 0f14022e1195dd325160e334fbe256064d0097e6 --- src/libdraw/buildfont.c +++ src/libdraw/buildfont.c @@ -25,6 +25,7 @@ buildfont(Display *d, char *buf, char *name) if(fnt == 0) return 0; memset(fnt, 0, sizeof(Font)); + fnt->scale = 1; fnt->display = d; fnt->name = strdup(name); fnt->ncache = NFCACHE+NFLOOK; blob - 0d8be9ff4e2a99a9a0e74d449e5bc2010cd88237 blob + 3f3b69545612c0351eb15e7047c3c2bbd48547d3 --- src/libdraw/getsubfont.c +++ src/libdraw/getsubfont.c @@ -8,8 +8,10 @@ int _fontpipe(char*); +static void scalesubfont(Subfont*, int); + Subfont* -_getsubfont(Display *d, char *name) +_getsubfont(Display *d, Font *ff, char *name) { int fd; Subfont *f; @@ -36,5 +38,61 @@ _getsubfont(Display *d, char *name) if(f == 0) fprint(2, "getsubfont: can't read %s: %r\n", name); close(fd); + if(ff->scale != 1 && ff->scale != 0) + scalesubfont(f, ff->scale); return f; } + +static void +scalesubfont(Subfont *f, int scale) +{ + Image *i; + Rectangle r, r2; + int y, x, x2, j; + uchar *src, *dst; + int srcn, dstn, n, mask, v, pack; + + r = f->bits->r; + r2 = r; + r2.min.x *= scale; + r2.min.y *= scale; + r2.max.x *= scale; + r2.max.y *= scale; + + srcn = bytesperline(r, f->bits->depth); + src = malloc(srcn); + dstn = bytesperline(r2, f->bits->depth); + dst = malloc(dstn+1); + i = allocimage(f->bits->display, r2, f->bits->chan, 0, DBlack); + for(y=r.min.y; y < r.max.y; y++) { + n = unloadimage(f->bits, Rect(r.min.x, y, r.max.x, y+1), src, srcn); + if(n != srcn) + sysfatal("scalesubfont: bad unload: %d < %d: %r", n, srcn); + memset(dst, 0, dstn+1); + pack = 8 / f->bits->depth; + mask = (1<bits->depth) - 1; + for(x=0; xbits->depth)) >> (8 - f->bits->depth)) & mask; + for(j=0; jbits->depth) >> ((x2%pack)*f->bits->depth); + } + } + if(dst[dstn] != 0) + sysfatal("overflow dst"); + for(j=0; jbits); + f->bits = i; + f->height *= scale; + f->ascent *= scale; + + for(j=0; jn; j++) { + f->info[j].x *= scale; + f->info[j].top *= scale; + f->info[j].bottom *= scale; + f->info[j].left *= scale; + f->info[j].width *= scale; + } +} blob - df6b0ec2f2dfc2cb6b5e3da3a355bdee0de52833 blob + cb8ab22b09a8ccbdca7390ed4021a5db9d2ac812 --- src/libdraw/mkfont.c +++ src/libdraw/mkfont.c @@ -15,6 +15,7 @@ mkfont(Subfont *subfont, Rune min) if(font == 0) return 0; memset(font, 0, sizeof(Font)); + font->scale = 1; font->display = subfont->bits->display; font->name = strdup(""); font->ncache = NFCACHE+NFLOOK; blob - 892f7f6137d2114412e079714f3c2a9e963114e2 blob + ae1462d41e344a6a668685e3d34b26fdd21aee15 --- src/libdraw/openfont.c +++ src/libdraw/openfont.c @@ -9,10 +9,15 @@ Font* openfont(Display *d, char *name) { Font *fnt; - int fd, i, n; + int fd, i, n, scale; char *buf, *nambuf; nambuf = 0; + scale = 1; + if('1' <= name[0] && name[0] <= '9' && name[1] == '*') { + scale = name[0] - '0'; + name += 2; + } fd = open(name, OREAD); if(fd < 0 && strncmp(name, "/lib/font/bit/", 14) == 0){ @@ -54,6 +59,12 @@ openfont(Display *d, char *name) fnt = buildfont(d, buf, name); free(buf); free(nambuf); + if(scale != 1) { + fnt->scale = scale; + fnt->height *= scale; + fnt->ascent *= scale; + fnt->width *= scale; + } return fnt; } blob - 392a7e8a7fb3c24cedd503f378569ce6f7ff24ce blob + c84112ec3539865e86c46962da88e684eb60d13b --- src/libdraw/string.c +++ src/libdraw/string.c @@ -130,7 +130,7 @@ _string(Image *dst, Point pt, Image *src, Point sp, Fo } if(subfontname){ freesubfont(sf); - if((sf=_getsubfont(f->display, subfontname)) == 0){ + if((sf=_getsubfont(f->display, f, subfontname)) == 0){ def = f->display ? f->display->defaultfont : nil; if(def && f!=def) f = def; blob - 522fbc0115d07609314b5133b5ef1adf11eddbb7 blob + e4630ca3ec40eb5b6d5442c3e424cb2c9c6b66be --- src/libdraw/stringwidth.c +++ src/libdraw/stringwidth.c @@ -48,7 +48,7 @@ _stringnwidth(Font *f, char *s, Rune *r, int len) } if(subfontname){ freesubfont(sf); - if((sf=_getsubfont(f->display, subfontname)) == 0){ + if((sf=_getsubfont(f->display, f, subfontname)) == 0){ def = f->display ? f->display->defaultfont : nil; if(def && f!=def) f = def;