From 77f23268f7073b254e91748d4764768bab6d6f1f Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 17 Feb 2015 00:57:10 -0500 Subject: 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 --- include/draw.h | 3 ++- src/libdraw/buildfont.c | 1 + src/libdraw/getsubfont.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++- src/libdraw/mkfont.c | 1 + src/libdraw/openfont.c | 13 +++++++++- src/libdraw/string.c | 2 +- src/libdraw/stringwidth.c | 2 +- 7 files changed, 77 insertions(+), 5 deletions(-) diff --git a/include/draw.h b/include/draw.h index d5f2ca69..ff760dd7 100644 --- a/include/draw.h +++ b/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*); diff --git a/src/libdraw/buildfont.c b/src/libdraw/buildfont.c index 75b59b11..0f14022e 100644 --- a/src/libdraw/buildfont.c +++ b/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; diff --git a/src/libdraw/getsubfont.c b/src/libdraw/getsubfont.c index 0d8be9ff..3f3b6954 100644 --- a/src/libdraw/getsubfont.c +++ b/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; + } +} diff --git a/src/libdraw/mkfont.c b/src/libdraw/mkfont.c index df6b0ec2..cb8ab22b 100644 --- a/src/libdraw/mkfont.c +++ b/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; diff --git a/src/libdraw/openfont.c b/src/libdraw/openfont.c index 892f7f61..ae1462d4 100644 --- a/src/libdraw/openfont.c +++ b/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; } diff --git a/src/libdraw/string.c b/src/libdraw/string.c index 392a7e8a..c84112ec 100644 --- a/src/libdraw/string.c +++ b/src/libdraw/string.c @@ -130,7 +130,7 @@ _string(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, Rune *r, i } 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; diff --git a/src/libdraw/stringwidth.c b/src/libdraw/stringwidth.c index 522fbc01..e4630ca3 100644 --- a/src/libdraw/stringwidth.c +++ b/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; -- cgit v1.2.3