plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

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 }