/*
 * (C) 1988, 1989 by Adobe Systems Incorporated. All rights reserved.
 *
 * This file may be freely copied and redistributed as long as:
 *   1) This entire notice continues to be included in the file,
 *   2) If the file has been modified in any way, a notice of such
 *      modification is conspicuously indicated.
 *
 * PostScript, Display PostScript, and Adobe are registered trademarks of
 * Adobe Systems Incorporated.
 *
 * ************************************************************************
 * THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO CHANGE WITHOUT
 * NOTICE, AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY ADOBE SYSTEMS
 * INCORPORATED. ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY OR
 * LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO WARRANTY OF ANY
 * KIND (EXPRESS, IMPLIED OR STATUTORY) WITH RESPECT TO THIS INFORMATION,
 * AND EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
 * ************************************************************************
 */

/*
 * Changes made for OpenOffice.org
 *
 *  10/24/2000 pl       - changed code to compile with c++-compilers
 *                      - added namespace to avoid symbol clashes
 *                      - replaced BOOL by bool
 *                      - added function to free space allocated by parseFile
 *  10/26/2000 pl       - added additional keys
 *                      - added ability to parse slightly broken files
 *                      - added charwidth member to GlobalFontInfo
 *  04/26/2001 pl       - added OpenOffice header
 *  10/19/2005 pl       - changed parseFile to accept a file name instead of a stream
 */

/* ParseAFM.h
 *
 * This header file is used in conjunction with the parseAFM.c file.
 * Together these files provide the functionality to parse Adobe Font
 * Metrics files and store the information in predefined data structures.
 * It is intended to work with an application program that needs font metric
 * information. The program can be used as is by making a procedure call to
 * parse an AFM file and have the data stored, or an application developer
 * may wish to customize the code.
 *
 * This header file defines the data structures used as well as the key
 * strings that are currently recognized by this version of the AFM parser.
 * This program is based on the document "Adobe Font Metrics Files,
 * Specification Version 2.0".
 *
 * AFM files are separated into distinct sections of different data. Because
 * of this, the parseAFM program can parse a specified file to only save
 * certain sections of information based on the application's needs. A record
 * containing the requested information will be returned to the application.
 *
 * AFM files are divided into five sections of data:
 *  1) The Global Font Information
 *  2) The Character Metrics Information
 *  3) The Track Kerning Data
 *  4) The Pair-Wise Kerning Data
 *  5) The Composite Character Data
 *
 * Basically, the application can request any of these sections independent
 * of what other sections are requested. In addition, in recognizing that
 * many applications will want ONLY the x-width of characters and not all
 * of the other character metrics information, there is a way to receive
 * only the width information so as not to pay the storage cost for the
 * unwanted data. An application should never request both the
 * "quick and dirty" char metrics (widths only) and the Character Metrics
 * Information since the Character Metrics Information will contain all
 * of the character widths as well.
 *
 * There is a procedure in parseAFM.c, called parseFile, that can be
 * called from any application wishing to get information from the AFM File.
 * This procedure expects 3 parameters: a valid file descriptor, a pointer
 * to a (FontInfo *) variable (for which space will be allocated and then
 * will be filled in with the data requested), and a mask specifying
 * which data from the AFM File should be saved in the FontInfo structure.
 *
 * The flags that can be used to set the appropriate mask are defined below.
 * In addition, several commonly used masks have already been defined.
 *
 * History:
 *  original: DSM  Thu Oct 20 17:39:59 PDT 1988
 *  modified: DSM  Mon Jul  3 14:17:50 PDT 1989
 *    - added 'storageProblem' return code
 *    - fixed typos
 */

#include <stdio.h>

