The main function.
64{
65
66 int i;
67
69 int loc;
70 char *gstart;
71
72 char glyph_width[0x20000];
74
75 FILE *infilefp;
76
77 if (argc != 3) {
78 fprintf (stderr, "\n\nUsage: %s <unifont.hex> <combining.txt>\n\n", argv[0]);
79 exit (EXIT_FAILURE);
80 }
81
82
83
84
85 if ((infilefp = fopen (argv[1],"r")) == NULL) {
86 fprintf (stderr,"ERROR - hex input file %s not found.\n\n", argv[1]);
87 exit (EXIT_FAILURE);
88 }
89
90
91 memset (glyph_width, -1, 0x20000 * sizeof (char));
92 memset (pikto_width, -1, (
PIKTO_SIZE) *
sizeof (
char));
93
95 while (fgets (teststring,
MAXSTRING-1, infilefp) != NULL) {
96 sscanf (teststring, "%X:%*s", &loc);
97 if (loc < 0x20000) {
98 gstart = strchr (teststring,':') + 1;
99
100
101
102
103 glyph_width[loc] = (strlen (gstart) - 1) >> 5;
104 }
106 gstart = strchr (teststring,':') + 1;
107 pikto_width[loc -
PIKTO_START] = strlen (gstart) <= 34 ? 1 : 2;
108 }
109 }
110
111 fclose (infilefp);
112
113
114
115
116 if ((infilefp = fopen (argv[2],"r")) == NULL) {
117 fprintf (stderr,"ERROR - combining characters file %s not found.\n\n", argv[2]);
118 exit (EXIT_FAILURE);
119 }
120
121 while (fgets (teststring,
MAXSTRING-1, infilefp) != NULL) {
122 sscanf (teststring, "%X:%*s", &loc);
123 if (loc < 0x20000) glyph_width[loc] = 0;
124 }
125
126 fclose (infilefp);
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212 for (i = 0xFDD0; i <= 0xFDEF; i++) glyph_width[i] = -1;
213 glyph_width[0xFFFE] = -1;
214 glyph_width[0xFFFF] = -1;
215
216
217 for (i = 0xD800; i <= 0xDFFF; i++) glyph_width[i]=-1;
218
219
220 for (i = 0x4E00; i <= 0x9FFF; i++) if (glyph_width[i] < 0) glyph_width[i] = 2;
221 for (i = 0x3400; i <= 0x4DBF; i++) if (glyph_width[i] < 0) glyph_width[i] = 2;
222 for (i = 0xF900; i <= 0xFAFF; i++) if (glyph_width[i] < 0) glyph_width[i] = 2;
223
224
225
226
227 printf ("/*\n");
228 printf (" wcwidth and wcswidth functions, as per IEEE 1003.1-2008\n");
229 printf (" System Interfaces, pp. 2241 and 2251.\n\n");
230 printf (" Author: Paul Hardy, 2013\n\n");
231 printf (" Copyright (c) 2013 Paul Hardy\n\n");
232 printf (" LICENSE:\n");
233 printf ("\n");
234 printf (" This program is free software: you can redistribute it and/or modify\n");
235 printf (" it under the terms of the GNU General Public License as published by\n");
236 printf (" the Free Software Foundation, either version 2 of the License, or\n");
237 printf (" (at your option) any later version.\n");
238 printf ("\n");
239 printf (" This program is distributed in the hope that it will be useful,\n");
240 printf (" but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
241 printf (" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");
242 printf (" GNU General Public License for more details.\n");
243 printf ("\n");
244 printf (" You should have received a copy of the GNU General Public License\n");
245 printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n");
246 printf ("*/\n\n");
247
248 printf ("#include <wchar.h>\n\n");
249 printf ("/* Definitions for Pikto CSUR Private Use Area glyphs */\n");
250 printf (
"#define PIKTO_START\t0x%06X\n",
PIKTO_START);
251 printf (
"#define PIKTO_END\t0x%06X\n",
PIKTO_END);
252 printf ("#define PIKTO_SIZE\t(PIKTO_END - PIKTO_START + 1)\n");
253 printf ("\n\n");
254 printf ("/* wcwidth -- return charcell positions of one code point */\n");
255 printf ("inline int\nwcwidth (wchar_t wc)\n{\n");
256 printf (" return (wcswidth (&wc, 1));\n");
257 printf ("}\n");
258 printf ("\n\n");
259 printf ("int\nwcswidth (const wchar_t *pwcs, size_t n)\n{\n\n");
260 printf (" int i; /* loop variable */\n");
261 printf (" unsigned codept; /* Unicode code point of current character */\n");
262 printf (" unsigned plane; /* Unicode plane, 0x00..0x10 */\n");
263 printf (" unsigned lower17; /* lower 17 bits of Unicode code point */\n");
264 printf (" unsigned lower16; /* lower 16 bits of Unicode code point */\n");
265 printf (" int lowpt, midpt, highpt; /* for binary searching in plane1zeroes[] */\n");
266 printf (" int found; /* for binary searching in plane1zeroes[] */\n");
267 printf (" int totalwidth; /* total width of string, in charcells (1 or 2/glyph) */\n");
268 printf (" int illegalchar; /* Whether or not this code point is illegal */\n");
269 putchar ('\n');
270
271
272
273
274
275 printf (" char glyph_width[0x20000] = {");
276 for (i = 0; i < 0x10000; i++) {
277 if ((i & 0x1F) == 0)
278 printf ("\n /* U+%04X */ ", i);
279 printf ("%d,", glyph_width[i]);
280 }
281 for (i = 0x10000; i < 0x20000; i++) {
282 if ((i & 0x1F) == 0)
283 printf ("\n /* U+%06X */ ", i);
284 printf ("%d", glyph_width[i]);
285 if (i < 0x1FFFF) putchar (',');
286 }
287 printf ("\n };\n\n");
288
289
290
291
292 printf (" char pikto_width[PIKTO_SIZE] = {");
294 if ((i & 0x1F) == 0)
296 printf ("%d", pikto_width[i]);
298 }
299 printf ("\n };\n\n");
300
301
302
303
304 printf ("\n");
305 printf (" illegalchar = totalwidth = 0;\n");
306 printf (" for (i = 0; !illegalchar && i < n; i++) {\n");
307 printf (" codept = pwcs[i];\n");
308 printf (" plane = codept >> 16;\n");
309 printf (" lower17 = codept & 0x1FFFF;\n");
310 printf (" lower16 = codept & 0xFFFF;\n");
311 printf (" if (plane < 2) { /* the most common case */\n");
312 printf (" if (glyph_width[lower17] < 0) illegalchar = 1;\n");
313 printf (" else totalwidth += glyph_width[lower17];\n");
314 printf (" }\n");
315 printf (" else { /* a higher plane or beyond Unicode range */\n");
316 printf (" if ((lower16 == 0xFFFE) || (lower16 == 0xFFFF)) {\n");
317 printf (" illegalchar = 1;\n");
318 printf (" }\n");
319 printf (" else if (plane < 4) { /* Ideographic Plane */\n");
320 printf (" totalwidth += 2; /* Default ideographic width */\n");
321 printf (" }\n");
322 printf (" else if (plane == 0x0F) { /* CSUR Private Use Area */\n");
323 printf (" if (lower16 <= 0x0E6F) { /* Kinya */\n");
324 printf (" totalwidth++; /* all Kinya syllables have width 1 */\n");
325 printf (" }\n");
326 printf (" else if (lower16 <= (PIKTO_END & 0xFFFF)) { /* Pikto */\n");
327 printf (" if (pikto_width[lower16 - (PIKTO_START & 0xFFFF)] < 0) illegalchar = 1;\n");
328 printf (" else totalwidth += pikto_width[lower16 - (PIKTO_START & 0xFFFF)];\n");
329 printf (" }\n");
330 printf (" }\n");
331 printf (" else if (plane > 0x10) {\n");
332 printf (" illegalchar = 1;\n");
333 printf (" }\n");
334 printf (" /* Other non-printing in higher planes; return -1 as per IEEE 1003.1-2008. */\n");
335 printf (" else if (/* language tags */\n");
336 printf (" codept == 0x0E0001 || (codept >= 0x0E0020 && codept <= 0x0E007F) ||\n");
337 printf (" /* variation selectors, 0x0E0100..0x0E01EF */\n");
338 printf (" (codept >= 0x0E0100 && codept <= 0x0E01EF)) {\n");
339 printf (" illegalchar = 1;\n");
340 printf (" }\n");
341 printf (" /*\n");
342 printf (" Unicode plane 0x02..0x10 printing character\n");
343 printf (" */\n");
344 printf (" else {\n");
345 printf (" illegalchar = 1; /* code is not in font */\n");
346 printf (" }\n");
347 printf ("\n");
348 printf (" }\n");
349 printf (" }\n");
350 printf (" if (illegalchar) totalwidth = -1;\n");
351 printf ("\n");
352 printf (" return (totalwidth);\n");
353 printf ("\n");
354 printf ("}\n");
355
356 exit (EXIT_SUCCESS);
357}
#define MAXSTRING
Maximum input line length - 1.
#define PIKTO_START
Start of Pikto code point range.
#define PIKTO_END
End of Pikto code point range.