An experiment. Change-Id: I40660a211b8372701597d80f7e86917e94cccbaa Reviewed-on: https://plan9port-review.googlesource.com/1161 Reviewed-by: Russ Cox <rsc@swtch.com>
116 lines
1.9 KiB
C
116 lines
1.9 KiB
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, 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];
|
|
}
|