xref: /inferno-os/libdraw/buildfont.c (revision 546783184a373a2dd59afef3affe029a6aedd701)
1 #include "lib9.h"
2 #include "draw.h"
3 #include "kernel.h"
4 
5 static char*
skip(char * s)6 skip(char *s)
7 {
8 	while(*s==' ' || *s=='\n' || *s=='\t')
9 		s++;
10 	return s;
11 }
12 
13 Font*
buildfont(Display * d,char * buf,char * name)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 		kwerrstr("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 			kwerrstr(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 			kwerrstr(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 			kwerrstr("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
freefont(Font * f)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)*/	/* Plan 9 uses this */
133 		if(s)
134 			freesubfont(s);
135 	}
136 	freeimage(f->cacheimage);
137 	free(f->name);
138 	free(f->cache);
139 	free(f->subf);
140 	free(f->sub);
141 	free(f);
142 }
143