shithub: fontsel

Download patch

ref: 79031edf486e44972249b1219357a591f5313ed4
parent: e9d1c9b99a6cd81f03681513d54d1a26dead3fb3
author: Sigrid Haflínudóttir <[email protected]>
date: Tue Apr 14 20:25:33 EDT 2020

add support for truetypefs

--- a/README.md
+++ b/README.md
@@ -11,7 +11,9 @@
 When the user decides to quit, using either `q` or `del`, program
 prints out the full path to the last font selected.
 
+`-` and `+` cycle through fonts of a specific font dir, or change the
+size of the font if it's a TTF one.
+
 ## TODO
 
  * Custom font paths
- * truetypefs support
--- a/fontsel.c
+++ b/fontsel.c
@@ -5,13 +5,21 @@
 #include <keyboard.h>
 #include <mouse.h>
 
+#define MIN(a,b) ((a)<=(b)?(a):(b))
+#define MAX(a,b) ((a)>=(b)?(a):(b))
+
 typedef struct Fontdir Fontdir;
 
 struct Fontdir {
 	char *name;
+	char *prefix;
 	char **fonts;
 	int nfonts;
-	int ifont;
+	int isttf;
+	union {
+		int ifont;
+		int sz;
+	};
 };
 
 enum
@@ -20,6 +28,8 @@
 	Cmouse,
 	Cresize,
 	Numchan,
+
+	Ttfdefsz = 16,
 };
 
 static char *text[] = {
@@ -38,7 +48,11 @@
 	"}",
 };
 
-static char *prefix = "/lib/font/bit";
+static char *prefixes[] = {
+	"/lib/font/bit",
+	"/lib/font/ttf",
+};
+
 static Font *f;
 static Fontdir *dirs, *cdir;
 static int ndirs, idir;
@@ -75,7 +89,10 @@
 
 	}
 
-	snprint(t, sizeof(t), "%s/%s", cdir->name, cdir->fonts[cdir->ifont]);
+	if(cdir->isttf)
+		snprint(t, sizeof(t), "/n/ttf/%s.%d/font", cdir->name, cdir->sz);
+	else
+		snprint(t, sizeof(t), "%s/%s", cdir->name, cdir->fonts[cdir->ifont]);
 	p = screen->r.max;
 	p.x -= Dx(screen->r)/2 + stringwidth(font, t)/2;
 	p.y -= font->height;
@@ -98,6 +115,14 @@
 	int doff, k;
 	long i, n;
 
+	k = strlen(t);
+	if(k > 4 && strcmp(&t[k-4], ".ttf") == 0){
+		fdir->nfonts = 1;
+		fdir->sz = Ttfdefsz;
+		fdir->isttf = 1;
+		return 0;
+	}
+
 	if((n = dirreadall(f, &d)) < 1)
 		return -1;
 	doff = strlen(t);
@@ -129,7 +154,7 @@
 }
 
 static void
-findfonts(void)
+findfonts(char *prefix)
 {
 	Dir *d, *din;
 	int f, fin, doff;
@@ -151,14 +176,14 @@
 			if((dirs = realloc(dirs, sizeof(Fontdir)*(ndirs+1))) == nil)
 				sysfatal("no memory");
 			memset(&dirs[ndirs], 0, sizeof(Fontdir));
-			if((din->mode&DMDIR) && fontdir(t, fin, &dirs[ndirs]) == 0 && dirs[ndirs].nfonts > 0)
+			dirs[ndirs].prefix = prefix;
+			if(fontdir(t, fin, &dirs[ndirs]) == 0 && dirs[ndirs].nfonts > 0)
 				dirs[ndirs++].name = strdup(d[i].name);
 			free(din);
 		}
+		close(fin);
 	}
 	free(d);
-
-	qsort(dirs, ndirs, sizeof(*dirs), dcmp);
 }
 
 static void
@@ -169,7 +194,10 @@
 	lockdisplay(display);
 	if(f != nil)
 		freefont(f);
-	snprint(t, sizeof(t), "%s/%s/%s.font", prefix, cdir->name, cdir->fonts[cdir->ifont]);
+	if(cdir->isttf)
+		snprint(t, sizeof(t), "/n/ttf/%s.%d/font", cdir->name, cdir->sz);
+	else
+		snprint(t, sizeof(t), "%s/%s/%s.font", cdir->prefix, cdir->name, cdir->fonts[cdir->ifont]);
 	if((f = openfont(display, t)) == nil)
 		snprint(lasterr, sizeof(lasterr), "%r");
 	unlockdisplay(display);
@@ -205,9 +233,11 @@
 
 	USED(argc); USED(argv);
 
-	findfonts();
+	for(n = 0; n < nelem(prefixes); n++)
+		findfonts(prefixes[n]);
 	if(ndirs < 1)
 		sysfatal("no fonts");
+	qsort(dirs, ndirs, sizeof(*dirs), dcmp);
 
 	if(initdraw(nil, nil, "fontsel") < 0)
 		sysfatal("initdraw: %r");
@@ -227,7 +257,7 @@
 	redraw();
 
 	for(;;){
-		switch (alt(a)) {
+		switch(alt(a)){
 		case -1:
 			goto end;
 
@@ -236,6 +266,16 @@
 			case Kdel:
 			case 'q':
 				goto end;
+			case '-':
+				cdir->ifont = MAX(cdir->isttf ? 6 : 0, cdir->ifont-1);
+				newfont();
+				redraw();
+				break;
+			case '+':
+				cdir->ifont = MIN(cdir->isttf ? 256 : cdir->nfonts-1, cdir->ifont+1);
+				newfont();
+				redraw();
+				break;
 			}
 			break;
 
@@ -249,7 +289,7 @@
 					newfont();
 					redraw();
 				}
-			}else if(m.buttons == 4){
+			}else if(m.buttons == 4 && cdir->isttf == 0){
 				menu.gen = fontgen;
 				menu.lasthit = cdir->ifont;
 				if((n = menuhit(3, mctl, &menu, nil)) >= 0){
@@ -268,7 +308,11 @@
 	}
 
 end:
-	if(f != nil)
-		print("%s/%s/%s.font\n", prefix, cdir->name, cdir->fonts[cdir->ifont]);
+	if(f != nil){
+		if(cdir->isttf)
+			print("/n/ttf/%s.%d/font\n", cdir->name, cdir->sz);
+		else
+			print("%s/%s/%s.font\n", cdir->prefix, cdir->name, cdir->fonts[cdir->ifont]);
+	}
 	threadexitsall(nil);
 }