/* Smalltalk from Squeak4.6 with VMMaker 4.20.6 translated as C source on 24 November 2023 3:42:30 pm */
/* Automatically generated by
	FT2PluginCodeGenerator Freetype-Plugin-dtl.71 uuid: 6329a996-8fa7-4097-bed4-f1e62c9a1445
   from
	FT2Plugin Freetype-Plugin-dtl.71 uuid: 6329a996-8fa7-4097-bed4-f1e62c9a1445
 */
static char __buildInfo[] = "FT2Plugin Freetype-Plugin-dtl.71 uuid: 6329a996-8fa7-4097-bed4-f1e62c9a1445 " __DATE__ ;




/* Configuration options */
#include "sqConfig.h"

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

/* Default EXPORT macro that does nothing (see comment in sq.h): */
#define EXPORT(returnType) returnType

/* Do not include the entire sq.h file but just those parts needed. */
/*  The virtual machine proxy definition */
#include "sqVirtualMachine.h"
/* Platform specific definitions */
#include "sqPlatformSpecific.h"

#define true 1
#define false 0
#define null 0  /* using 'null' because nil is predefined in Think C */
#ifdef SQUEAK_BUILTIN_PLUGIN
#undef EXPORT
// was #undef EXPORT(returnType) but screws NorCroft cc
#define EXPORT(returnType) static returnType
#endif
#include <ft2build.h>
#include FT_TRUETYPE_TABLES_H
#include FT_FREETYPE_H
#include FT_OUTLINE_H

#include "sqMemoryAccess.h"


/*** Constants ***/
#define FT2GlyphSlotFaceIndex 0
#define FT2GlyphSlotInstSize 17
#define FT2OutlineContoursIndex 4
#define FT2OutlineContoursSizeIndex 0
#define FT2OutlineFlagsIndex 5
#define FT2OutlineInstSize 6
#define FT2OutlinePointsIndex 2
#define FT2OutlinePointsSizeIndex 1
#define FT2OutlineTagsIndex 3
#define FormBitsIndex 0
#define FormDepthIndex 3
#define FormHeightIndex 2
#define FormInstSize 5
#define FormWidthIndex 1

/*** Function Prototypes ***/
static sqInt ftAllocateHandleInReceiverForPointer(void *aPointer);
static sqInt ftAllocateStringForPointer(const char *aPointer);
static FT_Encoding ftEncodingValueFromString(sqInt string);
static void * ftHandleValueFromReceiver(sqInt rcvrOop);
static int ftInitBitmapfromForm(FT_Bitmap*bitmap, sqInt formOop);
static int ftInitBitmapfromFormrenderMode(FT_Bitmap*bitmap, sqInt formOop, sqInt mode);
static int ftParameterError(void);
static sqInt ftStringFromEncodingValue(FT_Encoding encoding);
#pragma export on
EXPORT(const char*) getModuleName(void);
#pragma export off
static sqInt halt(void);
#pragma export on
EXPORT(sqInt) initialiseModule(void);
EXPORT(sqInt) primitiveCopyToExternalMemory(void);
EXPORT(sqInt) primitiveDoneFace(void);
EXPORT(sqInt) primitiveDoneFacePreserveFields(void);
EXPORT(sqInt) primitiveEmboldenFaceGlyphSlotOutline(void);
EXPORT(sqInt) primitiveErrorCode(void);
EXPORT(sqInt) primitiveFreeExternalMemory(void);
EXPORT(sqInt) primitiveGetFaceCharIndex(void);
EXPORT(sqInt) primitiveGetFaceCharMap(void);
EXPORT(sqInt) primitiveGetFaceCharMapsIntoArray(void);
EXPORT(sqInt) primitiveGetFaceGlyphName(void);
EXPORT(sqInt) primitiveGetKerningLeftRight(void);
EXPORT(sqInt) primitiveGetPostscriptName(void);
EXPORT(sqInt) primitiveGetSfntTableOS2(void);
EXPORT(sqInt) primitiveHasKerning(void);
EXPORT(sqInt) primitiveLibraryHandle(void);
EXPORT(sqInt) primitiveLoadCharacter(void);
EXPORT(sqInt) primitiveLoadFaceBbox(void);
EXPORT(sqInt) primitiveLoadFaceFields(void);
EXPORT(sqInt) primitiveLoadGlyph(void);
EXPORT(sqInt) primitiveLoadGlyphSlotFromFace(void);
EXPORT(sqInt) primitiveLoadOutlineArraysFromFace(void);
EXPORT(sqInt) primitiveLoadOutlineSizesFromFace(void);
EXPORT(sqInt) primitiveModuleErrorCode(void);
EXPORT(sqInt) primitiveNewFaceFromFileAndIndex(void);
EXPORT(sqInt) primitiveNewMemoryFaceFromExternalMemoryAndIndex(void);
EXPORT(sqInt) primitiveNumberOfOutlineCountours(void);
EXPORT(sqInt) primitiveRenderGlyphIntoForm(void);
EXPORT(sqInt) primitiveRenderGlyphIntoFormWithRenderMode(void);
EXPORT(sqInt) primitiveResetErrorCode(void);
EXPORT(sqInt) primitiveSetFaceCharMap(void);
EXPORT(sqInt) primitiveSetPixelSizes(void);
EXPORT(sqInt) primitiveSetTransform(void);
EXPORT(sqInt) primitiveTransformFaceGlyphSlotOutline(void);
EXPORT(sqInt) primitiveTranslateFaceGlyphSlotOutline(void);
EXPORT(sqInt) primitiveVersion(void);
EXPORT(sqInt) setInterpreter(struct VirtualMachine*anInterpreter);
EXPORT(sqInt) shutdownModule(void);
#pragma export off
/*** Variables ***/
static int errorCode;

#ifdef SQUEAK_BUILTIN_PLUGIN
extern
#endif
struct VirtualMachine* interpreterProxy;
static FT_Library library;
static const char *moduleName =
#ifdef SQUEAK_BUILTIN_PLUGIN
	"FT2Plugin 24 November 2023 (i)"
#else
	"FT2Plugin 24 November 2023 (e)"
#endif
;
static sqInt simulator;



/*	given aPointer (returned from a library call),
	set the receiver's (bottom of stack) first instance variable
	to a ByteArray containing the pointer's bytes */

static sqInt ftAllocateHandleInReceiverForPointer(void *aPointer) {
	sqInt returnedHandle;
	void **extraByteArrayPtr;

	if (aPointer) {

		/* Allocate a Smalltalk ByteArray -- lastAlloc contains the length */


		/* Copy from the C bytecode buffer to the Smalltalk ByteArray */

		returnedHandle = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), sizeof(void **));
		extraByteArrayPtr = interpreterProxy->arrayValueOf(returnedHandle);
		*extraByteArrayPtr = (void *)(aPointer);
	} else {
		returnedHandle = interpreterProxy->nilObject();
	}
	interpreterProxy->storePointerofObjectwithValue(0, interpreterProxy->stackObjectValue(interpreterProxy->methodArgumentCount()), returnedHandle);
	;
	return returnedHandle;
}


