diff options
author | Russ Cox <rsc@swtch.com> | 2015-02-17 00:57:10 -0500 |
---|---|---|
committer | Russ Cox <rsc@swtch.com> | 2015-02-17 05:58:37 +0000 |
commit | 77f23268f7073b254e91748d4764768bab6d6f1f (patch) | |
tree | 5b4128cb14c9d587d3f1567c2ae11b0a36cbb55a /src/libdraw | |
parent | 32dc15fa62d94c88f0b62bfe4d64ba60fe1733a6 (diff) | |
download | plan9port-77f23268f7073b254e91748d4764768bab6d6f1f.tar.gz plan9port-77f23268f7073b254e91748d4764768bab6d6f1f.tar.bz2 plan9port-77f23268f7073b254e91748d4764768bab6d6f1f.zip |
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 <rsc@swtch.com>
Diffstat (limited to 'src/libdraw')
-rw-r--r-- | src/libdraw/buildfont.c | 1 | ||||
-rw-r--r-- | src/libdraw/getsubfont.c | 60 | ||||
-rw-r--r-- | src/libdraw/mkfont.c | 1 | ||||
-rw-r--r-- | src/libdraw/openfont.c | 13 | ||||
-rw-r--r-- | src/libdraw/string.c | 2 | ||||
-rw-r--r-- | src/libdraw/stringwidth.c | 2 |
6 files changed, 75 insertions, 4 deletions
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<<f->bits->depth) - 1; + for(x=0; x<Dx(r); x++) { + v = ((src[x/pack] << ((x%pack)*f->bits->depth)) >> (8 - f->bits->depth)) & mask; + for(j=0; j<scale; j++) { + x2 = x*scale+j; + dst[x2/pack] |= v << (8 - f->bits->depth) >> ((x2%pack)*f->bits->depth); + } + } + if(dst[dstn] != 0) + sysfatal("overflow dst"); + for(j=0; j<scale; j++) + loadimage(i, Rect(r2.min.x, y*scale+j, r2.max.x, y*scale+j+1), dst, dstn); + } + freeimage(f->bits); + f->bits = i; + f->height *= scale; + f->ascent *= scale; + + for(j=0; j<f->n; 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("<synthetic>"); 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; |