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->namespec); free(f->cache); free(f->subf); free(f->sub); if(f->ondisplaylist) { f->ondisplaylist = 0; if(f->next) f->next->prev = f->prev; else f->display->lastfont = f->prev; if(f->prev) f->prev->next = f->next; else f->display->firstfont = f->next; } if(f->lodpi != f) freefont(f->lodpi); if(f->hidpi != f) freefont(f->hidpi); free(f); }
void rfclose(Reffont *r) { int i; if(decref(&r->ref) == 0){ for(i=0; i<nfontcache; i++) if(r == fontcache[i]) break; if(i >= nfontcache) warning(nil, "internal error: can't find font in cache\n"); else{ nfontcache--; memmove(fontcache+i, fontcache+i+1, (nfontcache-i)*sizeof(Reffont*)); } freefont(r->f); free(r); } }
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){ kwerrstr("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){ kwerrstr(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){ kwerrstr(badform, s-buf); goto Err3; } max = strtol(s, &s, 0); s = skip(s); if(*s==0 || min>=Runemax || max>=Runemax || min>max){ kwerrstr("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; }
static void loadfont(int n, int s) { char file[256]; int i, fd, t, deep; static char *try[3] = {"", "times/R.", "pelm/"}; Subfont *f; Font *ff; try[0] = fname[n]; for (t = 0; t < 3; t++) { i = s * mag * charmap[fmap[n]].xheight/0.72; /* a pixel is 0.72 points */ if (i < MINSIZE) i = MINSIZE; dprint(2, "size %d, i %d, mag %g\n", s, i, mag); for(; i >= MINSIZE; i--) { /* if .font file exists, take that */ snprint(file, sizeof file, "%s/%s%d.font", libfont, try[t], i); ff = openfont(display, file); if(ff != 0) { fonttab[n][s] = ff; dprint(2, "using %s for font %d %d\n", file, n, s); return; } /* else look for a subfont file */ for (deep = log2[screen->depth]; deep >= 0; deep--) { snprint(file, sizeof file, "%s/%s%d.%d", libfont, try[t], i, deep); dprint(2, "trying %s for %d\n", file, i); if ((fd = open(file, 0)) >= 0) { f = readsubfont(display, file, fd, 0); if (f == 0) { fprint(2, "can't rdsubfontfile %s: %r\n", file); exits("rdsubfont"); } close(fd); ff = mkfont(f, 0); if(ff == 0) { fprint(2, "can't mkfont %s: %r\n", file); exits("rdsubfont"); } fonttab[n][s] = ff; dprint(2, "using %s for font %d %d\n", file, n, s); return; } } } } fprint(2, "can't find font %s.%d or substitute, quitting\n", fname[n], s); exits("no font"); } void loadfontname(int n, char *s) { int i; Font *f, *g = 0; if (strcmp(s, fname[n]) == 0) return; if(fname[n] && fname[n][0]) { if(lastload[n] && strcmp(lastload[n], fname[n]) == 0) return; strcpy(lastload[n], fname[n]); } fontlookup(n, s); for (i = 0; i < NSIZE; i++) if (f = fonttab[n][i]) { if (f != g) { freefont(f); g = f; } fonttab[n][i] = 0; } } void allfree(void) { int i; for (i=0; i<NFONT; i++) loadfontname(i, "??"); } void readmapfile(char *file) { Biobuf *fp; char *p, cmd[100]; if ((fp=Bopen(file, OREAD)) == 0) { fprint(2, "proof: can't open map file %s\n", file); exits("urk"); } while((p=Brdline(fp, '\n')) != 0) { p[Blinelen(fp)-1] = 0; scanstr(p, cmd, 0); if(p[0]=='\0' || eq(cmd, "#")) /* skip comments, empty */ continue; else if(eq(cmd, "xheight")) buildxheight(fp); else if(eq(cmd, "map")) buildmap(fp); else if(eq(cmd, "special")) buildtroff(p); else if(eq(cmd, "troff")) buildtroff(p); else fprint(2, "weird map line %s\n", p); } Bterm(fp); }
char * message_root(void *p, IxpMsg *m) { Font *fn; char *s, *ret; ulong n; USED(p); ret = nil; s = getword(m); switch(getsym(s)) { case LQUIT: srv.running = 0; break; case LEXEC: execstr = smprint("exec %s", (char*)m->pos); srv.running = 0; break; case LVIEW: select_view((char*)m->pos); break; case LSELCOLORS: fprint(2, "%s: warning: selcolors have been removed\n", argv0); return Ebadcmd; case LFOCUSCOLORS: ret = parse_colors(m, &def.focuscolor); focus_view(screen, screen->sel); break; case LNORMCOLORS: ret = parse_colors(m, &def.normcolor); focus_view(screen, screen->sel); break; case LFONT: fn = loadfont((char*)m->pos); if(fn) { freefont(def.font); def.font = fn; resize_bar(screen); }else ret = "can't load font"; focus_view(screen, screen->sel); break; case LBORDER: if(!getulong(getword(m), &n)) return Ebadvalue; def.border = n; focus_view(screen, screen->sel); break; case LGRABMOD: s = getword(m); n = str2modmask(s); if((n & (Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) == 0) return Ebadvalue; utflcpy(def.grabmod, s, sizeof(def.grabmod)); def.mod = n; break; default: return Ebadcmd; } return ret; }