/* pfb section headers.
  There seem to be three and a half of them. the first is a the start of the
   file and is 6 bytes long "\200\001x\005\000\000", the second is right after
   the newline after eexec and is 6 bytes "\200\002I\224\000\000", the third
   is right before the zeros (after the encoded data) and is "\200\001\024\002\000\000"
   the last is at the end of file and is only two bytes "\200\003"
  The first two have different third and fourth chars in different fonts. I
   don't know what they mean.
*/
struct dict {
    int cnt;
    char **keys;
    char **values;
};

struct chars {
    int cnt, next;
    char **keys;
    unsigned char **values;
    int *lens;
};

typedef struct fontinfo {
    char *familyname;
    char *fullname;
    char *notice;
    char *weight;
    char *version;
    double italicangle;
    unsigned int isfixedpitch:1;
    double underlineposition;
    double underlinethickness;
    int em, ascent, descent;	/* Generated by Fontographer */
} FontInfo;

struct private {
    int bluefuzz;		/* (optional) (expand bluezones by this much, def=1) */
    double bluescale;		/* (optional) if the current pointsize in pixels is less than this value then do overshoot hinting */
    int blueshift;		/* (optional) */
    double bluevalues[14];	/* <=7 pairs of integers, first less than second, (may be empty) */
			/* first pair is baseline overshoots, other pairs above baseline */
    double expansionfactor;	/* (optional) only for languagegroup==1 (CJK) */
    double familyblues[14];	/* (optional) bluevalues for family, can override local entry at small pointsizes */
    double familyotherblues[10];/* (optional) otherblues for family */
    unsigned int forcebold:1;	/* (optional) */
    int languagegroup;		/* (optional) (0=>latin, greek, cyril, etc.), (1=>CJK)*/
    int leniv;			/* (optional) must be 4 for old interpreters (number of rand chars at start of charstrings entries) */
    char *minfeature;		/* obsolete, required must be {16 16} */
    char *nd;			/* "noaccess def" (may also be named "|-") */
    char *np;			/* "noaccess put" (may also be named "|") */
    double otherblues[10];	/* (optional) descender blue zones */
    struct chars *othersubrs;	/* (optional) shouldn't contain user defined subs */
	    /* This is not really an array of charstrings, but an array of */
	    /* normal postscript routines. I don't parse it correctly */
    int password;		/* obsolete, required must be 5839 */
    char *rd;			/* "{string currentfile exch readstring pop}" (may also be named "-|") */
    unsigned int rndstemup:1;	/* (optional) obsolete, false if languagegroud==1 */
    double stdhw[1];		/* (optional) dominant horizontal stem width */
    double stdvw[1];		/* (optional) dominant vert */
    double stemsnaph[12];	/* (optional) common h stem widths (at most 12, includes stdhw, sorted by increasing size) */
    double stemsnapv[12];	/* (optional) common v stem widths*/
    struct chars *subrs;	/* (optional, required if othersubrs is present) */
			/* 0-2 part of Flex, 3 hint replacement, 4 and up for charstrings */
    int uniqueid;		/* (optional) seems same as fontdict entry. why's it here too? what of XUID? */
};

typedef struct fontdict {
    int fonttype;
    double fontmatrix[6];
    char *fontname;		/* (optional) */
    struct fontinfo *fontinfo;
    int languagelevel;		/* (optional) */
    int wmode;			/* (optional) chooses between alternate metric sets */
/* non-type0 entries */
    char *encoding[256];
    double fontbb[4];
    int uniqueid;		/* (optional) open range between 4,000,000 and 4,999,999 */
    int xuid[20];		/* (optional) */
/* Type1 specific values */
    int painttype;		/* 0 (filled) 2 (stroked) */
    double strokewidth;		/* (optional) only if painttype==2 */
    struct metrics *metrics;	/* (optional) */
    struct metrics *metrics2;	/* (optional) */
    struct chars *chars;
    struct private *private;
/* Anything we don't understand */
    struct dict leftovers;
} FontDict;

extern char *AdobeStandardEncoding[256];

extern FontDict *ReadPSFont(char *fontname);
extern int WritePSFont(char *fontname,FontDict *fd,int dobinary);
extern void PSFontFree(FontDict *fd);
