/* This is an include file which describes the interface to
the TeX PK font file access routines. */

/*  Maximum number of glyphs (and maximum glyph_id) in a PK file is 127 */

#define PKFILESPECLENGTH	255
#define	PKMAXGLYPH		127
#define	PKMAXFONTSIZE		100000

/*  Various constants for items in the PK file.  See PKtoPX.WEB.  */

#define PK_XXX1 240
#define PK_XXX2 241
#define PK_XXX3 242
#define PK_XXX4 243
#define PK_YYY 244
#define PK_POST 245
#define PK_NO_OP 246
#define PK_PRE 247
#define PK_ID 89

typedef struct	pk_font {
	char *fontname;			/* a pointer to the fontname */
	char *filespec;			/* a pointer to the filespec */
	int magnification;		/* in (1.2^n) * 1000 units */
	int design_size;		/* in 2^-16 points */
	int checksum;			/* should match TFM file */
	int h_pixels_per_point;		/* * 2^16 */
	int v_pixels_per_point;		/* * 2^16 */
	unsigned char *fontstream;	/* ptr to memory image of PK font */
	unsigned char *fontidx;		/* first unread char in stream */
	int fontsize;			/* size of memory image */
	unsigned char *packed_glyphs[PKMAXGLYPH+1];   /* unexpanded glyphs */
	struct pk_glyph *unpacked_glyphs[PKMAXGLYPH+1];/* expanded glyphs */
}   PKFont;

typedef	struct	pk_glyph {
	int glyph_id;			/* The character id */
	PKFont *fontptr;		/* pointer to the PKfont structure */
	unsigned char *rasters;		/* pointer to the expanded rasters */
	unsigned char *prasters;	/* ptr to the packed rasters */
	unsigned tfm_width;		/* in FIXes (2^-20 * design_size) */
	unsigned width;			/* of minimum bound box in pixels */
	unsigned height;		/* of minimum bound box in pixels */
	int h_offset;			/* in pixels */
	int v_offset;			/* in pixels */
	unsigned h_escapement;		/* in pixels * 2^16 */
	unsigned v_escapement;		/* in pixels * 2^16 */
	unsigned dyn_f : 4;		/* see PKtoPX.WEB :-) */
	unsigned color : 1;		/* initial run: black(1) | white(0) */
	unsigned nybflag : 1;		/* nybble bit: upper or lower */
}   PKGlyph;

#ifdef ANSIC
extern	PKFont	*PKLoadFont( char *fontname, int magnification );
extern  PKGlyph *PKGetNextGlyph( char *fontname );
extern	PKGlyph	*PKGetGlyph( PKFont *fontptr, int glyphid );
extern	PKGlyph	*PKGetGlyphInfo( PKFont *fontptr, int glyphid );
extern	void	PKFreeGlyph( int glyphid );
extern	void	PKUnloadFont( PKFont *fontptr );
#else
extern	PKFont	*PKLoadFont();
extern  PKGlyph *PKGetNextGlyph();
extern	PKGlyph	*PKGetGlyph();
extern	PKGlyph	*PKGetGlyphInfo();
extern	void	PKFreeGlyph();
extern	void	PKUnloadFont();
#endif

/* global variables */

extern	char		PKerror[];	/* stores last err message */
extern	unsigned char	PKbitmask[9][8];	/* see pkgbl.c */
extern	unsigned char	PKbytereversal[256];	/* see pkgbl.c */

/*  Macros  */

/*  Here are my macros convert various sized Big-Endian integers into integers
will always be correct under C.  Yes,I know that an overlay (union) is faster
but these act like a function.  And that to me, makes them more useful.
[[The comma (",") operator is most (and only?) useful in macros.]]  */

#ifndef BIG_ENDIAN
#define Get_8Bit_Signed(ptr) \
	(ptr += 1, \
		(         (char *) ptr)[-1] \
	)
#define Get_8Bit_Unsigned(ptr) \
	(ptr += 1, \
		((unsigned char *) ptr)[-1] \
	)