/*	given NUL-terminated char* aPointer (returned from a library call), 
	return the oop for a String containing the pointer's bytes */

static sqInt ftAllocateStringForPointer(const char *aPointer) {
	sqInt returnedHandle;
	char *extraByteArrayPtr;

	if (aPointer) {

		/* Allocate a Smalltalk ByteArray -- lastAlloc contains the length */


		/* Copy from the C bytecode buffer to the Smalltalk ByteArray */

		returnedHandle = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(), strlen(aPointer));
		extraByteArrayPtr = interpreterProxy->arrayValueOf(returnedHandle);
		;
		strncpy(extraByteArrayPtr, aPointer, strlen(aPointer));
	} else {
		returnedHandle = interpreterProxy->nilObject();
	}
	return returnedHandle;
}


/*	Return a 32-bit word from the bytes held by string. */

static FT_Encoding ftEncodingValueFromString(sqInt string) {
	unsigned long retval;
	unsigned char*ptr;

	interpreterProxy->success((interpreterProxy->isBytes(string)) && ((interpreterProxy->slotSizeOf(string)) == (sizeof(FT_Encoding))));
	if (interpreterProxy->failed()) {
		return null;
	}
	retval = 0;

	/* 	ptr := self cCode: '(unsigned char *) (string + 4)'. */

	ptr = interpreterProxy->arrayValueOf(string);
	;
	retval = ((unsigned long)ptr[0]) << 24;
	retval += ((unsigned long)ptr[1]) << 16;
	retval += ((unsigned long)ptr[2]) << 8;
	retval += (unsigned long)ptr[3];
	;
	return (FT_Encoding)retval;
}


/*	this is the opposite of #ftAllocateHandleIn:forPointer: .
	It takes rcvr's first instance variable,
	which should be a ByteArray the size of a void*,
	and returns its value as a C pointer. */

static void * ftHandleValueFromReceiver(sqInt rcvrOop) {
	sqInt oop;
	sqInt btw;

	oop = interpreterProxy->fetchPointerofObject(0, rcvrOop);
	interpreterProxy->success((interpreterProxy->isBytes(oop)) && ((interpreterProxy->slotSizeOf(oop)) == (sizeof(void *))));
	if (interpreterProxy->failed()) {
		return null;
	}
	btw = BYTES_PER_WORD;
	return *(void**)(pointerForOop(oop + btw));
}


/*	Initialize the values in an FT_Bitmap from the given Form */

static int ftInitBitmapfromForm(FT_Bitmap*bitmap, sqInt formOop) {
	sqInt pixelMode;
	sqInt numGrays;
	sqInt width;
	sqInt depth;
	sqInt height;
	sqInt wordsPerRow;
	sqInt pitch;
	unsigned char*buffer;

	interpreterProxy->success(interpreterProxy->isPointers(formOop));
	interpreterProxy->success((interpreterProxy->slotSizeOf(formOop)) >= FormInstSize);
	if (interpreterProxy->failed()) {
		return null;
	}
	width = interpreterProxy->fetchIntegerofObject(FormWidthIndex, formOop);
	height = interpreterProxy->fetchIntegerofObject(FormHeightIndex, formOop);
	depth = interpreterProxy->fetchIntegerofObject(FormDepthIndex, formOop);
	buffer = ((void*) (interpreterProxy->fetchArrayofObject(FormBitsIndex, formOop)));
	if (interpreterProxy->failed()) {
		return null;
	}
	if (depth < 0) {
		depth = depth * -1;
	}
	if (depth == 1) {
		wordsPerRow = ((sqInt) (width + 0x1F) >> 5);
		numGrays = 1;
		pixelMode = FT_PIXEL_MODE_MONO;
	} else {
		if (depth == 8) {
			wordsPerRow = ((sqInt) (width + 3) >> 2);
			numGrays = 256;
			pixelMode = FT_PIXEL_MODE_GRAY;
		} else {
			return interpreterProxy->primitiveFail();
		}
	}
	
#ifndef WORDS_BIGENDIAN
	depth = depth * -1;
#endif
;
	interpreterProxy->storeIntegerofObjectwithValue(FormDepthIndex, formOop, depth);
	pitch = wordsPerRow * 4;
	bitmap->rows = height;
	bitmap->width = width;
	bitmap->pitch = pitch;
	bitmap->buffer = buffer;
	bitmap->num_grays = numGrays;
	bitmap->pixel_mode = pixelMode;
	return 1;
}


/*	Initialize the values in an FT_Bitmap from the given Form */
/*	pixelMode */

static int ftInitBitmapfromFormrenderMode(FT_Bitmap*bitmap, sqInt formOop, sqInt mode) {
	sqInt numGrays;
	sqInt width;
	sqInt depth;
	sqInt height;
	sqInt wordsPerRow;
	sqInt pitch;
	unsigned char*buffer;

	interpreterProxy->success(interpreterProxy->isPointers(formOop));
	interpreterProxy->success((interpreterProxy->slotSizeOf(formOop)) >= FormInstSize);
	if (interpreterProxy->failed()) {
		return null;
	}
	width = interpreterProxy->fetchIntegerofObject(FormWidthIndex, formOop);
	height = interpreterProxy->fetchIntegerofObject(FormHeightIndex, formOop);
	depth = interpreterProxy->fetchIntegerofObject(FormDepthIndex, formOop);
	buffer = ((void*) (interpreterProxy->fetchArrayofObject(FormBitsIndex, formOop)));
	if (interpreterProxy->failed()) {
		return null;
	}
	if (depth < 0) {
		depth = depth * -1;
	}
	if (depth == 1) {
		wordsPerRow = ((sqInt) (width + 0x1F) >> 5);
		numGrays = 1;
	} else {
		if (depth == 8) {
			wordsPerRow = ((sqInt) (width + 3) >> 2);
			numGrays = 256;
		} else {
			return interpreterProxy->primitiveFail();
		}
	}
	
#ifndef WORDS_BIGENDIAN
	depth = depth * -1;
#endif
;
	interpreterProxy->storeIntegerofObjectwithValue(FormDepthIndex, formOop, depth);
	pitch = wordsPerRow * 4;
	bitmap->rows = height;
	bitmap->width = width;
	bitmap->pitch = pitch;
	bitmap->buffer = buffer;
	bitmap->num_grays = numGrays;
	bitmap->pixel_mode = mode;
	return 1;
}

static int ftParameterError(void) {
	errorCode = 0xFF;
	return interpreterProxy->primitiveFail();
}


/*	Return a newly allocated String from the given 32-bit word */

static sqInt ftStringFromEncodingValue(FT_Encoding encoding) {
	unsigned char*ptr;
	sqInt stringOop;

	stringOop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(), sizeof(FT_Encoding));
	;
	if (interpreterProxy->failed()) {
		return null;
	}
	ptr = interpreterProxy->firstIndexableField(stringOop);
	;
	ptr[0] = (encoding & 0xFF000000) >> 24;
	ptr[1] = (encoding & 0x00FF0000) >> 16;
	ptr[2] = (encoding & 0x0000FF00) >> 8;
	ptr[3] = (encoding & 0x000000FF);
	return stringOop;
}


