Lay down the infrastructure for gdi font rendering.
[wine] / dlls / wineps / afm2c.c
1 /*******************************************************************************
2  *
3  *  Function to write WINEPS AFM data structures as C
4  *
5  *  Copyright 2001 Ian Pilcher
6  *
7  *
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.
13  *
14  *  To use this function, do the following:
15  *
16  *      *  Edit dlls/wineps/Makefile (or dlls/wineps/Makefile.in) and add
17  *         afm2c.c as a source file.
18  *
19  *      *  Edit dlls/wineps/afm.c and uncomment the call to PSDRV_AFM2C in
20  *         PSDRV_DumpFontList() (or wherever it gets moved).  The resulting
21  *         compiler warning can be safely ignored.
22  *
23  *  IMPORTANT:  For this to work, all glyph names in the AFM data being
24  *      written *MUST* already be present in PSDRV_AGLGlyphNames in agl.c.
25  *      See mkagl.c in this directory for information on how to generate
26  *      updated glyph name information.  Note, however, that if the glyph
27  *      name information in agl.c is regenerated, *ALL* AFM data must also
28  *      be recreated.
29  *
30  */
31
32 #include <string.h>
33 #include <stdio.h>
34 #include <math.h>
35
36 #include "debugtools.h"
37 #include "psdrv.h"
38
39 DEFAULT_DEBUG_CHANNEL(psdrv);
40
41 inline static void cursorto(FILE *of, int np, int cp)
42 {
43     int ntp = np & 0xfffffff8;
44     int ctp = cp & 0xfffffff8;
45     
46     while (ctp < ntp)
47     {
48         fputc('\t', of);
49         ctp += 8;
50         cp = ctp;
51     }
52     
53     while (cp < np)
54     {
55         fputc(' ', of);
56         ++cp;
57     }
58 }
59
60 static void writeHeader(FILE *of, const AFM *afm, const char *buffer)
61 {
62     int i;
63     
64     fputc('/', of);
65     for (i = 1; i < 80; ++i)
66         fputc('*', of);
67     fprintf(of, "\n"
68                 " *\n"
69                 " *\tFont metric data for %s\n"
70                 " *\n"
71                 " *\tCopyright 2001 Ian Pilcher\n"
72                 " *\n"
73                 " *\n"
74                 " *\tSee dlls/wineps/data/COPYRIGHTS for font copyright "
75                         "information.\n"
76                 " *\n"
77                 " */\n"
78                 "\n"
79                 "#include \"psdrv.h\"\n"
80                 "#include \"data/agl.h\"\n", afm->FullName);
81 }
82
83 static void writeMetrics(FILE *of, const AFM *afm, const char *buffer)
84 {
85     int i;
86     
87     fputs("\n\n/*\n *  Glyph metrics\n */\n\n", of);
88     
89     fprintf(of, "static const AFMMETRICS metrics[%i] = \n{\n",
90             afm->NumofMetrics);
91             
92     for (i = 0; i < afm->NumofMetrics - 1; ++i)
93     {
94         fprintf(of, "    { %3i, 0x%.4lx, %4g, GN_%s },\n", afm->Metrics[i].C,
95                 afm->Metrics[i].UV, afm->Metrics[i].WX, afm->Metrics[i].N->sz);
96     }
97     
98     fprintf(of, "    { %3i, 0x%.4lx, %4g, GN_%s }\n};\n", afm->Metrics[i].C,
99             afm->Metrics[i].UV, afm->Metrics[i].WX, afm->Metrics[i].N->sz);
100 }
101
102 static void writeAFM(FILE *of, const AFM *afm, const char *buffer)
103 {
104     fputs("\n\n/*\n *  Font metrics\n */\n\n", of);
105
106     fprintf(of, "const AFM PSDRV_%s =\n{\n", buffer);
107     cursorto(of, 44, fprintf(of, "    \"%s\",", afm->FontName));
108     fputs("/* FontName */\n", of);
109     cursorto(of, 44, fprintf(of, "    \"%s\",", afm->FullName));
110     fputs("/* FullName */\n", of);
111     cursorto(of, 44, fprintf(of, "    \"%s\",", afm->FamilyName));
112     fputs("/* FamilyName */\n", of);
113     cursorto(of, 44, fprintf(of, "    \"%s\",", afm->EncodingScheme));
114     fputs("/* EncodingScheme */\n", of);
115     cursorto(of, 44, fprintf(of, "    %s,",
116             (afm->Weight > 550) ? "FW_BOLD" : "FW_NORMAL"));
117     fputs("/* Weight */\n", of);
118     cursorto(of, 44, fprintf(of, "    %g,", afm->ItalicAngle));
119     fputs("/* ItalicAngle */\n", of);
120     cursorto(of, 44, fprintf(of, "    %s,",
121             afm->IsFixedPitch ? "TRUE" : "FALSE"));
122     fputs("/* IsFixedPitch */\n", of);
123     cursorto(of, 44, fprintf(of, "    %g,", afm->UnderlinePosition));
124     fputs("/* UnderlinePosition */\n", of);
125     cursorto(of, 44, fprintf(of, "    %g,", afm->UnderlineThickness));
126     fputs("/* UnderlineThickness */\n", of);
127     cursorto(of, 44, fprintf(of, "    { %g, %g, %g, %g },", afm->FontBBox.llx,
128             afm->FontBBox.lly, afm->FontBBox.urx, afm->FontBBox.ury));
129     fputs("/* FontBBox */\n", of);
130     cursorto(of, 44, fprintf(of, "    %g,", afm->Ascender));
131     fputs("/* Ascender */\n", of);
132     cursorto(of, 44, fprintf(of, "    %g,", afm->Descender));
133     fputs("/* Descender */\n", of);
134     fputs("    {\n", of);
135     cursorto(of, 44, 7 + fprintf(of, "\t%u,",
136             (unsigned int)(afm->WinMetrics.usUnitsPerEm)));
137     fputs("/* WinMetrics.usUnitsPerEm */\n", of);
138     cursorto(of, 44, 7 + fprintf(of, "\t%i,",
139             (int)(afm->WinMetrics.sAscender)));
140     fputs("/* WinMetrics.sAscender */\n", of);
141     cursorto(of, 44, 7 + fprintf(of, "\t%i,",
142             (int)(afm->WinMetrics.sDescender)));
143     fputs("/* WinMetrics.sDescender */\n", of);
144     cursorto(of, 44, 7 + fprintf(of, "\t%i,",
145             (int)(afm->WinMetrics.sLineGap)));
146     fputs("/* WinMetrics.sLineGap */\n", of);
147     cursorto(of, 44, 7 + fprintf(of, "\t%i,",
148             (int)(afm->WinMetrics.sAvgCharWidth)));
149     fputs("/* WinMetrics.sAvgCharWidth */\n", of);
150     cursorto(of, 44, 7 + fprintf(of, "\t%i,",
151             (int)(afm->WinMetrics.sTypoAscender)));
152     fputs("/* WinMetrics.sTypoAscender */\n", of);
153     cursorto(of, 44, 7 + fprintf(of, "\t%i,",
154             (int)(afm->WinMetrics.sTypoDescender)));
155     fputs("/* WinMetrics.sTypoDescender */\n", of);
156     cursorto(of, 44, 7 + fprintf(of, "\t%i,",
157             (int)(afm->WinMetrics.sTypoLineGap)));
158     fputs("/* WinMetrics.sTypoLineGap */\n", of);
159     cursorto(of, 44, 7 + fprintf(of, "\t%u,",
160             (unsigned int)(afm->WinMetrics.usWinAscent)));
161     fputs("/* WinMetrics.usWinAscent */\n", of);
162     cursorto(of, 44, 7 + fprintf(of, "\t%u",
163             (unsigned int)(afm->WinMetrics.usWinDescent)));
164     fputs("/* WinMetrics.usWinDescent */\n",of);
165     fputs("    },\n", of);
166     cursorto(of, 44, fprintf(of, "    %i,", afm->NumofMetrics));
167     fputs("/* NumofMetrics */\n", of);
168     fputs("    metrics\t\t\t\t    /* Metrics */\n};\n", of);
169 }
170
171 void PSDRV_AFM2C(const AFM *afm)
172 {
173     char    buffer[256];
174     FILE    *of;
175     int     i;
176     
177     strncpy(buffer, afm->FontName, sizeof(buffer) - 3);
178     buffer[sizeof(buffer) - 3] = '\0';
179     
180     for (i = 0; i < strlen(buffer); ++i)
181         if (buffer[i] == '-')
182             buffer[i] = '_';
183             
184     buffer[i] = '.';  buffer[i + 1] = 'c';  buffer[i + 2] = '\0';
185
186     MESSAGE("writing '%s'\n", buffer);
187     
188     of = fopen(buffer, "w");
189     if (of == NULL)
190     {
191         ERR("error opening '%s' for writing\n", buffer);
192         return;
193     }
194     
195     buffer[i] = '\0';
196     
197     writeHeader(of, afm, buffer);
198     writeMetrics(of, afm, buffer);
199     writeAFM(of, afm, buffer);
200     
201     fclose(of);
202 }