Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
5 /*
6 * Default version: treat as file name
7 */
9 int _fontpipe(char*);
11 static void scalesubfont(Subfont*, int);
13 Subfont*
14 _getsubfont(Display *d, char *name)
15 {
16 int fd;
17 Subfont *f;
18 int scale;
19 char *fname;
21 scale = parsefontscale(name, &fname);
22 fd = open(fname, OREAD);
23 if(fd < 0 && strncmp(fname, "/mnt/font/", 10) == 0)
24 fd = _fontpipe(fname+10);
26 if(fd < 0){
27 fprint(2, "getsubfont: can't open %s: %r\n", fname);
28 return 0;
29 }
30 /*
31 * unlock display so i/o happens with display released, unless
32 * user is doing his own locking, in which case this could break things.
33 * _getsubfont is called only from string.c and stringwidth.c,
34 * which are known to be safe to have this done.
35 */
36 if(d && d->locking == 0)
37 unlockdisplay(d);
38 f = readsubfont(d, name, fd, d && d->locking==0);
39 if(d && d->locking == 0)
40 lockdisplay(d);
41 if(f == 0)
42 fprint(2, "getsubfont: can't read %s: %r\n", name);
43 close(fd);
44 if(scale > 1)
45 scalesubfont(f, scale);
46 return f;
47 }
49 static void
50 scalesubfont(Subfont *f, int scale)
51 {
52 Image *i;
53 Rectangle r, r2;
54 int y, x, x2, j;
55 uchar *src, *dst;
56 int srcn, dstn, n, mask, v, pack;
58 r = f->bits->r;
59 r2 = r;
60 r2.min.x *= scale;
61 r2.min.y *= scale;
62 r2.max.x *= scale;
63 r2.max.y *= scale;
65 srcn = bytesperline(r, f->bits->depth);
66 src = malloc(srcn);
67 dstn = bytesperline(r2, f->bits->depth);
68 dst = malloc(dstn+1);
69 i = allocimage(f->bits->display, r2, f->bits->chan, 0, DBlack);
70 for(y=r.min.y; y < r.max.y; y++) {
71 n = unloadimage(f->bits, Rect(r.min.x, y, r.max.x, y+1), src, srcn);
72 if(n != srcn)
73 sysfatal("scalesubfont: bad unload: %d < %d: %r", n, srcn);
74 memset(dst, 0, dstn+1);
75 pack = 8 / f->bits->depth;
76 mask = (1<<f->bits->depth) - 1;
77 for(x=0; x<Dx(r); x++) {
78 v = ((src[x/pack] << ((x%pack)*f->bits->depth)) >> (8 - f->bits->depth)) & mask;
79 for(j=0; j<scale; j++) {
80 x2 = x*scale+j;
81 dst[x2/pack] |= v << (8 - f->bits->depth) >> ((x2%pack)*f->bits->depth);
82 }
83 }
84 if(dst[dstn] != 0)
85 sysfatal("overflow dst");
86 for(j=0; j<scale; j++)
87 loadimage(i, Rect(r2.min.x, y*scale+j, r2.max.x, y*scale+j+1), dst, dstn);
88 }
89 freeimage(f->bits);
90 f->bits = i;
91 f->height *= scale;
92 f->ascent *= scale;
94 for(j=0; j<f->n; j++) {
95 f->info[j].x *= scale;
96 f->info[j].top *= scale;
97 f->info[j].bottom *= scale;
98 f->info[j].left *= scale;
99 f->info[j].width *= scale;