/*	Note: This is hardcoded so it can be run from Squeak.
	The module name is used for validating a module *after*
	it is loaded to check if it does really contain the module
	we're thinking it contains. This is important! */

EXPORT(const char*) getModuleName(void) {
	return moduleName;
}

static sqInt halt(void) {
	;
	return null;
}

EXPORT(sqInt) initialiseModule(void) {

	/* not implemented?? commented out because of compilation errors */
	/* self ifDefined: 'macintoshSqueak' then: [self fetchPreferences]. */

	library = null;
	errorCode = FT_Init_FreeType(&library);
	return errorCode == 0;
}

EXPORT(sqInt) primitiveCopyToExternalMemory(void) {
	void *aPointer;
	sqInt rcvr;
	size_t byteSize;
	char *aByteArray;
	sqInt _return_value;

	interpreterProxy->success(interpreterProxy->isBytes(interpreterProxy->stackValue(0)));
	aByteArray = ((char *) (interpreterProxy->firstIndexableField(interpreterProxy->stackValue(0))));
	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FreeTypeExternalMemory"));
	rcvr = interpreterProxy->stackValue(1);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(2, _return_value);
		return null;
	}
	;
	errorCode = 0;
	byteSize = interpreterProxy->byteSizeOf((oopForPointer( aByteArray ) - BASE_HEADER_SIZE));
	;
	if (interpreterProxy->failed()) {
		return null;
	}
	aPointer = malloc(byteSize);
	memcpy(aPointer,aByteArray,byteSize);
	ftAllocateHandleInReceiverForPointer(aPointer);
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->pop(1);
	return null;
}


/*	Call the library to release the given face record.
	Nil out the pointer fields */

EXPORT(sqInt) primitiveDoneFace(void) {
	sqInt rcvr;
	sqInt i;
	FT_Face face;
	sqInt _return_value;

	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Face"));
	rcvr = interpreterProxy->stackValue(0);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(1, _return_value);
		return null;
	}
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	;

	/* nil out all the fields */

	errorCode = FT_Done_Face(face);
	for (i = 0; i <= 23; i += 1) {
		interpreterProxy->storePointerofObjectwithValue(i, rcvr, interpreterProxy->nilObject());
	}
	interpreterProxy->success(errorCode == 0);
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	return null;
}


/*	Call the library to release the given face record.
	Nil out the handle field, but do not nil the other fields,
	as their values are needed even if the face cannot be re-opened
	in the future due to a missing font file etc. */

EXPORT(sqInt) primitiveDoneFacePreserveFields(void) {
	sqInt rcvr;
	FT_Face face;
	sqInt _return_value;

	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Face"));
	rcvr = interpreterProxy->stackValue(0);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(1, _return_value);
		return null;
	}
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	;

	/* nil the handle field */

	errorCode = FT_Done_Face(face);
	interpreterProxy->storePointerofObjectwithValue(0, rcvr, interpreterProxy->nilObject());
	interpreterProxy->success(errorCode == 0);
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	return null;
}


/*	emboldens the outline in the face's glyphSlot by strength (expressed in 26.6 pixel format).
	The new outline will be at most 4 times `strength' pixels wider and higher.  */

EXPORT(sqInt) primitiveEmboldenFaceGlyphSlotOutline(void) {
	sqInt rcvr;
	FT_Face face;
	sqInt strength;
	sqInt _return_value;

	strength = interpreterProxy->stackIntegerValue(0);
	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Face"));
	rcvr = interpreterProxy->stackValue(1);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(2, _return_value);
		return null;
	}
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	errorCode = FT_Outline_Embolden( &face->glyph->outline, strength );
	interpreterProxy->success(errorCode == 0);
	if (interpreterProxy->failed()) {
		return null;
	}
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->pop(1);
	return null;
}


/*	high byte is module error, low is generic error */

EXPORT(sqInt) primitiveErrorCode(void) {
	sqInt _return_value;

	_return_value = interpreterProxy->positive32BitIntegerFor((FT_ERROR_BASE(errorCode)));
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->popthenPush(1, _return_value);
	return null;
}

EXPORT(sqInt) primitiveFreeExternalMemory(void) {
	sqInt rcvr;
	void*memPointer;
	sqInt _return_value;

	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FreeTypeExternalMemory"));
	rcvr = interpreterProxy->stackValue(0);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(1, _return_value);
		return null;
	}
	;

	/* free the memory handle */

	errorCode = 0;
	memPointer = ftHandleValueFromReceiver(rcvr);
	if (!(memPointer == null)) {
		free(memPointer);
	}
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	return null;
}


/*	Return the Freetype glyph index of the given character code, in the 
	current encoding. 
	Return value of 0 means 'undefined character code'. */

EXPORT(sqInt) primitiveGetFaceCharIndex(void) {
	sqInt rcvr;
	sqInt result;
	FT_Face face;
	sqInt charIndex;
	sqInt _return_value;

	charIndex = interpreterProxy->stackIntegerValue(0);
	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Face"));
	rcvr = interpreterProxy->stackValue(1);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(2, _return_value);
		return null;
	}
	errorCode = 0;
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	result = FT_Get_Char_Index(face, charIndex);
	_return_value = interpreterProxy->positive32BitIntegerFor(result);
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->popthenPush(2, _return_value);
	return null;
}

EXPORT(sqInt) primitiveGetFaceCharMap(void) {
	FT_Encoding encoding;
	sqInt rcvr;
	FT_CharMap charmap;
	sqInt stringOop;
	FT_Face face;
	sqInt _return_value;

	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Face"));
	rcvr = interpreterProxy->stackValue(0);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(1, _return_value);
		return null;
	}
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	charmap = face->charmap;
	if (!(charmap)) {
		return null;
	}
	interpreterProxy->pushRemappableOop(rcvr);
	encoding = charmap->encoding;
	stringOop = ftStringFromEncodingValue(encoding);
	rcvr = interpreterProxy->popRemappableOop();
	interpreterProxy->storePointerofObjectwithValue(22, rcvr, stringOop);
	interpreterProxy->storeIntegerofObjectwithValue(23, rcvr, charmap->platform_id);
	interpreterProxy->storeIntegerofObjectwithValue(24, rcvr, charmap->encoding_id);
	if (interpreterProxy->failed()) {
		return null;
	}
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	return null;
}

