Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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 && 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
}