/* Automatically generated by
	FT2PluginCodeGenerator Freetype-Plugin-EstebanLorenzano.70 uuid: 3729adbd-b383-456b-96ec-dac31cd293f8
   from
	FT2Plugin Freetype-Plugin-EstebanLorenzano.70 uuid: 3729adbd-b383-456b-96ec-dac31cd293f8
 */
static char __buildInfo[] = "FT2Plugin Freetype-Plugin-EstebanLorenzano.70 uuid: 3729adbd-b383-456b-96ec-dac31cd293f8 " __DATE__ ;



#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ft2build.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. */
#include "sqConfig.h"			/* Configuration options */
#include "sqVirtualMachine.h"	/*  The virtual machine proxy definition */
#include "sqPlatformSpecific.h"	/* Platform specific definitions */

#define true 1
#define false 0
#define null 0  /* using 'null' because nil is predefined in Think C */
#ifdef SQUEAK_BUILTIN_PLUGIN
# undef EXPORT
# define EXPORT(returnType) static returnType
#endif

#include FT_TRUETYPE_TABLES_H
#include FT_FREETYPE_H
#include FT_OUTLINE_H
#include "sqMemoryAccess.h"


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

typedef struct {
	int	errCode;
	char *errMsg;
 } FT2Error;

#define FT2ErrorStruct FT2Error



/*** Function Prototypes ***/
static char * fetchByteArrayofObjectassureSize(sqInt fieldIndex, sqInt objectPointer, sqInt aSize);
static short* fetchShortArrayofObjectassureSize(sqInt fieldIndex, sqInt objectPointer, sqInt aSize);
static long * fetchWordArrayofObjectassureSize(sqInt fieldIndex, sqInt objectPointer, sqInt aSize);
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);
EXPORT(const char*) getModuleName(void);
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) primitiveErrorString(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);
static sqInt primitiveGetTrackKerningPointSizedegree(sqInt pointSize, sqInt degree);
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);
static sqInt sqAssert(sqInt aBool);


/*** Variables ***/
static int errorCode;

#if !defined(SQUEAK_BUILTIN_PLUGIN)
static void * (*arrayValueOf)(sqInt oop);
static sqInt (*byteSizeOf)(sqInt oop);
static sqInt (*classByteArray)(void);
static sqInt (*classString)(void);
static sqInt (*failed)(void);
static void * (*fetchArrayofObject)(sqInt fieldIndex, sqInt objectPointer);
static sqInt (*fetchIntegerofObject)(sqInt fieldIndex, sqInt objectPointer);
static sqInt (*fetchPointerofObject)(sqInt index, sqInt oop);
static void * (*firstIndexableField)(sqInt oop);
static sqInt (*instantiateClassindexableSize)(sqInt classPointer, sqInt size);
static sqInt (*integerObjectOf)(sqInt value);
static sqInt (*ioFilenamefromStringofLengthresolveAliases)(char *aCharBuffer, char *aFilenameString, sqInt filenameLength, sqInt aBoolean);
static sqInt (*isKindOf)(sqInt oop, char *aString);
static sqInt (*isBytes)(sqInt oop);
static sqInt (*isIntegerObject)(sqInt objectPointer);
static sqInt (*isPointers)(sqInt oop);
static sqInt (*isWords)(sqInt oop);
static sqInt (*makePointwithxValueyValue)(sqInt xValue, sqInt yValue);
static sqInt (*methodArgumentCount)(void);
static sqInt (*nilObject)(void);
static sqInt (*pop)(sqInt nItems);
static sqInt (*popthenPush)(sqInt nItems, sqInt oop);
static sqInt (*popRemappableOop)(void);
static sqInt (*positive32BitIntegerFor)(unsigned int integerValue);
static sqInt (*primitiveFail)(void);
static sqInt (*pushRemappableOop)(sqInt oop);
static sqInt (*slotSizeOf)(sqInt oop);
static sqInt (*stackIntegerValue)(sqInt offset);
static sqInt (*stackObjectValue)(sqInt offset);
static sqInt (*stackValue)(sqInt offset);
static sqInt (*storeIntegerofObjectwithValue)(sqInt index, sqInt oop, sqInt integer);
static sqInt (*storePointerofObjectwithValue)(sqInt index, sqInt oop, sqInt valuePointer);
static sqInt (*success)(sqInt aBoolean);
#else /* !defined(SQUEAK_BUILTIN_PLUGIN) */
extern void * arrayValueOf(sqInt oop);
extern sqInt byteSizeOf(sqInt oop);
extern sqInt classByteArray(void);
extern sqInt classString(void);
extern sqInt failed(void);
extern void * fetchArrayofObject(sqInt fieldIndex, sqInt objectPointer);
extern sqInt fetchIntegerofObject(sqInt fieldIndex, sqInt objectPointer);
extern sqInt fetchPointerofObject(sqInt index, sqInt oop);
extern void * firstIndexableField(sqInt oop);
extern sqInt instantiateClassindexableSize(sqInt classPointer, sqInt size);
extern sqInt integerObjectOf(sqInt value);
extern sqInt ioFilenamefromStringofLengthresolveAliases(char *aCharBuffer, char *aFilenameString, sqInt filenameLength, sqInt aBoolean);
extern sqInt isKindOf(sqInt oop, char *aString);
extern sqInt isBytes(sqInt oop);
#if !defined(isIntegerObject)
extern sqInt isIntegerObject(sqInt objectPointer);
#endif
extern sqInt isPointers(sqInt oop);
extern sqInt isWords(sqInt oop);
extern sqInt makePointwithxValueyValue(sqInt xValue, sqInt yValue);
extern sqInt methodArgumentCount(void);
extern sqInt nilObject(void);
extern sqInt pop(sqInt nItems);
extern sqInt popthenPush(sqInt nItems, sqInt oop);
extern sqInt popRemappableOop(void);
extern sqInt positive32BitIntegerFor(unsigned int integerValue);
extern sqInt primitiveFail(void);
extern sqInt pushRemappableOop(sqInt oop);
extern sqInt slotSizeOf(sqInt oop);
extern sqInt stackIntegerValue(sqInt offset);
extern sqInt stackObjectValue(sqInt offset);
extern sqInt stackValue(sqInt offset);
extern sqInt storeIntegerofObjectwithValue(sqInt index, sqInt oop, sqInt integer);
extern sqInt storePointerofObjectwithValue(sqInt index, sqInt oop, sqInt valuePointer);
extern sqInt success(sqInt aBoolean);
extern
#endif
struct VirtualMachine* interpreterProxy;
static FT_Library library;
static const char *moduleName =
#ifdef SQUEAK_BUILTIN_PLUGIN
	"FT2Plugin Freetype-Plugin-EstebanLorenzano.70 (i)"
