/*	Willows Software, Inc. - Feb 1997	*/
#ifndef sfnt__h
#define sfnt__h
/*	"@(#)sfnt.h	1.2 :/users/sccs/src/win/mac/s.sfnt.h 2/7/97 11:16:22" */

#ifndef sfntIncludes
#define sfntIncludes

#ifndef Fixed
	#define Fixed	long
#endif

#ifndef sfntEnumIncludes
	#include "sfnt_enum.h"
#endif

typedef struct {
	unsigned long bc;
	unsigned long ad;
} BigDate;

typedef struct {
	unsigned long	tableTag;
	unsigned long	checkSum;
	unsigned long	offset;
	unsigned long	length;
} sfnt_DirectoryEntry;

#define SFNT_VERSION	0x10000

/*
 *	The search fields limits numOffsets to 4096.
 */
typedef struct {
	Fixed version;					/* 1.0 */
	unsigned short numOffsets;		/* number of tables */
	unsigned short searchRange;		/* (max2 <= numOffsets)*16 */
	unsigned short entrySelector;		/* log2(max2 <= numOffsets) */
	unsigned short rangeShift;			/* numOffsets*16-searchRange*/
	sfnt_DirectoryEntry table[1];		/* table[numOffsets] */
} sfnt_OffsetTable;

#define OFFSETTABLESIZE		12		/* not including any entries */

typedef enum sfntHeaderFlagBits {
	Y_POS_SPECS_BASELINE = 1,
	X_POS_SPECS_LSB = 2,
	HINTS_USE_POINTSIZE = 4,
	USE_INTEGER_SCALING = 8,
	INSTRUCTIONS_CHANGE_ADVANCEWIDTHS = 16,
	X_POS_SPECS_BASELINE = 32,
	Y_POS_SPECS_TSB = 64
} sfntHeaderFlagBits;

#define SFNT_MAGIC					0x5F0F3CF5
#define SHORT_INDEX_TO_LOC_FORMAT		0
#define LONG_INDEX_TO_LOC_FORMAT		1
#define GLYPH_DATA_FORMAT				0
#define FONT_HEADER_VERSION			0x10000

typedef struct {
	Fixed		version;			/* for this table, set to 1.0 */
	Fixed		fontRevision;		/* For Font Manufacturer */
	unsigned long	checkSumAdjustment;
	unsigned long	magicNumber; 		/* signature, should always be 0x5F0F3CF5  == MAGIC */
	unsigned short	flags;
	unsigned short	unitsPerEm;		/* Specifies how many in Font Units we have per EM */

	BigDate		created;
	BigDate		modified;

	/** This is the font wide bounding box in ideal space
	(baselines and metrics are NOT worked into these numbers) **/
	short		xMin;
	short		yMin;
	short		xMax;
	short		yMax;

	unsigned short		macStyle;			/* macintosh style word */
	unsigned short		lowestRecPPEM; 	/* lowest recommended pixels per Em */

	/* 0: fully mixed directional glyphs, 1: only strongly L->R or T->B glyphs, 
	   -1: only strongly R->L or B->T glyphs, 2: like 1 but also contains neutrals,
	   -2: like -1 but also contains neutrals */
	short		fontDirectionHint;

	short		indexToLocFormat;
	short		glyphDataFormat;
} sfnt_FontHeader;

#define METRIC_HEADER_FORMAT		0x10000

typedef struct {
	Fixed		version;				/* for this table, set to 1.0 */
	short		ascender;
	short		descender;
	short		lineGap;				/* linespacing = ascender - descender + linegap */
	unsigned short	advanceMax;	
	short		sideBearingMin;		/* left or top */
	short		otherSideBearingMin;	/* right or bottom */
	short		extentMax; 			/* Max of ( SB[i] + bounds[i] ), i loops through all glyphs */
	short		caretSlopeNumerator;
	short		caretSlopeDenominator;
	short		caretOffset;

	unsigned long	reserved1, reserved2;	/* set to 0 */

	short		metricDataFormat;		/* set to 0 for current format */
	unsigned short	numberLongMetrics;		/* if format == 0 */
} sfnt_MetricsHeader;

typedef sfnt_MetricsHeader sfnt_HorizontalHeader;
typedef sfnt_MetricsHeader sfnt_VerticalHeader;

#define MAX_PROFILE_VERSION		0x10000

