Commit Diff


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<<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;
+	}
+}
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("<synthetic>");
 	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;