blob: ae1462d41e344a6a668685e3d34b26fdd21aee15 [file] [log] [blame]
#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, 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){
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);
if(scale != 1) {
fnt->scale = scale;
fnt->height *= scale;
fnt->ascent *= scale;
fnt->width *= scale;
}
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];
}