aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/draw.h3
-rw-r--r--src/libdraw/buildfont.c1
-rw-r--r--src/libdraw/getsubfont.c60
-rw-r--r--src/libdraw/mkfont.c1
-rw-r--r--src/libdraw/openfont.c13
-rw-r--r--src/libdraw/string.c2
-rw-r--r--src/libdraw/stringwidth.c2
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<<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;