#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>Runemax || max>Runemax || 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;} voidfreefont(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 && display && s!=display->defaultsubfont) freesubfont(s); } freeimage(f->cacheimage); free(f->name); free(f->cache); free(f->subf); free(f->sub); free(f);}
#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>Runemax || max>Runemax || 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 && display && s!=display->defaultsubfont)
freesubfont(s);
}
freeimage(f->cacheimage);
free(f->name);
free(f->cache);
free(f->subf);
free(f->sub);
free(f);
}