/*
* get-computer-modern-metrics.c
*
* This extracts just enough font information from a bunch of *.afm
* files that I can render Postscript properly from FXDCPostscriptPrinter.cpp
*
* The font metrics used here are a subset of the Computer Modern set
* and I use the AMS versions, which are freely available for all purposes.
* I have the fonts themselves and the explicit statement of their
* license terms elsewhere.
*
* A C Norman. September 2004
*/
/*
* Copyright (c) 2004 A C Norman, Codemist Ltd
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
/* Signature: 59595815 25-Sep-2004 */
#include <stdio.h>
#include <stdlib.h>
/*
* This program is really just for MY use so I will build a fixed
* path in here and let anybody who disagrees with it change the source
* code and re-compile.
*/
#define FONT_PATH "../fonts/cmpsfont-unix/afm"
/*
* From the .afm file I will extract lines
* FontName name eg FontName Times-Italic
* IsFixedPitch fg eg fg=true or false
* Ascender n
* Descender n
* XHeight n
* CapHeight n
* FontBBox n n n n bounding box for entire font
* C nn ; WX mm ; N name ; B n n n n code, width, name, char bounding box
* other lines will be ignored
*/
static FILE *out = NULL;
static int process(char *d, char *s)
{
char line[1000], junk[1000], name[1000];
int charwidth[256];
int isFixed = -1;
int bb1=-1, bb2=-1, bb3=-1, bb4=-1; /* font bounding box */
int bc1, bc2, bc3, bc4;
double dw, dc1, dc2, dc3, dc4;
int ascender=-1, descender=-1, xheight=-1, capheight=-1;
int maxleftbearing = 0, maxrightbearing = 0i, maxwidth = 0;
int charNo, charWidth;
FILE *f;
int c, p, n;
int headershown = 0;
sprintf(line, "%s/%s", FONT_PATH, s);
f = fopen(line, "r");
if (f == NULL)
{ fprintf(stderr, "Failed to read \"%s\"\n", line);
exit(1);
}
name[0] = 0;
for (c=0; c<256; c++) charwidth[c] = -1;
for (;;)
{ p = 0;
for (c=getc(f); c!='\n' && c!=EOF; c=getc(f))
{ if (p < sizeof(line)-2) line[p++] = c;
}
line[p] = 0;
charNo = charWidth = -1;
if (sscanf(line, "FontName %s", name) == 1);
else if (sscanf(line, "IsFixedPitch fals%s", junk) == 1)
isFixed = 0;
else if (sscanf(line, "IsFixedPitch tru%s", junk) == 1)
isFixed = 1;
else if (sscanf(line, "Comment%s", junk) == 1);
else if (sscanf(line, "KPX%s", junk) == 1);
else if (sscanf(line, "FontBBox %d %d %d %d",
&bb1, &bb2, &bb3, &bb4) == 4);
else if (sscanf(line, "CapHeight %d", &capheight) == 1);
else if (sscanf(line, "XHeight %d", &xheight) == 1);
else if (sscanf(line, "Ascender %d", &ascender) == 1);
else if (sscanf(line, "Descender %d", &descender) == 1);
else if (sscanf(line, "C %d ; WX %lf ; N %*s ; B %lf %lf %lf %lf %s",
&charNo, &dw,
&dc1, &dc2, &dc3, &dc4, junk) == 7)
{ if (charNo >= 0 && charNo < 256 &&
dw >= 0.0)
{ int rightbearing, leftbearing;
charWidth = (int)(dw + 0.5);
bc1 = (int)(dc1 + 0.5);
bc2 = (int)(dc2 + 0.5);
bc3 = (int)(dc3 + 0.5);
bc4 = (int)(dc4 + 0.5);
charwidth[charNo] = charWidth;
if (charWidth > maxwidth) maxwidth = charWidth;
if (bc1!=0 || bc2!=0 || bc3!=0 || bc4!=0)
{ leftbearing = bc1;
rightbearing = charWidth - bc3;
if (leftbearing > maxleftbearing)
maxleftbearing = leftbearing;
if (rightbearing > maxrightbearing)
maxrightbearing = rightbearing;
}
}
}
else if (sscanf(line, "Comment%s", junk) == 1);
else if (sscanf(line, "EndKern%s", junk) == 1);
else if (sscanf(line, "EndFont%s", junk) == 1);
else if (sscanf(line, "StartFont%s", junk) == 1);
else if (sscanf(line, "Encoding%s", junk) == 1);
else if (sscanf(line, "Weight%s", junk) == 1);
else if (sscanf(line, "Italic%s", junk) == 1);
else if (sscanf(line, "Notice%s", junk) == 1);
else if (sscanf(line, "EndChar%s", junk) == 1);
else if (sscanf(line, "StartChar%s", junk) == 1);
else if (sscanf(line, "Family%s", junk) == 1);
else if (sscanf(line, "FullName%s", junk) == 1);
else if (sscanf(line, "StartKern%s", junk) == 1);
else if (sscanf(line, "Version%s", junk) == 1);
else if (sscanf(line, "KPX%s", junk) == 1);
else printf(" Unparsed \"%s\"\n", line);
if (c == EOF) break;
}
fclose(f);
if (name[0] == 0) return; /* no font name */
fprintf(out, "{\"%s\", %d, %d, %d, %d, %d, %d, %d, %d, {\n",
name, isFixed, maxwidth, maxleftbearing, maxrightbearing,
capheight, xheight, ascender, descender);
for (c=0; c<255; c++)
{ fprintf(out, "%6d,", charwidth[c]);
if ((c % 8) == 7) fprintf(out, "\n");
}
fprintf(out, "%6d }},\n", charwidth[255]);
}
int main(int argc, char *argv[])
{
FILE *note;
int ch;
out = fopen("cmfont-info.c", "w");
if (out == NULL)
{ printf("Failed to open cmfont-info.c\n");
return 1;
}
fprintf(out, "/*\n * cmfont-info.c\n");
fprintf(out, " * Font metrics for Type1 Computer Modern Fonts\n *\n");
fprintf(out, " * extracted from %s\n *\n", FONT_PATH);
fprintf(out, " */\n");
fprintf(out, "\n\n/* Signature: 7d4bbc1c 25-Sep-2004 */\n\n\n");
fprintf(out, "typedef struct font_info {\n");
fprintf(out, " char *name;\n");
fprintf(out, " short int isfixed, fontwidth, maxleftbearing, maxrightbearing;\n");
fprintf(out, " short int capheight, xheight, ascent, descent;\n");
fprintf(out, " short int charwidth[256];\n");
fprintf(out, "} font_info;\n\n");
fprintf(out, "static font_info cm_font_widths[] = {\n");
//
// There are fonts that actually interest me...
//
process("cmr5", "cmr5.afm");
process("cmr6", "cmr6.afm");
process("cmr7", "cmr7.afm");
process("cmr8", "cmr8.afm");
process("cmr9", "cmr9.afm");
process("cmr10", "cmr10.afm");
process("cmr12", "cmr12.afm");
process("cmr17", "cmr17.afm");
process("cmmi5", "cmmi5.afm");
process("cmmi6", "cmmi6.afm");
process("cmmi7", "cmmi7.afm");
process("cmmi8", "cmmi8.afm");
process("cmmi9", "cmmi9.afm");
process("cmmi10", "cmmi10.afm");
process("cmmi12", "cmmi12.afm");
process("cmsy5", "cmsy5.afm");
process("cmsy6", "cmsy6.afm");
process("cmsy7", "cmsy7.afm");
process("cmsy8", "cmsy8.afm");
process("cmsy9", "cmsy9.afm");
process("cmsy10", "cmsy10.afm");
process("cmex10", "cmex10.afm");
fprintf(out, "{(char *)0, 0,0,0,0,0,0,0,0, {0}}};\n\n\n");
fprintf(out, "/* End of cmfont-info.c */\n");
fclose(out);
printf("File \"cmfont-info.c\" created\n");
return 0;
}
/* end of get-computer-modern-metrics.c */