]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libdraw/buildfont.c
fix utf and rune handling in preparation for 32bit runes
[plan9front.git] / sys / src / libdraw / buildfont.c
1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4
5 static char*
6 skip(char *s)
7 {
8         while(*s==' ' || *s=='\n' || *s=='\t')
9                 s++;
10         return s;
11 }
12
13 Font*
14 buildfont(Display *d, char *buf, char *name)
15 {
16         Font *fnt;
17         Cachefont *c;
18         char *s, *t;
19         ulong min, max;
20         int offset;
21         char badform[] = "bad font format: number expected (char position %d)";
22
23         s = buf;
24         fnt = malloc(sizeof(Font));
25         if(fnt == 0)
26                 return 0;
27         memset(fnt, 0, sizeof(Font));
28         fnt->display = d;
29         fnt->name = strdup(name);
30         fnt->ncache = NFCACHE+NFLOOK;
31         fnt->nsubf = NFSUBF;
32         fnt->cache = malloc(fnt->ncache * sizeof(fnt->cache[0]));
33         fnt->subf = malloc(fnt->nsubf * sizeof(fnt->subf[0]));
34         if(fnt->name==0 || fnt->cache==0 || fnt->subf==0){
35     Err2:
36                 free(fnt->name);
37                 free(fnt->cache);
38                 free(fnt->subf);
39                 free(fnt->sub);
40                 free(fnt);
41                 return 0;
42         }
43         fnt->height = strtol(s, &s, 0);
44         s = skip(s);
45         fnt->ascent = strtol(s, &s, 0);
46         s = skip(s);
47         if(fnt->height<=0 || fnt->ascent<=0){
48                 werrstr("bad height or ascent in font file");
49                 goto Err2;
50         }
51         fnt->width = 0;
52         fnt->nsub = 0;
53         fnt->sub = 0;
54
55         memset(fnt->subf, 0, fnt->nsubf * sizeof(fnt->subf[0]));
56         memset(fnt->cache, 0, fnt->ncache*sizeof(fnt->cache[0]));
57         fnt->age = 1;
58         do{
59                 /* must be looking at a number now */
60                 if(*s<'0' || '9'<*s){
61                         werrstr(badform, s-buf);
62                         goto Err3;
63                 }
64                 min = strtol(s, &s, 0);
65                 s = skip(s);
66                 /* must be looking at a number now */
67                 if(*s<'0' || '9'<*s){
68                         werrstr(badform, s-buf);
69                         goto Err3;
70                 }
71                 max = strtol(s, &s, 0);
72                 s = skip(s);
73                 if(*s==0 || min>Runemax || max>Runemax || min>max){
74                         werrstr("illegal subfont range");
75     Err3:
76                         freefont(fnt);
77                         return 0;
78                 }
79                 t = s;
80                 offset = strtol(s, &t, 0);
81                 if(t>s && (*t==' ' || *t=='\t' || *t=='\n'))
82                         s = skip(t);
83                 else
84                         offset = 0;
85                 fnt->sub = realloc(fnt->sub, (fnt->nsub+1)*sizeof(Cachefont*));
86                 if(fnt->sub == 0){
87                         /* realloc manual says fnt->sub may have been destroyed */
88                         fnt->nsub = 0;
89                         goto Err3;
90                 }
91                 c = malloc(sizeof(Cachefont));
92                 if(c == 0)
93                         goto Err3;
94                 fnt->sub[fnt->nsub] = c;
95                 c->min = min;
96                 c->max = max;
97                 c->offset = offset;
98                 t = s;
99                 while(*s && *s!=' ' && *s!='\n' && *s!='\t')
100                         s++;
101                 *s++ = 0;
102                 c->subfontname = 0;
103                 c->name = strdup(t);
104                 if(c->name == 0){
105                         free(c);
106                         goto Err3;
107                 }
108                 s = skip(s);
109                 fnt->nsub++;
110         }while(*s);
111         return fnt;
112 }
113
114 void
115 freefont(Font *f)
116 {
117         int i;
118         Cachefont *c;
119         Subfont *s;
120
121         if(f == 0)
122                 return;
123
124         for(i=0; i<f->nsub; i++){
125                 c = f->sub[i];
126                 free(c->subfontname);
127                 free(c->name);
128                 free(c);
129         }
130         for(i=0; i<f->nsubf; i++){
131                 s = f->subf[i].f;
132                 if(s && s!=display->defaultsubfont)
133                         freesubfont(s);
134         }
135         freeimage(f->cacheimage);
136         free(f->name);
137         free(f->cache);
138         free(f->subf);
139         free(f->sub);
140         free(f);
141 }