EXPORT(sqInt) primitiveGetFaceCharMapsIntoArray(void) {
	FT_CharMap *charmap;
	int numCharmaps;
	sqInt i;
	sqInt stringOop;
	FT_Face face;
	sqInt arrayOop;
	sqInt rcvr;
	sqInt *array;
	sqInt _return_value;

	interpreterProxy->success(interpreterProxy->isIndexable(interpreterProxy->stackValue(0)));
	array = ((int *) (interpreterProxy->firstIndexableField(interpreterProxy->stackValue(0))));
	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Face"));
	rcvr = interpreterProxy->stackValue(1);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(2, _return_value);
		return null;
	}
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	numCharmaps = face->num_charmaps;
	arrayOop = oopForPointer(array) - BASE_HEADER_SIZE;
	interpreterProxy->success((interpreterProxy->slotSizeOf(arrayOop)) == numCharmaps);
	if (interpreterProxy->failed()) {
		return null;
	}
	charmap = face->charmaps;
	;
	for (i = 0; i <= (numCharmaps - 1); i += 1) {
		interpreterProxy->pushRemappableOop(arrayOop);
		stringOop = ftStringFromEncodingValue((*charmap)->encoding);
		arrayOop = interpreterProxy->popRemappableOop();
		interpreterProxy->storePointerofObjectwithValue(i, arrayOop, stringOop);
		charmap++;
	}
	if (interpreterProxy->failed()) {
		return null;
	}
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->pop(1);
	return null;
}


/*	return a String */

EXPORT(sqInt) primitiveGetFaceGlyphName(void) {
	char buffer[100];
	sqInt rcvr;
	sqInt string;
	FT_Face face;
	sqInt glyphIndex;
	sqInt _return_value;

	glyphIndex = interpreterProxy->stackIntegerValue(0);
	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Face"));
	rcvr = interpreterProxy->stackValue(1);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(2, _return_value);
		return null;
	}
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	errorCode = FT_Get_Glyph_Name(face, glyphIndex, buffer, 100);
	interpreterProxy->success(errorCode == 0);
	if (interpreterProxy->failed()) {
		return null;
	}
	string = ftAllocateStringForPointer(buffer);
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->popthenPush(2, string);
	return null;
}

EXPORT(sqInt) primitiveGetKerningLeftRight(void) {
	FT_Face face;
	sqInt rcvr;
	sqInt kernMode;
	FT_Vector result;
	sqInt pointOop;
	sqInt leftGlyph;
	sqInt rightGlyph;
	sqInt _return_value;

	leftGlyph = interpreterProxy->stackIntegerValue(1);
	rightGlyph = interpreterProxy->stackIntegerValue(0);
	
		result.x=3;
		result.y=4;;
	;
	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(2), "FT2Face"));
	rcvr = interpreterProxy->stackValue(2);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(3, _return_value);
		return null;
	}
	errorCode = 0;
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	kernMode = FT_KERNING_UNSCALED;
	;
	FT_Get_Kerning(face, leftGlyph, rightGlyph, kernMode, &result);;
	pointOop = interpreterProxy->makePointwithxValueyValue(result.x, result.y);
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->popthenPush(3, pointOop);
	return null;
}


/*	return a String */

EXPORT(sqInt) primitiveGetPostscriptName(void) {
	char*buffer;
	sqInt rcvr;
	sqInt string;
	FT_Face face;
	sqInt _return_value;

	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Face"));
	rcvr = interpreterProxy->stackValue(0);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(1, _return_value);
		return null;
	}
	buffer = 0;
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	buffer = FT_Get_Postscript_Name(face);
	interpreterProxy->success(buffer != 0);
	if (interpreterProxy->failed()) {
		return null;
	}
	string = ftAllocateStringForPointer(buffer);
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->popthenPush(1, string);
	return null;
}


/*	return the bytes from the OS/2 table */

EXPORT(sqInt) primitiveGetSfntTableOS2(void) {
	char *buffer;
	sqInt rcvr;
	sqInt returnedHandle;
	char *extraByteArrayPtr;
	FT_Face face;
	sqInt _return_value;

	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Face"));
	rcvr = interpreterProxy->stackValue(0);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(1, _return_value);
		return null;
	}
	buffer = 0;
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	buffer = FT_Get_Sfnt_Table(face,ft_sfnt_os2);
	if (buffer == 0) {
		_return_value = interpreterProxy->integerObjectOf(-1);
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(1, _return_value);
		return null;
	}

	/* Copy from the C bytecode buffer to the Smalltalk ByteArray */

	returnedHandle = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), sizeof(TT_OS2));
	extraByteArrayPtr = interpreterProxy->arrayValueOf(returnedHandle);
	;
	memcpy(extraByteArrayPtr, buffer, sizeof(TT_OS2));
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->popthenPush(1, returnedHandle);
	return null;
}

EXPORT(sqInt) primitiveHasKerning(void) {
	sqInt rcvr;
	FT_Face face;
	sqInt _return_value;


	/* ptr to struct */

	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Face"));
	rcvr = interpreterProxy->stackValue(0);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(1, _return_value);
		return null;
	}
	errorCode = 0;
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	_return_value = (((FT_HAS_KERNING( face )) << 1) | 1);
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->popthenPush(1, _return_value);
	return null;
}


/*	Fill in the handle in an FT2Library structure with a copy of our global pointer. */

EXPORT(sqInt) primitiveLibraryHandle(void) {
	sqInt rcvr;
	sqInt _return_value;

	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Library"));
	rcvr = interpreterProxy->stackValue(0);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(1, _return_value);
		return null;
	}
	errorCode = 0;
	ftAllocateHandleInReceiverForPointer((void  *)library);
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	return null;
}


/*	Load the glyph at the given index in the current charmap.
	The default map upon opening a font is the 'unic' or Unicode charmap, if any. */

EXPORT(sqInt) primitiveLoadCharacter(void) {
	sqInt rcvr;
	FT_Face face;
	sqInt index;
	sqInt flags;
	sqInt _return_value;

	index = interpreterProxy->stackIntegerValue(1);
	flags = interpreterProxy->stackIntegerValue(0);
	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(2), "FT2Face"));
	rcvr = interpreterProxy->stackValue(2);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(3, _return_value);
		return null;
	}
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	errorCode = FT_Load_Char(face, index, flags);
	interpreterProxy->success(errorCode == 0);
	if (interpreterProxy->failed()) {
		return null;
	}
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->pop(2);
	return null;
}

EXPORT(sqInt) primitiveLoadFaceBbox(void) {
	sqInt rcvr;
	sqInt pointOop;
	FT_Face face;
	sqInt rectOop;
	sqInt aRectangle;
	sqInt _return_value;

	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "Rectangle"));
	aRectangle = interpreterProxy->stackValue(0);
	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Face"));
	rcvr = interpreterProxy->stackValue(1);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(2, _return_value);
		return null;
	}
	rectOop = aRectangle;
	if (!(interpreterProxy->isPointers(rectOop))) {
		interpreterProxy->primitiveFail();
		return null;
	}
	if ((interpreterProxy->slotSizeOf(rectOop)) < 2) {
		interpreterProxy->primitiveFail();
		return null;
	}
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	;
	if (!(face->face_flags & FT_FACE_FLAG_SCALABLE)) {
		interpreterProxy->success(0);
	}
	if (interpreterProxy->failed()) {
		return null;
	}
	interpreterProxy->pushRemappableOop(rectOop);
	pointOop = interpreterProxy->makePointwithxValueyValue(face->bbox.xMin, face->bbox.yMin);
	rectOop = interpreterProxy->popRemappableOop();
	interpreterProxy->storePointerofObjectwithValue(0, rectOop, pointOop);
	interpreterProxy->pushRemappableOop(rectOop);
	pointOop = interpreterProxy->makePointwithxValueyValue(face->bbox.xMax, face->bbox.yMax);
	rectOop = interpreterProxy->popRemappableOop();
	interpreterProxy->storePointerofObjectwithValue(1, rectOop, pointOop);
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->pop(1);
	return null;
}


