~ft/fontsel

79031edf486e44972249b1219357a591f5313ed4 — Sigrid Haflínudóttir 7 months ago e9d1c9b
add support for truetypefs
2 files changed, 60 insertions(+), 14 deletions(-)

M README.md
M fontsel.c
M README.md => README.md +3 -1
@@ 11,7 11,9 @@ directory with the right mouse button.
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

M fontsel.c => fontsel.c +57 -13
@@ 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 @@ enum
	Cmouse,
	Cresize,
	Numchan,

	Ttfdefsz = 16,
};

static char *text[] = {


@@ 38,7 48,11 @@ static char *text[] = {
	"}",
};

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 @@ redraw(void)

	}

	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 @@ fontdir(char *t, int f, Fontdir *fdir)
	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 @@ dcmp(void *a_, void *b_)
}

static void
findfonts(void)
findfonts(char *prefix)
{
	Dir *d, *din;
	int f, fin, doff;


@@ 151,14 176,14 @@ findfonts(void)
			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 @@ newfont(void)
	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 @@ threadmain(int argc, char **argv)

	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 @@ threadmain(int argc, char **argv)
	redraw();

	for(;;){
		switch (alt(a)) {
		switch(alt(a)){
		case -1:
			goto end;



@@ 236,6 266,16 @@ threadmain(int argc, char **argv)
			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 @@ threadmain(int argc, char **argv)
					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 @@ threadmain(int argc, char **argv)
	}

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);
}