buildfont.c (3077B)
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->scale = 1; 29 fnt->display = d; 30 fnt->name = strdup(name); 31 fnt->namespec = strdup(name); 32 fnt->ncache = NFCACHE+NFLOOK; 33 fnt->nsubf = NFSUBF; 34 fnt->cache = malloc(fnt->ncache * sizeof(fnt->cache[0])); 35 fnt->subf = malloc(fnt->nsubf * sizeof(fnt->subf[0])); 36 if(fnt->name==0 || fnt->cache==0 || fnt->subf==0){ 37 Err2: 38 free(fnt->name); 39 free(fnt->namespec); 40 free(fnt->cache); 41 free(fnt->subf); 42 free(fnt->sub); 43 free(fnt); 44 return 0; 45 } 46 fnt->height = strtol(s, &s, 0); 47 s = skip(s); 48 fnt->ascent = strtol(s, &s, 0); 49 s = skip(s); 50 if(fnt->height<=0 || fnt->ascent<=0){ 51 werrstr("bad height or ascent in font file"); 52 goto Err2; 53 } 54 fnt->width = 0; 55 fnt->nsub = 0; 56 fnt->sub = 0; 57 58 memset(fnt->subf, 0, fnt->nsubf * sizeof(fnt->subf[0])); 59 memset(fnt->cache, 0, fnt->ncache*sizeof(fnt->cache[0])); 60 fnt->age = 1; 61 do{ 62 /* must be looking at a number now */ 63 if(*s<'0' || '9'<*s){ 64 werrstr(badform, s-buf); 65 goto Err3; 66 } 67 min = strtol(s, &s, 0); 68 s = skip(s); 69 /* must be looking at a number now */ 70 if(*s<'0' || '9'<*s){ 71 werrstr(badform, s-buf); 72 goto Err3; 73 } 74 max = strtol(s, &s, 0); 75 s = skip(s); 76 if(*s==0 || min>Runemax || max>Runemax || min>max){ 77 werrstr("illegal subfont range"); 78 Err3: 79 freefont(fnt); 80 return 0; 81 } 82 t = s; 83 offset = strtol(s, &t, 0); 84 if(t>s && (*t==' ' || *t=='\t' || *t=='\n')) 85 s = skip(t); 86 else 87 offset = 0; 88 fnt->sub = realloc(fnt->sub, (fnt->nsub+1)*sizeof(Cachefont*)); 89 if(fnt->sub == 0){ 90 /* realloc manual says fnt->sub may have been destroyed */ 91 fnt->nsub = 0; 92 goto Err3; 93 } 94 c = malloc(sizeof(Cachefont)); 95 if(c == 0) 96 goto Err3; 97 fnt->sub[fnt->nsub] = c; 98 c->min = min; 99 c->max = max; 100 c->offset = offset; 101 t = s; 102 while(*s && *s!=' ' && *s!='\n' && *s!='\t') 103 s++; 104 *s++ = 0; 105 c->subfontname = 0; 106 c->name = strdup(t); 107 if(c->name == 0){ 108 free(c); 109 goto Err3; 110 } 111 s = skip(s); 112 fnt->nsub++; 113 }while(*s); 114 return fnt; 115 } 116 117 void 118 freefont(Font *f) 119 { 120 int i; 121 Cachefont *c; 122 Subfont *s; 123 124 if(f == 0) 125 return; 126 127 for(i=0; i<f->nsub; i++){ 128 c = f->sub[i]; 129 free(c->subfontname); 130 free(c->name); 131 free(c); 132 } 133 for(i=0; i<f->nsubf; i++){ 134 s = f->subf[i].f; 135 if(s) 136 freesubfont(s); 137 } 138 freeimage(f->cacheimage); 139 free(f->name); 140 free(f->namespec); 141 free(f->cache); 142 free(f->subf); 143 free(f->sub); 144 145 if(f->ondisplaylist) { 146 f->ondisplaylist = 0; 147 if(f->next) 148 f->next->prev = f->prev; 149 else 150 f->display->lastfont = f->prev; 151 if(f->prev) 152 f->prev->next = f->next; 153 else 154 f->display->firstfont = f->next; 155 } 156 157 if(f->lodpi != f) 158 freefont(f->lodpi); 159 if(f->hidpi != f) 160 freefont(f->hidpi); 161 162 free(f); 163 }