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