13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier #include <event.h>
53e12c5d1SDavid du Colombier #include <bio.h>
63e12c5d1SDavid du Colombier #include "proof.h"
73e12c5d1SDavid du Colombier
83e12c5d1SDavid du Colombier char fname[NFONT][20]; /* font names */
97dd7cddfSDavid du Colombier char lastload[NFONT][20]; /* last file name prefix loaded for this font */
103e12c5d1SDavid du Colombier Font *fonttab[NFONT][NSIZE]; /* pointers to fonts */
113e12c5d1SDavid du Colombier int fmap[NFONT]; /* what map to use with this font */
123e12c5d1SDavid du Colombier
133e12c5d1SDavid du Colombier static void bufchar(Point, Subfont *, uchar *);
143e12c5d1SDavid du Colombier static void loadfont(int, int);
153e12c5d1SDavid du Colombier static void fontlookup(int, char *);
16219b2ee8SDavid du Colombier static void buildxheight(Biobuf*);
173e12c5d1SDavid du Colombier static void buildmap(Biobuf*);
183e12c5d1SDavid du Colombier static void buildtroff(char *);
193e12c5d1SDavid du Colombier static void addmap(int, char *, int);
20219b2ee8SDavid du Colombier static char *map(Rune*, int);
213e12c5d1SDavid du Colombier static void scanstr(char *, char *, char **);
223e12c5d1SDavid du Colombier
233e12c5d1SDavid du Colombier int specfont; /* somehow, number of special font */
243e12c5d1SDavid du Colombier
25219b2ee8SDavid du Colombier #define NMAP 5
26219b2ee8SDavid du Colombier #define QUICK 2048 /* char values less than this are quick to look up */
27219b2ee8SDavid du Colombier #define eq(s,t) strcmp((char *) s, (char *) t) == 0
28219b2ee8SDavid du Colombier
29219b2ee8SDavid du Colombier int curmap = -1; /* what map are we working on */
30219b2ee8SDavid du Colombier
31219b2ee8SDavid du Colombier typedef struct Link Link;
32219b2ee8SDavid du Colombier struct Link /* link names together */
333e12c5d1SDavid du Colombier {
34219b2ee8SDavid du Colombier uchar *name;
35219b2ee8SDavid du Colombier int val;
36219b2ee8SDavid du Colombier Link *next;
37219b2ee8SDavid du Colombier };
38219b2ee8SDavid du Colombier
39219b2ee8SDavid du Colombier typedef struct Map Map;
40219b2ee8SDavid du Colombier struct Map /* holds a mapping from uchar name to index */
41219b2ee8SDavid du Colombier {
42219b2ee8SDavid du Colombier double xheight;
43219b2ee8SDavid du Colombier Rune quick[QUICK]; /* low values get special treatment */
44219b2ee8SDavid du Colombier Link *slow; /* other stuff goes into a link list */
45219b2ee8SDavid du Colombier };
46219b2ee8SDavid du Colombier
47219b2ee8SDavid du Colombier Map charmap[5];
48219b2ee8SDavid du Colombier
49219b2ee8SDavid du Colombier typedef struct Fontmap Fontmap;
50219b2ee8SDavid du Colombier struct Fontmap /* mapping from troff name to filename */
51219b2ee8SDavid du Colombier {
52219b2ee8SDavid du Colombier char *troffname;
53219b2ee8SDavid du Colombier char *prefix;
54219b2ee8SDavid du Colombier int map; /* which charmap to use for this font */
55219b2ee8SDavid du Colombier char *fallback; /* font to look in if can't find char here */
56219b2ee8SDavid du Colombier };
57219b2ee8SDavid du Colombier
58219b2ee8SDavid du Colombier Fontmap fontmap[100];
59219b2ee8SDavid du Colombier int pos2fontmap[NFONT]; /* indexed by troff font position, gives Fontmap */
60219b2ee8SDavid du Colombier int nfontmap = 0; /* how many are there */
61219b2ee8SDavid du Colombier
62219b2ee8SDavid du Colombier
63219b2ee8SDavid du Colombier void
dochar(Rune r[])64219b2ee8SDavid du Colombier dochar(Rune r[])
65219b2ee8SDavid du Colombier {
66219b2ee8SDavid du Colombier char *s, *fb;
673e12c5d1SDavid du Colombier Font *f;
683e12c5d1SDavid du Colombier Point p;
69219b2ee8SDavid du Colombier int fontno, fm, i;
70bfe6f914SDavid du Colombier char buf[32];
713e12c5d1SDavid du Colombier
723e12c5d1SDavid du Colombier fontno = curfont;
73219b2ee8SDavid du Colombier if((s = map(r, curfont)) == 0){ /* not on current font */
74219b2ee8SDavid du Colombier if ((s = map(r, specfont)) != 0) /* on special font */
753e12c5d1SDavid du Colombier fontno = specfont;
76219b2ee8SDavid du Colombier else{
77219b2ee8SDavid du Colombier /* look for fallback */
78219b2ee8SDavid du Colombier fm = pos2fontmap[curfont];
79219b2ee8SDavid du Colombier fb = fontmap[fm].fallback;
80219b2ee8SDavid du Colombier if(fb){
81219b2ee8SDavid du Colombier /* see if fallback is mounted */
82219b2ee8SDavid du Colombier for(i = 0; i < NFONT; i++){
83219b2ee8SDavid du Colombier if(eq(fb, fontmap[pos2fontmap[i]].troffname)){
84219b2ee8SDavid du Colombier s = map(r, i);
85219b2ee8SDavid du Colombier if(s){
86219b2ee8SDavid du Colombier fontno = i;
87219b2ee8SDavid du Colombier goto found;
88219b2ee8SDavid du Colombier }
89219b2ee8SDavid du Colombier }
90219b2ee8SDavid du Colombier }
91219b2ee8SDavid du Colombier }
923e12c5d1SDavid du Colombier /* no such char; use name itself on defont */
93219b2ee8SDavid du Colombier /* this is not a general solution */
943e12c5d1SDavid du Colombier p.x = hpos/DIV + xyoffset.x + offset.x;
953e12c5d1SDavid du Colombier p.y = vpos/DIV + xyoffset.y + offset.y;
963e12c5d1SDavid du Colombier p.y -= font->ascent;
97bfe6f914SDavid du Colombier snprint(buf, sizeof buf, "%S", r);
987dd7cddfSDavid du Colombier string(screen, p, display->black, ZP, font, buf);
993e12c5d1SDavid du Colombier return;
1003e12c5d1SDavid du Colombier }
1013e12c5d1SDavid du Colombier }
102219b2ee8SDavid du Colombier found:
1033e12c5d1SDavid du Colombier p.x = hpos/DIV + xyoffset.x + offset.x;
1043e12c5d1SDavid du Colombier p.y = vpos/DIV + xyoffset.y + offset.y;
1053e12c5d1SDavid du Colombier while ((f = fonttab[fontno][cursize]) == 0)
1063e12c5d1SDavid du Colombier loadfont(fontno, cursize);
1073e12c5d1SDavid du Colombier p.y -= f->ascent;
108219b2ee8SDavid du Colombier dprint(2, "putting %S at %d,%d font %d, size %d\n", r, p.x, p.y, fontno, cursize);
1097dd7cddfSDavid du Colombier string(screen, p, display->black, ZP, f, s);
1103e12c5d1SDavid du Colombier }
1113e12c5d1SDavid du Colombier
112*bacfa46cSDavid du Colombier /* imported from libdraw/arith.c to permit an extern log2 function */
113*bacfa46cSDavid du Colombier static int log2[] = {
114*bacfa46cSDavid du Colombier -1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, 4,
115*bacfa46cSDavid du Colombier -1, -1, -1, -1, -1, -1, -1, 4 /* BUG */, -1, -1, -1, -1, -1, -1, -1, 5
116*bacfa46cSDavid du Colombier };
1173e12c5d1SDavid du Colombier
1183e12c5d1SDavid du Colombier static void
loadfont(int n,int s)1193e12c5d1SDavid du Colombier loadfont(int n, int s)
1203e12c5d1SDavid du Colombier {
121bfe6f914SDavid du Colombier char file[256];
1227dd7cddfSDavid du Colombier int i, fd, t, deep;
1233e12c5d1SDavid du Colombier static char *try[3] = {"", "times/R.", "pelm/"};
1243e12c5d1SDavid du Colombier Subfont *f;
1253e12c5d1SDavid du Colombier Font *ff;
1263e12c5d1SDavid du Colombier
1273e12c5d1SDavid du Colombier try[0] = fname[n];
1283e12c5d1SDavid du Colombier for (t = 0; t < 3; t++){
129219b2ee8SDavid du Colombier i = s * mag * charmap[fmap[n]].xheight/0.72; /* a pixel is 0.72 points */
1303e12c5d1SDavid du Colombier if (i < MINSIZE)
1313e12c5d1SDavid du Colombier i = MINSIZE;
1323e12c5d1SDavid du Colombier dprint(2, "size %d, i %d, mag %g\n", s, i, mag);
133219b2ee8SDavid du Colombier for(; i >= MINSIZE; i--){
134219b2ee8SDavid du Colombier /* if .font file exists, take that */
135bfe6f914SDavid du Colombier snprint(file, sizeof file, "%s/%s%d.font",
136bfe6f914SDavid du Colombier libfont, try[t], i);
1377dd7cddfSDavid du Colombier ff = openfont(display, file);
138219b2ee8SDavid du Colombier if(ff != 0){
139219b2ee8SDavid du Colombier fonttab[n][s] = ff;
140219b2ee8SDavid du Colombier dprint(2, "using %s for font %d %d\n", file, n, s);
141219b2ee8SDavid du Colombier return;
142219b2ee8SDavid du Colombier }
143219b2ee8SDavid du Colombier /* else look for a subfont file */
1447dd7cddfSDavid du Colombier for (deep = log2[screen->depth]; deep >= 0; deep--){
145bfe6f914SDavid du Colombier snprint(file, sizeof file, "%s/%s%d.%d",
146bfe6f914SDavid du Colombier libfont, try[t], i, deep);
1473e12c5d1SDavid du Colombier dprint(2, "trying %s for %d\n", file, i);
1483e12c5d1SDavid du Colombier if ((fd = open(file, 0)) >= 0){
1497dd7cddfSDavid du Colombier f = readsubfont(display, file, fd, 0);
1503e12c5d1SDavid du Colombier if (f == 0) {
1513e12c5d1SDavid du Colombier fprint(2, "can't rdsubfontfile %s: %r\n", file);
1523e12c5d1SDavid du Colombier exits("rdsubfont");
1533e12c5d1SDavid du Colombier }
1543e12c5d1SDavid du Colombier close(fd);
1553e12c5d1SDavid du Colombier ff = mkfont(f, 0);
1563e12c5d1SDavid du Colombier if(ff == 0){
1573e12c5d1SDavid du Colombier fprint(2, "can't mkfont %s: %r\n", file);
1583e12c5d1SDavid du Colombier exits("rdsubfont");
1593e12c5d1SDavid du Colombier }
1603e12c5d1SDavid du Colombier fonttab[n][s] = ff;
1613e12c5d1SDavid du Colombier dprint(2, "using %s for font %d %d\n", file, n, s);
1623e12c5d1SDavid du Colombier return;
1633e12c5d1SDavid du Colombier }
1643e12c5d1SDavid du Colombier }
1653e12c5d1SDavid du Colombier }
166219b2ee8SDavid du Colombier }
1673e12c5d1SDavid du Colombier fprint(2, "can't find font %s.%d or substitute, quitting\n", fname[n], s);
1683e12c5d1SDavid du Colombier exits("no font");
1693e12c5d1SDavid du Colombier }
1703e12c5d1SDavid du Colombier
1713e12c5d1SDavid du Colombier void
loadfontname(int n,char * s)1723e12c5d1SDavid du Colombier loadfontname(int n, char *s)
1733e12c5d1SDavid du Colombier {
1743e12c5d1SDavid du Colombier int i;
1753e12c5d1SDavid du Colombier Font *f, *g = 0;
1763e12c5d1SDavid du Colombier
1773e12c5d1SDavid du Colombier if (strcmp(s, fname[n]) == 0)
1783e12c5d1SDavid du Colombier return;
1797dd7cddfSDavid du Colombier if(fname[n] && fname[n][0]){
1807dd7cddfSDavid du Colombier if(lastload[n] && strcmp(lastload[n], fname[n]) == 0)
1817dd7cddfSDavid du Colombier return;
1827dd7cddfSDavid du Colombier strcpy(lastload[n], fname[n]);
1837dd7cddfSDavid du Colombier }
1843e12c5d1SDavid du Colombier fontlookup(n, s);
1853e12c5d1SDavid du Colombier for (i = 0; i < NSIZE; i++)
1863e12c5d1SDavid du Colombier if (f = fonttab[n][i]){
1873e12c5d1SDavid du Colombier if (f != g) {
1887dd7cddfSDavid du Colombier freefont(f);
1893e12c5d1SDavid du Colombier g = f;
1903e12c5d1SDavid du Colombier }
1913e12c5d1SDavid du Colombier fonttab[n][i] = 0;
1923e12c5d1SDavid du Colombier }
1933e12c5d1SDavid du Colombier }
1943e12c5d1SDavid du Colombier
1953e12c5d1SDavid du Colombier void
allfree(void)1963e12c5d1SDavid du Colombier allfree(void)
1973e12c5d1SDavid du Colombier {
1983e12c5d1SDavid du Colombier int i;
1993e12c5d1SDavid du Colombier
2003e12c5d1SDavid du Colombier for (i=0; i<NFONT; i++)
2013e12c5d1SDavid du Colombier loadfontname(i, "??");
2023e12c5d1SDavid du Colombier }
2033e12c5d1SDavid du Colombier
2043e12c5d1SDavid du Colombier
2053e12c5d1SDavid du Colombier void
readmapfile(char * file)2063e12c5d1SDavid du Colombier readmapfile(char *file)
2073e12c5d1SDavid du Colombier {
2083e12c5d1SDavid du Colombier Biobuf *fp;
2093e12c5d1SDavid du Colombier char *p, cmd[100];
2103e12c5d1SDavid du Colombier
2113e12c5d1SDavid du Colombier if ((fp=Bopen(file, OREAD)) == 0){
2123e12c5d1SDavid du Colombier fprint(2, "proof: can't open map file %s\n", file);
2133e12c5d1SDavid du Colombier exits("urk");
2143e12c5d1SDavid du Colombier }
2153e12c5d1SDavid du Colombier while((p=Brdline(fp, '\n')) != 0) {
2163e12c5d1SDavid du Colombier p[Blinelen(fp)-1] = 0;
2173e12c5d1SDavid du Colombier scanstr(p, cmd, 0);
2183e12c5d1SDavid du Colombier if(p[0]=='\0' || eq(cmd, "#")) /* skip comments, empty */
2193e12c5d1SDavid du Colombier continue;
220219b2ee8SDavid du Colombier else if(eq(cmd, "xheight"))
221219b2ee8SDavid du Colombier buildxheight(fp);
2223e12c5d1SDavid du Colombier else if(eq(cmd, "map"))
2233e12c5d1SDavid du Colombier buildmap(fp);
2243e12c5d1SDavid du Colombier else if(eq(cmd, "special"))
2253e12c5d1SDavid du Colombier buildtroff(p);
2263e12c5d1SDavid du Colombier else if(eq(cmd, "troff"))
2273e12c5d1SDavid du Colombier buildtroff(p);
2283e12c5d1SDavid du Colombier else
2293e12c5d1SDavid du Colombier fprint(2, "weird map line %s\n", p);
2303e12c5d1SDavid du Colombier }
231219b2ee8SDavid du Colombier Bterm(fp);
232219b2ee8SDavid du Colombier }
233219b2ee8SDavid du Colombier
234219b2ee8SDavid du Colombier static void
buildxheight(Biobuf * fp)235219b2ee8SDavid du Colombier buildxheight(Biobuf *fp) /* map goes from char name to value to print via *string() */
236219b2ee8SDavid du Colombier {
237219b2ee8SDavid du Colombier char *line;
238219b2ee8SDavid du Colombier
239219b2ee8SDavid du Colombier line = Brdline(fp, '\n');
240219b2ee8SDavid du Colombier if(line == 0){
241219b2ee8SDavid du Colombier fprint(2, "proof: bad map file\n");
242219b2ee8SDavid du Colombier exits("map");
243219b2ee8SDavid du Colombier }
244219b2ee8SDavid du Colombier charmap[curmap].xheight = atof(line);
2453e12c5d1SDavid du Colombier }
2463e12c5d1SDavid du Colombier
2473e12c5d1SDavid du Colombier static void
buildmap(Biobuf * fp)2483e12c5d1SDavid du Colombier buildmap(Biobuf *fp) /* map goes from char name to value to print via *string() */
2493e12c5d1SDavid du Colombier {
2503e12c5d1SDavid du Colombier uchar *p, *line, ch[100];
2513e12c5d1SDavid du Colombier int val;
252219b2ee8SDavid du Colombier Rune r;
2533e12c5d1SDavid du Colombier
2543e12c5d1SDavid du Colombier curmap++;
255219b2ee8SDavid du Colombier if(curmap >= NMAP){
256219b2ee8SDavid du Colombier fprint(2, "proof: out of char maps; recompile\n");
257219b2ee8SDavid du Colombier exits("charmap");
258219b2ee8SDavid du Colombier }
2593e12c5d1SDavid du Colombier while ((line = Brdline(fp, '\n'))!= 0){
2603e12c5d1SDavid du Colombier if (line[0] == '\n')
2613e12c5d1SDavid du Colombier return;
2623e12c5d1SDavid du Colombier line[Blinelen(fp)-1] = 0;
2633e12c5d1SDavid du Colombier scanstr((char *) line, (char *) ch, (char **) &p);
2643e12c5d1SDavid du Colombier if (ch[0] == '\0') {
2657dd7cddfSDavid du Colombier fprint(2, "bad map file line '%s'\n", (char*)line);
2663e12c5d1SDavid du Colombier continue;
2673e12c5d1SDavid du Colombier }
2683e12c5d1SDavid du Colombier val = strtol((char *) p, 0, 10);
2697dd7cddfSDavid du Colombier dprint(2, "buildmap %s (%x %x) %s %d\n", (char*)ch, ch[0], ch[1], (char*)p, val);
270219b2ee8SDavid du Colombier chartorune(&r, (char*)ch);
271219b2ee8SDavid du Colombier if(utflen((char*)ch)==1 && r<QUICK)
272219b2ee8SDavid du Colombier charmap[curmap].quick[r] = val;
273219b2ee8SDavid du Colombier else
2743e12c5d1SDavid du Colombier addmap(curmap, strdup((char *) ch), val); /* put somewhere else */
2753e12c5d1SDavid du Colombier }
2763e12c5d1SDavid du Colombier }
2773e12c5d1SDavid du Colombier
2783e12c5d1SDavid du Colombier static void
addmap(int n,char * s,int val)2793e12c5d1SDavid du Colombier addmap(int n, char *s, int val) /* stick a new link on */
2803e12c5d1SDavid du Colombier {
2813e12c5d1SDavid du Colombier Link *p = (Link *) malloc(sizeof(Link));
282219b2ee8SDavid du Colombier Link *prev = charmap[n].slow;
2833e12c5d1SDavid du Colombier
2843e12c5d1SDavid du Colombier if(p == 0)
2853e12c5d1SDavid du Colombier exits("out of memory in addmap");
2863e12c5d1SDavid du Colombier p->name = (uchar *) s;
2873e12c5d1SDavid du Colombier p->val = val;
288219b2ee8SDavid du Colombier p->next = prev;
289219b2ee8SDavid du Colombier charmap[n].slow = p;
2903e12c5d1SDavid du Colombier }
2913e12c5d1SDavid du Colombier
2923e12c5d1SDavid du Colombier static void
buildtroff(char * buf)2933e12c5d1SDavid du Colombier buildtroff(char *buf) /* map troff names into bitmap filenames */
2943e12c5d1SDavid du Colombier { /* e.g., R -> times/R., I -> times/I., etc. */
295219b2ee8SDavid du Colombier char *p, cmd[100], name[200], prefix[400], fallback[100];
2963e12c5d1SDavid du Colombier
2973e12c5d1SDavid du Colombier scanstr(buf, cmd, &p);
2983e12c5d1SDavid du Colombier scanstr(p, name, &p);
2993e12c5d1SDavid du Colombier scanstr(p, prefix, &p);
300219b2ee8SDavid du Colombier while(*p!=0 && isspace(*p))
301219b2ee8SDavid du Colombier p++;
302219b2ee8SDavid du Colombier if(*p != 0){
303219b2ee8SDavid du Colombier scanstr(p, fallback, &p);
304219b2ee8SDavid du Colombier fontmap[nfontmap].fallback = strdup(fallback);
305219b2ee8SDavid du Colombier }else
306219b2ee8SDavid du Colombier fontmap[nfontmap].fallback = 0;
3073e12c5d1SDavid du Colombier fontmap[nfontmap].troffname = strdup(name);
3083e12c5d1SDavid du Colombier fontmap[nfontmap].prefix = strdup(prefix);
3093e12c5d1SDavid du Colombier fontmap[nfontmap].map = curmap;
310bfe6f914SDavid du Colombier dprint(2, "troff name %s is bitmap %s map %d in slot %d fallback %s\n",
311bfe6f914SDavid du Colombier name, prefix, curmap, nfontmap, fontmap[nfontmap].fallback?
312bfe6f914SDavid du Colombier fontmap[nfontmap].fallback: "<null>");
3133e12c5d1SDavid du Colombier nfontmap++;
3143e12c5d1SDavid du Colombier }
3153e12c5d1SDavid du Colombier
3163e12c5d1SDavid du Colombier static void
fontlookup(int n,char * s)3173e12c5d1SDavid du Colombier fontlookup(int n, char *s) /* map troff name of s into position n */
3183e12c5d1SDavid du Colombier {
3193e12c5d1SDavid du Colombier int i;
3203e12c5d1SDavid du Colombier
3213e12c5d1SDavid du Colombier for(i = 0; i < nfontmap; i++)
3223e12c5d1SDavid du Colombier if (eq(s, fontmap[i].troffname)) {
3233e12c5d1SDavid du Colombier strcpy(fname[n], fontmap[i].prefix);
3243e12c5d1SDavid du Colombier fmap[n] = fontmap[i].map;
325219b2ee8SDavid du Colombier pos2fontmap[n] = i;
3263e12c5d1SDavid du Colombier if (eq(s, "S"))
3273e12c5d1SDavid du Colombier specfont = n;
3283e12c5d1SDavid du Colombier dprint(2, "font %d %s is %s\n", n, s, fname[n]);
3293e12c5d1SDavid du Colombier return;
3303e12c5d1SDavid du Colombier }
3313e12c5d1SDavid du Colombier /* god help us if this font isn't there */
3323e12c5d1SDavid du Colombier }
3333e12c5d1SDavid du Colombier
3343e12c5d1SDavid du Colombier
335219b2ee8SDavid du Colombier static char *
map(Rune rp[],int font)336219b2ee8SDavid du Colombier map(Rune rp[], int font) /* figure out mapping for char in this font */
3373e12c5d1SDavid du Colombier {
338219b2ee8SDavid du Colombier static char s[100];
339bfe6f914SDavid du Colombier unsigned m;
340bfe6f914SDavid du Colombier char c[32];
3413e12c5d1SDavid du Colombier Link *p;
342219b2ee8SDavid du Colombier Rune r;
3433e12c5d1SDavid du Colombier
344bfe6f914SDavid du Colombier if((unsigned)font >= NFONT) {
345bfe6f914SDavid du Colombier dprint(2, "map: font %ud >= NFONT (%d)\n", font, NFONT);
346bfe6f914SDavid du Colombier return 0;
347bfe6f914SDavid du Colombier }
348bfe6f914SDavid du Colombier m = fmap[font];
349bfe6f914SDavid du Colombier if(m >= nelem(charmap)) {
350bfe6f914SDavid du Colombier dprint(2, "map: fmap[font] %ud >= nelem(charmap) (%d)\n",
351bfe6f914SDavid du Colombier m, nelem(charmap));
352bfe6f914SDavid du Colombier return 0;
353bfe6f914SDavid du Colombier }
354219b2ee8SDavid du Colombier if(rp[1] == 0 && rp[0] < QUICK) /* fast lookup */
355bfe6f914SDavid du Colombier r = charmap[m].quick[rp[0]];
356219b2ee8SDavid du Colombier else { /* high-valued or compound character name */
357bfe6f914SDavid du Colombier snprint(c, sizeof c, "%S", rp);
358219b2ee8SDavid du Colombier r = 0;
359bfe6f914SDavid du Colombier for (p = charmap[m].slow; p; p = p->next)
360219b2ee8SDavid du Colombier if(eq(c, p->name)){
361219b2ee8SDavid du Colombier r = p->val;
362219b2ee8SDavid du Colombier break;
363219b2ee8SDavid du Colombier }
364219b2ee8SDavid du Colombier }
365219b2ee8SDavid du Colombier if(r == 0){ /* not there */
366219b2ee8SDavid du Colombier dprint(2, "didn't find %S font# %d\n", rp, font);
3673e12c5d1SDavid du Colombier return 0;
3683e12c5d1SDavid du Colombier }
369219b2ee8SDavid du Colombier dprint(2, "map %S to %s font# %d\n", rp, s, font);
370219b2ee8SDavid du Colombier s[runetochar(s, &r)] = 0;
3713e12c5d1SDavid du Colombier return s;
3723e12c5d1SDavid du Colombier }
3733e12c5d1SDavid du Colombier
3743e12c5d1SDavid du Colombier static void
scanstr(char * s,char * ans,char ** ep)3753e12c5d1SDavid du Colombier scanstr(char *s, char *ans, char **ep)
3763e12c5d1SDavid du Colombier {
3773e12c5d1SDavid du Colombier for (; isspace((uchar) *s); s++)
3783e12c5d1SDavid du Colombier ;
379219b2ee8SDavid du Colombier for (; *s!=0 && !isspace((uchar) *s); )
3803e12c5d1SDavid du Colombier *ans++ = *s++;
3813e12c5d1SDavid du Colombier *ans = 0;
3823e12c5d1SDavid du Colombier if (ep)
3833e12c5d1SDavid du Colombier *ep = s;
3843e12c5d1SDavid du Colombier }
385