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 76193d7c 2003-09-30 devnull
5 161060a4 2003-10-11 devnull extern vlong _drawflength(int);
6 9b4a2324 2009-07-09 rsc int _fontpipe(char*);
7 161060a4 2003-10-11 devnull
8 213fc4f6 2015-02-17 rsc int
9 213fc4f6 2015-02-17 rsc parsefontscale(char *name, char **base)
10 213fc4f6 2015-02-17 rsc {
11 213fc4f6 2015-02-17 rsc char *p;
12 213fc4f6 2015-02-17 rsc int scale;
13 fa325e9b 2020-01-10 cross
14 213fc4f6 2015-02-17 rsc p = name;
15 213fc4f6 2015-02-17 rsc scale = 0;
16 213fc4f6 2015-02-17 rsc while('0' <= *p && *p <= '9') {
17 213fc4f6 2015-02-17 rsc scale = scale*10 + *p - '0';
18 213fc4f6 2015-02-17 rsc p++;
19 213fc4f6 2015-02-17 rsc }
20 213fc4f6 2015-02-17 rsc if(*p == '*' && scale > 0)
21 213fc4f6 2015-02-17 rsc *base = p+1;
22 213fc4f6 2015-02-17 rsc else {
23 213fc4f6 2015-02-17 rsc *base = name;
24 213fc4f6 2015-02-17 rsc scale = 1;
25 213fc4f6 2015-02-17 rsc }
26 213fc4f6 2015-02-17 rsc return scale;
27 fa325e9b 2020-01-10 cross }
28 213fc4f6 2015-02-17 rsc
29 16d00819 2018-11-16 rsc extern char _defontfile[];
30 16d00819 2018-11-16 rsc
31 76193d7c 2003-09-30 devnull Font*
32 213fc4f6 2015-02-17 rsc openfont1(Display *d, char *name)
33 76193d7c 2003-09-30 devnull {
34 76193d7c 2003-09-30 devnull Font *fnt;
35 77f23268 2015-02-17 rsc int fd, i, n, scale;
36 dc2a17b9 2018-03-27 0intro char *buf, *nambuf, *nambuf0, *fname, *freename;
37 76193d7c 2003-09-30 devnull
38 e6f4b2e3 2003-10-13 devnull nambuf = 0;
39 213fc4f6 2015-02-17 rsc freename = nil;
40 213fc4f6 2015-02-17 rsc scale = parsefontscale(name, &fname);
41 e6f4b2e3 2003-10-13 devnull
42 16d00819 2018-11-16 rsc if(strcmp(fname, "*default*") == 0) {
43 16d00819 2018-11-16 rsc buf = strdup(_defontfile);
44 16d00819 2018-11-16 rsc goto build;
45 16d00819 2018-11-16 rsc }
46 213fc4f6 2015-02-17 rsc fd = open(fname, OREAD);
47 213fc4f6 2015-02-17 rsc if(fd < 0 && strncmp(fname, "/lib/font/bit/", 14) == 0){
48 213fc4f6 2015-02-17 rsc nambuf = smprint("#9/font/%s", fname+14);
49 e6f4b2e3 2003-10-13 devnull if(nambuf == nil)
50 e6f4b2e3 2003-10-13 devnull return 0;
51 03a8ec73 2018-03-27 0intro nambuf0 = unsharp(nambuf);
52 dc2a17b9 2018-03-27 0intro if(nambuf0 != nambuf)
53 dc2a17b9 2018-03-27 0intro free(nambuf);
54 dc2a17b9 2018-03-27 0intro nambuf = nambuf0;
55 8ad51794 2004-03-25 devnull if(nambuf == nil)
56 8ad51794 2004-03-25 devnull return 0;
57 e6f4b2e3 2003-10-13 devnull if((fd = open(nambuf, OREAD)) < 0){
58 e6f4b2e3 2003-10-13 devnull free(nambuf);
59 e6f4b2e3 2003-10-13 devnull return 0;
60 e6f4b2e3 2003-10-13 devnull }
61 213fc4f6 2015-02-17 rsc if(scale > 1) {
62 dc2a17b9 2018-03-27 0intro name = smprint("%d*%s", scale, nambuf);
63 213fc4f6 2015-02-17 rsc freename = name;
64 213fc4f6 2015-02-17 rsc } else {
65 dc2a17b9 2018-03-27 0intro name = nambuf;
66 213fc4f6 2015-02-17 rsc }
67 e6f4b2e3 2003-10-13 devnull }
68 9b4a2324 2009-07-09 rsc if(fd >= 0)
69 9b4a2324 2009-07-09 rsc n = _drawflength(fd);
70 213fc4f6 2015-02-17 rsc if(fd < 0 && strncmp(fname, "/mnt/font/", 10) == 0) {
71 213fc4f6 2015-02-17 rsc fd = _fontpipe(fname+10);
72 a6ad39aa 2020-05-30 rsc n = 1024*1024;
73 9b4a2324 2009-07-09 rsc }
74 dc2a17b9 2018-03-27 0intro if(fd < 0){
75 dc2a17b9 2018-03-27 0intro free(nambuf);
76 dc2a17b9 2018-03-27 0intro free(freename);
77 76193d7c 2003-09-30 devnull return 0;
78 dc2a17b9 2018-03-27 0intro }
79 76193d7c 2003-09-30 devnull
80 76193d7c 2003-09-30 devnull buf = malloc(n+1);
81 76193d7c 2003-09-30 devnull if(buf == 0){
82 76193d7c 2003-09-30 devnull close(fd);
83 e6f4b2e3 2003-10-13 devnull free(nambuf);
84 dc2a17b9 2018-03-27 0intro free(freename);
85 76193d7c 2003-09-30 devnull return 0;
86 76193d7c 2003-09-30 devnull }
87 9b4a2324 2009-07-09 rsc i = readn(fd, buf, n);
88 76193d7c 2003-09-30 devnull close(fd);
89 9b4a2324 2009-07-09 rsc if(i <= 0){
90 76193d7c 2003-09-30 devnull free(buf);
91 e6f4b2e3 2003-10-13 devnull free(nambuf);
92 dc2a17b9 2018-03-27 0intro free(freename);
93 76193d7c 2003-09-30 devnull return 0;
94 76193d7c 2003-09-30 devnull }
95 9b4a2324 2009-07-09 rsc buf[i] = 0;
96 16d00819 2018-11-16 rsc build:
97 76193d7c 2003-09-30 devnull fnt = buildfont(d, buf, name);
98 76193d7c 2003-09-30 devnull free(buf);
99 e6f4b2e3 2003-10-13 devnull free(nambuf);
100 213fc4f6 2015-02-17 rsc free(freename);
101 77f23268 2015-02-17 rsc if(scale != 1) {
102 77f23268 2015-02-17 rsc fnt->scale = scale;
103 77f23268 2015-02-17 rsc fnt->height *= scale;
104 77f23268 2015-02-17 rsc fnt->ascent *= scale;
105 77f23268 2015-02-17 rsc fnt->width *= scale;
106 77f23268 2015-02-17 rsc }
107 76193d7c 2003-09-30 devnull return fnt;
108 76193d7c 2003-09-30 devnull }
109 9b4a2324 2009-07-09 rsc
110 213fc4f6 2015-02-17 rsc void
111 213fc4f6 2015-02-17 rsc swapfont(Font *targ, Font **oldp, Font **newp)
112 213fc4f6 2015-02-17 rsc {
113 213fc4f6 2015-02-17 rsc Font f, *old, *new;
114 213fc4f6 2015-02-17 rsc
115 213fc4f6 2015-02-17 rsc if(targ != *oldp)
116 213fc4f6 2015-02-17 rsc sysfatal("bad swapfont %p %p %p", targ, *oldp, *newp);
117 fa325e9b 2020-01-10 cross
118 213fc4f6 2015-02-17 rsc old = *oldp;
119 213fc4f6 2015-02-17 rsc new = *newp;
120 213fc4f6 2015-02-17 rsc
121 213fc4f6 2015-02-17 rsc f.name = old->name;
122 213fc4f6 2015-02-17 rsc f.display = old->display;
123 213fc4f6 2015-02-17 rsc f.height = old->height;
124 213fc4f6 2015-02-17 rsc f.ascent = old->ascent;
125 213fc4f6 2015-02-17 rsc f.width = old->width;
126 213fc4f6 2015-02-17 rsc f.nsub = old->nsub;
127 213fc4f6 2015-02-17 rsc f.age = old->age;
128 213fc4f6 2015-02-17 rsc f.maxdepth = old->maxdepth;
129 213fc4f6 2015-02-17 rsc f.ncache = old->ncache;
130 213fc4f6 2015-02-17 rsc f.nsubf = old->nsubf;
131 213fc4f6 2015-02-17 rsc f.scale = old->scale;
132 213fc4f6 2015-02-17 rsc f.cache = old->cache;
133 213fc4f6 2015-02-17 rsc f.subf = old->subf;
134 213fc4f6 2015-02-17 rsc f.sub = old->sub;
135 213fc4f6 2015-02-17 rsc f.cacheimage = old->cacheimage;
136 213fc4f6 2015-02-17 rsc
137 213fc4f6 2015-02-17 rsc old->name = new->name;
138 213fc4f6 2015-02-17 rsc old->display = new->display;
139 213fc4f6 2015-02-17 rsc old->height = new->height;
140 213fc4f6 2015-02-17 rsc old->ascent = new->ascent;
141 213fc4f6 2015-02-17 rsc old->width = new->width;
142 213fc4f6 2015-02-17 rsc old->nsub = new->nsub;
143 213fc4f6 2015-02-17 rsc old->age = new->age;
144 213fc4f6 2015-02-17 rsc old->maxdepth = new->maxdepth;
145 213fc4f6 2015-02-17 rsc old->ncache = new->ncache;
146 213fc4f6 2015-02-17 rsc old->nsubf = new->nsubf;
147 213fc4f6 2015-02-17 rsc old->scale = new->scale;
148 213fc4f6 2015-02-17 rsc old->cache = new->cache;
149 213fc4f6 2015-02-17 rsc old->subf = new->subf;
150 213fc4f6 2015-02-17 rsc old->sub = new->sub;
151 213fc4f6 2015-02-17 rsc old->cacheimage = new->cacheimage;
152 213fc4f6 2015-02-17 rsc
153 213fc4f6 2015-02-17 rsc new->name = f.name;
154 213fc4f6 2015-02-17 rsc new->display = f.display;
155 213fc4f6 2015-02-17 rsc new->height = f.height;
156 213fc4f6 2015-02-17 rsc new->ascent = f.ascent;
157 213fc4f6 2015-02-17 rsc new->width = f.width;
158 213fc4f6 2015-02-17 rsc new->nsub = f.nsub;
159 213fc4f6 2015-02-17 rsc new->age = f.age;
160 213fc4f6 2015-02-17 rsc new->maxdepth = f.maxdepth;
161 213fc4f6 2015-02-17 rsc new->ncache = f.ncache;
162 213fc4f6 2015-02-17 rsc new->nsubf = f.nsubf;
163 213fc4f6 2015-02-17 rsc new->scale = f.scale;
164 213fc4f6 2015-02-17 rsc new->cache = f.cache;
165 213fc4f6 2015-02-17 rsc new->subf = f.subf;
166 213fc4f6 2015-02-17 rsc new->sub = f.sub;
167 213fc4f6 2015-02-17 rsc new->cacheimage = f.cacheimage;
168 213fc4f6 2015-02-17 rsc
169 213fc4f6 2015-02-17 rsc *oldp = new;
170 213fc4f6 2015-02-17 rsc *newp = old;
171 213fc4f6 2015-02-17 rsc }
172 213fc4f6 2015-02-17 rsc
173 79555a99 2015-02-17 rsc static char*
174 79555a99 2015-02-17 rsc hidpiname(Font *f)
175 79555a99 2015-02-17 rsc {
176 79555a99 2015-02-17 rsc char *p, *q;
177 79555a99 2015-02-17 rsc int size;
178 fa325e9b 2020-01-10 cross
179 79555a99 2015-02-17 rsc // If font name has form x,y return y.
180 79555a99 2015-02-17 rsc p = strchr(f->namespec, ',');
181 79555a99 2015-02-17 rsc if(p != nil)
182 79555a99 2015-02-17 rsc return strdup(p+1);
183 fa325e9b 2020-01-10 cross
184 79555a99 2015-02-17 rsc // If font name is /mnt/font/Name/Size/font, scale Size.
185 79555a99 2015-02-17 rsc if(strncmp(f->name, "/mnt/font/", 10) == 0) {
186 79555a99 2015-02-17 rsc p = strchr(f->name+10, '/');
187 79555a99 2015-02-17 rsc if(p == nil || *++p < '0' || *p > '9')
188 79555a99 2015-02-17 rsc goto scale;
189 79555a99 2015-02-17 rsc q = p;
190 79555a99 2015-02-17 rsc size = 0;
191 79555a99 2015-02-17 rsc while('0' <= *q && *q <= '9')
192 79555a99 2015-02-17 rsc size = size*10 + *q++ - '0';
193 79555a99 2015-02-17 rsc return smprint("%.*s%d%s", utfnlen(f->name, p-f->name), f->name, size*2, q);
194 fa325e9b 2020-01-10 cross }
195 79555a99 2015-02-17 rsc
196 fa325e9b 2020-01-10 cross // Otherwise use pixel doubling.
197 79555a99 2015-02-17 rsc scale:
198 79555a99 2015-02-17 rsc return smprint("%d*%s", f->scale*2, f->name);
199 79555a99 2015-02-17 rsc }
200 79555a99 2015-02-17 rsc
201 213fc4f6 2015-02-17 rsc void
202 213fc4f6 2015-02-17 rsc loadhidpi(Font *f)
203 213fc4f6 2015-02-17 rsc {
204 213fc4f6 2015-02-17 rsc char *name;
205 213fc4f6 2015-02-17 rsc Font *fnew;
206 213fc4f6 2015-02-17 rsc
207 213fc4f6 2015-02-17 rsc if(f->hidpi == f)
208 213fc4f6 2015-02-17 rsc return;
209 213fc4f6 2015-02-17 rsc if(f->hidpi != nil) {
210 213fc4f6 2015-02-17 rsc swapfont(f, &f->lodpi, &f->hidpi);
211 213fc4f6 2015-02-17 rsc return;
212 213fc4f6 2015-02-17 rsc }
213 fa325e9b 2020-01-10 cross
214 79555a99 2015-02-17 rsc name = hidpiname(f);
215 213fc4f6 2015-02-17 rsc fnew = openfont1(f->display, name);
216 213fc4f6 2015-02-17 rsc if(fnew == nil)
217 213fc4f6 2015-02-17 rsc return;
218 213fc4f6 2015-02-17 rsc f->hidpi = fnew;
219 213fc4f6 2015-02-17 rsc free(name);
220 213fc4f6 2015-02-17 rsc
221 213fc4f6 2015-02-17 rsc swapfont(f, &f->lodpi, &f->hidpi);
222 213fc4f6 2015-02-17 rsc }
223 213fc4f6 2015-02-17 rsc
224 213fc4f6 2015-02-17 rsc Font*
225 213fc4f6 2015-02-17 rsc openfont(Display *d, char *name)
226 213fc4f6 2015-02-17 rsc {
227 213fc4f6 2015-02-17 rsc Font *f;
228 79555a99 2015-02-17 rsc char *p;
229 79555a99 2015-02-17 rsc char *namespec;
230 fa325e9b 2020-01-10 cross
231 79555a99 2015-02-17 rsc // If font name has form x,y use x for lodpi, y for hidpi.
232 79555a99 2015-02-17 rsc name = strdup(name);
233 79555a99 2015-02-17 rsc namespec = strdup(name);
234 79555a99 2015-02-17 rsc if((p = strchr(name, ',')) != nil)
235 79555a99 2015-02-17 rsc *p = '\0';
236 79555a99 2015-02-17 rsc
237 213fc4f6 2015-02-17 rsc f = openfont1(d, name);
238 25822e8d 2015-05-15 rsc if(!f)
239 25822e8d 2015-05-15 rsc return nil;
240 213fc4f6 2015-02-17 rsc f->lodpi = f;
241 dc2a17b9 2018-03-27 0intro free(f->namespec);
242 79555a99 2015-02-17 rsc f->namespec = namespec;
243 fa325e9b 2020-01-10 cross
244 213fc4f6 2015-02-17 rsc /* add to display list for when dpi changes */
245 213fc4f6 2015-02-17 rsc /* d can be nil when invoked from mc. */
246 213fc4f6 2015-02-17 rsc if(d != nil) {
247 213fc4f6 2015-02-17 rsc f->ondisplaylist = 1;
248 213fc4f6 2015-02-17 rsc f->prev = d->lastfont;
249 213fc4f6 2015-02-17 rsc f->next = nil;
250 213fc4f6 2015-02-17 rsc if(f->prev)
251 213fc4f6 2015-02-17 rsc f->prev->next = f;
252 213fc4f6 2015-02-17 rsc else
253 213fc4f6 2015-02-17 rsc d->firstfont = f;
254 213fc4f6 2015-02-17 rsc d->lastfont = f;
255 fa325e9b 2020-01-10 cross
256 213fc4f6 2015-02-17 rsc /* if this is a hi-dpi display, find hi-dpi version and swap */
257 213fc4f6 2015-02-17 rsc if(d->dpi >= DefaultDPI*3/2)
258 213fc4f6 2015-02-17 rsc loadhidpi(f);
259 213fc4f6 2015-02-17 rsc }
260 fa325e9b 2020-01-10 cross
261 79555a99 2015-02-17 rsc free(name);
262 213fc4f6 2015-02-17 rsc
263 213fc4f6 2015-02-17 rsc return f;
264 213fc4f6 2015-02-17 rsc }
265 213fc4f6 2015-02-17 rsc
266 9b4a2324 2009-07-09 rsc int
267 9b4a2324 2009-07-09 rsc _fontpipe(char *name)
268 9b4a2324 2009-07-09 rsc {
269 9b4a2324 2009-07-09 rsc int p[2];
270 9b4a2324 2009-07-09 rsc char c;
271 9b4a2324 2009-07-09 rsc char buf[1024], *argv[10];
272 9b4a2324 2009-07-09 rsc int nbuf, pid;
273 fa325e9b 2020-01-10 cross
274 9b4a2324 2009-07-09 rsc if(pipe(p) < 0)
275 9b4a2324 2009-07-09 rsc return -1;
276 9b4a2324 2009-07-09 rsc pid = rfork(RFNOWAIT|RFFDG|RFPROC);
277 9b4a2324 2009-07-09 rsc if(pid < 0) {
278 9b4a2324 2009-07-09 rsc close(p[0]);
279 9b4a2324 2009-07-09 rsc close(p[1]);
280 9b4a2324 2009-07-09 rsc return -1;
281 9b4a2324 2009-07-09 rsc }
282 9b4a2324 2009-07-09 rsc if(pid == 0) {
283 9b4a2324 2009-07-09 rsc close(p[0]);
284 9b4a2324 2009-07-09 rsc dup(p[1], 1);
285 9b4a2324 2009-07-09 rsc dup(p[1], 2);
286 9b4a2324 2009-07-09 rsc if(p[1] > 2)
287 9b4a2324 2009-07-09 rsc close(p[1]);
288 9b4a2324 2009-07-09 rsc argv[0] = "fontsrv";
289 9b4a2324 2009-07-09 rsc argv[1] = "-pp";
290 9b4a2324 2009-07-09 rsc argv[2] = name;
291 9b4a2324 2009-07-09 rsc argv[3] = nil;
292 9b4a2324 2009-07-09 rsc execvp("fontsrv", argv);
293 9b4a2324 2009-07-09 rsc print("exec fontsrv: %r\n");
294 9b4a2324 2009-07-09 rsc _exit(0);
295 9b4a2324 2009-07-09 rsc }
296 9b4a2324 2009-07-09 rsc close(p[1]);
297 fa325e9b 2020-01-10 cross
298 9b4a2324 2009-07-09 rsc // success marked with leading \001.
299 9b4a2324 2009-07-09 rsc // otherwise an error happened.
300 9b4a2324 2009-07-09 rsc for(nbuf=0; nbuf<sizeof buf-1; nbuf++) {
301 9b4a2324 2009-07-09 rsc if(read(p[0], &c, 1) < 1 || c == '\n') {
302 9b4a2324 2009-07-09 rsc buf[nbuf] = '\0';
303 9b4a2324 2009-07-09 rsc werrstr(buf);
304 9b4a2324 2009-07-09 rsc close(p[0]);
305 9b4a2324 2009-07-09 rsc return -1;
306 9b4a2324 2009-07-09 rsc }
307 9b4a2324 2009-07-09 rsc if(c == '\001')
308 9b4a2324 2009-07-09 rsc break;
309 9b4a2324 2009-07-09 rsc }
310 9b4a2324 2009-07-09 rsc return p[0];
311 9b4a2324 2009-07-09 rsc }