/*	Fill in many of the receiver's (an FT2Face) fields (other than its handle)
	from the FT_Face record that it points to. */

EXPORT(sqInt) primitiveLoadFaceFields(void) {
	sqInt rcvr;
	sqInt strOop;
	FT_Face face;
	sqInt _return_value;

	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Face"));
	rcvr = interpreterProxy->stackValue(0);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(1, _return_value);
		return null;
	}
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	;
	interpreterProxy->storeIntegerofObjectwithValue(1, rcvr, face->num_faces);
	interpreterProxy->storeIntegerofObjectwithValue(2, rcvr, face->face_index);
	interpreterProxy->storeIntegerofObjectwithValue(3, rcvr, face->face_flags);
	interpreterProxy->storeIntegerofObjectwithValue(4, rcvr, face->style_flags);
	interpreterProxy->storeIntegerofObjectwithValue(5, rcvr, face->num_glyphs);
	interpreterProxy->pushRemappableOop(rcvr);
	strOop = ftAllocateStringForPointer(face->family_name);
	rcvr = interpreterProxy->popRemappableOop();
	interpreterProxy->storePointerofObjectwithValue(6, rcvr, strOop);
	interpreterProxy->pushRemappableOop(rcvr);
	strOop = ftAllocateStringForPointer(face->style_name);
	rcvr = interpreterProxy->popRemappableOop();
	interpreterProxy->storePointerofObjectwithValue(7, rcvr, strOop);
	interpreterProxy->storeIntegerofObjectwithValue(8, rcvr, face->num_fixed_sizes);
	interpreterProxy->storeIntegerofObjectwithValue(10, rcvr, face->num_charmaps);
	if (face->face_flags & FT_FACE_FLAG_SCALABLE) {

		/* bbox -- Rectangle xMin, yMin, xMax, yMax */
		/* unitsPerEm */

		interpreterProxy->storeIntegerofObjectwithValue(13, rcvr, face->units_per_EM);
		interpreterProxy->storeIntegerofObjectwithValue(14, rcvr, face->ascender);
		interpreterProxy->storeIntegerofObjectwithValue(15, rcvr, face->descender);
		interpreterProxy->storeIntegerofObjectwithValue(16, rcvr, face->height);
		interpreterProxy->storeIntegerofObjectwithValue(17, rcvr, face->max_advance_width);
		interpreterProxy->storeIntegerofObjectwithValue(18, rcvr, face->max_advance_height);
		interpreterProxy->storeIntegerofObjectwithValue(19, rcvr, face->underline_position);
		interpreterProxy->storeIntegerofObjectwithValue(20, rcvr, face->underline_thickness);
	}
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	return null;
}

EXPORT(sqInt) primitiveLoadGlyph(void) {
	sqInt rcvr;
	FT_Face face;
	sqInt index;
	sqInt flags;
	sqInt _return_value;

	index = interpreterProxy->stackIntegerValue(1);
	flags = interpreterProxy->stackIntegerValue(0);
	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(2), "FT2Face"));
	rcvr = interpreterProxy->stackValue(2);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(3, _return_value);
		return null;
	}
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	errorCode = FT_Load_Glyph(face, index, flags);
	interpreterProxy->success(errorCode == 0);
	if (interpreterProxy->failed()) {
		return null;
	}
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->pop(2);
	return null;
}


/*	Assumes that primitiveLoadGlyph:flags: has been called earlier to set face->glyph. */

EXPORT(sqInt) primitiveLoadGlyphSlotFromFace(void) {
	FT_Glyph_Format *gfPtr;
	FT_GlyphSlot gs;
	FT_Face face;
	sqInt btw;
	sqInt gfOop;
	sqInt rcvr;
	sqInt aFace;
	sqInt _return_value;

	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Face"));
	aFace = interpreterProxy->stackValue(0);
	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2GlyphSlot"));
	rcvr = interpreterProxy->stackValue(1);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(2, _return_value);
		return null;
	}
	errorCode = 0;
	if ((interpreterProxy->slotSizeOf(rcvr)) < 8) {
		interpreterProxy->primitiveFail();
		return null;
	}
	face = ftHandleValueFromReceiver(aFace);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	gs = face->glyph;
	if (!(gs)) {
		interpreterProxy->primitiveFail();
		return null;
	}
	;
	interpreterProxy->storePointerofObjectwithValue(0, rcvr, aFace);
	interpreterProxy->storeIntegerofObjectwithValue(1, rcvr, gs->linearHoriAdvance);
	interpreterProxy->storeIntegerofObjectwithValue(2, rcvr, gs->linearVertAdvance);
	interpreterProxy->storeIntegerofObjectwithValue(3, rcvr, gs->advance.x);
	interpreterProxy->storeIntegerofObjectwithValue(4, rcvr, gs->advance.y);
	interpreterProxy->pushRemappableOop(rcvr);
	gfOop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), sizeof(FT_Glyph_Format));
	;
	btw = BYTES_PER_WORD;
	gfPtr = (FT_Glyph_Format *) pointerForOop(gfOop + btw);
	;
	if (interpreterProxy->failed()) {
		return null;
	}
	*gfPtr = gs->format;
	rcvr = interpreterProxy->popRemappableOop();
	interpreterProxy->storePointerofObjectwithValue(5, rcvr, gfOop);
	interpreterProxy->storeIntegerofObjectwithValue(6, rcvr, gs->bitmap_left);
	interpreterProxy->storeIntegerofObjectwithValue(7, rcvr, gs->bitmap_top);
	interpreterProxy->storeIntegerofObjectwithValue(8, rcvr, gs->metrics.width);
	interpreterProxy->storeIntegerofObjectwithValue(9, rcvr, gs->metrics.height);
	interpreterProxy->storeIntegerofObjectwithValue(10, rcvr, gs->metrics.horiBearingX);
	interpreterProxy->storeIntegerofObjectwithValue(11, rcvr, gs->metrics.horiBearingY);
	interpreterProxy->storeIntegerofObjectwithValue(12, rcvr, gs->metrics.horiAdvance);
	interpreterProxy->storeIntegerofObjectwithValue(13, rcvr, gs->metrics.vertBearingX);
	interpreterProxy->storeIntegerofObjectwithValue(14, rcvr, gs->metrics.vertBearingY);
	interpreterProxy->storeIntegerofObjectwithValue(15, rcvr, gs->metrics.vertAdvance);
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->pop(1);
	return null;
}


/*	Assumes that primitiveLoadGlyph:flags: has been called earlier to set face->glyph. */

