blob: 10de740d8cfc8a41117112bd2840b1136574e79c [file] [log] [blame]
Ian Pilcher55d2e572001-05-29 22:06:10 +00001/*******************************************************************************
2 *
3 * Function to write WINEPS AFM data structures as C
4 *
5 * Copyright 2001 Ian Pilcher
6 *
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00007 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * NOTES:
Ian Pilcher55d2e572001-05-29 22:06:10 +000022 *
23 * PSDRV_AFM2C(AFM *afm) writes the AFM data structure addressed by afm (and
24 * its subsidiary objects) as a C file which can which can then be built in to
25 * the driver. It creates the file in the current directory with a name of
26 * the form {FontName}.c, where {FontName} is the PostScript font name with
27 * hyphens replaced by underscores.
28 *
29 * To use this function, do the following:
30 *
Ian Pilcher55d2e572001-05-29 22:06:10 +000031 * * Edit dlls/wineps/Makefile (or dlls/wineps/Makefile.in) and add
32 * afm2c.c as a source file.
33 *
34 * * Edit dlls/wineps/afm.c and uncomment the call to PSDRV_AFM2C in
Ian Pilcher25765132001-08-15 17:41:37 +000035 * PSDRV_DumpFontList() (or wherever it gets moved). The resulting
Ian Pilcher55d2e572001-05-29 22:06:10 +000036 * compiler warning can be safely ignored.
37 *
38 * IMPORTANT: For this to work, all glyph names in the AFM data being
39 * written *MUST* already be present in PSDRV_AGLGlyphNames in agl.c.
40 * See mkagl.c in this directory for information on how to generate
41 * updated glyph name information. Note, however, that if the glyph
42 * name information in agl.c is regenerated, *ALL* AFM data must also
43 * be recreated.
44 *
45 */
46
47#include <string.h>
48#include <stdio.h>
49#include <math.h>
50
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000051#include "wine/debug.h"
Ian Pilcher55d2e572001-05-29 22:06:10 +000052#include "psdrv.h"
53
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000054WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
Ian Pilcher55d2e572001-05-29 22:06:10 +000055
56inline static void cursorto(FILE *of, int np, int cp)
57{
58 int ntp = np & 0xfffffff8;
59 int ctp = cp & 0xfffffff8;
Vincent Béron9a624912002-05-31 23:06:46 +000060
Ian Pilcher55d2e572001-05-29 22:06:10 +000061 while (ctp < ntp)
62 {
63 fputc('\t', of);
64 ctp += 8;
65 cp = ctp;
66 }
Vincent Béron9a624912002-05-31 23:06:46 +000067
Ian Pilcher55d2e572001-05-29 22:06:10 +000068 while (cp < np)
69 {
70 fputc(' ', of);
71 ++cp;
72 }
73}
74
Ian Pilcher25765132001-08-15 17:41:37 +000075static void writeHeader(FILE *of, const AFM *afm, const char *buffer)
Ian Pilcher55d2e572001-05-29 22:06:10 +000076{
77 int i;
Vincent Béron9a624912002-05-31 23:06:46 +000078
Ian Pilcher55d2e572001-05-29 22:06:10 +000079 fputc('/', of);
80 for (i = 1; i < 80; ++i)
81 fputc('*', of);
82 fprintf(of, "\n"
83 " *\n"
84 " *\tFont metric data for %s\n"
85 " *\n"
86 " *\tCopyright 2001 Ian Pilcher\n"
87 " *\n"
88 " *\n"
Ian Pilcher25765132001-08-15 17:41:37 +000089 " *\tSee dlls/wineps/data/COPYRIGHTS for font copyright "
90 "information.\n"
Ian Pilcher55d2e572001-05-29 22:06:10 +000091 " *\n"
92 " */\n"
93 "\n"
Ian Pilcher25765132001-08-15 17:41:37 +000094 "#include \"psdrv.h\"\n"
95 "#include \"data/agl.h\"\n", afm->FullName);
Ian Pilcher55d2e572001-05-29 22:06:10 +000096}
97
Ian Pilcher25765132001-08-15 17:41:37 +000098static void writeMetrics(FILE *of, const AFM *afm, const char *buffer)
Ian Pilcher55d2e572001-05-29 22:06:10 +000099{
100 int i;
Vincent Béron9a624912002-05-31 23:06:46 +0000101
Ian Pilcher55d2e572001-05-29 22:06:10 +0000102 fputs("\n\n/*\n * Glyph metrics\n */\n\n", of);
Vincent Béron9a624912002-05-31 23:06:46 +0000103
104 fprintf(of, "static const AFMMETRICS metrics[%i] =\n{\n",
Ian Pilcher55d2e572001-05-29 22:06:10 +0000105 afm->NumofMetrics);
Vincent Béron9a624912002-05-31 23:06:46 +0000106
Ian Pilcher55d2e572001-05-29 22:06:10 +0000107 for (i = 0; i < afm->NumofMetrics - 1; ++i)
108 {
Ian Pilcher25765132001-08-15 17:41:37 +0000109 fprintf(of, " { %3i, 0x%.4lx, %4g, GN_%s },\n", afm->Metrics[i].C,
110 afm->Metrics[i].UV, afm->Metrics[i].WX, afm->Metrics[i].N->sz);
Ian Pilcher55d2e572001-05-29 22:06:10 +0000111 }
Vincent Béron9a624912002-05-31 23:06:46 +0000112
Ian Pilcher25765132001-08-15 17:41:37 +0000113 fprintf(of, " { %3i, 0x%.4lx, %4g, GN_%s }\n};\n", afm->Metrics[i].C,
114 afm->Metrics[i].UV, afm->Metrics[i].WX, afm->Metrics[i].N->sz);
Ian Pilcher55d2e572001-05-29 22:06:10 +0000115}
116
Ian Pilcher25765132001-08-15 17:41:37 +0000117static void writeAFM(FILE *of, const AFM *afm, const char *buffer)
Ian Pilcher55d2e572001-05-29 22:06:10 +0000118{
119 fputs("\n\n/*\n * Font metrics\n */\n\n", of);
120
Ian Pilcher25765132001-08-15 17:41:37 +0000121 fprintf(of, "const AFM PSDRV_%s =\n{\n", buffer);
122 cursorto(of, 44, fprintf(of, " \"%s\",", afm->FontName));
Ian Pilcher55d2e572001-05-29 22:06:10 +0000123 fputs("/* FontName */\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000124 cursorto(of, 44, fprintf(of, " \"%s\",", afm->FullName));
Ian Pilcher55d2e572001-05-29 22:06:10 +0000125 fputs("/* FullName */\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000126 cursorto(of, 44, fprintf(of, " \"%s\",", afm->FamilyName));
Ian Pilcher55d2e572001-05-29 22:06:10 +0000127 fputs("/* FamilyName */\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000128 cursorto(of, 44, fprintf(of, " \"%s\",", afm->EncodingScheme));
Ian Pilcher55d2e572001-05-29 22:06:10 +0000129 fputs("/* EncodingScheme */\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000130 cursorto(of, 44, fprintf(of, " %s,",
131 (afm->Weight > 550) ? "FW_BOLD" : "FW_NORMAL"));
Ian Pilcher55d2e572001-05-29 22:06:10 +0000132 fputs("/* Weight */\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000133 cursorto(of, 44, fprintf(of, " %g,", afm->ItalicAngle));
Ian Pilcher55d2e572001-05-29 22:06:10 +0000134 fputs("/* ItalicAngle */\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000135 cursorto(of, 44, fprintf(of, " %s,",
Ian Pilcher55d2e572001-05-29 22:06:10 +0000136 afm->IsFixedPitch ? "TRUE" : "FALSE"));
137 fputs("/* IsFixedPitch */\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000138 cursorto(of, 44, fprintf(of, " %g,", afm->UnderlinePosition));
Ian Pilcher55d2e572001-05-29 22:06:10 +0000139 fputs("/* UnderlinePosition */\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000140 cursorto(of, 44, fprintf(of, " %g,", afm->UnderlineThickness));
Ian Pilcher55d2e572001-05-29 22:06:10 +0000141 fputs("/* UnderlineThickness */\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000142 cursorto(of, 44, fprintf(of, " { %g, %g, %g, %g },", afm->FontBBox.llx,
Ian Pilcher55d2e572001-05-29 22:06:10 +0000143 afm->FontBBox.lly, afm->FontBBox.urx, afm->FontBBox.ury));
144 fputs("/* FontBBox */\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000145 cursorto(of, 44, fprintf(of, " %g,", afm->Ascender));
Ian Pilcher55d2e572001-05-29 22:06:10 +0000146 fputs("/* Ascender */\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000147 cursorto(of, 44, fprintf(of, " %g,", afm->Descender));
Ian Pilcher55d2e572001-05-29 22:06:10 +0000148 fputs("/* Descender */\n", of);
Ian Pilcher55d2e572001-05-29 22:06:10 +0000149 fputs(" {\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000150 cursorto(of, 44, 7 + fprintf(of, "\t%u,",
Ian Pilcher55d2e572001-05-29 22:06:10 +0000151 (unsigned int)(afm->WinMetrics.usUnitsPerEm)));
152 fputs("/* WinMetrics.usUnitsPerEm */\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000153 cursorto(of, 44, 7 + fprintf(of, "\t%i,",
Ian Pilcher55d2e572001-05-29 22:06:10 +0000154 (int)(afm->WinMetrics.sAscender)));
155 fputs("/* WinMetrics.sAscender */\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000156 cursorto(of, 44, 7 + fprintf(of, "\t%i,",
Ian Pilcher55d2e572001-05-29 22:06:10 +0000157 (int)(afm->WinMetrics.sDescender)));
158 fputs("/* WinMetrics.sDescender */\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000159 cursorto(of, 44, 7 + fprintf(of, "\t%i,",
Ian Pilcher55d2e572001-05-29 22:06:10 +0000160 (int)(afm->WinMetrics.sLineGap)));
161 fputs("/* WinMetrics.sLineGap */\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000162 cursorto(of, 44, 7 + fprintf(of, "\t%i,",
Ian Pilcher55d2e572001-05-29 22:06:10 +0000163 (int)(afm->WinMetrics.sAvgCharWidth)));
164 fputs("/* WinMetrics.sAvgCharWidth */\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000165 cursorto(of, 44, 7 + fprintf(of, "\t%i,",
Ian Pilcher55d2e572001-05-29 22:06:10 +0000166 (int)(afm->WinMetrics.sTypoAscender)));
167 fputs("/* WinMetrics.sTypoAscender */\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000168 cursorto(of, 44, 7 + fprintf(of, "\t%i,",
Ian Pilcher55d2e572001-05-29 22:06:10 +0000169 (int)(afm->WinMetrics.sTypoDescender)));
170 fputs("/* WinMetrics.sTypoDescender */\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000171 cursorto(of, 44, 7 + fprintf(of, "\t%i,",
Ian Pilcher55d2e572001-05-29 22:06:10 +0000172 (int)(afm->WinMetrics.sTypoLineGap)));
173 fputs("/* WinMetrics.sTypoLineGap */\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000174 cursorto(of, 44, 7 + fprintf(of, "\t%u,",
Ian Pilcher55d2e572001-05-29 22:06:10 +0000175 (unsigned int)(afm->WinMetrics.usWinAscent)));
176 fputs("/* WinMetrics.usWinAscent */\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000177 cursorto(of, 44, 7 + fprintf(of, "\t%u",
Ian Pilcher55d2e572001-05-29 22:06:10 +0000178 (unsigned int)(afm->WinMetrics.usWinDescent)));
179 fputs("/* WinMetrics.usWinDescent */\n",of);
Ian Pilcher25765132001-08-15 17:41:37 +0000180 fputs(" },\n", of);
181 cursorto(of, 44, fprintf(of, " %i,", afm->NumofMetrics));
Ian Pilcher55d2e572001-05-29 22:06:10 +0000182 fputs("/* NumofMetrics */\n", of);
Ian Pilcher25765132001-08-15 17:41:37 +0000183 fputs(" metrics\t\t\t\t /* Metrics */\n};\n", of);
Ian Pilcher55d2e572001-05-29 22:06:10 +0000184}
185
Ian Pilcher25765132001-08-15 17:41:37 +0000186void PSDRV_AFM2C(const AFM *afm)
Ian Pilcher55d2e572001-05-29 22:06:10 +0000187{
188 char buffer[256];
189 FILE *of;
190 int i;
Vincent Béron9a624912002-05-31 23:06:46 +0000191
Ian Pilcher55d2e572001-05-29 22:06:10 +0000192 strncpy(buffer, afm->FontName, sizeof(buffer) - 3);
193 buffer[sizeof(buffer) - 3] = '\0';
Vincent Béron9a624912002-05-31 23:06:46 +0000194
Ian Pilcher55d2e572001-05-29 22:06:10 +0000195 for (i = 0; i < strlen(buffer); ++i)
196 if (buffer[i] == '-')
197 buffer[i] = '_';
Vincent Béron9a624912002-05-31 23:06:46 +0000198
Ian Pilcher55d2e572001-05-29 22:06:10 +0000199 buffer[i] = '.'; buffer[i + 1] = 'c'; buffer[i + 2] = '\0';
200
201 MESSAGE("writing '%s'\n", buffer);
Vincent Béron9a624912002-05-31 23:06:46 +0000202
Ian Pilcher55d2e572001-05-29 22:06:10 +0000203 of = fopen(buffer, "w");
204 if (of == NULL)
205 {
206 ERR("error opening '%s' for writing\n", buffer);
207 return;
208 }
Vincent Béron9a624912002-05-31 23:06:46 +0000209
Ian Pilcher55d2e572001-05-29 22:06:10 +0000210 buffer[i] = '\0';
Vincent Béron9a624912002-05-31 23:06:46 +0000211
Ian Pilcher55d2e572001-05-29 22:06:10 +0000212 writeHeader(of, afm, buffer);
Ian Pilcher55d2e572001-05-29 22:06:10 +0000213 writeMetrics(of, afm, buffer);
214 writeAFM(of, afm, buffer);
Vincent Béron9a624912002-05-31 23:06:46 +0000215
Ian Pilcher55d2e572001-05-29 22:06:10 +0000216 fclose(of);
217}