#else
	"FT2Plugin Freetype-Plugin-EstebanLorenzano.70 (e)"
#endif
;


	/* FT2Plugin>>#fetchByteArray:ofObject:assureSize: */
static char *
fetchByteArrayofObjectassureSize(sqInt fieldIndex, sqInt objectPointer, sqInt aSize)
{
	sqInt array;

	array = fetchPointerofObject(fieldIndex, objectPointer);
	if ((isBytes(array))
	 && ((slotSizeOf(array)) == aSize)) {
		return arrayValueOf(array);
	}
	return null;
}

	/* FT2Plugin>>#fetchShortArray:ofObject:assureSize: */
static short*
fetchShortArrayofObjectassureSize(sqInt fieldIndex, sqInt objectPointer, sqInt aSize)
{
	sqInt array;

	array = fetchPointerofObject(fieldIndex, objectPointer);
	if ((isWords(array))
	 && ((slotSizeOf(array)) == ((aSize + 1) / 2))) {
		return arrayValueOf(array);
	}
	return null;
}

	/* FT2Plugin>>#fetchWordArray:ofObject:assureSize: */
static long *
fetchWordArrayofObjectassureSize(sqInt fieldIndex, sqInt objectPointer, sqInt aSize)
{
	sqInt array;

	array = fetchPointerofObject(fieldIndex, objectPointer);
	if ((isWords(array))
	 && ((slotSizeOf(array)) == aSize)) {
		return arrayValueOf(array);
	}
	return null;
}


/*	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 */

	/* FT2Plugin>>#ftAllocateHandleInReceiverForPointer: */