EXPORT(sqInt) primitiveLoadOutlineArraysFromFace(void) {
	sqInt i;
	sqInt pointsSize;
	FT_GlyphSlot gs;
	FT_Face face;
	sqInt rcvr;
	char * tags;
	short* contours;
	sqInt contoursSize;
	long * points;
	sqInt aFace;
	sqInt _return_value;
	sqInt array;
	sqInt array1;
	sqInt array2;


	/* ptr to struct */
	/* ptr to struct */

	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Face"));
	aFace = interpreterProxy->stackValue(0);
	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Outline"));
	rcvr = interpreterProxy->stackValue(1);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(2, _return_value);
		return null;
	}
	errorCode = 0;
	if ((interpreterProxy->slotSizeOf(rcvr)) < FT2OutlineInstSize) {
		interpreterProxy->primitiveFail();
		return null;
	}
	face = ftHandleValueFromReceiver(aFace);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	gs = face->glyph;
	if (!(gs)) {
		interpreterProxy->primitiveFail();
		return null;
	}
	;
	pointsSize = gs->outline.n_points;
	/* begin fetchWordArray:ofObject:assureSize: */
	array = interpreterProxy->fetchPointerofObject(FT2OutlinePointsIndex, rcvr);
	if ((interpreterProxy->isWords(array)) && ((interpreterProxy->slotSizeOf(array)) == (pointsSize * 2))) {
		points = interpreterProxy->arrayValueOf(array);
		goto l1;
	}
	points = null;
l1:	/* end fetchWordArray:ofObject:assureSize: */;
	if (points == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	/* begin fetchByteArray:ofObject:assureSize: */
	array1 = interpreterProxy->fetchPointerofObject(FT2OutlineTagsIndex, rcvr);
	if ((interpreterProxy->isBytes(array1)) && ((interpreterProxy->slotSizeOf(array1)) == pointsSize)) {
		tags = interpreterProxy->arrayValueOf(array1);
		goto l2;
	}
	tags = null;
l2:	/* end fetchByteArray:ofObject:assureSize: */;
	if (tags == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	for (i = 0; i <= (pointsSize - 1); i += 1) {
		points[2 * i] = (gs->outline.points[i].x);
		points[(2 * i) + 1] = (gs->outline.points[i].y);
		tags[i] = (gs->outline.tags[i]);
	}
	contoursSize = gs->outline.n_contours;
	/* begin fetchShortArray:ofObject:assureSize: */
	array2 = interpreterProxy->fetchPointerofObject(FT2OutlineContoursIndex, rcvr);
	if ((interpreterProxy->isWords(array2)) && ((interpreterProxy->slotSizeOf(array2)) == (((sqInt) (contoursSize + 1) >> 1)))) {
		contours = interpreterProxy->arrayValueOf(array2);
		goto l3;
	}
	contours = null;
l3:	/* end fetchShortArray:ofObject:assureSize: */;
	for (i = 0; i <= (contoursSize - 1); i += 1) {
		contours[i] = (gs->outline.contours[i]);
	}
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->pop(1);
	return null;
}


/*	Assumes that primitiveLoadGlyph:flags: has been called earlier to set face->glyph. */

EXPORT(sqInt) primitiveLoadOutlineSizesFromFace(void) {
	sqInt rcvr;
	FT_GlyphSlot gs;
	FT_Face face;
	sqInt aFace;
	sqInt _return_value;


	/* ptr to struct */

	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Face"));
	aFace = interpreterProxy->stackValue(0);
	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Outline"));
	rcvr = interpreterProxy->stackValue(1);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(2, _return_value);
		return null;
	}
	errorCode = 0;
	if ((interpreterProxy->slotSizeOf(rcvr)) < FT2OutlineInstSize) {
		interpreterProxy->primitiveFail();
		return null;
	}
	face = ftHandleValueFromReceiver(aFace);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	gs = face->glyph;
	if (!(gs)) {
		interpreterProxy->primitiveFail();
		return null;
	}
	;
	interpreterProxy->storeIntegerofObjectwithValue(FT2OutlineContoursSizeIndex, rcvr, gs->outline.n_contours);
	interpreterProxy->storeIntegerofObjectwithValue(FT2OutlinePointsSizeIndex, rcvr, gs->outline.n_points);
	interpreterProxy->storeIntegerofObjectwithValue(FT2OutlineFlagsIndex, rcvr, gs->outline.flags);
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->pop(1);
	return null;
}


/*	high byte is module error, low is generic error */

EXPORT(sqInt) primitiveModuleErrorCode(void) {
	sqInt _return_value;

	_return_value = interpreterProxy->positive32BitIntegerFor((FT_ERROR_MODULE(errorCode)));
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->popthenPush(1, _return_value);
	return null;
}


/*	Fill in the receiver's (a FT2Face object) fields
	from the address and fields of a newly opened FT_Face object. */

EXPORT(sqInt) primitiveNewFaceFromFileAndIndex(void) {
	char translatedFilePath[1024];
	sqInt rcvr;
	size_t byteSize;
	FT_Face face;
	char *fontFilePath;
	sqInt anInteger;
	sqInt _return_value;

	interpreterProxy->success(interpreterProxy->isBytes(interpreterProxy->stackValue(1)));
	fontFilePath = ((char *) (interpreterProxy->firstIndexableField(interpreterProxy->stackValue(1))));
	anInteger = interpreterProxy->stackIntegerValue(0);
	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(2), "FT2Face"));
	rcvr = interpreterProxy->stackValue(2);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(3, _return_value);
		return null;
	}
	;
	errorCode = 0;
	byteSize = interpreterProxy->byteSizeOf((oopForPointer( fontFilePath ) - BASE_HEADER_SIZE));
	;
	if (interpreterProxy->failed()) {
		return null;
	}
	if (byteSize > 1000) {
		interpreterProxy->success(0);
		return null;
	}
	interpreterProxy->ioFilenamefromStringofLengthresolveAliases(translatedFilePath, fontFilePath, byteSize, 1);
	errorCode = FT_New_Face(library, translatedFilePath, anInteger, &face);
	;
	;
	interpreterProxy->success(errorCode == 0);
	if (interpreterProxy->failed()) {
		return null;
	}
	ftAllocateHandleInReceiverForPointer(face);
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->pop(2);
	return null;
}


/*	Fill in the receiver's (a FT2Face object) fields
	from the address and fields of a newly opened FT_Face object. */

EXPORT(sqInt) primitiveNewMemoryFaceFromExternalMemoryAndIndex(void) {
	sqInt rcvr;
	void *memPointer;
	FT_Face face;
	sqInt aFreeTypeExternalMemory;
	sqInt byteSize;
	sqInt anInteger;
	sqInt _return_value;

	aFreeTypeExternalMemory = interpreterProxy->stackValue(2);
	byteSize = interpreterProxy->stackIntegerValue(1);
	anInteger = interpreterProxy->stackIntegerValue(0);
	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(3), "FT2Face"));
	rcvr = interpreterProxy->stackValue(3);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(4, _return_value);
		return null;
	}
	;
	errorCode = 0;
	memPointer = ftHandleValueFromReceiver(aFreeTypeExternalMemory);
	;
	if (interpreterProxy->failed()) {
		return null;
	}
	errorCode = FT_New_Memory_Face(library, memPointer, byteSize, anInteger, &face);
	;
	;
	interpreterProxy->success(errorCode == 0);
	if (interpreterProxy->failed()) {
		return null;
	}
	ftAllocateHandleInReceiverForPointer(face);
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->pop(3);
	return null;
}


