1 /* Copyright (C) 2000-2012 by George Williams */
2 /*
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are met:
5
6 * Redistributions of source code must retain the above copyright notice, this
7 * list of conditions and the following disclaimer.
8
9 * Redistributions in binary form must reproduce the above copyright notice,
10 * this list of conditions and the following disclaimer in the documentation
11 * and/or other materials provided with the distribution.
12
13 * The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include <fontforge-config.h>
29
30 #include "utype.c"
31 #include "utype.h"
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36
37 #define ACUTE 0x1
38 #define GRAVE 0x2
39 #define DIAERESIS 0x4
40 #define CIRCUMFLEX 0x8
41 #define TILDE 0x10
42 #define RING 0x20
43 #define SLASH 0x40
44 #define BREVE 0x80
45 #define CARON 0x100
46 #define DOTABOVE 0x200
47 #define DOTBELOW 0x400
48 #define CEDILLA 0x800
49 #define OGONEK 0x1000
50 #define MACRON 0x2000
51 #define DBLGRAVE 0x4000
52 #define DBLACUTE 0x8000
53 #define INVBREVE 0x10000
54 #define DIAERESISBELOW 0x20000
55 #define CIRCUMFLEXBELOW 0x40000
56 #define TILDEBELOW 0x80000
57 #define RINGBELOW 0x100000
58 #define LINEBELOW 0x200000
59 #define HOOKABOVE 0x400000
60 #define HORN 0x800000
61
62 #define GREEK 0x8000000
63
64 #define ANY (0xfffffff)
65
66 struct names { char *name; int mask; } names[] = {
67 {"ACUTE", 0x1},
68 {"GRAVE", 0x2},
69 {"DIAERESIS", 0x4},
70 {"CIRCUMFLEX", 0x8},
71 {"TILDE", 0x10},
72 {"RING", 0x20},
73 {"SLASH", 0x40},
74 {"BREVE", 0x80},
75 {"CARON", 0x100},
76 {"DOTABOVE", 0x200},
77 {"DOTBELOW", 0x400},
78 {"CEDILLA", 0x800},
79 {"OGONEK", 0x1000},
80 {"MACRON", 0x2000},
81 {"DBLGRAVE", 0x4000},
82 {"DBLACUTE", 0x8000},
83 {"INVBREVE", 0x10000},
84 {"DIAERESISBELOW", 0x20000},
85 {"CIRCUMFLEXBELOW", 0x40000},
86 {"TILDEBELOW", 0x80000},
87 {"RINGBELOW", 0x100000},
88 {"LINEBELOW", 0x200000},
89 {"HOOKABOVE", 0x400000},
90 {"HORN", 0x800000},
91 {"GREEK", 0x8000000},
92 {NULL}};
93
94 struct names names2[] = {
95 {"ACUTE", 0x1},
96 {"GRAVE", 0x2},
97 {"DIAERESIS BELOW", 0x20000},
98 {"DIAERESIS", 0x4},
99 {"CIRCUMFLEX BELOW", 0x40000},
100 {"CIRCUMFLEX", 0x8},
101 {"TILDE BELOW", 0x80000},
102 {"TILDE", 0x10},
103 {"RING ABOVE", 0x20},
104 {"RING BELOW", 0x100000},
105 {"STROKE", 0x40},
106 {"SLASH", 0x40},
107 {"BREVE", 0x80},
108 {"CARON", 0x100},
109 {"DOT ABOVE", 0x200},
110 {"MIDDLE DOT", 0x200},
111 {"DOT BELOW", 0x400},
112 {"CEDILLA", 0x800},
113 {"OGONEK", 0x1000},
114 {"MACRON", 0x2000},
115 {"DOUBLE GRAVE", 0x4000},
116 {"DOUBLE ACUTE", 0x8000},
117 {"INVERTED BREVE", 0x10000},
118 {"LINE BELOW", 0x200000},
119 {"HOOK ABOVE", 0x400000},
120 {"HORN", 0x800000},
121 {NULL}};
122
123 char *charnames[] = {
124 /* 0x0020 */ "space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quotesingle",
125 /* 0x0028 */ "parenleft","parenright","asterisk","plus","comma","hyphenminus","period","slash",
126 /* 0x0030 */ "zero","one","two","three","four","five","six","seven",
127 /* 0x0038 */ "eight","nine","colon","semicolon","less","equal","greater","question",
128 /* 0x0040 */ "at","A","B","C","D","E","F","G",
129 /* 0x0048 */ "H","I","J","K","L","M","N","O",
130 /* 0x0050 */ "P","Q","R","S","T","U","V","W",
131 /* 0x0058 */ "X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore",
132 /* 0x0060 */ "grave","a","b","c","d","e","f","g",
133 /* 0x0068 */ "h","i","j","k","l","m","n","o",
134 /* 0x0070 */ "p","q","r","s","t","u","v","w",
135 /* 0x0078 */ "x","y","z","braceleft","bar","braceright","asciitilde"
136 };
137
138 struct { char ch; unsigned int oldstate, newstate; unsigned short result; }
139 predefined[] = {
140 { '\'', ANY, ACUTE },
141 { 'e', 0, ACUTE },
142 { '`', ANY, GRAVE },
143 { ':', ANY, DIAERESIS },
144 { 'u', 0, DIAERESIS },
145 { '^', ANY, CIRCUMFLEX },
146 { 'i', 0, CIRCUMFLEX },
147 { '~', ANY, TILDE },
148 { 'n', 0, TILDE },
149 { '0', ANY, RING },
150 { '/', ANY, SLASH },
151 { '7', ANY, BREVE },
152 { '6', ANY, CARON },
153 { '.', ANY, DOTABOVE },
154 { ',', ANY, DOTBELOW },
155 { '5', ANY, CEDILLA },
156 { '4', ANY, OGONEK },
157 { '_', ANY, MACRON },
158 { '"', ANY, DBLGRAVE },
159 { '@', ANY, GREEK },
160
161 { ' ', 0, 0, 0x00a0 }, /* no break space */
162 { ' ', GREEK, 0, 0x2001 }, /* em space */
163 { '!', 0, 0, 0x00a1 }, /* inverted exclaim */
164 { '#', 0, 0, 0x00a3 }, /* sterling */
165 { '#', GREEK, 0, 0x00a5 }, /* Yen */
166 { '$', 0, 0, 0x20ac }, /* Euro */
167 { '$', GREEK, 0, 0x00a2 }, /* cent */
168 { '\\',0, 0, 0x00ab }, /* guillemotleft */
169 { '\\',GREEK, 0, 0x2039 }, /* single guillemotleft */
170 { '|', 0, 0, 0x00bb }, /* guillemotright */
171 { '|', GREEK, 0, 0x203a }, /* single guillemotright */
172 { '*', 0, 0, 0x00b0 }, /* degree */
173 { '*', GREEK, 0, 0x2022 }, /* bullet */
174 { '.', GREEK, 0, 0x00b7 }, /* centered dot */
175 { '-', 0, 0, 0x00ad }, /* soft hyphen */
176 { '-', GREEK, 0, 0x2013 }, /* en dash */
177 { '_', GREEK, 0, 0x2014 }, /* em dash */
178 { '=', GREEK, 0, 0x2015 }, /* quote dash */
179 { '+', 0, 0, 0x00b1 }, /* plus minus */
180 { ';', 0, 0, 0x2026 }, /* ellipsis */
181 { '[', 0, 0, 0x2018 }, /* open quote */
182 { ']', 0, 0, 0x2019 }, /* close quote */
183 { '{', 0, 0, 0x201c }, /* open double quote */
184 { '}', 0, 0, 0x201c }, /* close double quote */
185 { '>', 0, 0, 0x2264 }, /* greater than or equal */
186 { '>', GREEK, 0, 0x2023 }, /* triangle bullet */
187 { '<', 0, 0, 0x2265 }, /* less than or equal */
188 { '?', 0, 0, 0x00bf }, /* inverted quest */
189 { 'f', 0, 0, 0x2640 }, /* female */
190 { 'g', 0, 0, 0x00a9 }, /* copyright */
191 { 'h', GREEK|SLASH, 0, 0x210f },/* hbar */
192 { 'h', 0, 0, 0x261e }, /* right hand */
193 { 'H', 0, 0, 0x261e }, /* left hand */
194 { 'm', 0, 0, 0x2642 }, /* male */
195 { 'p', 0, 0, 0x00b6 }, /* paragraph */
196 { 'P', 0, 0, 0x00a7 }, /* section */
197 { 'r', 0, 0, 0x00ae }, /* registered */
198 { 't', 0, 0, 0x2122 }, /* TM */
199 { '2', BREVE, 0, 0x00bd }, /* 1/2 */
200
201 /* { 'A', 0, 0, 0x00c5 },*/ /* A ring */
202 /* { 'a', 0, 0, 0x00e5 },*/ /* a ring */
203 { 'C', 0, 0, 0x00c7 }, /* C cedilla */
204 { 'c', 0, 0, 0x00e7 }, /* c cedilla */
205 { 'A', 0, 0, 0x00c6 }, /* AE */
206 { 'a', 0, 0, 0x00e6 }, /* ae */
207 { 'O', 0, 0, 0x0152 }, /* OE */
208 { 'o', 0, 0, 0x1536 }, /* oe */
209 { 's', 0, 0, 0x00df }, /* es-zet */
210 { 'z', 0, 0, 0x017f }, /* long-s */
211
212 { 'i', DOTABOVE, 0, 0x131 }, /* dotless i */
213
214 /* the mapping from ascii->greek follows the symbol font */
215 { 'A', GREEK, 0, 0x391 }, /* Alpha */
216 { 'B', GREEK, 0, 0x392 }, /* Beta */
217 { 'C', GREEK, 0, 0x3A7 }, /* Chi */
218 { 'D', GREEK, 0, 0x394 }, /* Delta */
219 { 'E', GREEK, 0, 0x395 }, /* Epsilon */
220 { 'F', GREEK, 0, 0x3A6 }, /* Phi */
221 { 'G', GREEK, 0, 0x393 }, /* Gamma */
222 { 'H', GREEK, 0, 0x397 }, /* Eta */
223 { 'I', GREEK, 0, 0x399 }, /* Iota */
224 { 'J', GREEK, 0, 0x3d1 }, /* Theta Symbol */
225 { 'K', GREEK, 0, 0x39A }, /* Kappa */
226 { 'L', GREEK, 0, 0x39B }, /* Lamda */
227 { 'M', GREEK, 0, 0x39C }, /* Mu */
228 { 'N', GREEK, 0, 0x39D }, /* Nu */
229 { 'O', GREEK, 0, 0x39F }, /* Omicron */
230 { 'P', GREEK, 0, 0x3A0 }, /* Pi */
231 { 'Q', GREEK, 0, 0x398 }, /* Theta */
232 { 'R', GREEK, 0, 0x3A1 }, /* Rho */
233 { 'S', GREEK, 0, 0x3A3 }, /* Sigma */
234 { 'T', GREEK, 0, 0x3A4 }, /* Tau */
235 { 'U', GREEK, 0, 0x3A5 }, /* Upsilon */
236 { 'V', GREEK, 0, 0x3c2 }, /* lowercase final sigma */
237 { 'W', GREEK, 0, 0x3A9 }, /* Omega */
238 { 'X', GREEK, 0, 0x39E }, /* Xi */
239 { 'Y', GREEK, 0, 0x3A8 }, /* Psi */
240 { 'Z', GREEK, 0, 0x396 }, /* Zeta */
241 { 'a', GREEK, 0, 0x3b1 }, /* alpha */
242 { 'b', GREEK, 0, 0x3b2 }, /* beta */
243 { 'c', GREEK, 0, 0x3c7 }, /* chi */
244 { 'd', GREEK, 0, 0x3b4 }, /* delta */
245 { 'e', GREEK, 0, 0x3b5 }, /* epsilon */
246 { 'f', GREEK, 0, 0x3c6 }, /* phi */
247 { 'g', GREEK, 0, 0x3b3 }, /* gamma */
248 { 'h', GREEK, 0, 0x3b7 }, /* eta */
249 { 'i', GREEK, 0, 0x3b9 }, /* iota */
250 { 'j', GREEK, 0, 0x3d5 }, /* phi Symbol */
251 { 'k', GREEK, 0, 0x3bA }, /* kappa */
252 { 'l', GREEK, 0, 0x3bB }, /* lamda */
253 { 'm', GREEK, 0, 0x3bC }, /* mu */
254 { 'n', GREEK, 0, 0x3bD }, /* nu */
255 { 'o', GREEK, 0, 0x3bF }, /* omicron */
256 { 'p', GREEK, 0, 0x3c0 }, /* pi */
257 { 'q', GREEK, 0, 0x3b8 }, /* theta */
258 { 'r', GREEK, 0, 0x3c1 }, /* rho */
259 { 's', GREEK, 0, 0x3c3 }, /* sigma */
260 { 't', GREEK, 0, 0x3c4 }, /* tau */
261 { 'u', GREEK, 0, 0x3c5 }, /* upsilon */
262 { 'v', GREEK, 0, 0x3D6 }, /* pi Symbol */
263 { 'w', GREEK, 0, 0x3c9 }, /* omega */
264 { 'x', GREEK, 0, 0x3bE }, /* xi */
265 { 'y', GREEK, 0, 0x3c8 }, /* psi */
266 { 'z', GREEK, 0, 0x3b6 }, /* zeta */
267 { 'A', GREEK|DBLGRAVE, 0, 0x386 }, /* Alpha tonos */
268 { 'A', GREEK|BREVE, 0, 0x1fb8 }, /* Alpha vrachy */
269 { 'A', GREEK|MACRON, 0, 0x1fb9 }, /* Alpha macron */
270 { 'a', GREEK|DBLGRAVE, 0, 0x3ac }, /* alpha tonos */
271 { 'a', GREEK|GRAVE, 0, 0x1f70 }, /* alpha varia */
272 { 'a', GREEK|ACUTE, 0, 0x1f71 }, /* alpha oxia */
273 { 'a', GREEK|BREVE, 0, 0x1fb0 }, /* alpha vrachy */
274 { 'a', GREEK|MACRON, 0, 0x1fb1 }, /* alpha macron */
275 { 'a', GREEK|TILDE, 0, 0x1fb6 }, /* alpha perispomeni */
276 { 'E', GREEK|DBLGRAVE, 0, 0x388 }, /* Epsilon tonos */
277 { 'E', GREEK|GRAVE, 0, 0x1fc8 }, /* Epsilon varia */
278 { 'E', GREEK|ACUTE, 0, 0x1fc9 }, /* Epsilon oxia */
279 { 'e', GREEK|DBLGRAVE, 0, 0x3ad }, /* epsilon tonos */
280 { 'e', GREEK|GRAVE, 0, 0x1f72 }, /* epsilon varia */
281 { 'e', GREEK|ACUTE, 0, 0x1f73 }, /* epsilon oxia */
282 { 'H', GREEK|DBLGRAVE, 0, 0x389 }, /* Eta tonos */
283 { 'H', GREEK|GRAVE, 0, 0x1fca }, /* Eta varia */
284 { 'H', GREEK|ACUTE, 0, 0x1fcb }, /* Eta oxia */
285 { 'h', GREEK|DBLGRAVE, 0, 0x3ae }, /* eta tonos */
286 { 'h', GREEK|GRAVE, 0, 0x1f74 }, /* eta varia */
287 { 'h', GREEK|ACUTE, 0, 0x1f75 }, /* eta oxia */
288 { 'h', GREEK|TILDE, 0, 0x1fc6 }, /* eta perispomeni */
289 { 'I', GREEK|DBLGRAVE, 0, 0x38A }, /* Iota tonos */
290 { 'I', GREEK|DIAERESIS, 0, 0x3AA }, /* Iota dialytika */
291 { 'I', GREEK|GRAVE, 0, 0x1f7a }, /* Iota varia */
292 { 'I', GREEK|ACUTE, 0, 0x1f7b }, /* Iota oxia */
293 { 'I', GREEK|TILDE, 0, 0x1f78 }, /* Iota perispomeni */
294 { 'I', GREEK|MACRON, 0, 0x1f79 }, /* Iota macron */
295 { 'i', GREEK|DBLGRAVE, 0, 0x3af }, /* iota tonos */
296 { 'i', GREEK|DIAERESIS, 0, 0x3ca }, /* iota dialytika */
297 { 'i', GREEK|DBLGRAVE|DIAERESIS, 0, 0x390 },/* iota dialytika tonos */
298 { 'i', GREEK|GRAVE, 0, 0x1f76 }, /* iota varia */
299 { 'i', GREEK|ACUTE, 0, 0x1f77 }, /* iota oxia */
300 { 'i', GREEK|BREVE, 0, 0x1fd0 }, /* iota vrachy */
301 { 'i', GREEK|MACRON, 0, 0x1fd1 }, /* iota macron */
302 { 'i', GREEK|TILDE, 0, 0x1fd6 }, /* iota perispomeni */
303 { 'i', GREEK|GRAVE|DIAERESIS, 0, 0x1fd2},/* iota dialytika varia */
304 { 'i', GREEK|ACUTE|DIAERESIS, 0, 0x1fd3},/* iota dialytika oxia */
305 { 'i', GREEK|TILDE|DIAERESIS, 0, 0x1fd7},/* iota dialytika perispomeni */
306 { 'O', GREEK|DBLGRAVE, 0, 0x38C }, /* Omicron tonos */
307 { 'O', GREEK|GRAVE, 0, 0x1ff8 }, /* Omicron varia */
308 { 'O', GREEK|ACUTE, 0, 0x1ff9 }, /* Omicron oxia */
309 { 'o', GREEK|DBLGRAVE, 0, 0x3cc }, /* omicron tonos */
310 { 'o', GREEK|GRAVE, 0, 0x1f78 }, /* omicron varia */
311 { 'o', GREEK|ACUTE, 0, 0x1f79 }, /* omicron oxia */
312 { 'U', GREEK|DBLGRAVE, 0, 0x38E }, /* Upsilon tonos */
313 { 'U', GREEK|DIAERESIS, 0, 0x3AB }, /* Upsilon dialytika */
314 { 'U', GREEK|GRAVE, 0, 0x1fea }, /* Upsilon varia */
315 { 'U', GREEK|ACUTE, 0, 0x1feb }, /* Upsilon oxia */
316 { 'U', GREEK|BREVE, 0, 0x1fe8 }, /* Upsilon perispomeni */
317 { 'U', GREEK|MACRON, 0, 0x1fe9 }, /* Upsilon macron */
318 { 'u', GREEK|DBLGRAVE, 0, 0x3cd }, /* upsilon tonos */
319 { 'u', GREEK|DIAERESIS, 0, 0x3cb }, /* upsilon dialytika */
320 { 'u', GREEK|DBLGRAVE|DIAERESIS, 0, 0x3b0 },/* upsilon dialytika tonos */
321 { 'u', GREEK|GRAVE, 0, 0x1f7a }, /* upsilon varia */
322 { 'u', GREEK|ACUTE, 0, 0x1f7b }, /* upsilon oxia */
323 { 'u', GREEK|BREVE, 0, 0x1ff0 }, /* upsilon perispomeni */
324 { 'u', GREEK|MACRON, 0, 0x1fe1 }, /* upsilon macron */
325 { 'u', GREEK|GRAVE|DIAERESIS, 0, 0x1fe3 },/* upsilon dialytika varia */
326 { 'u', GREEK|ACUTE|DIAERESIS, 0, 0x1fe4 },/* upsilon dialytika oxia */
327 { 'u', GREEK|TILDE, 0, 0x1fe6 }, /* upsilon perispomeni */
328 { 'u', GREEK|TILDE|DIAERESIS, 0, 0x1fe7 },/* upsilon dialytika perispomeni */
329 { 'W', GREEK|DBLGRAVE, 0, 0x38F }, /* Omega tonos */
330 { 'W', GREEK|GRAVE, 0, 0x1ffa }, /* Omega varia */
331 { 'W', GREEK|ACUTE, 0, 0x1ffb }, /* Omega oxia */
332 { 'w', GREEK|DBLGRAVE, 0, 0x3ce }, /* omega tonos */
333 { 'w', GREEK|GRAVE, 0, 0x1f7a }, /* omega varia */
334 { 'w', GREEK|ACUTE, 0, 0x1f7b }, /* omega oxia */
335 { 0 }
336 };
337
338 struct transform {
339 uint32 oldstate;
340 uint32 newstate;
341 unichar_t resch;
342 struct transform *next;
343 } *info[95] = { 0 };
344
queuelen(struct transform * queue)345 int queuelen(struct transform *queue) {
346 int len=0;
347
348 while ( queue!=NULL ) {
349 queue = queue->next;
350 ++len;
351 }
352 return( len );
353 }
354
Mask(char * buffer,int mask)355 static char *Mask(char *buffer,int mask) {
356 int i;
357 char *bpt = buffer;
358
359 if ( mask==0 )
360 return( "0" );
361 if ( mask==ANY )
362 return("ANY");
363 *buffer = '\0';
364 for (i=0; names[i].name!=NULL; ++i ) {
365 if ( names[i].mask&mask ) {
366 if ( bpt!=buffer )
367 *bpt++ ='|';
368 strcpy(bpt,names[i].name);
369 bpt += strlen(bpt);
370 }
371 }
372 return( buffer );
373 }
374
dumpinfo()375 void dumpinfo() {
376 FILE *out;
377 int i;
378 struct transform *t;
379 char buffer[400], buffer2[400];
380
381 out = fopen("gdrawbuildchars.c","w");
382 fprintf(out, "/* Copyright (C) 2000-2012 by George Williams */\n" );
383 fprintf(out, "/*\n * Redistribution and use in source and binary forms, with or without\n" );
384 fprintf(out, " * modification, are permitted provided that the following conditions are met:\n *\n" );
385 fprintf(out, " * Redistributions of source code must retain the above copyright notice, this\n" );
386 fprintf(out, " * list of conditions and the following disclaimer.\n *\n" );
387 fprintf(out, " * Redistributions in binary form must reproduce the above copyright notice,\n" );
388 fprintf(out, " * this list of conditions and the following disclaimer in the documentation\n" );
389 fprintf(out, " * and/or other materials provided with the distribution.\n *\n" );
390 fprintf(out, " * The name of the author may not be used to endorse or promote products\n" );
391 fprintf(out, " * derived from this software without specific prior written permission.\n *\n" );
392 fprintf(out, " * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\n" );
393 fprintf(out, " * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n" );
394 fprintf(out, " * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n" );
395 fprintf(out, " * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n" );
396 fprintf(out, " * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n" );
397 fprintf(out, " * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n" );
398 fprintf(out, " * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n" );
399 fprintf(out, " * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n" );
400 fprintf(out, " * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n" );
401 fprintf(out, " * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n" );
402 fprintf(out, "/* This file was generated using the program 'makebuildtables.c' */\n\n" );
403 fprintf(out,"#include \"gdrawP.h\"\n\n" );
404
405 for ( i=0; names[i].name!=NULL; ++i )
406 fprintf( out, "#define\t%s\t%s0x%07x\n", names[i].name, \
407 strlen(names[i].name)>7?"":"\t", names[i].mask );
408 fprintf(out,"\n#define\tANY\t\t0x%07x\n\n", ANY );
409
410 for ( i=0; i<95; ++i ) if ( info[i]!=NULL ) {
411 fprintf(out, "static struct gchr_transform trans_%s[] = {\n", charnames[i] );
412 for ( t=info[i]; t!=NULL; t=t->next )
413 fprintf(out, " { %s, %s, 0x%07x }%s\n", Mask(buffer,t->oldstate),
414 Mask(buffer2,t->newstate), t->resch, t->next==NULL?"":"," );
415 fprintf(out,"};\n\n");
416 }
417 fprintf(out,"struct gchr_lookup _gdraw_chrlookup[95] = {\n" );
418 for ( i=0; i<95; ++i ) {
419 if ( info[i]==NULL )
420 fprintf(out, " /* %c */ { 0 },\n", i+' ' );
421 else
422 fprintf(out, " /* %c */ { %d, trans_%s },\n", i+' ', queuelen(info[i]), charnames[i] );
423 }
424 fprintf(out,"};\n\n" );
425
426 fprintf(out, "struct gchr_accents _gdraw_accents[] = {\n" );
427 fprintf(out, " { 0x0301, 0x%07x },\n", ACUTE );
428 fprintf(out, " { 0x0300, 0x%07x },\n", GRAVE );
429 fprintf(out, " { 0x0308, 0x%07x },\n", DIAERESIS );
430 fprintf(out, " { 0x0302, 0x%07x },\n", CIRCUMFLEX );
431 fprintf(out, " { 0x0303, 0x%07x },\n", TILDE );
432 fprintf(out, " { 0x030a, 0x%07x },\n", RING );
433 fprintf(out, " { 0x0338, 0x%07x },\n", SLASH );
434 fprintf(out, " { 0x0306, 0x%07x },\n", BREVE );
435 fprintf(out, " { 0x030c, 0x%07x },\n", CARON );
436 fprintf(out, " { 0x0307, 0x%07x },\n", DOTABOVE );
437 fprintf(out, " { 0x0323, 0x%07x },\n", DOTBELOW );
438 fprintf(out, " { 0x0327, 0x%07x },\n", CEDILLA );
439 fprintf(out, " { 0x0328, 0x%07x },\n", OGONEK );
440 fprintf(out, " { 0x0304, 0x%07x },\n", MACRON );
441 fprintf(out, " { 0x030d, 0x%07x },\n", DBLGRAVE|GREEK );
442 fprintf(out, " { 0x030b, 0x%07x },\n", DBLGRAVE );
443 fprintf(out, " { 0x030b, 0x%07x },\n", DBLACUTE );
444 fprintf(out, " { 0x030b, 0x%07x },\n", INVBREVE );
445 fprintf(out, " { 0x030b, 0x%07x },\n", DIAERESISBELOW );
446 fprintf(out, " { 0x030b, 0x%07x },\n", CIRCUMFLEXBELOW );
447 fprintf(out, " { 0x030b, 0x%07x },\n", TILDEBELOW );
448 fprintf(out, " { 0x030b, 0x%07x },\n", RINGBELOW );
449 fprintf(out, " { 0x030b, 0x%07x },\n", LINEBELOW );
450 fprintf(out, " { 0x030b, 0x%07x },\n", HOOKABOVE );
451 fprintf(out, " { 0x030b, 0x%07x },\n", HORN );
452 fprintf(out, " { 0, 0 },\n" );
453 fprintf(out, "};\n\n" );
454 fprintf(out, "uint32 _gdraw_chrs_any=ANY, _gdraw_chrs_ctlmask=GREEK, _gdraw_chrs_metamask=0;\n" );
455 fclose(out);
456 }
457
mygets(FILE * in,char * buffer)458 char *mygets(FILE *in,char *buffer) {
459 char *bpt = buffer;
460 int ch;
461
462 while ((ch = getc(in))!=EOF && ch!='\n' )
463 *bpt++ = ch;
464 *bpt = '\0';
465 if ( bpt==buffer && ch==EOF )
466 return( NULL );
467 return(buffer );
468 }
469
AddTransform(int ch,uint32 oldstate,uint32 newstate,unsigned short resch)470 void AddTransform(int ch, uint32 oldstate, uint32 newstate, unsigned short resch ) {
471 struct transform *trans;
472
473 ch -= ' ';
474 for ( trans=info[ch]; trans!=NULL; trans = trans->next )
475 if ( trans->oldstate==oldstate ) {
476 fprintf(stderr, "Duplicate entry for %c(%d) at 0x%07x, 0x%07x,0x%07x and 0x%07x,0x%07x\n",
477 ch+' ', ch+' ', oldstate, trans->newstate, trans->resch, newstate, resch );
478 break;
479 }
480
481 trans = calloc(1,sizeof(struct transform));
482 trans->next = info[ch];
483 info[ch] = trans;
484 trans->oldstate = oldstate;
485 trans->newstate = newstate;
486 trans->resch = resch;
487 }
488
ParseUnicodeFile(FILE * in)489 void ParseUnicodeFile(FILE *in) {
490 char buffer[600];
491 int ch, mask, base, lc, i;
492 char *pt;
493
494 while ( mygets(in,buffer)!=NULL ) {
495 ch = strtol(buffer,NULL,16);
496 if ( ch==0x1ec0 )
497 ch = 0x1ec0;
498 pt = buffer+4;
499 if ( strncmp(pt,";LATIN ",7)!=0 )
500 continue;
501 pt += 7;
502 if ( strncmp(pt,"CAPITAL ",8)==0 ) {
503 lc = 0;
504 pt += 8;
505 } else if ( strncmp(pt,"SMALL ",6)==0 ) {
506 lc = 1;
507 pt += 6;
508 } else
509 continue;
510 if ( strncmp(pt,"LETTER ",7)!=0 )
511 continue;
512 pt += 7;
513 base = *pt++;
514 if ( lc ) base = tolower(base);
515 if ( strncmp(pt," WITH ",6)!=0 )
516 continue;
517 pt += 6;
518 mask = 0;
519 for (;;) {
520 for ( i=0; names2[i].name!=NULL; ++i ) {
521 if ( strncmp(pt,names2[i].name,strlen(names2[i].name))==0 )
522 break;
523 }
524 if ( names2[i].name==NULL || names2[i].mask==0 )
525 goto continue_2_loop;
526 mask |= names2[i].mask;
527 pt += strlen(names2[i].name);
528 while ( *pt!=';' && !(*pt==' ' && pt[1]=='A' && pt[2]=='N' && pt[3]=='D' && pt[4]==' '))
529 ++pt;
530 if ( *pt==';' )
531 break;
532 else
533 pt += 5;
534 }
535 AddTransform(base,mask,0,ch);
536 continue_2_loop:;
537 }
538 fclose(in);
539 }
540
AddPredefineds()541 void AddPredefineds() {
542 int i;
543
544 for ( i=0; predefined[i].ch!='\0'; ++i )
545 AddTransform(predefined[i].ch, predefined[i].oldstate,
546 predefined[i].newstate, predefined[i].result );
547 }
548
RevQueue(struct transform * cur)549 struct transform *RevQueue(struct transform *cur) {
550 struct transform *prev=NULL, *next;
551
552 if ( cur==NULL )
553 return( NULL );
554 next = cur->next;
555 while ( next!=NULL ) {
556 cur->next = prev;
557 prev = cur;
558 cur = next;
559 next = cur->next;
560 }
561 cur->next = prev;
562 return( cur );
563 }
564
main()565 int main() {
566 FILE *in;
567 int i;
568
569 AddPredefineds();
570 in = fopen("UnicodeData.txt","r");
571 if ( in==NULL ) {
572 fprintf(stderr,"Can't open UnicodeData.txt\n" );
573 return( -1 );
574 }
575 ParseUnicodeFile(in);
576 for ( i=0; i<95; ++i )
577 info[i] = RevQueue(info[i]);
578 dumpinfo();
579 return( 0 );
580 }
581