Blame


1 76193d7c 2003-09-30 devnull #include <u.h>
2 76193d7c 2003-09-30 devnull #include <libc.h>
3 76193d7c 2003-09-30 devnull #include <draw.h>
4 16d00819 2018-11-16 rsc #include "defont.h"
5 76193d7c 2003-09-30 devnull
6 76193d7c 2003-09-30 devnull /*
7 76193d7c 2003-09-30 devnull * Default version: treat as file name
8 76193d7c 2003-09-30 devnull */
9 76193d7c 2003-09-30 devnull
10 9b4a2324 2009-07-09 rsc int _fontpipe(char*);
11 16d00819 2018-11-16 rsc static int defaultpipe(void);
12 9b4a2324 2009-07-09 rsc
13 77f23268 2015-02-17 rsc static void scalesubfont(Subfont*, int);
14 77f23268 2015-02-17 rsc
15 76193d7c 2003-09-30 devnull Subfont*
16 213fc4f6 2015-02-17 rsc _getsubfont(Display *d, char *name)
17 76193d7c 2003-09-30 devnull {
18 76193d7c 2003-09-30 devnull int fd;
19 76193d7c 2003-09-30 devnull Subfont *f;
20 213fc4f6 2015-02-17 rsc int scale;
21 213fc4f6 2015-02-17 rsc char *fname;
22 16d00819 2018-11-16 rsc
23 213fc4f6 2015-02-17 rsc scale = parsefontscale(name, &fname);
24 16d00819 2018-11-16 rsc if(strcmp(fname, "*default*") == 0)
25 16d00819 2018-11-16 rsc fd = defaultpipe();
26 16d00819 2018-11-16 rsc else
27 16d00819 2018-11-16 rsc fd = open(fname, OREAD);
28 213fc4f6 2015-02-17 rsc if(fd < 0 && strncmp(fname, "/mnt/font/", 10) == 0)
29 213fc4f6 2015-02-17 rsc fd = _fontpipe(fname+10);
30 76193d7c 2003-09-30 devnull if(fd < 0){
31 213fc4f6 2015-02-17 rsc fprint(2, "getsubfont: can't open %s: %r\n", fname);
32 76193d7c 2003-09-30 devnull return 0;
33 76193d7c 2003-09-30 devnull }
34 76193d7c 2003-09-30 devnull /*
35 76193d7c 2003-09-30 devnull * unlock display so i/o happens with display released, unless
36 76193d7c 2003-09-30 devnull * user is doing his own locking, in which case this could break things.
37 76193d7c 2003-09-30 devnull * _getsubfont is called only from string.c and stringwidth.c,
38 76193d7c 2003-09-30 devnull * which are known to be safe to have this done.
39 76193d7c 2003-09-30 devnull */
40 4e206880 2004-04-25 devnull if(d && d->locking == 0)
41 76193d7c 2003-09-30 devnull unlockdisplay(d);
42 4e206880 2004-04-25 devnull f = readsubfont(d, name, fd, d && d->locking==0);
43 4e206880 2004-04-25 devnull if(d && d->locking == 0)
44 76193d7c 2003-09-30 devnull lockdisplay(d);
45 76193d7c 2003-09-30 devnull if(f == 0)
46 76193d7c 2003-09-30 devnull fprint(2, "getsubfont: can't read %s: %r\n", name);
47 76193d7c 2003-09-30 devnull close(fd);
48 213fc4f6 2015-02-17 rsc if(scale > 1)
49 213fc4f6 2015-02-17 rsc scalesubfont(f, scale);
50 76193d7c 2003-09-30 devnull return f;
51 76193d7c 2003-09-30 devnull }
52 77f23268 2015-02-17 rsc
53 16d00819 2018-11-16 rsc static int
54 16d00819 2018-11-16 rsc defaultpipe(void)
55 16d00819 2018-11-16 rsc {
56 4ae529db 2020-01-14 rsc int p[2], pid;
57 16d00819 2018-11-16 rsc
58 4ae529db 2020-01-14 rsc // Used to assume that defontdata (<5k) fit in the
59 4ae529db 2020-01-14 rsc // pipe buffer, especially since p9pipe is actually
60 4ae529db 2020-01-14 rsc // a socket pair. But OpenBSD in particular saw hangs,
61 4ae529db 2020-01-14 rsc // so feed the pipe it the "right" way with a subprocess.
62 16d00819 2018-11-16 rsc if(pipe(p) < 0)
63 16d00819 2018-11-16 rsc return -1;
64 4ae529db 2020-01-14 rsc if((pid = fork()) < 0) {
65 4ae529db 2020-01-14 rsc close(p[0]);
66 4ae529db 2020-01-14 rsc close(p[1]);
67 4ae529db 2020-01-14 rsc return -1;
68 4ae529db 2020-01-14 rsc }
69 4ae529db 2020-01-14 rsc if(pid == 0) {
70 4ae529db 2020-01-14 rsc close(p[0]);
71 4ae529db 2020-01-14 rsc write(p[1], defontdata, sizeof defontdata);
72 4ae529db 2020-01-14 rsc close(p[1]);
73 4ae529db 2020-01-14 rsc _exit(0);
74 4ae529db 2020-01-14 rsc }
75 16d00819 2018-11-16 rsc return p[0];
76 16d00819 2018-11-16 rsc }
77 16d00819 2018-11-16 rsc
78 77f23268 2015-02-17 rsc static void
79 77f23268 2015-02-17 rsc scalesubfont(Subfont *f, int scale)
80 77f23268 2015-02-17 rsc {
81 77f23268 2015-02-17 rsc Image *i;
82 77f23268 2015-02-17 rsc Rectangle r, r2;
83 77f23268 2015-02-17 rsc int y, x, x2, j;
84 77f23268 2015-02-17 rsc uchar *src, *dst;
85 77f23268 2015-02-17 rsc int srcn, dstn, n, mask, v, pack;
86 fa325e9b 2020-01-10 cross
87 77f23268 2015-02-17 rsc r = f->bits->r;
88 77f23268 2015-02-17 rsc r2 = r;
89 77f23268 2015-02-17 rsc r2.min.x *= scale;
90 77f23268 2015-02-17 rsc r2.min.y *= scale;
91 77f23268 2015-02-17 rsc r2.max.x *= scale;
92 77f23268 2015-02-17 rsc r2.max.y *= scale;
93 fa325e9b 2020-01-10 cross
94 77f23268 2015-02-17 rsc srcn = bytesperline(r, f->bits->depth);
95 77f23268 2015-02-17 rsc src = malloc(srcn);
96 77f23268 2015-02-17 rsc dstn = bytesperline(r2, f->bits->depth);
97 77f23268 2015-02-17 rsc dst = malloc(dstn+1);
98 77f23268 2015-02-17 rsc i = allocimage(f->bits->display, r2, f->bits->chan, 0, DBlack);
99 77f23268 2015-02-17 rsc for(y=r.min.y; y < r.max.y; y++) {
100 77f23268 2015-02-17 rsc n = unloadimage(f->bits, Rect(r.min.x, y, r.max.x, y+1), src, srcn);
101 16d00819 2018-11-16 rsc if(n != srcn) {
102 16d00819 2018-11-16 rsc abort();
103 16d00819 2018-11-16 rsc sysfatal("scalesubfont: bad unload %R %R: %d < %d: %r", f->bits->r, Rect(r.min.x, y, r.max.x, y+1), n, srcn);
104 16d00819 2018-11-16 rsc }
105 77f23268 2015-02-17 rsc memset(dst, 0, dstn+1);
106 77f23268 2015-02-17 rsc pack = 8 / f->bits->depth;
107 77f23268 2015-02-17 rsc mask = (1<<f->bits->depth) - 1;
108 77f23268 2015-02-17 rsc for(x=0; x<Dx(r); x++) {
109 77f23268 2015-02-17 rsc v = ((src[x/pack] << ((x%pack)*f->bits->depth)) >> (8 - f->bits->depth)) & mask;
110 77f23268 2015-02-17 rsc for(j=0; j<scale; j++) {
111 77f23268 2015-02-17 rsc x2 = x*scale+j;
112 77f23268 2015-02-17 rsc dst[x2/pack] |= v << (8 - f->bits->depth) >> ((x2%pack)*f->bits->depth);
113 77f23268 2015-02-17 rsc }
114 77f23268 2015-02-17 rsc }
115 77f23268 2015-02-17 rsc if(dst[dstn] != 0)
116 77f23268 2015-02-17 rsc sysfatal("overflow dst");
117 77f23268 2015-02-17 rsc for(j=0; j<scale; j++)
118 77f23268 2015-02-17 rsc loadimage(i, Rect(r2.min.x, y*scale+j, r2.max.x, y*scale+j+1), dst, dstn);
119 77f23268 2015-02-17 rsc }
120 77f23268 2015-02-17 rsc freeimage(f->bits);
121 77f23268 2015-02-17 rsc f->bits = i;
122 77f23268 2015-02-17 rsc f->height *= scale;
123 77f23268 2015-02-17 rsc f->ascent *= scale;
124 fa325e9b 2020-01-10 cross
125 77f23268 2015-02-17 rsc for(j=0; j<f->n; j++) {
126 77f23268 2015-02-17 rsc f->info[j].x *= scale;
127 77f23268 2015-02-17 rsc f->info[j].top *= scale;
128 77f23268 2015-02-17 rsc f->info[j].bottom *= scale;
129 77f23268 2015-02-17 rsc f->info[j].left *= scale;
130 77f23268 2015-02-17 rsc f->info[j].width *= scale;
131 77f23268 2015-02-17 rsc }
132 77f23268 2015-02-17 rsc }