17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier
57dd7cddfSDavid du Colombier static char*
skip(char * s)67dd7cddfSDavid du Colombier skip(char *s)
77dd7cddfSDavid du Colombier {
87dd7cddfSDavid du Colombier while(*s==' ' || *s=='\n' || *s=='\t')
97dd7cddfSDavid du Colombier s++;
107dd7cddfSDavid du Colombier return s;
117dd7cddfSDavid du Colombier }
127dd7cddfSDavid du Colombier
137dd7cddfSDavid du Colombier Font*
buildfont(Display * d,char * buf,char * name)147dd7cddfSDavid du Colombier buildfont(Display *d, char *buf, char *name)
157dd7cddfSDavid du Colombier {
167dd7cddfSDavid du Colombier Font *fnt;
177dd7cddfSDavid du Colombier Cachefont *c;
187dd7cddfSDavid du Colombier char *s, *t;
197dd7cddfSDavid du Colombier ulong min, max;
207dd7cddfSDavid du Colombier int offset;
2180ee5cbfSDavid du Colombier char badform[] = "bad font format: number expected (char position %d)";
227dd7cddfSDavid du Colombier
237dd7cddfSDavid du Colombier s = buf;
247dd7cddfSDavid du Colombier fnt = malloc(sizeof(Font));
257dd7cddfSDavid du Colombier if(fnt == 0)
267dd7cddfSDavid du Colombier return 0;
277dd7cddfSDavid du Colombier memset(fnt, 0, sizeof(Font));
287dd7cddfSDavid du Colombier fnt->display = d;
297dd7cddfSDavid du Colombier fnt->name = strdup(name);
307dd7cddfSDavid du Colombier fnt->ncache = NFCACHE+NFLOOK;
317dd7cddfSDavid du Colombier fnt->nsubf = NFSUBF;
327dd7cddfSDavid du Colombier fnt->cache = malloc(fnt->ncache * sizeof(fnt->cache[0]));
337dd7cddfSDavid du Colombier fnt->subf = malloc(fnt->nsubf * sizeof(fnt->subf[0]));
347dd7cddfSDavid du Colombier if(fnt->name==0 || fnt->cache==0 || fnt->subf==0){
357dd7cddfSDavid du Colombier Err2:
367dd7cddfSDavid du Colombier free(fnt->name);
377dd7cddfSDavid du Colombier free(fnt->cache);
387dd7cddfSDavid du Colombier free(fnt->subf);
397dd7cddfSDavid du Colombier free(fnt->sub);
407dd7cddfSDavid du Colombier free(fnt);
417dd7cddfSDavid du Colombier return 0;
427dd7cddfSDavid du Colombier }
437dd7cddfSDavid du Colombier fnt->height = strtol(s, &s, 0);
447dd7cddfSDavid du Colombier s = skip(s);
457dd7cddfSDavid du Colombier fnt->ascent = strtol(s, &s, 0);
467dd7cddfSDavid du Colombier s = skip(s);
477dd7cddfSDavid du Colombier if(fnt->height<=0 || fnt->ascent<=0){
4880ee5cbfSDavid du Colombier werrstr("bad height or ascent in font file");
497dd7cddfSDavid du Colombier goto Err2;
507dd7cddfSDavid du Colombier }
517dd7cddfSDavid du Colombier fnt->width = 0;
527dd7cddfSDavid du Colombier fnt->nsub = 0;
537dd7cddfSDavid du Colombier fnt->sub = 0;
547dd7cddfSDavid du Colombier
557dd7cddfSDavid du Colombier memset(fnt->subf, 0, fnt->nsubf * sizeof(fnt->subf[0]));
567dd7cddfSDavid du Colombier memset(fnt->cache, 0, fnt->ncache*sizeof(fnt->cache[0]));
577dd7cddfSDavid du Colombier fnt->age = 1;
587dd7cddfSDavid du Colombier do{
5980ee5cbfSDavid du Colombier /* must be looking at a number now */
6080ee5cbfSDavid du Colombier if(*s<'0' || '9'<*s){
6180ee5cbfSDavid du Colombier werrstr(badform, s-buf);
6280ee5cbfSDavid du Colombier goto Err3;
6380ee5cbfSDavid du Colombier }
647dd7cddfSDavid du Colombier min = strtol(s, &s, 0);
657dd7cddfSDavid du Colombier s = skip(s);
6680ee5cbfSDavid du Colombier /* must be looking at a number now */
6780ee5cbfSDavid du Colombier if(*s<'0' || '9'<*s){
6880ee5cbfSDavid du Colombier werrstr(badform, s-buf);
6980ee5cbfSDavid du Colombier goto Err3;
7080ee5cbfSDavid du Colombier }
717dd7cddfSDavid du Colombier max = strtol(s, &s, 0);
727dd7cddfSDavid du Colombier s = skip(s);
73*eaba85aaSDavid du Colombier if(*s==0 || min>=Runemax || max>=Runemax || min>max){
747dd7cddfSDavid du Colombier werrstr("illegal subfont range");
757dd7cddfSDavid du Colombier Err3:
767dd7cddfSDavid du Colombier freefont(fnt);
777dd7cddfSDavid du Colombier return 0;
787dd7cddfSDavid du Colombier }
797dd7cddfSDavid du Colombier t = s;
807dd7cddfSDavid du Colombier offset = strtol(s, &t, 0);
817dd7cddfSDavid du Colombier if(t>s && (*t==' ' || *t=='\t' || *t=='\n'))
827dd7cddfSDavid du Colombier s = skip(t);
837dd7cddfSDavid du Colombier else
847dd7cddfSDavid du Colombier offset = 0;
857dd7cddfSDavid du Colombier fnt->sub = realloc(fnt->sub, (fnt->nsub+1)*sizeof(Cachefont*));
867dd7cddfSDavid du Colombier if(fnt->sub == 0){
877dd7cddfSDavid du Colombier /* realloc manual says fnt->sub may have been destroyed */
887dd7cddfSDavid du Colombier fnt->nsub = 0;
897dd7cddfSDavid du Colombier goto Err3;
907dd7cddfSDavid du Colombier }
917dd7cddfSDavid du Colombier c = malloc(sizeof(Cachefont));
927dd7cddfSDavid du Colombier if(c == 0)
937dd7cddfSDavid du Colombier goto Err3;
947dd7cddfSDavid du Colombier fnt->sub[fnt->nsub] = c;
957dd7cddfSDavid du Colombier c->min = min;
967dd7cddfSDavid du Colombier c->max = max;
977dd7cddfSDavid du Colombier c->offset = offset;
987dd7cddfSDavid du Colombier t = s;
997dd7cddfSDavid du Colombier while(*s && *s!=' ' && *s!='\n' && *s!='\t')
1007dd7cddfSDavid du Colombier s++;
1017dd7cddfSDavid du Colombier *s++ = 0;
1027dd7cddfSDavid du Colombier c->subfontname = 0;
1037dd7cddfSDavid du Colombier c->name = strdup(t);
1047dd7cddfSDavid du Colombier if(c->name == 0){
1057dd7cddfSDavid du Colombier free(c);
1067dd7cddfSDavid du Colombier goto Err3;
1077dd7cddfSDavid du Colombier }
1087dd7cddfSDavid du Colombier s = skip(s);
1097dd7cddfSDavid du Colombier fnt->nsub++;
1107dd7cddfSDavid du Colombier }while(*s);
1117dd7cddfSDavid du Colombier return fnt;
1127dd7cddfSDavid du Colombier }
1137dd7cddfSDavid du Colombier
1147dd7cddfSDavid du Colombier void
freefont(Font * f)1157dd7cddfSDavid du Colombier freefont(Font *f)
1167dd7cddfSDavid du Colombier {
1177dd7cddfSDavid du Colombier int i;
1187dd7cddfSDavid du Colombier Cachefont *c;
1197dd7cddfSDavid du Colombier Subfont *s;
1207dd7cddfSDavid du Colombier
1217dd7cddfSDavid du Colombier if(f == 0)
1227dd7cddfSDavid du Colombier return;
1237dd7cddfSDavid du Colombier
1247dd7cddfSDavid du Colombier for(i=0; i<f->nsub; i++){
1257dd7cddfSDavid du Colombier c = f->sub[i];
1267dd7cddfSDavid du Colombier free(c->subfontname);
1277dd7cddfSDavid du Colombier free(c->name);
1287dd7cddfSDavid du Colombier free(c);
1297dd7cddfSDavid du Colombier }
1307dd7cddfSDavid du Colombier for(i=0; i<f->nsubf; i++){
1317dd7cddfSDavid du Colombier s = f->subf[i].f;
132175630faSDavid du Colombier if(s && display && s!=display->defaultsubfont)
1337dd7cddfSDavid du Colombier freesubfont(s);
1347dd7cddfSDavid du Colombier }
1357dd7cddfSDavid du Colombier freeimage(f->cacheimage);
1367dd7cddfSDavid du Colombier free(f->name);
1377dd7cddfSDavid du Colombier free(f->cache);
1387dd7cddfSDavid du Colombier free(f->subf);
1397dd7cddfSDavid du Colombier free(f->sub);
1407dd7cddfSDavid du Colombier free(f);
1417dd7cddfSDavid du Colombier }
142