xref: /plan9/sys/src/libdraw/buildfont.c (revision eaba85aa6b158bdf68fdb77f770e3ba0899a8b5e)
1 #include <u.h>
2 #include <libc.h>
3 #include <draw.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 		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
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 && display && 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 }
142