8 char fname[NFONT][20]; /* font names */
9 char lastload[NFONT][20]; /* last file name prefix loaded for this font */
10 Font *fonttab[NFONT][NSIZE]; /* pointers to fonts */
11 int fmap[NFONT]; /* what map to use with this font */
13 static void loadfont(int, int);
14 static void fontlookup(int, char *);
15 static void buildxheight(Biobuf*);
16 static void buildmap(Biobuf*);
17 static void buildtroff(char *);
18 static void addmap(int, char *, int);
19 static char *map(Rune*, int);
20 static void scanstr(char *, char *, char **);
22 int specfont; /* somehow, number of special font */
25 #define QUICK 2048 /* char values less than this are quick to look up */
26 #define eq(s,t) strcmp((char *) s, (char *) t) == 0
28 int curmap = -1; /* what map are we working on */
30 typedef struct Link Link;
31 struct Link /* link names together */
38 typedef struct Map Map;
39 struct Map /* holds a mapping from uchar name to index */
42 Rune quick[QUICK]; /* low values get special treatment */
43 Link *slow; /* other stuff goes into a link list */
48 typedef struct Fontmap Fontmap;
49 struct Fontmap /* mapping from troff name to filename */
53 int map; /* which charmap to use for this font */
54 char *fallback; /* font to look in if can't find char here */
58 int pos2fontmap[NFONT]; /* indexed by troff font position, gives Fontmap */
59 int nfontmap = 0; /* how many are there */
72 if((s = map(r, curfont)) == 0){ /* not on current font */
73 if ((s = map(r, specfont)) != 0) /* on special font */
76 /* look for fallback */
77 fm = pos2fontmap[curfont];
78 fb = fontmap[fm].fallback;
80 /* see if fallback is mounted */
81 for(i = 0; i < NFONT; i++){
82 if(eq(fb, fontmap[pos2fontmap[i]].troffname)){
91 /* no such char; use name itself on defont */
92 /* this is not a general solution */
93 p.x = hpos/DIV + xyoffset.x + offset.x;
94 p.y = vpos/DIV + xyoffset.y + offset.y;
97 string(screen, p, display->black, ZP, font, buf);
102 p.x = hpos/DIV + xyoffset.x + offset.x;
103 p.y = vpos/DIV + xyoffset.y + offset.y;
104 while ((f = fonttab[fontno][cursize]) == 0)
105 loadfont(fontno, cursize);
107 dprint(2, "putting %S at %d,%d font %d, size %d\n", r, p.x, p.y, fontno, cursize);
108 string(screen, p, display->black, ZP, f, s);
111 static int drawlog2[] = {
115 3, 3, 3, 3, 3, 3, 3, 3,
116 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
121 loadfont(int n, int s)
125 static char *try[3] = {"", "times/R.", "pelm/"};
130 dprint(2, "loadfont %d %d\n", n, s);
131 for (t = 0; t < 3; t++){
132 i = s * mag * charmap[fmap[n]].xheight/0.72; /* a pixel is 0.72 points */
135 dprint(2, "size %d, i %d, mag %g\n", s, i, mag);
136 for(; i >= MINSIZE; i--){
137 /* if .font file exists, take that */
138 sprint(file, "%s/%s%d.font", libfont, try[t], i);
139 ff = openfont(display, file);
142 dprint(2, "using %s for font %d %d\n", file, n, s);
145 /* else look for a subfont file */
146 for (deep = drawlog2[screen->depth]; deep >= 0; deep--){
147 sprint(file, "%s/%s%d.%d", libfont, try[t], i, deep);
148 dprint(2, "trying %s for %d\n", file, i);
149 if ((fd = open(file, 0)) >= 0){
150 f = readsubfont(display, file, fd, 0);
152 fprint(2, "can't rdsubfontfile %s: %r\n", file);
158 fprint(2, "can't mkfont %s: %r\n", file);
162 dprint(2, "using %s for font %d %d\n", file, n, s);
168 fprint(2, "can't find font %s.%d or substitute, quitting\n", fname[n], s);
173 loadfontname(int n, char *s)
178 if (strcmp(s, fname[n]) == 0)
180 if(fname[n] && fname[n][0]){
181 if(lastload[n] && strcmp(lastload[n], fname[n]) == 0)
183 strcpy(lastload[n], fname[n]);
186 for (i = 0; i < NSIZE; i++)
187 if (f = fonttab[n][i]){
201 for (i=0; i<NFONT; i++)
202 loadfontname(i, "??");
207 readmapfile(char *file)
212 if ((fp=Bopen(file, OREAD)) == 0){
213 fprint(2, "proof: can't open map file %s\n", file);
216 while((p=Brdline(fp, '\n')) != 0) {
217 p[Blinelen(fp)-1] = 0;
219 if(p[0]=='\0' || eq(cmd, "#")) /* skip comments, empty */
221 else if(eq(cmd, "xheight"))
223 else if(eq(cmd, "map"))
225 else if(eq(cmd, "special"))
227 else if(eq(cmd, "troff"))
230 fprint(2, "weird map line %s\n", p);
236 buildxheight(Biobuf *fp) /* map goes from char name to value to print via *string() */
240 line = Brdline(fp, '\n');
242 fprint(2, "proof: bad map file\n");
245 charmap[curmap].xheight = atof(line);
249 buildmap(Biobuf *fp) /* map goes from char name to value to print via *string() */
251 uchar *p, *line, ch[100];
257 fprint(2, "proof: out of char maps; recompile\n");
260 while ((line = Brdline(fp, '\n'))!= 0){
263 line[Blinelen(fp)-1] = 0;
264 scanstr((char *) line, (char *) ch, (char **)(void*)&p);
266 fprint(2, "bad map file line '%s'\n", (char*)line);
269 val = strtol((char *) p, 0, 10);
270 dprint(2, "buildmap %s (%x %x) %s %d\n", (char*)ch, ch[0], ch[1], (char*)p, val);
271 chartorune(&r, (char*)ch);
272 if(utflen((char*)ch)==1 && r<QUICK)
273 charmap[curmap].quick[r] = val;
275 addmap(curmap, strdup((char *) ch), val); /* put somewhere else */
280 addmap(int n, char *s, int val) /* stick a new link on */
282 Link *p = (Link *) malloc(sizeof(Link));
283 Link *prev = charmap[n].slow;
286 exits("out of memory in addmap");
287 p->name = (uchar *) s;
294 buildtroff(char *buf) /* map troff names into bitmap filenames */
295 { /* e.g., R -> times/R., I -> times/I., etc. */
296 char *p, cmd[100], name[200], prefix[400], fallback[100];
298 scanstr(buf, cmd, &p);
299 scanstr(p, name, &p);
300 scanstr(p, prefix, &p);
301 while(*p!=0 && isspace(*p))
304 scanstr(p, fallback, &p);
305 fontmap[nfontmap].fallback = strdup(fallback);
307 fontmap[nfontmap].fallback = 0;
308 fontmap[nfontmap].troffname = strdup(name);
309 fontmap[nfontmap].prefix = strdup(prefix);
310 fontmap[nfontmap].map = curmap;
311 dprint(2, "troff name %s is bitmap %s map %d in slot %d fallback %s\n", name, prefix, curmap, nfontmap, fontmap[nfontmap].fallback? fontmap[nfontmap].fallback : "<null>");
316 fontlookup(int n, char *s) /* map troff name of s into position n */
320 for(i = 0; i < nfontmap; i++)
321 if (eq(s, fontmap[i].troffname)) {
322 strcpy(fname[n], fontmap[i].prefix);
323 fmap[n] = fontmap[i].map;
327 dprint(2, "font %d %s is %s\n", n, s, fname[n]);
330 /* god help us if this font isn't there */
335 map(Rune rp[], int font) /* figure out mapping for char in this font */
342 if(rp[1]==0 && rp[0]<QUICK) /* fast lookup */
343 r = charmap[fmap[font]].quick[rp[0]];
344 else { /* high-valued or compound character name */
347 for (p = charmap[fmap[font]].slow; p; p = p->next)
353 if(r == 0){ /* not there */
354 dprint(2, "didn't find %S font# %d\n", rp, font);
357 dprint(2, "map %S to %s font# %d\n", rp, s, font);
358 s[runetochar(s, &r)] = 0;
363 scanstr(char *s, char *ans, char **ep)
365 for (; isspace((uchar) *s); s++)
367 for (; *s!=0 && !isspace((uchar) *s); )