/*
 * get-adobe-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 it works can be found on many sites - they can be
 * downloaded directly from Adobe's ftp site but also they are included
 * with many existing software packages in forms that clearly state that
 * they are available for redistribution and that the authors of those
 * packages have checked license conditions carefully. The set of files
 * I use here came with "teTeX 2" where these terms are carefully set
 * out and where the package is very well established and widely used so
 * there would have been plenty of opportunity for concerns about rights
 * to be aired. I have not altered the metric files at all.
 *
 * Note that the file-names I expect to be used for fonts follow the
 * "Berry" naming convention used within the TeX community, and the
 * directory organisation is as in teTeX.
 *
 *                                      A C Norman.  November 2003
 */


/*
 * 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: 4cea1f74 20-Mar-2004 */

#include <stdio.h>
#include <stdlib.h>

#define FONT_PATH "./tetex/fonts/afm/adobe"


/*
 * 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;
    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/%s", FONT_PATH, d, 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, "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 %d ; N %*s ; B %d %d %d %d",
                              &charNo, &charWidth,
                              &bc1, &bc2, &bc3, &bc4) == 6)
        {   if (charNo >= 0 && charNo < 256 &&
                charWidth >= 0)
            {   int rightbearing, leftbearing;
                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;
                }
            }
        }
        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;
    if ((note = fopen(FONT_PATH "/../../../LICENSE.texmf", "r")) == NULL)
    {   fprintf(stderr, "+++ Failed to find proper fonts directory\n");
        exit(1);
    }
    printf("Here is the license notice from the fonts source directory:\n\n");
    for (ch=getc(note); ch!=EOF; ch=getc(note)) putchar(ch);
    printf("\n");
    out = fopen("font-info.c", "w");
    if (out == NULL)
    {   printf("Failed to open font-info.c\n");
        return 1;
    }
    fprintf(out, "/*\n * font-info.c\n");
    fprintf(out, " * Font metrics for Adobe Type1 Fonts\n *\n");
    fprintf(out, " * extracted from %s\n *\n", FONT_PATH);
    fprintf(out, " * see file LICENCE.texmf within that tree for a clear\n");
    fprintf(out, " * statement that the files may be distributed.\n");
    fprintf(out, " * Thank you to Adobe and to the teTeX people.\n");
    fprintf(out, " * ftp.adobe.com/pub/adobe/type/win/all/afmfiles/base35\n");
    fprintf(out, " * and www.tug.org/teTeX.\n");
    fprintf(out, " */\n");
    fprintf(out, "\n\n/* Signature: 2b9130e7 22-Nov-2003 */\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 font_widths[] = {\n");
//
// There are 35 standard Postscript fonts that might be used with this
// print package. They are:
//
    process("avantgar", "pagd8a.afm");   // AvantGarde-Demi
    process("avantgar", "pagdo8a.afm");  // AvantGarde-DemiOblique
    process("avantgar", "pagk8a.afm");   // AvantGarde-Book
    process("avantgar", "pagko8a.afm");  // AvantGarde-BookOblique
    process("bookman",  "pbkd8a.afm");   // Bookman-Demi
    process("bookman",  "pbkdi8a.afm");  // Bookman-DemiItalic
    process("bookman",  "pbkl8a.afm");   // Bookman-Light
    process("bookman",  "pbkli8a.afm");  // Bookman-LightItalic
    process("courier",  "pcrb8a.afm");   // Courier-Bold                 *
    process("courier",  "pcrbo8a.afm");  // Courier-BoldOblique          *
    process("courier",  "pcrr8a.afm");   // Courier                      *
    process("courier",  "pcrro8a.afm");  // Courier-Oblique              *
    process("helvetic", "phvb8a.afm");   // Helvetica-Bolda              *
    process("helvetic", "phvb8an.afm");  // Helvetica-Narrow-Bold
    process("helvetic", "phvbo8a.afm");  // Helvertica-BoldOblique       *
    process("helvetic", "phvbo8an.afm"); // Helvetica-Narrow-BoldOblique
    process("helvetic", "phvr8a.afm");   // Helvetica                    *
    process("helvetic", "phvr8an.afm");  // Helvetica-Narrow
    process("helvetic", "phvro8a.afm");  // Helvetica-Oblique            *
    process("helvetic", "phvro8an.afm"); // Helvetica-NarrowOblique
    process("ncntrsbk", "pncb8a.afm");   // NewCenturySchlbk-Bold
    process("ncntrsbk", "pncbi8a.afm");  // NewCenturySchlbk-BoldItalic
    process("ncntrsbk", "pncr8a.afm");   // NewCenturySchlbk-Roman
    process("ncntrsbk", "pncri8a.afm");  // NewCenturySchlbk-Italic
    process("palatino", "pplb8a.afm");   // Palatino-Bold
    process("palatino", "pplbi8a.afm");  // Palatino-BoldItalic
    process("palatino", "pplr8a.afm");   // Palatino-Roman
    process("palatino", "pplri8a.afm");  // Palatino-Italic
    process("symbol",   "psyr.afm");     // Symbol                       *
    process("times",    "ptmb8a.afm");   // Times-Bold                   *
    process("times",    "ptmbi8a.afm");  // Times-BoldItalic             *
    process("times",    "ptmr8a.afm");   // Times-Roman                  *
    process("times",    "ptmri8a.afm");  // Times-Italic                 *
    process("zapfchan", "pzcmi8a.afm");  // ZapfChancery-MediumItalic
    process("zapfding", "pzdr.afm");     // ZapfDingbats
// Fonts with a "*" comment above are the ones that the early versions
// of Postscript supported.
    fprintf(out, "{(char *)0, 0,0,0,0,0,0,0,0, {0}}};\n\n\n");
    fprintf(out, "/* End of font-info.c */\n");
    fclose(out);
    printf("File \"font-info.c\" created\n");
    return 0;
}

/* end of get-adobe-metrics.c */