/*	Assumes that primitiveLoadGlyph:flags: has been called earlier to set face->glyph. */

EXPORT(sqInt) primitiveNumberOfOutlineCountours(void) {
	sqInt rcvr;
	sqInt contoursSize;
	FT_GlyphSlot gs;
	sqInt aFace;
	FT_Face face;
	sqInt _return_value;


	/* ptr to struct */

	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2GlyphSlot"));
	rcvr = interpreterProxy->stackValue(0);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(1, _return_value);
		return null;
	}
	errorCode = 0;
	if ((interpreterProxy->slotSizeOf(rcvr)) < FT2GlyphSlotInstSize) {
		interpreterProxy->primitiveFail();
		return null;
	}
	aFace = interpreterProxy->fetchPointerofObject(FT2GlyphSlotFaceIndex, rcvr);
	face = ftHandleValueFromReceiver(aFace);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	gs = face->glyph;
	if (!(gs)) {
		interpreterProxy->primitiveFail();
		return null;
	}
	;
	contoursSize = gs->outline.n_contours;
	_return_value = ((contoursSize << 1) | 1);
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->popthenPush(1, _return_value);
	return null;
}


/*	Render this face into the given form */

EXPORT(sqInt) primitiveRenderGlyphIntoForm(void) {
	FT_Bitmap bitmap;
	sqInt faceOop;
	FT_Face face;
	sqInt formOop;
	sqInt _return_value;


	/* temp struct */

	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "Form"));
	formOop = interpreterProxy->stackValue(0);
	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Face"));
	faceOop = interpreterProxy->stackValue(1);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(2, _return_value);
		return null;
	}
	face = ftHandleValueFromReceiver(faceOop);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	ftInitBitmapfromForm(&bitmap, formOop);
	if (interpreterProxy->failed()) {
		return null;
	}
	errorCode = FT_Outline_Get_Bitmap(library, &face->glyph->outline, &bitmap);
	interpreterProxy->success(errorCode == 0);
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->pop(1);
	return null;
}


/*	Render this face into the given form */

EXPORT(sqInt) primitiveRenderGlyphIntoFormWithRenderMode(void) {
	FT_Bitmap bitmap;
	sqInt faceOop;
	FT_Face face;
	sqInt formOop;
	sqInt mode;
	sqInt _return_value;


	/* temp struct */

	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "Form"));
	formOop = interpreterProxy->stackValue(1);
	mode = interpreterProxy->stackIntegerValue(0);
	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(2), "FT2Face"));
	faceOop = interpreterProxy->stackValue(2);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(3, _return_value);
		return null;
	}
	face = ftHandleValueFromReceiver(faceOop);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	ftInitBitmapfromFormrenderMode(&bitmap, formOop, mode);
	if (interpreterProxy->failed()) {
		return null;
	}
	errorCode = FT_Outline_Get_Bitmap(library, &face->glyph->outline, &bitmap);
	interpreterProxy->success(errorCode == 0);
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->pop(2);
	return null;
}

EXPORT(sqInt) primitiveResetErrorCode(void) {
	sqInt oldError;
	sqInt _return_value;

	oldError = errorCode;
	errorCode = 0;
	_return_value = interpreterProxy->positive32BitIntegerFor(oldError);
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->popthenPush(1, _return_value);
	return null;
}

EXPORT(sqInt) primitiveSetFaceCharMap(void) {
	FT_Encoding encoding;
	sqInt rcvr;
	FT_Face face;
	sqInt encodingString;
	sqInt _return_value;

	encodingString = interpreterProxy->stackValue(0);
	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Face"));
	rcvr = interpreterProxy->stackValue(1);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(2, _return_value);
		return null;
	}
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	encoding = ftEncodingValueFromString(encodingString);
	if (interpreterProxy->failed()) {
		return null;
	}
	;
	errorCode = FT_Select_Charmap(face, encoding);
	interpreterProxy->success(errorCode == 0);
	if (interpreterProxy->failed()) {
		return null;
	}
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->pop(1);
	return null;
}

EXPORT(sqInt) primitiveSetPixelSizes(void) {
	sqInt rcvr;
	FT_Face face;
	sqInt x;
	sqInt y;
	sqInt _return_value;

	x = interpreterProxy->stackIntegerValue(1);
	y = interpreterProxy->stackIntegerValue(0);
	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(2), "FT2Face"));
	rcvr = interpreterProxy->stackValue(2);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(3, _return_value);
		return null;
	}
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	errorCode = FT_Set_Pixel_Sizes(face, x, y);
	interpreterProxy->success(errorCode == 0);
	if (interpreterProxy->failed()) {
		return null;
	}
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->pop(2);
	return null;
}

EXPORT(sqInt) primitiveSetTransform(void) {
	sqInt *matrixsqIntPtr;
	sqInt *deltasqIntPtr;
	FT_Face face;
	FT_Vector delta;
	FT_Matrix matrix;
	sqInt rcvr;
	sqInt matrixWordArray;
	sqInt deltaWordArray;
	sqInt _return_value;

	matrixWordArray = interpreterProxy->stackValue(1);
	deltaWordArray = interpreterProxy->stackValue(0);
	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(2), "FT2Face"));
	rcvr = interpreterProxy->stackValue(2);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(3, _return_value);
		return null;
	}
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	matrixsqIntPtr = interpreterProxy->arrayValueOf(matrixWordArray);
	deltasqIntPtr = interpreterProxy->arrayValueOf(deltaWordArray);
	delta.x = deltasqIntPtr[0]; delta.y = deltasqIntPtr[1];;
	matrix.xx = matrixsqIntPtr[0]; matrix.xy = matrixsqIntPtr[1]; 
		matrix.yx = matrixsqIntPtr[2]; matrix.yy = matrixsqIntPtr[3]; ;
	if (!(interpreterProxy->failed())) {
		FT_Set_Transform( face, &matrix, &delta);
	}
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->pop(2);
	return null;
}

EXPORT(sqInt) primitiveTransformFaceGlyphSlotOutline(void) {
	FT_Matrix matrix;
	sqInt rcvr;
	sqInt *matrixsqIntPtr;
	FT_Face face;
	sqInt matrixWordArray;
	sqInt _return_value;

	matrixWordArray = interpreterProxy->stackValue(0);
	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Face"));
	rcvr = interpreterProxy->stackValue(1);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(2, _return_value);
		return null;
	}
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	matrixsqIntPtr = interpreterProxy->arrayValueOf(matrixWordArray);
	matrix.xx = matrixsqIntPtr[0]; matrix.xy = matrixsqIntPtr[1]; 
		matrix.yx = matrixsqIntPtr[2]; matrix.yy = matrixsqIntPtr[3]; ;
	if (!(interpreterProxy->failed())) {
		FT_Outline_Transform( &face->glyph->outline, &matrix );
	}
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->pop(1);
	return null;
}

