t11.c - 9base - revived minimalist port of Plan 9 userland to Unix | |
git clone git://git.suckless.org/9base | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
t11.c (7140B) | |
--- | |
1 #include "tdef.h" | |
2 #include "fns.h" | |
3 #include "ext.h" | |
4 | |
5 #define MAXCH NCHARS /* maximum number of global c… | |
6 char *chnames[MAXCH]; /* chnames[n-ALPHABET] -> name of ch… | |
7 int nchnames; /* number of Cxy names currently see… | |
8 | |
9 #define MAXPS 100 /* max number of point si… | |
10 int pstab[MAXPS]; /* point sizes */ | |
11 int nsizes; /* number in DESC */ | |
12 | |
13 Font fonts[MAXFONTS+1]; /* font info + ptr to width info */ | |
14 | |
15 | |
16 #define skipline(f) while (getc(f) != '\n') | |
17 | |
18 #define eq(s1, s2) (strcmp(s1, s2) == 0) | |
19 | |
20 int | |
21 getdesc(char *name) | |
22 { | |
23 FILE *fin; | |
24 char cmd[100], s[100]; | |
25 int i, v; | |
26 | |
27 if ((fin = fopen(unsharp(name), "r")) == NULL) | |
28 return -1; | |
29 while (fscanf(fin, "%s", cmd) != EOF) { | |
30 if (strcmp(cmd, "res") == 0) { | |
31 fscanf(fin, "%d", &Inch); | |
32 } else if (strcmp(cmd, "hor") == 0) { | |
33 fscanf(fin, "%d", &Hor); | |
34 } else if (strcmp(cmd, "vert") == 0) { | |
35 fscanf(fin, "%d", &Vert); | |
36 } else if (strcmp(cmd, "unitwidth") == 0) { | |
37 fscanf(fin, "%d", &Unitwidth); | |
38 } else if (strcmp(cmd, "sizes") == 0) { | |
39 nsizes = 0; | |
40 while (fscanf(fin, "%d", &v) != EOF && v != 0 &&… | |
41 pstab[nsizes++] = v; | |
42 } else if (strcmp(cmd, "fonts") == 0) { | |
43 fscanf(fin, "%d", &nfonts); | |
44 for (i = 1; i <= nfonts; i++) { | |
45 fscanf(fin, "%s", s); | |
46 fontlab[i] = PAIR(s[0], s[1]); | |
47 } | |
48 } else if (strcmp(cmd, "charset") == 0) { /* add … | |
49 while (fscanf(fin, "%s", s) != EOF) | |
50 chadd(s, Troffchar, Install); | |
51 break; | |
52 } | |
53 /* else | |
54 just skip anything else */ | |
55 skipline(fin); | |
56 } | |
57 fclose(fin); | |
58 return 1; | |
59 } | |
60 | |
61 static int checkfont(char *name) | |
62 { /* in case it's not really a font description file */ | |
63 /* really paranoid, but consider \f. */ | |
64 FILE *fp; | |
65 char buf[300], buf2[300]; | |
66 int i, status = -1; | |
67 | |
68 if ((fp = fopen(unsharp(name), "r")) == NULL) | |
69 return -1; | |
70 for (i = 1; i <= 10; i++) { | |
71 if (fgets(buf, sizeof buf, fp) == NULL) | |
72 break; | |
73 sscanf(buf, "%s", buf2); | |
74 if (buf2[0] == '#') { | |
75 i--; | |
76 continue; | |
77 } | |
78 if (eq(buf2, "name") || eq(buf2, "fontname") || | |
79 eq(buf2, "special") || eq(buf2, "charset")) { | |
80 status = 1; | |
81 break; | |
82 } | |
83 } | |
84 fclose(fp); | |
85 return status; | |
86 | |
87 } | |
88 | |
89 int | |
90 getfont(char *name, int pos) /* create width tab for font */ | |
91 { | |
92 FILE *fin; | |
93 Font *ftemp = &fonts[pos]; | |
94 Chwid chtemp[MAXCH]; | |
95 static Chwid chinit; | |
96 int i, nw, n, wid, kern, code, type; | |
97 char buf[100], ch[100], s1[100], s2[100], s3[100], cmd[300]; | |
98 | |
99 nw = code = 0; | |
100 /* fprintf(stderr, "read font %s onto %d\n", name, pos); */ | |
101 if (checkfont(name) == -1) | |
102 return -1; | |
103 if ((fin = fopen(unsharp(name), "r")) == NULL) | |
104 return -1; | |
105 for (i = 0; i < ALPHABET; i++) | |
106 chtemp[i] = chinit; /* zero out to begin with */ | |
107 ftemp->specfont = ftemp->ligfont = 0; | |
108 ftemp->defaultwidth = ftemp->spacewidth = Inch * Unitwidth / 72 … | |
109 while (fscanf(fin, "%s", cmd) != EOF) { | |
110 if (strcmp(cmd, "name") == 0) | |
111 fscanf(fin, "%s", ftemp->longname); | |
112 else if (strcmp(cmd, "special") == 0) | |
113 ftemp->specfont = 1; | |
114 else if (strcmp(cmd, "ligatures") == 0) { | |
115 ftemp->ligfont = getlig(fin); | |
116 } else if (strcmp(cmd, "spacewidth") == 0) { | |
117 fscanf(fin, "%d", &ftemp->spacewidth); | |
118 } else if (strcmp(cmd, "defaultwidth") == 0) { | |
119 fscanf(fin, "%d", &ftemp->defaultwidth); | |
120 } else if (strcmp(cmd, "charset") == 0) { | |
121 wchar_t wc; | |
122 skipline(fin); | |
123 nw = ALPHABET; | |
124 while (fgets(buf, sizeof buf, fin) != NULL) { | |
125 sscanf(buf, "%s %s %s %s", ch, s1, s2, s… | |
126 if (s1[0] != '"') { /* genuine ne… | |
127 sscanf(s1, "%d", &wid); | |
128 sscanf(s2, "%d", &kern); | |
129 code = strtol(s3, 0, 0); … | |
130 } | |
131 /* otherwise it's a synonym for prev cha… | |
132 /* so leave previous values intact */ | |
133 | |
134 | |
135 /* decide what kind of alphabet it might… | |
136 | |
137 | |
138 if (strlen(ch) == 1) { /* it's as… | |
139 n = ch[0]; /* origin incl… | |
140 chtemp[n].num = ch[0]; | |
141 } else if (ch[0] == '\\' && ch[1] == '0'… | |
142 n = strtol(ch+1, 0, 0); /… | |
143 chtemp[n].num = n; | |
144 #ifdef UNICODE | |
145 } else if (mbtowc(&wc, ch, strlen(ch)) >… | |
146 chtemp[nw].num = chadd(ch, MBch… | |
147 n = nw; | |
148 nw++; | |
149 #endif /*UNICODE*/ | |
150 } else { | |
151 if (strcmp(ch, "---") == 0) { /*… | |
152 sprintf(ch, "%d", code); | |
153 type = Number; | |
154 } else | |
155 type = Troffchar; | |
156 chtemp[nw].num = chadd(ch, type,… | |
157 n = nw; | |
158 nw++; | |
159 } | |
160 chtemp[n].wid = wid; | |
161 chtemp[n].kern = kern; | |
162 chtemp[n].code = code; | |
163 /*fprintf(stderr, "font %2.2s char %4.4s… | |
164 ftemp->longname, ch, n, wid, cod… | |
165 */ | |
166 } | |
167 break; | |
168 } | |
169 skipline(fin); | |
170 } | |
171 fclose(fin); | |
172 chtemp[' '].wid = ftemp->spacewidth; /* width of space on… | |
173 ftemp->nchars = nw; | |
174 if (ftemp->wp) | |
175 free(ftemp->wp); /* god help us if this wasn't al… | |
176 ftemp->wp = (Chwid *) malloc(nw * sizeof(Chwid)); | |
177 if (ftemp->wp == NULL) | |
178 return -1; | |
179 for (i = 0; i < nw; i++) | |
180 ftemp->wp[i] = chtemp[i]; | |
181 /* | |
182 * printf("%d chars: ", nw); | |
183 * for (i = 0; i < nw; i++) | |
184 * if (ftemp->wp[i].num > 0 && ftemp->wp[i].num < ALPHABE… | |
185 * printf("%c %d ", ftemp->wp[i].num, ftemp->wp[i… | |
186 * else if (i >= ALPHABET) | |
187 * printf("%d (%s) %d ", ftemp->wp[i].num, | |
188 * chnames[ftemp->wp[i].num-ALPHABET], ft… | |
189 * } | |
190 * printf("\n"); | |
191 */ | |
192 return 1; | |
193 } | |
194 | |
195 int | |
196 chadd(char *s, int type, int install) /* add s to global characte… | |
197 { /* or just look it up */ | |
198 | |
199 /* a temporary kludge: store the "type" as the first character … | |
200 /* of the string, so we can remember from whence it came */ | |
201 | |
202 char *p; | |
203 int i; | |
204 | |
205 /* fprintf(stderr, "into chadd %s %c %c\n", s, type, install); /* */ | |
206 for (i = 0; i < nchnames; i++) | |
207 if (type == chnames[i][0] && eq(s, chnames[i]+1)) /* +1 … | |
208 break; | |
209 /* fprintf(stderr, "i %d, nchnames %d\n", i, nchnames); /* */ | |
210 if (i < nchnames) /* found same type and bytes at… | |
211 return ALPHABET + i; | |
212 else if (install == Lookup) /* not found, and we were jus… | |
213 return -1; | |
214 | |
215 chnames[nchnames] = p = (char *) malloc(strlen(s)+1+1); /… | |
216 if (p == NULL) { | |
217 ERROR "out of space adding character %s", s WARN; | |
218 return LEFTHAND; | |
219 } | |
220 if (nchnames >= NCHARS - ALPHABET) { | |
221 ERROR "out of table space adding character %s", s WARN; | |
222 return LEFTHAND; | |
223 } | |
224 strcpy(chnames[nchnames]+1, s); | |
225 chnames[nchnames][0] = type; | |
226 /* fprintf(stderr, "installed %c%s at %d\n", type, s, nchnames); /* */ | |
227 return nchnames++ + ALPHABET; | |
228 } | |
229 | |
230 char *chname(int n) /* return string for char with index n */ | |
231 { /* includes type char at front, to be peeled of… | |
232 if (n >= ALPHABET && n < nchnames + ALPHABET) | |
233 return chnames[n-ALPHABET]; | |
234 else | |
235 return ""; | |
236 } | |
237 | |
238 int | |
239 getlig(FILE *fin) /* pick up ligature list */ | |
240 { | |
241 int lig; | |
242 char temp[200]; | |
243 | |
244 lig = 0; | |
245 while (fscanf(fin, "%s", temp) != EOF && strcmp(temp, "0") != 0)… | |
246 if (strcmp(temp, "fi") == 0) | |
247 lig |= LFI; | |
248 else if (strcmp(temp, "fl") == 0) | |
249 lig |= LFL; | |
250 else if (strcmp(temp, "ff") == 0) | |
251 lig |= LFF; | |
252 else if (strcmp(temp, "ffi") == 0) | |
253 lig |= LFFI; | |
254 else if (strcmp(temp, "ffl") == 0) | |
255 lig |= LFFL; | |
256 else | |
257 fprintf(stderr, "illegal ligature %s ignored\n",… | |
258 } | |
259 return lig; | |
260 } |