Release 20030408.
[wine/gsoc-2012-control.git] / dlls / wineps / mkagl.c
blob085d2a7fae78930847bc15e93f97f5c26a759cac
1 /*
2 * Copyright 2001 Ian Pilcher
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include <sys/types.h>
20 #include <dirent.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <ctype.h>
28 * The array of glyph information
31 typedef struct
33 int UV;
34 int index; /* in PSDRV_AGLGlyphNames */
35 const char *name;
36 const char *comment;
38 } GLYPHINFO;
40 static GLYPHINFO glyphs[1500];
41 static int num_glyphs = 0;
45 * Functions to search and sort the array
48 static int cmp_by_UV(const void *a, const void *b)
50 return ((const GLYPHINFO *)a)->UV - ((const GLYPHINFO *)b)->UV;
53 static int cmp_by_name(const void *a, const void *b)
55 return strcmp(((const GLYPHINFO *)a)->name, ((const GLYPHINFO *)b)->name);
58 inline static void sort_by_UV()
60 qsort(glyphs, num_glyphs, sizeof(GLYPHINFO), cmp_by_UV);
63 inline static void sort_by_name()
65 qsort(glyphs, num_glyphs, sizeof(GLYPHINFO), cmp_by_name);
68 inline static GLYPHINFO *search_by_name(const char *name)
70 GLYPHINFO gi;
72 gi.name = name;
74 return (GLYPHINFO *)bsearch(&gi, glyphs, num_glyphs, sizeof(GLYPHINFO),
75 cmp_by_name);
80 * Use the 'optimal' combination of tabs and spaces to position the cursor
83 inline static void fcpto(FILE *f, int newpos, int curpos)
85 int newtpos = newpos & ~7;
86 int curtpos = curpos & ~7;
88 while (curtpos < newtpos)
90 fputc('\t', f);
91 curtpos += 8;
92 curpos = curtpos;
95 while (curpos < newpos)
97 fputc(' ', f);
98 ++curpos;
102 inline static void cpto(int newpos, int curpos)
104 fcpto(stdout, newpos, curpos);
109 * Make main() look "purty"
112 inline static void double_space(FILE *f)
114 fputc('\n', f);
117 inline static void triple_space(FILE *f)
119 fputc('\n', f); fputc('\n', f);
124 * Read the Adobe Glyph List from 'glyphlist.txt'
127 static void read_agl()
129 FILE *f = fopen("glyphlist.txt", "r");
130 char linebuf[256], namebuf[128], commbuf[128];
132 if (f == NULL)
134 fprintf(stderr, "Error opening glyphlist.txt\n");
135 exit(__LINE__);
138 while (fgets(linebuf, sizeof(linebuf), f) != NULL)
140 unsigned int UV;
142 if (linebuf[0] == '#')
143 continue;
145 sscanf(linebuf, "%X;%[^;];%[^\n]", &UV, namebuf, commbuf);
147 glyphs[num_glyphs].UV = (int)UV;
148 glyphs[num_glyphs].name = strdup(namebuf);
149 glyphs[num_glyphs].comment = strdup(commbuf);
151 if (glyphs[num_glyphs].name == NULL ||
152 glyphs[num_glyphs].comment == NULL)
154 fprintf(stderr, "Memory allocation failure\n");
155 exit(__LINE__);
158 ++num_glyphs;
161 fclose(f);
163 if (num_glyphs != 1051)
165 fprintf(stderr, "Read %i glyphs\n", num_glyphs);
166 exit(__LINE__);
172 * Read glyph names from all AFM files in current directory
175 static void read_afms(FILE *f_c, FILE *f_h)
177 DIR *d = opendir(".");
178 struct dirent *de;
180 fputs( "/*\n"
181 " * Built-in font metrics\n"
182 " */\n"
183 "\n"
184 "const AFM *const PSDRV_BuiltinAFMs[] =\n"
185 "{\n", f_c);
188 if (d == NULL)
190 fprintf(stderr, "Error opening current directory\n");
191 exit(__LINE__);
194 while ((de = readdir(d)) != NULL)
196 FILE *f;
197 char *cp, linebuf[256], font_family[128];
198 int i, num_metrics;
200 cp = strrchr(de->d_name, '.'); /* Does it end in */
201 if (cp == NULL || strcasecmp(cp, ".afm") != 0) /* .afm or .AFM? */
202 continue;
204 f = fopen(de->d_name, "r");
205 if (f == NULL)
207 fprintf(stderr, "Error opening %s\n", de->d_name);
208 exit(__LINE__);
211 while (1)
213 if (fgets(linebuf, sizeof(linebuf), f) == NULL)
215 fprintf(stderr, "FontName not found in %s\n", de->d_name);
216 exit(__LINE__);
219 if (strncmp(linebuf, "FontName ", 9) == 0)
220 break;
223 sscanf(linebuf, "FontName %[^\r\n]", font_family);
225 for (i = 0; font_family[i] != '\0'; ++i)
226 if (font_family[i] == '-')
227 font_family[i] = '_';
229 fprintf(f_h, "extern const AFM PSDRV_%s;\n", font_family);
230 fprintf(f_c, " &PSDRV_%s,\n", font_family);
232 while (1)
234 if (fgets(linebuf, sizeof(linebuf), f) == NULL)
236 fprintf(stderr, "FamilyName not found in %s\n", de->d_name);
237 exit(__LINE__);
240 if (strncmp(linebuf, "FamilyName ", 11) == 0)
241 break;
244 sscanf(linebuf, "FamilyName %[^\r\n]", font_family);
246 while (1)
248 if (fgets(linebuf, sizeof(linebuf), f) == NULL)
250 fprintf(stderr, "StartCharMetrics not found in %s\n",
251 de->d_name);
252 exit(__LINE__);
255 if (strncmp(linebuf, "StartCharMetrics ", 17) == 0)
256 break;
259 sscanf(linebuf, "StartCharMetrics %i", &num_metrics);
261 for (i = 0; i < num_metrics; ++i)
263 char namebuf[128];
265 if (fgets(linebuf, sizeof(linebuf), f) == NULL)
267 fprintf(stderr, "Unexpected EOF after %i glyphs in %s\n", i,
268 de->d_name);
269 exit(__LINE__);
272 cp = strchr(linebuf, 'N');
273 if (cp == NULL || strlen(cp) < 3)
275 fprintf(stderr, "Parse error after %i glyphs in %s\n", i,
276 de->d_name);
277 exit(__LINE__);
280 sscanf(cp, "N %s", namebuf);
281 if (search_by_name(namebuf) != NULL)
282 continue;
284 sprintf(linebuf, "FONT FAMILY;%s", font_family);
286 glyphs[num_glyphs].UV = -1;
287 glyphs[num_glyphs].name = strdup(namebuf);
288 glyphs[num_glyphs].comment = strdup(linebuf);
290 if (glyphs[num_glyphs].name == NULL ||
291 glyphs[num_glyphs].comment == NULL)
293 fprintf(stderr, "Memory allocation failure\n");
294 exit(__LINE__);
297 ++num_glyphs;
299 sort_by_name();
302 fclose(f);
305 closedir(d);
307 fputs(" NULL\n};\n", f_c);
312 * Write opening comments, etc.
315 static void write_header(FILE *f)
317 int i;
319 fputc('/', f);
320 for (i = 0; i < 79; ++i)
321 fputc('*', f);
322 fputs("\n"
323 " *\n"
324 " *\tFont and glyph data for the Wine PostScript driver\n"
325 " *\n"
326 " *\tCopyright 2001 Ian Pilcher\n"
327 " *\n"
328 " *\n"
329 " *\tThis data is derived from the Adobe Glyph list at\n"
330 " *\n"
331 " *\t "
332 "http://partners.adobe.com/asn/developer/type/glyphlist.txt\n"
333 " *\n"
334 " *\tand the Adobe Font Metrics files at\n"
335 " *\n"
336 " *\t "
337 "ftp://ftp.adobe.com/pub/adobe/type/win/all/afmfiles/base35/\n"
338 " *\n"
339 " *\twhich are Copyright 1985-1998 Adobe Systems Incorporated.\n"
340 " *\n"
341 " */\n"
342 "\n"
343 "#include \"psdrv.h\"\n"
344 "#include \"data/agl.h\"\n", f);
348 * Write the array of glyph names (also populates indexes)
351 static void write_glyph_names(FILE *f_c, FILE *f_h)
353 int i, num_names = 0, index = 0;
355 for (i = 0; i < num_glyphs; ++i)
356 if (i == 0 || strcmp(glyphs[i - 1].name, glyphs[i].name) != 0)
357 ++num_names;
359 fputs( "/*\n"
360 " * Every glyph name in the AGL and the 35 core PostScript fonts\n"
361 " */\n"
362 "\n", f_c);
364 fprintf(f_c, "const INT PSDRV_AGLGlyphNamesSize = %i;\n\n", num_names);
366 fprintf(f_c, "GLYPHNAME PSDRV_AGLGlyphNames[%i] =\n{\n", num_names);
368 for (i = 0; i < num_glyphs - 1; ++i)
370 int cp = 0;
372 if (i == 0 || strcmp(glyphs[i - 1].name, glyphs[i].name) != 0)
374 fcpto(f_h, 32, fprintf(f_h, "#define GN_%s", glyphs[i].name));
375 fprintf(f_h, "(PSDRV_AGLGlyphNames + %i)\n", index);
377 cp = fprintf(f_c, " { %4i, \"%s\" },", index, glyphs[i].name);
378 glyphs[i].index = index;
379 ++index;
381 else
383 glyphs[i].index = glyphs[i - 1].index;
386 fcpto(f_c, 40, cp);
388 fprintf(f_c, "/* %s */\n", glyphs[i].comment);
391 fcpto(f_h, 32, fprintf(f_h, "#define GN_%s", glyphs[i].name));
392 fprintf(f_h, "(PSDRV_AGLGlyphNames + %i)\n", index);
394 glyphs[i].index = index;
395 fcpto(f_c, 40, fprintf(f_c, " { %4i, \"%s\" }", index, glyphs[i].name));
396 fprintf(f_c, "/* %s */\n};\n", glyphs[i].comment);
401 * Write the AGL encoding vector, sorted by glyph name
404 static void write_encoding_by_name(FILE *f)
406 int i, size = 0, even = 1;
408 for (i = 0; i < num_glyphs; ++i)
409 if (glyphs[i].UV != -1 &&
410 (i == 0 || strcmp(glyphs[i - 1].name, glyphs[i].name) != 0))
411 ++size; /* should be 1039 */
413 fputs( "/*\n"
414 " * The AGL encoding vector, sorted by glyph name - "
415 "duplicates omitted\n"
416 " */\n"
417 "\n", f);
419 fprintf(f, "const INT PSDRV_AGLbyNameSize = %i;\n\n", size);
420 fprintf(f, "const UNICODEGLYPH PSDRV_AGLbyName[%i] =\n{\n", size);
422 for (i = 0; i < num_glyphs - 1; ++i)
424 int cp;
426 if (glyphs[i].UV == -1)
427 continue;
429 if (i != 0 && strcmp(glyphs[i - 1].name, glyphs[i].name) == 0)
430 continue;
432 cp = fprintf(f, " { 0x%.4x, GN_%s },", glyphs[i].UV, glyphs[i].name);
434 even = !even;
435 if (even)
436 fputc('\n', f);
437 else
438 fcpto(f, 40, cp);
441 fprintf(f, " { 0x%.4x, GN_%s }\n};\n", glyphs[i].UV, glyphs[i].name);
445 * Write the AGL encoding vector, sorted by Unicode value
448 static void write_encoding_by_UV(FILE *f)
450 int i, size = 0, even = 1;
452 for (i = 0; i < num_glyphs; ++i)
453 if (glyphs[i].UV != -1)
454 ++size; /* better be 1051! */
456 sort_by_UV();
458 fputs( "/*\n"
459 " * The AGL encoding vector, sorted by Unicode value - "
460 "duplicates included\n"
461 " */\n"
462 "\n", f);
464 fprintf(f, "const INT PSDRV_AGLbyUVSize = %i;\n\n", size);
465 fprintf(f, "const UNICODEGLYPH PSDRV_AGLbyUV[%i] =\n{\n", size);
467 for (i = 0; i < num_glyphs - 1; ++i)
469 int cp;
471 if (glyphs[i].UV == -1)
472 continue;
474 cp = fprintf(f, " { 0x%.4x, GN_%s },", glyphs[i].UV, glyphs[i].name);
476 even = !even;
477 if (even)
478 fputc('\n', f);
479 else
480 fcpto(f, 40, cp);
483 fprintf(f, " { 0x%.4x, GN_%s }\n};\n", glyphs[i].UV, glyphs[i].name);
488 * Do it!
491 int main(int argc, char *argv[])
493 FILE *f_c, *f_h;
495 if (argc < 3)
497 fprintf(stderr, "Usage: %s <C file> <header file>\n", argv[0]);
498 exit(__LINE__);
501 f_c = fopen(argv[1], "w");
502 if (f_c == NULL)
504 fprintf(stderr, "Error opening %s for writing\n", argv[1]);
505 exit(__LINE__);
508 f_h = fopen(argv[2], "w");
509 if (f_h == NULL)
511 fprintf(stderr, "Error opening %s for writing\n", argv[2]);
512 exit(__LINE__);
515 write_header(f_c);
516 triple_space(f_c);
517 read_agl();
518 read_afms(f_c, f_h); /* also writes font list */
519 triple_space(f_c);
520 write_glyph_names(f_c, f_h);
521 triple_space(f_c);
522 write_encoding_by_name(f_c);
523 triple_space(f_c);
524 write_encoding_by_UV(f_c);
526 return 0;