Plan 9 from User Space's /usr/local/plan9/src/libdraw/openfont.c

#include <u.h>
#include <libc.h>
#include <draw.h>

extern vlong _drawflength(int);
int _fontpipe(char*);

Font*
openfont(Display *d, char *name)
{
	Font *fnt;
	int fd, i, n;
	char *buf, *nambuf;

	nambuf = 0;
	fd = open(name, OREAD);

	if(fd < 0 && strncmp(name, "/lib/font/bit/", 14) == 0){
		nambuf = smprint("#9/font/%s", name+14);
		if(nambuf == nil)
			return 0;
		nambuf = unsharp(nambuf);
		if(nambuf == nil)
			return 0;
		if((fd = open(nambuf, OREAD)) < 0){
			free(nambuf);
			return 0;
		}
		name = nambuf;
	}
	if(fd >= 0)
		n = _drawflength(fd);
	if(fd < 0 && strncmp(name, "/mnt/font/", 10) == 0) {
		fd = _fontpipe(name+10);
		n = 8192;
	}
	if(fd < 0)
		return 0;

	buf = malloc(n+1);
	if(buf == 0){
		close(fd);
		free(nambuf);
		return 0;
	}
	i = readn(fd, buf, n);
	close(fd);
	if(i <= 0){
		free(buf);
		free(nambuf);
		return 0;
	}
	buf[i] = 0;
	fnt = buildfont(d, buf, name);
	free(buf);
	free(nambuf);
	return fnt;
}

int
_fontpipe(char *name)
{
	int p[2];
	char c;
	char buf[1024], *argv[10];
	int nbuf, pid;
	
	if(pipe(p) < 0)
		return -1;
	pid = rfork(RFNOWAIT|RFFDG|RFPROC);
	if(pid < 0) {
		close(p[0]);
		close(p[1]);
		return -1;
	}
	if(pid == 0) {
		close(p[0]);
		dup(p[1], 1);
		dup(p[1], 2);
		if(p[1] > 2)
			close(p[1]);
		argv[0] = "fontsrv";
		argv[1] = "-pp";
		argv[2] = name;
		argv[3] = nil;
		execvp("fontsrv", argv);
		print("exec fontsrv: %r\n");
		_exit(0);
	}
	close(p[1]);
	
	// success marked with leading \001.
	// otherwise an error happened.
	for(nbuf=0; nbuf<sizeof buf-1; nbuf++) {
		if(read(p[0], &c, 1) < 1 || c == '\n') {
			buf[nbuf] = '\0';
			werrstr(buf);
			close(p[0]);
			return -1;
		}
		if(c == '\001')
			break;
	}
	return p[0];
}

Space Glenda

Copyright © 2005 Lucent Technologies, Russ Cox, MIT.
See license for details.