9 static char Egreg[] = "my memory of truetype is fading";
10 static char Enoent[] = "not found";
12 static char *fontpath = "/lib/font/ttf";
14 enum { MAXSUB = 0x100 };
16 typedef struct TFont TFont;
17 typedef struct TSubfont TSubfont;
42 typedef struct FidAux FidAux;
55 TFont fontl = {.next = &fontl, .prev = &fontl};
63 if(v == nil) sysfatal("malloc: %r");
64 setmalloctag(v, getcallerpc(&n));
79 r->ofcall.qid = (Qid){0, 0, QTDIR};
80 r->fid->qid = r->ofcall.qid;
81 r->fid->aux = emalloc(sizeof(FidAux));
97 fmtprint(&fmt, "%d\t%d\n", f->ttf->ascentpx + f->ttf->descentpx, f->ttf->ascentpx);
99 for(c = u->cmap; c < u->cmap + u->ncmap; c++){
100 for(k = c->start; k < c->end; k += MAXSUB){
101 s = emalloc(sizeof(TSubfont));
104 s->end = k + MAXSUB - 1;
108 s->qid = (Qid){qidgen(), 0, 0};
109 s->next = f->sub[k >> 8 & 0xff];
110 f->sub[k >> 8 & 0xff] = s;
111 fmtprint(&fmt, "%#.4ux\t%#.4ux\ts.%.4ux-%.4ux\n", s->start, s->end, s->start, s->end);
115 s = emalloc(sizeof(TSubfont));
119 s->qid = (Qid){qidgen(), 0, 0};
122 fmtprint(&fmt, "%#.4ux\t%#.4ux\ts.%.4ux-%.4ux\n", 0, 0, 0, 0);
124 f->fontfile = fmtstrflush(&fmt);
125 f->nfontfile = strlen(f->fontfile);
129 blit(uchar *t, int x, int y, int tstride, uchar *s, int w, int h)
138 for(sy = 0; sy < h; sy++, ty++){
140 tp = t + ty * tstride + (tx >> 3);
142 for(sx = 0; sx < w; sx += 8){
143 b |= *sp++ << 8 - (tx & 7);
152 compilesub(TFont *f, TSubfont *s)
154 int n, i, w, x, h, g, sz;
160 n = s->end - s->start + 1;
161 gs = emalloc9p(sizeof(TTGlyph *) * n);
163 h = t->ascentpx + t->descentpx;
164 for(i = 0; i < n; i++){
165 if(s->start + i == 0)
168 g = ttffindchar(t, s->start + i);
169 gs[i] = ttfgetglyph(t, g, 1);
172 sz = 5 * 12 + (w+7>>3) * h + 3 * 12 + (n + 1) * 6;
174 p = d + sprint(d, "%11s %11d %11d %11d %11d ", "k1", 0, 0, w, h);
176 for(i = 0; i < n; i++){
177 blit((uchar*)p, x, t->ascentpx - gs[i]->ymaxpx, w+7>>3, gs[i]->bit, gs[i]->width, gs[i]->height);
181 p += sprint(p, "%11d %11d %11d ", n, h, t->ascentpx);
183 for(i = 0; i < n; i++){
188 *p++ = gs[i]->xminpx;
189 if(gs[i]->advanceWidthpx != 0)
190 *p++ = gs[i]->advanceWidthpx;
199 for(i = 0; i < n; i++)
213 for(f = fontl.next; f != &fontl; f = f->next)
214 if(strcmp(f->name9p, name) == 0)
216 d = strrchr(name, '.');
219 werrstr("invalid file name");
222 sz = strtol(d + 1, &p, 10);
223 if(d[1] == 0 || *p != 0)
225 buf = estrdup9p(name);
227 p = smprint("%s/%s", fontpath, buf);
229 sysfatal("smprint: %r");
230 ttf = ttfopen(p, sz, 0);
236 f = emalloc(sizeof(TFont));
238 f->name9p = strdup(name);
241 f->qid = (Qid){qidgen(), 0, QTDIR};
242 f->fileqid = (Qid){qidgen(), 0, 0};
244 f->prev = fontl.prev;
252 fsclone(Fid *old, Fid *new)
254 new->aux = emalloc(sizeof(FidAux));
255 *(FidAux*)new->aux = *(FidAux*)old->aux;
270 findsubfont(TFont *f, char *name)
277 if(name[0] != 's' || name[1] != '.' || name[2] == '-')
279 a = strtol(name + 2, &p, 16);
282 b = strtol(p + 1, &q, 16);
283 if(p + 1 == q || *q != 0)
285 snprint(buf, nelem(buf), "s.%.4ux-%.4ux", a, b);
286 if(strcmp(buf, name) != 0)
288 for(s = f->sub[a>>8&0xff]; s != nil; s = s->next)
289 if(s->start == a && s->end == b)
295 fswalk(Fid *fid, char *name, Qid *qid)
297 static char errbuf[ERRMAX];
304 fa->f = tryfont(name);
306 rerrstr(errbuf, nelem(errbuf));
311 fid->qid = fa->f->qid;
315 if(strcmp(name, "font") == 0){
317 fid->qid = fa->f->fileqid;
318 *qid = fa->f->fileqid;
321 fa->sub = findsubfont(fa->f, name);
325 fid->qid = fa->sub->qid;
340 r->d.uid = estrdup9p(getuser());
341 r->d.gid = estrdup9p(getuser());
342 r->d.muid = estrdup9p(getuser());
343 r->d.mtime = r->d.atime = time(0);
344 r->d.qid = r->fid->qid;
348 r->d.name = estrdup9p("/");
353 r->d.name = estrdup9p(fa->f->name9p);
358 r->d.name = estrdup9p("font");
359 r->d.length = fa->f->nfontfile;
364 r->d.name = smprint("s.%.4ux-%.4ux", fa->sub->start, fa->sub->end);
365 r->d.length = fa->sub->ndata;
374 fontdirread(int n, Dir *d, void *aux)
380 d->name = estrdup9p("font");
381 d->uid = estrdup9p(getuser());
382 d->gid = estrdup9p(getuser());
383 d->muid = estrdup9p(getuser());
385 d->qid = fa->f->fileqid;
386 d->mtime = d->atime = time(0);
387 d->length = fa->f->nfontfile;
405 dirread9p(r, fontdirread, fa);
409 readbuf(r, fa->f->fontfile, fa->f->nfontfile);
413 if(fa->sub->data == nil)
414 compilesub(fa->f, fa->sub);
415 readbuf(r, fa->sub->data, fa->sub->ndata);
429 .destroyfid = fsdestroyfid,
435 fprint(2, "usage: %s [-F fontpath]\n", argv0);
440 main(int argc, char **argv)
444 fontpath = EARGF(usage());
450 unmount(nil, "/n/ttf");
451 postmountsrv(&fssrv, nil, "/n/ttf", 0);