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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <sys/types.h>
30 * The array of glyph information
36 int index
; /* in PSDRV_AGLGlyphNames */
42 static GLYPHINFO glyphs
[1500];
43 static int num_glyphs
= 0;
47 * Functions to search and sort the array
50 static int cmp_by_UV(const void *a
, const void *b
)
52 return ((const GLYPHINFO
*)a
)->UV
- ((const GLYPHINFO
*)b
)->UV
;
55 static int cmp_by_name(const void *a
, const void *b
)
57 return strcmp(((const GLYPHINFO
*)a
)->name
, ((const GLYPHINFO
*)b
)->name
);
60 static inline void sort_by_UV(void)
62 qsort(glyphs
, num_glyphs
, sizeof(GLYPHINFO
), cmp_by_UV
);
65 static inline void sort_by_name(void)
67 qsort(glyphs
, num_glyphs
, sizeof(GLYPHINFO
), cmp_by_name
);
70 static inline GLYPHINFO
*search_by_name(const char *name
)
76 return (GLYPHINFO
*)bsearch(&gi
, glyphs
, num_glyphs
, sizeof(GLYPHINFO
),
82 * Use the 'optimal' combination of tabs and spaces to position the cursor
85 static inline void fcpto(FILE *f
, int newpos
, int curpos
)
87 int newtpos
= newpos
& ~7;
88 int curtpos
= curpos
& ~7;
90 while (curtpos
< newtpos
)
97 while (curpos
< newpos
)
105 * Make main() look "purty"
108 static inline void triple_space(FILE *f
)
110 fputc('\n', f
); fputc('\n', f
);
115 * Read the Adobe Glyph List from 'glyphlist.txt'
118 static void read_agl(void)
120 FILE *f
= fopen("glyphlist.txt", "r");
121 char linebuf
[256], namebuf
[128], commbuf
[128];
125 fprintf(stderr
, "Error opening glyphlist.txt\n");
129 while (fgets(linebuf
, sizeof(linebuf
), f
) != NULL
)
133 if (linebuf
[0] == '#')
136 sscanf(linebuf
, "%X;%[^;];%[^\n]", &UV
, namebuf
, commbuf
);
138 glyphs
[num_glyphs
].UV
= (int)UV
;
139 glyphs
[num_glyphs
].name
= strdup(namebuf
);
140 glyphs
[num_glyphs
].comment
= strdup(commbuf
);
142 if (glyphs
[num_glyphs
].name
== NULL
||
143 glyphs
[num_glyphs
].comment
== NULL
)
145 fprintf(stderr
, "Memory allocation failure\n");
154 if (num_glyphs
!= 1051)
156 fprintf(stderr
, "Read %i glyphs\n", num_glyphs
);
163 * Read glyph names from all AFM files in current directory
166 static void read_afms(FILE *f_c
, FILE *f_h
)
168 DIR *d
= opendir(".");
172 " * Built-in font metrics\n"
175 "const AFM *const PSDRV_BuiltinAFMs[] =\n"
181 fprintf(stderr
, "Error opening current directory\n");
185 while ((de
= readdir(d
)) != NULL
)
188 char *cp
, linebuf
[256], font_family
[128];
191 cp
= strrchr(de
->d_name
, '.'); /* Does it end in */
192 if (cp
== NULL
|| stricmp(cp
, ".afm") != 0) /* .afm or .AFM? */
195 f
= fopen(de
->d_name
, "r");
198 fprintf(stderr
, "Error opening %s\n", de
->d_name
);
204 if (fgets(linebuf
, sizeof(linebuf
), f
) == NULL
)
206 fprintf(stderr
, "FontName not found in %s\n", de
->d_name
);
210 if (strncmp(linebuf
, "FontName ", 9) == 0)
214 sscanf(linebuf
, "FontName %[^\r\n]", font_family
);
216 for (i
= 0; font_family
[i
] != '\0'; ++i
)
217 if (font_family
[i
] == '-')
218 font_family
[i
] = '_';
220 fprintf(f_h
, "DECLSPEC_HIDDEN extern const AFM PSDRV_%s;\n", font_family
);
221 fprintf(f_c
, " &PSDRV_%s,\n", font_family
);
225 if (fgets(linebuf
, sizeof(linebuf
), f
) == NULL
)
227 fprintf(stderr
, "FamilyName not found in %s\n", de
->d_name
);
231 if (strncmp(linebuf
, "FamilyName ", 11) == 0)
235 sscanf(linebuf
, "FamilyName %[^\r\n]", font_family
);
239 if (fgets(linebuf
, sizeof(linebuf
), f
) == NULL
)
241 fprintf(stderr
, "StartCharMetrics not found in %s\n",
246 if (strncmp(linebuf
, "StartCharMetrics ", 17) == 0)
250 sscanf(linebuf
, "StartCharMetrics %i", &num_metrics
);
252 for (i
= 0; i
< num_metrics
; ++i
)
256 if (fgets(linebuf
, sizeof(linebuf
), f
) == NULL
)
258 fprintf(stderr
, "Unexpected EOF after %i glyphs in %s\n", i
,
263 cp
= strchr(linebuf
, 'N');
264 if (cp
== NULL
|| strlen(cp
) < 3)
266 fprintf(stderr
, "Parse error after %i glyphs in %s\n", i
,
271 sscanf(cp
, "N %s", namebuf
);
272 if (search_by_name(namebuf
) != NULL
)
275 sprintf(linebuf
, "FONT FAMILY;%s", font_family
);
277 glyphs
[num_glyphs
].UV
= -1;
278 glyphs
[num_glyphs
].name
= strdup(namebuf
);
279 glyphs
[num_glyphs
].comment
= strdup(linebuf
);
281 if (glyphs
[num_glyphs
].name
== NULL
||
282 glyphs
[num_glyphs
].comment
== NULL
)
284 fprintf(stderr
, "Memory allocation failure\n");
298 fputs(" NULL\n};\n", f_c
);
303 * Write opening comments, etc.
306 static void write_header(FILE *f
)
311 for (i
= 0; i
< 79; ++i
)
315 " *\tFont and glyph data for the Wine PostScript driver\n"
317 " *\tCopyright 2001 Ian Pilcher\n"
320 " *\tThis data is derived from the Adobe Glyph list at\n"
323 "http://partners.adobe.com/asn/developer/type/glyphlist.txt\n"
325 " *\tand the Adobe Font Metrics files at\n"
328 "ftp://ftp.adobe.com/pub/adobe/type/win/all/afmfiles/base35/\n"
330 " *\twhich are Copyright 1985-1998 Adobe Systems Incorporated.\n"
334 "#include \"psdrv.h\"\n"
335 "#include \"data/agl.h\"\n", f
);
339 * Write the array of glyph names (also populates indexes)
342 static void write_glyph_names(FILE *f_c
, FILE *f_h
)
344 int i
, num_names
= 0, index
= 0;
346 for (i
= 0; i
< num_glyphs
; ++i
)
347 if (i
== 0 || strcmp(glyphs
[i
- 1].name
, glyphs
[i
].name
) != 0)
351 " * Every glyph name in the AGL and the 35 core PostScript fonts\n"
355 fprintf(f_c
, "const INT PSDRV_AGLGlyphNamesSize = %i;\n\n", num_names
);
357 fprintf(f_c
, "GLYPHNAME PSDRV_AGLGlyphNames[%i] =\n{\n", num_names
);
359 for (i
= 0; i
< num_glyphs
- 1; ++i
)
363 if (i
== 0 || strcmp(glyphs
[i
- 1].name
, glyphs
[i
].name
) != 0)
365 fcpto(f_h
, 32, fprintf(f_h
, "#define GN_%s", glyphs
[i
].name
));
366 fprintf(f_h
, "(PSDRV_AGLGlyphNames + %i)\n", index
);
368 cp
= fprintf(f_c
, " { %4i, \"%s\" },", index
, glyphs
[i
].name
);
369 glyphs
[i
].index
= index
;
374 glyphs
[i
].index
= glyphs
[i
- 1].index
;
379 fprintf(f_c
, "/* %s */\n", glyphs
[i
].comment
);
382 fcpto(f_h
, 32, fprintf(f_h
, "#define GN_%s", glyphs
[i
].name
));
383 fprintf(f_h
, "(PSDRV_AGLGlyphNames + %i)\n", index
);
385 glyphs
[i
].index
= index
;
386 fcpto(f_c
, 40, fprintf(f_c
, " { %4i, \"%s\" }", index
, glyphs
[i
].name
));
387 fprintf(f_c
, "/* %s */\n};\n", glyphs
[i
].comment
);
392 * Write the AGL encoding vector, sorted by glyph name
395 static void write_encoding_by_name(FILE *f
)
397 int i
, size
= 0, even
= 1;
399 for (i
= 0; i
< num_glyphs
; ++i
)
400 if (glyphs
[i
].UV
!= -1 &&
401 (i
== 0 || strcmp(glyphs
[i
- 1].name
, glyphs
[i
].name
) != 0))
402 ++size
; /* should be 1039 */
405 " * The AGL encoding vector, sorted by glyph name - "
406 "duplicates omitted\n"
410 fprintf(f
, "const INT PSDRV_AGLbyNameSize = %i;\n\n", size
);
411 fprintf(f
, "const UNICODEGLYPH PSDRV_AGLbyName[%i] =\n{\n", size
);
413 for (i
= 0; i
< num_glyphs
- 1; ++i
)
417 if (glyphs
[i
].UV
== -1)
420 if (i
!= 0 && strcmp(glyphs
[i
- 1].name
, glyphs
[i
].name
) == 0)
423 cp
= fprintf(f
, " { 0x%.4x, GN_%s },", glyphs
[i
].UV
, glyphs
[i
].name
);
432 fprintf(f
, " { 0x%.4x, GN_%s }\n};\n", glyphs
[i
].UV
, glyphs
[i
].name
);
436 * Write the AGL encoding vector, sorted by Unicode value
439 static void write_encoding_by_UV(FILE *f
)
441 int i
, size
= 0, even
= 1;
443 for (i
= 0; i
< num_glyphs
; ++i
)
444 if (glyphs
[i
].UV
!= -1)
445 ++size
; /* better be 1051! */
450 " * The AGL encoding vector, sorted by Unicode value - "
451 "duplicates included\n"
455 fprintf(f
, "const INT PSDRV_AGLbyUVSize = %i;\n\n", size
);
456 fprintf(f
, "const UNICODEGLYPH PSDRV_AGLbyUV[%i] =\n{\n", size
);
458 for (i
= 0; i
< num_glyphs
- 1; ++i
)
462 if (glyphs
[i
].UV
== -1)
465 cp
= fprintf(f
, " { 0x%.4x, GN_%s },", glyphs
[i
].UV
, glyphs
[i
].name
);
474 fprintf(f
, " { 0x%.4x, GN_%s }\n};\n", glyphs
[i
].UV
, glyphs
[i
].name
);
482 int main(int argc
, char *argv
[])
488 fprintf(stderr
, "Usage: %s <C file> <header file>\n", argv
[0]);
492 f_c
= fopen(argv
[1], "w");
495 fprintf(stderr
, "Error opening %s for writing\n", argv
[1]);
499 f_h
= fopen(argv
[2], "w");
502 fprintf(stderr
, "Error opening %s for writing\n", argv
[2]);
509 read_afms(f_c
, f_h
); /* also writes font list */
511 write_glyph_names(f_c
, f_h
);
513 write_encoding_by_name(f_c
);
515 write_encoding_by_UV(f_c
);