#define Get_16Bit_Signed(ptr) \
	(ptr += 2, \
		(         (char *) ptr)[-2] * 0x100 + \
		((unsigned char *) ptr)[-1] \
	)
#define Get_16Bit_Unsigned(ptr) \
	(ptr += 2, \
		((unsigned char *) ptr)[-2] * 0x100 + \
		((unsigned char *) ptr)[-1] \
	)


#define Get_24Bit_Singed(ptr) \
	(ptr += 3, \
		(         (char *) ptr)[-3] * 0x10000 + \
		((unsigned char *) ptr)[-2] * 0x100 + \
		((unsigned char *) ptr)[-1] \
	)
#define Get_24Bit_Unsigned(ptr) \
	(ptr += 3, \
		((unsigned char *) ptr)[-3] * 0x10000 + \
		((unsigned char *) ptr)[-2] * 0x100 + \
		((unsigned char *) ptr)[-1] \
	)


#define Get_32Bit_Signed(ptr) \
	(ptr += 4, \
		(         (char *) ptr)[-4] * 0x1000000 + \
		((unsigned char *) ptr)[-3] * 0x10000 + \
		((unsigned char *) ptr)[-2] * 0x100 + \
		((unsigned char *) ptr)[-1] \
	)
#define Get_32Bit_Unsigned(ptr) \
	(ptr += 4, \
		((unsigned char *) ptr)[-4] * 0x1000000 + \
		((unsigned char *) ptr)[-3] * 0x10000 + \
		((unsigned char *) ptr)[-2] * 0x100 + \
		((unsigned char *) ptr)[-1] \
	)
#else
#define Get_8Bit_Signed(ptr) \
	(ptr += 1, \
		(         (char *) ptr)[-1] \
	)
#define Get_8Bit_Unsigned(ptr) \
	(ptr += 1, \
		((unsigned char *) ptr)[-1] \
	)


#define Get_16Bit_Signed(ptr) \
	(ptr += 2, \
		(         (char *) ptr)[-1] * 0x100 + \
		((unsigned char *) ptr)[-2] \
	)
#define Get_16Bit_Unsigned(ptr) \
	(ptr += 2, \
		((unsigned char *) ptr)[-1] * 0x100 + \
		((unsigned char *) ptr)[-2] \
	)


#define Get_24Bit_Singed(ptr) \
	(ptr += 3, \
		(         (char *) ptr)[-1] * 0x10000 + \
		((unsigned char *) ptr)[-2] * 0x100 + \
		((unsigned char *) ptr)[-3] \
	)
#define Get_24Bit_Unsigned(ptr) \
	(ptr += 3, \
		((unsigned char *) ptr)[-1] * 0x10000 + \
		((unsigned char *) ptr)[-2] * 0x100 + \
		((unsigned char *) ptr)[-3] \
	)


#define Get_32Bit_Signed(ptr) \
	(ptr += 4, \
		(         (char *) ptr)[-1] * 0x1000000 + \
		((unsigned char *) ptr)[-2] * 0x10000 + \
		((unsigned char *) ptr)[-3] * 0x100 + \
		((unsigned char *) ptr)[-4] \
	)
#define Get_32Bit_Unsigned(ptr) \
	(ptr += 4, \
		((unsigned char *) ptr)[-1] * 0x1000000 + \
		((unsigned char *) ptr)[-2] * 0x10000 + \
		((unsigned char *) ptr)[-3] * 0x100 + \
		((unsigned char *) ptr)[-4] \
	)
#endif

#define		BitMask(count,bitpos)	(PKbitmask[count][bitpos])
#ifdef PKLTOR
#   define	CopyByte( byte )	((unsigned char) PKbytereversal[byte])
#   define	ReverseByte( byte )	((unsigned char) byte)
#else
#   define	CopyByte( byte )	((unsigned char) byte)
#   define	ReverseByte( byte )	((unsigned char) PKbytereversal[byte])
#endif
