11 * The array of glyph information
17 int index; /* in PSDRV_AGLGlyphNames */
23 static GLYPHINFO glyphs[1500];
24 static int num_glyphs = 0;
28 * Functions to search and sort the array
31 static int cmp_by_UV(const void *a, const void *b)
33 return ((const GLYPHINFO *)a)->UV - ((const GLYPHINFO *)b)->UV;
36 static int cmp_by_name(const void *a, const void *b)
38 return strcmp(((const GLYPHINFO *)a)->name, ((const GLYPHINFO *)b)->name);
41 inline static void sort_by_UV()
43 qsort(glyphs, num_glyphs, sizeof(GLYPHINFO), cmp_by_UV);
46 inline static void sort_by_name()
48 qsort(glyphs, num_glyphs, sizeof(GLYPHINFO), cmp_by_name);
51 inline static GLYPHINFO *search_by_name(const char *name)
57 return (GLYPHINFO *)bsearch(&gi, glyphs, num_glyphs, sizeof(GLYPHINFO),
63 * Use the 'optimal' combination of tabs and spaces to position the cursor
66 inline static void fcpto(FILE *f, int newpos, int curpos)
68 int newtpos = newpos & ~7;
69 int curtpos = curpos & ~7;
71 while (curtpos < newtpos)
78 while (curpos < newpos)
85 inline static void cpto(int newpos, int curpos)
87 fcpto(stdout, newpos, curpos);
92 * Make main() look "purty"
95 inline static void double_space(FILE *f)
100 inline static void triple_space(FILE *f)
102 fputc('\n', f); fputc('\n', f);
107 * Read the Adobe Glyph List from 'glyphlist.txt'
110 static void read_agl()
112 FILE *f = fopen("glyphlist.txt", "r");
113 char linebuf[256], namebuf[128], commbuf[128];
117 fprintf(stderr, "Error opening glyphlist.txt\n");
121 while (fgets(linebuf, sizeof(linebuf), f) != NULL)
125 if (linebuf[0] == '#')
128 sscanf(linebuf, "%X;%[^;];%[^\n]", &UV, namebuf, commbuf);
130 glyphs[num_glyphs].UV = (int)UV;
131 glyphs[num_glyphs].name = strdup(namebuf);
132 glyphs[num_glyphs].comment = strdup(commbuf);
134 if (glyphs[num_glyphs].name == NULL ||
135 glyphs[num_glyphs].comment == NULL)
137 fprintf(stderr, "Memory allocation failure\n");
146 if (num_glyphs != 1051)
148 fprintf(stderr, "Read %i glyphs\n", num_glyphs);
155 * Read glyph names from all AFM files in current directory
158 static void read_afms()
160 DIR *d = opendir(".");
165 fprintf(stderr, "Error opening current directory\n");
169 while ((de = readdir(d)) != NULL)
172 char *cp, linebuf[256], font_family[128];
175 cp = strrchr(de->d_name, '.'); /* Does it end in */
176 if (cp == NULL || strcasecmp(cp, ".afm") != 0) /* .afm or .AFM? */
179 f = fopen(de->d_name, "r");
182 fprintf(stderr, "Error opening %s\n", de->d_name);
188 if (fgets(linebuf, sizeof(linebuf), f) == NULL)
190 fprintf(stderr, "FamilyName not found in %s\n", de->d_name);
194 if (strncmp(linebuf, "FamilyName ", 11) == 0)
198 sscanf(linebuf, "FamilyName %[^\r\n]", font_family);
202 if (fgets(linebuf, sizeof(linebuf), f) == NULL)
204 fprintf(stderr, "StartCharMetrics not found in %s\n",
209 if (strncmp(linebuf, "StartCharMetrics ", 17) == 0)
213 sscanf(linebuf, "StartCharMetrics %i", &num_metrics);
215 for (i = 0; i < num_metrics; ++i)
219 if (fgets(linebuf, sizeof(linebuf), f) == NULL)
221 fprintf(stderr, "Unexpected EOF after %i glyphs in %s\n", i,
226 cp = strchr(linebuf, 'N');
227 if (cp == NULL || strlen(cp) < 3)
229 fprintf(stderr, "Parse error after %i glyphs in %s\n", i,
234 sscanf(cp, "N %s", namebuf);
235 if (search_by_name(namebuf) != NULL)
238 sprintf(linebuf, "FONT FAMILY;%s", font_family);
240 glyphs[num_glyphs].UV = -1;
241 glyphs[num_glyphs].name = strdup(namebuf);
242 glyphs[num_glyphs].comment = strdup(linebuf);
244 if (glyphs[num_glyphs].name == NULL ||
245 glyphs[num_glyphs].comment == NULL)
247 fprintf(stderr, "Memory allocation failure\n");
264 * Write opening comments, etc.
267 static void write_header(FILE *f)
272 for (i = 0; i < 79; ++i)
276 " *\tAdobe Glyph List data for the Wine PostScript driver\n"
278 " *\tCopyright 2001 Ian Pilcher\n"
281 " *\tThis data is derived from the Adobe Glyph list at\n"
284 "http://partners.adobe.com/asn/developer/type/glyphlist.txt\n"
286 " *\tand the Adobe Font Metrics files at\n"
289 "ftp://ftp.adobe.com/pub/adobe/type/win/all/afmfiles/base35/\n"
291 " *\twhich are Copyright 1985-1998 Adobe Systems Incorporated.\n"
295 "#include \"psdrv.h\"\n", f);
299 * Write the array of GLYPHNAME structures (also populates indexes)
302 static void write_glyph_names(FILE *f)
304 int i, num_names = 0, index = 0;
306 for (i = 0; i < num_glyphs; ++i)
307 if (i == 0 || strcmp(glyphs[i - 1].name, glyphs[i].name) != 0)
311 " * Every glyph name in the AGL and the 39 core PostScript fonts\n"
315 fprintf(f, "const INT PSDRV_AGLGlyphNamesSize = %i;\n\n", num_names);
317 fprintf(f, "GLYPHNAME PSDRV_AGLGlyphNames[%i] =\n{\n", num_names);
319 for (i = 0; i < num_glyphs - 1; ++i)
323 if (i == 0 || strcmp(glyphs[i - 1].name, glyphs[i].name) != 0)
325 cp = fprintf(f, " { -1, \"%s\" },", glyphs[i].name);
326 glyphs[i].index = index;
331 glyphs[i].index = index - 1;
336 fprintf(f, "/* %s */\n", glyphs[i].comment);
339 glyphs[i].index = index;
340 fcpto(f, 36, fprintf(f, " { -1, \"%s\" }", glyphs[i].name));
341 fprintf(f, "/* %s */\n};\n", glyphs[i].comment);
346 * Write the AGL encoding vector
349 static void write_encoding(FILE *f)
353 for (i = 0; i < num_glyphs; ++i)
354 if (glyphs[i].UV != -1)
355 ++size; /* better be 1051! */
360 " * The AGL encoding vector, sorted by Unicode value\n"
364 fprintf(f, "static const UNICODEGLYPH encoding[%i] = \n{\n", size);
366 for (i = 0; i < num_glyphs - 1; ++i)
368 if (glyphs[i].UV == -1)
371 fprintf(f, " { 0x%.4x, PSDRV_AGLGlyphNames + %4i },\t/* %s */\n",
372 glyphs[i].UV, glyphs[i].index, glyphs[i].name);
375 fprintf(f, " { 0x%.4x, PSDRV_AGLGlyphNames + %4i }\t/* %s */\n};\n\n",
376 glyphs[i].UV, glyphs[i].index, glyphs[i].name);
378 fprintf(f, "UNICODEVECTOR PSDRV_AdobeGlyphList = { %i, encoding };\n",
387 int main(int argc, char *argv[])
400 f = fopen(argv[1], "w");
403 fprintf(stderr, "Error opening %s for writing\n", argv[1]);
410 write_glyph_names(f);