1 /*******************************************************************************
3 * Function to write WINEPS AFM data structures as C
5 * Copyright 2001 Ian Pilcher
8 * PSDRV_AFM2C(AFM *afm) writes the AFM data structure addressed by afm (and
9 * its subsidiary objects) as a C file which can which can then be built in to
10 * the driver. It creates the file in the current directory with a name of
11 * the form {FontName}.c, where {FontName} is the PostScript font name with
12 * hyphens replaced by underscores.
14 * To use this function, do the following:
16 * * Move this file to the dlls/wineps directory.
18 * * Edit dlls/wineps/Makefile (or dlls/wineps/Makefile.in) and add
19 * afm2c.c as a source file.
21 * * Edit dlls/wineps/afm.c and uncomment the call to PSDRV_AFM2C in
22 * CalcWindowsMetrics() (or wherever it gets moved). The resulting
23 * compiler warning can be safely ignored.
25 * IMPORTANT: For this to work, all glyph names in the AFM data being
26 * written *MUST* already be present in PSDRV_AGLGlyphNames in agl.c.
27 * See mkagl.c in this directory for information on how to generate
28 * updated glyph name information. Note, however, that if the glyph
29 * name information in agl.c is regenerated, *ALL* AFM data must also
38 #include "debugtools.h"
41 DEFAULT_DEBUG_CHANNEL(psdrv);
43 inline static void cursorto(FILE *of, int np, int cp)
45 int ntp = np & 0xfffffff8;
46 int ctp = cp & 0xfffffff8;
62 static void writeCharWidths(FILE *of, AFM * afm)
64 int i, cp, w, row_start = 0;
66 fputc('\t', of); cp = 8;
68 for (i = 0; i < 255; ++i)
70 if (afm->CharWidths[i] == 0.0)
73 w = (int)log10(afm->CharWidths[i]) + 3;
77 cp += fprintf(of, "%g, ", (double)(afm->CharWidths[i]));
82 fprintf(of, "/* CharWidths[%i] - CharWidths[%i] */\n\t",
90 if (afm->CharWidths[255] == 0.0)
93 w = (int)pow(afm->CharWidths[i], 0.1) + 3;
97 cp += fprintf(of, "%g", (double)(afm->CharWidths[255]));
99 fprintf(of, "/* CharWidths[%i] - CharWidths[255] */\n },\n",
104 cursorto(of, 40, cp);
105 fprintf(of, "/* CharWidths[%i] - CharWidths[254] */\n\t", row_start);
106 cp = 8 + fprintf(of, "%g", (double)(afm->CharWidths[255]));
107 cursorto(of, 40, cp);
108 fputs("/* CharWidths[255] */\n },\n", of);
112 static void writeHeader(FILE *of, AFM *afm, const char *buffer)
117 for (i = 1; i < 80; ++i)
121 " *\tFont metric data for %s\n"
123 " *\tCopyright 2001 Ian Pilcher\n"
126 " *\tThis data is derived from the Adobe Font Metrics files at"
129 " *\t ftp://ftp.adobe.com/pub/adobe/type/win/all/afmfiles/"
132 " *\twhich are Copyright 1985-1992 Adobe Systems Incorporated."
137 "#include \"psdrv.h\"\n", afm->FullName);
140 static void writeEncoding(FILE *of, AFM *afm, const char *buffer)
144 fprintf(of, "\n\n/*\n * %s encoding vector\n */\n", afm->EncodingScheme);
146 fprintf(of, "\nstatic const UNICODEGLYPH ug_%s[%i] =\n{\n", buffer,
147 afm->Encoding->size);
149 for (i = 0; i < afm->Encoding->size - 1; ++i)
152 fprintf(of, " { 0x%.4lx, PSDRV_AGLGlyphNames + %4i },",
153 afm->Encoding->glyphs[i].UV,
154 afm->Encoding->glyphs[i].name - PSDRV_AGLGlyphNames));
155 fprintf(of, "/* %s */\n", afm->Encoding->glyphs[i].name->sz);
158 cursorto(of, 48, fprintf(of, " { 0x%.4lx, PSDRV_AGLGlyphNames + %4i }",
159 afm->Encoding->glyphs[i].UV,
160 afm->Encoding->glyphs[i].name - PSDRV_AGLGlyphNames));
161 fprintf(of, "/* %s */\n};\n\n", afm->Encoding->glyphs[i].name->sz);
163 fprintf(of, "static UNICODEVECTOR enc_%s = { %i, ug_%s };\n", buffer,
164 afm->Encoding->size, buffer);
167 static void writeMetrics(FILE *of, AFM *afm, const char *buffer)
171 fputs("\n\n/*\n * Glyph metrics\n */\n\n", of);
173 fprintf(of, "static AFMMETRICS met_%s[%i] = \n{\n", buffer,
176 for (i = 0; i < afm->NumofMetrics - 1; ++i)
179 fprintf(of, "%3i, 0x%.4lx, %4g, PSDRV_AGLGlyphNames + %4i,\n\t\t",
180 afm->Metrics[i].C, afm->Metrics[i].UV, afm->Metrics[i].WX,
181 afm->Metrics[i].N - PSDRV_AGLGlyphNames);
182 fprintf(of, "{ %4g, %4g, %4g, %4g }, NULL\t/* %s */\n },\n",
183 afm->Metrics[i].B.llx, afm->Metrics[i].B.lly,
184 afm->Metrics[i].B.urx, afm->Metrics[i].B.ury,
185 afm->Metrics[i].N->sz);
189 fprintf(of, "%3i, 0x%.4lx, %4g, PSDRV_AGLGlyphNames + %4i,\n\t\t",
190 afm->Metrics[i].C, afm->Metrics[i].UV, afm->Metrics[i].WX,
191 afm->Metrics[i].N - PSDRV_AGLGlyphNames);
192 fprintf(of, "{ %4g, %4g, %4g, %4g }, NULL\t/* %s */\n }\n};\n",
193 afm->Metrics[i].B.llx, afm->Metrics[i].B.lly,
194 afm->Metrics[i].B.urx, afm->Metrics[i].B.ury,
195 afm->Metrics[i].N->sz);
198 static void writeAFM(FILE *of, AFM *afm, const char *buffer)
200 fputs("\n\n/*\n * Font metrics\n */\n\n", of);
202 fprintf(of, "AFM PSDRV_%s =\n{\n", buffer);
203 cursorto(of, 48, fprintf(of, " \"%s\",", afm->FontName));
204 fputs("/* FontName */\n", of);
205 cursorto(of, 48, fprintf(of, " \"%s\",", afm->FullName));
206 fputs("/* FullName */\n", of);
207 cursorto(of, 48, fprintf(of, " \"%s\",", afm->FamilyName));
208 fputs("/* FamilyName */\n", of);
209 cursorto(of, 48, fprintf(of, " \"%s\",", afm->EncodingScheme));
210 fputs("/* EncodingScheme */\n", of);
211 cursorto(of, 48, fprintf(of, " %li,", afm->Weight));
212 fputs("/* Weight */\n", of);
213 cursorto(of, 48, fprintf(of, " %g,", afm->ItalicAngle));
214 fputs("/* ItalicAngle */\n", of);
215 cursorto(of, 48, fprintf(of, " %s,",
216 afm->IsFixedPitch ? "TRUE" : "FALSE"));
217 fputs("/* IsFixedPitch */\n", of);
218 cursorto(of, 48, fprintf(of, " %g,", afm->UnderlinePosition));
219 fputs("/* UnderlinePosition */\n", of);
220 cursorto(of, 48, fprintf(of, " %g,", afm->UnderlineThickness));
221 fputs("/* UnderlineThickness */\n", of);
222 cursorto(of, 48, fprintf(of, " { %g, %g, %g, %g },", afm->FontBBox.llx,
223 afm->FontBBox.lly, afm->FontBBox.urx, afm->FontBBox.ury));
224 fputs("/* FontBBox */\n", of);
225 cursorto(of, 48, fprintf(of, " %g,", afm->CapHeight));
226 fputs("/* CapHeight */\n", of);
227 cursorto(of, 48, fprintf(of, " %g,", afm->XHeight));
228 fputs("/* XHeight */\n", of);
229 cursorto(of, 48, fprintf(of, " %g,", afm->Ascender));
230 fputs("/* Ascender */\n", of);
231 cursorto(of, 48, fprintf(of, " %g,", afm->Descender));
232 fputs("/* Descender */\n", of);
233 cursorto(of, 48, fprintf(of, " %g,", afm->FullAscender));
234 fputs("/* FullAscender */\n", of);
236 cursorto(of, 40, 7 + fprintf(of, "\t%u,",
237 (unsigned int)(afm->WinMetrics.usUnitsPerEm)));
238 fputs("/* WinMetrics.usUnitsPerEm */\n", of);
239 cursorto(of, 40, 7 + fprintf(of, "\t%i,",
240 (int)(afm->WinMetrics.sAscender)));
241 fputs("/* WinMetrics.sAscender */\n", of);
242 cursorto(of, 40, 7 + fprintf(of, "\t%i,",
243 (int)(afm->WinMetrics.sDescender)));
244 fputs("/* WinMetrics.sDescender */\n", of);
245 cursorto(of, 40, 7 + fprintf(of, "\t%i,",
246 (int)(afm->WinMetrics.sLineGap)));
247 fputs("/* WinMetrics.sLineGap */\n", of);
248 cursorto(of, 40, 7 + fprintf(of, "\t%i,",
249 (int)(afm->WinMetrics.sAvgCharWidth)));
250 fputs("/* WinMetrics.sAvgCharWidth */\n", of);
251 cursorto(of, 40, 7 + fprintf(of, "\t%i,",
252 (int)(afm->WinMetrics.sTypoAscender)));
253 fputs("/* WinMetrics.sTypoAscender */\n", of);
254 cursorto(of, 40, 7 + fprintf(of, "\t%i,",
255 (int)(afm->WinMetrics.sTypoDescender)));
256 fputs("/* WinMetrics.sTypoDescender */\n", of);
257 cursorto(of, 40, 7 + fprintf(of, "\t%i,",
258 (int)(afm->WinMetrics.sTypoLineGap)));
259 fputs("/* WinMetrics.sTypoLineGap */\n", of);
260 cursorto(of, 40, 7 + fprintf(of, "\t%u,",
261 (unsigned int)(afm->WinMetrics.usWinAscent)));
262 fputs("/* WinMetrics.usWinAscent */\n", of);
263 cursorto(of, 40, 7 + fprintf(of, "\t%u",
264 (unsigned int)(afm->WinMetrics.usWinDescent)));
265 fputs("/* WinMetrics.usWinDescent */\n",of);
266 fputs(" },\n {\n", of);
267 writeCharWidths(of, afm);
268 cursorto(of, 48, fprintf(of, " %i,", afm->NumofMetrics));
269 fputs("/* NumofMetrics */\n", of);
270 cursorto(of, 48, fprintf(of, " met_%s,", buffer));
271 fputs("/* Metrics */\n", of);
272 if (afm->Encoding == &PSDRV_AdobeGlyphList)
273 cursorto(of, 48, fprintf(of, " &PSDRV_AdobeGlyphList"));
275 cursorto(of, 48, fprintf(of, " &enc_%s", buffer));
276 fputs("/* Encoding */\n};\n", of);
279 void PSDRV_AFM2C(AFM *afm)
285 strncpy(buffer, afm->FontName, sizeof(buffer) - 3);
286 buffer[sizeof(buffer) - 3] = '\0';
288 for (i = 0; i < strlen(buffer); ++i)
289 if (buffer[i] == '-')
292 buffer[i] = '.'; buffer[i + 1] = 'c'; buffer[i + 2] = '\0';
294 MESSAGE("writing '%s'\n", buffer);
296 of = fopen(buffer, "w");
299 ERR("error opening '%s' for writing\n", buffer);
305 writeHeader(of, afm, buffer);
307 if (afm->Encoding != &PSDRV_AdobeGlyphList)
308 writeEncoding(of, afm, buffer);
310 writeMetrics(of, afm, buffer);
311 writeAFM(of, afm, buffer);