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