namespace psp {

/* your basic constants */
#define EOL '\n'                /* end-of-line indicator */
#define MAX_NAME 4096           /* max length for identifiers */
#define FLAGS int



/* Flags that can be AND'ed together to specify exactly what
 * information from the AFM file should be saved.
 */
#define P_G 0x01    /* 0000 0001 */   /* Global Font Info      */
#define P_W 0x02    /* 0000 0010 */   /* Character Widths ONLY */
#define P_M 0x06    /* 0000 0110 */   /* All Char Metric Info  */
#define P_P 0x08    /* 0000 1000 */   /* Pair Kerning Info     */
#define P_T 0x10    /* 0001 0000 */   /* Track Kerning Info    */
#define P_C 0x20    /* 0010 0000 */   /* Composite Char Info   */


/* Commonly used flags
 */
#define P_GW    (P_G | P_W)
#define P_GM    (P_G | P_M)
#define P_GMP   (P_G | P_M | P_P)
#define P_GMK   (P_G | P_M | P_P | P_T)
#define P_ALL   (P_G | P_M | P_P | P_T | P_C)



/* Possible return codes from the parseFile procedure.
 *
 * ok means there were no problems parsing the file.
 *
 * parseError means that there was some kind of parsing error, but the
 * parser went on. This could include problems like the count for any given
 * section does not add up to how many entries there actually were, or
 * there was a key that was not recognized. The return record may contain
 * valid data or it may not.
 *
 * earlyEOF means that an End of File was encountered before expected. This
 * may mean that the AFM file had been truncated, or improperly formed.
 *
 * storageProblem means that there were problems allocating storage for
 * the data structures that would have contained the AFM data.
 */

enum afmError { ok = 0, parseError = -1, earlyEOF = -2, storageProblem = -3 };


/************************* TYPES *********************************/
/* Below are all of the data structure definitions. These structures
 * try to map as closely as possible to grouping and naming of data
 * in the AFM Files.
 */


/* Bounding box definition. Used for the Font BBox as well as the
 * Character BBox.
 */
typedef struct
{
    int llx;    /* lower left x-position  */
    int lly;    /* lower left y-position  */
    int urx;    /* upper right x-position */
    int ury;    /* upper right y-position */
} BBox;


/* Global Font information.
 * The key that each field is associated with is in comments. For an
 * explanation about each key and its value please refer to the AFM
 * documentation (full title & version given above).
 */
typedef struct
{
    char *afmVersion;       /* key: StartFontMetrics */
    char *fontName;     /* key: FontName */
    char *fullName;     /* key: FullName */
    char *familyName;       /* key: FamilyName */
    char *weight;       /* key: Weight */
    float italicAngle;      /* key: ItalicAngle */
    bool isFixedPitch;      /* key: IsFixedPitch */
    BBox fontBBox;      /* key: FontBBox */
    int underlinePosition;      /* key: UnderlinePosition */
    int underlineThickness;     /* key: UnderlineThickness */
    char *version;      /* key: Version */
    char *notice;       /* key: Notice */
    char *encodingScheme;   /* key: EncodingScheme */
    int capHeight;      /* key: CapHeight */
    int xHeight;            /* key: XHeight */
    int ascender;       /* key: Ascender */
    int descender;      /* key: Descender */
    int charwidth;      /* key: CharWidth */
} GlobalFontInfo;


/* Ligature definition is a linked list since any character can have
 * any number of ligatures.
 */
typedef struct _t_ligature
{
    char *succ, *lig;
    struct _t_ligature *next;
} Ligature;


/* Character Metric Information. This structure is used only if ALL
 * character metric information is requested. If only the character
 * widths is requested, then only an array of the character x-widths
 * is returned.
 *
 * The key that each field is associated with is in comments. For an
 * explanation about each key and its value please refer to the
 * Character Metrics section of the AFM documentation (full title
 * & version given above).
 */
typedef struct
{
    int code,       /* key: C */
        wx,     /* key: WX */
        w0x,        /* key: W0X */
        wy;     /* together wx and wy are associated with key: W */
    char *name;     /* key: N */
    BBox charBBox;  /* key: B */
    Ligature *ligs; /* key: L (linked list; not a fixed number of Ls */
} CharMetricInfo;


/* Track kerning data structure.
 * The fields of this record are the five values associated with every
 * TrackKern entry.
 *
 * For an explanation about each value please refer to the
 * Track Kerning section of the AFM documentation (full title
 * & version given above).
 */
typedef struct
{
    int degree;
    float minPtSize,
        minKernAmt,
        maxPtSize,
        maxKernAmt;
} TrackKernData;


/* Pair Kerning data structure.
 * The fields of this record are the four values associated with every
 * KP entry. For KPX entries, the yamt will be zero.
 *
 * For an explanation about each value please refer to the
 * Pair Kerning section of the AFM documentation (full title
 * & version given above).
 */
typedef struct
{
    char *name1;
    char *name2;
    int xamt,
        yamt;
} PairKernData;


/* PCC is a piece of a composite character. This is a sub structure of a
 * compCharData described below.
 * These fields will be filled in with the values from the key PCC.
 *
 * For an explanation about each key and its value please refer to the
 * Composite Character section of the AFM documentation (full title
 * & version given above).
 */
typedef struct
{
    char *pccName;
    int deltax,
        deltay;
} Pcc;


/* Composite Character Information data structure.
 * The fields ccName and numOfPieces are filled with the values associated
 * with the key CC. The field pieces points to an array (size = numOfPieces)
 * of information about each of the parts of the composite character. That
 * array is filled in with the values from the key PCC.
 *
 * For an explanation about each key and its value please refer to the
 * Composite Character section of the AFM documentation (full title
 * & version given above).
 */
typedef struct
{
    char *ccName;
    int numOfPieces;
    Pcc *pieces;
} CompCharData;


/*  FontInfo
 *  Record type containing pointers to all of the other data
 *  structures containing information about a font.
 *  A a record of this type is filled with data by the
 *  parseFile function.
 */
typedef struct
{
    GlobalFontInfo *gfi;    /* ptr to a GlobalFontInfo record */
    int *cwi;           /* ptr to 256 element array of just char widths */
    int numOfChars;     /* number of entries in char metrics array */
    CharMetricInfo *cmi;    /* ptr to char metrics array */
    int numOfTracks;        /* number to entries in track kerning array */
    TrackKernData *tkd;     /* ptr to track kerning array */
    int numOfPairs;     /* number to entries in pair kerning array */
    PairKernData *pkd;      /* ptr to pair kerning array */
    int numOfComps;     /* number to entries in comp char array */
    CompCharData *ccd;      /* ptr to comp char array */
} FontInfo;



/************************* PROCEDURES ****************************/

/*  Call this procedure to do the grunt work of parsing an AFM file.
 *
 *  "fp" should be a valid file pointer to an AFM file.
 *
 *  "fi" is a pointer to a pointer to a FontInfo record structure
 *  (defined above). Storage for the FontInfo structure will be
 *  allocated in parseFile and the structure will be filled in
 *  with the requested data from the AFM File.
 *
 *  "flags" is a mask with bits set representing what data should
 *  be saved. Defined above are valid flags that can be used to set
 *  the mask, as well as a few commonly used masks.
 *
 *  The possible return codes from parseFile are defined above.
 */

int parseFile( const char* pFilename, FontInfo **fi, FLAGS flags );
void freeFontInfo(FontInfo *fi);

} // namespace