EXPORT(sqInt) primitiveTranslateFaceGlyphSlotOutline(void) {
	sqInt rcvr;
	FT_Vector delta;
	sqInt *deltasqIntPtr;
	FT_Face face;
	sqInt deltaWordArray;
	sqInt _return_value;

	deltaWordArray = interpreterProxy->stackValue(0);
	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Face"));
	rcvr = interpreterProxy->stackValue(1);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(2, _return_value);
		return null;
	}
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
		interpreterProxy->primitiveFail();
		return null;
	}
	deltasqIntPtr = interpreterProxy->arrayValueOf(deltaWordArray);
	delta.x = deltasqIntPtr[0]; delta.y = deltasqIntPtr[1];;
	if (!(interpreterProxy->failed())) {
		FT_Outline_Translate( &face->glyph->outline, delta.x, delta.y );
	}
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	interpreterProxy->pop(1);
	return null;
}

EXPORT(sqInt) primitiveVersion(void) {
	int aminor;
	int apatch;
	sqInt rcvr;
	int amajor;
	sqInt _return_value;

	interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Version"));
	rcvr = interpreterProxy->stackValue(0);
	if (interpreterProxy->failed()) {
		_return_value = ftParameterError();
		if (interpreterProxy->failed()) {
			return ftParameterError();
		}
		interpreterProxy->popthenPush(1, _return_value);
		return null;
	}
	errorCode = 0;
	FT_Library_Version(library, &amajor, &aminor, &apatch);
	;
	interpreterProxy->storeIntegerofObjectwithValue(0, rcvr, amajor);
	;
	interpreterProxy->storeIntegerofObjectwithValue(1, rcvr, aminor);
	;
	interpreterProxy->storeIntegerofObjectwithValue(2, rcvr, apatch);
	if (interpreterProxy->failed()) {
		return ftParameterError();
	}
	return null;
}


/*	Note: This is coded so that is can be run from Squeak. */

EXPORT(sqInt) setInterpreter(struct VirtualMachine*anInterpreter) {
	sqInt ok;

	interpreterProxy = anInterpreter;
	ok = interpreterProxy->majorVersion() == VM_PROXY_MAJOR;
	if (ok == 0) {
		return 0;
	}
	ok = interpreterProxy->minorVersion() >= VM_PROXY_MINOR;
	return ok;
}

EXPORT(sqInt) shutdownModule(void) {
	errorCode = FT_Done_FreeType(library);
	if (errorCode == 0) {
		library = null;
	}
	return errorCode == 0;
}


#ifdef SQUEAK_BUILTIN_PLUGIN


void* FT2Plugin_exports[][3] = {
	{"FT2Plugin", "primitiveTransformFaceGlyphSlotOutline", (void*)primitiveTransformFaceGlyphSlotOutline},
	{"FT2Plugin", "primitiveModuleErrorCode", (void*)primitiveModuleErrorCode},
	{"FT2Plugin", "primitiveLoadFaceFields", (void*)primitiveLoadFaceFields},
	{"FT2Plugin", "primitiveGetFaceGlyphName", (void*)primitiveGetFaceGlyphName},
	{"FT2Plugin", "shutdownModule", (void*)shutdownModule},
	{"FT2Plugin", "primitiveGetSfntTableOS2", (void*)primitiveGetSfntTableOS2},
	{"FT2Plugin", "primitiveDoneFace", (void*)primitiveDoneFace},
	{"FT2Plugin", "primitiveNewFaceFromFileAndIndex", (void*)primitiveNewFaceFromFileAndIndex},
	{"FT2Plugin", "primitiveLibraryHandle", (void*)primitiveLibraryHandle},
	{"FT2Plugin", "primitiveGetKerningLeftRight", (void*)primitiveGetKerningLeftRight},
	{"FT2Plugin", "primitiveLoadOutlineArraysFromFace", (void*)primitiveLoadOutlineArraysFromFace},
	{"FT2Plugin", "primitiveEmboldenFaceGlyphSlotOutline", (void*)primitiveEmboldenFaceGlyphSlotOutline},
	{"FT2Plugin", "primitiveLoadGlyph", (void*)primitiveLoadGlyph},
	{"FT2Plugin", "getModuleName", (void*)getModuleName},
	{"FT2Plugin", "primitiveSetTransform", (void*)primitiveSetTransform},
	{"FT2Plugin", "primitiveResetErrorCode", (void*)primitiveResetErrorCode},
	{"FT2Plugin", "primitiveLoadGlyphSlotFromFace", (void*)primitiveLoadGlyphSlotFromFace},
	{"FT2Plugin", "primitiveNumberOfOutlineCountours", (void*)primitiveNumberOfOutlineCountours},
	{"FT2Plugin", "primitiveSetPixelSizes", (void*)primitiveSetPixelSizes},
	{"FT2Plugin", "primitiveTranslateFaceGlyphSlotOutline", (void*)primitiveTranslateFaceGlyphSlotOutline},
	{"FT2Plugin", "setInterpreter", (void*)setInterpreter},
	{"FT2Plugin", "primitiveGetFaceCharMapsIntoArray", (void*)primitiveGetFaceCharMapsIntoArray},
	{"FT2Plugin", "primitiveHasKerning", (void*)primitiveHasKerning},
	{"FT2Plugin", "primitiveGetFaceCharIndex", (void*)primitiveGetFaceCharIndex},
	{"FT2Plugin", "primitiveCopyToExternalMemory", (void*)primitiveCopyToExternalMemory},
	{"FT2Plugin", "primitiveLoadFaceBbox", (void*)primitiveLoadFaceBbox},
	{"FT2Plugin", "primitiveDoneFacePreserveFields", (void*)primitiveDoneFacePreserveFields},
	{"FT2Plugin", "primitiveNewMemoryFaceFromExternalMemoryAndIndex", (void*)primitiveNewMemoryFaceFromExternalMemoryAndIndex},
	{"FT2Plugin", "primitiveGetFaceCharMap", (void*)primitiveGetFaceCharMap},
	{"FT2Plugin", "primitiveSetFaceCharMap", (void*)primitiveSetFaceCharMap},
	{"FT2Plugin", "primitiveLoadOutlineSizesFromFace", (void*)primitiveLoadOutlineSizesFromFace},
	{"FT2Plugin", "primitiveFreeExternalMemory", (void*)primitiveFreeExternalMemory},
	{"FT2Plugin", "primitiveErrorCode", (void*)primitiveErrorCode},
	{"FT2Plugin", "initialiseModule", (void*)initialiseModule},
	{"FT2Plugin", "primitiveGetPostscriptName", (void*)primitiveGetPostscriptName},
	{"FT2Plugin", "primitiveLoadCharacter", (void*)primitiveLoadCharacter},
	{"FT2Plugin", "primitiveVersion", (void*)primitiveVersion},
	{"FT2Plugin", "primitiveRenderGlyphIntoForm", (void*)primitiveRenderGlyphIntoForm},
	{"FT2Plugin", "primitiveRenderGlyphIntoFormWithRenderMode", (void*)primitiveRenderGlyphIntoFormWithRenderMode},
	{NULL, NULL, NULL}
};


#endif /* ifdef SQ_BUILTIN_PLUGIN */

