Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
5 static char*
6 skip(char *s)
7 {
8 while(*s==' ' || *s=='\n' || *s=='\t')
9 s++;
10 return s;
11 }
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)";
23 s = buf;
24 fnt = malloc(sizeof(Font));
25 if(fnt == 0)
26 return 0;
27 memset(fnt, 0, sizeof(Font));
28 fnt->scale = 1;
29 fnt->display = d;
30 fnt->name = strdup(name);
31 fnt->namespec = strdup(name);
32 fnt->ncache = NFCACHE+NFLOOK;
33 fnt->nsubf = NFSUBF;
34 fnt->cache = malloc(fnt->ncache * sizeof(fnt->cache[0]));
35 fnt->subf = malloc(fnt->nsubf * sizeof(fnt->subf[0]));
36 if(fnt->name==0 || fnt->cache==0 || fnt->subf==0){
37 Err2:
38 free(fnt->name);
39 free(fnt->namespec);
40 free(fnt->cache);
41 free(fnt->subf);
42 free(fnt->sub);
43 free(fnt);
44 return 0;
45 }
46 fnt->height = strtol(s, &s, 0);
47 s = skip(s);
48 fnt->ascent = strtol(s, &s, 0);
49 s = skip(s);
50 if(fnt->height<=0 || fnt->ascent<=0){
51 werrstr("bad height or ascent in font file");
52 goto Err2;
53 }
54 fnt->width = 0;
55 fnt->nsub = 0;
56 fnt->sub = 0;
58 memset(fnt->subf, 0, fnt->nsubf * sizeof(fnt->subf[0]));
59 memset(fnt->cache, 0, fnt->ncache*sizeof(fnt->cache[0]));
60 fnt->age = 1;
61 do{
62 /* must be looking at a number now */
63 if(*s<'0' || '9'<*s){
64 werrstr(badform, s-buf);
65 goto Err3;
66 }
67 min = strtol(s, &s, 0);
68 s = skip(s);
69 /* must be looking at a number now */
70 if(*s<'0' || '9'<*s){
71 werrstr(badform, s-buf);
72 goto Err3;
73 }
74 max = strtol(s, &s, 0);
75 s = skip(s);
76 if(*s==0 || min>Runemax || max>Runemax || min>max){
77 werrstr("illegal subfont range");
78 Err3:
79 freefont(fnt);
80 return 0;
81 }
82 t = s;
83 offset = strtol(s, &t, 0);
84 if(t>s && (*t==' ' || *t=='\t' || *t=='\n'))
85 s = skip(t);
86 else
87 offset = 0;
88 fnt->sub = realloc(fnt->sub, (fnt->nsub+1)*sizeof(Cachefont*));
89 if(fnt->sub == 0){
90 /* realloc manual says fnt->sub may have been destroyed */
91 fnt->nsub = 0;
92 goto Err3;
93 }
94 c = malloc(sizeof(Cachefont));
95 if(c == 0)
96 goto Err3;
97 fnt->sub[fnt->nsub] = c;
98 c->min = min;
99 c->max = max;
100 c->offset = offset;
101 t = s;
102 while(*s && *s!=' ' && *s!='\n' && *s!='\t')
103 s++;
104 *s++ = 0;
105 c->subfontname = 0;
106 c->name = strdup(t);
107 if(c->name == 0){
108 free(c);
109 goto Err3;
111 s = skip(s);
112 fnt->nsub++;
113 }while(*s);
114 return fnt;
117 void
118 freefont(Font *f)
120 int i;
121 Cachefont *c;
122 Subfont *s;
124 if(f == 0)
125 return;
127 for(i=0; i<f->nsub; i++){
128 c = f->sub[i];
129 free(c->subfontname);
130 free(c->name);
131 free(c);
133 for(i=0; i<f->nsubf; i++){
134 s = f->subf[i].f;
135 if(s)
136 freesubfont(s);
138 freeimage(f->cacheimage);
139 free(f->name);
140 free(f->namespec);
141 free(f->cache);
142 free(f->subf);
143 free(f->sub);
145 if(f->ondisplaylist) {
146 f->ondisplaylist = 0;
147 if(f->next)
148 f->next->prev = f->prev;
149 else
150 f->display->lastfont = f->prev;
151 if(f->prev)
152 f->prev->next = f->next;
153 else
154 f->display->firstfont = f->next;
157 if(f->lodpi != f)
158 freefont(f->lodpi);
159 if(f->hidpi != f)
160 freefont(f->hidpi);
162 free(f);