afm2c.c 7.17 KB
Newer Older
1 2 3 4 5 6
/*******************************************************************************
 *
 *  Function to write WINEPS AFM data structures as C
 *
 *  Copyright 2001 Ian Pilcher
 *
7 8 9 10 11 12 13 14 15 16 17 18
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 21
 *
 * NOTES:
22 23 24 25 26 27 28 29 30 31 32 33 34
 *
 *  PSDRV_AFM2C(AFM *afm) writes the AFM data structure addressed by afm (and
 *  its subsidiary objects) as a C file which can which can then be built in to
 *  the driver.  It creates the file in the current directory with a name of
 *  the form {FontName}.c, where {FontName} is the PostScript font name with
 *  hyphens replaced by underscores.
 *
 *  To use this function, do the following:
 *
 *  	*  Edit dlls/wineps/Makefile (or dlls/wineps/Makefile.in) and add
 *  	   afm2c.c as a source file.
 *
 *  	*  Edit dlls/wineps/afm.c and uncomment the call to PSDRV_AFM2C in
35
 *  	   PSDRV_DumpFontList() (or wherever it gets moved).  The resulting
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
 *  	   compiler warning can be safely ignored.
 *
 *  IMPORTANT:  For this to work, all glyph names in the AFM data being
 *  	written *MUST* already be present in PSDRV_AGLGlyphNames in agl.c.
 *  	See mkagl.c in this directory for information on how to generate
 *  	updated glyph name information.  Note, however, that if the glyph
 *  	name information in agl.c is regenerated, *ALL* AFM data must also
 *  	be recreated.
 *
 */

#include <string.h>
#include <stdio.h>
#include <math.h>

51
#include "wine/debug.h"
52 53
#include "psdrv.h"

54
WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
55

56
static inline void cursorto(FILE *of, int np, int cp)
57 58 59
{
    int ntp = np & 0xfffffff8;
    int ctp = cp & 0xfffffff8;
60

61 62 63 64 65 66
    while (ctp < ntp)
    {
    	fputc('\t', of);
	ctp += 8;
	cp = ctp;
    }
67

68 69 70 71 72 73 74
    while (cp < np)
    {
    	fputc(' ', of);
	++cp;
    }
}

75
static void writeHeader(FILE *of, const AFM *afm, const char *buffer)
76 77
{
    int i;
78

79 80 81 82 83 84 85 86 87 88
    fputc('/', of);
    for (i = 1; i < 80; ++i)
    	fputc('*', of);
    fprintf(of, "\n"
    	    	" *\n"
		" *\tFont metric data for %s\n"
		" *\n"
		" *\tCopyright 2001 Ian Pilcher\n"
		" *\n"
		" *\n"
89 90
		" *\tSee dlls/wineps/data/COPYRIGHTS for font copyright "
		    	"information.\n"
91 92 93
		" *\n"
		" */\n"
		"\n"
94 95
		"#include \"psdrv.h\"\n"
		"#include \"data/agl.h\"\n", afm->FullName);
96 97
}

98
static void writeMetrics(FILE *of, const AFM *afm, const char *buffer)
99 100
{
    int i;
101

102
    fputs("\n\n/*\n *  Glyph metrics\n */\n\n", of);
103 104

    fprintf(of, "static const AFMMETRICS metrics[%i] =\n{\n",
105
    	    afm->NumofMetrics);
106

107 108
    for (i = 0; i < afm->NumofMetrics - 1; ++i)
    {
109 110
    	fprintf(of, "    { %3i, 0x%.4lx, %4g, GN_%s },\n", afm->Metrics[i].C,
	    	afm->Metrics[i].UV, afm->Metrics[i].WX, afm->Metrics[i].N->sz);
111
    }
112

113 114
    fprintf(of, "    { %3i, 0x%.4lx, %4g, GN_%s }\n};\n", afm->Metrics[i].C,
    	    afm->Metrics[i].UV, afm->Metrics[i].WX, afm->Metrics[i].N->sz);
115 116
}

