10 * The array of glyph information
16 int index; /* in PSDRV_AGLGlyphNames */
22 static GLYPHINFO glyphs[1500];
23 static int num_glyphs = 0;
27 * Functions to search and sort the array
30 static int cmp_by_UV(const void *a, const void *b)
32 return ((const GLYPHINFO *)a)->UV - ((const GLYPHINFO *)b)->UV;
35 static int cmp_by_name(const void *a, const void *b)
37 return strcmp(((const GLYPHINFO *)a)->name, ((const GLYPHINFO *)b)->name);
40 inline static void sort_by_UV()
42 qsort(glyphs, num_glyphs, sizeof(GLYPHINFO), cmp_by_UV);
45 inline static void sort_by_name()
47 qsort(glyphs, num_glyphs, sizeof(GLYPHINFO), cmp_by_name);
50 inline static GLYPHINFO *search_by_name(const char *name)
56 return (GLYPHINFO *)bsearch(&gi, glyphs, num_glyphs, sizeof(GLYPHINFO),
62 * Use the 'optimal' combination of tabs and spaces to position the cursor
65 inline static void fcpto(FILE *f, int newpos, int curpos)
67 int newtpos = newpos & ~7;
68 int curtpos = curpos & ~7;
70 while (curtpos < newtpos)
77 while (curpos < newpos)
84 inline static void cpto(int newpos, int curpos)
86 fcpto(stdout, newpos, curpos);
91 * Make main() look "purty"
94 inline static void double_space(FILE *f)
99 inline static void triple_space(FILE *f)
101 fputc('\n', f); fputc('\n', f);
106 * Read the Adobe Glyph List from 'glyphlist.txt'
109 static void read_agl()
111 FILE *f = fopen("glyphlist.txt", "r");
112 char linebuf[256], namebuf[128], commbuf[128];
116 fprintf(stderr, "Error opening glyphlist.txt\n");
120 while (fgets(linebuf, sizeof(linebuf), f) != NULL)
124 if (linebuf[0] == '#')
127 sscanf(linebuf, "%X;%[^;];%[^\n]", &UV, namebuf, commbuf);
129 glyphs[num_glyphs].UV = (int)UV;
130 glyphs[num_glyphs].name = strdup(namebuf);
131 glyphs[num_glyphs].comment = strdup(commbuf);
133 if (glyphs[num_glyphs].name == NULL ||
134 glyphs[num_glyphs].comment == NULL)
136 fprintf(stderr, "Memory allocation failure\n");
145 if (num_glyphs != 1051)
147 fprintf(stderr, "Read %i glyphs\n", num_glyphs);
154 * Read glyph names from all AFM files in current directory
157 static void read_afms(FILE *f_c, FILE *f_h)
159 DIR *d = opendir(".");
163 " * Built-in font metrics\n"
166 "const AFM *const PSDRV_BuiltinAFMs[] =\n"
172 fprintf(stderr, "Error opening current directory\n");
176 while ((de = readdir(d)) != NULL)
179 char *cp, linebuf[256], font_family[128];
182 cp = strrchr(de->d_name, '.'); /* Does it end in */
183 if (cp == NULL || strcasecmp(cp, ".afm") != 0) /* .afm or .AFM? */
186 f = fopen(de->d_name, "r");
189 fprintf(stderr, "Error opening %s\n", de->d_name);
195 if (fgets(linebuf, sizeof(linebuf), f) == NULL)
197 fprintf(stderr, "FontName not found in %s\n", de->d_name);
201 if (strncmp(linebuf, "FontName ", 9) == 0)
205 sscanf(linebuf, "FontName %[^\r\n]", font_family);
207 for (i = 0; font_family[i] != '\0'; ++i)
208 if (font_family[i] == '-')
209 font_family[i] = '_';
211 fprintf(f_h, "extern const AFM PSDRV_%s;\n", font_family);
212 fprintf(f_c, " &PSDRV_%s,\n", font_family);
216 if (fgets(linebuf, sizeof(linebuf), f) == NULL)
218 fprintf(stderr, "FamilyName not found in %s\n", de->d_name);
222 if (strncmp(linebuf, "FamilyName ", 11) == 0)
226 sscanf(linebuf, "FamilyName %[^\r\n]", font_family);
230 if (fgets(linebuf, sizeof(linebuf), f) == NULL)
232 fprintf(stderr, "StartCharMetrics not found in %s\n",
237 if (strncmp(linebuf, "StartCharMetrics ", 17) == 0)
241 sscanf(linebuf, "StartCharMetrics %i", &num_metrics);
243 for (i = 0; i < num_metrics; ++i)
247 if (fgets(linebuf, sizeof(linebuf), f) == NULL)
249 fprintf(stderr, "Unexpected EOF after %i glyphs in %s\n", i,
254 cp = strchr(linebuf, 'N');
255 if (cp == NULL || strlen(cp) < 3)
257 fprintf(stderr, "Parse error after %i glyphs in %s\n", i,
262 sscanf(cp, "N %s", namebuf);
263 if (search_by_name(namebuf) != NULL)
266 sprintf(linebuf, "FONT FAMILY;%s", font_family);
268 glyphs[num_glyphs].UV = -1;
269 glyphs[num_glyphs].name = strdup(namebuf);
270 glyphs[num_glyphs].comment = strdup(linebuf);
272 if (glyphs[num_glyphs].name == NULL ||
273 glyphs[num_glyphs].comment == NULL)
275 fprintf(stderr, "Memory allocation failure\n");
289 fputs(" NULL\n};\n", f_c);
294 * Write opening comments, etc.
297 static void write_header(FILE *f)
302 for (i = 0; i < 79; ++i)
306 " *\tFont and glyph data for the Wine PostScript driver\n"
308 " *\tCopyright 2001 Ian Pilcher\n"
311 " *\tThis data is derived from the Adobe Glyph list at\n"
314 "http://partners.adobe.com/asn/developer/type/glyphlist.txt\n"
316 " *\tand the Adobe Font Metrics files at\n"
319 "ftp://ftp.adobe.com/pub/adobe/type/win/all/afmfiles/base35/\n"
321 " *\twhich are Copyright 1985-1998 Adobe Systems Incorporated.\n"
325 "#include \"psdrv.h\"\n"
326 "#include \"data/agl.h\"\n", f);
330 * Write the array of glyph names (also populates indexes)
333 static void write_glyph_names(FILE *f_c, FILE *f_h)
335 int i, num_names = 0, index = 0;
337 for (i = 0; i < num_glyphs; ++i)
338 if (i == 0 || strcmp(glyphs[i - 1].name, glyphs[i].name) != 0)
342 " * Every glyph name in the AGL and the 35 core PostScript fonts\n"
346 fprintf(f_c, "const INT PSDRV_AGLGlyphNamesSize = %i;\n\n", num_names);
348 fprintf(f_c, "GLYPHNAME PSDRV_AGLGlyphNames[%i] =\n{\n", num_names);
350 for (i = 0; i < num_glyphs - 1; ++i)
354 if (i == 0 || strcmp(glyphs[i - 1].name, glyphs[i].name) != 0)
356 fcpto(f_h, 32, fprintf(f_h, "#define GN_%s", glyphs[i].name));
357 fprintf(f_h, "(PSDRV_AGLGlyphNames + %i)\n", index);
359 cp = fprintf(f_c, " { %4i, \"%s\" },", index, glyphs[i].name);
360 glyphs[i].index = index;
365 glyphs[i].index = glyphs[i - 1].index;
370 fprintf(f_c, "/* %s */\n", glyphs[i].comment);
373 fcpto(f_h, 32, fprintf(f_h, "#define GN_%s", glyphs[i].name));
374 fprintf(f_h, "(PSDRV_AGLGlyphNames + %i)\n", index);
376 glyphs[i].index = index;
377 fcpto(f_c, 40, fprintf(f_c, " { %4i, \"%s\" }", index, glyphs[i].name));
378 fprintf(f_c, "/* %s */\n};\n", glyphs[i].comment);
383 * Write the AGL encoding vector, sorted by glyph name
386 static void write_encoding_by_name(FILE *f)
388 int i, size = 0, even = 1;
390 for (i = 0; i < num_glyphs; ++i)
391 if (glyphs[i].UV != -1 &&
392 (i == 0 || strcmp(glyphs[i - 1].name, glyphs[i].name) != 0))
393 ++size; /* should be 1039 */
396 " * The AGL encoding vector, sorted by glyph name - "
397 "duplicates omitted\n"
401 fprintf(f, "const INT PSDRV_AGLbyNameSize = %i;\n\n", size);
402 fprintf(f, "const UNICODEGLYPH PSDRV_AGLbyName[%i] = \n{\n", size);
404 for (i = 0; i < num_glyphs - 1; ++i)
408 if (glyphs[i].UV == -1)
411 if (i != 0 && strcmp(glyphs[i - 1].name, glyphs[i].name) == 0)
414 cp = fprintf(f, " { 0x%.4x, GN_%s },", glyphs[i].UV, glyphs[i].name);
423 fprintf(f, " { 0x%.4x, GN_%s }\n};\n", glyphs[i].UV, glyphs[i].name);
427 * Write the AGL encoding vector, sorted by Unicode value
430 static void write_encoding_by_UV(FILE *f)
432 int i, size = 0, even = 1;
434 for (i = 0; i < num_glyphs; ++i)
435 if (glyphs[i].UV != -1)
436 ++size; /* better be 1051! */
441 " * The AGL encoding vector, sorted by Unicode value - "
442 "duplicates included\n"
446 fprintf(f, "const INT PSDRV_AGLbyUVSize = %i;\n\n", size);
447 fprintf(f, "const UNICODEGLYPH PSDRV_AGLbyUV[%i] = \n{\n", size);
449 for (i = 0; i < num_glyphs - 1; ++i)
453 if (glyphs[i].UV == -1)
456 cp = fprintf(f, " { 0x%.4x, GN_%s },", glyphs[i].UV, glyphs[i].name);
465 fprintf(f, " { 0x%.4x, GN_%s }\n};\n", glyphs[i].UV, glyphs[i].name);
473 int main(int argc, char *argv[])
479 fprintf(stderr, "Usage: %s <C file> <header file>\n", argv[0]);
483 f_c = fopen(argv[1], "w");
486 fprintf(stderr, "Error opening %s for writing\n", argv[1]);
490 f_h = fopen(argv[2], "w");
493 fprintf(stderr, "Error opening %s for writing\n", argv[2]);
500 read_afms(f_c, f_h); /* also writes font list */
502 write_glyph_names(f_c, f_h);
504 write_encoding_by_name(f_c);
506 write_encoding_by_UV(f_c);