]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/tcs/font/merge.c
dc: fix off by one in stack overflow check (thanks BurnZeZ)
[plan9front.git] / sys / src / cmd / tcs / font / merge.c
1 #include        <u.h>
2 #include        <libc.h>
3 #include        <libg.h>
4 #include        <bio.h>
5
6 static void usage(void);
7 static void snarf(char *, int);
8 static void choose(Fontchar *, Bitmap *, int, int, int);
9 struct {
10         char *name;
11         Bitmap *bm;
12         Subfont *sf;
13 } ft[1024];
14 int nf;
15
16 void
17 main(int argc, char **argv)
18 {
19         int i, errs;
20         Fontchar *fc;
21         Bitmap *b;
22         int nc, ht, as;
23         Subfont *f;
24
25         binit(0, 0, "font merge");
26         if(argc < 1)
27                 usage();
28         nf = argc-1;
29         for(i = 0; i < nf; i++)
30                 snarf(argv[i+1], i);
31         nc = ft[0].sf->n;
32         ht = ft[0].sf->height;
33         as = ft[0].sf->ascent;
34         errs = 0;
35         for(i = 0; i < nf; i++){
36                 if(nc < ft[i].sf->n) nc = ft[i].sf->n;
37                 if(ht != ft[1].sf->height){
38                         fprint(2, "%s: %s.height=%d (!= %s.height=%d)\n", argv[0],
39                                 ft[i].name, ft[i].sf->height, ft[0].name, ht);
40                         errs = 1;
41                 }
42                 if(as != ft[1].sf->ascent){
43                         fprint(2, "%s: %s.ascent=%d (!= %s.ascent=%d)\n", argv[0],
44                                 ft[i].name, ft[i].sf->ascent, ft[0].name, ht);
45                         errs = 1;
46                 }
47         }
48         if(errs)
49                 exits("param mismatch");
50         fc = (Fontchar *)malloc(nc*sizeof(Fontchar));
51         b = balloc(Rect(0, 0, nc*64, ht), ft[0].bm->ldepth);
52         if(b == 0 || fc == 0){
53                 fprint(2, "%s: couldn't malloc %d chars\n", argv0, nc);
54                 exits("out of memory");
55         }
56         bitblt(b, b->r.min, b, b->r, Zero);
57         choose(fc, b, nc, ht, as);
58         wrbitmapfile(1, b);
59 bitblt(&screen, screen.r.min, b, b->r, S); bflush();sleep(5000);
60         f = subfalloc(nc, ht, as, fc, b, ~0, ~0);
61         wrsubfontfile(1, f);
62         exits(0);
63 }
64
65 static void
66 usage(void)
67 {
68         fprint(2, "Usage: %s file ...\n", argv0);
69         exits("usage");
70 }
71
72 static void
73 snarf(char *name, int i)
74 {
75         int fd;
76         Bitmap *b;
77
78         ft[i].name = name;
79         if((fd = open(name, OREAD)) < 0){
80                 perror(name);
81                 exits("font read");
82         }
83         if((b = rdbitmapfile(fd)) == 0){
84                 fprint(2, "rdbitmapfile failed\n");
85                 exits("font read");
86         }
87         if((ft[i].bm = balloc(b->r, b->ldepth)) == 0){
88                 fprint(2, "ballocsnarf failed\n");
89                 exits("font read");
90         }
91         bitblt(ft[i].bm, b->r.min, b, b->r, S);
92         if((ft[i].sf = rdsubfontfile(fd, b)) == 0){
93                 fprint(2, "rdsubfontfile failed\n");
94                 exits("font read");
95         }
96         close(fd);
97 }
98
99 static void
100 choose(Fontchar *f, Bitmap *b, int nc, int ht, int as)
101 {
102         int j;
103         Fontchar *info;
104         int lastx = 0;
105         int w, n;
106
107         for(n = 0; n < nc; n++, f++){
108                 f->x = lastx;
109                 for(j = 0; j < nf; j++){
110                         if(n >= ft[j].sf->n)
111                                 continue;
112                         info = ft[j].sf->info;
113                         if(info[n+1].x != info[n].x)
114                                 goto found;
115                 }
116                 continue;
117         found:
118                 f->left = info[n].left;
119                 f->top = info[n].top;
120                 f->bottom = info[n].bottom;
121                 f->width = info[n].width;
122                 w = info[n+1].x - info[n].x;
123                 bitblt(b, Pt(0, lastx), ft[j].bm, Rect(0, info[n].x, ht, info[n+1].x), S);
124                 lastx += w;
125         }
126         f->x = lastx;
127 }