117
static void writeAFM(FILE *of, const AFM *afm, const char *buffer)
118 119 120
{
    fputs("\n\n/*\n *  Font metrics\n */\n\n", of);

121 122
    fprintf(of, "const AFM PSDRV_%s =\n{\n", buffer);
    cursorto(of, 44, fprintf(of, "    \"%s\",", afm->FontName));
123
    fputs("/* FontName */\n", of);
124
    cursorto(of, 44, fprintf(of, "    \"%s\",", afm->FullName));
125
    fputs("/* FullName */\n", of);
126
    cursorto(of, 44, fprintf(of, "    \"%s\",", afm->FamilyName));
127
    fputs("/* FamilyName */\n", of);
128
    cursorto(of, 44, fprintf(of, "    \"%s\",", afm->EncodingScheme));
129
    fputs("/* EncodingScheme */\n", of);
130 131
    cursorto(of, 44, fprintf(of, "    %s,",
    	    (afm->Weight > 550) ? "FW_BOLD" : "FW_NORMAL"));
132
    fputs("/* Weight */\n", of);
133
    cursorto(of, 44, fprintf(of, "    %g,", afm->ItalicAngle));
134
    fputs("/* ItalicAngle */\n", of);
135
    cursorto(of, 44, fprintf(of, "    %s,",
136 137
    	    afm->IsFixedPitch ? "TRUE" : "FALSE"));
    fputs("/* IsFixedPitch */\n", of);
138
    cursorto(of, 44, fprintf(of, "    %g,", afm->UnderlinePosition));
139
    fputs("/* UnderlinePosition */\n", of);
140
    cursorto(of, 44, fprintf(of, "    %g,", afm->UnderlineThickness));
141
    fputs("/* UnderlineThickness */\n", of);
142
    cursorto(of, 44, fprintf(of, "    { %g, %g, %g, %g },", afm->FontBBox.llx,
143 144
    	    afm->FontBBox.lly, afm->FontBBox.urx, afm->FontBBox.ury));
    fputs("/* FontBBox */\n", of);
145
    cursorto(of, 44, fprintf(of, "    %g,", afm->Ascender));
146
    fputs("/* Ascender */\n", of);
147
    cursorto(of, 44, fprintf(of, "    %g,", afm->Descender));
148 149
    fputs("/* Descender */\n", of);
    fputs("    {\n", of);
150
    cursorto(of, 44, 7 + fprintf(of, "\t%u,",
151 152
    	    (unsigned int)(afm->WinMetrics.usUnitsPerEm)));
    fputs("/* WinMetrics.usUnitsPerEm */\n", of);
153
    cursorto(of, 44, 7 + fprintf(of, "\t%i,",
154 155
    	    (int)(afm->WinMetrics.sAscender)));
    fputs("/* WinMetrics.sAscender */\n", of);
156
    cursorto(of, 44, 7 + fprintf(of, "\t%i,",
157 158
    	    (int)(afm->WinMetrics.sDescender)));
    fputs("/* WinMetrics.sDescender */\n", of);
159
    cursorto(of, 44, 7 + fprintf(of, "\t%i,",
160 161
    	    (int)(afm->WinMetrics.sLineGap)));
    fputs("/* WinMetrics.sLineGap */\n", of);
162
    cursorto(of, 44, 7 + fprintf(of, "\t%i,",
163 164
    	    (int)(afm->WinMetrics.sAvgCharWidth)));
    fputs("/* WinMetrics.sAvgCharWidth */\n", of);
165
    cursorto(of, 44, 7 + fprintf(of, "\t%i,",
166 167
    	    (int)(afm->WinMetrics.sTypoAscender)));
    fputs("/* WinMetrics.sTypoAscender */\n", of);
168
    cursorto(of, 44, 7 + fprintf(of, "\t%i,",
169 170
    	    (int)(afm->WinMetrics.sTypoDescender)));
    fputs("/* WinMetrics.sTypoDescender */\n", of);
171
    cursorto(of, 44, 7 + fprintf(of, "\t%i,",
172 173
    	    (int)(afm->WinMetrics.sTypoLineGap)));
    fputs("/* WinMetrics.sTypoLineGap */\n", of);
174
    cursorto(of, 44, 7 + fprintf(of, "\t%u,",
175 176
    	    (unsigned int)(afm->WinMetrics.usWinAscent)));
    fputs("/* WinMetrics.usWinAscent */\n", of);
177
    cursorto(of, 44, 7 + fprintf(of, "\t%u",
178 179
    	    (unsigned int)(afm->WinMetrics.usWinDescent)));
    fputs("/* WinMetrics.usWinDescent */\n",of);
180 181
    fputs("    },\n", of);
    cursorto(of, 44, fprintf(of, "    %i,", afm->NumofMetrics));
182
    fputs("/* NumofMetrics */\n", of);
183
    fputs("    metrics\t\t\t\t    /* Metrics */\n};\n", of);
184 185
}

186
void PSDRV_AFM2C(const AFM *afm)
187 188 189 190
{
    char    buffer[256];
    FILE    *of;
    int     i;
191

192
    lstrcpynA(buffer, afm->FontName, sizeof(buffer) - 2);
193

194 195 196
    for (i = 0; i < strlen(buffer); ++i)
    	if (buffer[i] == '-')
	    buffer[i] = '_';
197

198 199 200
    buffer[i] = '.';  buffer[i + 1] = 'c';  buffer[i + 2] = '\0';

    MESSAGE("writing '%s'\n", buffer);
201

202 203 204 205 206 207
    of = fopen(buffer, "w");
    if (of == NULL)
    {
    	ERR("error opening '%s' for writing\n", buffer);
	return;
    }
208

209
    buffer[i] = '\0';
210

211 212 213
    writeHeader(of, afm, buffer);
    writeMetrics(of, afm, buffer);
    writeAFM(of, afm, buffer);
214

215 216
    fclose(of);
}