123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- #include <u.h>
- #include <libc.h>
- #include <draw.h>
- static char*
- skip(char *s)
- {
- while(*s==' ' || *s=='\n' || *s=='\t')
- s++;
- return s;
- }
- Font*
- buildfont(Display *d, char *buf, char *name)
- {
- Font *fnt;
- Cachefont *c;
- char *s, *t;
- ulong min, max;
- int offset;
- char badform[] = "bad font format: number expected (char position %d)";
- s = buf;
- fnt = malloc(sizeof(Font));
- if(fnt == 0)
- return 0;
- memset(fnt, 0, sizeof(Font));
- fnt->display = d;
- fnt->name = strdup(name);
- fnt->ncache = NFCACHE+NFLOOK;
- fnt->nsubf = NFSUBF;
- fnt->cache = malloc(fnt->ncache * sizeof(fnt->cache[0]));
- fnt->subf = malloc(fnt->nsubf * sizeof(fnt->subf[0]));
- if(fnt->name==0 || fnt->cache==0 || fnt->subf==0){
- Err2:
- free(fnt->name);
- free(fnt->cache);
- free(fnt->subf);
- free(fnt->sub);
- free(fnt);
- return 0;
- }
- fnt->height = strtol(s, &s, 0);
- s = skip(s);
- fnt->ascent = strtol(s, &s, 0);
- s = skip(s);
- if(fnt->height<=0 || fnt->ascent<=0){
- werrstr("bad height or ascent in font file");
- goto Err2;
- }
- fnt->width = 0;
- fnt->nsub = 0;
- fnt->sub = 0;
- memset(fnt->subf, 0, fnt->nsubf * sizeof(fnt->subf[0]));
- memset(fnt->cache, 0, fnt->ncache*sizeof(fnt->cache[0]));
- fnt->age = 1;
- do{
- /* must be looking at a number now */
- if(*s<'0' || '9'<*s){
- werrstr(badform, s-buf);
- goto Err3;
- }
- min = strtol(s, &s, 0);
- s = skip(s);
- /* must be looking at a number now */
- if(*s<'0' || '9'<*s){
- werrstr(badform, s-buf);
- goto Err3;
- }
- max = strtol(s, &s, 0);
- s = skip(s);
- if(*s==0 || min>=65536 || max>=65536 || min>max){
- werrstr("illegal subfont range");
- Err3:
- freefont(fnt);
- return 0;
- }
- t = s;
- offset = strtol(s, &t, 0);
- if(t>s && (*t==' ' || *t=='\t' || *t=='\n'))
- s = skip(t);
- else
- offset = 0;
- fnt->sub = realloc(fnt->sub, (fnt->nsub+1)*sizeof(Cachefont*));
- if(fnt->sub == 0){
- /* realloc manual says fnt->sub may have been destroyed */
- fnt->nsub = 0;
- goto Err3;
- }
- c = malloc(sizeof(Cachefont));
- if(c == 0)
- goto Err3;
- fnt->sub[fnt->nsub] = c;
- c->min = min;
- c->max = max;
- c->offset = offset;
- t = s;
- while(*s && *s!=' ' && *s!='\n' && *s!='\t')
- s++;
- *s++ = 0;
- c->subfontname = 0;
- c->name = strdup(t);
- if(c->name == 0){
- free(c);
- goto Err3;
- }
- s = skip(s);
- fnt->nsub++;
- }while(*s);
- return fnt;
- }
- void
- freefont(Font *f)
- {
- int i;
- Cachefont *c;
- Subfont *s;
- if(f == 0)
- return;
- for(i=0; i<f->nsub; i++){
- c = f->sub[i];
- free(c->subfontname);
- free(c->name);
- free(c);
- }
- for(i=0; i<f->nsubf; i++){
- s = f->subf[i].f;
- if(s && s!=display->defaultsubfont)
- freesubfont(s);
- }
- freeimage(f->cacheimage);
- free(f->name);
- free(f->cache);
- free(f->subf);
- free(f->sub);
- free(f);
- }
|