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->cache);
40 free(fnt->subf);
41 free(fnt->sub);
42 free(fnt);
43 return 0;
44 }
45 fnt->height = strtol(s, &s, 0);
46 s = skip(s);
47 fnt->ascent = strtol(s, &s, 0);
48 s = skip(s);
49 if(fnt->height<=0 || fnt->ascent<=0){
50 werrstr("bad height or ascent in font file");
51 goto Err2;
52 }
53 fnt->width = 0;
54 fnt->nsub = 0;
55 fnt->sub = 0;
57 memset(fnt->subf, 0, fnt->nsubf * sizeof(fnt->subf[0]));
58 memset(fnt->cache, 0, fnt->ncache*sizeof(fnt->cache[0]));
59 fnt->age = 1;
60 do{
61 /* must be looking at a number now */
62 if(*s<'0' || '9'<*s){
63 werrstr(badform, s-buf);
64 goto Err3;
65 }
66 min = strtol(s, &s, 0);
67 s = skip(s);
68 /* must be looking at a number now */
69 if(*s<'0' || '9'<*s){
70 werrstr(badform, s-buf);
71 goto Err3;
72 }
73 max = strtol(s, &s, 0);
74 s = skip(s);
75 if(*s==0 || min>Runemax || max>Runemax || min>max){
76 werrstr("illegal subfont range");
77 Err3:
78 freefont(fnt);
79 return 0;
80 }
81 t = s;
82 offset = strtol(s, &t, 0);
83 if(t>s && (*t==' ' || *t=='\t' || *t=='\n'))
84 s = skip(t);
85 else
86 offset = 0;
87 fnt->sub = realloc(fnt->sub, (fnt->nsub+1)*sizeof(Cachefont*));
88 if(fnt->sub == 0){
89 /* realloc manual says fnt->sub may have been destroyed */
90 fnt->nsub = 0;
91 goto Err3;
92 }
93 c = malloc(sizeof(Cachefont));
94 if(c == 0)
95 goto Err3;
96 fnt->sub[fnt->nsub] = c;
97 c->min = min;
98 c->max = max;
99 c->offset = offset;
100 t = s;
101 while(*s && *s!=' ' && *s!='\n' && *s!='\t')
102 s++;
103 *s++ = 0;
104 c->subfontname = 0;
105 c->name = strdup(t);
106 if(c->name == 0){
107 free(c);
108 goto Err3;
110 s = skip(s);
111 fnt->nsub++;
112 }while(*s);
113 return fnt;
116 void
117 freefont(Font *f)
119 int i;
120 Cachefont *c;
121 Subfont *s;
123 if(f == 0)
124 return;
126 for(i=0; i<f->nsub; i++){
127 c = f->sub[i];
128 free(c->subfontname);
129 free(c->name);
130 free(c);
132 for(i=0; i<f->nsubf; i++){
133 s = f->subf[i].f;
134 if(s && (!display || s!=display->defaultsubfont))
135 freesubfont(s);
137 freeimage(f->cacheimage);
138 free(f->name);
139 free(f->namespec);
140 free(f->cache);
141 free(f->subf);
142 free(f->sub);
144 if(f->ondisplaylist) {
145 f->ondisplaylist = 0;
146 if(f->next)
147 f->next->prev = f->prev;
148 else
149 f->display->lastfont = f->prev;
150 if(f->prev)
151 f->prev->next = f->next;
152 else
153 f->display->firstfont = f->next;
156 if(f->lodpi != f)
157 freefont(f->lodpi);
158 if(f->hidpi != f)
159 freefont(f->hidpi);
161 free(f);