static sqInt
ftAllocateHandleInReceiverForPointer(void *aPointer)
{
	void **extraByteArrayPtr;
	sqInt returnedHandle;

	extraByteArrayPtr = 0;
	if (aPointer) {

		/* Allocate a Smalltalk ByteArray -- lastAlloc contains the length */
		/* Copy from the C bytecode buffer to the Smalltalk ByteArray */

		/* Allocate a Smalltalk ByteArray -- lastAlloc contains the length */
		/* Copy from the C bytecode buffer to the Smalltalk ByteArray */
returnedHandle = instantiateClassindexableSize(classByteArray(), sizeof(void **));
		extraByteArrayPtr = arrayValueOf(returnedHandle);
		*extraByteArrayPtr = (void *)(aPointer);
	}
	else {
returnedHandle = nilObject();
	}
	storePointerofObjectwithValue(0, stackObjectValue(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 */

	/* FT2Plugin>>#ftAllocateStringForPointer: */
static sqInt
ftAllocateStringForPointer(const char *aPointer)
{
	char *extraByteArrayPtr;
	sqInt returnedHandle;

	if (aPointer) {

		/* Allocate a Smalltalk ByteArray -- lastAlloc contains the length */
		/* Copy from the C bytecode buffer to the Smalltalk ByteArray */

		/* Allocate a Smalltalk ByteArray -- lastAlloc contains the length */
		/* Copy from the C bytecode buffer to the Smalltalk ByteArray */
returnedHandle = instantiateClassindexableSize(classString(), strlen(aPointer));
		extraByteArrayPtr = arrayValueOf(returnedHandle);
		strncpy(extraByteArrayPtr, aPointer, strlen(aPointer));
	}
	else {
returnedHandle = nilObject();
	}
	return returnedHandle;
}


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

	/* FT2Plugin>>#ftEncodingValueFromString: */
static FT_Encoding
ftEncodingValueFromString(sqInt string)
{
	unsigned char*ptr;
	unsigned long retval;

	success((!(isIntegerObject(string)))
	 && ((isBytes(string))
	 && ((slotSizeOf(string)) == (sizeof(FT_Encoding)))));
	if (failed()) {
		return null;
	}
	retval = 0;

	/* ptr := self cCode: '(unsigned char *) (string + 4)'. */
ptr = 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. */

	/* FT2Plugin>>#ftHandleValueFromReceiver: */
static void *
ftHandleValueFromReceiver(sqInt rcvrOop)
{
	sqInt btw;
	sqInt oop;

	oop = fetchPointerofObject(0, rcvrOop);
	success((isBytes(oop))
	 && ((slotSizeOf(oop)) == (sizeof(void *))));
	if (failed()) {
		return null;
	}

	/* self bytesPerWord */
btw = 8;
	return *(void**)(pointerForOop(oop + btw));
}


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

	/* FT2Plugin>>#ftInitBitmap:fromForm: */
static int
ftInitBitmapfromForm(FT_Bitmap*bitmap, sqInt formOop)
{
	unsigned char*buffer;
	sqInt depth;
	sqInt height;
	sqInt numGrays;
	sqInt pitch;
	sqInt pixelMode;
	sqInt width;
	sqInt wordsPerRow;

	numGrays = 0;
	pixelMode = 0;
	wordsPerRow = 0;
	success(isPointers(formOop));
	success((slotSizeOf(formOop)) >= FormInstSize);
	if (failed()) {
		return null;
	}
	width = fetchIntegerofObject(FormWidthIndex, formOop);
	height = fetchIntegerofObject(FormHeightIndex, formOop);
	depth = fetchIntegerofObject(FormDepthIndex, formOop);
	buffer = ((void*) (fetchArrayofObject(FormBitsIndex, formOop)));
	if (failed()) {
		return null;
	}
	if (depth < 0) {
depth = depth * -1;
	}
	if (depth == 1) {
wordsPerRow = (width + 0x1F) / 32;
		numGrays = 1;
		pixelMode = FT_PIXEL_MODE_MONO;
	}
	else {
if (depth == 8) {
wordsPerRow = (width + 3) / 4;
			numGrays = 256;
			pixelMode = FT_PIXEL_MODE_GRAY;
		}
		else {
return primitiveFail();
		}
	}
	
#ifndef WORDS_BIGENDIAN
depth = depth * -1;
#endif
;
	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 */

	/* FT2Plugin>>#ftInitBitmap:fromForm:renderMode: */
static int
ftInitBitmapfromFormrenderMode(FT_Bitmap*bitmap, sqInt formOop, sqInt mode)
{
	unsigned char*buffer;
	sqInt depth;
	sqInt height;
	sqInt numGrays;
	sqInt pitch;
	sqInt width;
	sqInt wordsPerRow;

	numGrays = 0;
	wordsPerRow = 0;
	success(isPointers(formOop));
	success((slotSizeOf(formOop)) >= FormInstSize);
	if (failed()) {
		return null;
	}
	width = fetchIntegerofObject(FormWidthIndex, formOop);
	height = fetchIntegerofObject(FormHeightIndex, formOop);
	depth = fetchIntegerofObject(FormDepthIndex, formOop);
	buffer = ((void*) (fetchArrayofObject(FormBitsIndex, formOop)));
	if (failed()) {
		return null;
	}
	if (depth < 0) {
depth = depth * -1;
	}
	if (depth == 1) {
wordsPerRow = (width + 0x1F) / 32;
		numGrays = 1;
	}
	else {
if (depth == 8) {
wordsPerRow = (width + 3) / 4;
			numGrays = 256;
		}
		else {
return primitiveFail();
		}
	}
	
#ifndef WORDS_BIGENDIAN
depth = depth * -1;
#endif
;
	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;
}

	/* FT2Plugin>>#ftParameterError */
static int
ftParameterError(void)
{
	errorCode = 0xFF;
	return primitiveFail();
}


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

	/* FT2Plugin>>#ftStringFromEncodingValue: */
static sqInt
ftStringFromEncodingValue(FT_Encoding encoding)
{
	unsigned char*ptr;
	sqInt stringOop;

	stringOop = instantiateClassindexableSize(classString(), sizeof(FT_Encoding));
	if (failed()) {
		return null;
	}
	ptr = 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! */

	/* InterpreterPlugin>>#getModuleName */
EXPORT(const char*)
getModuleName(void)
{
	return moduleName;
}

	/* FT2Plugin>>#initialiseModule */
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;
}

	/* FT2Plugin>>#primitiveCopyToExternalMemory: */
EXPORT(sqInt)
primitiveCopyToExternalMemory(void)
{
	char *aByteArray;
	void *aPointer;
	size_t byteSize;
	sqInt rcvr;

	success(isBytes(stackValue(0)));
	aByteArray = ((char *) (firstIndexableField(stackValue(0))));
	success(isKindOf(stackValue(1), "FreeTypeExternalMemory"));
	rcvr = stackValue(1);
	if (failed()) {
		ftParameterError();
		return null;
	}
	errorCode = 0;
	byteSize = byteSizeOf(((sqInt)(long)(aByteArray) - BaseHeaderSize));
	if (failed()) {
		return null;
	}
	aPointer = malloc(byteSize);
	memcpy(aPointer,aByteArray,byteSize);
	ftAllocateHandleInReceiverForPointer(aPointer);
	if (failed()) {
		ftParameterError();
		return null;
	}
	pop(1);
	return null;
}


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

	/* FT2Plugin>>#primitiveDoneFace */
EXPORT(sqInt)
primitiveDoneFace(void)
{
	FT_Face face;
	sqInt i;
	sqInt rcvr;

	success(isKindOf(stackValue(0), "FT2Face"));
	rcvr = stackValue(0);
	if (failed()) {
		ftParameterError();
		return null;
	}
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
primitiveFail();
		return null;
	}
	
	/* nil out all the fields */
errorCode = FT_Done_Face(face);
	for (i = 0; i <= 23; i += 1) {
storePointerofObjectwithValue(i, rcvr, nilObject());
	}
	success(errorCode == 0);
	if (failed()) {
		ftParameterError();
		return null;
	}
	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. */

	/* FT2Plugin>>#primitiveDoneFacePreserveFields */
EXPORT(sqInt)
primitiveDoneFacePreserveFields(void)
{
	FT_Face face;
	sqInt rcvr;

	success(isKindOf(stackValue(0), "FT2Face"));
	rcvr = stackValue(0);
	if (failed()) {
		ftParameterError();
		return null;
	}
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
primitiveFail();
		return null;
	}
	
	/* nil the handle field */
errorCode = FT_Done_Face(face);
	storePointerofObjectwithValue(0, rcvr, nilObject());
	success(errorCode == 0);
	if (failed()) {
		ftParameterError();
		return null;
	}
	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. 
 */

	/* FT2Plugin>>#primitiveEmboldenFaceGlyphSlotOutline: */
EXPORT(sqInt)
primitiveEmboldenFaceGlyphSlotOutline(void)
{
	FT_Face face;
	sqInt rcvr;
	sqInt strength;

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


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

	/* FT2Plugin>>#primitiveErrorCode */
EXPORT(sqInt)
primitiveErrorCode(void)
{
	sqInt _return_value;

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

	/* FT2Plugin>>#primitiveErrorString */
EXPORT(sqInt)
primitiveErrorString(void)
{
	FT2Error *ftError;
	const char *str;

	
#undef __FTERRORS_H__
#define FT_ERRORDEF( e, v, s )  { e, s },
#define FT_ERROR_START_LIST     {
#define FT_ERROR_END_LIST       { 0xFF, "Bad Squeak Method Parameter" }, { 0, NULL } };
static const FT2Error ftErrors[] =
#include FT_ERRORS_H
;
	ftError = ftErrors;
	while (((str = ftError->errMsg))
	 && (FT_ERROR_BASE(errorCode) != ftError->errCode)) {
		ftError++;
	}
	if (!str) {
success(0);
	}
	if (failed()) {
		return null;
	}
	popthenPush(1, ftAllocateStringForPointer(str));
	if (failed()) {
		ftParameterError();
		return null;
	}
	return null;
}

	/* FT2Plugin>>#primitiveFreeExternalMemory */
EXPORT(sqInt)
primitiveFreeExternalMemory(void)
{
	void*memPointer;
	sqInt rcvr;

	success(isKindOf(stackValue(0), "FreeTypeExternalMemory"));
	rcvr = stackValue(0);
	if (failed()) {
		ftParameterError();
		return null;
	}
	
	/* free the memory handle */
errorCode = 0;
	memPointer = ftHandleValueFromReceiver(rcvr);
	if (!(memPointer == null)) {
		free(memPointer);
	}
	if (failed()) {
		ftParameterError();
		return null;
	}
	return null;
}


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

	/* FT2Plugin>>#primitiveGetFaceCharIndex: */
EXPORT(sqInt)
primitiveGetFaceCharIndex(void)
{
	sqInt charIndex;
	FT_Face face;
	sqInt rcvr;
	sqInt result;
	sqInt _return_value;

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

	/* FT2Plugin>>#primitiveGetFaceCharMap */
EXPORT(sqInt)
primitiveGetFaceCharMap(void)
{
	FT_CharMap charmap;
	FT_Encoding encoding;
	FT_Face face;
	sqInt rcvr;
	sqInt stringOop;

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

	/* FT2Plugin>>#primitiveGetFaceCharMapsInto: */
EXPORT(sqInt)
primitiveGetFaceCharMapsIntoArray(void)
{
	sqInt array;
	sqInt arrayOop;
	FT_CharMap *charmap;
	FT_Face face;
	sqInt i;
	int numCharmaps;
	sqInt rcvr;
	sqInt stringOop;

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


/*	return a String */

	/* FT2Plugin>>#primitiveGetFaceGlyphName: */
EXPORT(sqInt)
primitiveGetFaceGlyphName(void)
{
	char buffer[100];
	FT_Face face;
	sqInt glyphIndex;
	sqInt rcvr;
	sqInt string;

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

	/* FT2Plugin>>#primitiveGetKerningLeft:right: */
EXPORT(sqInt)
primitiveGetKerningLeftRight(void)
{
	FT_Face face;
	sqInt kernMode;
	sqInt leftGlyph;
	sqInt pointOop;
	sqInt rcvr;
	FT_Vector result;
	sqInt rightGlyph;


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


/*	return a String */

	/* FT2Plugin>>#primitiveGetPostscriptName */
EXPORT(sqInt)
primitiveGetPostscriptName(void)
{
	char*buffer;
	FT_Face face;
	sqInt rcvr;
	sqInt string;


	/* ptr to struct */
success(isKindOf(stackValue(0), "FT2Face"));
	rcvr = stackValue(0);
	if (failed()) {
		ftParameterError();
		return null;
	}
	buffer = 0;
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
primitiveFail();
		return null;
	}
	buffer = FT_Get_Postscript_Name(face);
	success(buffer != 0);
	if (failed()) {
		return null;
	}
	string = ftAllocateStringForPointer(buffer);
	if (failed()) {
		ftParameterError();
		return null;
	}
	popthenPush(1, string);
	return null;
}


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

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


	/* ptr to struct */
	/* <var: #aPointer declareC: 'const char *aPointer'> */
success(isKindOf(stackValue(0), "FT2Face"));
	rcvr = stackValue(0);
	if (failed()) {
		ftParameterError();
		return null;
	}
	buffer = 0;
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
primitiveFail();
		return null;
	}
	buffer = FT_Get_Sfnt_Table(face,ft_sfnt_os2);
	if (buffer == 0) {
if (failed()) {
			ftParameterError();
			return null;
		}
		_return_value = integerObjectOf(-1);
		if (failed()) {
			ftParameterError();
			return null;
		}
		popthenPush(1, _return_value);
		return null;
	}

	/* Copy from the C bytecode buffer to the Smalltalk ByteArray */
returnedHandle = instantiateClassindexableSize(classByteArray(), sizeof(TT_OS2));
	extraByteArrayPtr = arrayValueOf(returnedHandle);
	memcpy(extraByteArrayPtr, buffer, sizeof(TT_OS2));
	if (failed()) {
		ftParameterError();
		return null;
	}
	popthenPush(1, returnedHandle);
	return null;
}


/*	disabled becaus of yet implemented */

	/* FT2Plugin>>#primitiveGetTrackKerningPointSize:degree: */
static sqInt
primitiveGetTrackKerningPointSizedegree(sqInt pointSize, sqInt degree)
{
	return primitiveFail();
}

	/* FT2Plugin>>#primitiveHasKerning */
EXPORT(sqInt)
primitiveHasKerning(void)
{
	FT_Face face;
	sqInt rcvr;
	sqInt _return_value;


	/* ptr to struct */
success(isKindOf(stackValue(0), "FT2Face"));
	rcvr = stackValue(0);
	if (failed()) {
		ftParameterError();
		return null;
	}
	errorCode = 0;
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
primitiveFail();
		return null;
	}
	if (failed()) {
		ftParameterError();
		return null;
	}
	_return_value = integerObjectOf(FT_HAS_KERNING( face ));
	if (failed()) {
		ftParameterError();
		return null;
	}
	popthenPush(1, _return_value);
	return null;
}


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

	/* FT2Plugin>>#primitiveLibraryHandle */
EXPORT(sqInt)
primitiveLibraryHandle(void)
{
	sqInt rcvr;

	success(isKindOf(stackValue(0), "FT2Library"));
	rcvr = stackValue(0);
	if (failed()) {
		ftParameterError();
		return null;
	}
	errorCode = 0;
	ftAllocateHandleInReceiverForPointer(library);
	if (failed()) {
		ftParameterError();
		return null;
	}
	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. 
 */

	/* FT2Plugin>>#primitiveLoadCharacter:flags: */
EXPORT(sqInt)
primitiveLoadCharacter(void)
{
	FT_Face face;
	sqInt flags;
	sqInt index;
	sqInt rcvr;

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

	/* FT2Plugin>>#primitiveLoadFaceBbox: */
EXPORT(sqInt)
primitiveLoadFaceBbox(void)
{
	sqInt aRectangle;
	FT_Face face;
	sqInt pointOop;
	sqInt rcvr;
	sqInt rectOop;

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

	/* FT2Plugin>>#primitiveLoadFaceFields */
EXPORT(sqInt)
primitiveLoadFaceFields(void)
{
	FT_Face face;
	sqInt rcvr;
	sqInt strOop;

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

		/* bbox -- Rectangle xMin, yMin, xMax, yMax */
		/* unitsPerEm */
		/* ascender */
storeIntegerofObjectwithValue(13, rcvr, face->units_per_EM);
		storeIntegerofObjectwithValue(14, rcvr, face->ascender);
		storeIntegerofObjectwithValue(15, rcvr, face->descender);
		storeIntegerofObjectwithValue(16, rcvr, face->height);
		storeIntegerofObjectwithValue(17, rcvr, face->max_advance_width);
		storeIntegerofObjectwithValue(18, rcvr, face->max_advance_height);
		storeIntegerofObjectwithValue(19, rcvr, face->underline_position);
		storeIntegerofObjectwithValue(20, rcvr, face->underline_thickness);
	}
	if (failed()) {
		ftParameterError();
		return null;
	}
	return null;
}

	/* FT2Plugin>>#primitiveLoadGlyph:flags: */
EXPORT(sqInt)
primitiveLoadGlyph(void)
{
	FT_Face face;
	sqInt flags;
	sqInt index;
	sqInt rcvr;

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


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

	/* FT2Plugin>>#primitiveLoadGlyphSlotFrom: */
EXPORT(sqInt)
primitiveLoadGlyphSlotFromFace(void)
{
	sqInt aFace;
	sqInt btw;
	FT_Face face;
	sqInt gfOop;
	FT_Glyph_Format *gfPtr;
	FT_GlyphSlot gs;
	sqInt rcvr;


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


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

	/* FT2Plugin>>#primitiveLoadOutlineArraysFrom: */
EXPORT(sqInt)
primitiveLoadOutlineArraysFromFace(void)
{
	sqInt aFace;
	sqInt array;
	sqInt array1;
	sqInt array2;
	short *contours;
	sqInt contoursSize;
	FT_Face face;
	FT_GlyphSlot gs;
	sqInt i;
	long *points;
	sqInt pointsSize;
	sqInt rcvr;
	char*tags;


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


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

	/* FT2Plugin>>#primitiveLoadOutlineSizesFrom: */
EXPORT(sqInt)
primitiveLoadOutlineSizesFromFace(void)
{
	sqInt aFace;
	FT_Face face;
	FT_GlyphSlot gs;
	sqInt rcvr;


	/* ptr to struct */
	/* ptr to struct */
success(isKindOf(stackValue(0), "FT2Face"));
	aFace = stackValue(0);
	success(isKindOf(stackValue(1), "FT2Outline"));
	rcvr = stackValue(1);
	if (failed()) {
		ftParameterError();
		return null;
	}
	errorCode = 0;
	if ((slotSizeOf(rcvr)) < FT2OutlineInstSize) {
		primitiveFail();
		return null;
	}
	face = ftHandleValueFromReceiver(aFace);
	if (face == null) {
primitiveFail();
		return null;
	}
	gs = face->glyph;
	if (!gs) {
primitiveFail();
		return null;
	}
	storeIntegerofObjectwithValue(FT2OutlineContoursSizeIndex, rcvr, gs->outline.n_contours);
	storeIntegerofObjectwithValue(FT2OutlinePointsSizeIndex, rcvr, gs->outline.n_points);
	if (failed()) {
		ftParameterError();
		return null;
	}
	pop(1);
	return null;
}


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

	/* FT2Plugin>>#primitiveModuleErrorCode */
EXPORT(sqInt)
primitiveModuleErrorCode(void)
{
	sqInt _return_value;

	if (failed()) {
		ftParameterError();
		return null;
	}
	_return_value = positive32BitIntegerFor((FT_ERROR_MODULE(errorCode)));
	if (failed()) {
		ftParameterError();
		return null;
	}
	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. */

	/* FT2Plugin>>#primitiveNewFaceFromFile:index: */
EXPORT(sqInt)
primitiveNewFaceFromFileAndIndex(void)
{
	sqInt anInteger;
	size_t byteSize;
	FT_Face face;
	char *fontFilePath;
	sqInt rcvr;
	char translatedFilePath[1024];

	success(isBytes(stackValue(1)));
	fontFilePath = ((char *) (firstIndexableField(stackValue(1))));
	anInteger = stackIntegerValue(0);
	success(isKindOf(stackValue(2), "FT2Face"));
	rcvr = stackValue(2);
	if (failed()) {
		ftParameterError();
		return null;
	}
	errorCode = 0;
	byteSize = byteSizeOf(((sqInt)(long)(fontFilePath) - BaseHeaderSize));
	if (failed()) {
		return null;
	}
	if (byteSize > 1000) {
success(0);
		return null;
	}
	ioFilenamefromStringofLengthresolveAliases(translatedFilePath, fontFilePath, byteSize, 1);
	errorCode = FT_New_Face(library, translatedFilePath, anInteger, &face);
	success(errorCode == 0);
	if (failed()) {
		return null;
	}
	ftAllocateHandleInReceiverForPointer(face);
	if (failed()) {
		ftParameterError();
		return null;
	}
	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. */

	/* FT2Plugin>>#primitiveNewMemoryFaceFrom:size:index: */
EXPORT(sqInt)
primitiveNewMemoryFaceFromExternalMemoryAndIndex(void)
{
	sqInt aFreeTypeExternalMemory;
	sqInt anInteger;
	sqInt byteSize;
	FT_Face face;
	void *memPointer;
	sqInt rcvr;


	/* a pointer */
aFreeTypeExternalMemory = stackValue(2);
	byteSize = stackIntegerValue(1);
	anInteger = stackIntegerValue(0);
	success(isKindOf(stackValue(3), "FT2Face"));
	rcvr = stackValue(3);
	if (failed()) {
		ftParameterError();
		return null;
	}
	errorCode = 0;
	memPointer = ftHandleValueFromReceiver(aFreeTypeExternalMemory);
	if (failed()) {
		return null;
	}
	errorCode = FT_New_Memory_Face(library, memPointer, byteSize, anInteger, &face);
	success(errorCode == 0);
	if (failed()) {
		return null;
	}
	ftAllocateHandleInReceiverForPointer(face);
	if (failed()) {
		ftParameterError();
		return null;
	}
	pop(3);
	return null;
}


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

	/* FT2Plugin>>#primitiveNumberOfOutlineCountours */
EXPORT(sqInt)
primitiveNumberOfOutlineCountours(void)
{
	sqInt aFace;
	sqInt contoursSize;
	FT_Face face;
	FT_GlyphSlot gs;
	sqInt rcvr;
	sqInt _return_value;


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


/*	Render this face into the given form */

	/* FT2Plugin>>#primitiveRenderGlyphIntoForm: */
EXPORT(sqInt)
primitiveRenderGlyphIntoForm(void)
{
	FT_Bitmap bitmap;
	FT_Face face;
	sqInt faceOop;
	sqInt formOop;


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


/*	Render this face into the given form */

	/* FT2Plugin>>#primitiveRenderGlyphIntoForm:renderMode: */
EXPORT(sqInt)
primitiveRenderGlyphIntoFormWithRenderMode(void)
{
	FT_Bitmap bitmap;
	FT_Face face;
	sqInt faceOop;
	sqInt formOop;
	sqInt mode;


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

	/* FT2Plugin>>#primitiveResetErrorCode */
EXPORT(sqInt)
primitiveResetErrorCode(void)
{
	int oldError;
	sqInt _return_value;

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

	/* FT2Plugin>>#primitiveSetFaceCharMap: */
EXPORT(sqInt)
primitiveSetFaceCharMap(void)
{
	FT_Encoding encoding;
	sqInt encodingString;
	FT_Face face;
	sqInt rcvr;

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

	/* FT2Plugin>>#primitiveSetPixelWidth:height: */
EXPORT(sqInt)
primitiveSetPixelSizes(void)
{
	FT_Face face;
	sqInt rcvr;
	sqInt x;
	sqInt y;

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

	/* FT2Plugin>>#primitiveSetTransform:delta: */
EXPORT(sqInt)
primitiveSetTransform(void)
{
	FT_Vector delta = {0};
	int *deltasqIntPtr;
	sqInt deltaWordArray;
	FT_Face face;
	FT_Matrix matrix = {0};
	int *matrixsqIntPtr;
	sqInt matrixWordArray;
	sqInt rcvr;

	matrixWordArray = stackValue(1);
	deltaWordArray = stackValue(0);
	success(isKindOf(stackValue(2), "FT2Face"));
	rcvr = stackValue(2);
	if (failed()) {
		ftParameterError();
		return null;
	}
	face = ftHandleValueFromReceiver(rcvr);
	if (face == null) {
primitiveFail();
		return null;
	}
	matrixsqIntPtr = ((int *) (arrayValueOf(matrixWordArray)));
	deltasqIntPtr = ((int *) (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 (!(failed())) {
		FT_Set_Transform( face, &matrix, &delta);
	}
	if (failed()) {
		ftParameterError();
		return null;
	}
	pop(2);
	return null;
}

	/* FT2Plugin>>#primitiveTransformFaceGlyphSlotOutline: */
EXPORT(sqInt)
primitiveTransformFaceGlyphSlotOutline(void)
{
	FT_Face face;
	FT_Matrix matrix = {0};
	int *matrixsqIntPtr;
	sqInt matrixWordArray;
	sqInt rcvr;

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

	/* FT2Plugin>>#primitiveTranslateFaceGlyphSlotOutline: */
EXPORT(sqInt)
primitiveTranslateFaceGlyphSlotOutline(void)
{
	FT_Vector delta = {0};
	int *deltasqIntPtr;
	sqInt deltaWordArray;
	FT_Face face;
	sqInt rcvr;

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

	/* FT2Plugin>>#primitiveVersion */
EXPORT(sqInt)
primitiveVersion(void)
{
	int amajor;
	int aminor;
	int apatch;
	sqInt rcvr;

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


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

	/* InterpreterPlugin>>#setInterpreter: */
EXPORT(sqInt)
setInterpreter(struct VirtualMachine*anInterpreter)
{
	sqInt ok;

	interpreterProxy = anInterpreter;
	ok = ((interpreterProxy->majorVersion()) == (VM_PROXY_MAJOR))
	 && ((interpreterProxy->minorVersion()) >= (VM_PROXY_MINOR));
	if (ok) {

#if !defined(SQUEAK_BUILTIN_PLUGIN)
		arrayValueOf = interpreterProxy->arrayValueOf;
		byteSizeOf = interpreterProxy->byteSizeOf;
		classByteArray = interpreterProxy->classByteArray;
		classString = interpreterProxy->classString;
		failed = interpreterProxy->failed;
		fetchArrayofObject = interpreterProxy->fetchArrayofObject;
		fetchIntegerofObject = interpreterProxy->fetchIntegerofObject;
		fetchPointerofObject = interpreterProxy->fetchPointerofObject;
		firstIndexableField = interpreterProxy->firstIndexableField;
		instantiateClassindexableSize = interpreterProxy->instantiateClassindexableSize;
		integerObjectOf = interpreterProxy->integerObjectOf;
		ioFilenamefromStringofLengthresolveAliases = interpreterProxy->ioFilenamefromStringofLengthresolveAliases;
		isKindOf = interpreterProxy->isKindOf;
		isBytes = interpreterProxy->isBytes;
		isIntegerObject = interpreterProxy->isIntegerObject;
		isPointers = interpreterProxy->isPointers;
		isWords = interpreterProxy->isWords;
		makePointwithxValueyValue = interpreterProxy->makePointwithxValueyValue;
		methodArgumentCount = interpreterProxy->methodArgumentCount;
		nilObject = interpreterProxy->nilObject;
		pop = interpreterProxy->pop;
		popthenPush = interpreterProxy->popthenPush;
		popRemappableOop = interpreterProxy->popRemappableOop;
		positive32BitIntegerFor = interpreterProxy->positive32BitIntegerFor;
		primitiveFail = interpreterProxy->primitiveFail;
		pushRemappableOop = interpreterProxy->pushRemappableOop;
		slotSizeOf = interpreterProxy->slotSizeOf;
		stackIntegerValue = interpreterProxy->stackIntegerValue;
		stackObjectValue = interpreterProxy->stackObjectValue;
		stackValue = interpreterProxy->stackValue;
		storeIntegerofObjectwithValue = interpreterProxy->storeIntegerofObjectwithValue;
		storePointerofObjectwithValue = interpreterProxy->storePointerofObjectwithValue;
		success = interpreterProxy->success;
#endif /* !defined(SQUEAK_BUILTIN_PLUGIN) */
	}
	return ok;
}

	/* FT2Plugin>>#shutdownModule */
EXPORT(sqInt)
shutdownModule(void)
{
	errorCode = FT_Done_FreeType(library);
	if (errorCode == 0) {
		library = null;
	}
	return errorCode == 0;
}

	/* SmartSyntaxInterpreterPlugin>>#sqAssert: */
static sqInt
sqAssert(sqInt aBool)
{
	/* missing DebugCode */;
	return aBool;
}


#ifdef SQUEAK_BUILTIN_PLUGIN

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

#else /* ifdef SQ_BUILTIN_PLUGIN */

signed char primitiveCopyToExternalMemoryAccessorDepth = 0;
signed char primitiveDoneFaceAccessorDepth = 1;
signed char primitiveDoneFacePreserveFieldsAccessorDepth = 1;
signed char primitiveEmboldenFaceGlyphSlotOutlineAccessorDepth = 1;
signed char primitiveFreeExternalMemoryAccessorDepth = 1;
signed char primitiveGetFaceCharIndexAccessorDepth = 1;
signed char primitiveGetFaceCharMapAccessorDepth = 1;
signed char primitiveGetFaceCharMapsIntoArrayAccessorDepth = 1;
signed char primitiveGetFaceGlyphNameAccessorDepth = 1;
signed char primitiveGetKerningLeftRightAccessorDepth = 1;
signed char primitiveGetPostscriptNameAccessorDepth = 1;
signed char primitiveGetSfntTableOS2AccessorDepth = 1;
signed char primitiveHasKerningAccessorDepth = 1;
signed char primitiveLibraryHandleAccessorDepth = 0;
signed char primitiveLoadCharacterAccessorDepth = 1;
signed char primitiveLoadFaceBboxAccessorDepth = 1;
signed char primitiveLoadFaceFieldsAccessorDepth = 1;
signed char primitiveLoadGlyphAccessorDepth = 1;
signed char primitiveLoadGlyphSlotFromFaceAccessorDepth = 1;
signed char primitiveLoadOutlineArraysFromFaceAccessorDepth = 2;
signed char primitiveLoadOutlineSizesFromFaceAccessorDepth = 1;
signed char primitiveNewFaceFromFileAndIndexAccessorDepth = 0;
signed char primitiveNewMemoryFaceFromExternalMemoryAndIndexAccessorDepth = 1;
signed char primitiveNumberOfOutlineCountoursAccessorDepth = 2;
signed char primitiveRenderGlyphIntoFormAccessorDepth = 1;
signed char primitiveRenderGlyphIntoFormWithRenderModeAccessorDepth = 1;
signed char primitiveSetFaceCharMapAccessorDepth = 1;
signed char primitiveSetPixelSizesAccessorDepth = 1;
signed char primitiveSetTransformAccessorDepth = 1;
signed char primitiveTransformFaceGlyphSlotOutlineAccessorDepth = 1;
signed char primitiveTranslateFaceGlyphSlotOutlineAccessorDepth = 1;
signed char primitiveVersionAccessorDepth = 0;

#endif /* ifdef SQ_BUILTIN_PLUGIN */