typedef struct {
	Fixed			version;				/* for this table, set to 1.0 */
	unsigned short		numGlyphs;
	unsigned short		maxPoints;			/* in an individual glyph */
	unsigned short		maxContours;			/* in an individual glyph */
	unsigned short		maxCompositePoints;	/* in an composite glyph */
	unsigned short		maxCompositeContours;	/* in an composite glyph */
	unsigned short		maxElements;			/* set to 2, or 1 if no twilightzone points */
	unsigned short		maxTwilightPoints;		/* max points in element zero */
	unsigned short		maxStorage;			/* max number of storage locations */
	unsigned short		maxFunctionDefs;		/* max number of FDEFs in any preprogram */
	unsigned short		maxInstructionDefs;		/* max number of IDEFs in any preprogram */
	unsigned short		maxStackElements;		/* max number of stack elements for any individual glyph */
	unsigned short		maxSizeOfInstructions;	/* max size in bytes for any individual glyph */
	unsigned short		maxComponentElements;	/* number of glyphs referenced at top level */
	unsigned short		maxComponentDepth;	/* levels of recursion, 1 for simple components */
} sfnt_maxProfileTable;


typedef struct {
	unsigned short	advance;
	short 	sideBearing;
} sfnt_GlyphMetrics;

typedef sfnt_GlyphMetrics sfnt_HorizontalMetrics;
typedef sfnt_GlyphMetrics sfnt_VerticalMetrics;

typedef short sfnt_ControlValue;

/*
 *	Char2Index structures, including platform IDs
 */
typedef struct {
	unsigned short	format;
	unsigned short	length;
	unsigned short	version;
} sfnt_mappingTable;

typedef struct {
	unsigned short	platformID;
	unsigned short	specificID;
	unsigned long	offset;
} sfnt_platformEntry;

typedef struct {
	unsigned short	version;
	unsigned short	numTables;
	sfnt_platformEntry platform[1];	/* platform[numTables] */
} sfnt_char2IndexDirectory;
#define SIZEOFCHAR2INDEXDIR		4

typedef struct {
	unsigned short platformID;
	unsigned short specificID;
	unsigned short languageID;
	unsigned short nameID;
	unsigned short length;
	unsigned short offset;
} sfnt_NameRecord;

typedef struct {
	unsigned short format;
	unsigned short count;
	unsigned short stringOffset;
/*	sfnt_NameRecord[count]	*/
} sfnt_NamingTable;

#define DEVWIDTHEXTRA	2	/* size + max */
/*
 *	Each record is n+2 bytes, padded to long word alignment.
 *	First byte is ppem, second is maxWidth, rest are widths for each glyph
 */
typedef struct {
	short				version;
	short				numRecords;
	long				recordSize;
	/* Byte widths[numGlyphs+DEVWIDTHEXTRA] * numRecords */
} sfnt_DeviceMetrics;

#define	stdPostTableFormat		0x10000
#define	wordPostTableFormat	0x20000
#define	bytePostTableFormat	0x28000
#define	richardsPostTableFormat	0x30000

typedef struct {
	Fixed	version;
	Fixed	italicAngle;
	short	underlinePosition;
	short	underlineThickness;
	short	isFixedPitch;
	short	pad;
	unsigned long	minMemType42;
	unsigned long	maxMemType42;
	unsigned long	minMemType1;
	unsigned long	maxMemType1;
/* if version == 2.0
	{
		numberGlyphs;
		unsigned short[numberGlyphs];
		pascalString[numberNewNames];
	}
	else if version == 2.5
	{
		numberGlyphs;
		int8[numberGlyphs];
	}
*/		
} sfnt_PostScriptInfo;

typedef enum outlinePacking {
	ONCURVE = 1,
	XSHORT = 2,
	YSHORT = 4,
	REPEAT_FLAGS = 8,
/* IF XSHORT */
	SHORT_X_IS_POS = 16,		/* the short vector is positive */
/* ELSE */
	NEXT_X_IS_ZERO = 16,		/* the relative x coordinate is zero */
/* ENDIF */
/* IF YSHORT */
	SHORT_Y_IS_POS = 32,		/* the short vector is positive */
/* ELSE */
	NEXT_Y_IS_ZERO = 32		/* the relative y coordinate is zero */
/* ENDIF */
} outlinePacking;

typedef enum componentPacking {
	COMPONENTCTRCOUNT = -1,
	ARG_1_AND_2_ARE_WORDS = 1,		/* if not, they are bytes */
	ARGS_ARE_XY_VALUES = 2,			/* if not, they are points */
	ROUND_XY_TO_GRID = 4,
	WE_HAVE_A_SCALE = 8,				/* if not, Sx = Sy = 1.0 */
	NON_OVERLAPPING = 16,
	MORE_COMPONENTS = 32,			/* if not, this is the last one */
	WE_HAVE_AN_X_AND_Y_SCALE = 64,	/* Sx != Sy */
	WE_HAVE_A_TWO_BY_TWO = 128,		/* t00, t01, t10, t11 */
	WE_HAVE_INSTRUCTIONS = 256,		/* short count followed by instructions follows */
	USE_MY_METRICS = 512				/* use my metrics for parent glyph */
} componentPacking;


#endif
#endif

