| #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]; |
| } |