/* Automatically generated by
	VMPluginCodeGenerator VMMaker.oscog-eem.2480 uuid: bb3ffda7-8241-4dea-b886-d656e474b6c1
   from
	BalloonEnginePlugin VMMaker.oscog-eem.2480 uuid: bb3ffda7-8241-4dea-b886-d656e474b6c1
 */
static char __buildInfo[] = "BalloonEnginePlugin VMMaker.oscog-eem.2480 uuid: bb3ffda7-8241-4dea-b886-d656e474b6c1 " __DATE__ ;



#include "config.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. */
#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 "sqMemoryAccess.h"


/*** Constants ***/
#define BEBalloonEngineSize 12
#define BEBitBltIndex 2
#define BEFormsIndex 3
#define BESpanIndex 1
#define BEWorkBufferIndex 0
#define ETBalloonEdgeDataSize 6
#define ETIndexIndex 0
#define ETLinesIndex 4
#define ETXValueIndex 1
#define ETYValueIndex 2
#define ETZValueIndex 3
#define FTBalloonFillDataSize 6
#define FTIndexIndex 0
#define FTMaxXIndex 2
#define FTMinXIndex 1
#define FTYValueIndex 3
#define GBBaseSize 16
#define GBBitmapDepth 12
#define GBBitmapHeight 11
#define GBBitmapRaster 14
#define GBBitmapSize 13
#define GBBitmapWidth 10
#define GBColormapOffset 18
#define GBColormapSize 15
#define GBEndX 14
#define GBEndY 15
#define GBFinalX 21
#define GBMBaseSize 18
#define GBTileFlag 16
#define GBUpdateData 10
#define GBUpdateDDX 4
#define GBUpdateDDY 5
#define GBUpdateDX 2
#define GBUpdateDY 3
#define GBUpdateX 0
#define GBUpdateY 1
#define GBViaX 12
#define GBViaY 13
#define GBWideEntry 18
#define GBWideExit 19
#define GBWideExtent 20
#define GBWideFill 16
#define GBWideSize 28
#define GBWideUpdateData 22
#define GBWideWidth 17
#define GEBaseEdgeSize 10
#define GEBaseFillSize 4
#define GEEdgeFillsInvalid 0x10000
#define GEFAlreadyFailed 100
#define GEFBadPoint 121
#define GEFBitBltLoadFailed 122
#define GEFClassMismatch 114
#define GEFEdgeDataTooSmall 112
#define GEFEngineIsInteger 101
#define GEFEngineIsWords 102
#define GEFEngineStopped 104
#define GEFEngineTooSmall 103
#define GEFEntityCheckFailed 120
#define GEFEntityLoadFailed 119
#define GEFFillDataTooSmall 113
#define GEFFormLoadFailed 123
#define GEFillIndexLeft 8
#define GEFillIndexRight 9
#define GEFSizeMismatch 115
#define GEFWorkBufferBadMagic 108
#define GEFWorkBufferIsInteger 105
#define GEFWorkBufferIsPointers 106
#define GEFWorkBufferStartWrong 110
#define GEFWorkBufferTooSmall 107
#define GEFWorkBufferWrongSize 109
#define GEFWorkTooBig 111
#define GEFWrongEdge 118
#define GEFWrongFill 117
#define GEFWrongState 116
#define GENumLines 7
#define GEObjectIndex 2
#define GEObjectLength 1
#define GEObjectType 0
#define GEPrimitiveBezier 6
#define GEPrimitiveClippedBitmapFill 0x400
#define GEPrimitiveEdge 2
#define GEPrimitiveEdgeMask 0xFF
#define GEPrimitiveFill 0x100
#define GEPrimitiveFillMask 0xFF00
#define GEPrimitiveLine 4
#define GEPrimitiveLinearGradientFill 0x200
#define GEPrimitiveRadialGradientFill 0x300
#define GEPrimitiveTypeMask 0xFFFF
#define GEPrimitiveWide 1
#define GEPrimitiveWideBezier 7
#define GEPrimitiveWideLine 5
#define GEPrimitiveWideMask 0xFE
#define GErrorAETEntry 6
#define GErrorBadState 2
#define GErrorFillEntry 5
#define GErrorGETEntry 4
#define GErrorNeedFlush 3
#define GErrorNoMoreSpace 1
#define GEStateAddingFromGET 1
#define GEStateBlitBuffer 5
#define GEStateCompleted 8
#define GEStateScanningAET 3
#define GEStateUnlocked 0
#define GEStateUpdateEdges 6
#define GEStateWaitingChange 7
#define GEStateWaitingForEdge 2
#define GEStateWaitingForFill 4
#define GEXValue 4
#define GEYValue 5
#define GEZValue 6
#define GFDirectionX 6
#define GFDirectionY 7
#define GFNormalX 8
#define GFNormalY 9
#define GFOriginX 4
#define GFOriginY 5
#define GFRampLength 10
#define GFRampOffset 12
#define GGBaseSize 12
#define GLBaseSize 16
#define GLEndX 14
#define GLEndY 15
#define GLError 13
#define GLErrorAdjDown 15
#define GLErrorAdjUp 14
#define GLWideEntry 18
#define GLWideExit 19
#define GLWideExtent 20
#define GLWideFill 16
#define GLWideSize 21
#define GLWideWidth 17
#define GLXDirection 10
#define GLXIncrement 12
#define GLYDirection 11
#define GWAAColorMask 0x33
#define GWAAColorShift 50
#define GWAAHalfPixel 53
#define GWAALevel 48
#define GWAAScanMask 0x34
#define GWAAShift 49
#define GWAETStart 13
#define GWAETUsed 14
#define GWBezierHeightSubdivisions 109
#define GWBezierLineConversions 111
#define GWBezierMonotonSubdivisions 108
#define GWBezierOverflowSubdivisions 110
#define GWBufferTop 10
#define GWClearSpanBuffer 69
#define GWClipMaxX 43
#define GWClipMaxY 45
#define GWClipMinX 42
#define GWClipMinY 44
#define GWColorTransform 24
#define GWCountAddAETEntry 97
#define GWCountChangeAETEntry 107
#define GWCountDisplaySpan 103
#define GWCountFinishTest 93
#define GWCountInitializing 91
#define GWCountMergeFill 101
#define GWCountNextAETEntry 105
#define GWCountNextFillEntry 99
#define GWCountNextGETEntry 95
#define GWCurrentY 88
#define GWCurrentZ 113
#define GWDestOffsetX 46
#define GWDestOffsetY 47
#define GWEdgeTransform 18
#define GWFillMaxX 37
#define GWFillMaxY 39
#define GWFillMinX 36
#define GWFillMinY 38
#define GWFillOffsetX 40
#define GWFillOffsetY 41
#define GWGETStart 11
#define GWGETUsed 12
#define GWHasColorTransform 17
#define GWHasEdgeTransform 16
#define GWHeaderSize 128
#define GWLastExportedEdge 65
#define GWLastExportedFill 66
#define GWLastExportedLeftX 67
#define GWLastExportedRightX 68
#define GWMagicIndex 0
#define GWMagicNumber 1097753705
#define GWMinimalSize 256
#define GWNeedsFlush 63
#define GWObjStart 8
#define GWObjUsed 9
#define GWPoint1 80
#define GWPoint2 82
#define GWPoint3 84
#define GWPoint4 86
#define GWPointListFirst 70
#define GWSize 1
#define GWSpanEnd 34
#define GWSpanEndAA 35
#define GWSpanSize 33
#define GWSpanStart 32
#define GWState 2
#define GWStopReason 64
#define GWTimeAddAETEntry 96
#define GWTimeChangeAETEntry 106
#define GWTimeDisplaySpan 102
#define GWTimeFinishTest 92
#define GWTimeInitializing 90
#define GWTimeMergeFill 100
#define GWTimeNextAETEntry 104
#define GWTimeNextFillEntry 98
#define GWTimeNextGETEntry 94
#define PrimErrBadArgument 3
#define PrimErrBadNumArgs 5


/*** Function Prototypes ***/
static sqInt aaColorMaskGet(void);
static sqInt aaColorMaskPut(sqInt value);
static sqInt aaColorShiftGet(void);
static sqInt aaColorShiftPut(sqInt value);
static sqInt aaFirstPixelFromto(sqInt leftX, sqInt rightX);
static sqInt aaHalfPixelGet(void);
static sqInt aaHalfPixelPut(sqInt value);
static sqInt aaLastPixelFromto(sqInt leftX, sqInt rightX);
static sqInt aaLevelGet(void);
static sqInt aaLevelPut(sqInt value);
static sqInt aaScanMaskGet(void);
static sqInt aaScanMaskPut(sqInt value);
static sqInt aaShiftGet(void);
static sqInt aaShiftPut(sqInt value);
static sqInt absoluteSquared8Dot24(sqInt value);
static sqInt accurateLengthOfwith(sqInt deltaX, sqInt deltaY);
static sqInt addEdgeToGET(sqInt edge);
static sqInt adjustAALevel(void);
static sqInt adjustWideBezierLeftwidthoffsetendX(sqInt bezier, sqInt lineWidth, sqInt lineOffset, sqInt endX);
static sqInt adjustWideBezierRightwidthoffsetendX(sqInt bezier, sqInt lineWidth, sqInt lineOffset, sqInt endX);
static sqInt adjustWideLineafterSteppingFromto(sqInt line, sqInt lastX, sqInt nextX);
static sqInt aetStartGet(void);
static sqInt aetStartPut(sqInt value);
static sqInt aetUsedGet(void);
static sqInt aetUsedPut(sqInt value);
static sqInt allocateAETEntry(sqInt nSlots);
static sqInt allocateBezier(void);
static sqInt allocateBezierStackEntry(void);
static sqInt allocateBitmapFillcolormap(sqInt cmSize, int *cmBits);
static sqInt allocateGETEntry(sqInt nSlots);
static sqInt allocateGradientFillrampWidthisRadial(int *ramp, sqInt rampWidth, sqInt isRadial);
static sqInt allocateLine(void);
static sqInt allocateObjEntry(sqInt nSlots);
static sqInt allocateStackEntry(sqInt nSlots);
static sqInt allocateStackFillEntry(void);
static sqInt allocateWideBezier(void);
static sqInt allocateWideLine(void);
static sqInt areEdgeFillsValid(sqInt edge);
static sqInt assureValuebetweenand(sqInt val1, sqInt val2, sqInt val3);
static sqInt bezierEndXOf(sqInt bezier);
static sqInt bezierEndXOfput(sqInt bezier, sqInt value);
static sqInt bezierEndYOf(sqInt bezier);
static sqInt bezierEndYOfput(sqInt bezier, sqInt value);
static sqInt bezierFinalXOf(sqInt bezier);
static sqInt bezierFinalXOfput(sqInt bezier, sqInt value);
static int * bezierUpdateDataOf(sqInt bezier);
static sqInt bezierViaXOf(sqInt bezier);
static sqInt bezierViaXOfput(sqInt bezier, sqInt value);
static sqInt bezierViaYOf(sqInt bezier);
static sqInt bezierViaYOfput(sqInt bezier, sqInt value);
static sqInt bitmapCmSizeOf(sqInt bmFill);
static sqInt bitmapCmSizeOfput(sqInt bmFill, sqInt value);
static sqInt bitmapDepthOf(sqInt bmFill);
static sqInt bitmapDepthOfput(sqInt bmFill, sqInt value);
static sqInt bitmapHeightOf(sqInt bmFill);
static sqInt bitmapHeightOfput(sqInt bmFill, sqInt value);
static sqInt bitmapRasterOf(sqInt bmFill);
static sqInt bitmapRasterOfput(sqInt bmFill, sqInt value);
static sqInt bitmapSizeOf(sqInt bmFill);
static sqInt bitmapSizeOfput(sqInt bmFill, sqInt value);
static sqInt bitmapTileFlagOf(sqInt bmFill);
static sqInt bitmapTileFlagOfput(sqInt bmFill, sqInt value);
static sqInt bitmapValuebitsatXy(sqInt bmFill, sqInt bits, sqInt xp, sqInt yp);
static sqInt bitmapWidthOf(sqInt bmFill);
static sqInt bitmapWidthOfput(sqInt bmFill, sqInt value);
static sqInt bzEndX(sqInt index);
static sqInt bzEndXput(sqInt index, sqInt value);
static sqInt bzEndY(sqInt index);
static sqInt bzEndYput(sqInt index, sqInt value);
static sqInt bzStartX(sqInt index);
static sqInt bzStartXput(sqInt index, sqInt value);
static sqInt bzStartY(sqInt index);
static sqInt bzStartYput(sqInt index, sqInt value);
static sqInt bzViaX(sqInt index);
static sqInt bzViaXput(sqInt index, sqInt value);
static sqInt bzViaY(sqInt index);
static sqInt bzViaYput(sqInt index, sqInt value);
static sqInt checkCompressedFillIndexListmaxsegments(sqInt fillList, sqInt maxIndex, sqInt nSegs);
static sqInt checkCompressedFills(sqInt indexList);
static sqInt checkCompressedLineWidthssegments(sqInt lineWidthList, sqInt nSegments);
static sqInt checkCompressedPointssegments(sqInt points, sqInt nSegments);
static sqInt checkCompressedShapesegmentsleftFillsrightFillslineWidthslineFillsfillIndexList(sqInt points, sqInt nSegments, sqInt leftFills, sqInt rightFills, sqInt lineWidths, sqInt lineFills, sqInt fillIndexList);
static sqInt checkedAddBezierToGET(sqInt bezier);
static sqInt checkedAddEdgeToGET(sqInt edge);
static sqInt checkedAddLineToGET(sqInt line);
static double * circleCosTable(void);
static double * circleSinTable(void);
static sqInt clampValuemax(sqInt value, sqInt maxValue);
static sqInt clearSpanBuffer(void);
static sqInt clearSpanBufferGet(void);
static sqInt clearSpanBufferPut(sqInt value);
static sqInt clipMaxXGet(void);
static sqInt clipMaxXPut(sqInt value);
static sqInt clipMaxYGet(void);
static sqInt clipMaxYPut(sqInt value);
static sqInt clipMinXGet(void);
static sqInt clipMinXPut(sqInt value);
static sqInt clipMinYGet(void);
static sqInt clipMinYPut(sqInt value);
static int * colormapOf(sqInt bmFill);
static float * colorTransform(void);
static sqInt computeBezierSplitAtHalf(sqInt index);
static sqInt computeBeziersplitAt(sqInt index, double param);
static sqInt computeFinalWideBezierValueswidth(sqInt bezier, sqInt lineWidth);
static sqInt computeSqrt(sqInt length2);
static sqInt copyBitsFromtoat(sqInt x0, sqInt x1, sqInt yValue);
static sqInt createGlobalEdgeTable(void);
static sqInt currentYGet(void);
static sqInt currentYPut(sqInt value);
static sqInt currentZGet(void);
static sqInt currentZPut(sqInt value);
static sqInt destOffsetXGet(void);
static sqInt destOffsetXPut(sqInt value);
static sqInt destOffsetYGet(void);
static sqInt destOffsetYPut(sqInt value);
static sqInt displaySpanBufferAt(sqInt y);
static sqInt drawWideEdgefrom(sqInt edge, sqInt leftX);
static sqInt edgeFillsInvalidate(sqInt edge);
static sqInt edgeFillsValidate(sqInt edge);
static sqInt edgeLeftFillOf(sqInt edge);
static sqInt edgeLeftFillOfput(sqInt edge, sqInt value);
static sqInt edgeNumLinesOf(sqInt edge);
static sqInt edgeNumLinesOfput(sqInt edge, sqInt value);
static sqInt edgeRightFillOf(sqInt edge);
static sqInt edgeRightFillOfput(sqInt edge, sqInt value);
static float * edgeTransform(void);
static sqInt edgeTypeOf(sqInt edge);
static sqInt edgeXValueOf(sqInt edge);
static sqInt edgeXValueOfput(sqInt edge, sqInt value);
static sqInt edgeYValueOf(sqInt edge);
static sqInt edgeYValueOfput(sqInt edge, sqInt value);
static sqInt edgeZValueOf(sqInt edge);
static sqInt edgeZValueOfput(sqInt edge, sqInt value);
static sqInt errorWrongIndex(void);
static sqInt estimatedLengthOfwith(sqInt deltaX, sqInt deltaY);
static sqInt fillAllFromto(sqInt leftX, sqInt rightX);
static sqInt fillBitmapSpan(void);
static sqInt fillBitmapSpanAAfromtoat(sqInt bmFill, sqInt leftX, sqInt rightX, sqInt yValue);
static sqInt fillBitmapSpanfromto(int *bits, sqInt leftX, sqInt rightX);
static sqInt fillBitmapSpanfromtoat(sqInt bmFill, sqInt leftX, sqInt rightX, sqInt yValue);
static sqInt fillColorSpanAAx0x1(sqInt pixelValue32, sqInt leftX, sqInt rightX);
static sqInt fillColorSpanfromto(sqInt pixelValue32, sqInt leftX, sqInt rightX);
static sqInt fillDirectionXOf(sqInt fill);
static sqInt fillDirectionXOfput(sqInt fill, sqInt value);
static sqInt fillDirectionYOf(sqInt fill);
static sqInt fillDirectionYOfput(sqInt fill, sqInt value);
static sqInt fillLinearGradient(void);
static sqInt fillLinearGradientAArampdsdsXfromto(sqInt fill, int *ramp, sqInt deltaS, sqInt dsX, sqInt leftX, sqInt rightX);
static sqInt fillLinearGradientfromtoat(sqInt fill, sqInt leftX, sqInt rightX, sqInt yValue);
static sqInt fillMaxXGet(void);
static sqInt fillMaxXPut(sqInt value);
static sqInt fillMaxYGet(void);
static sqInt fillMaxYPut(sqInt value);
static sqInt fillMinXGet(void);
static sqInt fillMinXPut(sqInt value);
static sqInt fillMinYGet(void);
static sqInt fillMinYPut(sqInt value);
static sqInt fillNormalXOf(sqInt fill);
static sqInt fillNormalXOfput(sqInt fill, sqInt value);
static sqInt fillNormalYOf(sqInt fill);
static sqInt fillNormalYOfput(sqInt fill, sqInt value);
static sqInt fillOffsetXGet(void);
static sqInt fillOffsetXPut(sqInt value);
static sqInt fillOffsetYGet(void);
static sqInt fillOffsetYPut(sqInt value);
static sqInt fillOriginXOf(sqInt fill);
static sqInt fillOriginXOfput(sqInt fill, sqInt value);
static sqInt fillOriginYOf(sqInt fill);
static sqInt fillOriginYOfput(sqInt fill, sqInt value);
static sqInt fillRadialDecreasingAArampdeltaSTdsXdtXfromto(sqInt fill, int *ramp, int *deltaST, sqInt dsX, sqInt dtX, sqInt leftX, sqInt rightX);
static sqInt fillRadialDecreasingrampdeltaSTdsXdtXfromto(sqInt fill, sqInt ramp, sqInt deltaST, sqInt dsX, sqInt dtX, sqInt leftX, sqInt rightX);
static sqInt fillRadialGradient(void);
static sqInt fillRadialGradientfromtoat(sqInt fill, sqInt leftX, sqInt rightX, sqInt yValue);
static sqInt fillRadialIncreasingAArampdeltaSTdsXdtXfromto(sqInt fill, int *ramp, int *deltaST, sqInt dsX, sqInt dtX, sqInt leftX, sqInt rightX);
static sqInt fillRadialIncreasingrampdeltaSTdsXdtXfromto(sqInt fill, sqInt ramp, sqInt deltaST, sqInt dsX, sqInt dtX, sqInt leftX, sqInt rightX);
static sqInt fillSortsbefore(sqInt fillEntry1, sqInt fillEntry2);
static sqInt fillSpanfromto(unsigned int fill, sqInt leftX, sqInt rightX);
static sqInt fillTypeOf(sqInt fill);
static sqInt findNextAETEdgeFrom(sqInt leftEdge);
static sqInt findNextExternalEntryFromGET(void);
static sqInt findNextExternalFillFromAET(void);
static sqInt findNextExternalUpdateFromAET(void);
static sqInt findStackFilldepth(sqInt fillIndex, sqInt depth);
static sqInt finishedProcessing(void);
static sqInt firstPointListGet(void);
static sqInt firstPointListPut(sqInt value);
static sqInt freeStackFillEntry(void);
EXPORT(const char*) getModuleName(void);
static sqInt getSortsbefore(sqInt edge1, sqInt edge2);
static sqInt getStartGet(void);
static sqInt getStartPut(sqInt value);
static sqInt getUsedGet(void);
static sqInt getUsedPut(sqInt value);
static sqInt gradientRampLengthOf(sqInt fill);
static sqInt gradientRampLengthOfput(sqInt fill, sqInt value);
static int * gradientRampOf(sqInt fill);
static sqInt hasColorTransform(void);
static sqInt hasColorTransformGet(void);
static sqInt hasColorTransformPut(sqInt value);
static sqInt hasEdgeTransform(void);
static sqInt hasEdgeTransformGet(void);
static sqInt hasEdgeTransformPut(sqInt value);
static sqInt hideFilldepth(sqInt fillIndex, sqInt depth);
static sqInt incrementPointby(int *point, sqInt delta);
static sqInt incrementStatby(sqInt statIndex, sqInt value);
static sqInt indexForInsertingIntoAET(sqInt edge);
static sqInt initColorTransform(void);
static sqInt initEdgeTransform(void);
EXPORT(sqInt) initialiseModule(void);
static sqInt initializeGETProcessing(void);
static sqInt insertEdgeIntoAET(sqInt edge);
static sqInt insertToAETbeforeIndex(sqInt edge, sqInt index);
static sqInt isBezier(sqInt bezier);
static sqInt isEdge(sqInt edge);
static sqInt isFillColor(sqInt fill);
static sqInt isFillOkay(sqInt fill);
static sqInt isFill(sqInt fill);
static sqInt isLine(sqInt line);
static sqInt isObject(sqInt obj);
static sqInt isRealFill(sqInt fill);
static sqInt isStackEntry(sqInt entry);
static sqInt isStackIndex(sqInt index);
static sqInt isWideBezier(sqInt bezier);
static sqInt isWideLine(sqInt line);
static sqInt isWide(sqInt object);
static sqInt lastExportedEdgeGet(void);
static sqInt lastExportedEdgePut(sqInt value);
static sqInt lastExportedFillGet(void);
static sqInt lastExportedFillPut(sqInt value);
static sqInt lastExportedLeftXGet(void);
static sqInt lastExportedLeftXPut(sqInt value);
static sqInt lastExportedRightXGet(void);
static sqInt lastExportedRightXPut(sqInt value);
static sqInt lineEndXOf(sqInt line);
static sqInt lineEndXOfput(sqInt line, sqInt value);
static sqInt lineEndYOf(sqInt line);
static sqInt lineEndYOfput(sqInt line, sqInt value);
static sqInt lineErrorAdjDownOf(sqInt line);
static sqInt lineErrorAdjDownOfput(sqInt line, sqInt value);
static sqInt lineErrorAdjUpOf(sqInt line);
static sqInt lineErrorAdjUpOfput(sqInt line, sqInt value);
static sqInt lineErrorOf(sqInt line);
static sqInt lineErrorOfput(sqInt line, sqInt value);
static sqInt lineXDirectionOf(sqInt line);
static sqInt lineXDirectionOfput(sqInt line, sqInt value);
static sqInt lineXIncrementOf(sqInt line);
static sqInt lineXIncrementOfput(sqInt line, sqInt value);
static sqInt lineYDirectionOf(sqInt line);
static sqInt lineYDirectionOfput(sqInt line, sqInt value);
static sqInt loadAndSubdivideBezierFromviatoisWide(int *point1, int *point2, int *point3, sqInt wideFlag);
static sqInt loadArrayPolygonnPointsfilllineWidthlineFill(sqInt points, sqInt nPoints, sqInt fillIndex, sqInt lineWidth, sqInt lineFill);
static sqInt loadArrayShapenSegmentsfilllineWidthlineFill(sqInt points, sqInt nSegments, sqInt fillIndex, sqInt lineWidth, sqInt lineFill);
static sqInt loadArrayTransformFromintolength(sqInt transformOop, float *destPtr, sqInt n);
static sqInt loadBeziersegmentleftFillrightFilloffset(sqInt bezier, sqInt index, sqInt leftFillIndex, sqInt rightFillIndex, sqInt yOffset);
static sqInt loadBitBltFrom(sqInt bbObj);
static sqInt loadBitmapFillcolormaptilefromalongnormalxIndex(sqInt formOop, sqInt cmOop, sqInt tileFlag, int *point1, int *point2, int *point3, sqInt xIndex);
static int * loadBitsFrom(sqInt bmFill);
static sqInt loadColorTransformFrom(sqInt transformOop);
static sqInt loadCompressedSegmentfromshortleftFillrightFilllineWidthlineColor(sqInt segmentIndex, sqInt points, sqInt pointsShort, sqInt leftFill, sqInt rightFill, sqInt lineWidth, sqInt lineFill);
static sqInt loadCompressedShapesegmentsleftFillsrightFillslineWidthslineFillsfillIndexListpointShort(int *points, sqInt nSegments, int *leftFills, int *rightFills, int *lineWidths, int *lineFills, int *fillIndexList, sqInt pointsShort);
static sqInt loadEdgeStateFrom(sqInt edgeOop);
static sqInt loadEdgeTransformFrom(sqInt transformOop);
static sqInt loadFillOrientationfromalongnormalwidthheight(sqInt fill, int *point1, int *point2, int *point3, sqInt fillWidth, sqInt fillHeight);
static sqInt loadFormsFrom(sqInt arrayOop);
static sqInt loadGradientFillfromalongnormalisRadial(sqInt rampOop, int *point1, int *point2, int *point3, sqInt isRadial);
static sqInt loadLinefromtooffsetleftFillrightFill(sqInt line, int *point1, int *point2, sqInt yOffset, sqInt leftFill, sqInt rightFill);
static sqInt loadOvalSegmentwhcxcy(sqInt seg, sqInt w, sqInt h, sqInt cx, sqInt cy);
static sqInt loadOvallineFillleftFillrightFill(sqInt lineWidth, sqInt lineFill, sqInt leftFill, sqInt rightFill);
static sqInt loadPointIntAtfrom(sqInt index, sqInt intArray);
static short loadPointShortAtfrom(sqInt index, sqInt shortArray);
static sqInt loadPointfrom(int *pointArray, sqInt pointOop);
static sqInt loadPolygonnPointsfilllineWidthlineFillpointsShort(int *points, sqInt nPoints, sqInt fillIndex, sqInt lineWidth, sqInt lineFill, sqInt isShort);
static sqInt loadRectanglelineFillleftFillrightFill(sqInt lineWidth, sqInt lineFill, sqInt leftFill, sqInt rightFill);
static sqInt loadRenderingState(void);
static sqInt loadShapenSegmentsfilllineWidthlineFillpointsShort(int *points, sqInt nSegments, sqInt fillIndex, sqInt lineWidth, sqInt lineFill, sqInt pointsShort);
static sqInt loadSpanBufferFrom(sqInt spanOop);
static sqInt loadTransformFromintolength(sqInt transformOop, float *destPtr, sqInt n);
static sqInt loadWideBezierlineFillleftFillrightFilln(sqInt lineWidth, sqInt lineFill, sqInt leftFill, sqInt rightFill, sqInt nSegments);
static sqInt loadWideLinefromtolineFillleftFillrightFill(sqInt lineWidth, int *p1, int *p2, sqInt lineFill, sqInt leftFill, sqInt rightFill);
static sqInt loadWordTransformFromintolength(sqInt transformOop, float *destPtr, sqInt n);
static sqInt loadWorkBufferFrom(sqInt wbOop);
static sqInt magicNumberGet(void);
static sqInt magicNumberPut(sqInt value);
static sqInt makeRectFromPoints(void);
static sqInt makeUnsignedFrom(sqInt someIntegerValue);
EXPORT(sqInt) moduleUnloaded(char *aModuleName);
static sqInt moveAETEntryFromedgex(sqInt index, sqInt edge, sqInt xValue);
static sqInt needAvailableSpace(sqInt nSlots);
static sqInt needsFlush(void);
static sqInt needsFlushGet(void);
static sqInt needsFlushPut(sqInt value);
static sqInt objectHeaderOf(sqInt obj);
static sqInt objectIndexOf(sqInt obj);
static sqInt objectIndexOfput(sqInt obj, sqInt value);
static sqInt objectLengthOf(sqInt obj);
static sqInt objectLengthOfput(sqInt obj, sqInt value);
static sqInt objectTypeOf(sqInt obj);
static sqInt objectTypeOfput(sqInt obj, sqInt value);
static sqInt objStartGet(void);
static sqInt objStartPut(sqInt value);
static sqInt objUsedGet(void);
static sqInt objUsedPut(sqInt value);
static sqInt objat(sqInt object, sqInt index);
static sqInt objatput(sqInt object, sqInt index, sqInt value);
static sqInt offsetFromWidth(sqInt lineWidth);
static int * point1Get(void);
static int * point2Get(void);
static int * point3Get(void);
static int * point4Get(void);
static sqInt postDisplayAction(void);
EXPORT(sqInt) primitiveAbortProcessing(void);
EXPORT(sqInt) primitiveAddActiveEdgeEntry(void);
EXPORT(sqInt) primitiveAddBezier(void);
EXPORT(sqInt) primitiveAddBezierShape(void);
EXPORT(sqInt) primitiveAddBitmapFill(void);
EXPORT(sqInt) primitiveAddCompressedShape(void);
EXPORT(sqInt) primitiveAddGradientFill(void);
EXPORT(sqInt) primitiveAddLine(void);
EXPORT(sqInt) primitiveAddOval(void);
EXPORT(sqInt) primitiveAddPolygon(void);
EXPORT(sqInt) primitiveAddRect(void);
EXPORT(sqInt) primitiveChangedActiveEdgeEntry(void);
EXPORT(sqInt) primitiveCopyBuffer(void);
EXPORT(sqInt) primitiveDisplaySpanBuffer(void);
EXPORT(sqInt) primitiveDoProfileStats(void);
EXPORT(sqInt) primitiveFinishedProcessing(void);
EXPORT(sqInt) primitiveGetAALevel(void);
EXPORT(sqInt) primitiveGetBezierStats(void);
EXPORT(sqInt) primitiveGetClipRect(void);
EXPORT(sqInt) primitiveGetCounts(void);
EXPORT(sqInt) primitiveGetDepth(void);
EXPORT(sqInt) primitiveGetFailureReason(void);
EXPORT(sqInt) primitiveGetOffset(void);
EXPORT(sqInt) primitiveGetTimes(void);
EXPORT(sqInt) primitiveInitializeBuffer(void);
EXPORT(sqInt) primitiveInitializeProcessing(void);
EXPORT(sqInt) primitiveMergeFillFrom(void);
EXPORT(sqInt) primitiveNeedsFlush(void);
EXPORT(sqInt) primitiveNeedsFlushPut(void);
EXPORT(sqInt) primitiveNextActiveEdgeEntry(void);
EXPORT(sqInt) primitiveNextFillEntry(void);
EXPORT(sqInt) primitiveNextGlobalEdgeEntry(void);
EXPORT(sqInt) primitiveRegisterExternalEdge(void);
EXPORT(sqInt) primitiveRegisterExternalFill(void);
EXPORT(sqInt) primitiveRenderImage(void);
EXPORT(sqInt) primitiveRenderScanline(void);
EXPORT(sqInt) primitiveSetAALevel(void);
EXPORT(sqInt) primitiveSetBitBltPlugin(void);
EXPORT(sqInt) primitiveSetClipRect(void);
EXPORT(sqInt) primitiveSetColorTransform(void);
EXPORT(sqInt) primitiveSetDepth(void);
EXPORT(sqInt) primitiveSetEdgeTransform(void);
EXPORT(sqInt) primitiveSetOffset(void);
static sqInt proceedRenderingImage(void);
static sqInt proceedRenderingScanline(void);
static sqInt quickLoadEngineFrom(sqInt engineOop);
static sqInt quickLoadEngineFromrequiredState(sqInt oop, sqInt requiredState);
static sqInt quickLoadEngineFromrequiredStateor(sqInt oop, sqInt requiredState, sqInt alternativeState);
static sqInt quickRemoveInvalidFillsAt(sqInt leftX);
static sqInt quickSortGlobalEdgeTablefromto(int *array, sqInt i, sqInt j);
static sqInt removeFirstAETEntry(void);
static sqInt repeatValuemax(sqInt delta, sqInt maxValue);
static sqInt resetGraphicsEngineStats(void);
static sqInt resortFirstAETEntry(void);
static sqInt returnWideBezierFill(void);
static sqInt returnWideBezierWidth(void);
static sqInt returnWideLineFill(void);
static sqInt returnWideLineWidth(void);
static int * rShiftTable(void);
static sqInt setAALevel(sqInt level);
EXPORT(sqInt) setInterpreter(struct VirtualMachine *anInterpreter);
static sqInt shortRunLengthAtfrom(sqInt i, sqInt runArray);
static sqInt shortRunValueAtfrom(sqInt i, sqInt runArray);
static sqInt showFilldepthrightX(sqInt fillIndex, sqInt depth, sqInt rightX);
static int * smallSqrtTable(void);
static sqInt sortGlobalEdgeTable(void);
static sqInt spanEndAAGet(void);
static sqInt spanEndAAPut(sqInt value);
static sqInt spanEndGet(void);
static sqInt spanEndPut(sqInt value);
static sqInt spanSizeGet(void);
static sqInt spanSizePut(sqInt value);
static sqInt spanStartGet(void);
static sqInt spanStartPut(sqInt value);
static sqInt squaredLengthOfwith(sqInt deltaX, sqInt deltaY);
static sqInt stackFillDepth(sqInt index);
static sqInt stackFillDepthput(sqInt index, sqInt value);
static sqInt stackFillEntryLength(void);
static sqInt stackFillRightX(sqInt index);
static sqInt stackFillRightXput(sqInt index, sqInt value);
static sqInt stackFillSize(void);
static sqInt stackFillValue(sqInt index);
static sqInt stackFillValueput(sqInt index, sqInt value);
static sqInt stateGet(void);
static sqInt statePut(sqInt value);
static sqInt stepToFirstBezier(void);
static sqInt stepToFirstBezierInat(sqInt bezier, sqInt yValue);
static sqInt stepToFirstLine(void);
static sqInt stepToFirstLineInat(sqInt line, sqInt yValue);
static sqInt stepToFirstWideBezier(void);
static sqInt stepToFirstWideBezierInat(sqInt bezier, sqInt yValue);
static sqInt stepToFirstWideLine(void);
static sqInt stepToFirstWideLineInat(sqInt line, sqInt yValue);
static sqInt stepToNextBezier(void);
static sqInt stepToNextBezierForwardat(int *updateData, sqInt yValue);
static sqInt stepToNextBezierInat(sqInt bezier, sqInt yValue);
static sqInt stepToNextLine(void);
static sqInt stepToNextLineInat(sqInt line, sqInt yValue);
static sqInt stepToNextWideBezier(void);
static sqInt stepToNextWideBezierInat(sqInt bezier, sqInt yValue);
static sqInt stepToNextWideLine(void);
static sqInt stepToNextWideLineInat(sqInt line, sqInt yValue);
static sqInt stopBecauseOf(sqInt stopReason);
static sqInt stopReasonGet(void);
static sqInt stopReasonPut(sqInt value);
static sqInt storeEdgeStateFrominto(sqInt edge, sqInt edgeOop);
static sqInt storeEngineStateInto(sqInt oop);
static sqInt storeFillStateInto(sqInt fillOop);
static sqInt storeRenderingState(void);
static sqInt storeStopStateIntoEdgefill(sqInt edgeOop, sqInt fillOop);
static sqInt subdivideBezierFrom(sqInt index);
static sqInt subdivideBezier(sqInt index);
static sqInt subdivideToBeMonotonInX(sqInt index);
static sqInt subdivideToBeMonotonInY(sqInt index);
static sqInt subdivideToBeMonotoninX(sqInt base, sqInt doTestX);
static sqInt toggleFillsOf(sqInt edge);
static sqInt toggleFilldepthrightX(sqInt fillIndex, sqInt depth, sqInt rightX);
static sqInt toggleWideFillOf(sqInt edge);
static sqInt topDepth(void);
static sqInt topFill(void);
static sqInt topFillDepth(void);
static sqInt topFillDepthPut(sqInt value);
static sqInt topFillRightX(void);
static sqInt topFillRightXPut(sqInt value);
static sqInt topFillValue(void);
static sqInt topFillValuePut(sqInt value);
static sqInt topRightX(void);
static sqInt transformColor(sqInt fillIndex);
static sqInt transformPoints(sqInt n);
static sqInt transformPointXyinto(double xValue, double yValue, int *dstPoint);
static sqInt transformPoint(int *point);
static sqInt transformPointinto(sqInt srcPoint, sqInt dstPoint);
static sqInt transformWidth(sqInt w);
static sqInt uncheckedTransformColor(sqInt fillIndex);
static sqInt wbSizeGet(void);
static sqInt wbSizePut(sqInt value);
static sqInt wbStackClear(void);
static sqInt wbStackPop(sqInt nItems);
static sqInt wbStackPush(sqInt nItems);
static sqInt wbStackSize(void);
static sqInt wbStackValue(sqInt index);
static sqInt wbStackValueput(sqInt index, sqInt value);
static sqInt wbTopGet(void);
static sqInt wbTopPut(sqInt value);
static sqInt wideBezierEntryOf(sqInt line);
static sqInt wideBezierEntryOfput(sqInt line, sqInt value);
static sqInt wideBezierExitOf(sqInt line);
static sqInt wideBezierExitOfput(sqInt line, sqInt value);
static sqInt wideBezierExtentOf(sqInt bezier);
static sqInt wideBezierExtentOfput(sqInt bezier, sqInt value);
static sqInt wideBezierFillOf(sqInt bezier);
static sqInt wideBezierFillOfput(sqInt bezier, sqInt value);
static int * wideBezierUpdateDataOf(sqInt bezier);
static sqInt wideBezierWidthOf(sqInt line);
static sqInt wideBezierWidthOfput(sqInt line, sqInt value);
static sqInt wideLineEntryOf(sqInt line);
static sqInt wideLineEntryOfput(sqInt line, sqInt value);
static sqInt wideLineExitOf(sqInt line);
static sqInt wideLineExitOfput(sqInt line, sqInt value);
static sqInt wideLineExtentOf(sqInt line);
static sqInt wideLineExtentOfput(sqInt line, sqInt value);
static sqInt wideLineFillOf(sqInt line);
static sqInt wideLineFillOfput(sqInt line, sqInt value);
static sqInt wideLineWidthOf(sqInt line);
static sqInt wideLineWidthOfput(sqInt line, sqInt value);
static sqInt workBufferPut(sqInt wbOop);


/*** Variables ***/
static int* aetBuffer;
static char bbPluginName[256] = "BitBltPlugin";
static void * copyBitsFn;
static sqInt dispatchedValue;
static sqInt dispatchReturnValue;
static int doProfileStats = 0;
static sqInt engine;
static sqInt engineStopped;
static sqInt formArray;
static sqInt geProfileTime;
static int* getBuffer;

#if !defined(SQUEAK_BUILTIN_PLUGIN)
static sqInt (*booleanValueOf)(sqInt obj);
static sqInt (*byteSizeOf)(sqInt oop);
static sqInt (*classBitmap)(void);
static sqInt (*classPoint)(void);
static sqInt (*failed)(void);
static sqInt (*fetchClassOf)(sqInt oop);
static sqInt (*fetchIntegerofObject)(sqInt fieldIndex, sqInt objectPointer);
static sqInt (*fetchPointerofObject)(sqInt index, sqInt oop);
static void * (*firstIndexableField)(sqInt oop);
static double (*floatValueOf)(sqInt oop);
static sqInt (*integerValueOf)(sqInt oop);
static void * (*ioLoadFunctionFrom)(char *functionName, char *moduleName);
static sqInt (*ioMicroMSecs)(void);
static sqInt (*isArray)(sqInt oop);
static sqInt (*isBytes)(sqInt oop);
static sqInt (*isFloatObject)(sqInt oop);
static sqInt (*isImmediate)(sqInt anObject);
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 void (*popthenPush)(sqInt nItems, sqInt oop);
static sqInt (*popRemappableOop)(void);
static sqInt (*positive32BitIntegerFor)(unsigned int integerValue);
static usqInt (*positive32BitValueOf)(sqInt oop);
static sqInt (*primitiveFail)(void);
static sqInt (*primitiveFailFor)(sqInt reasonCode);
static sqInt (*pushBool)(sqInt trueOrFalse);
static sqInt (*pushInteger)(sqInt integerValue);
static void (*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 (*topRemappableOop)(void);
#else /* !defined(SQUEAK_BUILTIN_PLUGIN) */
extern sqInt booleanValueOf(sqInt obj);
extern sqInt byteSizeOf(sqInt oop);
extern sqInt classBitmap(void);
extern sqInt classPoint(void);
extern sqInt failed(void);
extern sqInt fetchClassOf(sqInt oop);
extern sqInt fetchIntegerofObject(sqInt fieldIndex, sqInt objectPointer);
extern sqInt fetchPointerofObject(sqInt index, sqInt oop);
extern void * firstIndexableField(sqInt oop);
extern double floatValueOf(sqInt oop);
extern sqInt integerValueOf(sqInt oop);
extern void * ioLoadFunctionFrom(char *functionName, char *moduleName);
extern sqInt ioMicroMSecs(void);
extern sqInt isArray(sqInt oop);
extern sqInt isBytes(sqInt oop);
extern sqInt isFloatObject(sqInt oop);
#if !defined(isImmediate)
#if VM_PROXY_MAJOR > 1 || (VM_PROXY_MAJOR == 1 && VM_PROXY_MINOR >= 13)
extern sqInt isImmediate(sqInt anObject);
#else
# define isImmediate(anObject) 0
#endif
#endif /* !defined(isImmediate) */
#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 void popthenPush(sqInt nItems, sqInt oop);
extern sqInt popRemappableOop(void);
extern sqInt positive32BitIntegerFor(unsigned int integerValue);
extern usqInt positive32BitValueOf(sqInt oop);
extern sqInt primitiveFail(void);
extern sqInt primitiveFailFor(sqInt reasonCode);
extern sqInt pushBool(sqInt trueOrFalse);
extern sqInt pushInteger(sqInt integerValue);
extern void 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 topRemappableOop(void);
extern
#endif
struct VirtualMachine* interpreterProxy;
static void * loadBBFn;
static const char *moduleName =
#ifdef SQUEAK_BUILTIN_PLUGIN
	"B2DPlugin VMMaker.oscog-eem.2480 (i)"
#else
	"B2DPlugin VMMaker.oscog-eem.2480 (e)"
#endif
;
static int* objBuffer;
static sqInt objUsed;
static unsigned int* spanBuffer;
static int* workBuffer;


	/* BalloonEngineBase>>#aaColorMaskGet */
static sqInt
aaColorMaskGet(void)
{
	return workBuffer[GWAAColorMask];
}

	/* BalloonEngineBase>>#aaColorMaskPut: */
static sqInt
aaColorMaskPut(sqInt value)
{
	return workBuffer[GWAAColorMask] = value;
}

	/* BalloonEngineBase>>#aaColorShiftGet */
static sqInt
aaColorShiftGet(void)
{
	return workBuffer[GWAAColorShift];
}

	/* BalloonEngineBase>>#aaColorShiftPut: */
static sqInt
aaColorShiftPut(sqInt value)
{
	return workBuffer[GWAAColorShift] = value;
}


/*	Common function to compute the first full pixel for AA drawing */

	/* BalloonEngineBase>>#aaFirstPixelFrom:to: */
static sqInt
aaFirstPixelFromto(sqInt leftX, sqInt rightX)
{
    sqInt firstPixel;

	firstPixel = ((leftX + (workBuffer[GWAALevel])) - 1) & ((unsigned int)~((workBuffer[GWAALevel]) - 1));
	if (firstPixel > rightX) {
		return rightX;
	}
	else {
		return firstPixel;
	}
}

	/* BalloonEngineBase>>#aaHalfPixelGet */
static sqInt
aaHalfPixelGet(void)
{
	return workBuffer[GWAAHalfPixel];
}

	/* BalloonEngineBase>>#aaHalfPixelPut: */
static sqInt
aaHalfPixelPut(sqInt value)
{
	return workBuffer[GWAAHalfPixel] = value;
}


/*	Common function to compute the last full pixel for AA drawing */

	/* BalloonEngineBase>>#aaLastPixelFrom:to: */
static sqInt
aaLastPixelFromto(sqInt leftX, sqInt rightX)
{
	return (rightX - 1) & ((unsigned int)~((workBuffer[GWAALevel]) - 1));
}

	/* BalloonEngineBase>>#aaLevelGet */
static sqInt
aaLevelGet(void)
{
	return workBuffer[GWAALevel];
}

	/* BalloonEngineBase>>#aaLevelPut: */
static sqInt
aaLevelPut(sqInt value)
{
	return workBuffer[GWAALevel] = value;
}

	/* BalloonEngineBase>>#aaScanMaskGet */
static sqInt
aaScanMaskGet(void)
{
	return workBuffer[GWAAScanMask];
}

	/* BalloonEngineBase>>#aaScanMaskPut: */
static sqInt
aaScanMaskPut(sqInt value)
{
	return workBuffer[GWAAScanMask] = value;
}

	/* BalloonEngineBase>>#aaShiftGet */
static sqInt
aaShiftGet(void)
{
	return workBuffer[GWAAShift];
}

	/* BalloonEngineBase>>#aaShiftPut: */
static sqInt
aaShiftPut(sqInt value)
{
	return workBuffer[GWAAShift] = value;
}


/*	Compute the squared value of a 8.24 number with 0.0 <= value < 1.0,
	e.g., compute (value * value) bitShift: -24 */

	/* BalloonEnginePlugin>>#absoluteSquared8Dot24: */
static sqInt
absoluteSquared8Dot24(sqInt value)
{
    unsigned int word1;
    unsigned int word2;

	word1 = value & 0xFFFF;
	word2 = (((usqInt) value >> 16)) & 0xFF;
	return ((usqInt) (((((usqInt) (word1 * word1) >> 16)) + ((word1 * word2) * 2)) + (((usqInt) (word2 * word2) << 16))) >> 8);
}


/*	Return the accurate length of the vector described by deltaX and deltaY */

	/* BalloonEngineBase>>#accurateLengthOf:with: */
static sqInt
accurateLengthOfwith(sqInt deltaX, sqInt deltaY)
{
    sqInt length2;

	if (deltaX == 0) {
		if (deltaY < 0) {
			return 0 - deltaY;
		}
		else {
			return deltaY;
		}
	}
	if (deltaY == 0) {
		if (deltaX < 0) {
			return 0 - deltaX;
		}
		else {
			return deltaX;
		}
	}
	length2 = (deltaX * deltaX) + (deltaY * deltaY);
	/* begin computeSqrt: */
	if (length2 < 32) {
		return (smallSqrtTable())[length2];
	}
	else {
		return ((sqInt)((sqrt(((double) length2 ))) + 0.5));
	}
}

	/* BalloonEngineBase>>#addEdgeToGET: */
static sqInt
addEdgeToGET(sqInt edge)
{
	if (!(allocateGETEntry(1))) {
		return 0;
	}
	getBuffer[workBuffer[GWGETUsed]] = edge;
	/* begin getUsedPut: */
	workBuffer[GWGETUsed] = ((workBuffer[GWGETUsed]) + 1);
	return 0;
}


/*	NOTE: This method is (hopefully) obsolete due to unrolling 
	the fill loops to deal with full pixels. */
/*	Adjust the span buffers values by the appropriate color offset for
	anti-aliasing. We do this by replicating the top bits of each color in the
	lower bits. The idea is that we can scale each color value uniquely from 0
	to 255 and thus fill the entire range of colors.
 */

	/* BalloonEngineBase>>#adjustAALevel */
static sqInt
adjustAALevel(void)
{
    unsigned int adjustMask;
    sqInt adjustShift;
    unsigned int pixelValue;
    sqInt x0;
    sqInt x1;

	adjustShift = 8 - (workBuffer[GWAAColorShift]);
	adjustMask = (unsigned int)~(workBuffer[GWAAColorMask]);
	x0 = ((usqInt) (workBuffer[GWSpanStart])) >> (workBuffer[GWAAShift]);
	x1 = ((usqInt) (workBuffer[GWSpanEnd])) >> (workBuffer[GWAAShift]);
	while (x0 < x1) {
		pixelValue = spanBuffer[x0];
		spanBuffer[x0] = (pixelValue | ((((usqInt) pixelValue) >> adjustShift) & adjustMask));
		x0 += 1;
	}
	return 0;
}


/*	Adjust the wide bezier curve (dx < 0) to start/end at the right point */

	/* BalloonEnginePlugin>>#adjustWideBezierLeft:width:offset:endX: */
static sqInt
adjustWideBezierLeftwidthoffsetendX(sqInt bezier, sqInt lineWidth, sqInt lineOffset, sqInt endX)
{
    int lastX;
    int lastY;

	((objBuffer + bezier) + GBUpdateData)[GBUpdateX] = ((((objBuffer + bezier) + GBUpdateData)[GBUpdateX]) - (lineOffset * 256));
	lastX = ((objBuffer + bezier) + GBWideUpdateData)[GBUpdateX];
	((objBuffer + bezier) + GBWideUpdateData)[GBUpdateX] = (lastX + ((lineWidth - lineOffset) * 256));
	lastY = ((objBuffer + bezier) + GBWideUpdateData)[GBUpdateY];
	((objBuffer + bezier) + GBWideUpdateData)[GBUpdateY] = (lastY + (lineWidth * 256));
	/* begin obj:at:put: */
	objBuffer[bezier + GBFinalX] = (endX - lineOffset);
	return 0;
}


/*	Adjust the wide bezier curve (dx >= 0) to start/end at the right point */

	/* BalloonEnginePlugin>>#adjustWideBezierRight:width:offset:endX: */
static sqInt
adjustWideBezierRightwidthoffsetendX(sqInt bezier, sqInt lineWidth, sqInt lineOffset, sqInt endX)
{
    int lastX;
    int lastY;

	((objBuffer + bezier) + GBUpdateData)[GBUpdateX] = ((((objBuffer + bezier) + GBUpdateData)[GBUpdateX]) + (lineOffset * 256));
	lastX = ((objBuffer + bezier) + GBWideUpdateData)[GBUpdateX];
	((objBuffer + bezier) + GBWideUpdateData)[GBUpdateX] = (lastX - ((lineWidth - lineOffset) * 256));

	/* Set lineWidth pixels down */
	lastY = ((objBuffer + bezier) + GBWideUpdateData)[GBUpdateY];
	((objBuffer + bezier) + GBWideUpdateData)[GBUpdateY] = (lastY + (lineWidth * 256));
	/* begin obj:at:put: */
	objBuffer[bezier + GBFinalX] = ((endX - lineOffset) + lineWidth);
	return 0;
}


/*	Adjust the wide line after it has been stepped from lastX to nextX.
	Special adjustments of line width and start position are made here
	to simulate a rectangular brush */

	/* BalloonEnginePlugin>>#adjustWideLine:afterSteppingFrom:to: */
static sqInt
adjustWideLineafterSteppingFromto(sqInt line, sqInt lastX, sqInt nextX)
{
    sqInt baseWidth;
    sqInt deltaX;
    sqInt lineOffset;
    sqInt lineWidth;
    sqInt xDir;
    sqInt yEntry;
    sqInt yExit;


	/* Don't inline this */
	/* Fetch the values the adjustment decisions are based on */
	/* begin obj:at: */
	yEntry = objBuffer[line + GLWideEntry];
	/* begin obj:at: */
	yExit = objBuffer[line + GLWideExit];
	/* begin obj:at: */
	baseWidth = objBuffer[line + GLWideExtent];
	lineOffset = baseWidth / 2;
	/* begin obj:at: */
	lineWidth = objBuffer[line + GLWideWidth];
	/* begin obj:at: */
	xDir = objBuffer[line + GLXDirection];

	/* Adjust the start of the line to fill an entire rectangle */
	deltaX = nextX - lastX;
	if (yEntry < baseWidth) {
		if (xDir < 0) {

			/* effectively adding */
			lineWidth -= deltaX;
		}
		else {
			lineWidth += deltaX;
			/* begin obj:at:put: */
			objBuffer[line + GEXValue] = lastX;
		}
	}
	if ((yExit + lineOffset) == 0) {
		if (xDir > 0) {
			lineWidth -= objBuffer[line + GLXIncrement];
		}
		else {

			/* effectively subtracting */
			lineWidth += objBuffer[line + GLXIncrement];
			/* begin obj:at:put: */
			objBuffer[line + GEXValue] = lastX;
		}
	}
	if ((yExit + lineOffset) > 0) {
		if (xDir < 0) {

			/* effectively subtracting */
			lineWidth += deltaX;
			/* begin obj:at:put: */
			objBuffer[line + GEXValue] = lastX;
		}
		else {
			lineWidth -= deltaX;
		}
	}
	/* begin obj:at:put: */
	objBuffer[line + GLWideWidth] = lineWidth;
	return 0;
}

	/* BalloonEngineBase>>#aetStartGet */
static sqInt
aetStartGet(void)
{
	return workBuffer[GWAETStart];
}

	/* BalloonEngineBase>>#aetStartPut: */
static sqInt
aetStartPut(sqInt value)
{
	return workBuffer[GWAETStart] = value;
}

	/* BalloonEngineBase>>#aetUsedGet */
static sqInt
aetUsedGet(void)
{
	return workBuffer[GWAETUsed];
}

	/* BalloonEngineBase>>#aetUsedPut: */
static sqInt
aetUsedPut(sqInt value)
{
	return workBuffer[GWAETUsed] = value;
}


/*	Allocate n slots in the active edge table */

	/* BalloonEngineBase>>#allocateAETEntry: */
static sqInt
allocateAETEntry(sqInt nSlots)
{
	/* begin needAvailableSpace: */
	if (((((GWHeaderSize + objUsed) + (workBuffer[GWGETUsed])) + (workBuffer[GWAETUsed])) + nSlots) > (workBuffer[GWBufferTop])) {
		/* begin stopBecauseOf: */
		workBuffer[GWStopReason] = GErrorNoMoreSpace;
		engineStopped = 1;
		return 0;
	}
	return 1;
}

	/* BalloonEnginePlugin>>#allocateBezier */
static sqInt
allocateBezier(void)
{
    sqInt bezier;

	if (!(allocateObjEntry(GBBaseSize))) {
		return 0;
	}
	bezier = objUsed;
	objUsed = bezier + GBBaseSize;
	/* begin obj:at:put: */
	objBuffer[bezier + GEObjectType] = GEPrimitiveBezier;
	/* begin obj:at:put: */
	objBuffer[bezier + GEObjectIndex] = 0;
	/* begin obj:at:put: */
	objBuffer[bezier + GEObjectLength] = GBBaseSize;
	return bezier;
}

	/* BalloonEnginePlugin>>#allocateBezierStackEntry */
static sqInt
allocateBezierStackEntry(void)
{
	/* begin wbStackPush: */
	if (!(needAvailableSpace(6))) {
		goto l2;
	}
	/* begin wbTopPut: */
	workBuffer[GWBufferTop] = ((workBuffer[GWBufferTop]) - 6);
	l2:	/* end wbStackPush: */;
	return (workBuffer[GWSize]) - (workBuffer[GWBufferTop]);
}

	/* BalloonEnginePlugin>>#allocateBitmapFill:colormap: */
static sqInt
allocateBitmapFillcolormap(sqInt cmSize, int *cmBits)
{
    int *cm;
    sqInt fill;
    sqInt fillSize;
    sqInt i;

	fillSize = GBMBaseSize + cmSize;
	if (!(allocateObjEntry(fillSize))) {
		return 0;
	}
	fill = objUsed;
	objUsed = fill + fillSize;
	/* begin obj:at:put: */
	objBuffer[fill + GEObjectType] = GEPrimitiveClippedBitmapFill;
	/* begin obj:at:put: */
	objBuffer[fill + GEObjectIndex] = 0;
	/* begin obj:at:put: */
	objBuffer[fill + GEObjectLength] = fillSize;
	cm = (objBuffer + fill) + GBColormapOffset;
	if ((workBuffer[GWHasColorTransform]) != 0) {
		for (i = 0; i < cmSize; i += 1) {
			cm[i] = (transformColor(cmBits[i]));
		}
	}
	else {
		for (i = 0; i < cmSize; i += 1) {
			cm[i] = (cmBits[i]);
		}
	}
	/* begin obj:at:put: */
	objBuffer[fill + GBColormapSize] = cmSize;
	return fill;
}


/*	Allocate n slots in the global edge table */

	/* BalloonEngineBase>>#allocateGETEntry: */
static sqInt
allocateGETEntry(sqInt nSlots)
{
    sqInt dstIndex;
    sqInt i;
    sqInt srcIndex;


	/* First allocate nSlots in the AET */
	if (!(needAvailableSpace(nSlots))) {
		return 0;
	}
	if (!((workBuffer[GWAETUsed]) == 0)) {

		/* Then move the AET upwards */
		/* begin aetUsedGet */
		srcIndex = workBuffer[GWAETUsed];
		dstIndex = (workBuffer[GWAETUsed]) + nSlots;
		for (i = 1; i <= (workBuffer[GWAETUsed]); i += 1) {
			aetBuffer[(dstIndex -= 1)] = (aetBuffer[(srcIndex -= 1)]);
		}
	}
	aetBuffer += nSlots;
	return 1;
}

	/* BalloonEnginePlugin>>#allocateGradientFill:rampWidth:isRadial: */
static sqInt
allocateGradientFillrampWidthisRadial(int *ramp, sqInt rampWidth, sqInt isRadial)
{
    sqInt fill;
    sqInt fillSize;
    sqInt i;
    int *rampPtr;

	fillSize = GGBaseSize + rampWidth;
	if (!(allocateObjEntry(fillSize))) {
		return 0;
	}
	fill = objUsed;
	objUsed = fill + fillSize;
	if (isRadial) {
		/* begin obj:at:put: */
		objBuffer[fill + GEObjectType] = GEPrimitiveRadialGradientFill;
	}
	else {
		/* begin obj:at:put: */
		objBuffer[fill + GEObjectType] = GEPrimitiveLinearGradientFill;
	}
	/* begin obj:at:put: */
	objBuffer[fill + GEObjectIndex] = 0;
	/* begin obj:at:put: */
	objBuffer[fill + GEObjectLength] = fillSize;
	rampPtr = (objBuffer + fill) + GFRampOffset;
	if ((workBuffer[GWHasColorTransform]) != 0) {
		for (i = 0; i < rampWidth; i += 1) {
			rampPtr[i] = (transformColor(ramp[i]));
		}
	}
	else {
		for (i = 0; i < rampWidth; i += 1) {
			rampPtr[i] = (ramp[i]);
		}
	}
	/* begin obj:at:put: */
	objBuffer[fill + GFRampLength] = rampWidth;
	return fill;
}

	/* BalloonEnginePlugin>>#allocateLine */
static sqInt
allocateLine(void)
{
    sqInt line;

	if (!(allocateObjEntry(GLBaseSize))) {
		return 0;
	}
	line = objUsed;
	objUsed = line + GLBaseSize;
	/* begin obj:at:put: */
	objBuffer[line + GEObjectType] = GEPrimitiveLine;
	/* begin obj:at:put: */
	objBuffer[line + GEObjectIndex] = 0;
	/* begin obj:at:put: */
	objBuffer[line + GEObjectLength] = GLBaseSize;
	return line;
}


/*	Allocate n slots in the object buffer */

	/* BalloonEngineBase>>#allocateObjEntry: */
static sqInt
allocateObjEntry(sqInt nSlots)
{
    sqInt dstIndex;
    sqInt i;
    sqInt srcIndex;


	/* First allocate nSlots in the GET */
	if (!(allocateGETEntry(nSlots))) {
		return 0;
	}
	if (!((workBuffer[GWGETUsed]) == 0)) {

		/* Then move the GET upwards */
		srcIndex = workBuffer[GWGETUsed];
		dstIndex = (workBuffer[GWGETUsed]) + nSlots;
		for (i = 1; i <= (workBuffer[GWGETUsed]); i += 1) {
			getBuffer[(dstIndex -= 1)] = (getBuffer[(srcIndex -= 1)]);
		}
	}
	getBuffer += nSlots;
	return 1;
}


/*	AET and Stack allocation are symmetric */

	/* BalloonEngineBase>>#allocateStackEntry: */
static sqInt
allocateStackEntry(sqInt nSlots)
{
	/* begin needAvailableSpace: */
	if (((((GWHeaderSize + objUsed) + (workBuffer[GWGETUsed])) + (workBuffer[GWAETUsed])) + nSlots) > (workBuffer[GWBufferTop])) {
		/* begin stopBecauseOf: */
		workBuffer[GWStopReason] = GErrorNoMoreSpace;
		engineStopped = 1;
		return 0;
	}
	return 1;
}

	/* BalloonEngineBase>>#allocateStackFillEntry */
static sqInt
allocateStackFillEntry(void)
{
	/* begin wbStackPush: */
	if (!(needAvailableSpace(3 /* stackFillEntryLength */))) {
		return 0;
	}
	/* begin wbTopPut: */
	workBuffer[GWBufferTop] = ((workBuffer[GWBufferTop]) - 3 /* stackFillEntryLength */);
	return 1;
}

	/* BalloonEnginePlugin>>#allocateWideBezier */
static sqInt
allocateWideBezier(void)
{
    sqInt bezier;

	if (!(allocateObjEntry(GBWideSize))) {
		return 0;
	}
	bezier = objUsed;
	objUsed = bezier + GBWideSize;
	/* begin obj:at:put: */
	objBuffer[bezier + GEObjectType] = GEPrimitiveWideBezier;
	/* begin obj:at:put: */
	objBuffer[bezier + GEObjectIndex] = 0;
	/* begin obj:at:put: */
	objBuffer[bezier + GEObjectLength] = GBWideSize;
	return bezier;
}

	/* BalloonEnginePlugin>>#allocateWideLine */
static sqInt
allocateWideLine(void)
{
    sqInt line;

	if (!(allocateObjEntry(GLWideSize))) {
		return 0;
	}
	line = objUsed;
	objUsed = line + GLWideSize;
	/* begin obj:at:put: */
	objBuffer[line + GEObjectType] = GEPrimitiveWideLine;
	/* begin obj:at:put: */
	objBuffer[line + GEObjectIndex] = 0;
	/* begin obj:at:put: */
	objBuffer[line + GEObjectLength] = GLWideSize;
	return line;
}

	/* BalloonEngineBase>>#areEdgeFillsValid: */
static sqInt
areEdgeFillsValid(sqInt edge)
{
	return ((objBuffer[edge + GEObjectType]) & GEEdgeFillsInvalid) == 0;
}


/*	Make sure that val1 is between val2 and val3. */

	/* BalloonEnginePlugin>>#assureValue:between:and: */
static sqInt
assureValuebetweenand(sqInt val1, sqInt val2, sqInt val3)
{
	if (val2 > val3) {
		if (val1 > val2) {
			return val2;
		}
		if (val1 < val3) {
			return val3;
		}
	}
	else {
		if (val1 < val2) {
			return val2;
		}
		if (val1 > val3) {
			return val3;
		}
	}
	return val1;
}

	/* BalloonEnginePlugin>>#bezierEndXOf: */
static sqInt
bezierEndXOf(sqInt bezier)
{
	return objBuffer[bezier + GBEndX];
}

	/* BalloonEnginePlugin>>#bezierEndXOf:put: */
static sqInt
bezierEndXOfput(sqInt bezier, sqInt value)
{
	return objBuffer[bezier + GBEndX] = value;
}

	/* BalloonEnginePlugin>>#bezierEndYOf: */
static sqInt
bezierEndYOf(sqInt bezier)
{
	return objBuffer[bezier + GBEndY];
}

	/* BalloonEnginePlugin>>#bezierEndYOf:put: */
static sqInt
bezierEndYOfput(sqInt bezier, sqInt value)
{
	return objBuffer[bezier + GBEndY] = value;
}

	/* BalloonEnginePlugin>>#bezierFinalXOf: */
static sqInt
bezierFinalXOf(sqInt bezier)
{
	return objBuffer[bezier + GBFinalX];
}

	/* BalloonEnginePlugin>>#bezierFinalXOf:put: */
static sqInt
bezierFinalXOfput(sqInt bezier, sqInt value)
{
	return objBuffer[bezier + GBFinalX] = value;
}

	/* BalloonEnginePlugin>>#bezierUpdateDataOf: */
static int *
bezierUpdateDataOf(sqInt bezier)
{
	return (objBuffer + bezier) + GBUpdateData;
}

	/* BalloonEnginePlugin>>#bezierViaXOf: */
static sqInt
bezierViaXOf(sqInt bezier)
{
	return objBuffer[bezier + GBViaX];
}

	/* BalloonEnginePlugin>>#bezierViaXOf:put: */
static sqInt
bezierViaXOfput(sqInt bezier, sqInt value)
{
	return objBuffer[bezier + GBViaX] = value;
}

	/* BalloonEnginePlugin>>#bezierViaYOf: */
static sqInt
bezierViaYOf(sqInt bezier)
{
	return objBuffer[bezier + GBViaY];
}

	/* BalloonEnginePlugin>>#bezierViaYOf:put: */
static sqInt
bezierViaYOfput(sqInt bezier, sqInt value)
{
	return objBuffer[bezier + GBViaY] = value;
}

	/* BalloonEnginePlugin>>#bitmapCmSizeOf: */
static sqInt
bitmapCmSizeOf(sqInt bmFill)
{
	return objBuffer[bmFill + GBColormapSize];
}

	/* BalloonEnginePlugin>>#bitmapCmSizeOf:put: */
static sqInt
bitmapCmSizeOfput(sqInt bmFill, sqInt value)
{
	return objBuffer[bmFill + GBColormapSize] = value;
}

	/* BalloonEnginePlugin>>#bitmapDepthOf: */
static sqInt
bitmapDepthOf(sqInt bmFill)
{
	return objBuffer[bmFill + GBBitmapDepth];
}

	/* BalloonEnginePlugin>>#bitmapDepthOf:put: */
static sqInt
bitmapDepthOfput(sqInt bmFill, sqInt value)
{
	return objBuffer[bmFill + GBBitmapDepth] = value;
}

	/* BalloonEnginePlugin>>#bitmapHeightOf: */
static sqInt
bitmapHeightOf(sqInt bmFill)
{
	return objBuffer[bmFill + GBBitmapHeight];
}

	/* BalloonEnginePlugin>>#bitmapHeightOf:put: */
static sqInt
bitmapHeightOfput(sqInt bmFill, sqInt value)
{
	return objBuffer[bmFill + GBBitmapHeight] = value;
}

	/* BalloonEnginePlugin>>#bitmapRasterOf: */
static sqInt
bitmapRasterOf(sqInt bmFill)
{
	return objBuffer[bmFill + GBBitmapRaster];
}

	/* BalloonEnginePlugin>>#bitmapRasterOf:put: */
static sqInt
bitmapRasterOfput(sqInt bmFill, sqInt value)
{
	return objBuffer[bmFill + GBBitmapRaster] = value;
}

	/* BalloonEnginePlugin>>#bitmapSizeOf: */
static sqInt
bitmapSizeOf(sqInt bmFill)
{
	return objBuffer[bmFill + GBBitmapSize];
}

	/* BalloonEnginePlugin>>#bitmapSizeOf:put: */
static sqInt
bitmapSizeOfput(sqInt bmFill, sqInt value)
{
	return objBuffer[bmFill + GBBitmapSize] = value;
}

	/* BalloonEnginePlugin>>#bitmapTileFlagOf: */
static sqInt
bitmapTileFlagOf(sqInt bmFill)
{
	return objBuffer[bmFill + GBTileFlag];
}

	/* BalloonEnginePlugin>>#bitmapTileFlagOf:put: */
static sqInt
bitmapTileFlagOfput(sqInt bmFill, sqInt value)
{
	return objBuffer[bmFill + GBTileFlag] = value;
}

	/* BalloonEnginePlugin>>#bitmapValue:bits:atX:y: */
static sqInt
bitmapValuebitsatXy(sqInt bmFill, sqInt bits, sqInt xp, sqInt yp)
{
    sqInt a;
    sqInt b;
    sqInt bmDepth;
    sqInt bmRaster;
    int cMask;
    sqInt g;
    sqInt r;
    int rShift;
    int value;

	/* begin bitmapDepthOf: */
	bmDepth = objBuffer[bmFill + GBBitmapDepth];
	/* begin bitmapRasterOf: */
	bmRaster = objBuffer[bmFill + GBBitmapRaster];
	if (bmDepth == 32) {
		value = (((int*) bits))[(bmRaster * yp) + xp];
		if ((value != 0)
		 && ((value & 0xFF000000U) == 0)) {
			value = value | 0xFF000000U;
		}
		return uncheckedTransformColor(value);
	}
	rShift = (rShiftTable())[bmDepth];

	/* cMask - mask out the pixel from the word */
	value = (((int*) bits))[(bmRaster * yp) + (((usqInt) xp) >> rShift)];

	/* rShift - shift value to move the pixel in the word to the lowest bit position */
	cMask = (1U << bmDepth) - 1;
	rShift = (32 - bmDepth) - ((xp & ((1U << rShift) - 1)) * bmDepth);
	value = (((usqInt) value) >> rShift) & cMask;
	if (bmDepth == 16) {

		/* Must convert by expanding bits */
		if (!(value == 0)) {
			b = ((sqInt)((usqInt)((value & 0x1F)) << 3));
			b += ((usqInt) b) >> 5;
			g = ((sqInt)((usqInt)(((((usqInt) value) >> 5) & 0x1F)) << 3));
			g += ((usqInt) g) >> 5;
			r = ((sqInt)((usqInt)(((((usqInt) value) >> 10) & 0x1F)) << 3));
			r += ((usqInt) r) >> 5;
			a = 0xFF;
			value = ((b + (((sqInt)((usqInt)(g) << 8)))) + (((sqInt)((usqInt)(r) << 16)))) + (((sqInt)((usqInt)(a) << 24)));
		}
	}
	else {

		/* Must convert by using color map */
		if ((objBuffer[bmFill + GBColormapSize]) == 0) {
			value = 0;
		}
		else {
			/* begin makeUnsignedFrom: */
			value = ((objBuffer + bmFill) + GBColormapOffset)[value];
		}
	}
	return uncheckedTransformColor(value);
}

	/* BalloonEnginePlugin>>#bitmapWidthOf: */
static sqInt
bitmapWidthOf(sqInt bmFill)
{
	return objBuffer[bmFill + GBBitmapWidth];
}

	/* BalloonEnginePlugin>>#bitmapWidthOf:put: */
static sqInt
bitmapWidthOfput(sqInt bmFill, sqInt value)
{
	return objBuffer[bmFill + GBBitmapWidth] = value;
}

	/* BalloonEnginePlugin>>#bzEndX: */
static sqInt
bzEndX(sqInt index)
{
    sqInt index1;

	/* begin wbStackValue: */
	index1 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 4;
	return workBuffer[(workBuffer[GWBufferTop]) + index1];
}

	/* BalloonEnginePlugin>>#bzEndX:put: */
static sqInt
bzEndXput(sqInt index, sqInt value)
{
    sqInt index1;

	/* begin wbStackValue:put: */
	index1 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 4;
	return workBuffer[(workBuffer[GWBufferTop]) + index1] = value;
}

	/* BalloonEnginePlugin>>#bzEndY: */
static sqInt
bzEndY(sqInt index)
{
    sqInt index1;

	/* begin wbStackValue: */
	index1 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 5;
	return workBuffer[(workBuffer[GWBufferTop]) + index1];
}

	/* BalloonEnginePlugin>>#bzEndY:put: */
static sqInt
bzEndYput(sqInt index, sqInt value)
{
    sqInt index1;

	/* begin wbStackValue:put: */
	index1 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 5;
	return workBuffer[(workBuffer[GWBufferTop]) + index1] = value;
}

	/* BalloonEnginePlugin>>#bzStartX: */
static sqInt
bzStartX(sqInt index)
{
    sqInt index1;

	/* begin wbStackValue: */
	index1 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index);
	return workBuffer[(workBuffer[GWBufferTop]) + index1];
}

	/* BalloonEnginePlugin>>#bzStartX:put: */
static sqInt
bzStartXput(sqInt index, sqInt value)
{
    sqInt index1;

	/* begin wbStackValue:put: */
	index1 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index);
	return workBuffer[(workBuffer[GWBufferTop]) + index1] = value;
}

	/* BalloonEnginePlugin>>#bzStartY: */
static sqInt
bzStartY(sqInt index)
{
    sqInt index1;

	/* begin wbStackValue: */
	index1 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 1;
	return workBuffer[(workBuffer[GWBufferTop]) + index1];
}

	/* BalloonEnginePlugin>>#bzStartY:put: */
static sqInt
bzStartYput(sqInt index, sqInt value)
{
    sqInt index1;

	/* begin wbStackValue:put: */
	index1 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 1;
	return workBuffer[(workBuffer[GWBufferTop]) + index1] = value;
}

	/* BalloonEnginePlugin>>#bzViaX: */
static sqInt
bzViaX(sqInt index)
{
    sqInt index1;

	/* begin wbStackValue: */
	index1 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 2;
	return workBuffer[(workBuffer[GWBufferTop]) + index1];
}

	/* BalloonEnginePlugin>>#bzViaX:put: */
static sqInt
bzViaXput(sqInt index, sqInt value)
{
    sqInt index1;

	/* begin wbStackValue:put: */
	index1 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 2;
	return workBuffer[(workBuffer[GWBufferTop]) + index1] = value;
}

	/* BalloonEnginePlugin>>#bzViaY: */
static sqInt
bzViaY(sqInt index)
{
    sqInt index1;

	/* begin wbStackValue: */
	index1 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 3;
	return workBuffer[(workBuffer[GWBufferTop]) + index1];
}

	/* BalloonEnginePlugin>>#bzViaY:put: */
static sqInt
bzViaYput(sqInt index, sqInt value)
{
    sqInt index1;

	/* begin wbStackValue:put: */
	index1 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 3;
	return workBuffer[(workBuffer[GWBufferTop]) + index1] = value;
}


/*	Check the fill indexes in the run-length encoded fillList */

	/* BalloonEnginePlugin>>#checkCompressedFillIndexList:max:segments: */
static sqInt
checkCompressedFillIndexListmaxsegments(sqInt fillList, sqInt maxIndex, sqInt nSegs)
{
    int *fillPtr;
    sqInt i;
    sqInt length;
    sqInt nFills;
    sqInt runLength;
    sqInt runValue;

	length = slotSizeOf(fillList);
	fillPtr = firstIndexableField(fillList);
	nFills = 0;
	for (i = 0; i < length; i += 1) {
		runLength = ((usqInt) ((((int *) fillPtr))[i]) >> 16);
		runValue = ((((int *) fillPtr))[i]) & 0xFFFF;
		if (!((runValue >= 0)
			 && (runValue <= maxIndex))) {
			return 0;
		}
		nFills += runLength;
	}
	return nFills == nSegs;
}


/*	Check if the indexList (containing fill handles) is okay. */

	/* BalloonEnginePlugin>>#checkCompressedFills: */
static sqInt
checkCompressedFills(sqInt indexList)
{
    int fillIndex;
    int *fillPtr;
    sqInt i;
    sqInt length;


	/* First check if the oops have the right format */
	if (!(isWords(indexList))) {
		return 0;
	}
	length = slotSizeOf(indexList);
	fillPtr = firstIndexableField(indexList);
	for (i = 0; i < length; i += 1) {

		/* Make sure the fill is okay */
		fillIndex = fillPtr[i];
		if (!(isFillOkay(fillIndex))) {
			return 0;
		}
	}
	return 1;
}


/*	Check the run-length encoded lineWidthList matches nSegments */

	/* BalloonEnginePlugin>>#checkCompressedLineWidths:segments: */
static sqInt
checkCompressedLineWidthssegments(sqInt lineWidthList, sqInt nSegments)
{
    sqInt i;
    sqInt length;
    sqInt nItems;
    int *ptr;
    sqInt runLength;

	length = slotSizeOf(lineWidthList);
	ptr = firstIndexableField(lineWidthList);
	nItems = 0;
	for (i = 0; i < length; i += 1) {
		runLength = ((usqInt) ((((int *) ptr))[i]) >> 16);
		nItems += runLength;
	}
	return nItems == nSegments;
}


/*	Check if the given point array can be handled by the engine. */

	/* BalloonEnginePlugin>>#checkCompressedPoints:segments: */
static sqInt
checkCompressedPointssegments(sqInt points, sqInt nSegments)
{
    sqInt pSize;

	if (!(isWords(points))) {
		return 0;
	}

	/* The points must be either in PointArray format or ShortPointArray format.
	   Also, we currently handle only quadratic segments (e.g., 3 points each) and thus either
	   pSize = nSegments * 3,		for ShortPointArrays or,
	   pSize = nSegments * 6,		for PointArrays */
	pSize = slotSizeOf(points);
	if (!((pSize == (nSegments * 3))
		 || (pSize == (nSegments * 6)))) {
		return 0;
	}
	return 1;
}


/*	Check if the given shape can be handled by the engine. 
	Since there are a number of requirements this is an extra method. */

	/* BalloonEnginePlugin>>#checkCompressedShape:segments:leftFills:rightFills:lineWidths:lineFills:fillIndexList: */
static sqInt
checkCompressedShapesegmentsleftFillsrightFillslineWidthslineFillsfillIndexList(sqInt points, sqInt nSegments, sqInt leftFills, sqInt rightFills, sqInt lineWidths, sqInt lineFills, sqInt fillIndexList)
{
    sqInt maxFillIndex;

	if (!(checkCompressedPointssegments(points, nSegments))) {
		return 0;
	}
	if (!(checkCompressedFills(fillIndexList))) {
		return 0;
	}
	maxFillIndex = slotSizeOf(fillIndexList);
	if (!(checkCompressedFillIndexListmaxsegments(leftFills, maxFillIndex, nSegments))) {
		return 0;
	}
	if (!(checkCompressedFillIndexListmaxsegments(rightFills, maxFillIndex, nSegments))) {
		return 0;
	}
	if (!(checkCompressedFillIndexListmaxsegments(lineFills, maxFillIndex, nSegments))) {
		return 0;
	}
	if (!(checkCompressedLineWidthssegments(lineWidths, nSegments))) {
		return 0;
	}
	return 1;
}


/*	Add the bezier to the global edge table if it intersects the clipping
	region 
 */

	/* BalloonEnginePlugin>>#checkedAddBezierToGET: */
static sqInt
checkedAddBezierToGET(sqInt bezier)
{
    sqInt lineWidth;

	if ((((objBuffer[bezier + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveWide) != 0) {
		/* begin obj:at: */
		lineWidth = objBuffer[bezier + GBWideExtent];
	}
	else {
		lineWidth = 0;
	}
	if (((objBuffer[bezier + GBEndY]) + lineWidth) < (workBuffer[GWFillMinY])) {
		return 0;
	}
	if ((((objBuffer[bezier + GEXValue]) - lineWidth) >= (workBuffer[GWFillMaxX]))
	 && (((objBuffer[bezier + GBEndX]) - lineWidth) >= (workBuffer[GWFillMaxX]))) {
		return 0;
	}
	addEdgeToGET(bezier);
	return 0;
}


/*	Add the edge to the global edge table.
	For known edge types, check if the edge intersects the visible region */

	/* BalloonEnginePlugin>>#checkedAddEdgeToGET: */
static sqInt
checkedAddEdgeToGET(sqInt edge)
{
    sqInt lineWidth;
    sqInt lineWidth1;

	if ((((objBuffer[edge + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveWideMask) == GEPrimitiveLine) {
		/* begin checkedAddLineToGET: */
		if ((((objBuffer[edge + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveWide) != 0) {
			/* begin obj:at: */
			lineWidth1 = objBuffer[edge + GLWideExtent];
		}
		else {
			lineWidth1 = 0;
		}
		if (((objBuffer[edge + GLEndY]) + lineWidth1) < (workBuffer[GWFillMinY])) {
			return 0;
		}
		if ((((objBuffer[edge + GEXValue]) - lineWidth1) >= (workBuffer[GWFillMaxX]))
		 && (((objBuffer[edge + GLEndX]) - lineWidth1) >= (workBuffer[GWFillMaxX]))) {
			return 0;
		}
		addEdgeToGET(edge);
		return null;
	}
	if ((((objBuffer[edge + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveWideMask) == GEPrimitiveBezier) {
		/* begin checkedAddBezierToGET: */
		if ((((objBuffer[edge + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveWide) != 0) {
			/* begin obj:at: */
			lineWidth = objBuffer[edge + GBWideExtent];
		}
		else {
			lineWidth = 0;
		}
		if (((objBuffer[edge + GBEndY]) + lineWidth) < (workBuffer[GWFillMinY])) {
			return 0;
		}
		if ((((objBuffer[edge + GEXValue]) - lineWidth) >= (workBuffer[GWFillMaxX]))
		 && (((objBuffer[edge + GBEndX]) - lineWidth) >= (workBuffer[GWFillMaxX]))) {
			return 0;
		}
		addEdgeToGET(edge);
		return null;
	}
	addEdgeToGET(edge);
	return 0;
}


/*	Add the line to the global edge table if it intersects the clipping region */

	/* BalloonEnginePlugin>>#checkedAddLineToGET: */
static sqInt
checkedAddLineToGET(sqInt line)
{
    sqInt lineWidth;

	if ((((objBuffer[line + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveWide) != 0) {
		/* begin obj:at: */
		lineWidth = objBuffer[line + GLWideExtent];
	}
	else {
		lineWidth = 0;
	}
	if (((objBuffer[line + GLEndY]) + lineWidth) < (workBuffer[GWFillMinY])) {
		return 0;
	}
	if ((((objBuffer[line + GEXValue]) - lineWidth) >= (workBuffer[GWFillMaxX]))
	 && (((objBuffer[line + GLEndX]) - lineWidth) >= (workBuffer[GWFillMaxX]))) {
		return 0;
	}
	addEdgeToGET(line);
	return 0;
}

	/* BalloonEnginePlugin>>#circleCosTable */
static double *
circleCosTable(void)
{
    static double theTable[33] =
		{1.0, 0.98078528040323, 0.923879532511287, 0.831469612302545,
		0.7071067811865475, 0.555570233019602, 0.38268343236509, 0.1950903220161286,
		0.0, -0.1950903220161283, -0.3826834323650896, -0.555570233019602,
		-0.707106781186547, -0.831469612302545, -0.9238795325112865, -0.98078528040323,
		-1.0, -0.98078528040323, -0.923879532511287, -0.831469612302545,
		-0.707106781186548, -0.555570233019602, -0.3826834323650903, -0.1950903220161287,
		0.0, 0.1950903220161282, 0.38268343236509, 0.555570233019602,
		0.707106781186547, 0.831469612302545, 0.9238795325112865, 0.98078528040323,
		1.0 };

	return theTable;
}

	/* BalloonEnginePlugin>>#circleSinTable */
static double *
circleSinTable(void)
{
    static double theTable[33] =
		{0.0, 0.1950903220161282, 0.3826834323650897, 0.555570233019602,
		0.707106781186547, 0.831469612302545, 0.923879532511287, 0.98078528040323,
		1.0, 0.98078528040323, 0.923879532511287, 0.831469612302545,
		0.7071067811865475, 0.555570233019602, 0.38268343236509, 0.1950903220161286,
		0.0, -0.1950903220161283, -0.3826834323650896, -0.555570233019602,
		-0.707106781186547, -0.831469612302545, -0.9238795325112865, -0.98078528040323,
		-1.0, -0.98078528040323, -0.923879532511287, -0.831469612302545,
		-0.707106781186548, -0.555570233019602, -0.3826834323650903, -0.1950903220161287,
		 0.0 };

	return theTable;
}

	/* BalloonEnginePlugin>>#clampValue:max: */
static sqInt
clampValuemax(sqInt value, sqInt maxValue)
{
	if (value < 0) {
		return 0;
	}
	else {
		if (value >= maxValue) {
			return maxValue - 1;
		}
		else {
			return value;
		}
	}
}


/*	Clear the current span buffer.
	The span buffer is only cleared in the area that has been used by the
	previous scan line.
 */

	/* BalloonEngineBase>>#clearSpanBuffer */
static sqInt
clearSpanBuffer(void)
{
    sqInt x0;
    sqInt x1;

	x0 = ((usqInt) (workBuffer[GWSpanStart])) >> (workBuffer[GWAAShift]);
	x1 = (((usqInt) (workBuffer[GWSpanEnd])) >> (workBuffer[GWAAShift])) + 1;
	if (x0 < 0) {
		x0 = 0;
	}
	if (x1 > (workBuffer[GWSpanSize])) {
		x1 = workBuffer[GWSpanSize];
	}
	while (x0 < x1) {
		spanBuffer[x0] = 0;
		x0 += 1;
	}
	/* begin spanStartPut: */
	workBuffer[GWSpanStart] = (workBuffer[GWSpanSize]);
	workBuffer[GWSpanEnd] = 0;
	return 0;
}

	/* BalloonEngineBase>>#clearSpanBufferGet */
static sqInt
clearSpanBufferGet(void)
{
	return workBuffer[GWClearSpanBuffer];
}

	/* BalloonEngineBase>>#clearSpanBufferPut: */
static sqInt
clearSpanBufferPut(sqInt value)
{
	return workBuffer[GWClearSpanBuffer] = value;
}

	/* BalloonEngineBase>>#clipMaxXGet */
static sqInt
clipMaxXGet(void)
{
	return workBuffer[GWClipMaxX];
}

	/* BalloonEngineBase>>#clipMaxXPut: */
static sqInt
clipMaxXPut(sqInt value)
{
	return workBuffer[GWClipMaxX] = value;
}

	/* BalloonEngineBase>>#clipMaxYGet */
static sqInt
clipMaxYGet(void)
{
	return workBuffer[GWClipMaxY];
}

	/* BalloonEngineBase>>#clipMaxYPut: */
static sqInt
clipMaxYPut(sqInt value)
{
	return workBuffer[GWClipMaxY] = value;
}

	/* BalloonEngineBase>>#clipMinXGet */
static sqInt
clipMinXGet(void)
{
	return workBuffer[GWClipMinX];
}

	/* BalloonEngineBase>>#clipMinXPut: */
static sqInt
clipMinXPut(sqInt value)
{
	return workBuffer[GWClipMinX] = value;
}

	/* BalloonEngineBase>>#clipMinYGet */
static sqInt
clipMinYGet(void)
{
	return workBuffer[GWClipMinY];
}

	/* BalloonEngineBase>>#clipMinYPut: */
static sqInt
clipMinYPut(sqInt value)
{
	return workBuffer[GWClipMinY] = value;
}

	/* BalloonEnginePlugin>>#colormapOf: */
static int *
colormapOf(sqInt bmFill)
{
	return (objBuffer + bmFill) + GBColormapOffset;
}

	/* BalloonEngineBase>>#colorTransform */
static float *
colorTransform(void)
{
	return ((float *) (workBuffer + GWColorTransform));
}


/*	Split the bezier curve at 0.5. */

	/* BalloonEnginePlugin>>#computeBezierSplitAtHalf: */
static sqInt
computeBezierSplitAtHalf(sqInt index)
{
    sqInt endX;
    sqInt endY;
    sqInt index1;
    sqInt index10;
    sqInt index11;
    sqInt index12;
    sqInt index2;
    sqInt index3;
    sqInt index4;
    sqInt index5;
    sqInt index6;
    sqInt index7;
    sqInt index8;
    sqInt index9;
    sqInt leftViaX;
    sqInt leftViaY;
    sqInt newIndex;
    sqInt rightViaX;
    sqInt rightViaY;
    sqInt sharedX;
    sqInt sharedY;
    sqInt startX;
    sqInt startY;
    sqInt viaX;
    sqInt viaY;

	/* begin allocateBezierStackEntry */
	if (!(needAvailableSpace(6))) {
		goto l14;
	}
	/* begin wbTopPut: */
	workBuffer[GWBufferTop] = ((workBuffer[GWBufferTop]) - 6);
	l14:	/* end wbStackPush: */;
	newIndex = (workBuffer[GWSize]) - (workBuffer[GWBufferTop]);
	if (engineStopped) {
		return 0;
	}
	leftViaX = (startX = workBuffer[(workBuffer[GWBufferTop]) + ((((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index))]);
	leftViaY = (startY = workBuffer[(workBuffer[GWBufferTop]) + ((((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 1)]);
	rightViaX = (viaX = workBuffer[(workBuffer[GWBufferTop]) + ((((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 2)]);
	rightViaY = (viaY = workBuffer[(workBuffer[GWBufferTop]) + ((((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 3)]);
	/* begin wbStackValue: */
	index1 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 4;
	endX = workBuffer[(workBuffer[GWBufferTop]) + index1];
	/* begin wbStackValue: */
	index2 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 5;
	endY = workBuffer[(workBuffer[GWBufferTop]) + index2];
	leftViaX += (viaX - startX) / 2;
	leftViaY += (viaY - startY) / 2;
	sharedX = (rightViaX += (endX - viaX) / 2);

	/* Compute new shared point */
	sharedY = (rightViaY += (endY - viaY) / 2);
	sharedX += (leftViaX - rightViaX) / 2;

	/* Store the first part back */
	sharedY += (leftViaY - rightViaY) / 2;
	/* begin wbStackValue:put: */
	index3 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 2;
	workBuffer[(workBuffer[GWBufferTop]) + index3] = leftViaX;
	/* begin wbStackValue:put: */
	index4 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 3;
	workBuffer[(workBuffer[GWBufferTop]) + index4] = leftViaY;
	/* begin wbStackValue:put: */
	index5 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 4;
	workBuffer[(workBuffer[GWBufferTop]) + index5] = sharedX;
	/* begin wbStackValue:put: */
	index6 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 5;
	workBuffer[(workBuffer[GWBufferTop]) + index6] = sharedY;
	/* begin wbStackValue:put: */
	index7 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - newIndex);
	workBuffer[(workBuffer[GWBufferTop]) + index7] = sharedX;
	/* begin wbStackValue:put: */
	index8 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - newIndex) + 1;
	workBuffer[(workBuffer[GWBufferTop]) + index8] = sharedY;
	/* begin wbStackValue:put: */
	index9 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - newIndex) + 2;
	workBuffer[(workBuffer[GWBufferTop]) + index9] = rightViaX;
	/* begin wbStackValue:put: */
	index10 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - newIndex) + 3;
	workBuffer[(workBuffer[GWBufferTop]) + index10] = rightViaY;
	/* begin wbStackValue:put: */
	index11 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - newIndex) + 4;
	workBuffer[(workBuffer[GWBufferTop]) + index11] = endX;
	/* begin wbStackValue:put: */
	index12 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - newIndex) + 5;
	workBuffer[(workBuffer[GWBufferTop]) + index12] = endY;
	return newIndex;
}


/*	Split the bezier curve at the given parametric value.
	Note: Since this method is only invoked to make non-monoton
	beziers monoton we must check for the resulting y values
	to be *really* between the start and end value. */

	/* BalloonEnginePlugin>>#computeBezier:splitAt: */
static sqInt
computeBeziersplitAt(sqInt index, double param)
{
    sqInt endX;
    sqInt endY;
    sqInt index1;
    sqInt index10;
    sqInt index11;
    sqInt index12;
    sqInt index2;
    sqInt index3;
    sqInt index4;
    sqInt index5;
    sqInt index6;
    sqInt index7;
    sqInt index8;
    sqInt index9;
    sqInt leftViaX;
    sqInt leftViaY;
    sqInt newIndex;
    sqInt rightViaX;
    sqInt rightViaY;
    sqInt sharedX;
    sqInt sharedY;
    sqInt startX;
    sqInt startY;
    sqInt viaX;
    sqInt viaY;

	leftViaX = (startX = workBuffer[(workBuffer[GWBufferTop]) + ((((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index))]);
	leftViaY = (startY = workBuffer[(workBuffer[GWBufferTop]) + ((((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 1)]);
	rightViaX = (viaX = workBuffer[(workBuffer[GWBufferTop]) + ((((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 2)]);
	rightViaY = (viaY = workBuffer[(workBuffer[GWBufferTop]) + ((((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 3)]);
	/* begin wbStackValue: */
	index1 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 4;
	endX = workBuffer[(workBuffer[GWBufferTop]) + index1];
	/* begin wbStackValue: */
	index2 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 5;
	endY = workBuffer[(workBuffer[GWBufferTop]) + index2];
	sharedX = (leftViaX += ((sqInt)((((double) (viaX - startX) )) * param)));
	sharedY = (leftViaY += ((sqInt)((((double) (viaY - startY) )) * param)));
	rightViaX += ((sqInt)((((double) (endX - viaX) )) * param));

	/* Compute new shared point */
	rightViaY += ((sqInt)((((double) (endY - viaY) )) * param));
	sharedX += ((sqInt)((((double) (rightViaX - leftViaX) )) * param));

	/* Check the new via points */
	sharedY += ((sqInt)((((double) (rightViaY - leftViaY) )) * param));
	/* begin assureValue:between:and: */
	if (startY > sharedY) {
		if (leftViaY > startY) {
			leftViaY = startY;
			goto l1;
		}
		if (leftViaY < sharedY) {
			leftViaY = sharedY;
			goto l1;
		}
	}
	else {
		if (leftViaY < startY) {
			leftViaY = startY;
			goto l1;
		}
		if (leftViaY > sharedY) {
			leftViaY = sharedY;
			goto l1;
		}
	}
	l1:	/* end assureValue:between:and: */;
	/* begin assureValue:between:and: */
	if (sharedY > endY) {
		if (rightViaY > sharedY) {
			rightViaY = sharedY;
			goto l2;
		}
		if (rightViaY < endY) {
			rightViaY = endY;
			goto l2;
		}
	}
	else {
		if (rightViaY < sharedY) {
			rightViaY = sharedY;
			goto l2;
		}
		if (rightViaY > endY) {
			rightViaY = endY;
			goto l2;
		}
	}
	l2:	/* end assureValue:between:and: */;
	/* begin allocateBezierStackEntry */
	if (!(needAvailableSpace(6))) {
		goto l16;
	}
	/* begin wbTopPut: */
	workBuffer[GWBufferTop] = ((workBuffer[GWBufferTop]) - 6);
	l16:	/* end wbStackPush: */;
	newIndex = (workBuffer[GWSize]) - (workBuffer[GWBufferTop]);
	if (engineStopped) {
		return 0;
	}
	/* begin wbStackValue:put: */
	index3 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 2;
	workBuffer[(workBuffer[GWBufferTop]) + index3] = leftViaX;
	/* begin wbStackValue:put: */
	index4 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 3;
	workBuffer[(workBuffer[GWBufferTop]) + index4] = leftViaY;
	/* begin wbStackValue:put: */
	index5 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 4;
	workBuffer[(workBuffer[GWBufferTop]) + index5] = sharedX;
	/* begin wbStackValue:put: */
	index6 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 5;
	workBuffer[(workBuffer[GWBufferTop]) + index6] = sharedY;
	/* begin wbStackValue:put: */
	index7 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - newIndex);
	workBuffer[(workBuffer[GWBufferTop]) + index7] = sharedX;
	/* begin wbStackValue:put: */
	index8 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - newIndex) + 1;
	workBuffer[(workBuffer[GWBufferTop]) + index8] = sharedY;
	/* begin wbStackValue:put: */
	index9 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - newIndex) + 2;
	workBuffer[(workBuffer[GWBufferTop]) + index9] = rightViaX;
	/* begin wbStackValue:put: */
	index10 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - newIndex) + 3;
	workBuffer[(workBuffer[GWBufferTop]) + index10] = rightViaY;
	/* begin wbStackValue:put: */
	index11 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - newIndex) + 4;
	workBuffer[(workBuffer[GWBufferTop]) + index11] = endX;
	/* begin wbStackValue:put: */
	index12 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - newIndex) + 5;
	workBuffer[(workBuffer[GWBufferTop]) + index12] = endY;
	return newIndex;
}


/*	Get both values from the two boundaries of the given bezier 
	and compute the actual position/width of the line */

	/* BalloonEnginePlugin>>#computeFinalWideBezierValues:width: */
static sqInt
computeFinalWideBezierValueswidth(sqInt bezier, sqInt lineWidth)
{
    int leftX;
    int rightX;
    int temp;

	leftX = (((objBuffer + bezier) + GBUpdateData)[GBUpdateX]) / 256;
	rightX = (((objBuffer + bezier) + GBWideUpdateData)[GBUpdateX]) / 256;
	if (leftX > rightX) {
		temp = leftX;
		leftX = rightX;
		rightX = temp;
	}
	/* begin obj:at:put: */
	objBuffer[bezier + GEXValue] = leftX;
	if ((rightX - leftX) > lineWidth) {
		/* begin obj:at:put: */
		objBuffer[bezier + GBWideWidth] = (rightX - leftX);
	}
	else {
		/* begin obj:at:put: */
		objBuffer[bezier + GBWideWidth] = lineWidth;
	}
	return 0;
}

	/* BalloonEngineBase>>#computeSqrt: */
static sqInt
computeSqrt(sqInt length2)
{
	if (length2 < 32) {
		return (smallSqrtTable())[length2];
	}
	else {
		return ((sqInt)((sqrt(((double) length2 ))) + 0.5));
	}
}

	/* BalloonEngineBase>>#copyBitsFrom:to:at: */
static sqInt
copyBitsFromtoat(sqInt x0, sqInt x1, sqInt yValue)
{
	if (copyBitsFn == 0) {

		/* We need copyBits here so try to load it implicitly */
		if (!(initialiseModule())) {
			return 0;
		}
	}
	return ((sqInt (*)(sqInt, sqInt, sqInt))copyBitsFn)(x0, x1, yValue);
}


/*	Create the global edge table */

	/* BalloonEngineBase>>#createGlobalEdgeTable */
static sqInt
createGlobalEdgeTable(void)
{
    sqInt end;
    sqInt lineWidth;
    sqInt lineWidth1;
    sqInt object;

	object = 0;
	end = objUsed;
	while (object < end) {

		/* Note: addEdgeToGET: may fail on insufficient space but that's not a problem here */
		if (isEdge(object)) {

			/* Check if the edge starts below fillMaxY. */
			if (!((objBuffer[object + GEYValue]) >= (workBuffer[GWFillMaxY]))) {
				/* begin checkedAddEdgeToGET: */
				if ((((objBuffer[object + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveWideMask) == GEPrimitiveLine) {
					/* begin checkedAddLineToGET: */
					if ((((objBuffer[object + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveWide) != 0) {
						/* begin obj:at: */
						lineWidth1 = objBuffer[object + GLWideExtent];
					}
					else {
						lineWidth1 = 0;
					}
					if (((objBuffer[object + GLEndY]) + lineWidth1) < (workBuffer[GWFillMinY])) {
						goto l3;
					}
					if ((((objBuffer[object + GEXValue]) - lineWidth1) >= (workBuffer[GWFillMaxX]))
					 && (((objBuffer[object + GLEndX]) - lineWidth1) >= (workBuffer[GWFillMaxX]))) {
						goto l3;
					}
					addEdgeToGET(object);
					goto l3;
				}
				if ((((objBuffer[object + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveWideMask) == GEPrimitiveBezier) {
					/* begin checkedAddBezierToGET: */
					if ((((objBuffer[object + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveWide) != 0) {
						/* begin obj:at: */
						lineWidth = objBuffer[object + GBWideExtent];
					}
					else {
						lineWidth = 0;
					}
					if (((objBuffer[object + GBEndY]) + lineWidth) < (workBuffer[GWFillMinY])) {
						goto l3;
					}
					if ((((objBuffer[object + GEXValue]) - lineWidth) >= (workBuffer[GWFillMaxX]))
					 && (((objBuffer[object + GBEndX]) - lineWidth) >= (workBuffer[GWFillMaxX]))) {
						goto l3;
					}
					addEdgeToGET(object);
					goto l3;
				}
				addEdgeToGET(object);
	l3:	/* end checkedAddEdgeToGET: */;
			}
		}
		object += objBuffer[object + GEObjectLength];
	}
	return 0;
}

	/* BalloonEngineBase>>#currentYGet */
static sqInt
currentYGet(void)
{
	return workBuffer[GWCurrentY];
}

	/* BalloonEngineBase>>#currentYPut: */
static sqInt
currentYPut(sqInt value)
{
	return workBuffer[GWCurrentY] = value;
}

	/* BalloonEngineBase>>#currentZGet */
static sqInt
currentZGet(void)
{
	return workBuffer[GWCurrentZ];
}

	/* BalloonEngineBase>>#currentZPut: */
static sqInt
currentZPut(sqInt value)
{
	return workBuffer[GWCurrentZ] = value;
}

	/* BalloonEngineBase>>#destOffsetXGet */
static sqInt
destOffsetXGet(void)
{
	return workBuffer[GWDestOffsetX];
}

	/* BalloonEngineBase>>#destOffsetXPut: */
static sqInt
destOffsetXPut(sqInt value)
{
	return workBuffer[GWDestOffsetX] = value;
}

	/* BalloonEngineBase>>#destOffsetYGet */
static sqInt
destOffsetYGet(void)
{
	return workBuffer[GWDestOffsetY];
}

	/* BalloonEngineBase>>#destOffsetYPut: */
static sqInt
destOffsetYPut(sqInt value)
{
	return workBuffer[GWDestOffsetY] = value;
}


/*	Display the span buffer at the current scan line. */

	/* BalloonEngineBase>>#displaySpanBufferAt: */
static sqInt
displaySpanBufferAt(sqInt y)
{
    sqInt targetX0;
    sqInt targetX1;
    sqInt targetY;


	/* self aaLevelGet > 1 ifTrue:[self adjustAALevel]. */
	targetX0 = ((usqInt) (workBuffer[GWSpanStart])) >> (workBuffer[GWAAShift]);
	if (targetX0 < (workBuffer[GWClipMinX])) {
		/* begin clipMinXGet */
		targetX0 = workBuffer[GWClipMinX];
	}
	targetX1 = ((usqInt) (((workBuffer[GWSpanEnd]) + (workBuffer[GWAALevel])) - 1)) >> (workBuffer[GWAAShift]);
	if (targetX1 > (workBuffer[GWClipMaxX])) {
		/* begin clipMaxXGet */
		targetX1 = workBuffer[GWClipMaxX];
	}
	targetY = ((usqInt) y) >> (workBuffer[GWAAShift]);
	if ((targetY < (workBuffer[GWClipMinY]))
	 || ((targetY >= (workBuffer[GWClipMaxY]))
	 || ((targetX1 < (workBuffer[GWClipMinX]))
	 || (targetX0 >= (workBuffer[GWClipMaxX]))))) {
		return 0;
	}
	copyBitsFromtoat(targetX0, targetX1, targetY);
	return 0;
}


/*	Draw the given edge starting from leftX with the edge's fill.
	Return the end value of the drawing operation. */

	/* BalloonEngineBase>>#drawWideEdge:from: */
static sqInt
drawWideEdgefrom(sqInt edge, sqInt leftX)
{
    sqInt fill;
    sqInt lineWidth;
    sqInt rightX;
    sqInt type;


	/* Not for the moment */
	type = ((usqInt) ((objBuffer[edge + GEObjectType]) & GEPrimitiveTypeMask)) >> 1;
	dispatchedValue = edge;
	switch (type) {
	case 0:
	case 1:
		errorWrongIndex();
		break;
	case 2:
		dispatchReturnValue = wideLineWidthOf(dispatchedValue);
		break;
	case 3:
		dispatchReturnValue = wideBezierWidthOf(dispatchedValue);
		break;
	}
	lineWidth = dispatchReturnValue;
	switch (type) {
	case 0:
	case 1:
		errorWrongIndex();
		break;
	case 2:
		dispatchReturnValue = wideLineFillOf(dispatchedValue);
		break;
	case 3:
		dispatchReturnValue = wideBezierFillOf(dispatchedValue);
		break;
	}
	fill = dispatchReturnValue;
	if (fill == 0) {
		return leftX;
	}
	rightX = leftX + lineWidth;
	fillSpanfromto(fill, leftX, rightX);
	return rightX;
}

	/* BalloonEngineBase>>#edgeFillsInvalidate: */
static sqInt
edgeFillsInvalidate(sqInt edge)
{
    sqInt value;

	/* begin objectTypeOf:put: */
	value = ((objBuffer[edge + GEObjectType]) & GEPrimitiveTypeMask) | GEEdgeFillsInvalid;
	return objBuffer[edge + GEObjectType] = value;
}

	/* BalloonEngineBase>>#edgeFillsValidate: */
static sqInt
edgeFillsValidate(sqInt edge)
{
    sqInt value;

	/* begin objectTypeOf:put: */
	value = ((objBuffer[edge + GEObjectType]) & GEPrimitiveTypeMask) & ((unsigned int)~GEEdgeFillsInvalid);
	return objBuffer[edge + GEObjectType] = value;
}

	/* BalloonEngineBase>>#edgeLeftFillOf: */
static sqInt
edgeLeftFillOf(sqInt edge)
{
	return objBuffer[edge + GEFillIndexLeft];
}

	/* BalloonEngineBase>>#edgeLeftFillOf:put: */
static sqInt
edgeLeftFillOfput(sqInt edge, sqInt value)
{
	return objBuffer[edge + GEFillIndexLeft] = value;
}

	/* BalloonEngineBase>>#edgeNumLinesOf: */
static sqInt
edgeNumLinesOf(sqInt edge)
{
	return objBuffer[edge + GENumLines];
}

	/* BalloonEngineBase>>#edgeNumLinesOf:put: */
static sqInt
edgeNumLinesOfput(sqInt edge, sqInt value)
{
	return objBuffer[edge + GENumLines] = value;
}

	/* BalloonEngineBase>>#edgeRightFillOf: */
static sqInt
edgeRightFillOf(sqInt edge)
{
	return objBuffer[edge + GEFillIndexRight];
}

	/* BalloonEngineBase>>#edgeRightFillOf:put: */
static sqInt
edgeRightFillOfput(sqInt edge, sqInt value)
{
	return objBuffer[edge + GEFillIndexRight] = value;
}

	/* BalloonEngineBase>>#edgeTransform */
static float *
edgeTransform(void)
{
	return ((float *) (workBuffer + GWEdgeTransform));
}


/*	Return the edge type (e.g., witout the wide edge flag) */

	/* BalloonEngineBase>>#edgeTypeOf: */
static sqInt
edgeTypeOf(sqInt edge)
{
	return ((usqInt) ((objBuffer[edge + GEObjectType]) & GEPrimitiveTypeMask)) >> 1;
}

	/* BalloonEngineBase>>#edgeXValueOf: */
static sqInt
edgeXValueOf(sqInt edge)
{
	return objBuffer[edge + GEXValue];
}

	/* BalloonEngineBase>>#edgeXValueOf:put: */
static sqInt
edgeXValueOfput(sqInt edge, sqInt value)
{
	return objBuffer[edge + GEXValue] = value;
}

	/* BalloonEngineBase>>#edgeYValueOf: */
static sqInt
edgeYValueOf(sqInt edge)
{
	return objBuffer[edge + GEYValue];
}

	/* BalloonEngineBase>>#edgeYValueOf:put: */
static sqInt
edgeYValueOfput(sqInt edge, sqInt value)
{
	return objBuffer[edge + GEYValue] = value;
}

	/* BalloonEngineBase>>#edgeZValueOf: */
static sqInt
edgeZValueOf(sqInt edge)
{
	return objBuffer[edge + GEZValue];
}

	/* BalloonEngineBase>>#edgeZValueOf:put: */
static sqInt
edgeZValueOfput(sqInt edge, sqInt value)
{
	return objBuffer[edge + GEZValue] = value;
}


/*	Ignore dispatch errors when translating to C
	(since we have no entry point for #error in the VM proxy) */

	/* BalloonEngineBase>>#errorWrongIndex */
static sqInt
errorWrongIndex(void)
{
	return 0;
}


/*	Estimate the length of the vector described by deltaX and deltaY.
	This method may be extremely inaccurate - use it only
	if you know exactly that this doesn't matter. Otherwise
	use #accurateLengthOf:width: */

	/* BalloonEngineBase>>#estimatedLengthOf:with: */
static sqInt
estimatedLengthOfwith(sqInt deltaX, sqInt deltaY)
{
    sqInt absDx;
    sqInt absDy;

	if (deltaX >= 0) {
		absDx = deltaX;
	}
	else {
		absDx = 0 - deltaX;
	}
	if (deltaY >= 0) {
		absDy = deltaY;
	}
	else {
		absDy = 0 - deltaY;
	}
	if (absDx > absDy) {
		return absDx + (absDy / 2);
	}
	else {
		return absDy + (absDx / 2);
	}
}


/*	Fill the span buffer from leftX to rightX with the given fill. */

	/* BalloonEngineBase>>#fillAllFrom:to: */
static sqInt
fillAllFromto(sqInt leftX, sqInt rightX)
{
    sqInt fill;
    sqInt index;
    sqInt index1;
    sqInt index2;
    sqInt index3;
    sqInt index4;
    sqInt someIntegerValue;
    sqInt someIntegerValue1;
    sqInt startX;
    sqInt stopX;

	/* begin topFill */
	if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
		fill = 0;
		goto l5;
	}
	else {
		/* begin stackFillValue: */
		index2 = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
		fill = workBuffer[(workBuffer[GWBufferTop]) + index2];
		goto l5;
	}
	l5:	/* end topFill */;
	startX = leftX;
	/* begin topRightX */
	if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
		stopX = 999999999;
		goto l6;
	}
	else {
		/* begin stackFillRightX: */
		index3 = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
		stopX = workBuffer[(workBuffer[GWBufferTop]) + (index3 + 2)];
		goto l6;
	}
	l6:	/* end topRightX */;
	while (stopX < rightX) {
		/* begin makeUnsignedFrom: */
		if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
			someIntegerValue = 0;
			goto l3;
		}
		else {
			/* begin stackFillValue: */
			index = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
			someIntegerValue = workBuffer[(workBuffer[GWBufferTop]) + index];
			goto l3;
		}
	l3:	/* end topFill */;
		fill = someIntegerValue;
		if (!(fill == 0)) {
			if (fillSpanfromto(fill, startX, stopX)) {
				return 1;
			}
		}
		/* begin quickRemoveInvalidFillsAt: */
		if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
			goto l8;
		}
		while ((topRightX()) <= stopX) {
			hideFilldepth(topFill(), topDepth());
			if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
				goto l8;
			}
		}
	l8:	/* end quickRemoveInvalidFillsAt: */;
		startX = stopX;
		/* begin topRightX */
		if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
			stopX = 999999999;
			goto l4;
		}
		else {
			/* begin stackFillRightX: */
			index1 = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
			stopX = workBuffer[(workBuffer[GWBufferTop]) + (index1 + 2)];
			goto l4;
		}
	l4:	/* end topRightX */;
	}
	/* begin makeUnsignedFrom: */
	if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
		someIntegerValue1 = 0;
		goto l7;
	}
	else {
		/* begin stackFillValue: */
		index4 = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
		someIntegerValue1 = workBuffer[(workBuffer[GWBufferTop]) + index4];
		goto l7;
	}
	l7:	/* end topFill */;
	fill = someIntegerValue1;
	if (!(fill == 0)) {
		return fillSpanfromto(fill, startX, rightX);
	}
	return 0;
}

	/* BalloonEnginePlugin>>#fillBitmapSpan */
static sqInt
fillBitmapSpan(void)
{
	return fillBitmapSpanfromtoat(workBuffer[GWLastExportedFill], workBuffer[GWLastExportedLeftX], workBuffer[GWLastExportedRightX], workBuffer[GWCurrentY]);
}

	/* BalloonEnginePlugin>>#fillBitmapSpanAA:from:to:at: */
static sqInt
fillBitmapSpanAAfromtoat(sqInt bmFill, sqInt leftX, sqInt rightX, sqInt yValue)
{
    sqInt a;
    sqInt a1;
    sqInt a2;
    sqInt aaLevel;
    sqInt b;
    sqInt b1;
    sqInt b2;
    sqInt baseShift;
    int *bits;
    sqInt bmDepth;
    sqInt bmDepth1;
    sqInt bmDepth2;
    sqInt bmHeight;
    sqInt bmRaster;
    sqInt bmRaster1;
    sqInt bmRaster2;
    sqInt bmWidth;
    sqInt cMask;
    int cMask1;
    int cMask2;
    int cMask3;
    sqInt cShift;
    sqInt deltaX;
    sqInt deltaY;
    sqInt ds;
    sqInt dsX;
    sqInt dt;
    sqInt dtX;
    sqInt fillValue;
    sqInt firstPixel;
    sqInt firstPixel1;
    sqInt g;
    sqInt g1;
    sqInt g2;
    sqInt idx;
    sqInt lastPixel;
    sqInt newDelta;
    sqInt newDelta1;
    sqInt newDelta2;
    sqInt newDelta3;
    sqInt newDelta4;
    sqInt newDelta5;
    sqInt r;
    sqInt r1;
    sqInt r2;
    int rShift;
    int rShift1;
    int rShift2;
    int tileFlag;
    int value;
    int value1;
    int value2;
    sqInt x;
    sqInt xp;
    sqInt yp;

	bits = loadBitsFrom(bmFill);
	if (bits == null) {
		return null;
	}
	/* begin bitmapWidthOf: */
	bmWidth = objBuffer[bmFill + GBBitmapWidth];
	/* begin bitmapHeightOf: */
	bmHeight = objBuffer[bmFill + GBBitmapHeight];
	tileFlag = (objBuffer[bmFill + GBTileFlag]) == 1;
	deltaX = leftX - (objBuffer[bmFill + GFOriginX]);
	deltaY = yValue - (objBuffer[bmFill + GFOriginY]);
	/* begin obj:at: */
	dsX = objBuffer[bmFill + GFDirectionX];
	/* begin obj:at: */
	dtX = objBuffer[bmFill + GFNormalX];
	ds = (deltaX * dsX) + (deltaY * (objBuffer[bmFill + GFDirectionY]));
	dt = (deltaX * dtX) + (deltaY * (objBuffer[bmFill + GFNormalY]));
	/* begin aaLevelGet */
	aaLevel = workBuffer[GWAALevel];
	/* begin aaFirstPixelFrom:to: */
	firstPixel1 = ((leftX + (workBuffer[GWAALevel])) - 1) & ((unsigned int)~((workBuffer[GWAALevel]) - 1));
	if (firstPixel1 > rightX) {
		firstPixel = rightX;
		goto l10;
	}
	else {
		firstPixel = firstPixel1;
		goto l10;
	}
	l10:	/* end aaFirstPixelFrom:to: */;
	/* begin aaLastPixelFrom:to: */
	lastPixel = (rightX - 1) & ((unsigned int)~((workBuffer[GWAALevel]) - 1));
	/* begin aaShiftGet */
	baseShift = workBuffer[GWAAShift];
	/* begin aaColorMaskGet */
	cMask = workBuffer[GWAAColorMask];
	/* begin aaColorShiftGet */
	cShift = workBuffer[GWAAColorShift];
	x = leftX;
	while (x < firstPixel) {
		if (tileFlag) {
			/* begin repeatValue:max: */
			newDelta = ds;
			while (newDelta < 0) {
				newDelta += ((sqInt)((usqInt)(bmWidth) << 16));
			}
			while (newDelta >= (((sqInt)((usqInt)(bmWidth) << 16)))) {
				newDelta -= ((sqInt)((usqInt)(bmWidth) << 16));
			}
			ds = newDelta;
			/* begin repeatValue:max: */
			newDelta1 = dt;
			while (newDelta1 < 0) {
				newDelta1 += ((sqInt)((usqInt)(bmHeight) << 16));
			}
			while (newDelta1 >= (((sqInt)((usqInt)(bmHeight) << 16)))) {
				newDelta1 -= ((sqInt)((usqInt)(bmHeight) << 16));
			}
			dt = newDelta1;
		}
		xp = ds / 65536;
		yp = dt / 65536;
		if (!tileFlag) {
			/* begin clampValue:max: */
			if (xp < 0) {
				xp = 0;
				goto l1;
			}
			else {
				if (xp >= bmWidth) {
					xp = bmWidth - 1;
					goto l1;
				}
			}
	l1:	/* end clampValue:max: */;
			/* begin clampValue:max: */
			if (yp < 0) {
				yp = 0;
				goto l2;
			}
			else {
				if (yp >= bmHeight) {
					yp = bmHeight - 1;
					goto l2;
				}
			}
	l2:	/* end clampValue:max: */;
		}
		if ((xp >= 0)
		 && ((yp >= 0)
		 && ((xp < bmWidth)
		 && (yp < bmHeight)))) {
			/* begin bitmapValue:bits:atX:y: */
			bmDepth = objBuffer[bmFill + GBBitmapDepth];
			/* begin bitmapRasterOf: */
			bmRaster = objBuffer[bmFill + GBBitmapRaster];
			if (bmDepth == 32) {
				value = (((int*) bits))[(bmRaster * yp) + xp];
				if ((value != 0)
				 && ((value & 0xFF000000U) == 0)) {
					value = value | 0xFF000000U;
				}
				fillValue = uncheckedTransformColor(value);
				goto l23;
			}
			rShift = (rShiftTable())[bmDepth];

			/* cMask - mask out the pixel from the word */
			value = (((int*) bits))[(bmRaster * yp) + (((usqInt) xp) >> rShift)];

			/* rShift - shift value to move the pixel in the word to the lowest bit position */
			cMask1 = (1U << bmDepth) - 1;
			rShift = (32 - bmDepth) - ((xp & ((1U << rShift) - 1)) * bmDepth);
			value = (((usqInt) value) >> rShift) & cMask1;
			if (bmDepth == 16) {

				/* Must convert by expanding bits */
				if (!(value == 0)) {
					b = ((sqInt)((usqInt)((value & 0x1F)) << 3));
					b += ((usqInt) b) >> 5;
					g = ((sqInt)((usqInt)(((((usqInt) value) >> 5) & 0x1F)) << 3));
					g += ((usqInt) g) >> 5;
					r = ((sqInt)((usqInt)(((((usqInt) value) >> 10) & 0x1F)) << 3));
					r += ((usqInt) r) >> 5;
					a = 0xFF;
					value = ((b + (((sqInt)((usqInt)(g) << 8)))) + (((sqInt)((usqInt)(r) << 16)))) + (((sqInt)((usqInt)(a) << 24)));
				}
			}
			else {

				/* Must convert by using color map */
				if ((objBuffer[bmFill + GBColormapSize]) == 0) {
					value = 0;
				}
				else {
					/* begin makeUnsignedFrom: */
					value = ((objBuffer + bmFill) + GBColormapOffset)[value];
				}
			}
			fillValue = uncheckedTransformColor(value);
	l23:	/* end bitmapValue:bits:atX:y: */;
			fillValue = ((usqInt) (fillValue & cMask)) >> cShift;
			idx = ((usqInt) x) >> baseShift;
			spanBuffer[idx] = ((spanBuffer[idx]) + fillValue);
		}
		ds += dsX;
		dt += dtX;
		x += 1;
	}
	cMask = (((usqInt) (workBuffer[GWAAColorMask])) >> (workBuffer[GWAAShift])) | 4042322160U;
	/* begin aaShiftGet */
	cShift = workBuffer[GWAAShift];
	while (x < lastPixel) {
		if (tileFlag) {
			/* begin repeatValue:max: */
			newDelta2 = ds;
			while (newDelta2 < 0) {
				newDelta2 += ((sqInt)((usqInt)(bmWidth) << 16));
			}
			while (newDelta2 >= (((sqInt)((usqInt)(bmWidth) << 16)))) {
				newDelta2 -= ((sqInt)((usqInt)(bmWidth) << 16));
			}
			ds = newDelta2;
			/* begin repeatValue:max: */
			newDelta3 = dt;
			while (newDelta3 < 0) {
				newDelta3 += ((sqInt)((usqInt)(bmHeight) << 16));
			}
			while (newDelta3 >= (((sqInt)((usqInt)(bmHeight) << 16)))) {
				newDelta3 -= ((sqInt)((usqInt)(bmHeight) << 16));
			}
			dt = newDelta3;
		}
		xp = ds / 65536;
		yp = dt / 65536;
		if (!tileFlag) {
			/* begin clampValue:max: */
			if (xp < 0) {
				xp = 0;
				goto l3;
			}
			else {
				if (xp >= bmWidth) {
					xp = bmWidth - 1;
					goto l3;
				}
			}
	l3:	/* end clampValue:max: */;
			/* begin clampValue:max: */
			if (yp < 0) {
				yp = 0;
				goto l4;
			}
			else {
				if (yp >= bmHeight) {
					yp = bmHeight - 1;
					goto l4;
				}
			}
	l4:	/* end clampValue:max: */;
		}
		if ((xp >= 0)
		 && ((yp >= 0)
		 && ((xp < bmWidth)
		 && (yp < bmHeight)))) {
			/* begin bitmapValue:bits:atX:y: */
			bmDepth1 = objBuffer[bmFill + GBBitmapDepth];
			/* begin bitmapRasterOf: */
			bmRaster1 = objBuffer[bmFill + GBBitmapRaster];
			if (bmDepth1 == 32) {
				value1 = (((int*) bits))[(bmRaster1 * yp) + xp];
				if ((value1 != 0)
				 && ((value1 & 0xFF000000U) == 0)) {
					value1 = value1 | 0xFF000000U;
				}
				fillValue = uncheckedTransformColor(value1);
				goto l29;
			}
			rShift1 = (rShiftTable())[bmDepth1];

			/* cMask - mask out the pixel from the word */
			value1 = (((int*) bits))[(bmRaster1 * yp) + (((usqInt) xp) >> rShift1)];

			/* rShift - shift value to move the pixel in the word to the lowest bit position */
			cMask2 = (1U << bmDepth1) - 1;
			rShift1 = (32 - bmDepth1) - ((xp & ((1U << rShift1) - 1)) * bmDepth1);
			value1 = (((usqInt) value1) >> rShift1) & cMask2;
			if (bmDepth1 == 16) {

				/* Must convert by expanding bits */
				if (!(value1 == 0)) {
					b1 = ((sqInt)((usqInt)((value1 & 0x1F)) << 3));
					b1 += ((usqInt) b1) >> 5;
					g1 = ((sqInt)((usqInt)(((((usqInt) value1) >> 5) & 0x1F)) << 3));
					g1 += ((usqInt) g1) >> 5;
					r1 = ((sqInt)((usqInt)(((((usqInt) value1) >> 10) & 0x1F)) << 3));
					r1 += ((usqInt) r1) >> 5;
					a1 = 0xFF;
					value1 = ((b1 + (((sqInt)((usqInt)(g1) << 8)))) + (((sqInt)((usqInt)(r1) << 16)))) + (((sqInt)((usqInt)(a1) << 24)));
				}
			}
			else {

				/* Must convert by using color map */
				if ((objBuffer[bmFill + GBColormapSize]) == 0) {
					value1 = 0;
				}
				else {
					/* begin makeUnsignedFrom: */
					value1 = ((objBuffer + bmFill) + GBColormapOffset)[value1];
				}
			}
			fillValue = uncheckedTransformColor(value1);
	l29:	/* end bitmapValue:bits:atX:y: */;
			fillValue = ((usqInt) (fillValue & cMask)) >> cShift;
			idx = ((usqInt) x) >> baseShift;
			spanBuffer[idx] = ((spanBuffer[idx]) + fillValue);
		}
		ds += ((sqInt)((usqInt)(dsX) << cShift));
		dt += ((sqInt)((usqInt)(dtX) << cShift));
		x += aaLevel;
	}
	/* begin aaColorMaskGet */
	cMask = workBuffer[GWAAColorMask];
	/* begin aaColorShiftGet */
	cShift = workBuffer[GWAAColorShift];
	while (x < rightX) {
		if (tileFlag) {
			/* begin repeatValue:max: */
			newDelta4 = ds;
			while (newDelta4 < 0) {
				newDelta4 += ((sqInt)((usqInt)(bmWidth) << 16));
			}
			while (newDelta4 >= (((sqInt)((usqInt)(bmWidth) << 16)))) {
				newDelta4 -= ((sqInt)((usqInt)(bmWidth) << 16));
			}
			ds = newDelta4;
			/* begin repeatValue:max: */
			newDelta5 = dt;
			while (newDelta5 < 0) {
				newDelta5 += ((sqInt)((usqInt)(bmHeight) << 16));
			}
			while (newDelta5 >= (((sqInt)((usqInt)(bmHeight) << 16)))) {
				newDelta5 -= ((sqInt)((usqInt)(bmHeight) << 16));
			}
			dt = newDelta5;
		}
		xp = ds / 65536;
		yp = dt / 65536;
		if (!tileFlag) {
			/* begin clampValue:max: */
			if (xp < 0) {
				xp = 0;
				goto l5;
			}
			else {
				if (xp >= bmWidth) {
					xp = bmWidth - 1;
					goto l5;
				}
			}
	l5:	/* end clampValue:max: */;
			/* begin clampValue:max: */
			if (yp < 0) {
				yp = 0;
				goto l6;
			}
			else {
				if (yp >= bmHeight) {
					yp = bmHeight - 1;
					goto l6;
				}
			}
	l6:	/* end clampValue:max: */;
		}
		if ((xp >= 0)
		 && ((yp >= 0)
		 && ((xp < bmWidth)
		 && (yp < bmHeight)))) {
			/* begin bitmapValue:bits:atX:y: */
			bmDepth2 = objBuffer[bmFill + GBBitmapDepth];
			/* begin bitmapRasterOf: */
			bmRaster2 = objBuffer[bmFill + GBBitmapRaster];
			if (bmDepth2 == 32) {
				value2 = (((int*) bits))[(bmRaster2 * yp) + xp];
				if ((value2 != 0)
				 && ((value2 & 0xFF000000U) == 0)) {
					value2 = value2 | 0xFF000000U;
				}
				fillValue = uncheckedTransformColor(value2);
				goto l35;
			}
			rShift2 = (rShiftTable())[bmDepth2];

			/* cMask - mask out the pixel from the word */
			value2 = (((int*) bits))[(bmRaster2 * yp) + (((usqInt) xp) >> rShift2)];

			/* rShift - shift value to move the pixel in the word to the lowest bit position */
			cMask3 = (1U << bmDepth2) - 1;
			rShift2 = (32 - bmDepth2) - ((xp & ((1U << rShift2) - 1)) * bmDepth2);
			value2 = (((usqInt) value2) >> rShift2) & cMask3;
			if (bmDepth2 == 16) {

				/* Must convert by expanding bits */
				if (!(value2 == 0)) {
					b2 = ((sqInt)((usqInt)((value2 & 0x1F)) << 3));
					b2 += ((usqInt) b2) >> 5;
					g2 = ((sqInt)((usqInt)(((((usqInt) value2) >> 5) & 0x1F)) << 3));
					g2 += ((usqInt) g2) >> 5;
					r2 = ((sqInt)((usqInt)(((((usqInt) value2) >> 10) & 0x1F)) << 3));
					r2 += ((usqInt) r2) >> 5;
					a2 = 0xFF;
					value2 = ((b2 + (((sqInt)((usqInt)(g2) << 8)))) + (((sqInt)((usqInt)(r2) << 16)))) + (((sqInt)((usqInt)(a2) << 24)));
				}
			}
			else {

				/* Must convert by using color map */
				if ((objBuffer[bmFill + GBColormapSize]) == 0) {
					value2 = 0;
				}
				else {
					/* begin makeUnsignedFrom: */
					value2 = ((objBuffer + bmFill) + GBColormapOffset)[value2];
				}
			}
			fillValue = uncheckedTransformColor(value2);
	l35:	/* end bitmapValue:bits:atX:y: */;
			fillValue = ((usqInt) (fillValue & cMask)) >> cShift;
			idx = ((usqInt) x) >> baseShift;
			spanBuffer[idx] = ((spanBuffer[idx]) + fillValue);
		}
		ds += dsX;
		dt += dtX;
		x += 1;
	}
	return 0;
}


/*	Fill the span buffer between leftEdge and rightEdge using the given bits.
	Note: We always start from zero - this avoids using huge bitmap buffers if
	the bitmap is to be displayed at the very far right hand side and also
	gives us a chance of using certain bitmaps (e.g., those with depth 32)
	directly. 
 */

	/* BalloonEngineBase>>#fillBitmapSpan:from:to: */
static sqInt
fillBitmapSpanfromto(int *bits, sqInt leftX, sqInt rightX)
{
    sqInt baseShift;
    sqInt bitX;
    sqInt colorMask;
    sqInt colorShift;
    sqInt fillValue;
    sqInt x;
    sqInt x0;
    sqInt x1;

	x0 = leftX;
	x1 = rightX;

	/* Hack for pre-increment */
	bitX = -1;
	if ((workBuffer[GWAALevel]) == 1) {

		/* Speedy version for no anti-aliasing */
		while (x0 < x1) {
			fillValue = (((int *) bits))[(bitX += 1)];
			spanBuffer[x0] = fillValue;
			x0 += 1;
		}
	}
	else {

		/* Generic version with anti-aliasing */
		/* begin aaColorMaskGet */
		colorMask = workBuffer[GWAAColorMask];
		/* begin aaColorShiftGet */
		colorShift = workBuffer[GWAAColorShift];
		/* begin aaShiftGet */
		baseShift = workBuffer[GWAAShift];
		while (x0 < x1) {
			x = ((usqInt) x0) >> baseShift;
			fillValue = (((int *) bits))[(bitX += 1)];
			fillValue = ((usqInt) (fillValue & colorMask)) >> colorShift;
			spanBuffer[x] = ((spanBuffer[x]) + fillValue);
			x0 += 1;
		}
	}
	if (x1 > (workBuffer[GWSpanEnd])) {
		workBuffer[GWSpanEnd] = x1;
	}
	if (x1 > (workBuffer[GWSpanEndAA])) {
		workBuffer[GWSpanEndAA] = x1;
	}
	return 0;
}

	/* BalloonEnginePlugin>>#fillBitmapSpan:from:to:at: */
static sqInt
fillBitmapSpanfromtoat(sqInt bmFill, sqInt leftX, sqInt rightX, sqInt yValue)
{
    sqInt a;
    sqInt b;
    int *bits;
    sqInt bmDepth;
    sqInt bmHeight;
    sqInt bmRaster;
    sqInt bmWidth;
    int cMask;
    sqInt deltaX;
    sqInt deltaY;
    sqInt ds;
    sqInt dsX;
    sqInt dt;
    sqInt dtX;
    sqInt fillValue;
    sqInt g;
    sqInt newDelta;
    sqInt newDelta1;
    sqInt r;
    int rShift;
    int tileFlag;
    int value;
    sqInt x;
    sqInt x1;
    sqInt xp;
    sqInt yp;

	if (!((workBuffer[GWAALevel]) == 1)) {
		return fillBitmapSpanAAfromtoat(bmFill, leftX, rightX, yValue);
	}
	bits = loadBitsFrom(bmFill);
	if (bits == null) {
		return null;
	}
	/* begin bitmapWidthOf: */
	bmWidth = objBuffer[bmFill + GBBitmapWidth];
	/* begin bitmapHeightOf: */
	bmHeight = objBuffer[bmFill + GBBitmapHeight];
	tileFlag = (objBuffer[bmFill + GBTileFlag]) == 1;
	deltaX = leftX - (objBuffer[bmFill + GFOriginX]);
	deltaY = yValue - (objBuffer[bmFill + GFOriginY]);
	/* begin obj:at: */
	dsX = objBuffer[bmFill + GFDirectionX];
	/* begin obj:at: */
	dtX = objBuffer[bmFill + GFNormalX];
	ds = (deltaX * dsX) + (deltaY * (objBuffer[bmFill + GFDirectionY]));
	dt = (deltaX * dtX) + (deltaY * (objBuffer[bmFill + GFNormalY]));
	x = leftX;
	x1 = rightX;
	while (x < x1) {
		if (tileFlag) {
			/* begin repeatValue:max: */
			newDelta = ds;
			while (newDelta < 0) {
				newDelta += ((sqInt)((usqInt)(bmWidth) << 16));
			}
			while (newDelta >= (((sqInt)((usqInt)(bmWidth) << 16)))) {
				newDelta -= ((sqInt)((usqInt)(bmWidth) << 16));
			}
			ds = newDelta;
			/* begin repeatValue:max: */
			newDelta1 = dt;
			while (newDelta1 < 0) {
				newDelta1 += ((sqInt)((usqInt)(bmHeight) << 16));
			}
			while (newDelta1 >= (((sqInt)((usqInt)(bmHeight) << 16)))) {
				newDelta1 -= ((sqInt)((usqInt)(bmHeight) << 16));
			}
			dt = newDelta1;
		}
		xp = ds / 65536;
		yp = dt / 65536;
		if (!tileFlag) {
			/* begin clampValue:max: */
			if (xp < 0) {
				xp = 0;
				goto l1;
			}
			else {
				if (xp >= bmWidth) {
					xp = bmWidth - 1;
					goto l1;
				}
			}
	l1:	/* end clampValue:max: */;
			/* begin clampValue:max: */
			if (yp < 0) {
				yp = 0;
				goto l2;
			}
			else {
				if (yp >= bmHeight) {
					yp = bmHeight - 1;
					goto l2;
				}
			}
	l2:	/* end clampValue:max: */;
		}
		if ((xp >= 0)
		 && ((yp >= 0)
		 && ((xp < bmWidth)
		 && (yp < bmHeight)))) {
			/* begin bitmapValue:bits:atX:y: */
			bmDepth = objBuffer[bmFill + GBBitmapDepth];
			/* begin bitmapRasterOf: */
			bmRaster = objBuffer[bmFill + GBBitmapRaster];
			if (bmDepth == 32) {
				value = (((int*) bits))[(bmRaster * yp) + xp];
				if ((value != 0)
				 && ((value & 0xFF000000U) == 0)) {
					value = value | 0xFF000000U;
				}
				fillValue = uncheckedTransformColor(value);
				goto l10;
			}
			rShift = (rShiftTable())[bmDepth];

			/* cMask - mask out the pixel from the word */
			value = (((int*) bits))[(bmRaster * yp) + (((usqInt) xp) >> rShift)];

			/* rShift - shift value to move the pixel in the word to the lowest bit position */
			cMask = (1U << bmDepth) - 1;
			rShift = (32 - bmDepth) - ((xp & ((1U << rShift) - 1)) * bmDepth);
			value = (((usqInt) value) >> rShift) & cMask;
			if (bmDepth == 16) {

				/* Must convert by expanding bits */
				if (!(value == 0)) {
					b = ((sqInt)((usqInt)((value & 0x1F)) << 3));
					b += ((usqInt) b) >> 5;
					g = ((sqInt)((usqInt)(((((usqInt) value) >> 5) & 0x1F)) << 3));
					g += ((usqInt) g) >> 5;
					r = ((sqInt)((usqInt)(((((usqInt) value) >> 10) & 0x1F)) << 3));
					r += ((usqInt) r) >> 5;
					a = 0xFF;
					value = ((b + (((sqInt)((usqInt)(g) << 8)))) + (((sqInt)((usqInt)(r) << 16)))) + (((sqInt)((usqInt)(a) << 24)));
				}
			}
			else {

				/* Must convert by using color map */
				if ((objBuffer[bmFill + GBColormapSize]) == 0) {
					value = 0;
				}
				else {
					/* begin makeUnsignedFrom: */
					value = ((objBuffer + bmFill) + GBColormapOffset)[value];
				}
			}
			fillValue = uncheckedTransformColor(value);
	l10:	/* end bitmapValue:bits:atX:y: */;
			spanBuffer[x] = fillValue;
		}
		ds += dsX;
		dt += dtX;
		x += 1;
	}
	return 0;
}


/*	This is the inner loop for solid color fills with anti-aliasing.
	This loop has been unrolled for speed and quality into three parts:
	a) copy all pixels that fall into the first full pixel.
	b) copy aaLevel pixels between the first and the last full pixel
	c) copy all pixels that fall in the last full pixel */

	/* BalloonEngineBase>>#fillColorSpanAA:x0:x1: */
static sqInt
fillColorSpanAAx0x1(sqInt pixelValue32, sqInt leftX, sqInt rightX)
{
    sqInt aaLevel;
    sqInt baseShift;
    sqInt colorMask;
    sqInt firstPixel;
    sqInt firstPixel1;
    sqInt idx;
    sqInt lastPixel;
    sqInt pv32;
    sqInt x;


	/* Not now -- maybe later */
	/* Compute the pixel boundaries. */
	/* begin aaFirstPixelFrom:to: */
	firstPixel1 = ((leftX + (workBuffer[GWAALevel])) - 1) & ((unsigned int)~((workBuffer[GWAALevel]) - 1));
	if (firstPixel1 > rightX) {
		firstPixel = rightX;
		goto l1;
	}
	else {
		firstPixel = firstPixel1;
		goto l1;
	}
	l1:	/* end aaFirstPixelFrom:to: */;
	/* begin aaLastPixelFrom:to: */
	lastPixel = (rightX - 1) & ((unsigned int)~((workBuffer[GWAALevel]) - 1));
	/* begin aaLevelGet */
	aaLevel = workBuffer[GWAALevel];
	/* begin aaShiftGet */
	baseShift = workBuffer[GWAAShift];

	/* Part a: Deal with the first n sub-pixels */
	x = leftX;
	if (x < firstPixel) {
		pv32 = ((usqInt) (pixelValue32 & (workBuffer[GWAAColorMask]))) >> (workBuffer[GWAAColorShift]);
		while (x < firstPixel) {
			idx = ((usqInt) x) >> baseShift;
			spanBuffer[idx] = ((spanBuffer[idx]) + pv32);
			x += 1;
		}
	}
	if (x < lastPixel) {
		colorMask = (((usqInt) (workBuffer[GWAAColorMask])) >> (workBuffer[GWAAShift])) | 4042322160U;
		pv32 = ((usqInt) (pixelValue32 & colorMask)) >> (workBuffer[GWAAShift]);
		while (x < lastPixel) {
			idx = ((usqInt) x) >> baseShift;
			spanBuffer[idx] = ((spanBuffer[idx]) + pv32);
			x += aaLevel;
		}
	}
	if (x < rightX) {
		pv32 = ((usqInt) (pixelValue32 & (workBuffer[GWAAColorMask]))) >> (workBuffer[GWAAColorShift]);
		while (x < rightX) {
			idx = ((usqInt) x) >> baseShift;
			spanBuffer[idx] = ((spanBuffer[idx]) + pv32);
			x += 1;
		}
	}
	return 0;
}


/*	Fill the span buffer between leftEdge and rightEdge with the given pixel
	value. 
 */

	/* BalloonEngineBase>>#fillColorSpan:from:to: */
static sqInt
fillColorSpanfromto(sqInt pixelValue32, sqInt leftX, sqInt rightX)
{
    sqInt x0;
    sqInt x1;


	/* Use a unrolled version for anti-aliased fills... */
	if (!((workBuffer[GWAALevel]) == 1)) {
		return fillColorSpanAAx0x1(pixelValue32, leftX, rightX);
	}
	x0 = leftX;

	/* Unroll the inner loop four times, since we're only storing data. */
	x1 = rightX;
	while ((x0 + 4) < x1) {
		spanBuffer[x0] = pixelValue32;
		spanBuffer[x0 + 1] = pixelValue32;
		spanBuffer[x0 + 2] = pixelValue32;
		spanBuffer[x0 + 3] = pixelValue32;
		x0 += 4;
	}
	while (x0 < x1) {
		spanBuffer[x0] = pixelValue32;
		x0 += 1;
	}
	return 0;
}

	/* BalloonEnginePlugin>>#fillDirectionXOf: */
static sqInt
fillDirectionXOf(sqInt fill)
{
	return objBuffer[fill + GFDirectionX];
}

	/* BalloonEnginePlugin>>#fillDirectionXOf:put: */
static sqInt
fillDirectionXOfput(sqInt fill, sqInt value)
{
	return objBuffer[fill + GFDirectionX] = value;
}

	/* BalloonEnginePlugin>>#fillDirectionYOf: */
static sqInt
fillDirectionYOf(sqInt fill)
{
	return objBuffer[fill + GFDirectionY];
}

	/* BalloonEnginePlugin>>#fillDirectionYOf:put: */
static sqInt
fillDirectionYOfput(sqInt fill, sqInt value)
{
	return objBuffer[fill + GFDirectionY] = value;
}

	/* BalloonEnginePlugin>>#fillLinearGradient */
static sqInt
fillLinearGradient(void)
{
	return fillLinearGradientfromtoat(workBuffer[GWLastExportedFill], workBuffer[GWLastExportedLeftX], workBuffer[GWLastExportedRightX], workBuffer[GWCurrentY]);
}


/*	This is the AA version of linear gradient filling. */

	/* BalloonEnginePlugin>>#fillLinearGradientAA:ramp:ds:dsX:from:to: */
static sqInt
fillLinearGradientAArampdsdsXfromto(sqInt fill, int *ramp, sqInt deltaS, sqInt dsX, sqInt leftX, sqInt rightX)
{
    sqInt aaLevel;
    sqInt baseShift;
    sqInt colorMask;
    sqInt colorShift;
    sqInt ds;
    sqInt firstPixel;
    sqInt firstPixel1;
    sqInt idx;
    sqInt lastPixel;
    sqInt rampIndex;
    sqInt rampSize;
    sqInt rampValue;
    sqInt x;

	/* begin aaLevelGet */
	aaLevel = workBuffer[GWAALevel];
	/* begin aaShiftGet */
	baseShift = workBuffer[GWAAShift];
	/* begin obj:at: */
	rampSize = objBuffer[fill + GFRampLength];
	ds = deltaS;
	x = leftX;
	rampIndex = ds / 65536;
	/* begin aaFirstPixelFrom:to: */
	firstPixel1 = ((leftX + (workBuffer[GWAALevel])) - 1) & ((unsigned int)~((workBuffer[GWAALevel]) - 1));
	if (firstPixel1 > rightX) {
		firstPixel = rightX;
		goto l3;
	}
	else {
		firstPixel = firstPixel1;
		goto l3;
	}
	l3:	/* end aaFirstPixelFrom:to: */;
	/* begin aaLastPixelFrom:to: */
	lastPixel = (rightX - 1) & ((unsigned int)~((workBuffer[GWAALevel]) - 1));
	/* begin aaColorMaskGet */
	colorMask = workBuffer[GWAAColorMask];
	/* begin aaColorShiftGet */
	colorShift = workBuffer[GWAAColorShift];
	while ((x < firstPixel)
	 && ((rampIndex < rampSize)
	 && (rampIndex >= 0))) {
		rampValue = (((int *) ramp))[rampIndex];

		/* Copy as many pixels as possible */
		rampValue = ((usqInt) (rampValue & colorMask)) >> colorShift;
		while ((x < firstPixel)
		 && ((ds / 65536) == rampIndex)) {
			idx = ((usqInt) x) >> baseShift;
			spanBuffer[idx] = ((spanBuffer[idx]) + rampValue);
			x += 1;
			ds += dsX;
		}
		rampIndex = ds / 65536;
	}
	colorMask = (((usqInt) (workBuffer[GWAAColorMask])) >> (workBuffer[GWAAShift])) | 4042322160U;
	/* begin aaShiftGet */
	colorShift = workBuffer[GWAAShift];
	while ((x < lastPixel)
	 && ((rampIndex < rampSize)
	 && (rampIndex >= 0))) {
		rampValue = (((int *) ramp))[rampIndex];

		/* Copy as many pixels as possible */
		rampValue = ((usqInt) (rampValue & colorMask)) >> colorShift;
		while ((x < lastPixel)
		 && ((ds / 65536) == rampIndex)) {
			idx = ((usqInt) x) >> baseShift;
			spanBuffer[idx] = ((spanBuffer[idx]) + rampValue);
			x += aaLevel;
			ds += ((sqInt)((usqInt)(dsX) << colorShift));
		}
		rampIndex = ds / 65536;
	}
	/* begin aaColorMaskGet */
	colorMask = workBuffer[GWAAColorMask];
	/* begin aaColorShiftGet */
	colorShift = workBuffer[GWAAColorShift];
	while ((x < rightX)
	 && ((rampIndex < rampSize)
	 && (rampIndex >= 0))) {
		rampValue = (((int *) ramp))[rampIndex];

		/* Copy as many pixels as possible */
		rampValue = ((usqInt) (rampValue & colorMask)) >> colorShift;
		while ((x < rightX)
		 && ((ds / 65536) == rampIndex)) {
			idx = ((usqInt) x) >> baseShift;
			spanBuffer[idx] = ((spanBuffer[idx]) + rampValue);
			x += 1;
			ds += dsX;
		}
		rampIndex = ds / 65536;
	}
	return x;
}


/*	Draw a linear gradient fill. */

	/* BalloonEnginePlugin>>#fillLinearGradient:from:to:at: */
static sqInt
fillLinearGradientfromtoat(sqInt fill, sqInt leftX, sqInt rightX, sqInt yValue)
{
    sqInt ds;
    sqInt dsX;
    sqInt pixelValue32;
    sqInt pixelValue321;
    int *ramp;
    sqInt rampIndex;
    sqInt rampSize;
    sqInt x;
    sqInt x0;
    sqInt x01;
    sqInt x02;
    sqInt x1;
    sqInt x11;
    sqInt x12;

	ramp = (objBuffer + fill) + GFRampOffset;
	/* begin obj:at: */
	rampSize = objBuffer[fill + GFRampLength];
	/* begin fillDirectionXOf: */
	dsX = objBuffer[fill + GFDirectionX];
	ds = ((leftX - (objBuffer[fill + GFOriginX])) * dsX) + ((yValue - (objBuffer[fill + GFOriginY])) * (objBuffer[fill + GFDirectionY]));
	x = (x0 = leftX);

	/* Note: The inner loop has been divided into three parts for speed */
	/* Part one: Fill everything outside the left boundary */
	x1 = rightX;
	while (((((rampIndex = ds / 65536)) < 0)
	 || (rampIndex >= rampSize))
	 && (x < x1)) {
		x += 1;
		ds += dsX;
	}
	if (x > x0) {
		if (rampIndex < 0) {
			rampIndex = 0;
		}
		if (rampIndex >= rampSize) {
			rampIndex = rampSize - 1;
		}
		/* begin fillColorSpan:from:to: */
		pixelValue32 = ramp[rampIndex];
		if (!((workBuffer[GWAALevel]) == 1)) {
			fillColorSpanAAx0x1(pixelValue32, x0, x);
			goto l1;
		}
		x01 = x0;

		/* Unroll the inner loop four times, since we're only storing data. */
		x11 = x;
		while ((x01 + 4) < x11) {
			spanBuffer[x01] = pixelValue32;
			spanBuffer[x01 + 1] = pixelValue32;
			spanBuffer[x01 + 2] = pixelValue32;
			spanBuffer[x01 + 3] = pixelValue32;
			x01 += 4;
		}
		while (x01 < x11) {
			spanBuffer[x01] = pixelValue32;
			x01 += 1;
		}
	l1:	/* end fillColorSpan:from:to: */;
	}
	if ((workBuffer[GWAALevel]) == 1) {

		/* Fast version w/o anti-aliasing */
		while (((((rampIndex = ds / 65536)) < rampSize)
		 && (rampIndex >= 0))
		 && (x < x1)) {
			spanBuffer[x] = (ramp[rampIndex]);
			x += 1;
			ds += dsX;
		}
	}
	else {
		x = fillLinearGradientAArampdsdsXfromto(fill, ramp, ds, dsX, x, rightX);
	}
	if (x < x1) {
		if (rampIndex < 0) {
			rampIndex = 0;
		}
		if (rampIndex >= rampSize) {
			rampIndex = rampSize - 1;
		}
		/* begin fillColorSpan:from:to: */
		pixelValue321 = ramp[rampIndex];
		if (!((workBuffer[GWAALevel]) == 1)) {
			fillColorSpanAAx0x1(pixelValue321, x, x1);
			goto l2;
		}
		x02 = x;

		/* Unroll the inner loop four times, since we're only storing data. */
		x12 = x1;
		while ((x02 + 4) < x12) {
			spanBuffer[x02] = pixelValue321;
			spanBuffer[x02 + 1] = pixelValue321;
			spanBuffer[x02 + 2] = pixelValue321;
			spanBuffer[x02 + 3] = pixelValue321;
			x02 += 4;
		}
		while (x02 < x12) {
			spanBuffer[x02] = pixelValue321;
			x02 += 1;
		}
	l2:	/* end fillColorSpan:from:to: */;
	}
	return 0;
}

	/* BalloonEngineBase>>#fillMaxXGet */
static sqInt
fillMaxXGet(void)
{
	return workBuffer[GWFillMaxX];
}

	/* BalloonEngineBase>>#fillMaxXPut: */
static sqInt
fillMaxXPut(sqInt value)
{
	return workBuffer[GWFillMaxX] = value;
}

	/* BalloonEngineBase>>#fillMaxYGet */
static sqInt
fillMaxYGet(void)
{
	return workBuffer[GWFillMaxY];
}

	/* BalloonEngineBase>>#fillMaxYPut: */
static sqInt
fillMaxYPut(sqInt value)
{
	return workBuffer[GWFillMaxY] = value;
}

	/* BalloonEngineBase>>#fillMinXGet */
static sqInt
fillMinXGet(void)
{
	return workBuffer[GWFillMinX];
}

	/* BalloonEngineBase>>#fillMinXPut: */
static sqInt
fillMinXPut(sqInt value)
{
	return workBuffer[GWFillMinX] = value;
}

	/* BalloonEngineBase>>#fillMinYGet */
static sqInt
fillMinYGet(void)
{
	return workBuffer[GWFillMinY];
}

	/* BalloonEngineBase>>#fillMinYPut: */
static sqInt
fillMinYPut(sqInt value)
{
	return workBuffer[GWFillMinY] = value;
}

	/* BalloonEnginePlugin>>#fillNormalXOf: */
static sqInt
fillNormalXOf(sqInt fill)
{
	return objBuffer[fill + GFNormalX];
}

	/* BalloonEnginePlugin>>#fillNormalXOf:put: */
static sqInt
fillNormalXOfput(sqInt fill, sqInt value)
{
	return objBuffer[fill + GFNormalX] = value;
}

	/* BalloonEnginePlugin>>#fillNormalYOf: */
static sqInt
fillNormalYOf(sqInt fill)
{
	return objBuffer[fill + GFNormalY];
}

	/* BalloonEnginePlugin>>#fillNormalYOf:put: */
static sqInt
fillNormalYOfput(sqInt fill, sqInt value)
{
	return objBuffer[fill + GFNormalY] = value;
}

	/* BalloonEngineBase>>#fillOffsetXGet */
static sqInt
fillOffsetXGet(void)
{
	return workBuffer[GWFillOffsetX];
}

	/* BalloonEngineBase>>#fillOffsetXPut: */
static sqInt
fillOffsetXPut(sqInt value)
{
	return workBuffer[GWFillOffsetX] = value;
}

	/* BalloonEngineBase>>#fillOffsetYGet */
static sqInt
fillOffsetYGet(void)
{
	return workBuffer[GWFillOffsetY];
}

	/* BalloonEngineBase>>#fillOffsetYPut: */
static sqInt
fillOffsetYPut(sqInt value)
{
	return workBuffer[GWFillOffsetY] = value;
}

	/* BalloonEnginePlugin>>#fillOriginXOf: */
static sqInt
fillOriginXOf(sqInt fill)
{
	return objBuffer[fill + GFOriginX];
}

	/* BalloonEnginePlugin>>#fillOriginXOf:put: */
static sqInt
fillOriginXOfput(sqInt fill, sqInt value)
{
	return objBuffer[fill + GFOriginX] = value;
}

	/* BalloonEnginePlugin>>#fillOriginYOf: */
static sqInt
fillOriginYOf(sqInt fill)
{
	return objBuffer[fill + GFOriginY];
}

	/* BalloonEnginePlugin>>#fillOriginYOf:put: */
static sqInt
fillOriginYOfput(sqInt fill, sqInt value)
{
	return objBuffer[fill + GFOriginY] = value;
}


/*	Part 2a) Compute the decreasing part of the ramp */

	/* BalloonEnginePlugin>>#fillRadialDecreasingAA:ramp:deltaST:dsX:dtX:from:to: */
static sqInt
fillRadialDecreasingAArampdeltaSTdsXdtXfromto(sqInt fill, int *ramp, int *deltaST, sqInt dsX, sqInt dtX, sqInt leftX, sqInt rightX)
{
    sqInt aaLevel;
    sqInt baseShift;
    sqInt colorMask;
    sqInt colorShift;
    int ds;
    int dt;
    sqInt firstPixel;
    sqInt firstPixel1;
    sqInt index;
    sqInt lastPixel;
    sqInt length2;
    sqInt nextLength;
    sqInt rampIndex;
    sqInt rampValue;
    sqInt x;
    sqInt x1;

	ds = (((int*) deltaST))[0];
	dt = (((int*) deltaST))[1];
	/* begin aaLevelGet */
	aaLevel = workBuffer[GWAALevel];
	/* begin aaShiftGet */
	baseShift = workBuffer[GWAAShift];
	rampIndex = accurateLengthOfwith(ds / 65536, dt / 65536);
	length2 = (rampIndex - 1) * (rampIndex - 1);
	x = leftX;
	/* begin fillOriginXOf: */
	x1 = objBuffer[fill + GFOriginX];
	if (x1 > rightX) {
		x1 = rightX;
	}
	/* begin aaFirstPixelFrom:to: */
	firstPixel1 = ((leftX + (workBuffer[GWAALevel])) - 1) & ((unsigned int)~((workBuffer[GWAALevel]) - 1));
	if (firstPixel1 > x1) {
		firstPixel = x1;
		goto l9;
	}
	else {
		firstPixel = firstPixel1;
		goto l9;
	}
	l9:	/* end aaFirstPixelFrom:to: */;
	/* begin aaLastPixelFrom:to: */
	lastPixel = (x1 - 1) & ((unsigned int)~((workBuffer[GWAALevel]) - 1));
	if (x < firstPixel) {
		/* begin aaColorMaskGet */
		colorMask = workBuffer[GWAAColorMask];
		/* begin aaColorShiftGet */
		colorShift = workBuffer[GWAAColorShift];
		rampValue = (((int *) ramp))[rampIndex];
		rampValue = ((usqInt) (rampValue & colorMask)) >> colorShift;
		while (x < firstPixel) {

			/* Try to copy the current value more than just once */
			while ((x < firstPixel)
			 && ((((ds / 65536) * (ds / 65536)) + ((dt / 65536) * (dt / 65536))) >= length2)) {
				index = ((usqInt) x) >> baseShift;
				spanBuffer[index] = ((spanBuffer[index]) + rampValue);
				x += 1;
				ds += dsX;
				dt += dtX;
			}
			nextLength = ((ds / 65536) * (ds / 65536)) + ((dt / 65536) * (dt / 65536));
			while (nextLength < length2) {
				rampIndex -= 1;
				rampValue = (((int *) ramp))[rampIndex];
				rampValue = ((usqInt) (rampValue & colorMask)) >> colorShift;
				length2 = (rampIndex - 1) * (rampIndex - 1);
			}
		}
	}
	if (x < lastPixel) {
		colorMask = (((usqInt) (workBuffer[GWAAColorMask])) >> (workBuffer[GWAAShift])) | 4042322160U;
		/* begin aaShiftGet */
		colorShift = workBuffer[GWAAShift];
		rampValue = (((int *) ramp))[rampIndex];
		rampValue = ((usqInt) (rampValue & colorMask)) >> colorShift;
		while (x < lastPixel) {

			/* Try to copy the current value more than just once */
			while ((x < lastPixel)
			 && ((((ds / 65536) * (ds / 65536)) + ((dt / 65536) * (dt / 65536))) >= length2)) {
				index = ((usqInt) x) >> baseShift;
				spanBuffer[index] = ((spanBuffer[index]) + rampValue);
				x += aaLevel;
				ds += ((sqInt)((usqInt)(dsX) << colorShift));
				dt += ((sqInt)((usqInt)(dtX) << colorShift));
			}
			nextLength = ((ds / 65536) * (ds / 65536)) + ((dt / 65536) * (dt / 65536));
			while (nextLength < length2) {
				rampIndex -= 1;
				rampValue = (((int *) ramp))[rampIndex];
				rampValue = ((usqInt) (rampValue & colorMask)) >> colorShift;
				length2 = (rampIndex - 1) * (rampIndex - 1);
			}
		}
	}
	if (x < x1) {
		/* begin aaColorMaskGet */
		colorMask = workBuffer[GWAAColorMask];
		/* begin aaColorShiftGet */
		colorShift = workBuffer[GWAAColorShift];
		rampValue = (((int *) ramp))[rampIndex];
		rampValue = ((usqInt) (rampValue & colorMask)) >> colorShift;
		while (x < x1) {

			/* Try to copy the current value more than just once */
			while ((x < x1)
			 && ((((ds / 65536) * (ds / 65536)) + ((dt / 65536) * (dt / 65536))) >= length2)) {
				index = ((usqInt) x) >> baseShift;
				spanBuffer[index] = ((spanBuffer[index]) + rampValue);
				x += 1;
				ds += dsX;
				dt += dtX;
			}
			nextLength = ((ds / 65536) * (ds / 65536)) + ((dt / 65536) * (dt / 65536));
			while (nextLength < length2) {
				rampIndex -= 1;
				rampValue = (((int *) ramp))[rampIndex];
				rampValue = ((usqInt) (rampValue & colorMask)) >> colorShift;
				length2 = (rampIndex - 1) * (rampIndex - 1);
			}
		}
	}
	(((int *) deltaST))[0] = ds;
	(((int *) deltaST))[1] = dt;
	return x;
}


/*	Part 2a) Compute the decreasing part of the ramp */

	/* BalloonEnginePlugin>>#fillRadialDecreasing:ramp:deltaST:dsX:dtX:from:to: */
static sqInt
fillRadialDecreasingrampdeltaSTdsXdtXfromto(sqInt fill, sqInt ramp, sqInt deltaST, sqInt dsX, sqInt dtX, sqInt leftX, sqInt rightX)
{
    int ds;
    int dt;
    sqInt length2;
    sqInt nextLength;
    sqInt rampIndex;
    sqInt rampValue;
    sqInt x;
    sqInt x1;

	ds = (((int*) deltaST))[0];
	dt = (((int*) deltaST))[1];
	rampIndex = accurateLengthOfwith(ds / 65536, dt / 65536);
	rampValue = (((int *) ramp))[rampIndex];
	length2 = (rampIndex - 1) * (rampIndex - 1);
	x = leftX;
	x1 = rightX;
	if (x1 > (objBuffer[fill + GFOriginX])) {
		/* begin fillOriginXOf: */
		x1 = objBuffer[fill + GFOriginX];
	}
	while (x < x1) {

		/* Try to copy the current value more than just once */
		while ((x < x1)
		 && ((((ds / 65536) * (ds / 65536)) + ((dt / 65536) * (dt / 65536))) >= length2)) {
			spanBuffer[x] = rampValue;
			x += 1;
			ds += dsX;
			dt += dtX;
		}
		nextLength = ((ds / 65536) * (ds / 65536)) + ((dt / 65536) * (dt / 65536));
		while (nextLength < length2) {
			rampIndex -= 1;
			rampValue = (((int *) ramp))[rampIndex];
			length2 = (rampIndex - 1) * (rampIndex - 1);
		}
	}
	(((int *) deltaST))[0] = ds;
	(((int *) deltaST))[1] = dt;
	return x;
}

	/* BalloonEnginePlugin>>#fillRadialGradient */
static sqInt
fillRadialGradient(void)
{
	return fillRadialGradientfromtoat(workBuffer[GWLastExportedFill], workBuffer[GWLastExportedLeftX], workBuffer[GWLastExportedRightX], workBuffer[GWCurrentY]);
}


/*	Draw a radial gradient fill. */

	/* BalloonEnginePlugin>>#fillRadialGradient:from:to:at: */
static sqInt
fillRadialGradientfromtoat(sqInt fill, sqInt leftX, sqInt rightX, sqInt yValue)
{
    int *deltaST;
    sqInt deltaX;
    sqInt deltaY;
    sqInt ds;
    int ds1;
    int ds2;
    sqInt dsX;
    sqInt dt;
    int dt1;
    int dt2;
    sqInt dtX;
    sqInt lastLength;
    sqInt length2;
    sqInt length21;
    sqInt length22;
    sqInt nextLength;
    sqInt nextLength1;
    sqInt pixelValue32;
    sqInt pixelValue321;
    int *ramp;
    sqInt rampIndex;
    sqInt rampIndex1;
    sqInt rampSize;
    sqInt rampSize1;
    sqInt rampValue;
    sqInt rampValue1;
    sqInt x;
    sqInt x0;
    sqInt x01;
    sqInt x1;
    sqInt x11;
    sqInt x12;
    sqInt x13;
    sqInt x14;
    sqInt x2;
    sqInt x3;

	ramp = (objBuffer + fill) + GFRampOffset;
	/* begin obj:at: */
	rampSize = objBuffer[fill + GFRampLength];
	deltaX = leftX - (objBuffer[fill + GFOriginX]);
	deltaY = yValue - (objBuffer[fill + GFOriginY]);
	/* begin fillDirectionXOf: */
	dsX = objBuffer[fill + GFDirectionX];
	/* begin fillNormalXOf: */
	dtX = objBuffer[fill + GFNormalX];
	ds = (deltaX * dsX) + (deltaY * (objBuffer[fill + GFDirectionY]));
	dt = (deltaX * dtX) + (deltaY * (objBuffer[fill + GFNormalY]));
	x = leftX;

	/* Note: The inner loop has been divided into three parts for speed */
	/* Part one: Fill everything outside the left boundary */
	x1 = rightX;

	/* This is the upper bound */
	length2 = (rampSize - 1) * (rampSize - 1);
	while (((((ds / 65536) * (ds / 65536)) + ((dt / 65536) * (dt / 65536))) >= length2)
	 && (x < x1)) {
		x += 1;
		ds += dsX;
		dt += dtX;
	}
	if (x > leftX) {
		/* begin fillColorSpan:from:to: */
		pixelValue32 = ramp[rampSize - 1];
		if (!((workBuffer[GWAALevel]) == 1)) {
			fillColorSpanAAx0x1(pixelValue32, leftX, x);
			goto l1;
		}
		x0 = leftX;

		/* Unroll the inner loop four times, since we're only storing data. */
		x11 = x;
		while ((x0 + 4) < x11) {
			spanBuffer[x0] = pixelValue32;
			spanBuffer[x0 + 1] = pixelValue32;
			spanBuffer[x0 + 2] = pixelValue32;
			spanBuffer[x0 + 3] = pixelValue32;
			x0 += 4;
		}
		while (x0 < x11) {
			spanBuffer[x0] = pixelValue32;
			x0 += 1;
		}
	l1:	/* end fillColorSpan:from:to: */;
	}
	deltaST = ((int *) (workBuffer + GWPoint1));
	deltaST[0] = ds;
	deltaST[1] = dt;
	if (x < (objBuffer[fill + GFOriginX])) {

		/* Draw the decreasing part */
		if ((workBuffer[GWAALevel]) == 1) {
			/* begin fillRadialDecreasing:ramp:deltaST:dsX:dtX:from:to: */
			ds1 = (((int*) deltaST))[0];
			dt1 = (((int*) deltaST))[1];
			rampIndex = accurateLengthOfwith(ds1 / 65536, dt1 / 65536);
			rampValue = (((int *) ramp))[rampIndex];
			length21 = (rampIndex - 1) * (rampIndex - 1);
			x2 = x;
			x13 = x1;
			if (x13 > (objBuffer[fill + GFOriginX])) {
				/* begin fillOriginXOf: */
				x13 = objBuffer[fill + GFOriginX];
			}
			while (x2 < x13) {

				/* Try to copy the current value more than just once */
				while ((x2 < x13)
				 && ((((ds1 / 65536) * (ds1 / 65536)) + ((dt1 / 65536) * (dt1 / 65536))) >= length21)) {
					spanBuffer[x2] = rampValue;
					x2 += 1;
					ds1 += dsX;
					dt1 += dtX;
				}
				nextLength = ((ds1 / 65536) * (ds1 / 65536)) + ((dt1 / 65536) * (dt1 / 65536));
				while (nextLength < length21) {
					rampIndex -= 1;
					rampValue = (((int *) ramp))[rampIndex];
					length21 = (rampIndex - 1) * (rampIndex - 1);
				}
			}
			(((int *) deltaST))[0] = ds1;
			(((int *) deltaST))[1] = dt1;
			x = x2;
		}
		else {
			x = fillRadialDecreasingAArampdeltaSTdsXdtXfromto(fill, ramp, deltaST, dsX, dtX, x, x1);
		}
	}
	if (x < x1) {

		/* Draw the increasing part */
		if ((workBuffer[GWAALevel]) == 1) {
			/* begin fillRadialIncreasing:ramp:deltaST:dsX:dtX:from:to: */
			ds2 = (((int*) deltaST))[0];
			dt2 = (((int*) deltaST))[1];
			rampIndex1 = accurateLengthOfwith(ds2 / 65536, dt2 / 65536);
			rampValue1 = (((int *) ramp))[rampIndex1];
			/* begin obj:at: */
			rampSize1 = objBuffer[fill + GFRampLength];

			/* This is the upper bound */
			length22 = (rampSize1 - 1) * (rampSize1 - 1);
			nextLength1 = (rampIndex1 + 1) * (rampIndex1 + 1);
			lastLength = ((ds2 / 65536) * (ds2 / 65536)) + ((dt2 / 65536) * (dt2 / 65536));
			x3 = x;
			x14 = x1;
			while ((x3 < x14)
			 && (lastLength < length22)) {

				/* Try to copy the current value more than once */
				while ((x3 < x14)
				 && ((((ds2 / 65536) * (ds2 / 65536)) + ((dt2 / 65536) * (dt2 / 65536))) <= nextLength1)) {
					spanBuffer[x3] = rampValue1;
					x3 += 1;
					ds2 += dsX;
					dt2 += dtX;
				}
				lastLength = ((ds2 / 65536) * (ds2 / 65536)) + ((dt2 / 65536) * (dt2 / 65536));
				while (lastLength > nextLength1) {
					rampIndex1 += 1;
					rampValue1 = (((int *) ramp))[rampIndex1];
					nextLength1 = (rampIndex1 + 1) * (rampIndex1 + 1);
				}
			}
			(((int *) deltaST))[0] = ds2;
			(((int *) deltaST))[1] = dt2;
			x = x3;
		}
		else {
			x = fillRadialIncreasingAArampdeltaSTdsXdtXfromto(fill, ramp, deltaST, dsX, dtX, x, x1);
		}
	}
	if (x < rightX) {
		/* begin fillColorSpan:from:to: */
		pixelValue321 = ramp[rampSize - 1];
		if (!((workBuffer[GWAALevel]) == 1)) {
			fillColorSpanAAx0x1(pixelValue321, x, rightX);
			goto l2;
		}
		x01 = x;

		/* Unroll the inner loop four times, since we're only storing data. */
		x12 = rightX;
		while ((x01 + 4) < x12) {
			spanBuffer[x01] = pixelValue321;
			spanBuffer[x01 + 1] = pixelValue321;
			spanBuffer[x01 + 2] = pixelValue321;
			spanBuffer[x01 + 3] = pixelValue321;
			x01 += 4;
		}
		while (x01 < x12) {
			spanBuffer[x01] = pixelValue321;
			x01 += 1;
		}
	l2:	/* end fillColorSpan:from:to: */;
	}
	return 0;
}


/*	Part 2b) Compute the increasing part of the ramp */

	/* BalloonEnginePlugin>>#fillRadialIncreasingAA:ramp:deltaST:dsX:dtX:from:to: */
static sqInt
fillRadialIncreasingAArampdeltaSTdsXdtXfromto(sqInt fill, int *ramp, int *deltaST, sqInt dsX, sqInt dtX, sqInt leftX, sqInt rightX)
{
    sqInt aaLevel;
    sqInt baseShift;
    sqInt colorMask;
    sqInt colorShift;
    int ds;
    int dt;
    sqInt firstPixel;
    sqInt firstPixel1;
    sqInt index;
    sqInt lastLength;
    sqInt lastPixel;
    sqInt length2;
    sqInt nextLength;
    sqInt rampIndex;
    sqInt rampSize;
    sqInt rampValue;
    sqInt x;

	ds = (((int*) deltaST))[0];
	dt = (((int*) deltaST))[1];
	/* begin aaLevelGet */
	aaLevel = workBuffer[GWAALevel];
	/* begin aaShiftGet */
	baseShift = workBuffer[GWAAShift];
	rampIndex = accurateLengthOfwith(ds / 65536, dt / 65536);
	/* begin obj:at: */
	rampSize = objBuffer[fill + GFRampLength];

	/* This is the upper bound */
	length2 = (rampSize - 1) * (rampSize - 1);
	nextLength = (rampIndex + 1) * (rampIndex + 1);
	lastLength = ((ds / 65536) * (ds / 65536)) + ((dt / 65536) * (dt / 65536));
	x = leftX;
	/* begin aaFirstPixelFrom:to: */
	firstPixel1 = ((leftX + (workBuffer[GWAALevel])) - 1) & ((unsigned int)~((workBuffer[GWAALevel]) - 1));
	if (firstPixel1 > rightX) {
		firstPixel = rightX;
		goto l8;
	}
	else {
		firstPixel = firstPixel1;
		goto l8;
	}
	l8:	/* end aaFirstPixelFrom:to: */;
	/* begin aaLastPixelFrom:to: */
	lastPixel = (rightX - 1) & ((unsigned int)~((workBuffer[GWAALevel]) - 1));
	if ((x < firstPixel)
	 && (lastLength < length2)) {
		/* begin aaColorMaskGet */
		colorMask = workBuffer[GWAAColorMask];
		/* begin aaColorShiftGet */
		colorShift = workBuffer[GWAAColorShift];
		rampValue = (((int *) ramp))[rampIndex];
		rampValue = ((usqInt) (rampValue & colorMask)) >> colorShift;
		while ((x < firstPixel)
		 && (lastLength < length2)) {

			/* Try to copy the current value more than once */
			while ((x < firstPixel)
			 && ((((ds / 65536) * (ds / 65536)) + ((dt / 65536) * (dt / 65536))) <= nextLength)) {
				index = ((usqInt) x) >> baseShift;
				spanBuffer[index] = ((spanBuffer[index]) + rampValue);
				x += 1;
				ds += dsX;
				dt += dtX;
			}
			lastLength = ((ds / 65536) * (ds / 65536)) + ((dt / 65536) * (dt / 65536));
			while (lastLength > nextLength) {
				rampIndex += 1;
				rampValue = (((int *) ramp))[rampIndex];
				rampValue = ((usqInt) (rampValue & colorMask)) >> colorShift;
				nextLength = (rampIndex + 1) * (rampIndex + 1);
			}
		}
	}
	if ((x < lastPixel)
	 && (lastLength < length2)) {
		colorMask = (((usqInt) (workBuffer[GWAAColorMask])) >> (workBuffer[GWAAShift])) | 4042322160U;
		/* begin aaShiftGet */
		colorShift = workBuffer[GWAAShift];
		rampValue = (((int *) ramp))[rampIndex];
		rampValue = ((usqInt) (rampValue & colorMask)) >> colorShift;
		while ((x < lastPixel)
		 && (lastLength < length2)) {

			/* Try to copy the current value more than once */
			while ((x < lastPixel)
			 && ((((ds / 65536) * (ds / 65536)) + ((dt / 65536) * (dt / 65536))) <= nextLength)) {
				index = ((usqInt) x) >> baseShift;
				spanBuffer[index] = ((spanBuffer[index]) + rampValue);
				x += aaLevel;
				ds += ((sqInt)((usqInt)(dsX) << colorShift));
				dt += ((sqInt)((usqInt)(dtX) << colorShift));
			}
			lastLength = ((ds / 65536) * (ds / 65536)) + ((dt / 65536) * (dt / 65536));
			while (lastLength > nextLength) {
				rampIndex += 1;
				rampValue = (((int *) ramp))[rampIndex];
				rampValue = ((usqInt) (rampValue & colorMask)) >> colorShift;
				nextLength = (rampIndex + 1) * (rampIndex + 1);
			}
		}
	}
	if ((x < rightX)
	 && (lastLength < length2)) {
		/* begin aaColorMaskGet */
		colorMask = workBuffer[GWAAColorMask];
		/* begin aaColorShiftGet */
		colorShift = workBuffer[GWAAColorShift];
		rampValue = (((int *) ramp))[rampIndex];
		rampValue = ((usqInt) (rampValue & colorMask)) >> colorShift;
		while ((x < rightX)
		 && (lastLength < length2)) {

			/* Try to copy the current value more than once */
			while ((x < rightX)
			 && ((((ds / 65536) * (ds / 65536)) + ((dt / 65536) * (dt / 65536))) <= nextLength)) {
				index = ((usqInt) x) >> baseShift;
				spanBuffer[index] = ((spanBuffer[index]) + rampValue);
				x += 1;
				ds += dsX;
				dt += dtX;
			}
			lastLength = ((ds / 65536) * (ds / 65536)) + ((dt / 65536) * (dt / 65536));
			while (lastLength > nextLength) {
				rampIndex += 1;
				rampValue = (((int *) ramp))[rampIndex];
				rampValue = ((usqInt) (rampValue & colorMask)) >> colorShift;
				nextLength = (rampIndex + 1) * (rampIndex + 1);
			}
		}
	}
	(((int *) deltaST))[0] = ds;
	(((int *) deltaST))[1] = dt;
	return x;
}


/*	Part 2b) Compute the increasing part of the ramp */

	/* BalloonEnginePlugin>>#fillRadialIncreasing:ramp:deltaST:dsX:dtX:from:to: */
static sqInt
fillRadialIncreasingrampdeltaSTdsXdtXfromto(sqInt fill, sqInt ramp, sqInt deltaST, sqInt dsX, sqInt dtX, sqInt leftX, sqInt rightX)
{
    int ds;
    int dt;
    sqInt lastLength;
    sqInt length2;
    sqInt nextLength;
    sqInt rampIndex;
    sqInt rampSize;
    sqInt rampValue;
    sqInt x;
    sqInt x1;

	ds = (((int*) deltaST))[0];
	dt = (((int*) deltaST))[1];
	rampIndex = accurateLengthOfwith(ds / 65536, dt / 65536);
	rampValue = (((int *) ramp))[rampIndex];
	/* begin obj:at: */
	rampSize = objBuffer[fill + GFRampLength];

	/* This is the upper bound */
	length2 = (rampSize - 1) * (rampSize - 1);
	nextLength = (rampIndex + 1) * (rampIndex + 1);
	lastLength = ((ds / 65536) * (ds / 65536)) + ((dt / 65536) * (dt / 65536));
	x = leftX;
	x1 = rightX;
	while ((x < x1)
	 && (lastLength < length2)) {

		/* Try to copy the current value more than once */
		while ((x < x1)
		 && ((((ds / 65536) * (ds / 65536)) + ((dt / 65536) * (dt / 65536))) <= nextLength)) {
			spanBuffer[x] = rampValue;
			x += 1;
			ds += dsX;
			dt += dtX;
		}
		lastLength = ((ds / 65536) * (ds / 65536)) + ((dt / 65536) * (dt / 65536));
		while (lastLength > nextLength) {
			rampIndex += 1;
			rampValue = (((int *) ramp))[rampIndex];
			nextLength = (rampIndex + 1) * (rampIndex + 1);
		}
	}
	(((int *) deltaST))[0] = ds;
	(((int *) deltaST))[1] = dt;
	return x;
}


/*	Return true if fillEntry1 should be drawn before fillEntry2 */

	/* BalloonEngineBase>>#fillSorts:before: */
static sqInt
fillSortsbefore(sqInt fillEntry1, sqInt fillEntry2)
{
    sqInt diff;


	/* First check the depth value */
	diff = (workBuffer[(workBuffer[GWBufferTop]) + (fillEntry1 + 1)]) - (workBuffer[(workBuffer[GWBufferTop]) + (fillEntry2 + 1)]);
	if (!(diff == 0)) {
		return diff > 0;
	}
	return (((unsigned) (workBuffer[(workBuffer[GWBufferTop]) + fillEntry1]))) < (((unsigned) (workBuffer[(workBuffer[GWBufferTop]) + fillEntry2])));
}


/*	Fill the span buffer from leftX to rightX with the given fill.
	Clip before performing any operations. Return true if the fill must
	be handled by some Smalltalk code. */

	/* BalloonEngineBase>>#fillSpan:from:to: */
static sqInt
fillSpanfromto(unsigned int fill, sqInt leftX, sqInt rightX)
{
    sqInt type;
    sqInt x0;
    sqInt x01;
    sqInt x1;
    sqInt x11;

	if (fill == 0) {
		return 0;
	}
	if (leftX < (workBuffer[GWSpanEndAA])) {
		x0 = workBuffer[GWSpanEndAA];
	}
	else {
		x0 = leftX;
	}
	if (rightX > (((sqInt)((usqInt)((workBuffer[GWSpanSize])) << (workBuffer[GWAAShift]))))) {
		x1 = ((sqInt)((usqInt)((workBuffer[GWSpanSize])) << (workBuffer[GWAAShift])));
	}
	else {
		x1 = rightX;
	}
	if (x0 < (workBuffer[GWFillMinX])) {
		/* begin fillMinXGet */
		x0 = workBuffer[GWFillMinX];
	}
	if (x1 > (workBuffer[GWFillMaxX])) {
		/* begin fillMaxXGet */
		x1 = workBuffer[GWFillMaxX];
	}
	if (x0 < (workBuffer[GWSpanStart])) {
		workBuffer[GWSpanStart] = x0;
	}
	if (x1 > (workBuffer[GWSpanEnd])) {
		workBuffer[GWSpanEnd] = x1;
	}
	if (x1 > (workBuffer[GWSpanEndAA])) {
		workBuffer[GWSpanEndAA] = x1;
	}
	if (x0 >= x1) {
		return 0;
	}
	if ((fill & 0xFF000000U) != 0) {
		/* begin fillColorSpan:from:to: */
		if (!((workBuffer[GWAALevel]) == 1)) {
			fillColorSpanAAx0x1(fill, x0, x1);
			goto l3;
		}
		x01 = x0;

		/* Unroll the inner loop four times, since we're only storing data. */
		x11 = x1;
		while ((x01 + 4) < x11) {
			spanBuffer[x01] = fill;
			spanBuffer[x01 + 1] = fill;
			spanBuffer[x01 + 2] = fill;
			spanBuffer[x01 + 3] = fill;
			x01 += 4;
		}
		while (x01 < x11) {
			spanBuffer[x01] = fill;
			x01 += 1;
		}
	l3:	/* end fillColorSpan:from:to: */;
	}
	else {

		/* Store the values for the dispatch */
		workBuffer[GWLastExportedFill] = fill;
		workBuffer[GWLastExportedLeftX] = x0;
		workBuffer[GWLastExportedRightX] = x1;
		type = ((usqInt) (((objBuffer[fill + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveFillMask)) >> 8;
		if (type <= 1) {
			return 1;
		}
		switch (type) {
		case 0:
		case 1:
			errorWrongIndex();
			break;
		case 2:
			fillLinearGradientfromtoat(workBuffer[GWLastExportedFill], workBuffer[GWLastExportedLeftX], workBuffer[GWLastExportedRightX], workBuffer[GWCurrentY]);
			break;
		case 3:
			fillRadialGradientfromtoat(workBuffer[GWLastExportedFill], workBuffer[GWLastExportedLeftX], workBuffer[GWLastExportedRightX], workBuffer[GWCurrentY]);
			break;
		case 4:
		case 5:
			fillBitmapSpanfromtoat(workBuffer[GWLastExportedFill], workBuffer[GWLastExportedLeftX], workBuffer[GWLastExportedRightX], workBuffer[GWCurrentY]);
			break;
		}
	}
	return 0;
}

	/* BalloonEngineBase>>#fillTypeOf: */
static sqInt
fillTypeOf(sqInt fill)
{
	return ((usqInt) (((objBuffer[fill + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveFillMask)) >> 8;
}

	/* BalloonEngineBase>>#findNextAETEdgeFrom: */
static sqInt
findNextAETEdgeFrom(sqInt leftEdge)
{
    sqInt depth;
    int rightEdge;
    sqInt value;

	/* begin edgeZValueOf: */
	depth = objBuffer[leftEdge + GEZValue];
	while ((workBuffer[GWAETStart]) < (workBuffer[GWAETUsed])) {
		rightEdge = aetBuffer[workBuffer[GWAETStart]];
		if ((objBuffer[rightEdge + GEZValue]) >= depth) {
			return rightEdge;
		}
		/* begin aetStartPut: */
		value = (workBuffer[GWAETStart]) + 1;
		workBuffer[GWAETStart] = value;
	}
	return null;
}


/*	Check the global edge table for any entries that cannot be handled by the
	engine itself.
	If there are any, return true. Otherwise, initialize the the edge and add
	it to the AET
 */

	/* BalloonEngineBase>>#findNextExternalEntryFromGET */
static sqInt
findNextExternalEntryFromGET(void)
{
    int edge;
    sqInt type;
    sqInt yValue;

	/* begin currentYGet */
	yValue = workBuffer[GWCurrentY];
	while ((workBuffer[GWGETStart]) < (workBuffer[GWGETUsed])) {
		edge = getBuffer[workBuffer[GWGETStart]];
		if ((objBuffer[edge + GEYValue]) > yValue) {
			return 0;
		}
		type = (objBuffer[edge + GEObjectType]) & GEPrimitiveTypeMask;
		if ((type & GEPrimitiveWideMask) == GEPrimitiveEdge) {
			return 1;
		}
		if (!(needAvailableSpace(1))) {
			return 0;
		}
		switch (type) {
		case 0:
		case 1:
		case 2:
		case 3:
			errorWrongIndex();
			break;
		case 4:
			stepToFirstLineInat(getBuffer[workBuffer[GWGETStart]], workBuffer[GWCurrentY]);
			break;
		case 5:
			stepToFirstWideLineInat(getBuffer[workBuffer[GWGETStart]], workBuffer[GWCurrentY]);
			break;
		case 6:
			stepToFirstBezierInat(getBuffer[workBuffer[GWGETStart]], workBuffer[GWCurrentY]);
			break;
		case 7:
			stepToFirstWideBezierInat(getBuffer[workBuffer[GWGETStart]], workBuffer[GWCurrentY]);
			break;
		}
		insertEdgeIntoAET(edge);
		/* begin getStartPut: */
		workBuffer[GWGETStart] = ((workBuffer[GWGETStart]) + 1);
	}
	return 0;
}


/*	Scan the active edge table. If there is any fill that cannot be handled by
	the engine itself, return true. Otherwise handle the fills and return
	false. 
 */
/*	self currentYGet >= 680 ifTrue:[
	self printAET.
	self halt.
	].
 */

	/* BalloonEngineBase>>#findNextExternalFillFromAET */
static sqInt
findNextExternalFillFromAET(void)
{
    sqInt fill;
    sqInt fill1;
    sqInt index;
    sqInt index1;
    sqInt index11;
    sqInt index2;
    sqInt index21;
    sqInt index3;
    sqInt index31;
    sqInt index4;
    sqInt index41;
    sqInt index5;
    int leftEdge;
    sqInt leftX;
    int rightEdge;
    sqInt rightX;
    sqInt someIntegerValue;
    sqInt someIntegerValue1;
    sqInt someIntegerValue11;
    sqInt someIntegerValue2;
    sqInt startX;
    sqInt startX1;
    sqInt stopX;
    sqInt stopX1;
    sqInt value;

	leftX = (rightX = workBuffer[GWFillMaxX]);
	while ((workBuffer[GWAETStart]) < (workBuffer[GWAETUsed])) {

		/* TODO: We should check if leftX from last operation
		   is  greater than leftX from next edge.
		   Currently, we rely here on spanEndAA
		   from the span buffer fill. */
		leftEdge = (rightEdge = aetBuffer[workBuffer[GWAETStart]]);
		leftX = (rightX = objBuffer[leftEdge + GEXValue]);
		if (leftX >= (workBuffer[GWFillMaxX])) {
			return 0;
		}
		/* begin quickRemoveInvalidFillsAt: */
		if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
			goto l12;
		}
		while ((topRightX()) <= leftX) {
			hideFilldepth(topFill(), topDepth());
			if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
				goto l12;
			}
		}
	l12:	/* end quickRemoveInvalidFillsAt: */;
		if ((((objBuffer[leftEdge + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveWide) != 0) {
			toggleWideFillOf(leftEdge);
		}
		if (((objBuffer[leftEdge + GEObjectType]) & GEEdgeFillsInvalid) == 0) {
			toggleFillsOf(leftEdge);
			if (engineStopped) {
				return 0;
			}
		}
		/* begin aetStartPut: */
		value = (workBuffer[GWAETStart]) + 1;
		workBuffer[GWAETStart] = value;
		if ((workBuffer[GWAETStart]) < (workBuffer[GWAETUsed])) {
			rightEdge = aetBuffer[workBuffer[GWAETStart]];
			/* begin edgeXValueOf: */
			rightX = objBuffer[rightEdge + GEXValue];
			if (rightX >= (workBuffer[GWFillMinX])) {

				/* This is the visible portion */
				/* begin fillAllFrom:to: */
				if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
					fill = 0;
					goto l5;
				}
				else {
					/* begin stackFillValue: */
					index2 = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
					fill = workBuffer[(workBuffer[GWBufferTop]) + index2];
					goto l5;
				}
	l5:	/* end topFill */;
				startX = leftX;
				/* begin topRightX */
				if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
					stopX = 999999999;
					goto l6;
				}
				else {
					/* begin stackFillRightX: */
					index3 = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
					stopX = workBuffer[(workBuffer[GWBufferTop]) + (index3 + 2)];
					goto l6;
				}
	l6:	/* end topRightX */;
				while (stopX < rightX) {
					/* begin makeUnsignedFrom: */
					if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
						someIntegerValue = 0;
						goto l3;
					}
					else {
						/* begin stackFillValue: */
						index = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
						someIntegerValue = workBuffer[(workBuffer[GWBufferTop]) + index];
						goto l3;
					}
	l3:	/* end topFill */;
					fill = someIntegerValue;
					if (!(fill == 0)) {
						if (fillSpanfromto(fill, startX, stopX)) {
							goto l11;
						}
					}
					/* begin quickRemoveInvalidFillsAt: */
					if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
						goto l8;
					}
					while ((topRightX()) <= stopX) {
						hideFilldepth(topFill(), topDepth());
						if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
							goto l8;
						}
					}
	l8:	/* end quickRemoveInvalidFillsAt: */;
					startX = stopX;
					/* begin topRightX */
					if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
						stopX = 999999999;
						goto l4;
					}
					else {
						/* begin stackFillRightX: */
						index1 = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
						stopX = workBuffer[(workBuffer[GWBufferTop]) + (index1 + 2)];
						goto l4;
					}
	l4:	/* end topRightX */;
				}
				/* begin makeUnsignedFrom: */
				if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
					someIntegerValue1 = 0;
					goto l7;
				}
				else {
					/* begin stackFillValue: */
					index4 = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
					someIntegerValue1 = workBuffer[(workBuffer[GWBufferTop]) + index4];
					goto l7;
				}
	l7:	/* end topFill */;
				fill = someIntegerValue1;
				if (!(fill == 0)) {
					fillSpanfromto(fill, startX, rightX);
					goto l11;
				}
	l11:	/* end fillAllFrom:to: */;
			}
		}
	}
	if (rightX < (workBuffer[GWFillMaxX])) {
		/* begin fillAllFrom:to: */
		if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
			fill1 = 0;
			goto l14;
		}
		else {
			/* begin stackFillValue: */
			index21 = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
			fill1 = workBuffer[(workBuffer[GWBufferTop]) + index21];
			goto l14;
		}
	l14:	/* end topFill */;
		startX1 = rightX;
		/* begin topRightX */
		if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
			stopX1 = 999999999;
			goto l18;
		}
		else {
			/* begin stackFillRightX: */
			index31 = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
			stopX1 = workBuffer[(workBuffer[GWBufferTop]) + (index31 + 2)];
			goto l18;
		}
	l18:	/* end topRightX */;
		while (stopX1 < (workBuffer[GWFillMaxX])) {
			/* begin makeUnsignedFrom: */
			if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
				someIntegerValue2 = 0;
				goto l15;
			}
			else {
				/* begin stackFillValue: */
				index5 = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
				someIntegerValue2 = workBuffer[(workBuffer[GWBufferTop]) + index5];
				goto l15;
			}
	l15:	/* end topFill */;
			fill1 = someIntegerValue2;
			if (!(fill1 == 0)) {
				if (fillSpanfromto(fill1, startX1, stopX1)) {
					goto l21;
				}
			}
			/* begin quickRemoveInvalidFillsAt: */
			if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
				goto l17;
			}
			while ((topRightX()) <= stopX1) {
				hideFilldepth(topFill(), topDepth());
				if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
					goto l17;
				}
			}
	l17:	/* end quickRemoveInvalidFillsAt: */;
			startX1 = stopX1;
			/* begin topRightX */
			if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
				stopX1 = 999999999;
				goto l19;
			}
			else {
				/* begin stackFillRightX: */
				index11 = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
				stopX1 = workBuffer[(workBuffer[GWBufferTop]) + (index11 + 2)];
				goto l19;
			}
	l19:	/* end topRightX */;
		}
		/* begin makeUnsignedFrom: */
		if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
			someIntegerValue11 = 0;
			goto l13;
		}
		else {
			/* begin stackFillValue: */
			index41 = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
			someIntegerValue11 = workBuffer[(workBuffer[GWBufferTop]) + index41];
			goto l13;
		}
	l13:	/* end topFill */;
		fill1 = someIntegerValue11;
		if (!(fill1 == 0)) {
			fillSpanfromto(fill1, startX1, workBuffer[GWFillMaxX]);
			goto l21;
		}
	l21:	/* end fillAllFrom:to: */;
	}
	return 0;
}


/*	Check the active edge table for any entries that cannot be handled by the
	engine itself.
	If there are any, return true. Otherwise, step the the edge to the next y
	value. 
 */

	/* BalloonEngineBase>>#findNextExternalUpdateFromAET */
static sqInt
findNextExternalUpdateFromAET(void)
{
    sqInt count;
    int edge;
    sqInt type;
    sqInt value;

	while ((workBuffer[GWAETStart]) < (workBuffer[GWAETUsed])) {
		edge = aetBuffer[workBuffer[GWAETStart]];
		count = (objBuffer[edge + GENumLines]) - 1;
		if (count == 0) {

			/* Edge at end -- remove it */
			removeFirstAETEntry();
		}
		else {

			/* Store remaining lines back */
			/* begin edgeNumLinesOf:put: */
			objBuffer[edge + GENumLines] = count;
			type = (objBuffer[edge + GEObjectType]) & GEPrimitiveTypeMask;
			if ((type & GEPrimitiveWideMask) == GEPrimitiveEdge) {
				return 1;
			}
			switch (type) {
			case 0:
			case 1:
			case 2:
			case 3:
				errorWrongIndex();
				break;
			case 4:
				stepToNextLineInat(aetBuffer[workBuffer[GWAETStart]], workBuffer[GWCurrentY]);
				break;
			case 5:
				stepToNextWideLineInat(aetBuffer[workBuffer[GWAETStart]], workBuffer[GWCurrentY]);
				break;
			case 6:
				stepToNextBezierInat(aetBuffer[workBuffer[GWAETStart]], workBuffer[GWCurrentY]);
				break;
			case 7:
				stepToNextWideBezier();
				break;
			}
			resortFirstAETEntry();
			/* begin aetStartPut: */
			value = (workBuffer[GWAETStart]) + 1;
			workBuffer[GWAETStart] = value;
		}
	}
	return 0;
}

	/* BalloonEngineBase>>#findStackFill:depth: */
static sqInt
findStackFilldepth(sqInt fillIndex, sqInt depth)
{
    sqInt index;

	index = 0;
	while ((index < ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])))
	 && (((workBuffer[(workBuffer[GWBufferTop]) + index]) != fillIndex)
	 || ((workBuffer[(workBuffer[GWBufferTop]) + (index + 1)]) != depth))) {
		index += 3 /* stackFillEntryLength */;
	}
	if (index >= ((workBuffer[GWSize]) - (workBuffer[GWBufferTop]))) {
		return -1;
	}
	else {
		return index;
	}
}


/*	Return true if processing is finished */

	/* BalloonEngineBase>>#finishedProcessing */
static sqInt
finishedProcessing(void)
{
	return (workBuffer[GWState]) == GEStateCompleted;
}

	/* BalloonEngineBase>>#firstPointListGet */
static sqInt
firstPointListGet(void)
{
	return workBuffer[GWPointListFirst];
}

	/* BalloonEngineBase>>#firstPointListPut: */
static sqInt
firstPointListPut(sqInt value)
{
	return workBuffer[GWPointListFirst] = value;
}

	/* BalloonEngineBase>>#freeStackFillEntry */
static sqInt
freeStackFillEntry(void)
{
	/* begin wbStackPop: */
	workBuffer[GWBufferTop] = ((workBuffer[GWBufferTop]) + 3 /* stackFillEntryLength */);
	return 0;
}


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


/*	Return true if the edge at index i should sort before the edge at index j. */

	/* BalloonEngineBase>>#getSorts:before: */
static sqInt
getSortsbefore(sqInt edge1, sqInt edge2)
{
    sqInt diff;

	if (edge1 == edge2) {
		return 1;
	}
	diff = (objBuffer[edge1 + GEYValue]) - (objBuffer[edge2 + GEYValue]);
	if (!(diff == 0)) {
		return diff < 0;
	}
	diff = (objBuffer[edge1 + GEXValue]) - (objBuffer[edge2 + GEXValue]);
	return diff < 0;
}

	/* BalloonEngineBase>>#getStartGet */
static sqInt
getStartGet(void)
{
	return workBuffer[GWGETStart];
}

	/* BalloonEngineBase>>#getStartPut: */
static sqInt
getStartPut(sqInt value)
{
	return workBuffer[GWGETStart] = value;
}

	/* BalloonEngineBase>>#getUsedGet */
static sqInt
getUsedGet(void)
{
	return workBuffer[GWGETUsed];
}

	/* BalloonEngineBase>>#getUsedPut: */
static sqInt
getUsedPut(sqInt value)
{
	return workBuffer[GWGETUsed] = value;
}

	/* BalloonEnginePlugin>>#gradientRampLengthOf: */
static sqInt
gradientRampLengthOf(sqInt fill)
{
	return objBuffer[fill + GFRampLength];
}

	/* BalloonEnginePlugin>>#gradientRampLengthOf:put: */
static sqInt
gradientRampLengthOfput(sqInt fill, sqInt value)
{
	return objBuffer[fill + GFRampLength] = value;
}

	/* BalloonEnginePlugin>>#gradientRampOf: */
static int *
gradientRampOf(sqInt fill)
{
	return (objBuffer + fill) + GFRampOffset;
}

	/* BalloonEngineBase>>#hasColorTransform */
static sqInt
hasColorTransform(void)
{
	return (workBuffer[GWHasColorTransform]) != 0;
}

	/* BalloonEngineBase>>#hasColorTransformGet */
static sqInt
hasColorTransformGet(void)
{
	return workBuffer[GWHasColorTransform];
}

	/* BalloonEngineBase>>#hasColorTransformPut: */
static sqInt
hasColorTransformPut(sqInt value)
{
	return workBuffer[GWHasColorTransform] = value;
}

	/* BalloonEngineBase>>#hasEdgeTransform */
static sqInt
hasEdgeTransform(void)
{
	return (workBuffer[GWHasEdgeTransform]) != 0;
}

	/* BalloonEngineBase>>#hasEdgeTransformGet */
static sqInt
hasEdgeTransformGet(void)
{
	return workBuffer[GWHasEdgeTransform];
}

	/* BalloonEngineBase>>#hasEdgeTransformPut: */
static sqInt
hasEdgeTransformPut(sqInt value)
{
	return workBuffer[GWHasEdgeTransform] = value;
}


/*	Make the fill style with the given index invisible */

	/* BalloonEngineBase>>#hideFill:depth: */
static sqInt
hideFilldepth(sqInt fillIndex, sqInt depth)
{
    sqInt index;
    sqInt index1;
    sqInt index2;
    sqInt index3;
    sqInt newDepth;
    sqInt newRightX;
    sqInt newTop;
    sqInt newTopIndex;
    sqInt value;
    sqInt value1;
    sqInt value2;

	index = findStackFilldepth(fillIndex, depth);
	if (index == -1) {
		return 0;
	}
	if (index == 0) {
		/* begin freeStackFillEntry */
		workBuffer[GWBufferTop] = ((workBuffer[GWBufferTop]) + 3 /* stackFillEntryLength */);
		return 1;
	}
	/* begin stackFillValue:put: */
	workBuffer[(workBuffer[GWBufferTop]) + index] = (workBuffer[(workBuffer[GWBufferTop])]);
	/* begin stackFillDepth:put: */
	workBuffer[(workBuffer[GWBufferTop]) + (index + 1)] = (workBuffer[(workBuffer[GWBufferTop]) + (0 + 1)]);
	/* begin stackFillRightX:put: */
	workBuffer[(workBuffer[GWBufferTop]) + (index + 2)] = (workBuffer[(workBuffer[GWBufferTop]) + (0 + 2)]);
	/* begin freeStackFillEntry */
	workBuffer[GWBufferTop] = ((workBuffer[GWBufferTop]) + 3 /* stackFillEntryLength */);
	if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) <= 3 /* stackFillEntryLength */) {
		return 1;
	}
	newTopIndex = 0;
	index = 3 /* stackFillEntryLength */;
	while (index < ((workBuffer[GWSize]) - (workBuffer[GWBufferTop]))) {
		if (fillSortsbefore(index, newTopIndex)) {
			newTopIndex = index;
		}
		index += 3 /* stackFillEntryLength */;
	}
	if ((newTopIndex + 3 /* stackFillEntryLength */) == ((workBuffer[GWSize]) - (workBuffer[GWBufferTop]))) {
		return 1;
	}
	/* begin wbStackValue: */
	newTop = workBuffer[(workBuffer[GWBufferTop]) + newTopIndex];
	/* begin stackFillValue:put: */
	value = workBuffer[(workBuffer[GWBufferTop]) + (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */)];
	workBuffer[(workBuffer[GWBufferTop]) + newTopIndex] = value;
	/* begin stackFillValue:put: */
	index1 = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
	workBuffer[(workBuffer[GWBufferTop]) + index1] = newTop;
	/* begin wbStackValue: */
	newDepth = workBuffer[(workBuffer[GWBufferTop]) + (newTopIndex + 1)];
	/* begin stackFillDepth:put: */
	value1 = workBuffer[(workBuffer[GWBufferTop]) + ((((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */) + 1)];
	workBuffer[(workBuffer[GWBufferTop]) + (newTopIndex + 1)] = value1;
	/* begin stackFillDepth:put: */
	index2 = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
	workBuffer[(workBuffer[GWBufferTop]) + (index2 + 1)] = newDepth;
	/* begin wbStackValue: */
	newRightX = workBuffer[(workBuffer[GWBufferTop]) + (newTopIndex + 2)];
	/* begin stackFillRightX:put: */
	value2 = workBuffer[(workBuffer[GWBufferTop]) + ((((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */) + 2)];
	workBuffer[(workBuffer[GWBufferTop]) + (newTopIndex + 2)] = value2;
	/* begin stackFillRightX:put: */
	index3 = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
	workBuffer[(workBuffer[GWBufferTop]) + (index3 + 2)] = newRightX;
	return 1;
}

	/* BalloonEngineBase>>#incrementPoint:by: */
static sqInt
incrementPointby(int *point, sqInt delta)
{
	point[0] = ((point[0]) + delta);
	point[1] = ((point[1]) + delta);
	return 0;
}

	/* BalloonEngineBase>>#incrementStat:by: */
static sqInt
incrementStatby(sqInt statIndex, sqInt value)
{
	return workBuffer[statIndex] = ((workBuffer[statIndex]) + value);
}


/*	Find insertion point for the given edge in the AET */

	/* BalloonEngineBase>>#indexForInsertingIntoAET: */
static sqInt
indexForInsertingIntoAET(sqInt edge)
{
    sqInt index;
    sqInt initialX;

	/* begin edgeXValueOf: */
	initialX = objBuffer[edge + GEXValue];
	index = 0;
	while ((index < (workBuffer[GWAETUsed]))
	 && ((objBuffer[(aetBuffer[index]) + GEXValue]) < initialX)) {
		index += 1;
	}
	while ((index < (workBuffer[GWAETUsed]))
	 && (((objBuffer[(aetBuffer[index]) + GEXValue]) == initialX)
	 && (getSortsbefore(aetBuffer[index], edge)))) {
		index += 1;
	}
	return index;
}

	/* BalloonEngineBase>>#initColorTransform */
static sqInt
initColorTransform(void)
{
    float *transform;

	/* begin colorTransform */
	transform = ((float *) (workBuffer + GWColorTransform));
	transform[0] = (1.0f);
	transform[1] = (0.0f);
	transform[2] = (1.0f);
	transform[3] = (0.0f);
	transform[4] = (1.0f);
	transform[5] = (0.0f);
	transform[6] = (1.0f);
	transform[7] = (0.0f);
	/* begin hasColorTransformPut: */
	workBuffer[GWHasColorTransform] = 0;
	return 0;
}

	/* BalloonEngineBase>>#initEdgeTransform */
static sqInt
initEdgeTransform(void)
{
    float *transform;

	/* begin edgeTransform */
	transform = ((float *) (workBuffer + GWEdgeTransform));
	transform[0] = (1.0f);
	transform[1] = (0.0f);
	transform[2] = (0.0f);
	transform[3] = (0.0f);
	transform[4] = (1.0f);
	transform[5] = (0.0f);
	/* begin hasEdgeTransformPut: */
	workBuffer[GWHasEdgeTransform] = 0;
	return 0;
}

	/* BalloonEngineBase>>#initialiseModule */
EXPORT(sqInt)
initialiseModule(void)
{
	loadBBFn = ioLoadFunctionFrom("loadBitBltFrom", bbPluginName);
	copyBitsFn = ioLoadFunctionFrom("copyBitsFromtoat", bbPluginName);
	return (loadBBFn != 0)
	 && (copyBitsFn != 0);
}


/*	Initialization stuff that needs to be done before any processing can take
	place. 
 */
/*	Make sure aaLevel is initialized */

	/* BalloonEngineBase>>#initializeGETProcessing */
static sqInt
initializeGETProcessing(void)
{
    sqInt value;
    sqInt value1;
    sqInt value2;
    sqInt value3;
    sqInt value4;
    sqInt value5;
    sqInt value6;
    sqInt value7;

	setAALevel(workBuffer[GWAALevel]);
	if ((workBuffer[GWClipMinX]) < 0) {
		/* begin clipMinXPut: */
		workBuffer[GWClipMinX] = 0;
	}
	if ((workBuffer[GWClipMaxX]) > (workBuffer[GWSpanSize])) {
		/* begin clipMaxXPut: */
		value = workBuffer[GWSpanSize];
		workBuffer[GWClipMaxX] = value;
	}
	/* begin fillMinXPut: */
	value3 = ((sqInt)((usqInt)((workBuffer[GWClipMinX])) << (workBuffer[GWAAShift])));
	workBuffer[GWFillMinX] = value3;
	/* begin fillMinYPut: */
	value4 = ((sqInt)((usqInt)((workBuffer[GWClipMinY])) << (workBuffer[GWAAShift])));
	workBuffer[GWFillMinY] = value4;
	/* begin fillMaxXPut: */
	value5 = ((sqInt)((usqInt)((workBuffer[GWClipMaxX])) << (workBuffer[GWAAShift])));
	workBuffer[GWFillMaxX] = value5;
	/* begin fillMaxYPut: */
	value6 = ((sqInt)((usqInt)((workBuffer[GWClipMaxY])) << (workBuffer[GWAAShift])));
	workBuffer[GWFillMaxY] = value6;
	/* begin getUsedPut: */
	workBuffer[GWGETUsed] = 0;
	/* begin aetUsedPut: */
	workBuffer[GWAETUsed] = 0;
	getBuffer = objBuffer + objUsed;

	/* Create the global edge table */
	aetBuffer = objBuffer + objUsed;
	createGlobalEdgeTable();
	if (engineStopped) {
		return null;
	}
	if ((workBuffer[GWGETUsed]) == 0) {

		/* Nothing to do */
		/* begin currentYPut: */
		value1 = workBuffer[GWFillMaxY];
		workBuffer[GWCurrentY] = value1;
		return 0;
	}
	/* begin sortGlobalEdgeTable */
	quickSortGlobalEdgeTablefromto(getBuffer, 0, (workBuffer[GWGETUsed]) - 1);
	/* begin currentYPut: */
	value7 = objBuffer[(getBuffer[0]) + GEYValue];
	workBuffer[GWCurrentY] = value7;
	if ((workBuffer[GWCurrentY]) < (workBuffer[GWFillMinY])) {
		/* begin currentYPut: */
		value2 = workBuffer[GWFillMinY];
		workBuffer[GWCurrentY] = value2;
	}
	workBuffer[GWSpanStart] = 0;
	/* begin spanEndPut: */
	workBuffer[GWSpanEnd] = ((((sqInt)((usqInt)((workBuffer[GWSpanSize])) << (workBuffer[GWAAShift])))) - 1);
	clearSpanBuffer();
	return 0;
}


/*	Insert the edge with the given index from the global edge table into the
	active edge table.
	The edge has already been stepped to the initial yValue -- thus
	remainingLines and rasterX
	are both set.
 */

	/* BalloonEngineBase>>#insertEdgeIntoAET: */
static sqInt
insertEdgeIntoAET(sqInt edge)
{
    sqInt index;


	/* Check for the number of lines remaining */
	if ((objBuffer[edge + GENumLines]) <= 0) {
		return null;
	}

	/* And insert edge */
	index = indexForInsertingIntoAET(edge);
	insertToAETbeforeIndex(edge, index);
	return 0;
}


/*	Insert the given edge into the AET. */

	/* BalloonEngineBase>>#insertToAET:beforeIndex: */
static sqInt
insertToAETbeforeIndex(sqInt edge, sqInt index)
{
    sqInt i;
    sqInt value;


	/* Make sure we have space in the AET */
	if (!(needAvailableSpace(1))) {
		return null;
	}
	i = (workBuffer[GWAETUsed]) - 1;
	while (!(i < index)) {
		aetBuffer[i + 1] = (aetBuffer[i]);
		i -= 1;
	}
	aetBuffer[index] = edge;
	/* begin aetUsedPut: */
	value = (workBuffer[GWAETUsed]) + 1;
	workBuffer[GWAETUsed] = value;
	return 0;
}

	/* BalloonEnginePlugin>>#isBezier: */
static sqInt
isBezier(sqInt bezier)
{
	return (((objBuffer[bezier + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveWideMask) == GEPrimitiveBezier;
}

	/* BalloonEngineBase>>#isEdge: */
static sqInt
isEdge(sqInt edge)
{
    sqInt type;

	type = (objBuffer[edge + GEObjectType]) & GEPrimitiveTypeMask;
	if (type > GEPrimitiveEdgeMask) {
		return 0;
	}
	return (((objBuffer[edge + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveEdgeMask) != 0;
}

	/* BalloonEngineBase>>#isFillColor: */
static sqInt
isFillColor(sqInt fill)
{
	return (fill & 0xFF000000U) != 0;
}

	/* BalloonEnginePlugin>>#isFillOkay: */
static sqInt
isFillOkay(sqInt fill)
{
	return (fill == 0)
	 || (((fill & 0xFF000000U) != 0)
	 || (((fill >= 0)
	 && (fill < objUsed))
	 && (((fill & 0xFF000000U) != 0)
	 || ((((objBuffer[fill + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveFillMask) != 0))));
}

	/* BalloonEngineBase>>#isFill: */
static sqInt
isFill(sqInt fill)
{
	return ((fill & 0xFF000000U) != 0)
	 || ((((objBuffer[fill + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveFillMask) != 0);
}

	/* BalloonEnginePlugin>>#isLine: */
static sqInt
isLine(sqInt line)
{
	return (((objBuffer[line + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveWideMask) == GEPrimitiveLine;
}

	/* BalloonEngineBase>>#isObject: */
static sqInt
isObject(sqInt obj)
{
	return (obj >= 0)
	 && (obj < objUsed);
}

	/* BalloonEngineBase>>#isRealFill: */
static sqInt
isRealFill(sqInt fill)
{
	return (((objBuffer[fill + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveFillMask) != 0;
}

	/* BalloonEngineBase>>#isStackEntry: */
static sqInt
isStackEntry(sqInt entry)
{
	return (entry >= (workBuffer[GWBufferTop]))
	 && (entry < (workBuffer[GWSize]));
}

	/* BalloonEngineBase>>#isStackIndex: */
static sqInt
isStackIndex(sqInt index)
{
	return (index >= 0)
	 && (index < ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])));
}

	/* BalloonEnginePlugin>>#isWideBezier: */
static sqInt
isWideBezier(sqInt bezier)
{
	return ((((objBuffer[bezier + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveWideMask) == GEPrimitiveBezier)
	 && ((((objBuffer[bezier + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveWide) != 0);
}

	/* BalloonEnginePlugin>>#isWideLine: */
static sqInt
isWideLine(sqInt line)
{
	return ((((objBuffer[line + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveWideMask) == GEPrimitiveLine)
	 && ((((objBuffer[line + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveWide) != 0);
}

	/* BalloonEngineBase>>#isWide: */
static sqInt
isWide(sqInt object)
{
	return (((objBuffer[object + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveWide) != 0;
}

	/* BalloonEngineBase>>#lastExportedEdgeGet */
static sqInt
lastExportedEdgeGet(void)
{
	return workBuffer[GWLastExportedEdge];
}

	/* BalloonEngineBase>>#lastExportedEdgePut: */
static sqInt
lastExportedEdgePut(sqInt value)
{
	return workBuffer[GWLastExportedEdge] = value;
}

	/* BalloonEngineBase>>#lastExportedFillGet */
static sqInt
lastExportedFillGet(void)
{
	return workBuffer[GWLastExportedFill];
}

	/* BalloonEngineBase>>#lastExportedFillPut: */
static sqInt
lastExportedFillPut(sqInt value)
{
	return workBuffer[GWLastExportedFill] = value;
}

	/* BalloonEngineBase>>#lastExportedLeftXGet */
static sqInt
lastExportedLeftXGet(void)
{
	return workBuffer[GWLastExportedLeftX];
}

	/* BalloonEngineBase>>#lastExportedLeftXPut: */
static sqInt
lastExportedLeftXPut(sqInt value)
{
	return workBuffer[GWLastExportedLeftX] = value;
}

	/* BalloonEngineBase>>#lastExportedRightXGet */
static sqInt
lastExportedRightXGet(void)
{
	return workBuffer[GWLastExportedRightX];
}

	/* BalloonEngineBase>>#lastExportedRightXPut: */
static sqInt
lastExportedRightXPut(sqInt value)
{
	return workBuffer[GWLastExportedRightX] = value;
}

	/* BalloonEnginePlugin>>#lineEndXOf: */
static sqInt
lineEndXOf(sqInt line)
{
	return objBuffer[line + GLEndX];
}

	/* BalloonEnginePlugin>>#lineEndXOf:put: */
static sqInt
lineEndXOfput(sqInt line, sqInt value)
{
	return objBuffer[line + GLEndX] = value;
}

	/* BalloonEnginePlugin>>#lineEndYOf: */
static sqInt
lineEndYOf(sqInt line)
{
	return objBuffer[line + GLEndY];
}

	/* BalloonEnginePlugin>>#lineEndYOf:put: */
static sqInt
lineEndYOfput(sqInt line, sqInt value)
{
	return objBuffer[line + GLEndY] = value;
}

	/* BalloonEnginePlugin>>#lineErrorAdjDownOf: */
static sqInt
lineErrorAdjDownOf(sqInt line)
{
	return objBuffer[line + GLErrorAdjDown];
}

	/* BalloonEnginePlugin>>#lineErrorAdjDownOf:put: */
static sqInt
lineErrorAdjDownOfput(sqInt line, sqInt value)
{
	return objBuffer[line + GLErrorAdjDown] = value;
}

	/* BalloonEnginePlugin>>#lineErrorAdjUpOf: */
static sqInt
lineErrorAdjUpOf(sqInt line)
{
	return objBuffer[line + GLErrorAdjUp];
}

	/* BalloonEnginePlugin>>#lineErrorAdjUpOf:put: */
static sqInt
lineErrorAdjUpOfput(sqInt line, sqInt value)
{
	return objBuffer[line + GLErrorAdjUp] = value;
}

	/* BalloonEnginePlugin>>#lineErrorOf: */
static sqInt
lineErrorOf(sqInt line)
{
	return objBuffer[line + GLError];
}

	/* BalloonEnginePlugin>>#lineErrorOf:put: */
static sqInt
lineErrorOfput(sqInt line, sqInt value)
{
	return objBuffer[line + GLError] = value;
}

	/* BalloonEnginePlugin>>#lineXDirectionOf: */
static sqInt
lineXDirectionOf(sqInt line)
{
	return objBuffer[line + GLXDirection];
}

	/* BalloonEnginePlugin>>#lineXDirectionOf:put: */
static sqInt
lineXDirectionOfput(sqInt line, sqInt value)
{
	return objBuffer[line + GLXDirection] = value;
}

	/* BalloonEnginePlugin>>#lineXIncrementOf: */
static sqInt
lineXIncrementOf(sqInt line)
{
	return objBuffer[line + GLXIncrement];
}

	/* BalloonEnginePlugin>>#lineXIncrementOf:put: */
static sqInt
lineXIncrementOfput(sqInt line, sqInt value)
{
	return objBuffer[line + GLXIncrement] = value;
}

	/* BalloonEnginePlugin>>#lineYDirectionOf: */
static sqInt
lineYDirectionOf(sqInt line)
{
	return objBuffer[line + GLYDirection];
}

	/* BalloonEnginePlugin>>#lineYDirectionOf:put: */
static sqInt
lineYDirectionOfput(sqInt line, sqInt value)
{
	return objBuffer[line + GLYDirection] = value;
}


/*	Load and subdivide the bezier curve from point1/point2/point3.
	If wideFlag is set then make sure the curve is monoton in X. */

	/* BalloonEnginePlugin>>#loadAndSubdivideBezierFrom:via:to:isWide: */
static sqInt
loadAndSubdivideBezierFromviatoisWide(int *point1, int *point2, int *point3, sqInt wideFlag)
{
    sqInt bz1;
    sqInt bz2;
    sqInt index;
    sqInt index1;
    sqInt index2;
    sqInt index3;
    sqInt index4;
    sqInt index5;
    sqInt index6;
    sqInt index7;
    sqInt index8;

	/* begin allocateBezierStackEntry */
	if (!(needAvailableSpace(6))) {
		goto l8;
	}
	/* begin wbTopPut: */
	workBuffer[GWBufferTop] = ((workBuffer[GWBufferTop]) - 6);
	l8:	/* end wbStackPush: */;
	bz1 = (workBuffer[GWSize]) - (workBuffer[GWBufferTop]);
	if (engineStopped) {
		return 0;
	}
	/* begin wbStackValue:put: */
	index3 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - bz1);
	workBuffer[(workBuffer[GWBufferTop]) + index3] = (point1[0]);
	/* begin wbStackValue:put: */
	index4 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - bz1) + 1;
	workBuffer[(workBuffer[GWBufferTop]) + index4] = (point1[1]);
	/* begin wbStackValue:put: */
	index5 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - bz1) + 2;
	workBuffer[(workBuffer[GWBufferTop]) + index5] = (point2[0]);
	/* begin wbStackValue:put: */
	index6 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - bz1) + 3;
	workBuffer[(workBuffer[GWBufferTop]) + index6] = (point2[1]);
	/* begin wbStackValue:put: */
	index7 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - bz1) + 4;
	workBuffer[(workBuffer[GWBufferTop]) + index7] = (point3[0]);
	/* begin wbStackValue:put: */
	index8 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - bz1) + 5;
	workBuffer[(workBuffer[GWBufferTop]) + index8] = (point3[1]);
	index2 = (bz2 = subdivideToBeMonotoninX(bz1, wideFlag));
	for (index = bz1; index <= bz2; index += 6) {
		index1 = subdivideBezierFrom(index);
		if (index1 > index2) {
			index2 = index1;
		}
		if (engineStopped) {
			return 0;
		}
	}
	return index2 / 6;
}

	/* BalloonEnginePlugin>>#loadArrayPolygon:nPoints:fill:lineWidth:lineFill: */
static sqInt
loadArrayPolygonnPointsfilllineWidthlineFill(sqInt points, sqInt nPoints, sqInt fillIndex, sqInt lineWidth, sqInt lineFill)
{
    sqInt i;
    int *point;
    int *point1;
    int *point2;
    int *point3;
    float *transform;
    float *transform1;
    float *transform2;
    float *transform3;
    sqInt x;
    int x0;
    int x1;
    sqInt x11;
    sqInt x2;
    sqInt x3;
    double xValue;
    double xValue1;
    double xValue2;
    double xValue3;
    sqInt y;
    int y0;
    int y1;
    sqInt y11;
    sqInt y2;
    sqInt y3;
    double yValue;
    double yValue1;
    double yValue2;
    double yValue3;

	loadPointfrom(((int *) (workBuffer + GWPoint1)), fetchPointerofObject(0, points));
	if (failed()) {
		return null;
	}
	x0 = (((int *) (workBuffer + GWPoint1)))[0];
	y0 = (((int *) (workBuffer + GWPoint1)))[1];
	for (i = 1; i < nPoints; i += 1) {
		loadPointfrom(((int *) (workBuffer + GWPoint1)), fetchPointerofObject(i, points));
		if (failed()) {
			return null;
		}
		x1 = (((int *) (workBuffer + GWPoint1)))[0];
		y1 = (((int *) (workBuffer + GWPoint1)))[1];
		(((int *) (workBuffer + GWPoint1)))[0] = x0;
		(((int *) (workBuffer + GWPoint1)))[1] = y0;
		(((int *) (workBuffer + GWPoint2)))[0] = x1;
		(((int *) (workBuffer + GWPoint2)))[1] = y1;
		/* begin transformPoints: */
		if (2 > 0) {
			/* begin transformPoint: */
			point = ((int *) (workBuffer + GWPoint1));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue = ((double) ((((int *) point))[0]) );
				yValue = ((double) ((((int *) point))[1]) );
				/* begin edgeTransform */
				transform = ((float *) (workBuffer + GWEdgeTransform));
				x = ((sqInt)(((((transform[0]) * xValue) + ((transform[1]) * yValue)) + (transform[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y = ((sqInt)(((((transform[3]) * xValue) + ((transform[4]) * yValue)) + (transform[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point))[0] = x;
				(((int *) point))[1] = y;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point[0] = (((point[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point[1] = (((point[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		if (2 > 1) {
			/* begin transformPoint: */
			point1 = ((int *) (workBuffer + GWPoint2));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue1 = ((double) ((((int *) point1))[0]) );
				yValue1 = ((double) ((((int *) point1))[1]) );
				/* begin edgeTransform */
				transform1 = ((float *) (workBuffer + GWEdgeTransform));
				x11 = ((sqInt)(((((transform1[0]) * xValue1) + ((transform1[1]) * yValue1)) + (transform1[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y11 = ((sqInt)(((((transform1[3]) * xValue1) + ((transform1[4]) * yValue1)) + (transform1[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point1))[0] = x11;
				(((int *) point1))[1] = y11;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point1[0] = (((point1[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point1[1] = (((point1[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		if (2 > 2) {
			/* begin transformPoint: */
			point2 = ((int *) (workBuffer + GWPoint3));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue2 = ((double) ((((int *) point2))[0]) );
				yValue2 = ((double) ((((int *) point2))[1]) );
				/* begin edgeTransform */
				transform2 = ((float *) (workBuffer + GWEdgeTransform));
				x2 = ((sqInt)(((((transform2[0]) * xValue2) + ((transform2[1]) * yValue2)) + (transform2[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y2 = ((sqInt)(((((transform2[3]) * xValue2) + ((transform2[4]) * yValue2)) + (transform2[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point2))[0] = x2;
				(((int *) point2))[1] = y2;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point2[0] = (((point2[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point2[1] = (((point2[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		if (2 > 3) {
			/* begin transformPoint: */
			point3 = ((int *) (workBuffer + GWPoint4));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue3 = ((double) ((((int *) point3))[0]) );
				yValue3 = ((double) ((((int *) point3))[1]) );
				/* begin edgeTransform */
				transform3 = ((float *) (workBuffer + GWEdgeTransform));
				x3 = ((sqInt)(((((transform3[0]) * xValue3) + ((transform3[1]) * yValue3)) + (transform3[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y3 = ((sqInt)(((((transform3[3]) * xValue3) + ((transform3[4]) * yValue3)) + (transform3[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point3))[0] = x3;
				(((int *) point3))[1] = y3;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point3[0] = (((point3[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point3[1] = (((point3[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		loadWideLinefromtolineFillleftFillrightFill(lineWidth, ((int *) (workBuffer + GWPoint1)), ((int *) (workBuffer + GWPoint2)), lineFill, fillIndex, 0);
		if (engineStopped) {
			return null;
		}
		x0 = x1;
		y0 = y1;
	}
	return 0;
}

	/* BalloonEnginePlugin>>#loadArrayShape:nSegments:fill:lineWidth:lineFill: */
static sqInt
loadArrayShapenSegmentsfilllineWidthlineFill(sqInt points, sqInt nSegments, sqInt fillIndex, sqInt lineWidth, sqInt lineFill)
{
    sqInt i;
    int *point;
    int *point1;
    int *point2;
    int *point3;
    sqInt pointOop;
    sqInt segs;
    float *transform;
    float *transform1;
    float *transform2;
    float *transform3;
    sqInt x;
    int x0;
    int x1;
    sqInt x11;
    int x2;
    sqInt x21;
    sqInt x3;
    double xValue;
    double xValue1;
    double xValue2;
    double xValue3;
    sqInt y;
    int y0;
    int y1;
    sqInt y11;
    int y2;
    sqInt y21;
    sqInt y3;
    double yValue;
    double yValue1;
    double yValue2;
    double yValue3;

	for (i = 0; i < nSegments; i += 1) {
		pointOop = fetchPointerofObject(i * 3, points);
		loadPointfrom(((int *) (workBuffer + GWPoint1)), pointOop);
		pointOop = fetchPointerofObject((i * 3) + 1, points);
		loadPointfrom(((int *) (workBuffer + GWPoint2)), pointOop);
		pointOop = fetchPointerofObject((i * 3) + 2, points);
		loadPointfrom(((int *) (workBuffer + GWPoint3)), pointOop);
		if (failed()) {
			return null;
		}
		/* begin transformPoints: */
		if (3 > 0) {
			/* begin transformPoint: */
			point = ((int *) (workBuffer + GWPoint1));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue = ((double) ((((int *) point))[0]) );
				yValue = ((double) ((((int *) point))[1]) );
				/* begin edgeTransform */
				transform = ((float *) (workBuffer + GWEdgeTransform));
				x = ((sqInt)(((((transform[0]) * xValue) + ((transform[1]) * yValue)) + (transform[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y = ((sqInt)(((((transform[3]) * xValue) + ((transform[4]) * yValue)) + (transform[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point))[0] = x;
				(((int *) point))[1] = y;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point[0] = (((point[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point[1] = (((point[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		if (3 > 1) {
			/* begin transformPoint: */
			point1 = ((int *) (workBuffer + GWPoint2));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue1 = ((double) ((((int *) point1))[0]) );
				yValue1 = ((double) ((((int *) point1))[1]) );
				/* begin edgeTransform */
				transform1 = ((float *) (workBuffer + GWEdgeTransform));
				x11 = ((sqInt)(((((transform1[0]) * xValue1) + ((transform1[1]) * yValue1)) + (transform1[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y11 = ((sqInt)(((((transform1[3]) * xValue1) + ((transform1[4]) * yValue1)) + (transform1[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point1))[0] = x11;
				(((int *) point1))[1] = y11;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point1[0] = (((point1[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point1[1] = (((point1[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		if (3 > 2) {
			/* begin transformPoint: */
			point2 = ((int *) (workBuffer + GWPoint3));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue2 = ((double) ((((int *) point2))[0]) );
				yValue2 = ((double) ((((int *) point2))[1]) );
				/* begin edgeTransform */
				transform2 = ((float *) (workBuffer + GWEdgeTransform));
				x21 = ((sqInt)(((((transform2[0]) * xValue2) + ((transform2[1]) * yValue2)) + (transform2[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y21 = ((sqInt)(((((transform2[3]) * xValue2) + ((transform2[4]) * yValue2)) + (transform2[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point2))[0] = x21;
				(((int *) point2))[1] = y21;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point2[0] = (((point2[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point2[1] = (((point2[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		if (3 > 3) {
			/* begin transformPoint: */
			point3 = ((int *) (workBuffer + GWPoint4));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue3 = ((double) ((((int *) point3))[0]) );
				yValue3 = ((double) ((((int *) point3))[1]) );
				/* begin edgeTransform */
				transform3 = ((float *) (workBuffer + GWEdgeTransform));
				x3 = ((sqInt)(((((transform3[0]) * xValue3) + ((transform3[1]) * yValue3)) + (transform3[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y3 = ((sqInt)(((((transform3[3]) * xValue3) + ((transform3[4]) * yValue3)) + (transform3[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point3))[0] = x3;
				(((int *) point3))[1] = y3;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point3[0] = (((point3[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point3[1] = (((point3[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		x0 = (((int *) (workBuffer + GWPoint1)))[0];
		y0 = (((int *) (workBuffer + GWPoint1)))[1];
		x1 = (((int *) (workBuffer + GWPoint2)))[0];
		y1 = (((int *) (workBuffer + GWPoint2)))[1];
		x2 = (((int *) (workBuffer + GWPoint3)))[0];

		/* Check if we can use a line */
		y2 = (((int *) (workBuffer + GWPoint3)))[1];
		if (((x0 == y0)
		 && (x1 == y1))
		 || ((x1 == x2)
		 && (y1 == y2))) {
			loadWideLinefromtolineFillleftFillrightFill(lineWidth, ((int *) (workBuffer + GWPoint1)), ((int *) (workBuffer + GWPoint3)), lineFill, fillIndex, 0);
		}
		else {

			/* Need bezier */
			segs = loadAndSubdivideBezierFromviatoisWide(((int *) (workBuffer + GWPoint1)), ((int *) (workBuffer + GWPoint2)), ((int *) (workBuffer + GWPoint3)), (lineWidth != 0)
			 && (lineFill != 0));
			if (engineStopped) {
				return null;
			}
			loadWideBezierlineFillleftFillrightFilln(lineWidth, lineFill, fillIndex, 0, segs);
		}
		if (engineStopped) {
			return null;
		}
	}
	return 0;
}


/*	Load a transformation from the given array. */

	/* BalloonEngineBase>>#loadArrayTransformFrom:into:length: */
static sqInt
loadArrayTransformFromintolength(sqInt transformOop, float *destPtr, sqInt n)
{
    sqInt i;
    sqInt value;

	for (i = 0; i < n; i += 1) {
		value = fetchPointerofObject(i, transformOop);
		if (!((isIntegerObject(value))
			 || (isFloatObject(value)))) {
			return primitiveFail();
		}
		if (isIntegerObject(value)) {
			destPtr[i] = (((float) (((double) (integerValueOf(value)) ))));
		}
		else {
			destPtr[i] = (((float) (floatValueOf(value))));
		}
	}
	return 0;
}


/*	Initialize the bezier segment stored on the stack */

	/* BalloonEnginePlugin>>#loadBezier:segment:leftFill:rightFill:offset: */
static sqInt
loadBeziersegmentleftFillrightFilloffset(sqInt bezier, sqInt index, sqInt leftFillIndex, sqInt rightFillIndex, sqInt yOffset)
{
    sqInt index1;
    sqInt index2;
    sqInt index3;
    sqInt index4;
    sqInt index5;
    sqInt index6;
    sqInt value;
    sqInt value1;
    sqInt value10;
    sqInt value11;
    sqInt value12;
    sqInt value2;
    sqInt value3;
    sqInt value4;
    sqInt value5;
    sqInt value6;
    sqInt value7;
    sqInt value8;
    sqInt value9;

	if ((workBuffer[(workBuffer[GWBufferTop]) + ((((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 5)]) >= (workBuffer[(workBuffer[GWBufferTop]) + ((((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 1)])) {

		/* Top to bottom */
		/* begin edgeXValueOf:put: */
		index1 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index);
		value = workBuffer[(workBuffer[GWBufferTop]) + index1];
		objBuffer[bezier + GEXValue] = value;
		/* begin edgeYValueOf:put: */
		value1 = (workBuffer[(workBuffer[GWBufferTop]) + ((((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 1)]) - yOffset;
		objBuffer[bezier + GEYValue] = value1;
		/* begin bezierViaXOf:put: */
		index2 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 2;
		value2 = workBuffer[(workBuffer[GWBufferTop]) + index2];
		objBuffer[bezier + GBViaX] = value2;
		/* begin bezierViaYOf:put: */
		value3 = (workBuffer[(workBuffer[GWBufferTop]) + ((((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 3)]) - yOffset;
		objBuffer[bezier + GBViaY] = value3;
		/* begin bezierEndXOf:put: */
		index3 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 4;
		value4 = workBuffer[(workBuffer[GWBufferTop]) + index3];
		objBuffer[bezier + GBEndX] = value4;
		/* begin bezierEndYOf:put: */
		value5 = (workBuffer[(workBuffer[GWBufferTop]) + ((((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 5)]) - yOffset;
		objBuffer[bezier + GBEndY] = value5;
	}
	else {
		/* begin edgeXValueOf:put: */
		index4 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 4;
		value6 = workBuffer[(workBuffer[GWBufferTop]) + index4];
		objBuffer[bezier + GEXValue] = value6;
		/* begin edgeYValueOf:put: */
		value7 = (workBuffer[(workBuffer[GWBufferTop]) + ((((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 5)]) - yOffset;
		objBuffer[bezier + GEYValue] = value7;
		/* begin bezierViaXOf:put: */
		index5 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 2;
		value8 = workBuffer[(workBuffer[GWBufferTop]) + index5];
		objBuffer[bezier + GBViaX] = value8;
		/* begin bezierViaYOf:put: */
		value9 = (workBuffer[(workBuffer[GWBufferTop]) + ((((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 3)]) - yOffset;
		objBuffer[bezier + GBViaY] = value9;
		/* begin bezierEndXOf:put: */
		index6 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index);
		value10 = workBuffer[(workBuffer[GWBufferTop]) + index6];
		objBuffer[bezier + GBEndX] = value10;
		/* begin bezierEndYOf:put: */
		value11 = (workBuffer[(workBuffer[GWBufferTop]) + ((((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 1)]) - yOffset;
		objBuffer[bezier + GBEndY] = value11;
	}
	/* begin edgeZValueOf:put: */
	value12 = workBuffer[GWCurrentZ];
	objBuffer[bezier + GEZValue] = value12;
	/* begin edgeLeftFillOf:put: */
	objBuffer[bezier + GEFillIndexLeft] = leftFillIndex;
	/* begin edgeRightFillOf:put: */
	objBuffer[bezier + GEFillIndexRight] = rightFillIndex;
	return 0;
}

	/* BalloonEngineBase>>#loadBitBltFrom: */
static sqInt
loadBitBltFrom(sqInt bbObj)
{
	if (loadBBFn == 0) {

		/* We need copyBits here so try to load it implicitly */
		if (!(initialiseModule())) {
			return 0;
		}
	}
	return ((sqInt (*)(sqInt))loadBBFn)(bbObj);
}


/*	Load the bitmap fill. */

	/* BalloonEnginePlugin>>#loadBitmapFill:colormap:tile:from:along:normal:xIndex: */
static sqInt
loadBitmapFillcolormaptilefromalongnormalxIndex(sqInt formOop, sqInt cmOop, sqInt tileFlag, int *point1, int *point2, int *point3, sqInt xIndex)
{
    sqInt bmBits;
    sqInt bmBitsSize;
    sqInt bmDepth;
    sqInt bmFill;
    sqInt bmHeight;
    sqInt bmRaster;
    sqInt bmWidth;
    int *cm;
    int *cmBits;
    sqInt cmSize;
    sqInt fill;
    sqInt fillSize;
    sqInt i;
    sqInt ppw;

	if (cmOop == (nilObject())) {
		cmSize = 0;
		cmBits = null;
	}
	else {
		if (!((fetchClassOf(cmOop)) == (classBitmap()))) {
			return primitiveFail();
		}
		cmSize = slotSizeOf(cmOop);
		cmBits = firstIndexableField(cmOop);
	}
	if (!(isPointers(formOop))) {
		return primitiveFail();
	}
	if ((slotSizeOf(formOop)) < 5) {
		return primitiveFail();
	}
	bmBits = fetchPointerofObject(0, formOop);
	if (!((fetchClassOf(bmBits)) == (classBitmap()))) {
		return primitiveFail();
	}
	bmBitsSize = slotSizeOf(bmBits);
	bmWidth = fetchIntegerofObject(1, formOop);
	bmHeight = fetchIntegerofObject(2, formOop);
	bmDepth = fetchIntegerofObject(3, formOop);
	if (failed()) {
		return null;
	}
	if (!((bmWidth >= 0)
		 && (bmHeight >= 0))) {
		return primitiveFail();
	}
	if (!((((((bmDepth == 32) || (bmDepth == 8)) || (bmDepth == 16)) || (bmDepth == 1)) || (bmDepth == 2)) || (bmDepth == 4))) {
		return primitiveFail();
	}
	if (!((cmSize == 0)
		 || (cmSize == (1U << bmDepth)))) {
		return primitiveFail();
	}
	ppw = 32 / bmDepth;
	bmRaster = (bmWidth + (ppw - 1)) / ppw;
	if (!(bmBitsSize == (bmRaster * bmHeight))) {
		return primitiveFail();
	}
	/* begin allocateBitmapFill:colormap: */
	fillSize = GBMBaseSize + cmSize;
	if (!(allocateObjEntry(fillSize))) {
		bmFill = 0;
		goto l11;
	}
	fill = objUsed;
	objUsed = fill + fillSize;
	/* begin obj:at:put: */
	objBuffer[fill + GEObjectType] = GEPrimitiveClippedBitmapFill;
	/* begin obj:at:put: */
	objBuffer[fill + GEObjectIndex] = 0;
	/* begin obj:at:put: */
	objBuffer[fill + GEObjectLength] = fillSize;
	cm = (objBuffer + fill) + GBColormapOffset;
	if ((workBuffer[GWHasColorTransform]) != 0) {
		for (i = 0; i < cmSize; i += 1) {
			cm[i] = (transformColor(cmBits[i]));
		}
	}
	else {
		for (i = 0; i < cmSize; i += 1) {
			cm[i] = (cmBits[i]);
		}
	}
	/* begin obj:at:put: */
	objBuffer[fill + GBColormapSize] = cmSize;
	bmFill = fill;
	l11:	/* end allocateBitmapFill:colormap: */;
	if (engineStopped) {
		return null;
	}
	/* begin bitmapWidthOf:put: */
	objBuffer[bmFill + GBBitmapWidth] = bmWidth;
	/* begin bitmapHeightOf:put: */
	objBuffer[bmFill + GBBitmapHeight] = bmHeight;
	/* begin bitmapDepthOf:put: */
	objBuffer[bmFill + GBBitmapDepth] = bmDepth;
	/* begin bitmapRasterOf:put: */
	objBuffer[bmFill + GBBitmapRaster] = bmRaster;
	/* begin bitmapSizeOf:put: */
	objBuffer[bmFill + GBBitmapSize] = bmBitsSize;
	/* begin bitmapTileFlagOf:put: */
	objBuffer[bmFill + GBTileFlag] = tileFlag;
	/* begin obj:at:put: */
	objBuffer[bmFill + GEObjectIndex] = xIndex;
	loadFillOrientationfromalongnormalwidthheight(bmFill, point1, point2, point3, bmWidth, bmHeight);
	return bmFill;
}


/*	Note: Assumes that the contents of formArray has been checked before */

	/* BalloonEnginePlugin>>#loadBitsFrom: */
static int *
loadBitsFrom(sqInt bmFill)
{
    sqInt bitsLen;
    sqInt bitsOop;
    sqInt formOop;
    sqInt xIndex;

	/* begin obj:at: */
	xIndex = objBuffer[bmFill + GEObjectIndex];
	if (xIndex > (slotSizeOf(formArray))) {
		return null;
	}
	formOop = fetchPointerofObject(xIndex, formArray);
	bitsOop = fetchPointerofObject(0, formOop);
	bitsLen = slotSizeOf(bitsOop);
	if (!(bitsLen == (objBuffer[bmFill + GBBitmapSize]))) {
		return null;
	}
	return firstIndexableField(bitsOop);
}


/*	Load a 2x3 transformation matrix from the given oop.
	Return true if the matrix is not nil, false otherwise */

	/* BalloonEngineBase>>#loadColorTransformFrom: */
static sqInt
loadColorTransformFrom(sqInt transformOop)
{
    sqInt okay;
    float *transform;

	/* begin colorTransform */
	transform = ((float *) (workBuffer + GWColorTransform));
	/* begin hasColorTransformPut: */
	workBuffer[GWHasColorTransform] = 0;
	okay = loadTransformFromintolength(transformOop, transform, 8);
	if (!okay) {
		return 0;
	}
	/* begin hasColorTransformPut: */
	workBuffer[GWHasColorTransform] = 1;
	transform[1] = ((transform[1]) * (256.0f));
	transform[3] = ((transform[3]) * (256.0f));
	transform[5] = ((transform[5]) * (256.0f));
	transform[7] = ((transform[7]) * (256.0f));
	return okay;
}


/*	Load the compressed segment identified by segment index */

	/* BalloonEnginePlugin>>#loadCompressedSegment:from:short:leftFill:rightFill:lineWidth:lineColor: */
static sqInt
loadCompressedSegmentfromshortleftFillrightFilllineWidthlineColor(sqInt segmentIndex, sqInt points, sqInt pointsShort, sqInt leftFill, sqInt rightFill, sqInt lineWidth, sqInt lineFill)
{
    sqInt index;
    int *point;
    int *point1;
    int *point11;
    int *point2;
    int *point21;
    int *point3;
    int *point31;
    int *point4;
    sqInt segs;
    float *transform;
    float *transform1;
    float *transform11;
    float *transform2;
    float *transform21;
    float *transform3;
    float *transform31;
    float *transform4;
    sqInt x;
    sqInt x0;
    sqInt x1;
    sqInt x11;
    sqInt x12;
    sqInt x2;
    sqInt x21;
    sqInt x22;
    sqInt x3;
    sqInt x31;
    sqInt x4;
    double xValue;
    double xValue1;
    double xValue11;
    double xValue2;
    double xValue21;
    double xValue3;
    double xValue31;
    double xValue4;
    sqInt y;
    sqInt y0;
    sqInt y1;
    sqInt y11;
    sqInt y12;
    sqInt y2;
    sqInt y21;
    sqInt y22;
    sqInt y3;
    sqInt y31;
    sqInt y4;
    double yValue;
    double yValue1;
    double yValue11;
    double yValue2;
    double yValue21;
    double yValue3;
    double yValue31;
    double yValue4;


	/* Check if have anything to do at all */
	if ((leftFill == rightFill)
	 && ((lineWidth == 0)
	 || (lineFill == 0))) {
		return null;
	}

	/* 3 points with x/y each */
	index = segmentIndex * 6;
	if (pointsShort) {

		/* Load short points */
		/* begin loadPointShortAt:from: */
		x0 = (((short *) points))[index];
		/* begin loadPointShortAt:from: */
		y0 = (((short *) points))[index + 1];
		/* begin loadPointShortAt:from: */
		x1 = (((short *) points))[index + 2];
		/* begin loadPointShortAt:from: */
		y1 = (((short *) points))[index + 3];
		/* begin loadPointShortAt:from: */
		x2 = (((short *) points))[index + 4];
		/* begin loadPointShortAt:from: */
		y2 = (((short *) points))[index + 5];
	}
	else {
		x0 = (((int *) points))[index];
		y0 = (((int *) points))[index + 1];
		x1 = (((int *) points))[index + 2];
		y1 = (((int *) points))[index + 3];
		x2 = (((int *) points))[index + 4];
		y2 = (((int *) points))[index + 5];
	}
	if (((x0 == x1)
	 && (y0 == y1))
	 || ((x1 == x2)
	 && (y1 == y2))) {

		/* We can use a line from x0/y0 to x2/y2 */
		if ((x0 == x2)
		 && (y0 == y2)) {
			return null;
		}
		(((int *) (workBuffer + GWPoint1)))[0] = x0;
		(((int *) (workBuffer + GWPoint1)))[1] = y0;
		(((int *) (workBuffer + GWPoint2)))[0] = x2;
		(((int *) (workBuffer + GWPoint2)))[1] = y2;
		/* begin transformPoints: */
		if (2 > 0) {
			/* begin transformPoint: */
			point = ((int *) (workBuffer + GWPoint1));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue = ((double) ((((int *) point))[0]) );
				yValue = ((double) ((((int *) point))[1]) );
				/* begin edgeTransform */
				transform = ((float *) (workBuffer + GWEdgeTransform));
				x = ((sqInt)(((((transform[0]) * xValue) + ((transform[1]) * yValue)) + (transform[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y = ((sqInt)(((((transform[3]) * xValue) + ((transform[4]) * yValue)) + (transform[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point))[0] = x;
				(((int *) point))[1] = y;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point[0] = (((point[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point[1] = (((point[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		if (2 > 1) {
			/* begin transformPoint: */
			point1 = ((int *) (workBuffer + GWPoint2));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue1 = ((double) ((((int *) point1))[0]) );
				yValue1 = ((double) ((((int *) point1))[1]) );
				/* begin edgeTransform */
				transform1 = ((float *) (workBuffer + GWEdgeTransform));
				x11 = ((sqInt)(((((transform1[0]) * xValue1) + ((transform1[1]) * yValue1)) + (transform1[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y11 = ((sqInt)(((((transform1[3]) * xValue1) + ((transform1[4]) * yValue1)) + (transform1[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point1))[0] = x11;
				(((int *) point1))[1] = y11;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point1[0] = (((point1[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point1[1] = (((point1[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		if (2 > 2) {
			/* begin transformPoint: */
			point2 = ((int *) (workBuffer + GWPoint3));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue2 = ((double) ((((int *) point2))[0]) );
				yValue2 = ((double) ((((int *) point2))[1]) );
				/* begin edgeTransform */
				transform2 = ((float *) (workBuffer + GWEdgeTransform));
				x21 = ((sqInt)(((((transform2[0]) * xValue2) + ((transform2[1]) * yValue2)) + (transform2[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y21 = ((sqInt)(((((transform2[3]) * xValue2) + ((transform2[4]) * yValue2)) + (transform2[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point2))[0] = x21;
				(((int *) point2))[1] = y21;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point2[0] = (((point2[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point2[1] = (((point2[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		if (2 > 3) {
			/* begin transformPoint: */
			point3 = ((int *) (workBuffer + GWPoint4));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue3 = ((double) ((((int *) point3))[0]) );
				yValue3 = ((double) ((((int *) point3))[1]) );
				/* begin edgeTransform */
				transform3 = ((float *) (workBuffer + GWEdgeTransform));
				x3 = ((sqInt)(((((transform3[0]) * xValue3) + ((transform3[1]) * yValue3)) + (transform3[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y3 = ((sqInt)(((((transform3[3]) * xValue3) + ((transform3[4]) * yValue3)) + (transform3[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point3))[0] = x3;
				(((int *) point3))[1] = y3;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point3[0] = (((point3[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point3[1] = (((point3[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		return loadWideLinefromtolineFillleftFillrightFill(lineWidth, ((int *) (workBuffer + GWPoint1)), ((int *) (workBuffer + GWPoint2)), lineFill, leftFill, rightFill);
	}
	(((int *) (workBuffer + GWPoint1)))[0] = x0;
	(((int *) (workBuffer + GWPoint1)))[1] = y0;
	(((int *) (workBuffer + GWPoint2)))[0] = x1;
	(((int *) (workBuffer + GWPoint2)))[1] = y1;
	(((int *) (workBuffer + GWPoint3)))[0] = x2;
	(((int *) (workBuffer + GWPoint3)))[1] = y2;
	/* begin transformPoints: */
	if (3 > 0) {
		/* begin transformPoint: */
		point4 = ((int *) (workBuffer + GWPoint1));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue4 = ((double) ((((int *) point4))[0]) );
			yValue4 = ((double) ((((int *) point4))[1]) );
			/* begin edgeTransform */
			transform4 = ((float *) (workBuffer + GWEdgeTransform));
			x4 = ((sqInt)(((((transform4[0]) * xValue4) + ((transform4[1]) * yValue4)) + (transform4[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y4 = ((sqInt)(((((transform4[3]) * xValue4) + ((transform4[4]) * yValue4)) + (transform4[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point4))[0] = x4;
			(((int *) point4))[1] = y4;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point4[0] = (((point4[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point4[1] = (((point4[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	if (3 > 1) {
		/* begin transformPoint: */
		point11 = ((int *) (workBuffer + GWPoint2));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue11 = ((double) ((((int *) point11))[0]) );
			yValue11 = ((double) ((((int *) point11))[1]) );
			/* begin edgeTransform */
			transform11 = ((float *) (workBuffer + GWEdgeTransform));
			x12 = ((sqInt)(((((transform11[0]) * xValue11) + ((transform11[1]) * yValue11)) + (transform11[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y12 = ((sqInt)(((((transform11[3]) * xValue11) + ((transform11[4]) * yValue11)) + (transform11[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point11))[0] = x12;
			(((int *) point11))[1] = y12;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point11[0] = (((point11[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point11[1] = (((point11[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	if (3 > 2) {
		/* begin transformPoint: */
		point21 = ((int *) (workBuffer + GWPoint3));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue21 = ((double) ((((int *) point21))[0]) );
			yValue21 = ((double) ((((int *) point21))[1]) );
			/* begin edgeTransform */
			transform21 = ((float *) (workBuffer + GWEdgeTransform));
			x22 = ((sqInt)(((((transform21[0]) * xValue21) + ((transform21[1]) * yValue21)) + (transform21[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y22 = ((sqInt)(((((transform21[3]) * xValue21) + ((transform21[4]) * yValue21)) + (transform21[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point21))[0] = x22;
			(((int *) point21))[1] = y22;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point21[0] = (((point21[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point21[1] = (((point21[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	if (3 > 3) {
		/* begin transformPoint: */
		point31 = ((int *) (workBuffer + GWPoint4));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue31 = ((double) ((((int *) point31))[0]) );
			yValue31 = ((double) ((((int *) point31))[1]) );
			/* begin edgeTransform */
			transform31 = ((float *) (workBuffer + GWEdgeTransform));
			x31 = ((sqInt)(((((transform31[0]) * xValue31) + ((transform31[1]) * yValue31)) + (transform31[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y31 = ((sqInt)(((((transform31[3]) * xValue31) + ((transform31[4]) * yValue31)) + (transform31[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point31))[0] = x31;
			(((int *) point31))[1] = y31;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point31[0] = (((point31[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point31[1] = (((point31[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	segs = loadAndSubdivideBezierFromviatoisWide(((int *) (workBuffer + GWPoint1)), ((int *) (workBuffer + GWPoint2)), ((int *) (workBuffer + GWPoint3)), (lineWidth != 0)
	 && (lineFill != 0));
	if (engineStopped) {
		return null;
	}
	loadWideBezierlineFillleftFillrightFilln(lineWidth, lineFill, leftFill, rightFill, segs);
	return 0;
}


/*	Load a compressed shape into the engine.
	WARNING: THIS METHOD NEEDS THE FULL FRAME SIZE!!!!
	 */

	/* BalloonEnginePlugin>>#loadCompressedShape:segments:leftFills:rightFills:lineWidths:lineFills:fillIndexList:pointShort: */
static sqInt
loadCompressedShapesegmentsleftFillsrightFillslineWidthslineFillsfillIndexListpointShort(int *points, sqInt nSegments, int *leftFills, int *rightFills, int *lineWidths, int *lineFills, int *fillIndexList, sqInt pointsShort)
{
    sqInt i;
    sqInt index;
    sqInt leftLength;
    sqInt leftRun;
    sqInt leftValue;
    sqInt lineFillLength;
    sqInt lineFillRun;
    sqInt lineFillValue;
    int *point;
    int *point1;
    int *point11;
    int *point2;
    int *point21;
    int *point3;
    int *point31;
    int *point4;
    sqInt rightLength;
    sqInt rightRun;
    sqInt rightValue;
    sqInt segs;
    float *transform;
    float *transform1;
    float *transform11;
    float *transform2;
    float *transform21;
    float *transform3;
    float *transform31;
    float *transform4;
    sqInt widthLength;
    sqInt widthRun;
    sqInt widthValue;
    sqInt x;
    sqInt x0;
    sqInt x1;
    sqInt x11;
    sqInt x12;
    sqInt x2;
    sqInt x21;
    sqInt x22;
    sqInt x3;
    sqInt x31;
    sqInt x4;
    double xValue;
    double xValue1;
    double xValue11;
    double xValue2;
    double xValue21;
    double xValue3;
    double xValue31;
    double xValue4;
    sqInt y;
    sqInt y0;
    sqInt y1;
    sqInt y11;
    sqInt y12;
    sqInt y2;
    sqInt y21;
    sqInt y22;
    sqInt y3;
    sqInt y31;
    sqInt y4;
    double yValue;
    double yValue1;
    double yValue11;
    double yValue2;
    double yValue21;
    double yValue3;
    double yValue31;
    double yValue4;

	if (nSegments == 0) {
		return 0;
	}
	leftRun = (rightRun = (widthRun = (lineFillRun = -1)));
	leftLength = (rightLength = (widthLength = (lineFillLength = 1)));
	leftValue = (rightValue = (widthValue = (lineFillValue = 0)));
	for (i = 1; i <= nSegments; i += 1) {

		/* Decrement current run length and load new stuff */
		if (((leftLength -= 1)) <= 0) {
			leftRun += 1;
			leftLength = ((usqInt) ((((int *) leftFills))[leftRun]) >> 16);
			leftValue = ((((int *) leftFills))[leftRun]) & 0xFFFF;
			if (!(leftValue == 0)) {
				leftValue = fillIndexList[leftValue - 1];
				leftValue = transformColor(leftValue);
				if (engineStopped) {
					return null;
				}
			}
		}
		if (((rightLength -= 1)) <= 0) {
			rightRun += 1;
			rightLength = ((usqInt) ((((int *) rightFills))[rightRun]) >> 16);
			rightValue = ((((int *) rightFills))[rightRun]) & 0xFFFF;
			if (!(rightValue == 0)) {
				rightValue = fillIndexList[rightValue - 1];
				rightValue = transformColor(rightValue);
			}
		}
		if (((widthLength -= 1)) <= 0) {
			widthRun += 1;
			widthLength = ((usqInt) ((((int *) lineWidths))[widthRun]) >> 16);
			widthValue = ((((int *) lineWidths))[widthRun]) & 0xFFFF;
			if (!(widthValue == 0)) {
				widthValue = transformWidth(widthValue);
			}
		}
		if (((lineFillLength -= 1)) <= 0) {
			lineFillRun += 1;
			lineFillLength = ((usqInt) ((((int *) lineFills))[lineFillRun]) >> 16);
			lineFillValue = ((((int *) lineFills))[lineFillRun]) & 0xFFFF;
			if (!(lineFillValue == 0)) {
				lineFillValue = fillIndexList[lineFillValue - 1];
			}
		}
		/* begin loadCompressedSegment:from:short:leftFill:rightFill:lineWidth:lineColor: */
		if ((leftValue == rightValue)
		 && ((widthValue == 0)
		 || (lineFillValue == 0))) {
			goto l15;
		}

		/* 3 points with x/y each */
		index = (i - 1) * 6;
		if (pointsShort) {

			/* Load short points */
			/* begin loadPointShortAt:from: */
			x0 = (((short *) points))[index];
			/* begin loadPointShortAt:from: */
			y0 = (((short *) points))[index + 1];
			/* begin loadPointShortAt:from: */
			x1 = (((short *) points))[index + 2];
			/* begin loadPointShortAt:from: */
			y1 = (((short *) points))[index + 3];
			/* begin loadPointShortAt:from: */
			x2 = (((short *) points))[index + 4];
			/* begin loadPointShortAt:from: */
			y2 = (((short *) points))[index + 5];
		}
		else {
			x0 = (((int *) points))[index];
			y0 = (((int *) points))[index + 1];
			x1 = (((int *) points))[index + 2];
			y1 = (((int *) points))[index + 3];
			x2 = (((int *) points))[index + 4];
			y2 = (((int *) points))[index + 5];
		}
		if (((x0 == x1)
		 && (y0 == y1))
		 || ((x1 == x2)
		 && (y1 == y2))) {

			/* We can use a line from x0/y0 to x2/y2 */
			if ((x0 == x2)
			 && (y0 == y2)) {
				goto l15;
			}
			(((int *) (workBuffer + GWPoint1)))[0] = x0;
			(((int *) (workBuffer + GWPoint1)))[1] = y0;
			(((int *) (workBuffer + GWPoint2)))[0] = x2;
			(((int *) (workBuffer + GWPoint2)))[1] = y2;
			/* begin transformPoints: */
			if (2 > 0) {
				/* begin transformPoint: */
				point = ((int *) (workBuffer + GWPoint1));
				if ((workBuffer[GWHasEdgeTransform]) != 0) {

					/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
					/* begin transformPoint:into: */
					xValue = ((double) ((((int *) point))[0]) );
					yValue = ((double) ((((int *) point))[1]) );
					/* begin edgeTransform */
					transform = ((float *) (workBuffer + GWEdgeTransform));
					x = ((sqInt)(((((transform[0]) * xValue) + ((transform[1]) * yValue)) + (transform[2])) * (((double) (workBuffer[GWAALevel]) ))));
					y = ((sqInt)(((((transform[3]) * xValue) + ((transform[4]) * yValue)) + (transform[5])) * (((double) (workBuffer[GWAALevel]) ))));
					(((int *) point))[0] = x;
					(((int *) point))[1] = y;
				}
				else {

					/* Multiply each component by aaLevel and add a half pixel */
					point[0] = (((point[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
					point[1] = (((point[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
				}
			}
			if (2 > 1) {
				/* begin transformPoint: */
				point1 = ((int *) (workBuffer + GWPoint2));
				if ((workBuffer[GWHasEdgeTransform]) != 0) {

					/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
					/* begin transformPoint:into: */
					xValue1 = ((double) ((((int *) point1))[0]) );
					yValue1 = ((double) ((((int *) point1))[1]) );
					/* begin edgeTransform */
					transform1 = ((float *) (workBuffer + GWEdgeTransform));
					x11 = ((sqInt)(((((transform1[0]) * xValue1) + ((transform1[1]) * yValue1)) + (transform1[2])) * (((double) (workBuffer[GWAALevel]) ))));
					y11 = ((sqInt)(((((transform1[3]) * xValue1) + ((transform1[4]) * yValue1)) + (transform1[5])) * (((double) (workBuffer[GWAALevel]) ))));
					(((int *) point1))[0] = x11;
					(((int *) point1))[1] = y11;
				}
				else {

					/* Multiply each component by aaLevel and add a half pixel */
					point1[0] = (((point1[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
					point1[1] = (((point1[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
				}
			}
			if (2 > 2) {
				/* begin transformPoint: */
				point2 = ((int *) (workBuffer + GWPoint3));
				if ((workBuffer[GWHasEdgeTransform]) != 0) {

					/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
					/* begin transformPoint:into: */
					xValue2 = ((double) ((((int *) point2))[0]) );
					yValue2 = ((double) ((((int *) point2))[1]) );
					/* begin edgeTransform */
					transform2 = ((float *) (workBuffer + GWEdgeTransform));
					x21 = ((sqInt)(((((transform2[0]) * xValue2) + ((transform2[1]) * yValue2)) + (transform2[2])) * (((double) (workBuffer[GWAALevel]) ))));
					y21 = ((sqInt)(((((transform2[3]) * xValue2) + ((transform2[4]) * yValue2)) + (transform2[5])) * (((double) (workBuffer[GWAALevel]) ))));
					(((int *) point2))[0] = x21;
					(((int *) point2))[1] = y21;
				}
				else {

					/* Multiply each component by aaLevel and add a half pixel */
					point2[0] = (((point2[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
					point2[1] = (((point2[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
				}
			}
			if (2 > 3) {
				/* begin transformPoint: */
				point3 = ((int *) (workBuffer + GWPoint4));
				if ((workBuffer[GWHasEdgeTransform]) != 0) {

					/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
					/* begin transformPoint:into: */
					xValue3 = ((double) ((((int *) point3))[0]) );
					yValue3 = ((double) ((((int *) point3))[1]) );
					/* begin edgeTransform */
					transform3 = ((float *) (workBuffer + GWEdgeTransform));
					x3 = ((sqInt)(((((transform3[0]) * xValue3) + ((transform3[1]) * yValue3)) + (transform3[2])) * (((double) (workBuffer[GWAALevel]) ))));
					y3 = ((sqInt)(((((transform3[3]) * xValue3) + ((transform3[4]) * yValue3)) + (transform3[5])) * (((double) (workBuffer[GWAALevel]) ))));
					(((int *) point3))[0] = x3;
					(((int *) point3))[1] = y3;
				}
				else {

					/* Multiply each component by aaLevel and add a half pixel */
					point3[0] = (((point3[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
					point3[1] = (((point3[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
				}
			}
			loadWideLinefromtolineFillleftFillrightFill(widthValue, ((int *) (workBuffer + GWPoint1)), ((int *) (workBuffer + GWPoint2)), lineFillValue, leftValue, rightValue);
			goto l15;
		}
		(((int *) (workBuffer + GWPoint1)))[0] = x0;
		(((int *) (workBuffer + GWPoint1)))[1] = y0;
		(((int *) (workBuffer + GWPoint2)))[0] = x1;
		(((int *) (workBuffer + GWPoint2)))[1] = y1;
		(((int *) (workBuffer + GWPoint3)))[0] = x2;
		(((int *) (workBuffer + GWPoint3)))[1] = y2;
		/* begin transformPoints: */
		if (3 > 0) {
			/* begin transformPoint: */
			point4 = ((int *) (workBuffer + GWPoint1));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue4 = ((double) ((((int *) point4))[0]) );
				yValue4 = ((double) ((((int *) point4))[1]) );
				/* begin edgeTransform */
				transform4 = ((float *) (workBuffer + GWEdgeTransform));
				x4 = ((sqInt)(((((transform4[0]) * xValue4) + ((transform4[1]) * yValue4)) + (transform4[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y4 = ((sqInt)(((((transform4[3]) * xValue4) + ((transform4[4]) * yValue4)) + (transform4[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point4))[0] = x4;
				(((int *) point4))[1] = y4;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point4[0] = (((point4[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point4[1] = (((point4[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		if (3 > 1) {
			/* begin transformPoint: */
			point11 = ((int *) (workBuffer + GWPoint2));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue11 = ((double) ((((int *) point11))[0]) );
				yValue11 = ((double) ((((int *) point11))[1]) );
				/* begin edgeTransform */
				transform11 = ((float *) (workBuffer + GWEdgeTransform));
				x12 = ((sqInt)(((((transform11[0]) * xValue11) + ((transform11[1]) * yValue11)) + (transform11[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y12 = ((sqInt)(((((transform11[3]) * xValue11) + ((transform11[4]) * yValue11)) + (transform11[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point11))[0] = x12;
				(((int *) point11))[1] = y12;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point11[0] = (((point11[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point11[1] = (((point11[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		if (3 > 2) {
			/* begin transformPoint: */
			point21 = ((int *) (workBuffer + GWPoint3));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue21 = ((double) ((((int *) point21))[0]) );
				yValue21 = ((double) ((((int *) point21))[1]) );
				/* begin edgeTransform */
				transform21 = ((float *) (workBuffer + GWEdgeTransform));
				x22 = ((sqInt)(((((transform21[0]) * xValue21) + ((transform21[1]) * yValue21)) + (transform21[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y22 = ((sqInt)(((((transform21[3]) * xValue21) + ((transform21[4]) * yValue21)) + (transform21[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point21))[0] = x22;
				(((int *) point21))[1] = y22;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point21[0] = (((point21[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point21[1] = (((point21[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		if (3 > 3) {
			/* begin transformPoint: */
			point31 = ((int *) (workBuffer + GWPoint4));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue31 = ((double) ((((int *) point31))[0]) );
				yValue31 = ((double) ((((int *) point31))[1]) );
				/* begin edgeTransform */
				transform31 = ((float *) (workBuffer + GWEdgeTransform));
				x31 = ((sqInt)(((((transform31[0]) * xValue31) + ((transform31[1]) * yValue31)) + (transform31[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y31 = ((sqInt)(((((transform31[3]) * xValue31) + ((transform31[4]) * yValue31)) + (transform31[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point31))[0] = x31;
				(((int *) point31))[1] = y31;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point31[0] = (((point31[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point31[1] = (((point31[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		segs = loadAndSubdivideBezierFromviatoisWide(((int *) (workBuffer + GWPoint1)), ((int *) (workBuffer + GWPoint2)), ((int *) (workBuffer + GWPoint3)), (widthValue != 0)
		 && (lineFillValue != 0));
		if (engineStopped) {
			goto l15;
		}
		loadWideBezierlineFillleftFillrightFilln(widthValue, lineFillValue, leftValue, rightValue, segs);
	l15:	/* end loadCompressedSegment:from:short:leftFill:rightFill:lineWidth:lineColor: */;
		if (engineStopped) {
			return null;
		}
	}
	return 0;
}

	/* BalloonEngineBase>>#loadEdgeStateFrom: */
static sqInt
loadEdgeStateFrom(sqInt edgeOop)
{
    sqInt edge;
    sqInt value;
    sqInt value1;
    sqInt value2;
    sqInt value3;

	/* begin lastExportedEdgeGet */
	edge = workBuffer[GWLastExportedEdge];
	if ((slotSizeOf(edgeOop)) < ETBalloonEdgeDataSize) {
		return null;
	}
	/* begin edgeXValueOf:put: */
	value = fetchIntegerofObject(ETXValueIndex, edgeOop);
	objBuffer[edge + GEXValue] = value;
	/* begin edgeYValueOf:put: */
	value1 = fetchIntegerofObject(ETYValueIndex, edgeOop);
	objBuffer[edge + GEYValue] = value1;
	/* begin edgeZValueOf:put: */
	value2 = fetchIntegerofObject(ETZValueIndex, edgeOop);
	objBuffer[edge + GEZValue] = value2;
	/* begin edgeNumLinesOf:put: */
	value3 = fetchIntegerofObject(ETLinesIndex, edgeOop);
	objBuffer[edge + GENumLines] = value3;
	return edge;
}


/*	Load a 2x3 transformation matrix from the given oop.
	Return true if the matrix is not nil, false otherwise */

	/* BalloonEngineBase>>#loadEdgeTransformFrom: */
static sqInt
loadEdgeTransformFrom(sqInt transformOop)
{
    sqInt okay;
    float *transform;

	/* begin hasEdgeTransformPut: */
	workBuffer[GWHasEdgeTransform] = 0;
	/* begin edgeTransform */
	transform = ((float *) (workBuffer + GWEdgeTransform));
	okay = loadTransformFromintolength(transformOop, transform, 6);
	if (failed()) {
		return null;
	}
	if (!okay) {
		return 0;
	}
	/* begin hasEdgeTransformPut: */
	workBuffer[GWHasEdgeTransform] = 1;
	transform[2] = (((float) ((transform[2]) + (((double) (workBuffer[GWDestOffsetX]) )))));
	transform[5] = (((float) ((transform[5]) + (((double) (workBuffer[GWDestOffsetY]) )))));
	return 1;
}


/*	Transform the points */

	/* BalloonEnginePlugin>>#loadFillOrientation:from:along:normal:width:height: */
static sqInt
loadFillOrientationfromalongnormalwidthheight(sqInt fill, int *point1, int *point2, int *point3, sqInt fillWidth, sqInt fillHeight)
{
    int dirX;
    int dirY;
    int dsLength2;
    sqInt dsX;
    sqInt dsY;
    int dtLength2;
    sqInt dtX;
    sqInt dtY;
    int nrmX;
    int nrmY;
    float *transform;
    float *transform1;
    float *transform2;
    sqInt x;
    sqInt x1;
    sqInt x2;
    double xValue;
    double xValue1;
    double xValue2;
    sqInt y;
    sqInt y1;
    sqInt y2;
    double yValue;
    double yValue1;
    double yValue2;

	point2[0] = ((point2[0]) + (point1[0]));
	point2[1] = ((point2[1]) + (point1[1]));
	point3[0] = ((point3[0]) + (point1[0]));
	point3[1] = ((point3[1]) + (point1[1]));
	/* begin transformPoint: */
	if ((workBuffer[GWHasEdgeTransform]) != 0) {

		/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
		/* begin transformPoint:into: */
		xValue = ((double) ((((int *) point1))[0]) );
		yValue = ((double) ((((int *) point1))[1]) );
		/* begin edgeTransform */
		transform = ((float *) (workBuffer + GWEdgeTransform));
		x = ((sqInt)(((((transform[0]) * xValue) + ((transform[1]) * yValue)) + (transform[2])) * (((double) (workBuffer[GWAALevel]) ))));
		y = ((sqInt)(((((transform[3]) * xValue) + ((transform[4]) * yValue)) + (transform[5])) * (((double) (workBuffer[GWAALevel]) ))));
		(((int *) point1))[0] = x;
		(((int *) point1))[1] = y;
	}
	else {

		/* Multiply each component by aaLevel and add a half pixel */
		point1[0] = (((point1[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
		point1[1] = (((point1[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
	}
	/* begin transformPoint: */
	if ((workBuffer[GWHasEdgeTransform]) != 0) {

		/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
		/* begin transformPoint:into: */
		xValue1 = ((double) ((((int *) point2))[0]) );
		yValue1 = ((double) ((((int *) point2))[1]) );
		/* begin edgeTransform */
		transform1 = ((float *) (workBuffer + GWEdgeTransform));
		x1 = ((sqInt)(((((transform1[0]) * xValue1) + ((transform1[1]) * yValue1)) + (transform1[2])) * (((double) (workBuffer[GWAALevel]) ))));
		y1 = ((sqInt)(((((transform1[3]) * xValue1) + ((transform1[4]) * yValue1)) + (transform1[5])) * (((double) (workBuffer[GWAALevel]) ))));
		(((int *) point2))[0] = x1;
		(((int *) point2))[1] = y1;
	}
	else {

		/* Multiply each component by aaLevel and add a half pixel */
		point2[0] = (((point2[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
		point2[1] = (((point2[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
	}
	/* begin transformPoint: */
	if ((workBuffer[GWHasEdgeTransform]) != 0) {

		/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
		/* begin transformPoint:into: */
		xValue2 = ((double) ((((int *) point3))[0]) );
		yValue2 = ((double) ((((int *) point3))[1]) );
		/* begin edgeTransform */
		transform2 = ((float *) (workBuffer + GWEdgeTransform));
		x2 = ((sqInt)(((((transform2[0]) * xValue2) + ((transform2[1]) * yValue2)) + (transform2[2])) * (((double) (workBuffer[GWAALevel]) ))));
		y2 = ((sqInt)(((((transform2[3]) * xValue2) + ((transform2[4]) * yValue2)) + (transform2[5])) * (((double) (workBuffer[GWAALevel]) ))));
		(((int *) point3))[0] = x2;
		(((int *) point3))[1] = y2;
	}
	else {

		/* Multiply each component by aaLevel and add a half pixel */
		point3[0] = (((point3[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
		point3[1] = (((point3[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
	}
	dirX = (point2[0]) - (point1[0]);
	dirY = (point2[1]) - (point1[1]);
	nrmX = (point3[0]) - (point1[0]);

	/* Compute the scale from direction/normal into ramp size */
	nrmY = (point3[1]) - (point1[1]);
	dsLength2 = (dirX * dirX) + (dirY * dirY);
	if (dsLength2 > 0) {
		dsX = ((sqInt)((((((double) dirX )) * (((double) fillWidth ))) * 65536.0) / (((double) dsLength2 ))));
		dsY = ((sqInt)((((((double) dirY )) * (((double) fillWidth ))) * 65536.0) / (((double) dsLength2 ))));
	}
	else {
		dsX = 0;
		dsY = 0;
	}
	dtLength2 = (nrmX * nrmX) + (nrmY * nrmY);
	if (dtLength2 > 0) {
		dtX = ((sqInt)((((((double) nrmX )) * (((double) fillHeight ))) * 65536.0) / (((double) dtLength2 ))));
		dtY = ((sqInt)((((((double) nrmY )) * (((double) fillHeight ))) * 65536.0) / (((double) dtLength2 ))));
	}
	else {
		dtX = 0;
		dtY = 0;
	}
	/* begin fillOriginXOf:put: */
	objBuffer[fill + GFOriginX] = (point1[0]);
	/* begin fillOriginYOf:put: */
	objBuffer[fill + GFOriginY] = (point1[1]);
	/* begin fillDirectionXOf:put: */
	objBuffer[fill + GFDirectionX] = dsX;
	/* begin fillDirectionYOf:put: */
	objBuffer[fill + GFDirectionY] = dsY;
	/* begin fillNormalXOf:put: */
	objBuffer[fill + GFNormalX] = dtX;
	/* begin fillNormalYOf:put: */
	objBuffer[fill + GFNormalY] = dtY;
	return 0;
}


/*	Check all the forms from arrayOop. */

	/* BalloonEngineBase>>#loadFormsFrom: */
static sqInt
loadFormsFrom(sqInt arrayOop)
{
    sqInt bmBits;
    sqInt bmBitsSize;
    sqInt bmDepth;
    sqInt bmHeight;
    sqInt bmRaster;
    sqInt bmWidth;
    sqInt formOop;
    sqInt i;
    sqInt iLimiT;
    sqInt ppw;

	if (!(isArray(arrayOop))) {
		return 0;
	}
	formArray = arrayOop;
	for (i = 0, iLimiT = ((slotSizeOf(formArray)) - 1); i <= iLimiT; i += 1) {
		formOop = fetchPointerofObject(i, formArray);
		if (!(isPointers(formOop))) {
			return 0;
		}
		if ((slotSizeOf(formOop)) < 5) {
			return 0;
		}
		bmBits = fetchPointerofObject(0, formOop);
		if (!((fetchClassOf(bmBits)) == (classBitmap()))) {
			return 0;
		}
		bmBitsSize = slotSizeOf(bmBits);
		bmWidth = fetchIntegerofObject(1, formOop);
		bmHeight = fetchIntegerofObject(2, formOop);
		bmDepth = fetchIntegerofObject(3, formOop);
		if (failed()) {
			return 0;
		}
		if (!((bmWidth >= 0)
			 && (bmHeight >= 0))) {
			return 0;
		}
		ppw = 32 / bmDepth;
		bmRaster = (bmWidth + (ppw - 1)) / ppw;
		if (!(bmBitsSize == (bmRaster * bmHeight))) {
			return 0;
		}
	}
	return 1;
}


/*	Load the gradient fill as defined by the color ramp. */

	/* BalloonEnginePlugin>>#loadGradientFill:from:along:normal:isRadial: */
static sqInt
loadGradientFillfromalongnormalisRadial(sqInt rampOop, int *point1, int *point2, int *point3, sqInt isRadial)
{
    sqInt fill;
    sqInt fill1;
    sqInt fillSize;
    sqInt i;
    int *ramp;
    int *rampPtr;
    sqInt rampWidth;

	if (!((fetchClassOf(rampOop)) == (classBitmap()))) {
		return primitiveFail();
	}
	rampWidth = slotSizeOf(rampOop);
	/* begin allocateGradientFill:rampWidth:isRadial: */
	ramp = ((int *) (firstIndexableField(rampOop)));
	fillSize = GGBaseSize + rampWidth;
	if (!(allocateObjEntry(fillSize))) {
		fill = 0;
		goto l6;
	}
	fill1 = objUsed;
	objUsed = fill1 + fillSize;
	if (isRadial) {
		/* begin obj:at:put: */
		objBuffer[fill1 + GEObjectType] = GEPrimitiveRadialGradientFill;
	}
	else {
		/* begin obj:at:put: */
		objBuffer[fill1 + GEObjectType] = GEPrimitiveLinearGradientFill;
	}
	/* begin obj:at:put: */
	objBuffer[fill1 + GEObjectIndex] = 0;
	/* begin obj:at:put: */
	objBuffer[fill1 + GEObjectLength] = fillSize;
	rampPtr = (objBuffer + fill1) + GFRampOffset;
	if ((workBuffer[GWHasColorTransform]) != 0) {
		for (i = 0; i < rampWidth; i += 1) {
			rampPtr[i] = (transformColor(ramp[i]));
		}
	}
	else {
		for (i = 0; i < rampWidth; i += 1) {
			rampPtr[i] = (ramp[i]);
		}
	}
	/* begin obj:at:put: */
	objBuffer[fill1 + GFRampLength] = rampWidth;
	fill = fill1;
	l6:	/* end allocateGradientFill:rampWidth:isRadial: */;
	if (engineStopped) {
		return null;
	}
	loadFillOrientationfromalongnormalwidthheight(fill, point1, point2, point3, rampWidth, rampWidth);
	return fill;
}


/*	Load the line defined by point1 and point2. */

	/* BalloonEnginePlugin>>#loadLine:from:to:offset:leftFill:rightFill: */
static sqInt
loadLinefromtooffsetleftFillrightFill(sqInt line, int *point1, int *point2, sqInt yOffset, sqInt leftFill, sqInt rightFill)
{
    int *p1;
    int *p2;
    sqInt value;
    sqInt yDir;

	if ((point1[1]) <= (point2[1])) {
		p1 = point1;
		p2 = point2;
		yDir = 1;
	}
	else {
		p1 = point2;
		p2 = point1;
		yDir = -1;
	}
	/* begin edgeXValueOf:put: */
	objBuffer[line + GEXValue] = (p1[0]);
	/* begin edgeYValueOf:put: */
	objBuffer[line + GEYValue] = ((p1[1]) - yOffset);
	/* begin edgeZValueOf:put: */
	value = workBuffer[GWCurrentZ];
	objBuffer[line + GEZValue] = value;
	/* begin edgeLeftFillOf:put: */
	objBuffer[line + GEFillIndexLeft] = leftFill;
	/* begin edgeRightFillOf:put: */
	objBuffer[line + GEFillIndexRight] = rightFill;
	/* begin lineEndXOf:put: */
	objBuffer[line + GLEndX] = (p2[0]);
	/* begin lineEndYOf:put: */
	objBuffer[line + GLEndY] = ((p2[1]) - yOffset);
	/* begin lineYDirectionOf:put: */
	objBuffer[line + GLYDirection] = yDir;
	return 0;
}

	/* BalloonEnginePlugin>>#loadOvalSegment:w:h:cx:cy: */
static sqInt
loadOvalSegmentwhcxcy(sqInt seg, sqInt w, sqInt h, sqInt cx, sqInt cy)
{
    sqInt x0;
    sqInt x1;
    sqInt x2;
    sqInt y0;
    sqInt y1;
    sqInt y2;


	/* Load start point of segment */
	x0 = ((sqInt)((((circleCosTable())[(seg * 2)]) * (((double) w ))) + cx));
	y0 = ((sqInt)((((circleSinTable())[(seg * 2)]) * (((double) h ))) + cy));
	(((int *) (workBuffer + GWPoint1)))[0] = x0;
	(((int *) (workBuffer + GWPoint1)))[1] = y0;
	x2 = ((sqInt)((((circleCosTable())[(seg * 2) + 2]) * (((double) w ))) + cx));
	y2 = ((sqInt)((((circleSinTable())[(seg * 2) + 2]) * (((double) h ))) + cy));
	(((int *) (workBuffer + GWPoint3)))[0] = x2;
	(((int *) (workBuffer + GWPoint3)))[1] = y2;
	x1 = ((sqInt)((((circleCosTable())[(seg * 2) + 1]) * (((double) w ))) + cx));

	/* NOTE: The intermediate point is the point ON the curve
	   and not yet the control point (which is OFF the curve) */
	y1 = ((sqInt)((((circleSinTable())[(seg * 2) + 1]) * (((double) h ))) + cy));
	x1 = (x1 * 2) - ((x0 + x2) / 2);
	y1 = (y1 * 2) - ((y0 + y2) / 2);
	(((int *) (workBuffer + GWPoint2)))[0] = x1;
	(((int *) (workBuffer + GWPoint2)))[1] = y1;
	return 0;
}


/*	Load a rectangular oval currently defined by point1/point2 */

	/* BalloonEnginePlugin>>#loadOval:lineFill:leftFill:rightFill: */
static sqInt
loadOvallineFillleftFillrightFill(sqInt lineWidth, sqInt lineFill, sqInt leftFill, sqInt rightFill)
{
    int cx;
    int cy;
    int h;
    sqInt i;
    sqInt nSegments;
    int *point;
    int *point1;
    int *point2;
    int *point3;
    float *transform;
    float *transform1;
    float *transform2;
    float *transform3;
    int w;
    sqInt x;
    sqInt x1;
    sqInt x2;
    sqInt x3;
    double xValue;
    double xValue1;
    double xValue2;
    double xValue3;
    sqInt y;
    sqInt y1;
    sqInt y2;
    sqInt y3;
    double yValue;
    double yValue1;
    double yValue2;
    double yValue3;

	w = (((((int *) (workBuffer + GWPoint2)))[0]) - ((((int *) (workBuffer + GWPoint1)))[0])) / 2;
	h = (((((int *) (workBuffer + GWPoint2)))[1]) - ((((int *) (workBuffer + GWPoint1)))[1])) / 2;
	cx = (((((int *) (workBuffer + GWPoint2)))[0]) + ((((int *) (workBuffer + GWPoint1)))[0])) / 2;
	cy = (((((int *) (workBuffer + GWPoint2)))[1]) + ((((int *) (workBuffer + GWPoint1)))[1])) / 2;
	for (i = 0; i <= 15; i += 1) {
		loadOvalSegmentwhcxcy(i, w, h, cx, cy);
		/* begin transformPoints: */
		if (3 > 0) {
			/* begin transformPoint: */
			point = ((int *) (workBuffer + GWPoint1));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue = ((double) ((((int *) point))[0]) );
				yValue = ((double) ((((int *) point))[1]) );
				/* begin edgeTransform */
				transform = ((float *) (workBuffer + GWEdgeTransform));
				x = ((sqInt)(((((transform[0]) * xValue) + ((transform[1]) * yValue)) + (transform[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y = ((sqInt)(((((transform[3]) * xValue) + ((transform[4]) * yValue)) + (transform[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point))[0] = x;
				(((int *) point))[1] = y;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point[0] = (((point[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point[1] = (((point[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		if (3 > 1) {
			/* begin transformPoint: */
			point1 = ((int *) (workBuffer + GWPoint2));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue1 = ((double) ((((int *) point1))[0]) );
				yValue1 = ((double) ((((int *) point1))[1]) );
				/* begin edgeTransform */
				transform1 = ((float *) (workBuffer + GWEdgeTransform));
				x1 = ((sqInt)(((((transform1[0]) * xValue1) + ((transform1[1]) * yValue1)) + (transform1[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y1 = ((sqInt)(((((transform1[3]) * xValue1) + ((transform1[4]) * yValue1)) + (transform1[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point1))[0] = x1;
				(((int *) point1))[1] = y1;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point1[0] = (((point1[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point1[1] = (((point1[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		if (3 > 2) {
			/* begin transformPoint: */
			point2 = ((int *) (workBuffer + GWPoint3));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue2 = ((double) ((((int *) point2))[0]) );
				yValue2 = ((double) ((((int *) point2))[1]) );
				/* begin edgeTransform */
				transform2 = ((float *) (workBuffer + GWEdgeTransform));
				x2 = ((sqInt)(((((transform2[0]) * xValue2) + ((transform2[1]) * yValue2)) + (transform2[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y2 = ((sqInt)(((((transform2[3]) * xValue2) + ((transform2[4]) * yValue2)) + (transform2[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point2))[0] = x2;
				(((int *) point2))[1] = y2;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point2[0] = (((point2[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point2[1] = (((point2[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		if (3 > 3) {
			/* begin transformPoint: */
			point3 = ((int *) (workBuffer + GWPoint4));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue3 = ((double) ((((int *) point3))[0]) );
				yValue3 = ((double) ((((int *) point3))[1]) );
				/* begin edgeTransform */
				transform3 = ((float *) (workBuffer + GWEdgeTransform));
				x3 = ((sqInt)(((((transform3[0]) * xValue3) + ((transform3[1]) * yValue3)) + (transform3[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y3 = ((sqInt)(((((transform3[3]) * xValue3) + ((transform3[4]) * yValue3)) + (transform3[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point3))[0] = x3;
				(((int *) point3))[1] = y3;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point3[0] = (((point3[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point3[1] = (((point3[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		nSegments = loadAndSubdivideBezierFromviatoisWide(((int *) (workBuffer + GWPoint1)), ((int *) (workBuffer + GWPoint2)), ((int *) (workBuffer + GWPoint3)), (lineWidth != 0)
		 && (lineFill != 0));
		if (engineStopped) {
			return null;
		}
		loadWideBezierlineFillleftFillrightFilln(lineWidth, lineFill, leftFill, rightFill, nSegments);
		if (engineStopped) {
			return null;
		}
	}
	return 0;
}


/*	Load the int value from the given index in intArray */

	/* BalloonEnginePlugin>>#loadPointIntAt:from: */
static sqInt
loadPointIntAtfrom(sqInt index, sqInt intArray)
{
	return (((int *) intArray))[index];
}


/*	Load the short value from the given index in shortArray */

	/* BalloonEnginePlugin>>#loadPointShortAt:from: */
static short
loadPointShortAtfrom(sqInt index, sqInt shortArray)
{
	return (((short *) shortArray))[index];
}


/*	Load the contents of pointOop into pointArray */

	/* BalloonEngineBase>>#loadPoint:from: */
static sqInt
loadPointfrom(int *pointArray, sqInt pointOop)
{
    sqInt value;

	if (!((fetchClassOf(pointOop)) == (classPoint()))) {
		return primitiveFail();
	}
	value = fetchPointerofObject(0, pointOop);
	if (!((isIntegerObject(value))
		 || (isFloatObject(value)))) {
		return primitiveFail();
	}
	if (isIntegerObject(value)) {
		pointArray[0] = (integerValueOf(value));
	}
	else {
		pointArray[0] = (((sqInt)(floatValueOf(value))));
	}
	value = fetchPointerofObject(1, pointOop);
	if (!((isIntegerObject(value))
		 || (isFloatObject(value)))) {
		return primitiveFail();
	}
	if (isIntegerObject(value)) {
		pointArray[1] = (integerValueOf(value));
	}
	else {
		pointArray[1] = (((sqInt)(floatValueOf(value))));
	}
	return 0;
}

	/* BalloonEnginePlugin>>#loadPolygon:nPoints:fill:lineWidth:lineFill:pointsShort: */
static sqInt
loadPolygonnPointsfilllineWidthlineFillpointsShort(int *points, sqInt nPoints, sqInt fillIndex, sqInt lineWidth, sqInt lineFill, sqInt isShort)
{
    sqInt i;
    int *point;
    int *point1;
    int *point2;
    int *point3;
    float *transform;
    float *transform1;
    float *transform2;
    float *transform3;
    sqInt x;
    sqInt x0;
    sqInt x1;
    sqInt x11;
    sqInt x2;
    sqInt x3;
    double xValue;
    double xValue1;
    double xValue2;
    double xValue3;
    sqInt y;
    sqInt y0;
    sqInt y1;
    sqInt y11;
    sqInt y2;
    sqInt y3;
    double yValue;
    double yValue1;
    double yValue2;
    double yValue3;

	if (isShort) {
		/* begin loadPointShortAt:from: */
		x0 = (((short *) points))[0];
		/* begin loadPointShortAt:from: */
		y0 = (((short *) points))[1];
	}
	else {
		/* begin loadPointIntAt:from: */
		x0 = (((int *) points))[0];
		/* begin loadPointIntAt:from: */
		y0 = (((int *) points))[1];
	}
	for (i = 1; i < nPoints; i += 1) {
		if (isShort) {
			/* begin loadPointShortAt:from: */
			x1 = (((short *) points))[i * 2];
			/* begin loadPointShortAt:from: */
			y1 = (((short *) points))[(i * 2) + 1];
		}
		else {
			/* begin loadPointIntAt:from: */
			x1 = (((int *) points))[i * 2];
			/* begin loadPointIntAt:from: */
			y1 = (((int *) points))[(i * 2) + 1];
		}
		(((int *) (workBuffer + GWPoint1)))[0] = x0;
		(((int *) (workBuffer + GWPoint1)))[1] = y0;
		(((int *) (workBuffer + GWPoint2)))[0] = x1;
		(((int *) (workBuffer + GWPoint2)))[1] = y1;
		/* begin transformPoints: */
		if (2 > 0) {
			/* begin transformPoint: */
			point = ((int *) (workBuffer + GWPoint1));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue = ((double) ((((int *) point))[0]) );
				yValue = ((double) ((((int *) point))[1]) );
				/* begin edgeTransform */
				transform = ((float *) (workBuffer + GWEdgeTransform));
				x = ((sqInt)(((((transform[0]) * xValue) + ((transform[1]) * yValue)) + (transform[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y = ((sqInt)(((((transform[3]) * xValue) + ((transform[4]) * yValue)) + (transform[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point))[0] = x;
				(((int *) point))[1] = y;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point[0] = (((point[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point[1] = (((point[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		if (2 > 1) {
			/* begin transformPoint: */
			point1 = ((int *) (workBuffer + GWPoint2));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue1 = ((double) ((((int *) point1))[0]) );
				yValue1 = ((double) ((((int *) point1))[1]) );
				/* begin edgeTransform */
				transform1 = ((float *) (workBuffer + GWEdgeTransform));
				x11 = ((sqInt)(((((transform1[0]) * xValue1) + ((transform1[1]) * yValue1)) + (transform1[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y11 = ((sqInt)(((((transform1[3]) * xValue1) + ((transform1[4]) * yValue1)) + (transform1[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point1))[0] = x11;
				(((int *) point1))[1] = y11;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point1[0] = (((point1[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point1[1] = (((point1[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		if (2 > 2) {
			/* begin transformPoint: */
			point2 = ((int *) (workBuffer + GWPoint3));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue2 = ((double) ((((int *) point2))[0]) );
				yValue2 = ((double) ((((int *) point2))[1]) );
				/* begin edgeTransform */
				transform2 = ((float *) (workBuffer + GWEdgeTransform));
				x2 = ((sqInt)(((((transform2[0]) * xValue2) + ((transform2[1]) * yValue2)) + (transform2[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y2 = ((sqInt)(((((transform2[3]) * xValue2) + ((transform2[4]) * yValue2)) + (transform2[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point2))[0] = x2;
				(((int *) point2))[1] = y2;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point2[0] = (((point2[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point2[1] = (((point2[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		if (2 > 3) {
			/* begin transformPoint: */
			point3 = ((int *) (workBuffer + GWPoint4));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue3 = ((double) ((((int *) point3))[0]) );
				yValue3 = ((double) ((((int *) point3))[1]) );
				/* begin edgeTransform */
				transform3 = ((float *) (workBuffer + GWEdgeTransform));
				x3 = ((sqInt)(((((transform3[0]) * xValue3) + ((transform3[1]) * yValue3)) + (transform3[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y3 = ((sqInt)(((((transform3[3]) * xValue3) + ((transform3[4]) * yValue3)) + (transform3[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point3))[0] = x3;
				(((int *) point3))[1] = y3;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point3[0] = (((point3[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point3[1] = (((point3[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		loadWideLinefromtolineFillleftFillrightFill(lineWidth, ((int *) (workBuffer + GWPoint1)), ((int *) (workBuffer + GWPoint2)), lineFill, fillIndex, 0);
		if (engineStopped) {
			return null;
		}
		x0 = x1;
		y0 = y1;
	}
	return 0;
}


/*	Load a rectangle currently defined by point1-point4 */

	/* BalloonEnginePlugin>>#loadRectangle:lineFill:leftFill:rightFill: */
static sqInt
loadRectanglelineFillleftFillrightFill(sqInt lineWidth, sqInt lineFill, sqInt leftFill, sqInt rightFill)
{
	loadWideLinefromtolineFillleftFillrightFill(lineWidth, ((int *) (workBuffer + GWPoint1)), ((int *) (workBuffer + GWPoint2)), lineFill, leftFill, rightFill);
	loadWideLinefromtolineFillleftFillrightFill(lineWidth, ((int *) (workBuffer + GWPoint2)), ((int *) (workBuffer + GWPoint3)), lineFill, leftFill, rightFill);
	loadWideLinefromtolineFillleftFillrightFill(lineWidth, ((int *) (workBuffer + GWPoint3)), ((int *) (workBuffer + GWPoint4)), lineFill, leftFill, rightFill);
	loadWideLinefromtolineFillleftFillrightFill(lineWidth, ((int *) (workBuffer + GWPoint4)), ((int *) (workBuffer + GWPoint1)), lineFill, leftFill, rightFill);
	return 0;
}


/*	Load the entire state from the interpreter for the rendering primitives.
	Answer 0 on success or a non-zero failure code on failure. */

	/* BalloonEngineBase>>#loadRenderingState */
static sqInt
loadRenderingState(void)
{
    sqInt edgeOop;
    sqInt failCode;
    sqInt fillOop;
    sqInt state;

	if (!((methodArgumentCount()) == 2)) {
		return PrimErrBadNumArgs;
	}
	if (((failCode = quickLoadEngineFrom(stackValue(2)))) != 0) {
		return failCode;
	}
	fillOop = stackObjectValue(0);
	edgeOop = stackObjectValue(1);
	if (failed()) {
		return PrimErrBadArgument;
	}
	if (!(((failCode = loadSpanBufferFrom(fetchPointerofObject(BESpanIndex, engine)))) == 0)) {
		return failCode;
	}
	if (!(loadBitBltFrom(fetchPointerofObject(BEBitBltIndex, engine)))) {
		return GEFBitBltLoadFailed;
	}
	if (!(loadFormsFrom(fetchPointerofObject(BEFormsIndex, engine)))) {
		return GEFFormLoadFailed;
	}
	if ((slotSizeOf(edgeOop)) < ETBalloonEdgeDataSize) {
		return GEFEdgeDataTooSmall;
	}
	if ((slotSizeOf(fillOop)) < FTBalloonFillDataSize) {
		return GEFFillDataTooSmall;
	}
	state = workBuffer[GWState];
	if ((state == GEStateWaitingForEdge)
	 || ((state == GEStateWaitingForFill)
	 || (state == GEStateWaitingChange))) {
		return GEFWrongState;
	}
	return 0;
}

	/* BalloonEnginePlugin>>#loadShape:nSegments:fill:lineWidth:lineFill:pointsShort: */
static sqInt
loadShapenSegmentsfilllineWidthlineFillpointsShort(int *points, sqInt nSegments, sqInt fillIndex, sqInt lineWidth, sqInt lineFill, sqInt pointsShort)
{
    sqInt i;
    sqInt index;
    int *point;
    int *point1;
    int *point11;
    int *point2;
    int *point21;
    int *point3;
    int *point31;
    int *point4;
    sqInt segs;
    float *transform;
    float *transform1;
    float *transform11;
    float *transform2;
    float *transform21;
    float *transform3;
    float *transform31;
    float *transform4;
    sqInt x;
    sqInt x0;
    sqInt x1;
    sqInt x11;
    sqInt x12;
    sqInt x2;
    sqInt x21;
    sqInt x22;
    sqInt x3;
    sqInt x31;
    sqInt x4;
    double xValue;
    double xValue1;
    double xValue11;
    double xValue2;
    double xValue21;
    double xValue3;
    double xValue31;
    double xValue4;
    sqInt y;
    sqInt y0;
    sqInt y1;
    sqInt y11;
    sqInt y12;
    sqInt y2;
    sqInt y21;
    sqInt y22;
    sqInt y3;
    sqInt y31;
    sqInt y4;
    double yValue;
    double yValue1;
    double yValue11;
    double yValue2;
    double yValue21;
    double yValue3;
    double yValue31;
    double yValue4;

	for (i = 1; i <= nSegments; i += 1) {
		/* begin loadCompressedSegment:from:short:leftFill:rightFill:lineWidth:lineColor: */
		if ((fillIndex == 0)
		 && ((lineWidth == 0)
		 || (lineFill == 0))) {
			goto l15;
		}

		/* 3 points with x/y each */
		index = (i - 1) * 6;
		if (pointsShort) {

			/* Load short points */
			/* begin loadPointShortAt:from: */
			x0 = (((short *) points))[index];
			/* begin loadPointShortAt:from: */
			y0 = (((short *) points))[index + 1];
			/* begin loadPointShortAt:from: */
			x1 = (((short *) points))[index + 2];
			/* begin loadPointShortAt:from: */
			y1 = (((short *) points))[index + 3];
			/* begin loadPointShortAt:from: */
			x2 = (((short *) points))[index + 4];
			/* begin loadPointShortAt:from: */
			y2 = (((short *) points))[index + 5];
		}
		else {
			x0 = (((int *) points))[index];
			y0 = (((int *) points))[index + 1];
			x1 = (((int *) points))[index + 2];
			y1 = (((int *) points))[index + 3];
			x2 = (((int *) points))[index + 4];
			y2 = (((int *) points))[index + 5];
		}
		if (((x0 == x1)
		 && (y0 == y1))
		 || ((x1 == x2)
		 && (y1 == y2))) {

			/* We can use a line from x0/y0 to x2/y2 */
			if ((x0 == x2)
			 && (y0 == y2)) {
				goto l15;
			}
			(((int *) (workBuffer + GWPoint1)))[0] = x0;
			(((int *) (workBuffer + GWPoint1)))[1] = y0;
			(((int *) (workBuffer + GWPoint2)))[0] = x2;
			(((int *) (workBuffer + GWPoint2)))[1] = y2;
			/* begin transformPoints: */
			if (2 > 0) {
				/* begin transformPoint: */
				point = ((int *) (workBuffer + GWPoint1));
				if ((workBuffer[GWHasEdgeTransform]) != 0) {

					/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
					/* begin transformPoint:into: */
					xValue = ((double) ((((int *) point))[0]) );
					yValue = ((double) ((((int *) point))[1]) );
					/* begin edgeTransform */
					transform = ((float *) (workBuffer + GWEdgeTransform));
					x = ((sqInt)(((((transform[0]) * xValue) + ((transform[1]) * yValue)) + (transform[2])) * (((double) (workBuffer[GWAALevel]) ))));
					y = ((sqInt)(((((transform[3]) * xValue) + ((transform[4]) * yValue)) + (transform[5])) * (((double) (workBuffer[GWAALevel]) ))));
					(((int *) point))[0] = x;
					(((int *) point))[1] = y;
				}
				else {

					/* Multiply each component by aaLevel and add a half pixel */
					point[0] = (((point[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
					point[1] = (((point[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
				}
			}
			if (2 > 1) {
				/* begin transformPoint: */
				point1 = ((int *) (workBuffer + GWPoint2));
				if ((workBuffer[GWHasEdgeTransform]) != 0) {

					/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
					/* begin transformPoint:into: */
					xValue1 = ((double) ((((int *) point1))[0]) );
					yValue1 = ((double) ((((int *) point1))[1]) );
					/* begin edgeTransform */
					transform1 = ((float *) (workBuffer + GWEdgeTransform));
					x11 = ((sqInt)(((((transform1[0]) * xValue1) + ((transform1[1]) * yValue1)) + (transform1[2])) * (((double) (workBuffer[GWAALevel]) ))));
					y11 = ((sqInt)(((((transform1[3]) * xValue1) + ((transform1[4]) * yValue1)) + (transform1[5])) * (((double) (workBuffer[GWAALevel]) ))));
					(((int *) point1))[0] = x11;
					(((int *) point1))[1] = y11;
				}
				else {

					/* Multiply each component by aaLevel and add a half pixel */
					point1[0] = (((point1[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
					point1[1] = (((point1[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
				}
			}
			if (2 > 2) {
				/* begin transformPoint: */
				point2 = ((int *) (workBuffer + GWPoint3));
				if ((workBuffer[GWHasEdgeTransform]) != 0) {

					/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
					/* begin transformPoint:into: */
					xValue2 = ((double) ((((int *) point2))[0]) );
					yValue2 = ((double) ((((int *) point2))[1]) );
					/* begin edgeTransform */
					transform2 = ((float *) (workBuffer + GWEdgeTransform));
					x21 = ((sqInt)(((((transform2[0]) * xValue2) + ((transform2[1]) * yValue2)) + (transform2[2])) * (((double) (workBuffer[GWAALevel]) ))));
					y21 = ((sqInt)(((((transform2[3]) * xValue2) + ((transform2[4]) * yValue2)) + (transform2[5])) * (((double) (workBuffer[GWAALevel]) ))));
					(((int *) point2))[0] = x21;
					(((int *) point2))[1] = y21;
				}
				else {

					/* Multiply each component by aaLevel and add a half pixel */
					point2[0] = (((point2[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
					point2[1] = (((point2[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
				}
			}
			if (2 > 3) {
				/* begin transformPoint: */
				point3 = ((int *) (workBuffer + GWPoint4));
				if ((workBuffer[GWHasEdgeTransform]) != 0) {

					/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
					/* begin transformPoint:into: */
					xValue3 = ((double) ((((int *) point3))[0]) );
					yValue3 = ((double) ((((int *) point3))[1]) );
					/* begin edgeTransform */
					transform3 = ((float *) (workBuffer + GWEdgeTransform));
					x3 = ((sqInt)(((((transform3[0]) * xValue3) + ((transform3[1]) * yValue3)) + (transform3[2])) * (((double) (workBuffer[GWAALevel]) ))));
					y3 = ((sqInt)(((((transform3[3]) * xValue3) + ((transform3[4]) * yValue3)) + (transform3[5])) * (((double) (workBuffer[GWAALevel]) ))));
					(((int *) point3))[0] = x3;
					(((int *) point3))[1] = y3;
				}
				else {

					/* Multiply each component by aaLevel and add a half pixel */
					point3[0] = (((point3[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
					point3[1] = (((point3[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
				}
			}
			loadWideLinefromtolineFillleftFillrightFill(lineWidth, ((int *) (workBuffer + GWPoint1)), ((int *) (workBuffer + GWPoint2)), lineFill, fillIndex, 0);
			goto l15;
		}
		(((int *) (workBuffer + GWPoint1)))[0] = x0;
		(((int *) (workBuffer + GWPoint1)))[1] = y0;
		(((int *) (workBuffer + GWPoint2)))[0] = x1;
		(((int *) (workBuffer + GWPoint2)))[1] = y1;
		(((int *) (workBuffer + GWPoint3)))[0] = x2;
		(((int *) (workBuffer + GWPoint3)))[1] = y2;
		/* begin transformPoints: */
		if (3 > 0) {
			/* begin transformPoint: */
			point4 = ((int *) (workBuffer + GWPoint1));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue4 = ((double) ((((int *) point4))[0]) );
				yValue4 = ((double) ((((int *) point4))[1]) );
				/* begin edgeTransform */
				transform4 = ((float *) (workBuffer + GWEdgeTransform));
				x4 = ((sqInt)(((((transform4[0]) * xValue4) + ((transform4[1]) * yValue4)) + (transform4[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y4 = ((sqInt)(((((transform4[3]) * xValue4) + ((transform4[4]) * yValue4)) + (transform4[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point4))[0] = x4;
				(((int *) point4))[1] = y4;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point4[0] = (((point4[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point4[1] = (((point4[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		if (3 > 1) {
			/* begin transformPoint: */
			point11 = ((int *) (workBuffer + GWPoint2));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue11 = ((double) ((((int *) point11))[0]) );
				yValue11 = ((double) ((((int *) point11))[1]) );
				/* begin edgeTransform */
				transform11 = ((float *) (workBuffer + GWEdgeTransform));
				x12 = ((sqInt)(((((transform11[0]) * xValue11) + ((transform11[1]) * yValue11)) + (transform11[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y12 = ((sqInt)(((((transform11[3]) * xValue11) + ((transform11[4]) * yValue11)) + (transform11[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point11))[0] = x12;
				(((int *) point11))[1] = y12;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point11[0] = (((point11[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point11[1] = (((point11[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		if (3 > 2) {
			/* begin transformPoint: */
			point21 = ((int *) (workBuffer + GWPoint3));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue21 = ((double) ((((int *) point21))[0]) );
				yValue21 = ((double) ((((int *) point21))[1]) );
				/* begin edgeTransform */
				transform21 = ((float *) (workBuffer + GWEdgeTransform));
				x22 = ((sqInt)(((((transform21[0]) * xValue21) + ((transform21[1]) * yValue21)) + (transform21[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y22 = ((sqInt)(((((transform21[3]) * xValue21) + ((transform21[4]) * yValue21)) + (transform21[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point21))[0] = x22;
				(((int *) point21))[1] = y22;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point21[0] = (((point21[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point21[1] = (((point21[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		if (3 > 3) {
			/* begin transformPoint: */
			point31 = ((int *) (workBuffer + GWPoint4));
			if ((workBuffer[GWHasEdgeTransform]) != 0) {

				/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
				/* begin transformPoint:into: */
				xValue31 = ((double) ((((int *) point31))[0]) );
				yValue31 = ((double) ((((int *) point31))[1]) );
				/* begin edgeTransform */
				transform31 = ((float *) (workBuffer + GWEdgeTransform));
				x31 = ((sqInt)(((((transform31[0]) * xValue31) + ((transform31[1]) * yValue31)) + (transform31[2])) * (((double) (workBuffer[GWAALevel]) ))));
				y31 = ((sqInt)(((((transform31[3]) * xValue31) + ((transform31[4]) * yValue31)) + (transform31[5])) * (((double) (workBuffer[GWAALevel]) ))));
				(((int *) point31))[0] = x31;
				(((int *) point31))[1] = y31;
			}
			else {

				/* Multiply each component by aaLevel and add a half pixel */
				point31[0] = (((point31[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
				point31[1] = (((point31[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
			}
		}
		segs = loadAndSubdivideBezierFromviatoisWide(((int *) (workBuffer + GWPoint1)), ((int *) (workBuffer + GWPoint2)), ((int *) (workBuffer + GWPoint3)), (lineWidth != 0)
		 && (lineFill != 0));
		if (engineStopped) {
			goto l15;
		}
		loadWideBezierlineFillleftFillrightFilln(lineWidth, lineFill, fillIndex, 0, segs);
	l15:	/* end loadCompressedSegment:from:short:leftFill:rightFill:lineWidth:lineColor: */;
		if (engineStopped) {
			return null;
		}
	}
	return 0;
}


/*	Load the span buffer from the given oop.
	Answer 0 on success or a non-zero failure code on failure. */

	/* BalloonEngineBase>>#loadSpanBufferFrom: */
static sqInt
loadSpanBufferFrom(sqInt spanOop)
{
    sqInt value;

	if (!((fetchClassOf(spanOop)) == (classBitmap()))) {
		return GEFClassMismatch;
	}

	/* Leave last entry unused to avoid complications */
	spanBuffer = firstIndexableField(spanOop);
	/* begin spanSizePut: */
	value = (slotSizeOf(spanOop)) - 1;
	workBuffer[GWSpanSize] = value;
	return 0;
}


/*	Load a transformation from transformOop into the float array
	defined by destPtr. The transformation is assumed to be either
	an array or a FloatArray of length n. */

	/* BalloonEngineBase>>#loadTransformFrom:into:length: */
static sqInt
loadTransformFromintolength(sqInt transformOop, float *destPtr, sqInt n)
{
	if (transformOop == (nilObject())) {
		return 0;
	}
	if (isImmediate(transformOop)) {
		return primitiveFail();
	}
	if (!((slotSizeOf(transformOop)) == n)) {
		return primitiveFail();
	}
	if (isWords(transformOop)) {
		loadWordTransformFromintolength(transformOop, destPtr, n);
	}
	else {
		loadArrayTransformFromintolength(transformOop, destPtr, n);
	}
	return 1;
}


/*	Load the (possibly wide) bezier from the segments currently on the bezier
	stack. 
 */

	/* BalloonEnginePlugin>>#loadWideBezier:lineFill:leftFill:rightFill:n: */
static sqInt
loadWideBezierlineFillleftFillrightFilln(sqInt lineWidth, sqInt lineFill, sqInt leftFill, sqInt rightFill, sqInt nSegments)
{
    sqInt bezier;
    sqInt bezier1;
    sqInt bezier2;
    sqInt index;
    sqInt offset;
    sqInt wide;

	if ((lineWidth == 0)
	 || (lineFill == 0)) {
		wide = 0;
		offset = 0;
	}
	else {
		wide = 1;
		offset = lineWidth / 2;
	}
	index = nSegments * 6;
	while (index > 0) {
		if (wide) {
			/* begin allocateWideBezier */
			if (!(allocateObjEntry(GBWideSize))) {
				bezier = 0;
				goto l4;
			}
			bezier1 = objUsed;
			objUsed = bezier1 + GBWideSize;
			/* begin obj:at:put: */
			objBuffer[bezier1 + GEObjectType] = GEPrimitiveWideBezier;
			/* begin obj:at:put: */
			objBuffer[bezier1 + GEObjectIndex] = 0;
			/* begin obj:at:put: */
			objBuffer[bezier1 + GEObjectLength] = GBWideSize;
			bezier = bezier1;
	l4:	/* end allocateWideBezier */;
		}
		else {
			/* begin allocateBezier */
			if (!(allocateObjEntry(GBBaseSize))) {
				bezier = 0;
				goto l8;
			}
			bezier2 = objUsed;
			objUsed = bezier2 + GBBaseSize;
			/* begin obj:at:put: */
			objBuffer[bezier2 + GEObjectType] = GEPrimitiveBezier;
			/* begin obj:at:put: */
			objBuffer[bezier2 + GEObjectIndex] = 0;
			/* begin obj:at:put: */
			objBuffer[bezier2 + GEObjectLength] = GBBaseSize;
			bezier = bezier2;
	l8:	/* end allocateBezier */;
		}
		if (engineStopped) {
			return 0;
		}
		loadBeziersegmentleftFillrightFilloffset(bezier, index, leftFill, rightFill, offset);
		if (wide) {
			/* begin obj:at:put: */
			objBuffer[bezier + GBWideFill] = lineFill;
			/* begin obj:at:put: */
			objBuffer[bezier + GBWideWidth] = lineWidth;
			/* begin obj:at:put: */
			objBuffer[bezier + GBWideExtent] = lineWidth;
		}
		index -= 6;
	}
	/* begin wbStackClear */
	workBuffer[GWBufferTop] = (workBuffer[GWSize]);
	return 0;
}


/*	Load a (possibly wide) line defined by the points p1 and p2 */

	/* BalloonEnginePlugin>>#loadWideLine:from:to:lineFill:leftFill:rightFill: */
static sqInt
loadWideLinefromtolineFillleftFillrightFill(sqInt lineWidth, int *p1, int *p2, sqInt lineFill, sqInt leftFill, sqInt rightFill)
{
    sqInt line;
    sqInt line1;
    sqInt line2;
    sqInt offset;
    int *p11;
    int *p21;
    sqInt value;
    sqInt yDir;

	if ((lineWidth == 0)
	 || (lineFill == 0)) {
		/* begin allocateLine */
		if (!(allocateObjEntry(GLBaseSize))) {
			line = 0;
			goto l12;
		}
		line1 = objUsed;
		objUsed = line1 + GLBaseSize;
		/* begin obj:at:put: */
		objBuffer[line1 + GEObjectType] = GEPrimitiveLine;
		/* begin obj:at:put: */
		objBuffer[line1 + GEObjectIndex] = 0;
		/* begin obj:at:put: */
		objBuffer[line1 + GEObjectLength] = GLBaseSize;
		line = line1;
	l12:	/* end allocateLine */;
		offset = 0;
	}
	else {
		/* begin allocateWideLine */
		if (!(allocateObjEntry(GLWideSize))) {
			line = 0;
			goto l16;
		}
		line2 = objUsed;
		objUsed = line2 + GLWideSize;
		/* begin obj:at:put: */
		objBuffer[line2 + GEObjectType] = GEPrimitiveWideLine;
		/* begin obj:at:put: */
		objBuffer[line2 + GEObjectIndex] = 0;
		/* begin obj:at:put: */
		objBuffer[line2 + GEObjectLength] = GLWideSize;
		line = line2;
	l16:	/* end allocateWideLine */;
		offset = lineWidth / 2;
	}
	if (engineStopped) {
		return 0;
	}
	/* begin loadLine:from:to:offset:leftFill:rightFill: */
	if ((p1[1]) <= (p2[1])) {
		p11 = p1;
		p21 = p2;
		yDir = 1;
	}
	else {
		p11 = p2;
		p21 = p1;
		yDir = -1;
	}
	/* begin edgeXValueOf:put: */
	objBuffer[line + GEXValue] = (p11[0]);
	/* begin edgeYValueOf:put: */
	objBuffer[line + GEYValue] = ((p11[1]) - offset);
	/* begin edgeZValueOf:put: */
	value = workBuffer[GWCurrentZ];
	objBuffer[line + GEZValue] = value;
	/* begin edgeLeftFillOf:put: */
	objBuffer[line + GEFillIndexLeft] = leftFill;
	/* begin edgeRightFillOf:put: */
	objBuffer[line + GEFillIndexRight] = rightFill;
	/* begin lineEndXOf:put: */
	objBuffer[line + GLEndX] = (p21[0]);
	/* begin lineEndYOf:put: */
	objBuffer[line + GLEndY] = ((p21[1]) - offset);
	/* begin lineYDirectionOf:put: */
	objBuffer[line + GLYDirection] = yDir;
	if ((((objBuffer[line + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveWide) != 0) {
		/* begin obj:at:put: */
		objBuffer[line + GLWideFill] = lineFill;
		/* begin obj:at:put: */
		objBuffer[line + GLWideWidth] = lineWidth;
		/* begin obj:at:put: */
		objBuffer[line + GLWideExtent] = lineWidth;
	}
	return 0;
}


/*	Load a float array transformation from the given oop */

	/* BalloonEngineBase>>#loadWordTransformFrom:into:length: */
static sqInt
loadWordTransformFromintolength(sqInt transformOop, float *destPtr, sqInt n)
{
    sqInt i;
    float *srcPtr;

	srcPtr = ((float *) (firstIndexableField(transformOop)));
	for (i = 0; i < n; i += 1) {
		destPtr[i] = (srcPtr[i]);
	}
	return 0;
}


/*	Load the working buffer from the given oop */

	/* BalloonEngineBase>>#loadWorkBufferFrom: */
static sqInt
loadWorkBufferFrom(sqInt wbOop)
{
	if (isImmediate(wbOop)) {
		return GEFWorkBufferIsInteger;
	}
	if (!(isWords(wbOop))) {
		return GEFWorkBufferIsPointers;
	}
	if ((slotSizeOf(wbOop)) < GWMinimalSize) {
		return GEFWorkBufferTooSmall;
	}
	/* begin workBufferPut: */
	workBuffer = firstIndexableField(wbOop);
	if (!((workBuffer[GWMagicIndex]) == GWMagicNumber)) {
		return GEFWorkBufferBadMagic;
	}
	if (!((workBuffer[GWSize]) == (slotSizeOf(wbOop)))) {
		return GEFWorkBufferWrongSize;
	}
	if (!((workBuffer[GWObjStart]) == GWHeaderSize)) {
		return GEFWorkBufferStartWrong;
	}
	objBuffer = workBuffer + (workBuffer[GWObjStart]);
	getBuffer = objBuffer + (workBuffer[GWObjUsed]);

	/* Make sure we don't exceed the work buffer */
	aetBuffer = getBuffer + (workBuffer[GWGETUsed]);
	if ((((GWHeaderSize + (workBuffer[GWObjUsed])) + (workBuffer[GWGETUsed])) + (workBuffer[GWAETUsed])) > (workBuffer[GWSize])) {
		return GEFWorkTooBig;
	}
	return 0;
}

	/* BalloonEngineBase>>#magicNumberGet */
static sqInt
magicNumberGet(void)
{
	return workBuffer[GWMagicIndex];
}

	/* BalloonEngineBase>>#magicNumberPut: */
static sqInt
magicNumberPut(sqInt value)
{
	return workBuffer[GWMagicIndex] = value;
}

	/* BalloonEnginePlugin>>#makeRectFromPoints */
static sqInt
makeRectFromPoints(void)
{
	(((int *) (workBuffer + GWPoint2)))[0] = ((((int *) (workBuffer + GWPoint3)))[0]);
	(((int *) (workBuffer + GWPoint2)))[1] = ((((int *) (workBuffer + GWPoint1)))[1]);
	(((int *) (workBuffer + GWPoint4)))[0] = ((((int *) (workBuffer + GWPoint1)))[0]);
	(((int *) (workBuffer + GWPoint4)))[1] = ((((int *) (workBuffer + GWPoint3)))[1]);
	return 0;
}

	/* BalloonEngineBase>>#makeUnsignedFrom: */
static sqInt
makeUnsignedFrom(sqInt someIntegerValue)
{
	return someIntegerValue;
}


/*	The module with the given name was just unloaded.
	Make sure we have no dangling references. */

	/* BalloonEngineBase>>#moduleUnloaded: */
EXPORT(sqInt)
moduleUnloaded(char *aModuleName)
{
	if ((strcmp(aModuleName, bbPluginName)) == 0) {

		/* BitBlt just shut down. How nasty. */
		loadBBFn = 0;
		copyBitsFn = 0;
	}
	return 0;
}


/*	The entry at index is not in the right position of the AET. 
	Move it to the left until the position is okay. */

	/* BalloonEngineBase>>#moveAETEntryFrom:edge:x: */
static sqInt
moveAETEntryFromedgex(sqInt index, sqInt edge, sqInt xValue)
{
    sqInt newIndex;

	newIndex = index;
	while ((newIndex > 0)
	 && ((objBuffer[(aetBuffer[newIndex - 1]) + GEXValue]) > xValue)) {
		aetBuffer[newIndex] = (aetBuffer[newIndex - 1]);
		newIndex -= 1;
	}
	aetBuffer[newIndex] = edge;
	return 0;
}


/*	Check if we have n slots available */

	/* BalloonEngineBase>>#needAvailableSpace: */
static sqInt
needAvailableSpace(sqInt nSlots)
{
	if (((((GWHeaderSize + objUsed) + (workBuffer[GWGETUsed])) + (workBuffer[GWAETUsed])) + nSlots) > (workBuffer[GWBufferTop])) {
		/* begin stopBecauseOf: */
		workBuffer[GWStopReason] = GErrorNoMoreSpace;
		engineStopped = 1;
		return 0;
	}
	return 1;
}

	/* BalloonEngineBase>>#needsFlush */
static sqInt
needsFlush(void)
{
	return (workBuffer[GWNeedsFlush]) != 0;
}

	/* BalloonEngineBase>>#needsFlushGet */
static sqInt
needsFlushGet(void)
{
	return workBuffer[GWNeedsFlush];
}

	/* BalloonEngineBase>>#needsFlushPut: */
static sqInt
needsFlushPut(sqInt value)
{
	return workBuffer[GWNeedsFlush] = value;
}

	/* BalloonEngineBase>>#objectHeaderOf: */
static sqInt
objectHeaderOf(sqInt obj)
{
    sqInt someIntegerValue;

	/* begin makeUnsignedFrom: */
	someIntegerValue = objBuffer[obj + GEObjectType];
	return someIntegerValue;
}

	/* BalloonEngineBase>>#objectIndexOf: */
static sqInt
objectIndexOf(sqInt obj)
{
	return objBuffer[obj + GEObjectIndex];
}

	/* BalloonEngineBase>>#objectIndexOf:put: */
static sqInt
objectIndexOfput(sqInt obj, sqInt value)
{
	return objBuffer[obj + GEObjectIndex] = value;
}

	/* BalloonEngineBase>>#objectLengthOf: */
static sqInt
objectLengthOf(sqInt obj)
{
	return objBuffer[obj + GEObjectLength];
}

	/* BalloonEngineBase>>#objectLengthOf:put: */
static sqInt
objectLengthOfput(sqInt obj, sqInt value)
{
	return objBuffer[obj + GEObjectLength] = value;
}

	/* BalloonEngineBase>>#objectTypeOf: */
static sqInt
objectTypeOf(sqInt obj)
{
	return (objBuffer[obj + GEObjectType]) & GEPrimitiveTypeMask;
}

	/* BalloonEngineBase>>#objectTypeOf:put: */
static sqInt
objectTypeOfput(sqInt obj, sqInt value)
{
	return objBuffer[obj + GEObjectType] = value;
}

	/* BalloonEngineBase>>#objStartGet */
static sqInt
objStartGet(void)
{
	return workBuffer[GWObjStart];
}

	/* BalloonEngineBase>>#objStartPut: */
static sqInt
objStartPut(sqInt value)
{
	return workBuffer[GWObjStart] = value;
}

	/* BalloonEngineBase>>#objUsedGet */
static sqInt
objUsedGet(void)
{
	return workBuffer[GWObjUsed];
}

	/* BalloonEngineBase>>#objUsedPut: */
static sqInt
objUsedPut(sqInt value)
{
	return workBuffer[GWObjUsed] = value;
}

	/* BalloonEngineBase>>#obj:at: */
static sqInt
objat(sqInt object, sqInt index)
{
	return objBuffer[object + index];
}

	/* BalloonEngineBase>>#obj:at:put: */
static sqInt
objatput(sqInt object, sqInt index, sqInt value)
{
	return objBuffer[object + index] = value;
}


/*	Common function so that we don't compute that wrong in any place
	and can easily find all the places where we deal with one-pixel offsets. */

	/* BalloonEnginePlugin>>#offsetFromWidth: */
static sqInt
offsetFromWidth(sqInt lineWidth)
{
	return lineWidth / 2;
}

	/* BalloonEngineBase>>#point1Get */
static int *
point1Get(void)
{
	return ((int *) (workBuffer + GWPoint1));
}

	/* BalloonEngineBase>>#point2Get */
static int *
point2Get(void)
{
	return ((int *) (workBuffer + GWPoint2));
}

	/* BalloonEngineBase>>#point3Get */
static int *
point3Get(void)
{
	return ((int *) (workBuffer + GWPoint3));
}

	/* BalloonEngineBase>>#point4Get */
static int *
point4Get(void)
{
	return ((int *) (workBuffer + GWPoint4));
}


/*	We have just blitted a scan line to the screen.
	Do whatever seems to be a good idea here. */
/*	Note: In the future we may check the time needed for this scan line and
	interrupt processing to give the Smalltalk code a chance to run at a
	certain time.
 */
/*	Check if there is any more work to do. */

	/* BalloonEngineBase>>#postDisplayAction */
static sqInt
postDisplayAction(void)
{
	if (((workBuffer[GWGETStart]) >= (workBuffer[GWGETUsed]))
	 && ((workBuffer[GWAETUsed]) == 0)) {

		/* No more entries to process */
		workBuffer[GWState] = GEStateCompleted;
	}
	if ((workBuffer[GWCurrentY]) >= (workBuffer[GWFillMaxY])) {

		/* Out of clipping range */
		workBuffer[GWState] = GEStateCompleted;
	}
	return 0;
}

	/* BalloonEngineBase>>#primitiveAbortProcessing */
EXPORT(sqInt)
primitiveAbortProcessing(void)
{
    sqInt failureCode;

	if (!((methodArgumentCount()) == 0)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFrom(stackValue(0)))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	workBuffer[GWState] = GEStateCompleted;
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	return 0;
}


/*	Note: No need to load either bitBlt or spanBuffer */

	/* BalloonEngineBase>>#primitiveAddActiveEdgeEntry */
EXPORT(sqInt)
primitiveAddActiveEdgeEntry(void)
{
    sqInt edge;
    sqInt edgeOop;
    sqInt failureCode;
    sqInt value;

	if (doProfileStats) {
		geProfileTime = ioMicroMSecs();
	}
	if (!((methodArgumentCount()) == 1)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(1), GEStateWaitingForEdge))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	edgeOop = stackObjectValue(0);
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	edge = loadEdgeStateFrom(edgeOop);
	if (edge == null) {
		return primitiveFailFor(GEFEdgeDataTooSmall);
	}
	if (!(needAvailableSpace(1))) {
		return primitiveFailFor(GEFWorkTooBig);
	}
	if ((objBuffer[edge + GENumLines]) > 0) {
		insertEdgeIntoAET(edge);
	}
	if (engineStopped) {
		return primitiveFailFor(GEFEngineStopped);
	}
	workBuffer[GWState] = GEStateAddingFromGET;
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(1);
	if (doProfileStats) {
		/* begin incrementStat:by: */
		workBuffer[GWCountAddAETEntry] = ((workBuffer[GWCountAddAETEntry]) + 1);
		/* begin incrementStat:by: */
		value = (ioMicroMSecs()) - geProfileTime;
		workBuffer[GWTimeAddAETEntry] = ((workBuffer[GWTimeAddAETEntry]) + value);
	}
	return 0;
}

	/* BalloonEnginePlugin>>#primitiveAddBezier */
EXPORT(sqInt)
primitiveAddBezier(void)
{
    sqInt endOop;
    sqInt failureCode;
    sqInt leftFill;
    sqInt nSegments;
    int *point;
    int *point1;
    int *point2;
    int *point3;
    sqInt rightFill;
    sqInt startOop;
    float *transform;
    float *transform1;
    float *transform2;
    float *transform3;
    sqInt viaOop;
    sqInt x;
    sqInt x1;
    sqInt x2;
    sqInt x3;
    double xValue;
    double xValue1;
    double xValue2;
    double xValue3;
    sqInt y;
    sqInt y1;
    sqInt y2;
    sqInt y3;
    double yValue;
    double yValue1;
    double yValue2;
    double yValue3;


	/* Fail if we have the wrong number of arguments */
	if (!((methodArgumentCount()) == 5)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	rightFill = positive32BitValueOf(stackValue(0));
	leftFill = positive32BitValueOf(stackValue(1));
	viaOop = stackObjectValue(2);
	endOop = stackObjectValue(3);
	startOop = stackObjectValue(4);
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(5), GEStateUnlocked))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	if (!((isFillOkay(leftFill))
		 && (isFillOkay(rightFill)))) {
		return primitiveFailFor(GEFWrongFill);
	}
	if ((leftFill == rightFill) && 0) {
		return pop(6);
	}
	loadPointfrom(((int *) (workBuffer + GWPoint1)), startOop);
	loadPointfrom(((int *) (workBuffer + GWPoint2)), viaOop);
	loadPointfrom(((int *) (workBuffer + GWPoint3)), endOop);
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	/* begin transformPoints: */
	if (3 > 0) {
		/* begin transformPoint: */
		point = ((int *) (workBuffer + GWPoint1));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue = ((double) ((((int *) point))[0]) );
			yValue = ((double) ((((int *) point))[1]) );
			/* begin edgeTransform */
			transform = ((float *) (workBuffer + GWEdgeTransform));
			x = ((sqInt)(((((transform[0]) * xValue) + ((transform[1]) * yValue)) + (transform[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y = ((sqInt)(((((transform[3]) * xValue) + ((transform[4]) * yValue)) + (transform[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point))[0] = x;
			(((int *) point))[1] = y;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point[0] = (((point[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point[1] = (((point[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	if (3 > 1) {
		/* begin transformPoint: */
		point1 = ((int *) (workBuffer + GWPoint2));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue1 = ((double) ((((int *) point1))[0]) );
			yValue1 = ((double) ((((int *) point1))[1]) );
			/* begin edgeTransform */
			transform1 = ((float *) (workBuffer + GWEdgeTransform));
			x1 = ((sqInt)(((((transform1[0]) * xValue1) + ((transform1[1]) * yValue1)) + (transform1[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y1 = ((sqInt)(((((transform1[3]) * xValue1) + ((transform1[4]) * yValue1)) + (transform1[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point1))[0] = x1;
			(((int *) point1))[1] = y1;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point1[0] = (((point1[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point1[1] = (((point1[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	if (3 > 2) {
		/* begin transformPoint: */
		point2 = ((int *) (workBuffer + GWPoint3));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue2 = ((double) ((((int *) point2))[0]) );
			yValue2 = ((double) ((((int *) point2))[1]) );
			/* begin edgeTransform */
			transform2 = ((float *) (workBuffer + GWEdgeTransform));
			x2 = ((sqInt)(((((transform2[0]) * xValue2) + ((transform2[1]) * yValue2)) + (transform2[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y2 = ((sqInt)(((((transform2[3]) * xValue2) + ((transform2[4]) * yValue2)) + (transform2[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point2))[0] = x2;
			(((int *) point2))[1] = y2;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point2[0] = (((point2[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point2[1] = (((point2[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	if (3 > 3) {
		/* begin transformPoint: */
		point3 = ((int *) (workBuffer + GWPoint4));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue3 = ((double) ((((int *) point3))[0]) );
			yValue3 = ((double) ((((int *) point3))[1]) );
			/* begin edgeTransform */
			transform3 = ((float *) (workBuffer + GWEdgeTransform));
			x3 = ((sqInt)(((((transform3[0]) * xValue3) + ((transform3[1]) * yValue3)) + (transform3[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y3 = ((sqInt)(((((transform3[3]) * xValue3) + ((transform3[4]) * yValue3)) + (transform3[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point3))[0] = x3;
			(((int *) point3))[1] = y3;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point3[0] = (((point3[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point3[1] = (((point3[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	nSegments = loadAndSubdivideBezierFromviatoisWide(((int *) (workBuffer + GWPoint1)), ((int *) (workBuffer + GWPoint2)), ((int *) (workBuffer + GWPoint3)), 0);
	/* begin needAvailableSpace: */
	if (((((GWHeaderSize + objUsed) + (workBuffer[GWGETUsed])) + (workBuffer[GWAETUsed])) + (nSegments * GBBaseSize)) > (workBuffer[GWBufferTop])) {
		/* begin stopBecauseOf: */
		workBuffer[GWStopReason] = GErrorNoMoreSpace;
		engineStopped = 1;
		goto l1;
	}
	l1:	/* end needAvailableSpace: */;
	if (!engineStopped) {
		leftFill = transformColor(leftFill);
		rightFill = transformColor(rightFill);
	}
	if (!engineStopped) {
		loadWideBezierlineFillleftFillrightFilln(0, 0, leftFill, rightFill, nSegments);
	}
	if (engineStopped) {

		/* Make sure the stack is okay */
		/* begin wbStackClear */
		workBuffer[GWBufferTop] = (workBuffer[GWSize]);
		return primitiveFailFor(GEFEngineStopped);
	}
	if (failed()) {
		return primitiveFailFor(GEFEntityLoadFailed);
	}
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(5);
	return 0;
}

	/* BalloonEnginePlugin>>#primitiveAddBezierShape */
EXPORT(sqInt)
primitiveAddBezierShape(void)
{
    sqInt failureCode;
    sqInt fillIndex;
    sqInt length;
    sqInt lineFill;
    sqInt lineWidth;
    sqInt nSegments;
    sqInt points;
    sqInt pointsIsArray;
    sqInt segSize;


	/* Fail if we have the wrong number of arguments */
	if (!((methodArgumentCount()) == 5)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	lineFill = positive32BitValueOf(stackValue(0));
	lineWidth = stackIntegerValue(1);
	fillIndex = positive32BitValueOf(stackValue(2));
	nSegments = stackIntegerValue(3);
	points = stackObjectValue(4);
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(5), GEStateUnlocked))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	length = slotSizeOf(points);
	if (isWords(points)) {

		/* Either PointArray or ShortPointArray */
		pointsIsArray = 0;
		if (!((length == (nSegments * 3))
			 || (length == (nSegments * 6)))) {
			return primitiveFailFor(PrimErrBadArgument);
		}
	}
	else {

		/* Must be Array of points */
		if (!(isArray(points))) {
			return primitiveFailFor(PrimErrBadArgument);
		}
		if (!(length == (nSegments * 3))) {
			return primitiveFailFor(PrimErrBadArgument);
		}
		pointsIsArray = 1;
	}
	if ((lineWidth == 0)
	 || (lineFill == 0)) {
		segSize = GLBaseSize;
	}
	else {
		segSize = GLWideSize;
	}
	if (!(needAvailableSpace(segSize * nSegments))) {
		return primitiveFailFor(GEFWorkTooBig);
	}
	if (!((isFillOkay(lineFill))
		 && (isFillOkay(fillIndex)))) {
		return primitiveFailFor(GEFWrongFill);
	}
	lineFill = transformColor(lineFill);
	fillIndex = transformColor(fillIndex);
	if (engineStopped) {
		return primitiveFailFor(GEFEngineStopped);
	}
	if (((lineFill == 0)
	 || (lineWidth == 0))
	 && (fillIndex == 0)) {
		return pop(5);
	}
	if (!(lineWidth == 0)) {
		lineWidth = transformWidth(lineWidth);
		if (lineWidth < 1) {
			lineWidth = 1;
		}
	}
	if (pointsIsArray) {
		loadArrayShapenSegmentsfilllineWidthlineFill(points, nSegments, fillIndex, lineWidth, lineFill);
	}
	else {
		loadShapenSegmentsfilllineWidthlineFillpointsShort(firstIndexableField(points), nSegments, fillIndex, lineWidth, lineFill, (nSegments * 3) == length);
	}
	if (engineStopped) {
		return primitiveFailFor(GEFEngineStopped);
	}
	if (failed()) {
		return primitiveFailFor(GEFEntityLoadFailed);
	}
	/* begin needsFlushPut: */
	workBuffer[GWNeedsFlush] = 1;
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(5);
	return 0;
}

	/* BalloonEnginePlugin>>#primitiveAddBitmapFill */
EXPORT(sqInt)
primitiveAddBitmapFill(void)
{
    sqInt bmBits;
    sqInt bmBitsSize;
    sqInt bmDepth;
    sqInt bmFill;
    sqInt bmHeight;
    sqInt bmRaster;
    sqInt bmWidth;
    int *cm;
    int *cmBits;
    sqInt cmOop;
    sqInt cmSize;
    sqInt dirOop;
    sqInt failureCode;
    sqInt fill;
    sqInt fill1;
    sqInt fillSize;
    sqInt formOop;
    sqInt i;
    sqInt nrmOop;
    sqInt originOop;
    sqInt ppw;
    sqInt tileFlag;
    sqInt tileFlag1;
    sqInt xIndex;


	/* Fail if we have the wrong number of arguments */
	if (!((methodArgumentCount()) == 7)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	xIndex = stackIntegerValue(0);
	if (xIndex <= 0) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	nrmOop = stackObjectValue(1);
	dirOop = stackObjectValue(2);
	originOop = stackObjectValue(3);
	tileFlag = booleanValueOf(stackValue(4));
	cmOop = stackObjectValue(5);
	formOop = stackObjectValue(6);
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(7), GEStateUnlocked))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	loadPointfrom(((int *) (workBuffer + GWPoint1)), originOop);
	loadPointfrom(((int *) (workBuffer + GWPoint2)), dirOop);
	loadPointfrom(((int *) (workBuffer + GWPoint3)), nrmOop);
	if (failed()) {
		return primitiveFailFor(GEFBadPoint);
	}
	/* begin loadBitmapFill:colormap:tile:from:along:normal:xIndex: */
	tileFlag1 = (tileFlag
		? 1
		: 0);
	if (cmOop == (nilObject())) {
		cmSize = 0;
		cmBits = null;
	}
	else {
		if (!((fetchClassOf(cmOop)) == (classBitmap()))) {
			fill = primitiveFail();
			goto l14;
		}
		cmSize = slotSizeOf(cmOop);
		cmBits = firstIndexableField(cmOop);
	}
	if (!(isPointers(formOop))) {
		fill = primitiveFail();
		goto l14;
	}
	if ((slotSizeOf(formOop)) < 5) {
		fill = primitiveFail();
		goto l14;
	}
	bmBits = fetchPointerofObject(0, formOop);
	if (!((fetchClassOf(bmBits)) == (classBitmap()))) {
		fill = primitiveFail();
		goto l14;
	}
	bmBitsSize = slotSizeOf(bmBits);
	bmWidth = fetchIntegerofObject(1, formOop);
	bmHeight = fetchIntegerofObject(2, formOop);
	bmDepth = fetchIntegerofObject(3, formOop);
	if (failed()) {
		fill = null;
		goto l14;
	}
	if (!((bmWidth >= 0)
		 && (bmHeight >= 0))) {
		fill = primitiveFail();
		goto l14;
	}
	if (!((((((bmDepth == 32) || (bmDepth == 8)) || (bmDepth == 16)) || (bmDepth == 1)) || (bmDepth == 2)) || (bmDepth == 4))) {
		fill = primitiveFail();
		goto l14;
	}
	if (!((cmSize == 0)
		 || (cmSize == (1U << bmDepth)))) {
		fill = primitiveFail();
		goto l14;
	}
	ppw = 32 / bmDepth;
	bmRaster = (bmWidth + (ppw - 1)) / ppw;
	if (!(bmBitsSize == (bmRaster * bmHeight))) {
		fill = primitiveFail();
		goto l14;
	}
	/* begin allocateBitmapFill:colormap: */
	fillSize = GBMBaseSize + cmSize;
	if (!(allocateObjEntry(fillSize))) {
		bmFill = 0;
		goto l11;
	}
	fill1 = objUsed;
	objUsed = fill1 + fillSize;
	/* begin obj:at:put: */
	objBuffer[fill1 + GEObjectType] = GEPrimitiveClippedBitmapFill;
	/* begin obj:at:put: */
	objBuffer[fill1 + GEObjectIndex] = 0;
	/* begin obj:at:put: */
	objBuffer[fill1 + GEObjectLength] = fillSize;
	cm = (objBuffer + fill1) + GBColormapOffset;
	if ((workBuffer[GWHasColorTransform]) != 0) {
		for (i = 0; i < cmSize; i += 1) {
			cm[i] = (transformColor(cmBits[i]));
		}
	}
	else {
		for (i = 0; i < cmSize; i += 1) {
			cm[i] = (cmBits[i]);
		}
	}
	/* begin obj:at:put: */
	objBuffer[fill1 + GBColormapSize] = cmSize;
	bmFill = fill1;
	l11:	/* end allocateBitmapFill:colormap: */;
	if (engineStopped) {
		fill = null;
		goto l14;
	}
	/* begin bitmapWidthOf:put: */
	objBuffer[bmFill + GBBitmapWidth] = bmWidth;
	/* begin bitmapHeightOf:put: */
	objBuffer[bmFill + GBBitmapHeight] = bmHeight;
	/* begin bitmapDepthOf:put: */
	objBuffer[bmFill + GBBitmapDepth] = bmDepth;
	/* begin bitmapRasterOf:put: */
	objBuffer[bmFill + GBBitmapRaster] = bmRaster;
	/* begin bitmapSizeOf:put: */
	objBuffer[bmFill + GBBitmapSize] = bmBitsSize;
	/* begin bitmapTileFlagOf:put: */
	objBuffer[bmFill + GBTileFlag] = tileFlag1;
	/* begin obj:at:put: */
	objBuffer[bmFill + GEObjectIndex] = (xIndex - 1);
	loadFillOrientationfromalongnormalwidthheight(bmFill, ((int *) (workBuffer + GWPoint1)), ((int *) (workBuffer + GWPoint2)), ((int *) (workBuffer + GWPoint3)), bmWidth, bmHeight);
	fill = bmFill;
	l14:	/* end loadBitmapFill:colormap:tile:from:along:normal:xIndex: */;
	if (engineStopped) {

		/* Make sure the stack is okay */
		return primitiveFailFor(GEFEngineStopped);
	}
	if (failed()) {
		return primitiveFailFor(GEFEntityLoadFailed);
	}
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	popthenPush(8, positive32BitIntegerFor(fill));
	return 0;
}

	/* BalloonEnginePlugin>>#primitiveAddCompressedShape */
EXPORT(sqInt)
primitiveAddCompressedShape(void)
{
    sqInt failureCode;
    sqInt fillIndexList;
    sqInt leftFills;
    sqInt lineFills;
    sqInt lineWidths;
    sqInt nSegments;
    sqInt points;
    int pointsShort;
    sqInt rightFills;


	/* Fail if we have the wrong number of arguments */
	if (!((methodArgumentCount()) == 7)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	fillIndexList = stackObjectValue(0);
	lineFills = stackObjectValue(1);
	lineWidths = stackObjectValue(2);
	rightFills = stackObjectValue(3);
	leftFills = stackObjectValue(4);
	nSegments = stackIntegerValue(5);
	points = stackObjectValue(6);
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(7), GEStateUnlocked))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	if (!(checkCompressedShapesegmentsleftFillsrightFillslineWidthslineFillsfillIndexList(points, nSegments, leftFills, rightFills, lineWidths, lineFills, fillIndexList))) {
		return primitiveFailFor(GEFEntityCheckFailed);
	}
	if (!(needAvailableSpace((((GBBaseSize < GLBaseSize) ? GLBaseSize : GBBaseSize)) * nSegments))) {
		return primitiveFailFor(GEFWorkTooBig);
	}

	/* Then actually load the compressed shape */
	pointsShort = (slotSizeOf(points)) == (nSegments * 3);
	loadCompressedShapesegmentsleftFillsrightFillslineWidthslineFillsfillIndexListpointShort(firstIndexableField(points), nSegments, firstIndexableField(leftFills), firstIndexableField(rightFills), firstIndexableField(lineWidths), firstIndexableField(lineFills), firstIndexableField(fillIndexList), pointsShort);
	if (engineStopped) {
		return primitiveFailFor(GEFEngineStopped);
	}
	if (failed()) {
		return primitiveFailFor(GEFEntityLoadFailed);
	}
	/* begin needsFlushPut: */
	workBuffer[GWNeedsFlush] = 1;
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(7);
	return 0;
}

	/* BalloonEnginePlugin>>#primitiveAddGradientFill */
EXPORT(sqInt)
primitiveAddGradientFill(void)
{
    sqInt dirOop;
    sqInt failureCode;
    sqInt fill;
    sqInt isRadial;
    sqInt nrmOop;
    sqInt originOop;
    sqInt rampOop;


	/* Fail if we have the wrong number of arguments */
	if (!((methodArgumentCount()) == 5)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	isRadial = booleanValueOf(stackValue(0));
	nrmOop = stackValue(1);
	dirOop = stackValue(2);
	originOop = stackValue(3);
	rampOop = stackValue(4);
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(5), GEStateUnlocked))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	loadPointfrom(((int *) (workBuffer + GWPoint1)), originOop);
	loadPointfrom(((int *) (workBuffer + GWPoint2)), dirOop);
	loadPointfrom(((int *) (workBuffer + GWPoint3)), nrmOop);
	if (failed()) {
		return primitiveFailFor(GEFBadPoint);
	}
	fill = loadGradientFillfromalongnormalisRadial(rampOop, ((int *) (workBuffer + GWPoint1)), ((int *) (workBuffer + GWPoint2)), ((int *) (workBuffer + GWPoint3)), isRadial);
	if (engineStopped) {

		/* Make sure the stack is okay */
		return primitiveFailFor(GEFEngineStopped);
	}
	if (failed()) {
		return primitiveFailFor(GEFEntityLoadFailed);
	}
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	popthenPush(6, positive32BitIntegerFor(fill));
	return 0;
}

	/* BalloonEnginePlugin>>#primitiveAddLine */
EXPORT(sqInt)
primitiveAddLine(void)
{
    sqInt endOop;
    sqInt failureCode;
    sqInt leftFill;
    int *point;
    int *point1;
    int *point2;
    int *point3;
    sqInt rightFill;
    sqInt startOop;
    float *transform;
    float *transform1;
    float *transform2;
    float *transform3;
    sqInt x;
    sqInt x1;
    sqInt x2;
    sqInt x3;
    double xValue;
    double xValue1;
    double xValue2;
    double xValue3;
    sqInt y;
    sqInt y1;
    sqInt y2;
    sqInt y3;
    double yValue;
    double yValue1;
    double yValue2;
    double yValue3;


	/* Fail if we have the wrong number of arguments */
	if (!((methodArgumentCount()) == 4)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	rightFill = positive32BitValueOf(stackValue(0));
	leftFill = positive32BitValueOf(stackValue(1));
	endOop = stackObjectValue(2);
	startOop = stackObjectValue(3);
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(4), GEStateUnlocked))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	if (!((isFillOkay(leftFill))
		 && (isFillOkay(rightFill)))) {
		return primitiveFailFor(GEFWrongFill);
	}
	loadPointfrom(((int *) (workBuffer + GWPoint1)), startOop);
	loadPointfrom(((int *) (workBuffer + GWPoint2)), endOop);
	if (failed()) {
		return primitiveFailFor(GEFBadPoint);
	}
	/* begin transformPoints: */
	if (2 > 0) {
		/* begin transformPoint: */
		point = ((int *) (workBuffer + GWPoint1));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue = ((double) ((((int *) point))[0]) );
			yValue = ((double) ((((int *) point))[1]) );
			/* begin edgeTransform */
			transform = ((float *) (workBuffer + GWEdgeTransform));
			x = ((sqInt)(((((transform[0]) * xValue) + ((transform[1]) * yValue)) + (transform[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y = ((sqInt)(((((transform[3]) * xValue) + ((transform[4]) * yValue)) + (transform[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point))[0] = x;
			(((int *) point))[1] = y;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point[0] = (((point[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point[1] = (((point[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	if (2 > 1) {
		/* begin transformPoint: */
		point1 = ((int *) (workBuffer + GWPoint2));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue1 = ((double) ((((int *) point1))[0]) );
			yValue1 = ((double) ((((int *) point1))[1]) );
			/* begin edgeTransform */
			transform1 = ((float *) (workBuffer + GWEdgeTransform));
			x1 = ((sqInt)(((((transform1[0]) * xValue1) + ((transform1[1]) * yValue1)) + (transform1[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y1 = ((sqInt)(((((transform1[3]) * xValue1) + ((transform1[4]) * yValue1)) + (transform1[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point1))[0] = x1;
			(((int *) point1))[1] = y1;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point1[0] = (((point1[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point1[1] = (((point1[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	if (2 > 2) {
		/* begin transformPoint: */
		point2 = ((int *) (workBuffer + GWPoint3));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue2 = ((double) ((((int *) point2))[0]) );
			yValue2 = ((double) ((((int *) point2))[1]) );
			/* begin edgeTransform */
			transform2 = ((float *) (workBuffer + GWEdgeTransform));
			x2 = ((sqInt)(((((transform2[0]) * xValue2) + ((transform2[1]) * yValue2)) + (transform2[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y2 = ((sqInt)(((((transform2[3]) * xValue2) + ((transform2[4]) * yValue2)) + (transform2[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point2))[0] = x2;
			(((int *) point2))[1] = y2;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point2[0] = (((point2[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point2[1] = (((point2[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	if (2 > 3) {
		/* begin transformPoint: */
		point3 = ((int *) (workBuffer + GWPoint4));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue3 = ((double) ((((int *) point3))[0]) );
			yValue3 = ((double) ((((int *) point3))[1]) );
			/* begin edgeTransform */
			transform3 = ((float *) (workBuffer + GWEdgeTransform));
			x3 = ((sqInt)(((((transform3[0]) * xValue3) + ((transform3[1]) * yValue3)) + (transform3[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y3 = ((sqInt)(((((transform3[3]) * xValue3) + ((transform3[4]) * yValue3)) + (transform3[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point3))[0] = x3;
			(((int *) point3))[1] = y3;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point3[0] = (((point3[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point3[1] = (((point3[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	leftFill = transformColor(leftFill);
	rightFill = transformColor(rightFill);
	if (engineStopped) {
		return primitiveFailFor(GEFEngineStopped);
	}
	loadWideLinefromtolineFillleftFillrightFill(0, ((int *) (workBuffer + GWPoint1)), ((int *) (workBuffer + GWPoint2)), 0, leftFill, rightFill);
	if (engineStopped) {
		return primitiveFailFor(GEFEngineStopped);
	}
	if (failed()) {
		return primitiveFailFor(GEFEntityLoadFailed);
	}
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(4);
	return 0;
}

	/* BalloonEnginePlugin>>#primitiveAddOval */
EXPORT(sqInt)
primitiveAddOval(void)
{
    sqInt borderIndex;
    sqInt borderWidth;
    sqInt endOop;
    sqInt failureCode;
    sqInt fillIndex;
    sqInt startOop;


	/* Fail if we have the wrong number of arguments */
	if (!((methodArgumentCount()) == 5)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	borderIndex = positive32BitValueOf(stackValue(0));
	borderWidth = stackIntegerValue(1);
	fillIndex = positive32BitValueOf(stackValue(2));
	endOop = stackObjectValue(3);
	startOop = stackObjectValue(4);
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(5), GEStateUnlocked))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	if (!((isFillOkay(borderIndex))
		 && (isFillOkay(fillIndex)))) {
		return primitiveFailFor(GEFWrongFill);
	}
	fillIndex = transformColor(fillIndex);
	borderIndex = transformColor(borderIndex);
	if (engineStopped) {
		return primitiveFailFor(GEFEngineStopped);
	}
	if ((fillIndex == 0)
	 && ((borderIndex == 0)
	 || (borderWidth <= 0))) {
		return pop(5);
	}
	if (!(needAvailableSpace(16 * GBBaseSize))) {
		return primitiveFailFor(GEFWorkTooBig);
	}
	if ((borderWidth > 0)
	 && (borderIndex != 0)) {
		borderWidth = transformWidth(borderWidth);
	}
	else {
		borderWidth = 0;
	}
	loadPointfrom(((int *) (workBuffer + GWPoint1)), startOop);
	loadPointfrom(((int *) (workBuffer + GWPoint2)), endOop);
	if (failed()) {
		return primitiveFailFor(GEFBadPoint);
	}
	loadOvallineFillleftFillrightFill(borderWidth, borderIndex, 0, fillIndex);
	if (engineStopped) {
		/* begin wbStackClear */
		workBuffer[GWBufferTop] = (workBuffer[GWSize]);
		return primitiveFailFor(GEFEngineStopped);
	}
	if (failed()) {
		return primitiveFailFor(GEFEntityLoadFailed);
	}
	/* begin needsFlushPut: */
	workBuffer[GWNeedsFlush] = 1;
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(5);
	return 0;
}

	/* BalloonEnginePlugin>>#primitiveAddPolygon */
EXPORT(sqInt)
primitiveAddPolygon(void)
{
    sqInt failureCode;
    sqInt fillIndex;
    sqInt i;
    sqInt i1;
    sqInt length;
    sqInt lineFill;
    sqInt lineWidth;
    sqInt nPoints;
    int *point;
    int *point1;
    int *point11;
    int *point2;
    int *point21;
    int *point3;
    int *point31;
    int *point4;
    sqInt points;
    int *points1;
    sqInt pointsIsArray;
    sqInt segSize;
    float *transform;
    float *transform1;
    float *transform11;
    float *transform2;
    float *transform21;
    float *transform3;
    float *transform31;
    float *transform4;
    sqInt x;
    int x0;
    sqInt x01;
    int x1;
    sqInt x11;
    sqInt x111;
    sqInt x12;
    sqInt x2;
    sqInt x21;
    sqInt x3;
    sqInt x31;
    sqInt x4;
    double xValue;
    double xValue1;
    double xValue11;
    double xValue2;
    double xValue21;
    double xValue3;
    double xValue31;
    double xValue4;
    sqInt y;
    int y0;
    sqInt y01;
    int y1;
    sqInt y11;
    sqInt y111;
    sqInt y12;
    sqInt y2;
    sqInt y21;
    sqInt y3;
    sqInt y31;
    sqInt y4;
    double yValue;
    double yValue1;
    double yValue11;
    double yValue2;
    double yValue21;
    double yValue3;
    double yValue31;
    double yValue4;


	/* Fail if we have the wrong number of arguments */
	if (!((methodArgumentCount()) == 5)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	lineFill = positive32BitValueOf(stackValue(0));
	lineWidth = stackIntegerValue(1);
	fillIndex = positive32BitValueOf(stackValue(2));
	nPoints = stackIntegerValue(3);
	points = stackObjectValue(4);
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(5), GEStateUnlocked))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	length = slotSizeOf(points);
	if (isWords(points)) {

		/* Either PointArray or ShortPointArray */
		pointsIsArray = 0;
		if (!((length == nPoints)
			 || ((nPoints * 2) == length))) {
			return primitiveFailFor(PrimErrBadArgument);
		}
	}
	else {

		/* Must be Array of points */
		if (!(isArray(points))) {
			return primitiveFailFor(PrimErrBadArgument);
		}
		if (!(length == nPoints)) {
			return primitiveFailFor(PrimErrBadArgument);
		}
		pointsIsArray = 1;
	}
	if ((lineWidth == 0)
	 || (lineFill == 0)) {
		segSize = GLBaseSize;
	}
	else {
		segSize = GLWideSize;
	}
	if (!(needAvailableSpace(segSize * nPoints))) {
		return primitiveFail();
	}
	if (!((isFillOkay(lineFill))
		 && (isFillOkay(fillIndex)))) {
		return primitiveFailFor(GEFWrongFill);
	}
	lineFill = transformColor(lineFill);
	fillIndex = transformColor(fillIndex);
	if (engineStopped) {
		return primitiveFailFor(GEFEngineStopped);
	}
	if (((lineFill == 0)
	 || (lineWidth == 0))
	 && (fillIndex == 0)) {
		return pop(5);
	}
	if (!(lineWidth == 0)) {
		lineWidth = transformWidth(lineWidth);
	}
	if (pointsIsArray) {
		/* begin loadArrayPolygon:nPoints:fill:lineWidth:lineFill: */
		loadPointfrom(((int *) (workBuffer + GWPoint1)), fetchPointerofObject(0, points));
		if (failed()) {
			goto l7;
		}
		x0 = (((int *) (workBuffer + GWPoint1)))[0];
		y0 = (((int *) (workBuffer + GWPoint1)))[1];
		for (i = 1; i < nPoints; i += 1) {
			loadPointfrom(((int *) (workBuffer + GWPoint1)), fetchPointerofObject(i, points));
			if (failed()) {
				goto l7;
			}
			x1 = (((int *) (workBuffer + GWPoint1)))[0];
			y1 = (((int *) (workBuffer + GWPoint1)))[1];
			(((int *) (workBuffer + GWPoint1)))[0] = x0;
			(((int *) (workBuffer + GWPoint1)))[1] = y0;
			(((int *) (workBuffer + GWPoint2)))[0] = x1;
			(((int *) (workBuffer + GWPoint2)))[1] = y1;
			/* begin transformPoints: */
			if (2 > 0) {
				/* begin transformPoint: */
				point = ((int *) (workBuffer + GWPoint1));
				if ((workBuffer[GWHasEdgeTransform]) != 0) {

					/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
					/* begin transformPoint:into: */
					xValue = ((double) ((((int *) point))[0]) );
					yValue = ((double) ((((int *) point))[1]) );
					/* begin edgeTransform */
					transform = ((float *) (workBuffer + GWEdgeTransform));
					x = ((sqInt)(((((transform[0]) * xValue) + ((transform[1]) * yValue)) + (transform[2])) * (((double) (workBuffer[GWAALevel]) ))));
					y = ((sqInt)(((((transform[3]) * xValue) + ((transform[4]) * yValue)) + (transform[5])) * (((double) (workBuffer[GWAALevel]) ))));
					(((int *) point))[0] = x;
					(((int *) point))[1] = y;
				}
				else {

					/* Multiply each component by aaLevel and add a half pixel */
					point[0] = (((point[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
					point[1] = (((point[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
				}
			}
			if (2 > 1) {
				/* begin transformPoint: */
				point1 = ((int *) (workBuffer + GWPoint2));
				if ((workBuffer[GWHasEdgeTransform]) != 0) {

					/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
					/* begin transformPoint:into: */
					xValue1 = ((double) ((((int *) point1))[0]) );
					yValue1 = ((double) ((((int *) point1))[1]) );
					/* begin edgeTransform */
					transform1 = ((float *) (workBuffer + GWEdgeTransform));
					x11 = ((sqInt)(((((transform1[0]) * xValue1) + ((transform1[1]) * yValue1)) + (transform1[2])) * (((double) (workBuffer[GWAALevel]) ))));
					y11 = ((sqInt)(((((transform1[3]) * xValue1) + ((transform1[4]) * yValue1)) + (transform1[5])) * (((double) (workBuffer[GWAALevel]) ))));
					(((int *) point1))[0] = x11;
					(((int *) point1))[1] = y11;
				}
				else {

					/* Multiply each component by aaLevel and add a half pixel */
					point1[0] = (((point1[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
					point1[1] = (((point1[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
				}
			}
			if (2 > 2) {
				/* begin transformPoint: */
				point2 = ((int *) (workBuffer + GWPoint3));
				if ((workBuffer[GWHasEdgeTransform]) != 0) {

					/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
					/* begin transformPoint:into: */
					xValue2 = ((double) ((((int *) point2))[0]) );
					yValue2 = ((double) ((((int *) point2))[1]) );
					/* begin edgeTransform */
					transform2 = ((float *) (workBuffer + GWEdgeTransform));
					x2 = ((sqInt)(((((transform2[0]) * xValue2) + ((transform2[1]) * yValue2)) + (transform2[2])) * (((double) (workBuffer[GWAALevel]) ))));
					y2 = ((sqInt)(((((transform2[3]) * xValue2) + ((transform2[4]) * yValue2)) + (transform2[5])) * (((double) (workBuffer[GWAALevel]) ))));
					(((int *) point2))[0] = x2;
					(((int *) point2))[1] = y2;
				}
				else {

					/* Multiply each component by aaLevel and add a half pixel */
					point2[0] = (((point2[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
					point2[1] = (((point2[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
				}
			}
			if (2 > 3) {
				/* begin transformPoint: */
				point3 = ((int *) (workBuffer + GWPoint4));
				if ((workBuffer[GWHasEdgeTransform]) != 0) {

					/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
					/* begin transformPoint:into: */
					xValue3 = ((double) ((((int *) point3))[0]) );
					yValue3 = ((double) ((((int *) point3))[1]) );
					/* begin edgeTransform */
					transform3 = ((float *) (workBuffer + GWEdgeTransform));
					x3 = ((sqInt)(((((transform3[0]) * xValue3) + ((transform3[1]) * yValue3)) + (transform3[2])) * (((double) (workBuffer[GWAALevel]) ))));
					y3 = ((sqInt)(((((transform3[3]) * xValue3) + ((transform3[4]) * yValue3)) + (transform3[5])) * (((double) (workBuffer[GWAALevel]) ))));
					(((int *) point3))[0] = x3;
					(((int *) point3))[1] = y3;
				}
				else {

					/* Multiply each component by aaLevel and add a half pixel */
					point3[0] = (((point3[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
					point3[1] = (((point3[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
				}
			}
			loadWideLinefromtolineFillleftFillrightFill(lineWidth, ((int *) (workBuffer + GWPoint1)), ((int *) (workBuffer + GWPoint2)), lineFill, fillIndex, 0);
			if (engineStopped) {
				goto l7;
			}
			x0 = x1;
			y0 = y1;
		}
	l7:	/* end loadArrayPolygon:nPoints:fill:lineWidth:lineFill: */;
	}
	else {
		/* begin loadPolygon:nPoints:fill:lineWidth:lineFill:pointsShort: */
		points1 = ((int *) (firstIndexableField(points)));
		if (nPoints == length) {
			/* begin loadPointShortAt:from: */
			x01 = (((short *) points1))[0];
			/* begin loadPointShortAt:from: */
			y01 = (((short *) points1))[1];
		}
		else {
			/* begin loadPointIntAt:from: */
			x01 = (((int *) points1))[0];
			/* begin loadPointIntAt:from: */
			y01 = (((int *) points1))[1];
		}
		for (i1 = 1; i1 < nPoints; i1 += 1) {
			if (nPoints == length) {
				/* begin loadPointShortAt:from: */
				x12 = (((short *) points1))[i1 * 2];
				/* begin loadPointShortAt:from: */
				y12 = (((short *) points1))[(i1 * 2) + 1];
			}
			else {
				/* begin loadPointIntAt:from: */
				x12 = (((int *) points1))[i1 * 2];
				/* begin loadPointIntAt:from: */
				y12 = (((int *) points1))[(i1 * 2) + 1];
			}
			(((int *) (workBuffer + GWPoint1)))[0] = x01;
			(((int *) (workBuffer + GWPoint1)))[1] = y01;
			(((int *) (workBuffer + GWPoint2)))[0] = x12;
			(((int *) (workBuffer + GWPoint2)))[1] = y12;
			/* begin transformPoints: */
			if (2 > 0) {
				/* begin transformPoint: */
				point4 = ((int *) (workBuffer + GWPoint1));
				if ((workBuffer[GWHasEdgeTransform]) != 0) {

					/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
					/* begin transformPoint:into: */
					xValue4 = ((double) ((((int *) point4))[0]) );
					yValue4 = ((double) ((((int *) point4))[1]) );
					/* begin edgeTransform */
					transform4 = ((float *) (workBuffer + GWEdgeTransform));
					x4 = ((sqInt)(((((transform4[0]) * xValue4) + ((transform4[1]) * yValue4)) + (transform4[2])) * (((double) (workBuffer[GWAALevel]) ))));
					y4 = ((sqInt)(((((transform4[3]) * xValue4) + ((transform4[4]) * yValue4)) + (transform4[5])) * (((double) (workBuffer[GWAALevel]) ))));
					(((int *) point4))[0] = x4;
					(((int *) point4))[1] = y4;
				}
				else {

					/* Multiply each component by aaLevel and add a half pixel */
					point4[0] = (((point4[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
					point4[1] = (((point4[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
				}
			}
			if (2 > 1) {
				/* begin transformPoint: */
				point11 = ((int *) (workBuffer + GWPoint2));
				if ((workBuffer[GWHasEdgeTransform]) != 0) {

					/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
					/* begin transformPoint:into: */
					xValue11 = ((double) ((((int *) point11))[0]) );
					yValue11 = ((double) ((((int *) point11))[1]) );
					/* begin edgeTransform */
					transform11 = ((float *) (workBuffer + GWEdgeTransform));
					x111 = ((sqInt)(((((transform11[0]) * xValue11) + ((transform11[1]) * yValue11)) + (transform11[2])) * (((double) (workBuffer[GWAALevel]) ))));
					y111 = ((sqInt)(((((transform11[3]) * xValue11) + ((transform11[4]) * yValue11)) + (transform11[5])) * (((double) (workBuffer[GWAALevel]) ))));
					(((int *) point11))[0] = x111;
					(((int *) point11))[1] = y111;
				}
				else {

					/* Multiply each component by aaLevel and add a half pixel */
					point11[0] = (((point11[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
					point11[1] = (((point11[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
				}
			}
			if (2 > 2) {
				/* begin transformPoint: */
				point21 = ((int *) (workBuffer + GWPoint3));
				if ((workBuffer[GWHasEdgeTransform]) != 0) {

					/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
					/* begin transformPoint:into: */
					xValue21 = ((double) ((((int *) point21))[0]) );
					yValue21 = ((double) ((((int *) point21))[1]) );
					/* begin edgeTransform */
					transform21 = ((float *) (workBuffer + GWEdgeTransform));
					x21 = ((sqInt)(((((transform21[0]) * xValue21) + ((transform21[1]) * yValue21)) + (transform21[2])) * (((double) (workBuffer[GWAALevel]) ))));
					y21 = ((sqInt)(((((transform21[3]) * xValue21) + ((transform21[4]) * yValue21)) + (transform21[5])) * (((double) (workBuffer[GWAALevel]) ))));
					(((int *) point21))[0] = x21;
					(((int *) point21))[1] = y21;
				}
				else {

					/* Multiply each component by aaLevel and add a half pixel */
					point21[0] = (((point21[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
					point21[1] = (((point21[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
				}
			}
			if (2 > 3) {
				/* begin transformPoint: */
				point31 = ((int *) (workBuffer + GWPoint4));
				if ((workBuffer[GWHasEdgeTransform]) != 0) {

					/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
					/* begin transformPoint:into: */
					xValue31 = ((double) ((((int *) point31))[0]) );
					yValue31 = ((double) ((((int *) point31))[1]) );
					/* begin edgeTransform */
					transform31 = ((float *) (workBuffer + GWEdgeTransform));
					x31 = ((sqInt)(((((transform31[0]) * xValue31) + ((transform31[1]) * yValue31)) + (transform31[2])) * (((double) (workBuffer[GWAALevel]) ))));
					y31 = ((sqInt)(((((transform31[3]) * xValue31) + ((transform31[4]) * yValue31)) + (transform31[5])) * (((double) (workBuffer[GWAALevel]) ))));
					(((int *) point31))[0] = x31;
					(((int *) point31))[1] = y31;
				}
				else {

					/* Multiply each component by aaLevel and add a half pixel */
					point31[0] = (((point31[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
					point31[1] = (((point31[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
				}
			}
			loadWideLinefromtolineFillleftFillrightFill(lineWidth, ((int *) (workBuffer + GWPoint1)), ((int *) (workBuffer + GWPoint2)), lineFill, fillIndex, 0);
			if (engineStopped) {
				goto l20;
			}
			x01 = x12;
			y01 = y12;
		}
	l20:	/* end loadPolygon:nPoints:fill:lineWidth:lineFill:pointsShort: */;
	}
	if (engineStopped) {
		return primitiveFailFor(GEFEngineStopped);
	}
	if (failed()) {
		return primitiveFailFor(GEFEntityLoadFailed);
	}
	/* begin needsFlushPut: */
	workBuffer[GWNeedsFlush] = 1;
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(5);
	return 0;
}

	/* BalloonEnginePlugin>>#primitiveAddRect */
EXPORT(sqInt)
primitiveAddRect(void)
{
    sqInt borderIndex;
    sqInt borderWidth;
    sqInt endOop;
    sqInt failureCode;
    sqInt fillIndex;
    int *point;
    int *point1;
    int *point2;
    int *point3;
    sqInt startOop;
    float *transform;
    float *transform1;
    float *transform2;
    float *transform3;
    sqInt x;
    sqInt x1;
    sqInt x2;
    sqInt x3;
    double xValue;
    double xValue1;
    double xValue2;
    double xValue3;
    sqInt y;
    sqInt y1;
    sqInt y2;
    sqInt y3;
    double yValue;
    double yValue1;
    double yValue2;
    double yValue3;


	/* Fail if we have the wrong number of arguments */
	if (!((methodArgumentCount()) == 5)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	borderIndex = positive32BitValueOf(stackValue(0));
	borderWidth = stackIntegerValue(1);
	fillIndex = positive32BitValueOf(stackValue(2));
	endOop = stackObjectValue(3);
	startOop = stackObjectValue(4);
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(5), GEStateUnlocked))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	if (!((isFillOkay(borderIndex))
		 && (isFillOkay(fillIndex)))) {
		return primitiveFailFor(GEFWrongFill);
	}
	borderIndex = transformColor(borderIndex);
	fillIndex = transformColor(fillIndex);
	if (engineStopped) {
		return primitiveFailFor(GEFEngineStopped);
	}
	if ((fillIndex == 0)
	 && ((borderIndex == 0)
	 || (borderWidth == 0))) {
		return pop(5);
	}
	if (!(needAvailableSpace(4 * GLBaseSize))) {
		return primitiveFailFor(GEFWorkTooBig);
	}
	if ((borderWidth > 0)
	 && (borderIndex != 0)) {
		borderWidth = transformWidth(borderWidth);
	}
	else {
		borderWidth = 0;
	}
	loadPointfrom(((int *) (workBuffer + GWPoint1)), startOop);
	loadPointfrom(((int *) (workBuffer + GWPoint3)), endOop);
	if (failed()) {
		return primitiveFailFor(GEFBadPoint);
	}
	(((int *) (workBuffer + GWPoint2)))[0] = ((((int *) (workBuffer + GWPoint3)))[0]);
	(((int *) (workBuffer + GWPoint2)))[1] = ((((int *) (workBuffer + GWPoint1)))[1]);
	(((int *) (workBuffer + GWPoint4)))[0] = ((((int *) (workBuffer + GWPoint1)))[0]);
	(((int *) (workBuffer + GWPoint4)))[1] = ((((int *) (workBuffer + GWPoint3)))[1]);
	/* begin transformPoints: */
	if (4 > 0) {
		/* begin transformPoint: */
		point = ((int *) (workBuffer + GWPoint1));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue = ((double) ((((int *) point))[0]) );
			yValue = ((double) ((((int *) point))[1]) );
			/* begin edgeTransform */
			transform = ((float *) (workBuffer + GWEdgeTransform));
			x = ((sqInt)(((((transform[0]) * xValue) + ((transform[1]) * yValue)) + (transform[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y = ((sqInt)(((((transform[3]) * xValue) + ((transform[4]) * yValue)) + (transform[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point))[0] = x;
			(((int *) point))[1] = y;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point[0] = (((point[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point[1] = (((point[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	if (4 > 1) {
		/* begin transformPoint: */
		point1 = ((int *) (workBuffer + GWPoint2));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue1 = ((double) ((((int *) point1))[0]) );
			yValue1 = ((double) ((((int *) point1))[1]) );
			/* begin edgeTransform */
			transform1 = ((float *) (workBuffer + GWEdgeTransform));
			x1 = ((sqInt)(((((transform1[0]) * xValue1) + ((transform1[1]) * yValue1)) + (transform1[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y1 = ((sqInt)(((((transform1[3]) * xValue1) + ((transform1[4]) * yValue1)) + (transform1[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point1))[0] = x1;
			(((int *) point1))[1] = y1;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point1[0] = (((point1[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point1[1] = (((point1[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	if (4 > 2) {
		/* begin transformPoint: */
		point2 = ((int *) (workBuffer + GWPoint3));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue2 = ((double) ((((int *) point2))[0]) );
			yValue2 = ((double) ((((int *) point2))[1]) );
			/* begin edgeTransform */
			transform2 = ((float *) (workBuffer + GWEdgeTransform));
			x2 = ((sqInt)(((((transform2[0]) * xValue2) + ((transform2[1]) * yValue2)) + (transform2[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y2 = ((sqInt)(((((transform2[3]) * xValue2) + ((transform2[4]) * yValue2)) + (transform2[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point2))[0] = x2;
			(((int *) point2))[1] = y2;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point2[0] = (((point2[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point2[1] = (((point2[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	if (4 > 3) {
		/* begin transformPoint: */
		point3 = ((int *) (workBuffer + GWPoint4));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue3 = ((double) ((((int *) point3))[0]) );
			yValue3 = ((double) ((((int *) point3))[1]) );
			/* begin edgeTransform */
			transform3 = ((float *) (workBuffer + GWEdgeTransform));
			x3 = ((sqInt)(((((transform3[0]) * xValue3) + ((transform3[1]) * yValue3)) + (transform3[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y3 = ((sqInt)(((((transform3[3]) * xValue3) + ((transform3[4]) * yValue3)) + (transform3[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point3))[0] = x3;
			(((int *) point3))[1] = y3;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point3[0] = (((point3[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point3[1] = (((point3[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	/* begin loadRectangle:lineFill:leftFill:rightFill: */
	loadWideLinefromtolineFillleftFillrightFill(borderWidth, ((int *) (workBuffer + GWPoint1)), ((int *) (workBuffer + GWPoint2)), borderIndex, 0, fillIndex);
	loadWideLinefromtolineFillleftFillrightFill(borderWidth, ((int *) (workBuffer + GWPoint2)), ((int *) (workBuffer + GWPoint3)), borderIndex, 0, fillIndex);
	loadWideLinefromtolineFillleftFillrightFill(borderWidth, ((int *) (workBuffer + GWPoint3)), ((int *) (workBuffer + GWPoint4)), borderIndex, 0, fillIndex);
	loadWideLinefromtolineFillleftFillrightFill(borderWidth, ((int *) (workBuffer + GWPoint4)), ((int *) (workBuffer + GWPoint1)), borderIndex, 0, fillIndex);
	if (failed()) {
		return primitiveFailFor(GEFEntityLoadFailed);
	}
	/* begin needsFlushPut: */
	workBuffer[GWNeedsFlush] = 1;
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(5);
	return 0;
}


/*	Note: No need to load either bitBlt or spanBuffer */

	/* BalloonEngineBase>>#primitiveChangedActiveEdgeEntry */
EXPORT(sqInt)
primitiveChangedActiveEdgeEntry(void)
{
    sqInt edge;
    sqInt edgeOop;
    sqInt failureCode;
    sqInt value;
    sqInt value1;

	if (doProfileStats) {
		geProfileTime = ioMicroMSecs();
	}
	if (!((methodArgumentCount()) == 1)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(1), GEStateWaitingChange))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	edgeOop = stackObjectValue(0);
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	edge = loadEdgeStateFrom(edgeOop);
	if (edge == null) {
		return primitiveFailFor(GEFEdgeDataTooSmall);
	}
	if ((objBuffer[edge + GENumLines]) == 0) {
		removeFirstAETEntry();
	}
	else {
		resortFirstAETEntry();
		/* begin aetStartPut: */
		value = (workBuffer[GWAETStart]) + 1;
		workBuffer[GWAETStart] = value;
	}
	workBuffer[GWState] = GEStateUpdateEdges;
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(1);
	if (doProfileStats) {
		/* begin incrementStat:by: */
		workBuffer[GWCountChangeAETEntry] = ((workBuffer[GWCountChangeAETEntry]) + 1);
		/* begin incrementStat:by: */
		value1 = (ioMicroMSecs()) - geProfileTime;
		workBuffer[GWTimeChangeAETEntry] = ((workBuffer[GWTimeChangeAETEntry]) + value1);
	}
	return 0;
}

	/* BalloonEngineBase>>#primitiveCopyBuffer */
EXPORT(sqInt)
primitiveCopyBuffer(void)
{
    sqInt buf1;
    sqInt buf2;
    sqInt diff;
    int *dst;
    sqInt failCode;
    sqInt i;
    int *src;

	if (!((methodArgumentCount()) == 2)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	buf2 = stackValue(0);

	/* Make sure the old buffer is properly initialized */
	buf1 = stackValue(1);
	if (!(((failCode = loadWorkBufferFrom(buf1))) == 0)) {
		return primitiveFailFor(failCode);
	}
	if (!((fetchClassOf(buf1)) == (fetchClassOf(buf2)))) {
		return primitiveFailFor(GEFClassMismatch);
	}
	diff = (slotSizeOf(buf2)) - (slotSizeOf(buf1));
	if (diff < 0) {
		return primitiveFailFor(GEFSizeMismatch);
	}
	src = workBuffer;
	dst = firstIndexableField(buf2);
	for (i = 0; i < (workBuffer[GWBufferTop]); i += 1) {
		dst[i] = (src[i]);
	}
	dst[GWBufferTop] = ((workBuffer[GWBufferTop]) + diff);
	dst[GWSize] = ((workBuffer[GWSize]) + diff);
	src += workBuffer[GWBufferTop];
	dst = (dst + (workBuffer[GWBufferTop])) + diff;
	for (i = 0; i < ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])); i += 1) {
		dst[i] = (src[i]);
	}
	if (!(((failCode = loadWorkBufferFrom(buf2))) == 0)) {
		return primitiveFailFor(failCode);
	}
	pop(2);
	return 0;
}


/*	Note: Must load bitBlt and spanBuffer */

	/* BalloonEngineBase>>#primitiveDisplaySpanBuffer */
EXPORT(sqInt)
primitiveDisplaySpanBuffer(void)
{
    sqInt failureCode;
    sqInt value;
    sqInt value1;

	if (doProfileStats) {
		geProfileTime = ioMicroMSecs();
	}
	if (!((methodArgumentCount()) == 0)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(0), GEStateBlitBuffer))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	if (!(((failureCode = loadSpanBufferFrom(fetchPointerofObject(BESpanIndex, engine)))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	if (!(loadBitBltFrom(fetchPointerofObject(BEBitBltIndex, engine)))) {
		return primitiveFailFor(GEFBitBltLoadFailed);
	}
	if (((workBuffer[GWCurrentY]) & (workBuffer[GWAAScanMask])) == (workBuffer[GWAAScanMask])) {
		displaySpanBufferAt(workBuffer[GWCurrentY]);
		postDisplayAction();
	}
	if (!((workBuffer[GWState]) == GEStateCompleted)) {
		/* begin aetStartPut: */
		workBuffer[GWAETStart] = 0;
		/* begin currentYPut: */
		value = (workBuffer[GWCurrentY]) + 1;
		workBuffer[GWCurrentY] = value;
		workBuffer[GWState] = GEStateUpdateEdges;
	}
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	if (doProfileStats) {
		/* begin incrementStat:by: */
		workBuffer[GWCountDisplaySpan] = ((workBuffer[GWCountDisplaySpan]) + 1);
		/* begin incrementStat:by: */
		value1 = (ioMicroMSecs()) - geProfileTime;
		workBuffer[GWTimeDisplaySpan] = ((workBuffer[GWTimeDisplaySpan]) + value1);
	}
	return 0;
}


/*	Turn on/off profiling. Return the old value of the flag. */

	/* BalloonEngineBase>>#primitiveDoProfileStats */
EXPORT(sqInt)
primitiveDoProfileStats(void)
{
    sqInt newValue;
    int oldValue;

	oldValue = doProfileStats;
	newValue = stackObjectValue(0);
	newValue = booleanValueOf(newValue);
	if (!(failed())) {
		doProfileStats = newValue;
		pop(2);
		pushBool(oldValue);
	}
	return 0;
}

	/* BalloonEngineBase>>#primitiveFinishedProcessing */
EXPORT(sqInt)
primitiveFinishedProcessing(void)
{
    sqInt failureCode;
    sqInt finished;
    sqInt value;

	if (doProfileStats) {
		geProfileTime = ioMicroMSecs();
	}
	if (!((methodArgumentCount()) == 0)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFrom(stackValue(0)))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	/* begin finishedProcessing */
	finished = (workBuffer[GWState]) == GEStateCompleted;
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(1);
	pushBool(finished);
	if (doProfileStats) {
		/* begin incrementStat:by: */
		workBuffer[GWCountFinishTest] = ((workBuffer[GWCountFinishTest]) + 1);
		/* begin incrementStat:by: */
		value = (ioMicroMSecs()) - geProfileTime;
		workBuffer[GWTimeFinishTest] = ((workBuffer[GWTimeFinishTest]) + value);
	}
	return 0;
}

	/* BalloonEngineBase>>#primitiveGetAALevel */
EXPORT(sqInt)
primitiveGetAALevel(void)
{
    sqInt failureCode;

	if (!((methodArgumentCount()) == 0)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFrom(stackValue(0)))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	pop(1);
	pushInteger(workBuffer[GWAALevel]);
	return 0;
}

	/* BalloonEnginePlugin>>#primitiveGetBezierStats */
EXPORT(sqInt)
primitiveGetBezierStats(void)
{
    sqInt failureCode;
    sqInt statOop;
    int *stats;

	if (!((methodArgumentCount()) == 1)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFrom(stackValue(1)))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	statOop = stackObjectValue(0);
	if (!((!(failed()))
		 && ((isWords(statOop))
		 && ((slotSizeOf(statOop)) >= 4)))) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	stats = firstIndexableField(statOop);
	stats[0] = ((stats[0]) + (workBuffer[GWBezierMonotonSubdivisions]));
	stats[1] = ((stats[1]) + (workBuffer[GWBezierHeightSubdivisions]));
	stats[2] = ((stats[2]) + (workBuffer[GWBezierOverflowSubdivisions]));
	stats[3] = ((stats[3]) + (workBuffer[GWBezierLineConversions]));
	pop(1);
	return 0;
}

	/* BalloonEngineBase>>#primitiveGetClipRect */
EXPORT(sqInt)
primitiveGetClipRect(void)
{
    sqInt failureCode;
    sqInt pointOop;
    sqInt rectOop;

	if (!((methodArgumentCount()) == 1)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFrom(stackValue(1)))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	rectOop = stackObjectValue(0);
	if (!((!(failed()))
		 && ((isPointers(rectOop))
		 && ((slotSizeOf(rectOop)) >= 2)))) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	pushRemappableOop(rectOop);
	pointOop = makePointwithxValueyValue(workBuffer[GWClipMinX], workBuffer[GWClipMinY]);
	storePointerofObjectwithValue(0, topRemappableOop(), pointOop);
	pointOop = makePointwithxValueyValue(workBuffer[GWClipMaxX], workBuffer[GWClipMaxY]);
	rectOop = popRemappableOop();
	storePointerofObjectwithValue(1, rectOop, pointOop);
	popthenPush(2, rectOop);
	return 0;
}

	/* BalloonEngineBase>>#primitiveGetCounts */
EXPORT(sqInt)
primitiveGetCounts(void)
{
    sqInt failureCode;
    sqInt statOop;
    int *stats;

	if (!((methodArgumentCount()) == 1)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFrom(stackValue(1)))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	statOop = stackObjectValue(0);
	if (!((!(failed()))
		 && ((isWords(statOop))
		 && ((slotSizeOf(statOop)) >= 9)))) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	stats = firstIndexableField(statOop);
	stats[0] = ((stats[0]) + (workBuffer[GWCountInitializing]));
	stats[1] = ((stats[1]) + (workBuffer[GWCountFinishTest]));
	stats[2] = ((stats[2]) + (workBuffer[GWCountNextGETEntry]));
	stats[3] = ((stats[3]) + (workBuffer[GWCountAddAETEntry]));
	stats[4] = ((stats[4]) + (workBuffer[GWCountNextFillEntry]));
	stats[5] = ((stats[5]) + (workBuffer[GWCountMergeFill]));
	stats[6] = ((stats[6]) + (workBuffer[GWCountDisplaySpan]));
	stats[7] = ((stats[7]) + (workBuffer[GWCountNextAETEntry]));
	stats[8] = ((stats[8]) + (workBuffer[GWCountChangeAETEntry]));
	pop(1);
	return 0;
}

	/* BalloonEngineBase>>#primitiveGetDepth */
EXPORT(sqInt)
primitiveGetDepth(void)
{
    sqInt failureCode;

	if (!((methodArgumentCount()) == 0)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFrom(stackValue(0)))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	pop(1);
	pushInteger(workBuffer[GWCurrentZ]);
	return 0;
}


/*	Return the reason why the last operation failed. */

	/* BalloonEngineBase>>#primitiveGetFailureReason */
EXPORT(sqInt)
primitiveGetFailureReason(void)
{
    sqInt failCode;

	if (!((methodArgumentCount()) == 0)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}

	/* Note -- don't call loadEngineFrom here because this will override the stopReason with Zero */
	engine = stackValue(0);
	if (isImmediate(engine)) {
		return primitiveFailFor(GEFEngineIsInteger);
	}
	if (!(isPointers(engine))) {
		return primitiveFailFor(GEFEngineIsWords);
	}
	if ((slotSizeOf(engine)) < BEBalloonEngineSize) {
		return primitiveFailFor(GEFEngineTooSmall);
	}
	if (!(((failCode = loadWorkBufferFrom(fetchPointerofObject(BEWorkBufferIndex, engine)))) == 0)) {
		return primitiveFailFor(failCode);
	}
	pop(1);
	pushInteger(workBuffer[GWStopReason]);
	return 0;
}

	/* BalloonEngineBase>>#primitiveGetOffset */
EXPORT(sqInt)
primitiveGetOffset(void)
{
    sqInt failureCode;
    sqInt pointOop;

	if (!((methodArgumentCount()) == 0)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFrom(stackValue(0)))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	pointOop = makePointwithxValueyValue(workBuffer[GWDestOffsetX], workBuffer[GWDestOffsetY]);
	popthenPush(1, pointOop);
	return 0;
}

	/* BalloonEngineBase>>#primitiveGetTimes */
EXPORT(sqInt)
primitiveGetTimes(void)
{
    sqInt failureCode;
    sqInt statOop;
    int *stats;

	if (!((methodArgumentCount()) == 1)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFrom(stackValue(1)))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	statOop = stackObjectValue(0);
	if (!((!(failed()))
		 && ((isWords(statOop))
		 && ((slotSizeOf(statOop)) >= 9)))) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	stats = firstIndexableField(statOop);
	stats[0] = ((stats[0]) + (workBuffer[GWTimeInitializing]));
	stats[1] = ((stats[1]) + (workBuffer[GWTimeFinishTest]));
	stats[2] = ((stats[2]) + (workBuffer[GWTimeNextGETEntry]));
	stats[3] = ((stats[3]) + (workBuffer[GWTimeAddAETEntry]));
	stats[4] = ((stats[4]) + (workBuffer[GWTimeNextFillEntry]));
	stats[5] = ((stats[5]) + (workBuffer[GWTimeMergeFill]));
	stats[6] = ((stats[6]) + (workBuffer[GWTimeDisplaySpan]));
	stats[7] = ((stats[7]) + (workBuffer[GWTimeNextAETEntry]));
	stats[8] = ((stats[8]) + (workBuffer[GWTimeChangeAETEntry]));
	pop(1);
	return 0;
}

	/* BalloonEngineBase>>#primitiveInitializeBuffer */
EXPORT(sqInt)
primitiveInitializeBuffer(void)
{
    sqInt size;
    sqInt wbOop;

	if (!(((methodArgumentCount()) == 1)
		 && ((isWords((wbOop = stackValue(0))))
		 && (((size = slotSizeOf(wbOop))) >= GWMinimalSize)))) {
		return primitiveFail();
	}
	/* begin workBufferPut: */
	workBuffer = firstIndexableField(wbOop);
	objBuffer = workBuffer + GWHeaderSize;
	/* begin magicNumberPut: */
	workBuffer[GWMagicIndex] = GWMagicNumber;
	workBuffer[GWSize] = size;
	workBuffer[GWBufferTop] = size;
	workBuffer[GWState] = GEStateUnlocked;
	/* begin objStartPut: */
	workBuffer[GWObjStart] = GWHeaderSize;
	/* begin objUsedPut: */
	workBuffer[GWObjUsed] = 4;
	/* begin objectTypeOf:put: */
	objBuffer[0 + GEObjectType] = GEPrimitiveFill;
	/* begin objectLengthOf:put: */
	objBuffer[0 + GEObjectLength] = 4;
	/* begin objectIndexOf:put: */
	objBuffer[0 + GEObjectIndex] = 0;
	/* begin getStartPut: */
	workBuffer[GWGETStart] = 0;
	/* begin getUsedPut: */
	workBuffer[GWGETUsed] = 0;
	/* begin aetStartPut: */
	workBuffer[GWAETStart] = 0;
	/* begin aetUsedPut: */
	workBuffer[GWAETUsed] = 0;
	workBuffer[GWStopReason] = 0;
	/* begin needsFlushPut: */
	workBuffer[GWNeedsFlush] = 0;
	/* begin clipMinXPut: */
	workBuffer[GWClipMinX] = 0;
	/* begin clipMaxXPut: */
	workBuffer[GWClipMaxX] = 0;
	/* begin clipMinYPut: */
	workBuffer[GWClipMinY] = 0;
	/* begin clipMaxYPut: */
	workBuffer[GWClipMaxY] = 0;
	/* begin currentZPut: */
	workBuffer[GWCurrentZ] = 0;
	resetGraphicsEngineStats();
	initEdgeTransform();
	initColorTransform();
	popthenPush(2, wbOop);
	return 0;
}


/*	Note: No need to load bitBlt but must load spanBuffer */

	/* BalloonEngineBase>>#primitiveInitializeProcessing */
EXPORT(sqInt)
primitiveInitializeProcessing(void)
{
    sqInt failureCode;
    sqInt value;

	if (doProfileStats) {
		geProfileTime = ioMicroMSecs();
	}
	if (!((methodArgumentCount()) == 0)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(0), GEStateUnlocked))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	if (!(((failureCode = loadSpanBufferFrom(fetchPointerofObject(BESpanIndex, engine)))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	initializeGETProcessing();
	if (engineStopped) {
		return primitiveFailFor(GEFEngineStopped);
	}
	workBuffer[GWState] = GEStateAddingFromGET;
	if (!(failed())) {
		/* begin storeEngineStateInto: */
		workBuffer[GWObjUsed] = objUsed;
	}
	if (doProfileStats) {
		/* begin incrementStat:by: */
		workBuffer[GWCountInitializing] = ((workBuffer[GWCountInitializing]) + 1);
		/* begin incrementStat:by: */
		value = (ioMicroMSecs()) - geProfileTime;
		workBuffer[GWTimeInitializing] = ((workBuffer[GWTimeInitializing]) + value);
	}
	return 0;
}


/*	Note: No need to load bitBlt but must load spanBuffer */

	/* BalloonEngineBase>>#primitiveMergeFillFrom */
EXPORT(sqInt)
primitiveMergeFillFrom(void)
{
    sqInt bitsOop;
    sqInt failureCode;
    sqInt fillOop;
    sqInt value;
    sqInt value1;

	if (doProfileStats) {
		geProfileTime = ioMicroMSecs();
	}
	if (!((methodArgumentCount()) == 2)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(2), GEStateWaitingForFill))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	if (!(((failureCode = loadSpanBufferFrom(fetchPointerofObject(BESpanIndex, engine)))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	fillOop = stackObjectValue(0);

	/* Check bitmap */
	bitsOop = stackObjectValue(1);
	if (!((!(failed()))
		 && ((fetchClassOf(bitsOop)) == (classBitmap())))) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	if ((slotSizeOf(fillOop)) < FTBalloonFillDataSize) {
		return primitiveFailFor(GEFFillDataTooSmall);
	}
	value = fetchIntegerofObject(FTIndexIndex, fillOop);
	if (!((objBuffer[(workBuffer[GWLastExportedFill]) + GEObjectIndex]) == value)) {
		return primitiveFailFor(GEFWrongFill);
	}
	value = fetchIntegerofObject(FTMinXIndex, fillOop);
	if (!((workBuffer[GWLastExportedLeftX]) == value)) {
		return primitiveFailFor(GEFWrongFill);
	}
	value = fetchIntegerofObject(FTMaxXIndex, fillOop);
	if (!((workBuffer[GWLastExportedRightX]) == value)) {
		return primitiveFailFor(GEFWrongFill);
	}
	if ((slotSizeOf(bitsOop)) < ((workBuffer[GWLastExportedRightX]) - (workBuffer[GWLastExportedLeftX]))) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	if (failed()) {
		return null;
	}
	fillBitmapSpanfromto(firstIndexableField(bitsOop), workBuffer[GWLastExportedLeftX], workBuffer[GWLastExportedRightX]);
	workBuffer[GWState] = GEStateScanningAET;
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(2);
	if (doProfileStats) {
		/* begin incrementStat:by: */
		workBuffer[GWCountMergeFill] = ((workBuffer[GWCountMergeFill]) + 1);
		/* begin incrementStat:by: */
		value1 = (ioMicroMSecs()) - geProfileTime;
		workBuffer[GWTimeMergeFill] = ((workBuffer[GWTimeMergeFill]) + value1);
	}
	return 0;
}

	/* BalloonEngineBase>>#primitiveNeedsFlush */
EXPORT(sqInt)
primitiveNeedsFlush(void)
{
    sqInt failureCode;
    sqInt needFlush;

	if (!((methodArgumentCount()) == 0)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFrom(stackValue(0)))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	/* begin needsFlush */
	needFlush = (workBuffer[GWNeedsFlush]) != 0;
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(1);
	pushBool(needFlush);
	return 0;
}

	/* BalloonEngineBase>>#primitiveNeedsFlushPut */
EXPORT(sqInt)
primitiveNeedsFlushPut(void)
{
    sqInt failureCode;
    sqInt needFlush;

	if (!((methodArgumentCount()) == 1)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFrom(stackValue(1)))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	needFlush = booleanValueOf(stackValue(0));
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	if (needFlush == 1) {
		/* begin needsFlushPut: */
		workBuffer[GWNeedsFlush] = 1;
	}
	else {
		/* begin needsFlushPut: */
		workBuffer[GWNeedsFlush] = 0;
	}
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(1);
	return 0;
}


/*	Note: No need to load either bitBlt or spanBuffer */

	/* BalloonEngineBase>>#primitiveNextActiveEdgeEntry */
EXPORT(sqInt)
primitiveNextActiveEdgeEntry(void)
{
    int edge;
    sqInt edgeOop;
    sqInt failureCode;
    sqInt hasEdge;
    sqInt value;

	if (doProfileStats) {
		geProfileTime = ioMicroMSecs();
	}
	if (!((methodArgumentCount()) == 1)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredStateor(stackValue(1), GEStateUpdateEdges, GEStateCompleted))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	edgeOop = stackObjectValue(0);
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	hasEdge = 0;
	if (!((workBuffer[GWState]) == GEStateCompleted)) {
		hasEdge = findNextExternalUpdateFromAET();
		if (hasEdge) {
			edge = aetBuffer[workBuffer[GWAETStart]];
			storeEdgeStateFrominto(edge, edgeOop);
			workBuffer[GWState] = GEStateWaitingChange;
		}
		else {
			workBuffer[GWState] = GEStateAddingFromGET;
		}
	}
	if (failed()) {
		return null;
	}
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(2);
	pushBool(!hasEdge);
	if (doProfileStats) {
		/* begin incrementStat:by: */
		workBuffer[GWCountNextAETEntry] = ((workBuffer[GWCountNextAETEntry]) + 1);
		/* begin incrementStat:by: */
		value = (ioMicroMSecs()) - geProfileTime;
		workBuffer[GWTimeNextAETEntry] = ((workBuffer[GWTimeNextAETEntry]) + value);
	}
	return 0;
}


/*	Note: No need to load bitBlt but must load spanBuffer */

	/* BalloonEngineBase>>#primitiveNextFillEntry */
EXPORT(sqInt)
primitiveNextFillEntry(void)
{
    sqInt failureCode;
    sqInt fillOop;
    sqInt hasFill;
    sqInt value;

	if (doProfileStats) {
		geProfileTime = ioMicroMSecs();
	}
	if (!((methodArgumentCount()) == 1)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(1), GEStateScanningAET))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	if (!(((failureCode = loadSpanBufferFrom(fetchPointerofObject(BESpanIndex, engine)))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	if (!(loadFormsFrom(fetchPointerofObject(BEFormsIndex, engine)))) {
		return primitiveFailFor(GEFFormLoadFailed);
	}
	if (!((workBuffer[GWClearSpanBuffer]) == 0)) {
		if (((workBuffer[GWCurrentY]) & (workBuffer[GWAAScanMask])) == 0) {
			clearSpanBuffer();
		}
		/* begin clearSpanBufferPut: */
		workBuffer[GWClearSpanBuffer] = 0;
	}
	fillOop = stackObjectValue(0);
	hasFill = findNextExternalFillFromAET();
	if (engineStopped) {
		return primitiveFailFor(GEFEngineStopped);
	}
	if (hasFill) {
		storeFillStateInto(fillOop);
	}
	if (failed()) {
		return primitiveFailFor(GEFWrongFill);
	}
	if (hasFill) {
		workBuffer[GWState] = GEStateWaitingForFill;
	}
	else {
		/* begin wbStackClear */
		workBuffer[GWBufferTop] = (workBuffer[GWSize]);
		workBuffer[GWSpanEndAA] = 0;
		workBuffer[GWState] = GEStateBlitBuffer;
	}
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(2);
	pushBool(!hasFill);
	if (doProfileStats) {
		/* begin incrementStat:by: */
		workBuffer[GWCountNextFillEntry] = ((workBuffer[GWCountNextFillEntry]) + 1);
		/* begin incrementStat:by: */
		value = (ioMicroMSecs()) - geProfileTime;
		workBuffer[GWTimeNextFillEntry] = ((workBuffer[GWTimeNextFillEntry]) + value);
	}
	return 0;
}


/*	Note: No need to load either bitBlt or spanBuffer */

	/* BalloonEngineBase>>#primitiveNextGlobalEdgeEntry */
EXPORT(sqInt)
primitiveNextGlobalEdgeEntry(void)
{
    int edge;
    sqInt edgeOop;
    sqInt failureCode;
    sqInt hasEdge;
    sqInt value;
    sqInt value1;

	if (doProfileStats) {
		geProfileTime = ioMicroMSecs();
	}
	if (!((methodArgumentCount()) == 1)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(1), GEStateAddingFromGET))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	edgeOop = stackObjectValue(0);
	hasEdge = findNextExternalEntryFromGET();
	if (hasEdge) {
		edge = getBuffer[workBuffer[GWGETStart]];
		storeEdgeStateFrominto(edge, edgeOop);
		/* begin getStartPut: */
		value = (workBuffer[GWGETStart]) + 1;
		workBuffer[GWGETStart] = value;
	}
	if (failed()) {
		return primitiveFailFor(GEFWrongEdge);
	}
	if (hasEdge) {
		workBuffer[GWState] = GEStateWaitingForEdge;
	}
	else {

		/* Start scanning the AET */
		workBuffer[GWState] = GEStateScanningAET;
		/* begin clearSpanBufferPut: */
		workBuffer[GWClearSpanBuffer] = 1;
		/* begin aetStartPut: */
		workBuffer[GWAETStart] = 0;
		/* begin wbStackClear */
		workBuffer[GWBufferTop] = (workBuffer[GWSize]);
	}
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(2);
	pushBool(!hasEdge);
	if (doProfileStats) {
		/* begin incrementStat:by: */
		workBuffer[GWCountNextGETEntry] = ((workBuffer[GWCountNextGETEntry]) + 1);
		/* begin incrementStat:by: */
		value1 = (ioMicroMSecs()) - geProfileTime;
		workBuffer[GWTimeNextGETEntry] = ((workBuffer[GWTimeNextGETEntry]) + value1);
	}
	return 0;
}

	/* BalloonEngineBase>>#primitiveRegisterExternalEdge */
EXPORT(sqInt)
primitiveRegisterExternalEdge(void)
{
    sqInt edge;
    sqInt failureCode;
    sqInt index;
    sqInt initialX;
    sqInt initialY;
    sqInt initialZ;
    sqInt leftFillIndex;
    sqInt rightFillIndex;
    sqInt value;
    sqInt value1;

	if (!((methodArgumentCount()) == 6)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(6), GEStateUnlocked))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	rightFillIndex = positive32BitValueOf(stackValue(0));
	leftFillIndex = positive32BitValueOf(stackValue(1));
	initialZ = stackIntegerValue(2);
	initialY = stackIntegerValue(3);
	initialX = stackIntegerValue(4);
	index = stackIntegerValue(5);
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	if (!(allocateObjEntry(GEBaseEdgeSize))) {
		return primitiveFailFor(GEFWorkTooBig);
	}
	if (!((isFillOkay(leftFillIndex))
		 && (isFillOkay(rightFillIndex)))) {
		return primitiveFailFor(GEFWrongFill);
	}
	edge = objUsed;

	/* Install type and length */
	objUsed = edge + GEBaseEdgeSize;
	/* begin objectTypeOf:put: */
	objBuffer[edge + GEObjectType] = GEPrimitiveEdge;
	/* begin objectLengthOf:put: */
	objBuffer[edge + GEObjectLength] = GEBaseEdgeSize;
	/* begin objectIndexOf:put: */
	objBuffer[edge + GEObjectIndex] = index;
	/* begin edgeXValueOf:put: */
	objBuffer[edge + GEXValue] = initialX;
	/* begin edgeYValueOf:put: */
	objBuffer[edge + GEYValue] = initialY;
	/* begin edgeZValueOf:put: */
	objBuffer[edge + GEZValue] = initialZ;
	/* begin edgeLeftFillOf:put: */
	value = transformColor(leftFillIndex);
	objBuffer[edge + GEFillIndexLeft] = value;
	/* begin edgeRightFillOf:put: */
	value1 = transformColor(rightFillIndex);
	objBuffer[edge + GEFillIndexRight] = value1;
	if (engineStopped) {
		return primitiveFailFor(GEFEngineStopped);
	}
	if (!(failed())) {
		/* begin storeEngineStateInto: */
		workBuffer[GWObjUsed] = objUsed;
		pop(6);
	}
	return 0;
}

	/* BalloonEngineBase>>#primitiveRegisterExternalFill */
EXPORT(sqInt)
primitiveRegisterExternalFill(void)
{
    sqInt failureCode;
    sqInt fill;
    sqInt index;

	if (!((methodArgumentCount()) == 1)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(1), GEStateUnlocked))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	index = stackIntegerValue(0);
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	fill = 0;
	while (fill == 0) {
		if (!(allocateObjEntry(GEBaseEdgeSize))) {
			return primitiveFailFor(GEFWorkTooBig);
		}
		fill = objUsed;

		/* Install type and length */
		objUsed = fill + GEBaseFillSize;
		/* begin objectTypeOf:put: */
		objBuffer[fill + GEObjectType] = GEPrimitiveFill;
		/* begin objectLengthOf:put: */
		objBuffer[fill + GEObjectLength] = GEBaseFillSize;
		/* begin objectIndexOf:put: */
		objBuffer[fill + GEObjectIndex] = index;
	}
	if (!(failed())) {
		/* begin storeEngineStateInto: */
		workBuffer[GWObjUsed] = objUsed;
		pop(2);
		pushInteger(fill);
	}
	return 0;
}


/*	Start/Proceed rendering the entire image */

	/* BalloonEngineBase>>#primitiveRenderImage */
EXPORT(sqInt)
primitiveRenderImage(void)
{
    sqInt failCode;

	if (!(((failCode = loadRenderingState())) == 0)) {
		return primitiveFailFor(failCode);
	}
	proceedRenderingScanline();
	if (engineStopped) {
		return storeRenderingState();
	}
	proceedRenderingImage();
	storeRenderingState();
	return 0;
}


/*	Start rendering the entire image */

	/* BalloonEngineBase>>#primitiveRenderScanline */
EXPORT(sqInt)
primitiveRenderScanline(void)
{
    sqInt failCode;

	if (!(((failCode = loadRenderingState())) == 0)) {
		return primitiveFailFor(failCode);
	}
	proceedRenderingScanline();
	storeRenderingState();
	return 0;
}

	/* BalloonEngineBase>>#primitiveSetAALevel */
EXPORT(sqInt)
primitiveSetAALevel(void)
{
    sqInt failureCode;
    sqInt level;

	if (!((methodArgumentCount()) == 1)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(1), GEStateUnlocked))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	level = stackIntegerValue(0);
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	setAALevel(level);
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(1);
	return 0;
}


/*	Primitive. Set the BitBlt plugin to use. */

	/* BalloonEngineBase>>#primitiveSetBitBltPlugin */
EXPORT(sqInt)
primitiveSetBitBltPlugin(void)
{
    sqInt i;
    sqInt length;
    sqInt needReload;
    sqInt pluginName;
    char *ptr;


	/* Must be string to work */
	pluginName = stackValue(0);
	if (!(isBytes(pluginName))) {
		return primitiveFail();
	}
	length = byteSizeOf(pluginName);
	if (length >= 256) {
		return primitiveFail();
	}
	ptr = firstIndexableField(pluginName);
	needReload = 0;
	for (i = 0; i < length; i += 1) {

		/* Compare and store the plugin to be used */
		if (!((bbPluginName[i]) == (ptr[i]))) {
			bbPluginName[i] = (ptr[i]);
			needReload = 1;
		}
	}
	if (!((bbPluginName[length]) == 0)) {
		bbPluginName[length] = 0;
		needReload = 1;
	}
	if (needReload) {
		if (!(initialiseModule())) {
			return primitiveFail();
		}
	}
	pop(1);
	return 0;
}

	/* BalloonEngineBase>>#primitiveSetClipRect */
EXPORT(sqInt)
primitiveSetClipRect(void)
{
    sqInt failureCode;
    sqInt rectOop;
    sqInt value;
    sqInt value1;
    sqInt value2;
    sqInt value3;

	if (!((methodArgumentCount()) == 1)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(1), GEStateUnlocked))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	rectOop = stackObjectValue(0);
	if (!((!(failed()))
		 && ((isPointers(rectOop))
		 && ((slotSizeOf(rectOop)) >= 2)))) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	loadPointfrom(((int *) (workBuffer + GWPoint1)), fetchPointerofObject(0, rectOop));
	loadPointfrom(((int *) (workBuffer + GWPoint2)), fetchPointerofObject(1, rectOop));
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	/* begin clipMinXPut: */
	value = (((int *) (workBuffer + GWPoint1)))[0];
	workBuffer[GWClipMinX] = value;
	/* begin clipMinYPut: */
	value1 = (((int *) (workBuffer + GWPoint1)))[1];
	workBuffer[GWClipMinY] = value1;
	/* begin clipMaxXPut: */
	value2 = (((int *) (workBuffer + GWPoint2)))[0];
	workBuffer[GWClipMaxX] = value2;
	/* begin clipMaxYPut: */
	value3 = (((int *) (workBuffer + GWPoint2)))[1];
	workBuffer[GWClipMaxY] = value3;
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(1);
	return 0;
}

	/* BalloonEngineBase>>#primitiveSetColorTransform */
EXPORT(sqInt)
primitiveSetColorTransform(void)
{
    sqInt failureCode;
    sqInt okay;
    float *transform;
    sqInt transformOop;

	if (!((methodArgumentCount()) == 1)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(1), GEStateUnlocked))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	transformOop = stackObjectValue(0);
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	/* begin loadColorTransformFrom: */
	transform = ((float *) (workBuffer + GWColorTransform));
	/* begin hasColorTransformPut: */
	workBuffer[GWHasColorTransform] = 0;
	okay = loadTransformFromintolength(transformOop, transform, 8);
	if (!okay) {
		goto l4;
	}
	/* begin hasColorTransformPut: */
	workBuffer[GWHasColorTransform] = 1;
	transform[1] = ((transform[1]) * (256.0f));
	transform[3] = ((transform[3]) * (256.0f));
	transform[5] = ((transform[5]) * (256.0f));
	transform[7] = ((transform[7]) * (256.0f));
	l4:	/* end loadColorTransformFrom: */;
	if (failed()) {
		return primitiveFailFor(GEFEntityLoadFailed);
	}
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(1);
	return 0;
}

	/* BalloonEngineBase>>#primitiveSetDepth */
EXPORT(sqInt)
primitiveSetDepth(void)
{
    sqInt depth;
    sqInt failureCode;

	if (!((methodArgumentCount()) == 1)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(1), GEStateUnlocked))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	depth = stackIntegerValue(0);
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	/* begin currentZPut: */
	workBuffer[GWCurrentZ] = depth;
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(1);
	return 0;
}

	/* BalloonEngineBase>>#primitiveSetEdgeTransform */
EXPORT(sqInt)
primitiveSetEdgeTransform(void)
{
    sqInt failureCode;
    sqInt transformOop;

	if (!((methodArgumentCount()) == 1)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(1), GEStateUnlocked))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	transformOop = stackObjectValue(0);
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	loadEdgeTransformFrom(transformOop);
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(1);
	return 0;
}

	/* BalloonEngineBase>>#primitiveSetOffset */
EXPORT(sqInt)
primitiveSetOffset(void)
{
    sqInt failureCode;
    sqInt pointOop;
    sqInt value;
    sqInt value1;

	if (!((methodArgumentCount()) == 1)) {
		return primitiveFailFor(PrimErrBadNumArgs);
	}
	if (!(((failureCode = quickLoadEngineFromrequiredState(stackValue(1), GEStateUnlocked))) == 0)) {
		return primitiveFailFor(failureCode);
	}
	pointOop = stackValue(0);
	if (!((fetchClassOf(pointOop)) == (classPoint()))) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	loadPointfrom(((int *) (workBuffer + GWPoint1)), pointOop);
	if (failed()) {
		return primitiveFailFor(PrimErrBadArgument);
	}
	/* begin destOffsetXPut: */
	value = (((int *) (workBuffer + GWPoint1)))[0];
	workBuffer[GWDestOffsetX] = value;
	/* begin destOffsetYPut: */
	value1 = (((int *) (workBuffer + GWPoint1)))[1];
	workBuffer[GWDestOffsetY] = value1;
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(1);
	return 0;
}


/*	This is the main rendering entry */

	/* BalloonEngineBase>>#proceedRenderingImage */
static sqInt
proceedRenderingImage(void)
{
    sqInt external;
    sqInt value;
    sqInt value1;
    sqInt value2;
    sqInt value3;
    sqInt value4;

	while (!((workBuffer[GWState]) == GEStateCompleted)) {
		if (doProfileStats) {
			geProfileTime = ioMicroMSecs();
		}
		external = findNextExternalEntryFromGET();
		if (doProfileStats) {
			/* begin incrementStat:by: */
			workBuffer[GWCountNextGETEntry] = ((workBuffer[GWCountNextGETEntry]) + 1);
			/* begin incrementStat:by: */
			value = (ioMicroMSecs()) - geProfileTime;
			workBuffer[GWTimeNextGETEntry] = ((workBuffer[GWTimeNextGETEntry]) + value);
		}
		if (engineStopped) {
			return workBuffer[GWState] = GEStateAddingFromGET;
		}
		if (external) {
			workBuffer[GWState] = GEStateWaitingForEdge;
			/* begin stopBecauseOf: */
			workBuffer[GWStopReason] = GErrorGETEntry;
			engineStopped = 1;
			return null;
		}
		/* begin aetStartPut: */
		workBuffer[GWAETStart] = 0;
		/* begin wbStackClear */
		workBuffer[GWBufferTop] = (workBuffer[GWSize]);
		/* begin clearSpanBufferPut: */
		workBuffer[GWClearSpanBuffer] = 1;
		if (doProfileStats) {
			geProfileTime = ioMicroMSecs();
		}
		if (((workBuffer[GWClearSpanBuffer]) != 0)
		 && (((workBuffer[GWCurrentY]) & (workBuffer[GWAAScanMask])) == 0)) {
			clearSpanBuffer();
		}
		/* begin clearSpanBufferPut: */
		workBuffer[GWClearSpanBuffer] = 0;
		external = findNextExternalFillFromAET();
		if (doProfileStats) {
			/* begin incrementStat:by: */
			workBuffer[GWCountNextFillEntry] = ((workBuffer[GWCountNextFillEntry]) + 1);
			/* begin incrementStat:by: */
			value1 = (ioMicroMSecs()) - geProfileTime;
			workBuffer[GWTimeNextFillEntry] = ((workBuffer[GWTimeNextFillEntry]) + value1);
		}
		if (engineStopped) {
			return workBuffer[GWState] = GEStateScanningAET;
		}
		if (external) {
			workBuffer[GWState] = GEStateWaitingForFill;
			/* begin stopBecauseOf: */
			workBuffer[GWStopReason] = GErrorFillEntry;
			engineStopped = 1;
			return null;
		}
		/* begin wbStackClear */
		workBuffer[GWBufferTop] = (workBuffer[GWSize]);
		workBuffer[GWSpanEndAA] = 0;
		if (doProfileStats) {
			geProfileTime = ioMicroMSecs();
		}
		if (((workBuffer[GWCurrentY]) & (workBuffer[GWAAScanMask])) == (workBuffer[GWAAScanMask])) {
			displaySpanBufferAt(workBuffer[GWCurrentY]);
			postDisplayAction();
		}
		if (doProfileStats) {
			/* begin incrementStat:by: */
			workBuffer[GWCountDisplaySpan] = ((workBuffer[GWCountDisplaySpan]) + 1);
			/* begin incrementStat:by: */
			value2 = (ioMicroMSecs()) - geProfileTime;
			workBuffer[GWTimeDisplaySpan] = ((workBuffer[GWTimeDisplaySpan]) + value2);
		}
		if (engineStopped) {
			return workBuffer[GWState] = GEStateBlitBuffer;
		}
		if ((workBuffer[GWState]) == GEStateCompleted) {
			return 0;
		}
		/* begin aetStartPut: */
		workBuffer[GWAETStart] = 0;
		/* begin currentYPut: */
		value4 = (workBuffer[GWCurrentY]) + 1;
		workBuffer[GWCurrentY] = value4;
		if (doProfileStats) {
			geProfileTime = ioMicroMSecs();
		}
		external = findNextExternalUpdateFromAET();
		if (doProfileStats) {
			/* begin incrementStat:by: */
			workBuffer[GWCountNextAETEntry] = ((workBuffer[GWCountNextAETEntry]) + 1);
			/* begin incrementStat:by: */
			value3 = (ioMicroMSecs()) - geProfileTime;
			workBuffer[GWTimeNextAETEntry] = ((workBuffer[GWTimeNextAETEntry]) + value3);
		}
		if (engineStopped) {
			return workBuffer[GWState] = GEStateUpdateEdges;
		}
		if (external) {
			workBuffer[GWState] = GEStateWaitingChange;
			/* begin stopBecauseOf: */
			workBuffer[GWStopReason] = GErrorAETEntry;
			engineStopped = 1;
			return null;
		}
	}
	return 0;
}


/*	Proceed rendering the current scan line.
	This method may be called after some Smalltalk code has been executed
	inbetween. 
 */
/*	This is the main rendering entry */

	/* BalloonEngineBase>>#proceedRenderingScanline */
static sqInt
proceedRenderingScanline(void)
{
    sqInt external;
    sqInt state;
    sqInt value;
    sqInt value1;
    sqInt value2;
    sqInt value3;
    sqInt value4;

	state = workBuffer[GWState];
	if (state == GEStateUnlocked) {
		initializeGETProcessing();
		if (engineStopped) {
			return 0;
		}
		state = GEStateAddingFromGET;
	}
	if (state == GEStateAddingFromGET) {
		if (doProfileStats) {
			geProfileTime = ioMicroMSecs();
		}
		external = findNextExternalEntryFromGET();
		if (doProfileStats) {
			/* begin incrementStat:by: */
			workBuffer[GWCountNextGETEntry] = ((workBuffer[GWCountNextGETEntry]) + 1);
			/* begin incrementStat:by: */
			value = (ioMicroMSecs()) - geProfileTime;
			workBuffer[GWTimeNextGETEntry] = ((workBuffer[GWTimeNextGETEntry]) + value);
		}
		if (engineStopped) {
			return workBuffer[GWState] = GEStateAddingFromGET;
		}
		if (external) {
			workBuffer[GWState] = GEStateWaitingForEdge;
			/* begin stopBecauseOf: */
			workBuffer[GWStopReason] = GErrorGETEntry;
			engineStopped = 1;
			return null;
		}
		/* begin aetStartPut: */
		workBuffer[GWAETStart] = 0;
		/* begin wbStackClear */
		workBuffer[GWBufferTop] = (workBuffer[GWSize]);
		/* begin clearSpanBufferPut: */
		workBuffer[GWClearSpanBuffer] = 1;
		state = GEStateScanningAET;
	}
	if (state == GEStateScanningAET) {
		if (doProfileStats) {
			geProfileTime = ioMicroMSecs();
		}
		if (((workBuffer[GWClearSpanBuffer]) != 0)
		 && (((workBuffer[GWCurrentY]) & (workBuffer[GWAAScanMask])) == 0)) {
			clearSpanBuffer();
		}
		/* begin clearSpanBufferPut: */
		workBuffer[GWClearSpanBuffer] = 0;
		external = findNextExternalFillFromAET();
		if (doProfileStats) {
			/* begin incrementStat:by: */
			workBuffer[GWCountNextFillEntry] = ((workBuffer[GWCountNextFillEntry]) + 1);
			/* begin incrementStat:by: */
			value1 = (ioMicroMSecs()) - geProfileTime;
			workBuffer[GWTimeNextFillEntry] = ((workBuffer[GWTimeNextFillEntry]) + value1);
		}
		if (engineStopped) {
			return workBuffer[GWState] = GEStateScanningAET;
		}
		if (external) {
			workBuffer[GWState] = GEStateWaitingForFill;
			/* begin stopBecauseOf: */
			workBuffer[GWStopReason] = GErrorFillEntry;
			engineStopped = 1;
			return null;
		}
		state = GEStateBlitBuffer;
		/* begin wbStackClear */
		workBuffer[GWBufferTop] = (workBuffer[GWSize]);
		workBuffer[GWSpanEndAA] = 0;
	}
	if (state == GEStateBlitBuffer) {
		if (doProfileStats) {
			geProfileTime = ioMicroMSecs();
		}
		if (((workBuffer[GWCurrentY]) & (workBuffer[GWAAScanMask])) == (workBuffer[GWAAScanMask])) {
			displaySpanBufferAt(workBuffer[GWCurrentY]);
			postDisplayAction();
		}
		if (doProfileStats) {
			/* begin incrementStat:by: */
			workBuffer[GWCountDisplaySpan] = ((workBuffer[GWCountDisplaySpan]) + 1);
			/* begin incrementStat:by: */
			value2 = (ioMicroMSecs()) - geProfileTime;
			workBuffer[GWTimeDisplaySpan] = ((workBuffer[GWTimeDisplaySpan]) + value2);
		}
		if (engineStopped) {
			return workBuffer[GWState] = GEStateBlitBuffer;
		}
		if ((workBuffer[GWState]) == GEStateCompleted) {
			return 0;
		}
		state = GEStateUpdateEdges;
		/* begin aetStartPut: */
		workBuffer[GWAETStart] = 0;
		/* begin currentYPut: */
		value3 = (workBuffer[GWCurrentY]) + 1;
		workBuffer[GWCurrentY] = value3;
	}
	if (state == GEStateUpdateEdges) {
		if (doProfileStats) {
			geProfileTime = ioMicroMSecs();
		}
		external = findNextExternalUpdateFromAET();
		if (doProfileStats) {
			/* begin incrementStat:by: */
			workBuffer[GWCountNextAETEntry] = ((workBuffer[GWCountNextAETEntry]) + 1);
			/* begin incrementStat:by: */
			value4 = (ioMicroMSecs()) - geProfileTime;
			workBuffer[GWTimeNextAETEntry] = ((workBuffer[GWTimeNextAETEntry]) + value4);
		}
		if (engineStopped) {
			return workBuffer[GWState] = GEStateUpdateEdges;
		}
		if (external) {
			workBuffer[GWState] = GEStateWaitingChange;
			/* begin stopBecauseOf: */
			workBuffer[GWStopReason] = GErrorAETEntry;
			engineStopped = 1;
			return null;
		}
		workBuffer[GWState] = GEStateAddingFromGET;
	}
	return 0;
}


/*	Load the minimal required state from the engineOop, e.g., just the work
	buffer. Answer 0 on success or non-zero a failure code on failure */

	/* BalloonEngineBase>>#quickLoadEngineFrom: */
static sqInt
quickLoadEngineFrom(sqInt engineOop)
{
    sqInt failCode;

	if (failed()) {
		return GEFAlreadyFailed;
	}
	if (isImmediate(engineOop)) {
		return GEFEngineIsInteger;
	}
	if (!(isPointers(engineOop))) {
		return GEFEngineIsWords;
	}
	if ((slotSizeOf(engineOop)) < BEBalloonEngineSize) {
		return GEFEngineTooSmall;
	}
	engine = engineOop;
	if (!(((failCode = loadWorkBufferFrom(fetchPointerofObject(BEWorkBufferIndex, engineOop)))) == 0)) {
		return failCode;
	}
	workBuffer[GWStopReason] = 0;
	/* begin objUsedGet */
	objUsed = workBuffer[GWObjUsed];
	engineStopped = 0;
	return 0;
}

	/* BalloonEngineBase>>#quickLoadEngineFrom:requiredState: */
static sqInt
quickLoadEngineFromrequiredState(sqInt oop, sqInt requiredState)
{
    sqInt failureCode;

	if (!(((failureCode = quickLoadEngineFrom(oop))) == 0)) {
		return failureCode;
	}
	if ((workBuffer[GWState]) == requiredState) {
		return 0;
	}
	workBuffer[GWStopReason] = GErrorBadState;
	return GEFWrongState;
}

	/* BalloonEngineBase>>#quickLoadEngineFrom:requiredState:or: */
static sqInt
quickLoadEngineFromrequiredStateor(sqInt oop, sqInt requiredState, sqInt alternativeState)
{
    sqInt failureCode;

	if (!(((failureCode = quickLoadEngineFrom(oop))) == 0)) {
		return failureCode;
	}
	if ((workBuffer[GWState]) == requiredState) {
		return 0;
	}
	if ((workBuffer[GWState]) == alternativeState) {
		return 0;
	}
	workBuffer[GWStopReason] = GErrorBadState;
	return GEFWrongState;
}


/*	Remove any top fills if they have become invalid. */

	/* BalloonEngineBase>>#quickRemoveInvalidFillsAt: */
static sqInt
quickRemoveInvalidFillsAt(sqInt leftX)
{
	if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
		return null;
	}
	while ((topRightX()) <= leftX) {
		hideFilldepth(topFill(), topDepth());
		if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
			return null;
		}
	}
	return 0;
}


/*	Sort elements i through j of self to be nondescending according to
	sortBlock. */
/*	Note: The original loop has been heavily re-written for C translation */

	/* BalloonEngineBase>>#quickSortGlobalEdgeTable:from:to: */
static sqInt
quickSortGlobalEdgeTablefromto(int *array, sqInt i, sqInt j)
{
    sqInt again;
    sqInt before;
    int di;
    int dij;
    int dj;
    sqInt ij;
    sqInt k;
    sqInt l;
    sqInt n;
    int tmp;
    int tt;


	/* The prefix d means the data at that index. */
	if (((n = (j + 1) - i)) <= 1) {
		return 0;
	}
	di = array[i];
	dj = array[j];

	/* i.e., should di precede dj? */
	before = getSortsbefore(di, dj);
	if (!before) {
		tmp = array[i];
		array[i] = (array[j]);
		array[j] = tmp;
		tt = di;
		di = dj;
		dj = tt;
	}
	if (n <= 2) {
		return 0;
	}

	/* ij is the midpoint of i and j. */
	ij = (i + j) / 2;

	/* Sort di,dij,dj.  Make dij be their median. */
	dij = array[ij];

	/* i.e. should di precede dij? */
	before = getSortsbefore(di, dij);
	if (before) {

		/* i.e., should dij precede dj? */
		before = getSortsbefore(dij, dj);
		if (!before) {

			/* i.e., should dij precede dj? */
			tmp = array[j];
			array[j] = (array[ij]);
			array[ij] = tmp;
			dij = dj;
		}
	}
	else {

		/* i.e. di should come after dij */
		tmp = array[i];
		array[i] = (array[ij]);
		array[ij] = tmp;
		dij = di;
	}
	if (n <= 3) {
		return 0;
	}
	k = i;
	l = j;
	again = 1;
	while (again) {
		before = 1;
		while (before) {
			if (k <= ((l -= 1))) {
				tmp = array[l];
				before = getSortsbefore(dij, tmp);
			}
			else {
				before = 0;
			}
		}
		before = 1;
		while (before) {
			if (((k += 1)) <= l) {
				tmp = array[k];
				before = getSortsbefore(tmp, dij);
			}
			else {
				before = 0;
			}
		}
		again = k <= l;
		if (again) {
			tmp = array[k];
			array[k] = (array[l]);
			array[l] = tmp;
		}
	}
	quickSortGlobalEdgeTablefromto(array, i, l);
	quickSortGlobalEdgeTablefromto(array, k, j);
	return 0;
}

	/* BalloonEngineBase>>#removeFirstAETEntry */
static sqInt
removeFirstAETEntry(void)
{
    sqInt index;
    sqInt value;

	/* begin aetStartGet */
	index = workBuffer[GWAETStart];
	/* begin aetUsedPut: */
	value = (workBuffer[GWAETUsed]) - 1;
	workBuffer[GWAETUsed] = value;
	while (index < (workBuffer[GWAETUsed])) {
		aetBuffer[index] = (aetBuffer[index + 1]);
		index += 1;
	}
	return 0;
}

	/* BalloonEnginePlugin>>#repeatValue:max: */
static sqInt
repeatValuemax(sqInt delta, sqInt maxValue)
{
    sqInt newDelta;

	newDelta = delta;
	while (newDelta < 0) {
		newDelta += maxValue;
	}
	while (newDelta >= maxValue) {
		newDelta -= maxValue;
	}
	return newDelta;
}

	/* BalloonEngineBase>>#resetGraphicsEngineStats */
static sqInt
resetGraphicsEngineStats(void)
{
	workBuffer[GWTimeInitializing] = 0;
	workBuffer[GWTimeFinishTest] = 0;
	workBuffer[GWTimeNextGETEntry] = 0;
	workBuffer[GWTimeAddAETEntry] = 0;
	workBuffer[GWTimeNextFillEntry] = 0;
	workBuffer[GWTimeMergeFill] = 0;
	workBuffer[GWTimeDisplaySpan] = 0;
	workBuffer[GWTimeNextAETEntry] = 0;
	workBuffer[GWTimeChangeAETEntry] = 0;
	workBuffer[GWCountInitializing] = 0;
	workBuffer[GWCountFinishTest] = 0;
	workBuffer[GWCountNextGETEntry] = 0;
	workBuffer[GWCountAddAETEntry] = 0;
	workBuffer[GWCountNextFillEntry] = 0;
	workBuffer[GWCountMergeFill] = 0;
	workBuffer[GWCountDisplaySpan] = 0;
	workBuffer[GWCountNextAETEntry] = 0;
	workBuffer[GWCountChangeAETEntry] = 0;
	workBuffer[GWBezierMonotonSubdivisions] = 0;
	workBuffer[GWBezierHeightSubdivisions] = 0;
	workBuffer[GWBezierOverflowSubdivisions] = 0;
	workBuffer[GWBezierLineConversions] = 0;
	return 0;
}

	/* BalloonEngineBase>>#resortFirstAETEntry */
static sqInt
resortFirstAETEntry(void)
{
    int edge;
    int leftEdge;
    sqInt xValue;

	if ((workBuffer[GWAETStart]) == 0) {
		return null;
	}
	edge = aetBuffer[workBuffer[GWAETStart]];
	/* begin edgeXValueOf: */
	xValue = objBuffer[edge + GEXValue];
	leftEdge = aetBuffer[(workBuffer[GWAETStart]) - 1];
	if ((objBuffer[leftEdge + GEXValue]) <= xValue) {
		return null;
	}
	moveAETEntryFromedgex(workBuffer[GWAETStart], edge, xValue);
	return 0;
}

	/* BalloonEnginePlugin>>#returnWideBezierFill */
static sqInt
returnWideBezierFill(void)
{
	return (dispatchReturnValue = objBuffer[dispatchedValue + GBWideFill]);
}

	/* BalloonEnginePlugin>>#returnWideBezierWidth */
static sqInt
returnWideBezierWidth(void)
{
	return (dispatchReturnValue = objBuffer[dispatchedValue + GBWideWidth]);
}


/*	Return the fill of the (wide) line - this method is called from a case. */

	/* BalloonEnginePlugin>>#returnWideLineFill */
static sqInt
returnWideLineFill(void)
{
	return (dispatchReturnValue = objBuffer[dispatchedValue + GLWideFill]);
}


/*	Return the width of the (wide) line - this method is called from a case. */

	/* BalloonEnginePlugin>>#returnWideLineWidth */
static sqInt
returnWideLineWidth(void)
{
	return (dispatchReturnValue = objBuffer[dispatchedValue + GLWideWidth]);
}

	/* BalloonEnginePlugin>>#rShiftTable */
static int *
rShiftTable(void)
{
    static int theTable[17] =
		{0, 5, 4, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1};

	return theTable;
}


/*	Set the anti-aliasing level. Three levels are supported:
	1 - No antialiasing
	2 - 2x2 unweighted anti-aliasing
	4 - 4x4 unweighted anti-aliasing.
	 */

	/* BalloonEngineBase>>#setAALevel: */
static sqInt
setAALevel(sqInt level)
{
    sqInt aaLevel;
    sqInt value;
    sqInt value1;

	aaLevel = 0;
	if (level >= 4) {
		aaLevel = 4;
	}
	if ((level >= 2) && (level < 4)) {
		aaLevel = 2;
	}
	if (level < 2) {
		aaLevel = 1;
	}
	/* begin aaLevelPut: */
	workBuffer[GWAALevel] = aaLevel;
	if (aaLevel == 1) {
		/* begin aaShiftPut: */
		workBuffer[GWAAShift] = 0;
		/* begin aaColorMaskPut: */
		workBuffer[GWAAColorMask] = 0xFFFFFFFFU;
		/* begin aaScanMaskPut: */
		workBuffer[GWAAScanMask] = 0;
	}
	if (aaLevel == 2) {
		/* begin aaShiftPut: */
		workBuffer[GWAAShift] = 1;
		/* begin aaColorMaskPut: */
		workBuffer[GWAAColorMask] = 4244438268U;
		/* begin aaScanMaskPut: */
		workBuffer[GWAAScanMask] = 1;
	}
	if (aaLevel == 4) {
		/* begin aaShiftPut: */
		workBuffer[GWAAShift] = 2;
		/* begin aaColorMaskPut: */
		workBuffer[GWAAColorMask] = 4042322160U;
		/* begin aaScanMaskPut: */
		workBuffer[GWAAScanMask] = 3;
	}
	/* begin aaColorShiftPut: */
	value = (workBuffer[GWAAShift]) * 2;
	workBuffer[GWAAColorShift] = value;
	/* begin aaHalfPixelPut: */
	value1 = workBuffer[GWAAShift];
	workBuffer[GWAAHalfPixel] = value1;
	return 0;
}


/*	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)
		booleanValueOf = interpreterProxy->booleanValueOf;
		byteSizeOf = interpreterProxy->byteSizeOf;
		classBitmap = interpreterProxy->classBitmap;
		classPoint = interpreterProxy->classPoint;
		failed = interpreterProxy->failed;
		fetchClassOf = interpreterProxy->fetchClassOf;
		fetchIntegerofObject = interpreterProxy->fetchIntegerofObject;
		fetchPointerofObject = interpreterProxy->fetchPointerofObject;
		firstIndexableField = interpreterProxy->firstIndexableField;
		floatValueOf = interpreterProxy->floatValueOf;
		integerValueOf = interpreterProxy->integerValueOf;
		ioLoadFunctionFrom = interpreterProxy->ioLoadFunctionFrom;
		ioMicroMSecs = interpreterProxy->ioMicroMSecs;
		isArray = interpreterProxy->isArray;
		isBytes = interpreterProxy->isBytes;
		isFloatObject = interpreterProxy->isFloatObject;
#if VM_PROXY_MAJOR > 1 || (VM_PROXY_MAJOR == 1 && VM_PROXY_MINOR >= 13)
		isImmediate = interpreterProxy->isImmediate;
#else
#if !defined(isImmediate)
		isImmediate = 0;
#endif
#endif
		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;
		positive32BitValueOf = interpreterProxy->positive32BitValueOf;
		primitiveFail = interpreterProxy->primitiveFail;
		primitiveFailFor = interpreterProxy->primitiveFailFor;
		pushBool = interpreterProxy->pushBool;
		pushInteger = interpreterProxy->pushInteger;
		pushRemappableOop = interpreterProxy->pushRemappableOop;
		slotSizeOf = interpreterProxy->slotSizeOf;
		stackIntegerValue = interpreterProxy->stackIntegerValue;
		stackObjectValue = interpreterProxy->stackObjectValue;
		stackValue = interpreterProxy->stackValue;
		storeIntegerofObjectwithValue = interpreterProxy->storeIntegerofObjectwithValue;
		storePointerofObjectwithValue = interpreterProxy->storePointerofObjectwithValue;
		topRemappableOop = interpreterProxy->topRemappableOop;
#endif /* !defined(SQUEAK_BUILTIN_PLUGIN) */
	}
	return ok;
}


/*	Return the run-length value from the given ShortRunArray. */

	/* BalloonEnginePlugin>>#shortRunLengthAt:from: */
static sqInt
shortRunLengthAtfrom(sqInt i, sqInt runArray)
{
	return ((usqInt) ((((int *) runArray))[i]) >> 16);
}


/*	Return the run-length value from the given ShortRunArray.
	Note: We don't need any coercion to short/int here, since
	we deal basically only with unsigned values. */

	/* BalloonEnginePlugin>>#shortRunValueAt:from: */
static sqInt
shortRunValueAtfrom(sqInt i, sqInt runArray)
{
	return ((((int *) runArray))[i]) & 0xFFFF;
}

	/* BalloonEngineBase>>#showFill:depth:rightX: */
static sqInt
showFilldepthrightX(sqInt fillIndex, sqInt depth, sqInt rightX)
{
    sqInt index;
    sqInt index1;
    sqInt index2;
    sqInt value;
    sqInt value1;
    sqInt value2;

	if (!(wbStackPush(3 /* stackFillEntryLength */))) {
		return null;
	}
	/* begin wbStackValue:put: */
	workBuffer[(workBuffer[GWBufferTop])] = fillIndex;
	/* begin wbStackValue:put: */
	workBuffer[(workBuffer[GWBufferTop]) + (0 + 1)] = depth;
	/* begin wbStackValue:put: */
	workBuffer[(workBuffer[GWBufferTop]) + (0 + 2)] = rightX;
	if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 3 /* stackFillEntryLength */) {
		return null;
	}
	if (fillSortsbefore(0, ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */)) {

		/* New top fill */
		/* begin stackFillValue:put: */
		value = workBuffer[(workBuffer[GWBufferTop]) + (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */)];
		workBuffer[(workBuffer[GWBufferTop])] = value;
		/* begin stackFillDepth:put: */
		value1 = workBuffer[(workBuffer[GWBufferTop]) + ((((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */) + 1)];
		workBuffer[(workBuffer[GWBufferTop]) + (0 + 1)] = value1;
		/* begin stackFillRightX:put: */
		value2 = workBuffer[(workBuffer[GWBufferTop]) + ((((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */) + 2)];
		workBuffer[(workBuffer[GWBufferTop]) + (0 + 2)] = value2;
		/* begin stackFillValue:put: */
		index = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
		workBuffer[(workBuffer[GWBufferTop]) + index] = fillIndex;
		/* begin stackFillDepth:put: */
		index1 = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
		workBuffer[(workBuffer[GWBufferTop]) + (index1 + 1)] = depth;
		/* begin stackFillRightX:put: */
		index2 = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
		workBuffer[(workBuffer[GWBufferTop]) + (index2 + 2)] = rightX;
	}
	return 0;
}

	/* BalloonEngineBase>>#smallSqrtTable */
static int *
smallSqrtTable(void)
{
    static int theTable[32] = 
	{0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6};

	return theTable;
}


/*	Sort the entire global edge table */

	/* BalloonEngineBase>>#sortGlobalEdgeTable */
static sqInt
sortGlobalEdgeTable(void)
{
	quickSortGlobalEdgeTablefromto(getBuffer, 0, (workBuffer[GWGETUsed]) - 1);
	return 0;
}

	/* BalloonEngineBase>>#spanEndAAGet */
static sqInt
spanEndAAGet(void)
{
	return workBuffer[GWSpanEndAA];
}

	/* BalloonEngineBase>>#spanEndAAPut: */
static sqInt
spanEndAAPut(sqInt value)
{
	return workBuffer[GWSpanEndAA] = value;
}

	/* BalloonEngineBase>>#spanEndGet */
static sqInt
spanEndGet(void)
{
	return workBuffer[GWSpanEnd];
}

	/* BalloonEngineBase>>#spanEndPut: */
static sqInt
spanEndPut(sqInt value)
{
	return workBuffer[GWSpanEnd] = value;
}

	/* BalloonEngineBase>>#spanSizeGet */
static sqInt
spanSizeGet(void)
{
	return workBuffer[GWSpanSize];
}

	/* BalloonEngineBase>>#spanSizePut: */
static sqInt
spanSizePut(sqInt value)
{
	return workBuffer[GWSpanSize] = value;
}

	/* BalloonEngineBase>>#spanStartGet */
static sqInt
spanStartGet(void)
{
	return workBuffer[GWSpanStart];
}

	/* BalloonEngineBase>>#spanStartPut: */
static sqInt
spanStartPut(sqInt value)
{
	return workBuffer[GWSpanStart] = value;
}

	/* BalloonEngineBase>>#squaredLengthOf:with: */
static sqInt
squaredLengthOfwith(sqInt deltaX, sqInt deltaY)
{
	return (deltaX * deltaX) + (deltaY * deltaY);
}

	/* BalloonEngineBase>>#stackFillDepth: */
static sqInt
stackFillDepth(sqInt index)
{
	return workBuffer[(workBuffer[GWBufferTop]) + (index + 1)];
}

	/* BalloonEngineBase>>#stackFillDepth:put: */
static sqInt
stackFillDepthput(sqInt index, sqInt value)
{
	return workBuffer[(workBuffer[GWBufferTop]) + (index + 1)] = value;
}

	/* BalloonEngineBase>>#stackFillEntryLength */
static sqInt
stackFillEntryLength(void)
{
	return 3;
}

	/* BalloonEngineBase>>#stackFillRightX: */
static sqInt
stackFillRightX(sqInt index)
{
	return workBuffer[(workBuffer[GWBufferTop]) + (index + 2)];
}

	/* BalloonEngineBase>>#stackFillRightX:put: */
static sqInt
stackFillRightXput(sqInt index, sqInt value)
{
	return workBuffer[(workBuffer[GWBufferTop]) + (index + 2)] = value;
}

	/* BalloonEngineBase>>#stackFillSize */
static sqInt
stackFillSize(void)
{
	return (workBuffer[GWSize]) - (workBuffer[GWBufferTop]);
}

	/* BalloonEngineBase>>#stackFillValue: */
static sqInt
stackFillValue(sqInt index)
{
	return workBuffer[(workBuffer[GWBufferTop]) + index];
}

	/* BalloonEngineBase>>#stackFillValue:put: */
static sqInt
stackFillValueput(sqInt index, sqInt value)
{
	return workBuffer[(workBuffer[GWBufferTop]) + index] = value;
}

	/* BalloonEngineBase>>#stateGet */
static sqInt
stateGet(void)
{
	return workBuffer[GWState];
}

	/* BalloonEngineBase>>#statePut: */
static sqInt
statePut(sqInt value)
{
	return workBuffer[GWState] = value;
}


/*	Initialize the current entry in the GET by stepping to the current scan
	line 
 */

	/* BalloonEnginePlugin>>#stepToFirstBezier */
static sqInt
stepToFirstBezier(void)
{
	return stepToFirstBezierInat(getBuffer[workBuffer[GWGETStart]], workBuffer[GWCurrentY]);
}


/*	Initialize the bezier at yValue.
	TODO: Check if reducing maxSteps from 2*deltaY to deltaY 
	brings a *significant* performance improvement.
	In theory this should make for double step performance
	but will cost in quality. Might be that the AA stuff will
	compensate for this - but I'm not really sure. */

	/* BalloonEnginePlugin>>#stepToFirstBezierIn:at: */
static sqInt
stepToFirstBezierInat(sqInt bezier, sqInt yValue)
{
    sqInt deltaY;
    sqInt endX;
    sqInt endY;
    sqInt fwDDx;
    sqInt fwDDy;
    sqInt fwDx;
    int fwDx1;
    sqInt fwDy;
    int fwDy1;
    sqInt fwX1;
    sqInt fwX2;
    sqInt fwY1;
    sqInt fwY2;
    int lastX;
    int lastY;
    sqInt maxSteps;
    sqInt minY;
    sqInt scaledStepSize;
    sqInt squaredStepSize;
    sqInt startX;
    sqInt startY;
    int *updateData;
    int *updateData1;
    sqInt viaX;
    sqInt viaY;
    unsigned int word1;
    unsigned int word2;
    sqInt xValue;


	/* Do a quick check if there is anything at all to do */
	if ((!((((objBuffer[bezier + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveWide) != 0))
	 && (yValue >= (objBuffer[bezier + GBEndY]))) {
		/* begin edgeNumLinesOf:put: */
		return objBuffer[bezier + GENumLines] = 0;
	}
	/* begin edgeXValueOf: */
	startX = objBuffer[bezier + GEXValue];
	/* begin edgeYValueOf: */
	startY = objBuffer[bezier + GEYValue];
	/* begin bezierViaXOf: */
	viaX = objBuffer[bezier + GBViaX];
	/* begin bezierViaYOf: */
	viaY = objBuffer[bezier + GBViaY];
	/* begin bezierEndXOf: */
	endX = objBuffer[bezier + GBEndX];
	/* begin bezierEndYOf: */
	endY = objBuffer[bezier + GBEndY];

	/* Initialize integer forward differencing */
	deltaY = endY - startY;
	fwX1 = (viaX - startX) * 2;
	fwX2 = (startX + endX) - (viaX * 2);
	fwY1 = (viaY - startY) * 2;
	fwY2 = (startY + endY) - (viaY * 2);
	maxSteps = deltaY * 2;
	if (maxSteps < 2) {
		maxSteps = 2;
	}
	scaledStepSize = 0x1000000 / maxSteps;
	/* begin absoluteSquared8Dot24: */
	word1 = scaledStepSize & 0xFFFF;
	word2 = (((usqInt) scaledStepSize >> 16)) & 0xFF;
	squaredStepSize = ((usqInt) (((((usqInt) (word1 * word1) >> 16)) + ((word1 * word2) * 2)) + (((usqInt) (word2 * word2) << 16))) >> 8);
	fwDx = fwX1 * scaledStepSize;
	fwDDx = (fwX2 * squaredStepSize) * 2;
	fwDx += fwDDx / 2;
	fwDy = fwY1 * scaledStepSize;
	fwDDy = (fwY2 * squaredStepSize) * 2;

	/* Store the values */
	fwDy += fwDDy / 2;
	/* begin edgeNumLinesOf:put: */
	objBuffer[bezier + GENumLines] = deltaY;
	/* begin bezierUpdateDataOf: */
	updateData = (objBuffer + bezier) + GBUpdateData;
	updateData[GBUpdateX] = (startX * 256);
	updateData[GBUpdateY] = (startY * 256);
	updateData[GBUpdateDX] = fwDx;
	updateData[GBUpdateDY] = fwDy;
	updateData[GBUpdateDDX] = fwDDx;
	updateData[GBUpdateDDY] = fwDDy;
	if (!(((startY = objBuffer[bezier + GEYValue])) == yValue)) {
		/* begin stepToNextBezierIn:at: */
		updateData1 = (objBuffer + bezier) + GBUpdateData;
		lastX = updateData1[GBUpdateX];
		lastY = updateData1[GBUpdateY];
		fwDx1 = updateData1[GBUpdateDX];
		fwDy1 = updateData1[GBUpdateDY];

		/* Step as long as we haven't yet reached minY and also
		   as long as fwDy is greater than zero thus stepping down.
		   Note: The test for fwDy should not be necessary in theory
		   but is a good insurance in practice. */
		minY = yValue * 256;
		while ((minY > lastY)
		 && (fwDy1 >= 0)) {
			lastX += ((signed)(fwDx1 + 32768) >> 16);
			lastY += ((signed)(fwDy1 + 32768) >> 16);
			fwDx1 += updateData1[GBUpdateDDX];
			fwDy1 += updateData1[GBUpdateDDY];
		}
		updateData1[GBUpdateX] = lastX;
		updateData1[GBUpdateY] = lastY;
		updateData1[GBUpdateDX] = fwDx1;
		updateData1[GBUpdateDY] = fwDy1;
		xValue = ((signed)lastX >> 8);
		/* begin edgeXValueOf:put: */
		objBuffer[bezier + GEXValue] = xValue;
		/* begin edgeNumLinesOf:put: */
		objBuffer[bezier + GENumLines] = (deltaY - (yValue - startY));
	}
	return 0;
}


/*	Initialize the current entry in the GET by stepping to the current scan
	line 
 */

	/* BalloonEnginePlugin>>#stepToFirstLine */
static sqInt
stepToFirstLine(void)
{
	return stepToFirstLineInat(getBuffer[workBuffer[GWGETStart]], workBuffer[GWCurrentY]);
}


/*	Initialize the line at yValue */

	/* BalloonEnginePlugin>>#stepToFirstLineIn:at: */
static sqInt
stepToFirstLineInat(sqInt line, sqInt yValue)
{
    sqInt deltaX;
    sqInt deltaY;
    sqInt err;
    sqInt error;
    sqInt errorAdjUp;
    sqInt i;
    sqInt startY;
    sqInt widthX;
    sqInt x;
    sqInt xDir;
    sqInt xInc;


	/* Do a quick check if there is anything at all to do */
	if ((!((((objBuffer[line + GEObjectType]) & GEPrimitiveTypeMask) & GEPrimitiveWide) != 0))
	 && (yValue >= (objBuffer[line + GLEndY]))) {
		/* begin edgeNumLinesOf:put: */
		return objBuffer[line + GENumLines] = 0;
	}
	deltaX = (objBuffer[line + GLEndX]) - (objBuffer[line + GEXValue]);

	/* Check if edge goes left to right */
	deltaY = (objBuffer[line + GLEndY]) - (objBuffer[line + GEYValue]);
	if (deltaX >= 0) {
		xDir = 1;
		widthX = deltaX;
		error = 0;
	}
	else {
		xDir = -1;
		widthX = 0 - deltaX;
		error = 1 - deltaY;
	}
	if (deltaY == 0) {

		/* No error for horizontal edges */
		error = 0;

		/* Encodes width and direction */
		xInc = deltaX;
		errorAdjUp = 0;
	}
	else {

		/* Check if edge is y-major */
		if (deltaY > widthX) {

			/* Note: The '>' instead of '>=' could be important here... */
			xInc = 0;
			errorAdjUp = widthX;
		}
		else {
			xInc = (widthX / deltaY) * xDir;
			errorAdjUp = widthX % deltaY;
		}
	}
	/* begin edgeNumLinesOf:put: */
	objBuffer[line + GENumLines] = deltaY;
	/* begin lineXDirectionOf:put: */
	objBuffer[line + GLXDirection] = xDir;
	/* begin lineXIncrementOf:put: */
	objBuffer[line + GLXIncrement] = xInc;
	/* begin lineErrorOf:put: */
	objBuffer[line + GLError] = error;
	/* begin lineErrorAdjUpOf:put: */
	objBuffer[line + GLErrorAdjUp] = errorAdjUp;
	/* begin lineErrorAdjDownOf:put: */
	objBuffer[line + GLErrorAdjDown] = deltaY;
	if (!(((startY = objBuffer[line + GEYValue])) == yValue)) {
		for (i = startY; i < yValue; i += 1) {
			/* begin stepToNextLineIn:at: */
			x = (objBuffer[line + GEXValue]) + (objBuffer[line + GLXIncrement]);
			err = (objBuffer[line + GLError]) + (objBuffer[line + GLErrorAdjUp]);
			if (err > 0) {
				x += objBuffer[line + GLXDirection];
				err -= objBuffer[line + GLErrorAdjDown];
			}
			/* begin lineErrorOf:put: */
			objBuffer[line + GLError] = err;
			/* begin edgeXValueOf:put: */
			objBuffer[line + GEXValue] = x;
		}
		/* begin edgeNumLinesOf:put: */
		objBuffer[line + GENumLines] = (deltaY - (yValue - startY));
	}
	return 0;
}


/*	Initialize the current entry in the GET by stepping to the current scan
	line 
 */

	/* BalloonEnginePlugin>>#stepToFirstWideBezier */
static sqInt
stepToFirstWideBezier(void)
{
	return stepToFirstWideBezierInat(getBuffer[workBuffer[GWGETStart]], workBuffer[GWCurrentY]);
}


/*	Initialize the bezier at yValue */

	/* BalloonEnginePlugin>>#stepToFirstWideBezierIn:at: */
static sqInt
stepToFirstWideBezierInat(sqInt bezier, sqInt yValue)
{
    sqInt endX;
    sqInt i;
    sqInt lineOffset;
    sqInt lineWidth;
    sqInt nLines;
    sqInt startY;
    sqInt value;
    sqInt value1;
    sqInt value2;
    int xDir;
    sqInt yEntry;
    sqInt yExit;


	/* Get some values */
	/* begin obj:at: */
	lineWidth = objBuffer[bezier + GBWideExtent];
	/* begin offsetFromWidth: */
	lineOffset = lineWidth / 2;
	/* begin bezierEndXOf: */
	endX = objBuffer[bezier + GBEndX];
	/* begin edgeYValueOf: */
	startY = objBuffer[bezier + GEYValue];
	stepToFirstBezierInat(bezier, startY);
	/* begin edgeNumLinesOf: */
	nLines = objBuffer[bezier + GENumLines];
	for (i = 0; i <= 5; i += 1) {
		((objBuffer + bezier) + GBWideUpdateData)[i] = (((objBuffer + bezier) + GBUpdateData)[i]);
	}
	xDir = ((objBuffer + bezier) + GBUpdateData)[GBUpdateDX];
	if (xDir == 0) {
		xDir = ((objBuffer + bezier) + GBUpdateData)[GBUpdateDDX];
	}
	if (xDir >= 0) {
		xDir = 1;
	}
	else {
		xDir = -1;
	}
	if (xDir < 0) {
		adjustWideBezierLeftwidthoffsetendX(bezier, lineWidth, lineOffset, endX);
	}
	else {
		adjustWideBezierRightwidthoffsetendX(bezier, lineWidth, lineOffset, endX);
	}
	if (nLines == 0) {
		((objBuffer + bezier) + GBUpdateData)[GBUpdateX] = ((objBuffer[bezier + GBFinalX]) * 256);
	}
	/* begin edgeNumLinesOf:put: */
	objBuffer[bezier + GENumLines] = (nLines + lineWidth);

	/* turned on at lineOffset */
	yEntry = 0;

	/* turned off at zero */
	yExit = (0 - nLines) - lineOffset;
	/* begin obj:at:put: */
	objBuffer[bezier + GBWideEntry] = yEntry;
	/* begin obj:at:put: */
	objBuffer[bezier + GBWideExit] = yExit;
	if ((yEntry >= lineOffset)
	 && (yExit < 0)) {
		/* begin objectTypeOf:put: */
		value1 = ((objBuffer[bezier + GEObjectType]) & GEPrimitiveTypeMask) & ((unsigned int)~GEEdgeFillsInvalid);
		objBuffer[bezier + GEObjectType] = value1;
	}
	else {
		/* begin objectTypeOf:put: */
		value2 = ((objBuffer[bezier + GEObjectType]) & GEPrimitiveTypeMask) | GEEdgeFillsInvalid;
		objBuffer[bezier + GEObjectType] = value2;
	}
	computeFinalWideBezierValueswidth(bezier, lineWidth);
	if (!(startY == yValue)) {

		/* Note: Must single step here so that entry/exit works */
		for (i = startY; i < yValue; i += 1) {
			stepToNextWideBezierInat(bezier, i);
		}
		/* begin edgeNumLinesOf:put: */
		value = (objBuffer[bezier + GENumLines]) - (yValue - startY);
		objBuffer[bezier + GENumLines] = value;
	}
	return 0;
}


/*	Initialize the current entry in the GET by stepping to the current scan
	line 
 */

	/* BalloonEnginePlugin>>#stepToFirstWideLine */
static sqInt
stepToFirstWideLine(void)
{
	return stepToFirstWideLineInat(getBuffer[workBuffer[GWGETStart]], workBuffer[GWCurrentY]);
}


/*	Initialize the wide line at yValue. */

	/* BalloonEnginePlugin>>#stepToFirstWideLineIn:at: */
static sqInt
stepToFirstWideLineInat(sqInt line, sqInt yValue)
{
    sqInt err;
    sqInt i;
    sqInt lastX;
    sqInt lineOffset;
    sqInt lineOffset1;
    sqInt lineWidth;
    sqInt lineWidth1;
    sqInt nextX;
    sqInt nLines;
    sqInt startX;
    sqInt startY;
    sqInt value;
    sqInt value1;
    sqInt value11;
    sqInt value2;
    sqInt value3;
    sqInt value4;
    sqInt x;
    sqInt xDir;
    sqInt yEntry;
    sqInt yEntry1;
    sqInt yExit;
    sqInt yExit1;


	/* Get some values */
	/* begin obj:at: */
	lineWidth = objBuffer[line + GLWideExtent];
	/* begin offsetFromWidth: */
	lineOffset = lineWidth / 2;
	/* begin edgeXValueOf: */
	startX = objBuffer[line + GEXValue];
	/* begin edgeYValueOf: */
	startY = objBuffer[line + GEYValue];
	stepToFirstLineInat(line, startY);
	/* begin edgeNumLinesOf: */
	nLines = objBuffer[line + GENumLines];
	/* begin lineXDirectionOf: */
	xDir = objBuffer[line + GLXDirection];
	/* begin edgeXValueOf:put: */
	objBuffer[line + GEXValue] = (startX - lineOffset);
	/* begin edgeNumLinesOf:put: */
	objBuffer[line + GENumLines] = (nLines + lineWidth);
	if (xDir > 0) {
		/* begin wideLineWidthOf:put: */
		objBuffer[line + GLWideWidth] = ((objBuffer[line + GLXIncrement]) + lineWidth);
	}
	else {
		/* begin wideLineWidthOf:put: */
		objBuffer[line + GLWideWidth] = (lineWidth - (objBuffer[line + GLXIncrement]));
		/* begin edgeXValueOf:put: */
		value = (objBuffer[line + GEXValue]) + (objBuffer[line + GLXIncrement]);
		objBuffer[line + GEXValue] = value;
	}

	/* turned on at lineOffset */
	yEntry = 0;

	/* turned off at zero */
	yExit = (0 - nLines) - lineOffset;
	/* begin obj:at:put: */
	objBuffer[line + GLWideEntry] = yEntry;
	/* begin obj:at:put: */
	objBuffer[line + GLWideExit] = yExit;
	if ((yEntry >= lineOffset)
	 && (yExit < 0)) {
		/* begin objectTypeOf:put: */
		value2 = ((objBuffer[line + GEObjectType]) & GEPrimitiveTypeMask) & ((unsigned int)~GEEdgeFillsInvalid);
		objBuffer[line + GEObjectType] = value2;
	}
	else {
		/* begin objectTypeOf:put: */
		value3 = ((objBuffer[line + GEObjectType]) & GEPrimitiveTypeMask) | GEEdgeFillsInvalid;
		objBuffer[line + GEObjectType] = value3;
	}
	if (!(startY == yValue)) {
		for (i = startY; i < yValue; i += 1) {
			/* begin stepToNextWideLineIn:at: */
			yEntry1 = (objBuffer[line + GLWideEntry]) + 1;
			yExit1 = (objBuffer[line + GLWideExit]) + 1;
			/* begin obj:at:put: */
			objBuffer[line + GLWideEntry] = yEntry1;
			/* begin obj:at:put: */
			objBuffer[line + GLWideExit] = yExit1;
			/* begin obj:at: */
			lineWidth1 = objBuffer[line + GLWideExtent];
			/* begin offsetFromWidth: */
			lineOffset1 = lineWidth1 / 2;
			if (yEntry1 >= lineOffset1) {
				/* begin objectTypeOf:put: */
				value4 = ((objBuffer[line + GEObjectType]) & GEPrimitiveTypeMask) & ((unsigned int)~GEEdgeFillsInvalid);
				objBuffer[line + GEObjectType] = value4;
			}
			if (yExit1 >= 0) {
				/* begin objectTypeOf:put: */
				value11 = ((objBuffer[line + GEObjectType]) & GEPrimitiveTypeMask) | GEEdgeFillsInvalid;
				objBuffer[line + GEObjectType] = value11;
			}
			/* begin edgeXValueOf: */
			lastX = objBuffer[line + GEXValue];
			/* begin stepToNextLineIn:at: */
			x = (objBuffer[line + GEXValue]) + (objBuffer[line + GLXIncrement]);
			err = (objBuffer[line + GLError]) + (objBuffer[line + GLErrorAdjUp]);
			if (err > 0) {
				x += objBuffer[line + GLXDirection];
				err -= objBuffer[line + GLErrorAdjDown];
			}
			/* begin lineErrorOf:put: */
			objBuffer[line + GLError] = err;
			/* begin edgeXValueOf:put: */
			objBuffer[line + GEXValue] = x;
			/* begin edgeXValueOf: */
			nextX = objBuffer[line + GEXValue];
			if ((yEntry1 <= lineWidth1)
			 || ((yExit1 + lineOffset1) >= 0)) {

				/* Yes, need an update */
				adjustWideLineafterSteppingFromto(line, lastX, nextX);
			}
		}
		/* begin edgeNumLinesOf:put: */
		value1 = (objBuffer[line + GENumLines]) - (yValue - startY);
		objBuffer[line + GENumLines] = value1;
	}
	return 0;
}


/*	Process the current entry in the AET by stepping to the next scan line */

	/* BalloonEnginePlugin>>#stepToNextBezier */
static sqInt
stepToNextBezier(void)
{
    int fwDx;
    int fwDy;
    int lastX;
    int lastY;
    sqInt minY;
    int *updateData;
    sqInt xValue;

	/* begin stepToNextBezierIn:at: */
	updateData = (objBuffer + (aetBuffer[workBuffer[GWAETStart]])) + GBUpdateData;
	lastX = updateData[GBUpdateX];
	lastY = updateData[GBUpdateY];
	fwDx = updateData[GBUpdateDX];
	fwDy = updateData[GBUpdateDY];

	/* Step as long as we haven't yet reached minY and also
	   as long as fwDy is greater than zero thus stepping down.
	   Note: The test for fwDy should not be necessary in theory
	   but is a good insurance in practice. */
	minY = (workBuffer[GWCurrentY]) * 256;
	while ((minY > lastY)
	 && (fwDy >= 0)) {
		lastX += ((signed)(fwDx + 32768) >> 16);
		lastY += ((signed)(fwDy + 32768) >> 16);
		fwDx += updateData[GBUpdateDDX];
		fwDy += updateData[GBUpdateDDY];
	}
	updateData[GBUpdateX] = lastX;
	updateData[GBUpdateY] = lastY;
	updateData[GBUpdateDX] = fwDx;
	updateData[GBUpdateDY] = fwDy;
	xValue = ((signed)lastX >> 8);
	/* begin edgeXValueOf:put: */
	objBuffer[(aetBuffer[workBuffer[GWAETStart]]) + GEXValue] = xValue;
	return null;
}


/*	Incrementally step to the next scan line in the given bezier update data.
	Note: This method has been written so that inlining works, e.g.,
	not declaring updateData as 'int*' but casting it on every use. */

	/* BalloonEnginePlugin>>#stepToNextBezierForward:at: */
static sqInt
stepToNextBezierForwardat(int *updateData, sqInt yValue)
{
    int fwDx;
    int fwDy;
    int lastX;
    int lastY;
    sqInt minY;

	lastX = updateData[GBUpdateX];
	lastY = updateData[GBUpdateY];
	fwDx = updateData[GBUpdateDX];
	fwDy = updateData[GBUpdateDY];

	/* Step as long as we haven't yet reached minY and also
	   as long as fwDy is greater than zero thus stepping down.
	   Note: The test for fwDy should not be necessary in theory
	   but is a good insurance in practice. */
	minY = yValue * 256;
	while ((minY > lastY)
	 && (fwDy >= 0)) {
		lastX += ((signed)(fwDx + 32768) >> 16);
		lastY += ((signed)(fwDy + 32768) >> 16);
		fwDx += updateData[GBUpdateDDX];
		fwDy += updateData[GBUpdateDDY];
	}
	updateData[GBUpdateX] = lastX;
	updateData[GBUpdateY] = lastY;
	updateData[GBUpdateDX] = fwDx;
	updateData[GBUpdateDY] = fwDy;
	return ((signed)lastX >> 8);
}


/*	Incrementally step to the next scan line in the given bezier */

	/* BalloonEnginePlugin>>#stepToNextBezierIn:at: */
static sqInt
stepToNextBezierInat(sqInt bezier, sqInt yValue)
{
    int fwDx;
    int fwDy;
    int lastX;
    int lastY;
    sqInt minY;
    int *updateData;
    sqInt xValue;

	/* begin stepToNextBezierForward:at: */
	updateData = (objBuffer + bezier) + GBUpdateData;
	lastX = updateData[GBUpdateX];
	lastY = updateData[GBUpdateY];
	fwDx = updateData[GBUpdateDX];
	fwDy = updateData[GBUpdateDY];

	/* Step as long as we haven't yet reached minY and also
	   as long as fwDy is greater than zero thus stepping down.
	   Note: The test for fwDy should not be necessary in theory
	   but is a good insurance in practice. */
	minY = yValue * 256;
	while ((minY > lastY)
	 && (fwDy >= 0)) {
		lastX += ((signed)(fwDx + 32768) >> 16);
		lastY += ((signed)(fwDy + 32768) >> 16);
		fwDx += updateData[GBUpdateDDX];
		fwDy += updateData[GBUpdateDDY];
	}
	updateData[GBUpdateX] = lastX;
	updateData[GBUpdateY] = lastY;
	updateData[GBUpdateDX] = fwDx;
	updateData[GBUpdateDY] = fwDy;
	xValue = ((signed)lastX >> 8);
	/* begin edgeXValueOf:put: */
	objBuffer[bezier + GEXValue] = xValue;
	return 0;
}


/*	Process the current entry in the AET by stepping to the next scan line */

	/* BalloonEnginePlugin>>#stepToNextLine */
static sqInt
stepToNextLine(void)
{
    sqInt err;
    sqInt line;
    sqInt x;
    sqInt yValue;

	/* begin stepToNextLineIn:at: */
	line = aetBuffer[workBuffer[GWAETStart]];
	yValue = workBuffer[GWCurrentY];
	x = (objBuffer[line + GEXValue]) + (objBuffer[line + GLXIncrement]);
	err = (objBuffer[line + GLError]) + (objBuffer[line + GLErrorAdjUp]);
	if (err > 0) {
		x += objBuffer[line + GLXDirection];
		err -= objBuffer[line + GLErrorAdjDown];
	}
	/* begin lineErrorOf:put: */
	objBuffer[line + GLError] = err;
	/* begin edgeXValueOf:put: */
	objBuffer[line + GEXValue] = x;
	return null;
}


/*	Incrementally step to the next scan line in the given line */

	/* BalloonEnginePlugin>>#stepToNextLineIn:at: */
static sqInt
stepToNextLineInat(sqInt line, sqInt yValue)
{
    sqInt err;
    sqInt x;

	x = (objBuffer[line + GEXValue]) + (objBuffer[line + GLXIncrement]);
	err = (objBuffer[line + GLError]) + (objBuffer[line + GLErrorAdjUp]);
	if (err > 0) {
		x += objBuffer[line + GLXDirection];
		err -= objBuffer[line + GLErrorAdjDown];
	}
	/* begin lineErrorOf:put: */
	objBuffer[line + GLError] = err;
	/* begin edgeXValueOf:put: */
	objBuffer[line + GEXValue] = x;
	return 0;
}


/*	Initialize the current entry in the GET by stepping to the current scan
	line 
 */

	/* BalloonEnginePlugin>>#stepToNextWideBezier */
static sqInt
stepToNextWideBezier(void)
{
	stepToNextWideBezierInat(aetBuffer[workBuffer[GWAETStart]], workBuffer[GWCurrentY]);
	return 0;
}


/*	Incrementally step to the next scan line in the given wide bezier */

	/* BalloonEnginePlugin>>#stepToNextWideBezierIn:at: */
static sqInt
stepToNextWideBezierInat(sqInt bezier, sqInt yValue)
{
    int fwDx;
    int fwDx1;
    int fwDy;
    int fwDy1;
    int lastX;
    int lastX1;
    int lastY;
    int lastY1;
    sqInt lineOffset;
    sqInt lineWidth;
    sqInt minY;
    sqInt minY1;
    int *updateData;
    int *updateData1;
    sqInt value;
    sqInt value1;
    sqInt yEntry;
    sqInt yExit;


	/* Don't inline this */
	/* begin obj:at: */
	lineWidth = objBuffer[bezier + GBWideExtent];
	/* begin offsetFromWidth: */
	lineOffset = lineWidth / 2;
	yEntry = (objBuffer[bezier + GBWideEntry]) + 1;
	yExit = (objBuffer[bezier + GBWideExit]) + 1;
	/* begin obj:at:put: */
	objBuffer[bezier + GBWideEntry] = yEntry;
	/* begin obj:at:put: */
	objBuffer[bezier + GBWideExit] = yExit;
	if (yEntry >= lineOffset) {
		/* begin objectTypeOf:put: */
		value = ((objBuffer[bezier + GEObjectType]) & GEPrimitiveTypeMask) & ((unsigned int)~GEEdgeFillsInvalid);
		objBuffer[bezier + GEObjectType] = value;
	}
	if (yExit >= 0) {
		/* begin objectTypeOf:put: */
		value1 = ((objBuffer[bezier + GEObjectType]) & GEPrimitiveTypeMask) | GEEdgeFillsInvalid;
		objBuffer[bezier + GEObjectType] = value1;
	}
	if ((yExit + lineOffset) < 0) {
		/* begin stepToNextBezierForward:at: */
		updateData = (objBuffer + bezier) + GBUpdateData;
		lastX = updateData[GBUpdateX];
		lastY = updateData[GBUpdateY];
		fwDx = updateData[GBUpdateDX];
		fwDy = updateData[GBUpdateDY];

		/* Step as long as we haven't yet reached minY and also
		   as long as fwDy is greater than zero thus stepping down.
		   Note: The test for fwDy should not be necessary in theory
		   but is a good insurance in practice. */
		minY = yValue * 256;
		while ((minY > lastY)
		 && (fwDy >= 0)) {
			lastX += ((signed)(fwDx + 32768) >> 16);
			lastY += ((signed)(fwDy + 32768) >> 16);
			fwDx += updateData[GBUpdateDDX];
			fwDy += updateData[GBUpdateDDY];
		}
		updateData[GBUpdateX] = lastX;
		updateData[GBUpdateY] = lastY;
		updateData[GBUpdateDX] = fwDx;
		updateData[GBUpdateDY] = fwDy;
	}
	else {

		/* Adjust the last x value to the final x recorded previously */
		((objBuffer + bezier) + GBUpdateData)[GBUpdateX] = ((objBuffer[bezier + GBFinalX]) * 256);
	}
	/* begin stepToNextBezierForward:at: */
	updateData1 = (objBuffer + bezier) + GBWideUpdateData;
	lastX1 = updateData1[GBUpdateX];
	lastY1 = updateData1[GBUpdateY];
	fwDx1 = updateData1[GBUpdateDX];
	fwDy1 = updateData1[GBUpdateDY];

	/* Step as long as we haven't yet reached minY and also
	   as long as fwDy is greater than zero thus stepping down.
	   Note: The test for fwDy should not be necessary in theory
	   but is a good insurance in practice. */
	minY1 = yValue * 256;
	while ((minY1 > lastY1)
	 && (fwDy1 >= 0)) {
		lastX1 += ((signed)(fwDx1 + 32768) >> 16);
		lastY1 += ((signed)(fwDy1 + 32768) >> 16);
		fwDx1 += updateData1[GBUpdateDDX];
		fwDy1 += updateData1[GBUpdateDDY];
	}
	updateData1[GBUpdateX] = lastX1;
	updateData1[GBUpdateY] = lastY1;
	updateData1[GBUpdateDX] = fwDx1;
	updateData1[GBUpdateDY] = fwDy1;
	
	computeFinalWideBezierValueswidth(bezier, lineWidth);
	return 0;
}


/*	Process the current entry in the AET by stepping to the next scan line */

	/* BalloonEnginePlugin>>#stepToNextWideLine */
static sqInt
stepToNextWideLine(void)
{
    sqInt err;
    sqInt lastX;
    sqInt line;
    sqInt lineOffset;
    sqInt lineWidth;
    sqInt nextX;
    sqInt value;
    sqInt value1;
    sqInt x;
    sqInt yEntry;
    sqInt yExit;
    sqInt yValue;

	/* begin stepToNextWideLineIn:at: */
	line = aetBuffer[workBuffer[GWAETStart]];
	yValue = workBuffer[GWCurrentY];
	yEntry = (objBuffer[line + GLWideEntry]) + 1;
	yExit = (objBuffer[line + GLWideExit]) + 1;
	/* begin obj:at:put: */
	objBuffer[line + GLWideEntry] = yEntry;
	/* begin obj:at:put: */
	objBuffer[line + GLWideExit] = yExit;
	/* begin obj:at: */
	lineWidth = objBuffer[line + GLWideExtent];
	/* begin offsetFromWidth: */
	lineOffset = lineWidth / 2;
	if (yEntry >= lineOffset) {
		/* begin objectTypeOf:put: */
		value = ((objBuffer[line + GEObjectType]) & GEPrimitiveTypeMask) & ((unsigned int)~GEEdgeFillsInvalid);
		objBuffer[line + GEObjectType] = value;
	}
	if (yExit >= 0) {
		/* begin objectTypeOf:put: */
		value1 = ((objBuffer[line + GEObjectType]) & GEPrimitiveTypeMask) | GEEdgeFillsInvalid;
		objBuffer[line + GEObjectType] = value1;
	}
	/* begin edgeXValueOf: */
	lastX = objBuffer[line + GEXValue];
	/* begin stepToNextLineIn:at: */
	x = (objBuffer[line + GEXValue]) + (objBuffer[line + GLXIncrement]);
	err = (objBuffer[line + GLError]) + (objBuffer[line + GLErrorAdjUp]);
	if (err > 0) {
		x += objBuffer[line + GLXDirection];
		err -= objBuffer[line + GLErrorAdjDown];
	}
	/* begin lineErrorOf:put: */
	objBuffer[line + GLError] = err;
	/* begin edgeXValueOf:put: */
	objBuffer[line + GEXValue] = x;
	/* begin edgeXValueOf: */
	nextX = objBuffer[line + GEXValue];
	if ((yEntry <= lineWidth)
	 || ((yExit + lineOffset) >= 0)) {

		/* Yes, need an update */
		adjustWideLineafterSteppingFromto(line, lastX, nextX);
	}
	return null;
}


/*	Incrementally step to the next scan line in the given wide line */

	/* BalloonEnginePlugin>>#stepToNextWideLineIn:at: */
static sqInt
stepToNextWideLineInat(sqInt line, sqInt yValue)
{
    sqInt err;
    sqInt lastX;
    sqInt lineOffset;
    sqInt lineWidth;
    sqInt nextX;
    sqInt value;
    sqInt value1;
    sqInt x;
    sqInt yEntry;
    sqInt yExit;


	/* Adjust entry/exit values */
	yEntry = (objBuffer[line + GLWideEntry]) + 1;
	yExit = (objBuffer[line + GLWideExit]) + 1;
	/* begin obj:at:put: */
	objBuffer[line + GLWideEntry] = yEntry;
	/* begin obj:at:put: */
	objBuffer[line + GLWideExit] = yExit;
	/* begin obj:at: */
	lineWidth = objBuffer[line + GLWideExtent];
	/* begin offsetFromWidth: */
	lineOffset = lineWidth / 2;
	if (yEntry >= lineOffset) {
		/* begin objectTypeOf:put: */
		value = ((objBuffer[line + GEObjectType]) & GEPrimitiveTypeMask) & ((unsigned int)~GEEdgeFillsInvalid);
		objBuffer[line + GEObjectType] = value;
	}
	if (yExit >= 0) {
		/* begin objectTypeOf:put: */
		value1 = ((objBuffer[line + GEObjectType]) & GEPrimitiveTypeMask) | GEEdgeFillsInvalid;
		objBuffer[line + GEObjectType] = value1;
	}
	/* begin edgeXValueOf: */
	lastX = objBuffer[line + GEXValue];
	/* begin stepToNextLineIn:at: */
	x = (objBuffer[line + GEXValue]) + (objBuffer[line + GLXIncrement]);
	err = (objBuffer[line + GLError]) + (objBuffer[line + GLErrorAdjUp]);
	if (err > 0) {
		x += objBuffer[line + GLXDirection];
		err -= objBuffer[line + GLErrorAdjDown];
	}
	/* begin lineErrorOf:put: */
	objBuffer[line + GLError] = err;
	/* begin edgeXValueOf:put: */
	objBuffer[line + GEXValue] = x;
	/* begin edgeXValueOf: */
	nextX = objBuffer[line + GEXValue];
	if ((yEntry <= lineWidth)
	 || ((yExit + lineOffset) >= 0)) {

		/* Yes, need an update */
		adjustWideLineafterSteppingFromto(line, lastX, nextX);
	}
	return 0;
}

	/* BalloonEngineBase>>#stopBecauseOf: */
static sqInt
stopBecauseOf(sqInt stopReason)
{
	workBuffer[GWStopReason] = stopReason;
	engineStopped = 1;
	return 0;
}

	/* BalloonEngineBase>>#stopReasonGet */
static sqInt
stopReasonGet(void)
{
	return workBuffer[GWStopReason];
}

	/* BalloonEngineBase>>#stopReasonPut: */
static sqInt
stopReasonPut(sqInt value)
{
	return workBuffer[GWStopReason] = value;
}

	/* BalloonEngineBase>>#storeEdgeStateFrom:into: */
static sqInt
storeEdgeStateFrominto(sqInt edge, sqInt edgeOop)
{
	if ((slotSizeOf(edgeOop)) < ETBalloonEdgeDataSize) {
		return primitiveFail();
	}
	storeIntegerofObjectwithValue(ETIndexIndex, edgeOop, objBuffer[edge + GEObjectIndex]);
	storeIntegerofObjectwithValue(ETXValueIndex, edgeOop, objBuffer[edge + GEXValue]);
	storeIntegerofObjectwithValue(ETYValueIndex, edgeOop, workBuffer[GWCurrentY]);
	storeIntegerofObjectwithValue(ETZValueIndex, edgeOop, objBuffer[edge + GEZValue]);
	storeIntegerofObjectwithValue(ETLinesIndex, edgeOop, objBuffer[edge + GENumLines]);
	/* begin lastExportedEdgePut: */
	workBuffer[GWLastExportedEdge] = edge;
	return 0;
}

	/* BalloonEngineBase>>#storeEngineStateInto: */
static sqInt
storeEngineStateInto(sqInt oop)
{
	/* begin objUsedPut: */
	workBuffer[GWObjUsed] = objUsed;
	return 0;
}

	/* BalloonEngineBase>>#storeFillStateInto: */
static sqInt
storeFillStateInto(sqInt fillOop)
{
    sqInt fillIndex;
    sqInt leftX;
    sqInt rightX;

	/* begin lastExportedFillGet */
	fillIndex = workBuffer[GWLastExportedFill];
	/* begin lastExportedLeftXGet */
	leftX = workBuffer[GWLastExportedLeftX];
	/* begin lastExportedRightXGet */
	rightX = workBuffer[GWLastExportedRightX];
	if ((slotSizeOf(fillOop)) < FTBalloonFillDataSize) {
		return primitiveFail();
	}
	storeIntegerofObjectwithValue(FTIndexIndex, fillOop, objBuffer[fillIndex + GEObjectIndex]);
	storeIntegerofObjectwithValue(FTMinXIndex, fillOop, leftX);
	storeIntegerofObjectwithValue(FTMaxXIndex, fillOop, rightX);
	storeIntegerofObjectwithValue(FTYValueIndex, fillOop, workBuffer[GWCurrentY]);
	return 0;
}

	/* BalloonEngineBase>>#storeRenderingState */
static sqInt
storeRenderingState(void)
{
    int edge;
    sqInt edgeOop;
    sqInt fillOop;
    sqInt reason;
    sqInt value;

	if (failed()) {
		return null;
	}
	if (engineStopped) {

		/* Check the stop reason and store the required information */
		/* begin storeStopStateIntoEdge:fill: */
		edgeOop = stackObjectValue(1);
		fillOop = stackObjectValue(0);
		/* begin stopReasonGet */
		reason = workBuffer[GWStopReason];
		if (reason == GErrorGETEntry) {
			edge = getBuffer[workBuffer[GWGETStart]];
			storeEdgeStateFrominto(edge, edgeOop);
			/* begin getStartPut: */
			value = (workBuffer[GWGETStart]) + 1;
			workBuffer[GWGETStart] = value;
		}
		if (reason == GErrorFillEntry) {
			storeFillStateInto(fillOop);
		}
		if (reason == GErrorAETEntry) {
			edge = aetBuffer[workBuffer[GWAETStart]];
			storeEdgeStateFrominto(edge, edgeOop);
		}
	}
	/* begin storeEngineStateInto: */
	workBuffer[GWObjUsed] = objUsed;
	pop(3);
	pushInteger(workBuffer[GWStopReason]);
	return 0;
}

	/* BalloonEngineBase>>#storeStopStateIntoEdge:fill: */
static sqInt
storeStopStateIntoEdgefill(sqInt edgeOop, sqInt fillOop)
{
    int edge;
    sqInt reason;
    sqInt value;

	/* begin stopReasonGet */
	reason = workBuffer[GWStopReason];
	if (reason == GErrorGETEntry) {
		edge = getBuffer[workBuffer[GWGETStart]];
		storeEdgeStateFrominto(edge, edgeOop);
		/* begin getStartPut: */
		value = (workBuffer[GWGETStart]) + 1;
		workBuffer[GWGETStart] = value;
	}
	if (reason == GErrorFillEntry) {
		storeFillStateInto(fillOop);
	}
	if (reason == GErrorAETEntry) {
		edge = aetBuffer[workBuffer[GWAETStart]];
		storeEdgeStateFrominto(edge, edgeOop);
	}
	return 0;
}


/*	Recursively subdivide the curve on the bezier stack. */

	/* BalloonEnginePlugin>>#subdivideBezierFrom: */
static sqInt
subdivideBezierFrom(sqInt index)
{
    sqInt index1;
    sqInt index2;
    sqInt otherIndex;

	otherIndex = subdivideBezier(index);
	if (!(otherIndex == index)) {
		index1 = subdivideBezierFrom(index);
		if (engineStopped) {
			return 0;
		}
		index2 = subdivideBezierFrom(otherIndex);
		if (engineStopped) {
			return 0;
		}
		if (index1 >= index2) {
			return index1;
		}
		else {
			return index2;
		}
	}
	return index;
}


/*	Subdivide the given bezier curve if necessary */

	/* BalloonEnginePlugin>>#subdivideBezier: */
static sqInt
subdivideBezier(sqInt index)
{
    sqInt deltaX;
    sqInt deltaY;
    sqInt endX;
    sqInt endY;
    sqInt index1;
    sqInt index2;
    sqInt index3;
    sqInt index4;
    sqInt startX;
    sqInt startY;

	/* begin wbStackValue: */
	index1 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 1;
	startY = workBuffer[(workBuffer[GWBufferTop]) + index1];
	/* begin wbStackValue: */
	index2 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 5;
	endY = workBuffer[(workBuffer[GWBufferTop]) + index2];
	if (endY == startY) {
		return index;
	}
	deltaY = endY - startY;
	if (deltaY < 0) {
		deltaY = 0 - deltaY;
	}
	if (deltaY > 0xFF) {
		/* begin incrementStat:by: */
		workBuffer[GWBezierHeightSubdivisions] = ((workBuffer[GWBezierHeightSubdivisions]) + 1);
		return computeBezierSplitAtHalf(index);
	}
	/* begin wbStackValue: */
	index3 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index);
	startX = workBuffer[(workBuffer[GWBufferTop]) + index3];
	/* begin wbStackValue: */
	index4 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 4;
	endX = workBuffer[(workBuffer[GWBufferTop]) + index4];
	deltaX = endX - startX;
	if (deltaX < 0) {
		deltaX = 0 - deltaX;
	}
	if ((deltaY * 32) < deltaX) {
		/* begin incrementStat:by: */
		workBuffer[GWBezierOverflowSubdivisions] = ((workBuffer[GWBezierOverflowSubdivisions]) + 1);
		return computeBezierSplitAtHalf(index);
	}
	return index;
}


/*	Check if the given bezier curve is monoton in X. If not, subdivide it */

	/* BalloonEnginePlugin>>#subdivideToBeMonotonInX: */
static sqInt
subdivideToBeMonotonInX(sqInt index)
{
    sqInt denom;
    sqInt dx1;
    sqInt dx2;
    sqInt endX;
    sqInt index1;
    sqInt index2;
    sqInt index3;
    sqInt num;
    sqInt startX;
    sqInt viaX;

	/* begin wbStackValue: */
	index1 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index);
	startX = workBuffer[(workBuffer[GWBufferTop]) + index1];
	/* begin wbStackValue: */
	index2 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 2;
	viaX = workBuffer[(workBuffer[GWBufferTop]) + index2];
	/* begin wbStackValue: */
	index3 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 4;
	endX = workBuffer[(workBuffer[GWBufferTop]) + index3];
	dx1 = viaX - startX;
	dx2 = endX - viaX;
	if ((dx1 * dx2) >= 0) {
		return index;
	}
	/* begin incrementStat:by: */
	workBuffer[GWBezierMonotonSubdivisions] = ((workBuffer[GWBezierMonotonSubdivisions]) + 1);
	denom = dx2 - dx1;
	num = dx1;
	if (num < 0) {
		num = 0 - num;
	}
	if (denom < 0) {
		denom = 0 - denom;
	}
	return computeBeziersplitAt(index, (((double) num )) / (((double) denom )));
}


/*	Check if the given bezier curve is monoton in Y. If not, subdivide it */

	/* BalloonEnginePlugin>>#subdivideToBeMonotonInY: */
static sqInt
subdivideToBeMonotonInY(sqInt index)
{
    sqInt denom;
    sqInt dy1;
    sqInt dy2;
    sqInt endY;
    sqInt index1;
    sqInt index2;
    sqInt index3;
    sqInt num;
    sqInt startY;
    sqInt viaY;

	/* begin wbStackValue: */
	index1 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 1;
	startY = workBuffer[(workBuffer[GWBufferTop]) + index1];
	/* begin wbStackValue: */
	index2 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 3;
	viaY = workBuffer[(workBuffer[GWBufferTop]) + index2];
	/* begin wbStackValue: */
	index3 = (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - index) + 5;
	endY = workBuffer[(workBuffer[GWBufferTop]) + index3];
	dy1 = viaY - startY;
	dy2 = endY - viaY;
	if ((dy1 * dy2) >= 0) {
		return index;
	}
	/* begin incrementStat:by: */
	workBuffer[GWBezierMonotonSubdivisions] = ((workBuffer[GWBezierMonotonSubdivisions]) + 1);
	denom = dy2 - dy1;
	num = dy1;
	if (num < 0) {
		num = 0 - num;
	}
	if (denom < 0) {
		denom = 0 - denom;
	}
	return computeBeziersplitAt(index, (((double) num )) / (((double) denom )));
}


/*	Check if the given bezier curve is monoton in Y, and, if desired in X. 
	If not, subdivide it */

	/* BalloonEnginePlugin>>#subdivideToBeMonoton:inX: */
static sqInt
subdivideToBeMonotoninX(sqInt base, sqInt doTestX)
{
    sqInt base2;
    sqInt index1;
    sqInt index2;

	base2 = (index1 = (index2 = subdivideToBeMonotonInY(base)));
	if (doTestX) {
		index1 = subdivideToBeMonotonInX(base);
	}
	if (index1 > index2) {
		index2 = index1;
	}
	if ((base != base2)
	 && (doTestX)) {
		index1 = subdivideToBeMonotonInX(base2);
	}
	if (index1 > index2) {
		index2 = index1;
	}
	return index2;
}

	/* BalloonEngineBase>>#toggleFillsOf: */
static sqInt
toggleFillsOf(sqInt edge)
{
    sqInt depth;
    sqInt fillIndex;

	if (!(needAvailableSpace(3 /* stackFillEntryLength */ * 2))) {
		return null;
	}
	depth = ((sqInt)((usqInt)((objBuffer[edge + GEZValue])) << 1));
	/* begin edgeLeftFillOf: */
	fillIndex = objBuffer[edge + GEFillIndexLeft];
	if (!(fillIndex == 0)) {
		toggleFilldepthrightX(fillIndex, depth, 999999999);
	}
	/* begin edgeRightFillOf: */
	fillIndex = objBuffer[edge + GEFillIndexRight];
	if (!(fillIndex == 0)) {
		toggleFilldepthrightX(fillIndex, depth, 999999999);
	}
	/* begin quickRemoveInvalidFillsAt: */
	if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
		goto l3;
	}
	while ((topRightX()) <= (objBuffer[edge + GEXValue])) {
		hideFilldepth(topFill(), topDepth());
		if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
			goto l3;
		}
	}
	l3:	/* end quickRemoveInvalidFillsAt: */;
	return 0;
}


/*	Make the fill style with the given index either visible or invisible */

	/* BalloonEngineBase>>#toggleFill:depth:rightX: */
static sqInt
toggleFilldepthrightX(sqInt fillIndex, sqInt depth, sqInt rightX)
{
    sqInt hidden;
    sqInt index;
    sqInt index1;
    sqInt index2;

	if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
		if (wbStackPush(3 /* stackFillEntryLength */)) {
			/* begin stackFillValue:put: */
			index = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
			workBuffer[(workBuffer[GWBufferTop]) + index] = fillIndex;
			/* begin stackFillDepth:put: */
			index1 = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
			workBuffer[(workBuffer[GWBufferTop]) + (index1 + 1)] = depth;
			/* begin stackFillRightX:put: */
			index2 = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
			workBuffer[(workBuffer[GWBufferTop]) + (index2 + 2)] = rightX;
		}
	}
	else {
		hidden = hideFilldepth(fillIndex, depth);
		if (!hidden) {
			showFilldepthrightX(fillIndex, depth, rightX);
		}
	}
	return 0;
}

	/* BalloonEngineBase>>#toggleWideFillOf: */
static sqInt
toggleWideFillOf(sqInt edge)
{
    sqInt depth;
    sqInt fill;
    sqInt index;
    sqInt lineWidth;
    sqInt rightX;
    sqInt type;

	type = ((usqInt) ((objBuffer[edge + GEObjectType]) & GEPrimitiveTypeMask)) >> 1;
	dispatchedValue = edge;
	switch (type) {
	case 0:
	case 1:
		errorWrongIndex();
		break;
	case 2:
		dispatchReturnValue = objBuffer[dispatchedValue + GLWideWidth];
		break;
	case 3:
		dispatchReturnValue = objBuffer[dispatchedValue + GBWideWidth];
		break;
	}
	lineWidth = dispatchReturnValue;
	switch (type) {
	case 0:
	case 1:
		errorWrongIndex();
		break;
	case 2:
		dispatchReturnValue = objBuffer[dispatchedValue + GLWideFill];
		break;
	case 3:
		dispatchReturnValue = objBuffer[dispatchedValue + GBWideFill];
		break;
	}
	fill = dispatchReturnValue;
	if (fill == 0) {
		return null;
	}
	if (!(needAvailableSpace(3 /* stackFillEntryLength */))) {
		return null;
	}

	/* So lines sort before interior fills */
	depth = (((sqInt)((usqInt)((objBuffer[edge + GEZValue])) << 1))) + 1;
	rightX = (objBuffer[edge + GEXValue]) + lineWidth;
	index = findStackFilldepth(fill, depth);
	if (index == -1) {
		showFilldepthrightX(fill, depth, rightX);
	}
	else {
		if ((workBuffer[(workBuffer[GWBufferTop]) + (index + 2)]) < rightX) {
			workBuffer[(workBuffer[GWBufferTop]) + (index + 2)] = rightX;
		}
	}
	/* begin quickRemoveInvalidFillsAt: */
	if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
		goto l1;
	}
	while ((topRightX()) <= (objBuffer[edge + GEXValue])) {
		hideFilldepth(topFill(), topDepth());
		if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
			goto l1;
		}
	}
	l1:	/* end quickRemoveInvalidFillsAt: */;
	return 0;
}

	/* BalloonEngineBase>>#topDepth */
static sqInt
topDepth(void)
{
    sqInt index;

	if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
		return -1;
	}
	else {
		/* begin stackFillDepth: */
		index = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
		return workBuffer[(workBuffer[GWBufferTop]) + (index + 1)];
	}
}

	/* BalloonEngineBase>>#topFill */
static sqInt
topFill(void)
{
    sqInt index;

	if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
		return 0;
	}
	else {
		/* begin stackFillValue: */
		index = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
		return workBuffer[(workBuffer[GWBufferTop]) + index];
	}
}

	/* BalloonEngineBase>>#topFillDepth */
static sqInt
topFillDepth(void)
{
    sqInt index;

	/* begin stackFillDepth: */
	index = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
	return workBuffer[(workBuffer[GWBufferTop]) + (index + 1)];
}

	/* BalloonEngineBase>>#topFillDepthPut: */
static sqInt
topFillDepthPut(sqInt value)
{
    sqInt index;

	/* begin stackFillDepth:put: */
	index = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
	return workBuffer[(workBuffer[GWBufferTop]) + (index + 1)] = value;
}

	/* BalloonEngineBase>>#topFillRightX */
static sqInt
topFillRightX(void)
{
    sqInt index;

	/* begin stackFillRightX: */
	index = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
	return workBuffer[(workBuffer[GWBufferTop]) + (index + 2)];
}

	/* BalloonEngineBase>>#topFillRightXPut: */
static sqInt
topFillRightXPut(sqInt value)
{
    sqInt index;

	/* begin stackFillRightX:put: */
	index = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
	return workBuffer[(workBuffer[GWBufferTop]) + (index + 2)] = value;
}

	/* BalloonEngineBase>>#topFillValue */
static sqInt
topFillValue(void)
{
    sqInt index;

	/* begin stackFillValue: */
	index = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
	return workBuffer[(workBuffer[GWBufferTop]) + index];
}

	/* BalloonEngineBase>>#topFillValuePut: */
static sqInt
topFillValuePut(sqInt value)
{
    sqInt index;

	/* begin stackFillValue:put: */
	index = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
	return workBuffer[(workBuffer[GWBufferTop]) + index] = value;
}

	/* BalloonEngineBase>>#topRightX */
static sqInt
topRightX(void)
{
    sqInt index;

	if (((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) == 0) {
		return 999999999;
	}
	else {
		/* begin stackFillRightX: */
		index = ((workBuffer[GWSize]) - (workBuffer[GWBufferTop])) - 3 /* stackFillEntryLength */;
		return workBuffer[(workBuffer[GWBufferTop]) + (index + 2)];
	}
}

	/* BalloonEngineBase>>#transformColor: */
static sqInt
transformColor(sqInt fillIndex)
{
    sqInt a;
    double alphaScale;
    sqInt b;
    sqInt g;
    sqInt r;
    float *transform;

	if (!((fillIndex == 0)
		 || ((fillIndex & 0xFF000000U) != 0))) {
		return fillIndex;
	}
	b = fillIndex & 0xFF;
	g = (((usqInt) fillIndex) >> 8) & 0xFF;
	r = (((usqInt) fillIndex) >> 16) & 0xFF;
	a = (((usqInt) fillIndex) >> 24) & 0xFF;
	if ((workBuffer[GWHasColorTransform]) != 0) {
		/* begin colorTransform */
		transform = ((float *) (workBuffer + GWColorTransform));
		alphaScale = ((a * (transform[6])) + (transform[7])) / a;
		r = ((sqInt)(((r * (transform[0])) + (transform[1])) * alphaScale));
		g = ((sqInt)(((g * (transform[2])) + (transform[3])) * alphaScale));
		b = ((sqInt)(((b * (transform[4])) + (transform[5])) * alphaScale));
		a = a * alphaScale;
		r = ((r < 0) ? 0 : r);
		r = ((r < 0xFF) ? r : 0xFF);
		g = ((g < 0) ? 0 : g);
		g = ((g < 0xFF) ? g : 0xFF);
		b = ((b < 0) ? 0 : b);
		b = ((b < 0xFF) ? b : 0xFF);
		a = ((a < 0) ? 0 : a);
		a = ((a < 0xFF) ? a : 0xFF);
	}
	if (a < 1) {
		return 0;
	}
	if ((a < 0xFF)
	 && ((workBuffer[GWNeedsFlush]) != 0)) {
		/* begin stopBecauseOf: */
		workBuffer[GWStopReason] = GErrorNeedFlush;
		engineStopped = 1;
	}
	return ((b + (((sqInt)((usqInt)(g) << 8)))) + (((sqInt)((usqInt)(r) << 16)))) + (((sqInt)((usqInt)(a) << 24)));
}


/*	Transform n (n=1,2,3) points.
	If haveMatrix is true then the matrix contains the actual transformation. */

	/* BalloonEngineBase>>#transformPoints: */
static sqInt
transformPoints(sqInt n)
{
    int *point;
    int *point1;
    int *point2;
    int *point3;
    float *transform;
    float *transform1;
    float *transform2;
    float *transform3;
    sqInt x;
    sqInt x1;
    sqInt x2;
    sqInt x3;
    double xValue;
    double xValue1;
    double xValue2;
    double xValue3;
    sqInt y;
    sqInt y1;
    sqInt y2;
    sqInt y3;
    double yValue;
    double yValue1;
    double yValue2;
    double yValue3;

	if (n > 0) {
		/* begin transformPoint: */
		point = ((int *) (workBuffer + GWPoint1));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue = ((double) ((((int *) point))[0]) );
			yValue = ((double) ((((int *) point))[1]) );
			/* begin edgeTransform */
			transform = ((float *) (workBuffer + GWEdgeTransform));
			x = ((sqInt)(((((transform[0]) * xValue) + ((transform[1]) * yValue)) + (transform[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y = ((sqInt)(((((transform[3]) * xValue) + ((transform[4]) * yValue)) + (transform[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point))[0] = x;
			(((int *) point))[1] = y;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point[0] = (((point[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point[1] = (((point[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	if (n > 1) {
		/* begin transformPoint: */
		point1 = ((int *) (workBuffer + GWPoint2));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue1 = ((double) ((((int *) point1))[0]) );
			yValue1 = ((double) ((((int *) point1))[1]) );
			/* begin edgeTransform */
			transform1 = ((float *) (workBuffer + GWEdgeTransform));
			x1 = ((sqInt)(((((transform1[0]) * xValue1) + ((transform1[1]) * yValue1)) + (transform1[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y1 = ((sqInt)(((((transform1[3]) * xValue1) + ((transform1[4]) * yValue1)) + (transform1[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point1))[0] = x1;
			(((int *) point1))[1] = y1;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point1[0] = (((point1[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point1[1] = (((point1[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	if (n > 2) {
		/* begin transformPoint: */
		point2 = ((int *) (workBuffer + GWPoint3));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue2 = ((double) ((((int *) point2))[0]) );
			yValue2 = ((double) ((((int *) point2))[1]) );
			/* begin edgeTransform */
			transform2 = ((float *) (workBuffer + GWEdgeTransform));
			x2 = ((sqInt)(((((transform2[0]) * xValue2) + ((transform2[1]) * yValue2)) + (transform2[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y2 = ((sqInt)(((((transform2[3]) * xValue2) + ((transform2[4]) * yValue2)) + (transform2[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point2))[0] = x2;
			(((int *) point2))[1] = y2;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point2[0] = (((point2[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point2[1] = (((point2[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	if (n > 3) {
		/* begin transformPoint: */
		point3 = ((int *) (workBuffer + GWPoint4));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue3 = ((double) ((((int *) point3))[0]) );
			yValue3 = ((double) ((((int *) point3))[1]) );
			/* begin edgeTransform */
			transform3 = ((float *) (workBuffer + GWEdgeTransform));
			x3 = ((sqInt)(((((transform3[0]) * xValue3) + ((transform3[1]) * yValue3)) + (transform3[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y3 = ((sqInt)(((((transform3[3]) * xValue3) + ((transform3[4]) * yValue3)) + (transform3[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point3))[0] = x3;
			(((int *) point3))[1] = y3;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point3[0] = (((point3[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point3[1] = (((point3[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	return 0;
}


/*	Transform srcPoint into dstPoint by using the currently loaded matrix */
/*	Note: This should be rewritten so that inlining works (e.g., removing
	the declarations and adding argument coercions at the appropriate points) */

	/* BalloonEngineBase>>#transformPointX:y:into: */
static sqInt
transformPointXyinto(double xValue, double yValue, int *dstPoint)
{
    float *transform;
    sqInt x;
    sqInt y;

	/* begin edgeTransform */
	transform = ((float *) (workBuffer + GWEdgeTransform));
	x = ((sqInt)(((((transform[0]) * xValue) + ((transform[1]) * yValue)) + (transform[2])) * (((double) (workBuffer[GWAALevel]) ))));
	y = ((sqInt)(((((transform[3]) * xValue) + ((transform[4]) * yValue)) + (transform[5])) * (((double) (workBuffer[GWAALevel]) ))));
	dstPoint[0] = x;
	dstPoint[1] = y;
	return 0;
}


/*	Transform the given point. If haveMatrix is true then use the current
	transformation. 
 */

	/* BalloonEngineBase>>#transformPoint: */
static sqInt
transformPoint(int *point)
{
    float *transform;
    sqInt x;
    double xValue;
    sqInt y;
    double yValue;

	if ((workBuffer[GWHasEdgeTransform]) != 0) {

		/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
		/* begin transformPoint:into: */
		xValue = ((double) ((((int *) point))[0]) );
		yValue = ((double) ((((int *) point))[1]) );
		/* begin edgeTransform */
		transform = ((float *) (workBuffer + GWEdgeTransform));
		x = ((sqInt)(((((transform[0]) * xValue) + ((transform[1]) * yValue)) + (transform[2])) * (((double) (workBuffer[GWAALevel]) ))));
		y = ((sqInt)(((((transform[3]) * xValue) + ((transform[4]) * yValue)) + (transform[5])) * (((double) (workBuffer[GWAALevel]) ))));
		(((int *) point))[0] = x;
		(((int *) point))[1] = y;
	}
	else {

		/* Multiply each component by aaLevel and add a half pixel */
		point[0] = (((point[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
		point[1] = (((point[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
	}
	return 0;
}


/*	Transform srcPoint into dstPoint by using the currently loaded matrix */
/*	Note: This method has been rewritten so that inlining works (e.g.,
	removing the declarations and adding argument coercions at the appropriate
	points) 
 */

	/* BalloonEngineBase>>#transformPoint:into: */
static sqInt
transformPointinto(sqInt srcPoint, sqInt dstPoint)
{
    float *transform;
    sqInt x;
    double xValue;
    sqInt y;
    double yValue;

	/* begin transformPointX:y:into: */
	xValue = ((double) ((((int *) srcPoint))[0]) );
	yValue = ((double) ((((int *) srcPoint))[1]) );
	/* begin edgeTransform */
	transform = ((float *) (workBuffer + GWEdgeTransform));
	x = ((sqInt)(((((transform[0]) * xValue) + ((transform[1]) * yValue)) + (transform[2])) * (((double) (workBuffer[GWAALevel]) ))));
	y = ((sqInt)(((((transform[3]) * xValue) + ((transform[4]) * yValue)) + (transform[5])) * (((double) (workBuffer[GWAALevel]) ))));
	(((int *) dstPoint))[0] = x;
	(((int *) dstPoint))[1] = y;
	return 0;
}


/*	Transform the given width */

	/* BalloonEngineBase>>#transformWidth: */
static sqInt
transformWidth(sqInt w)
{
    double deltaX;
    double deltaY;
    sqInt dstWidth;
    sqInt dstWidth2;
    int *point;
    int *point1;
    int *point2;
    int *point3;
    float *transform;
    float *transform1;
    float *transform2;
    float *transform3;
    sqInt x;
    sqInt x1;
    sqInt x2;
    sqInt x3;
    double xValue;
    double xValue1;
    double xValue2;
    double xValue3;
    sqInt y;
    sqInt y1;
    sqInt y2;
    sqInt y3;
    double yValue;
    double yValue1;
    double yValue2;
    double yValue3;

	if (w == 0) {
		return 0;
	}
	(((int *) (workBuffer + GWPoint1)))[0] = 0;
	(((int *) (workBuffer + GWPoint1)))[1] = 0;
	(((int *) (workBuffer + GWPoint2)))[0] = (w * 256);
	(((int *) (workBuffer + GWPoint2)))[1] = 0;
	(((int *) (workBuffer + GWPoint3)))[0] = 0;
	(((int *) (workBuffer + GWPoint3)))[1] = (w * 256);
	/* begin transformPoints: */
	if (3 > 0) {
		/* begin transformPoint: */
		point = ((int *) (workBuffer + GWPoint1));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue = ((double) ((((int *) point))[0]) );
			yValue = ((double) ((((int *) point))[1]) );
			/* begin edgeTransform */
			transform = ((float *) (workBuffer + GWEdgeTransform));
			x = ((sqInt)(((((transform[0]) * xValue) + ((transform[1]) * yValue)) + (transform[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y = ((sqInt)(((((transform[3]) * xValue) + ((transform[4]) * yValue)) + (transform[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point))[0] = x;
			(((int *) point))[1] = y;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point[0] = (((point[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point[1] = (((point[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	if (3 > 1) {
		/* begin transformPoint: */
		point1 = ((int *) (workBuffer + GWPoint2));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue1 = ((double) ((((int *) point1))[0]) );
			yValue1 = ((double) ((((int *) point1))[1]) );
			/* begin edgeTransform */
			transform1 = ((float *) (workBuffer + GWEdgeTransform));
			x1 = ((sqInt)(((((transform1[0]) * xValue1) + ((transform1[1]) * yValue1)) + (transform1[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y1 = ((sqInt)(((((transform1[3]) * xValue1) + ((transform1[4]) * yValue1)) + (transform1[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point1))[0] = x1;
			(((int *) point1))[1] = y1;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point1[0] = (((point1[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point1[1] = (((point1[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	if (3 > 2) {
		/* begin transformPoint: */
		point2 = ((int *) (workBuffer + GWPoint3));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue2 = ((double) ((((int *) point2))[0]) );
			yValue2 = ((double) ((((int *) point2))[1]) );
			/* begin edgeTransform */
			transform2 = ((float *) (workBuffer + GWEdgeTransform));
			x2 = ((sqInt)(((((transform2[0]) * xValue2) + ((transform2[1]) * yValue2)) + (transform2[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y2 = ((sqInt)(((((transform2[3]) * xValue2) + ((transform2[4]) * yValue2)) + (transform2[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point2))[0] = x2;
			(((int *) point2))[1] = y2;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point2[0] = (((point2[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point2[1] = (((point2[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	if (3 > 3) {
		/* begin transformPoint: */
		point3 = ((int *) (workBuffer + GWPoint4));
		if ((workBuffer[GWHasEdgeTransform]) != 0) {

			/* Note: AA adjustment is done in #transformPoint: for higher accuracy */
			/* begin transformPoint:into: */
			xValue3 = ((double) ((((int *) point3))[0]) );
			yValue3 = ((double) ((((int *) point3))[1]) );
			/* begin edgeTransform */
			transform3 = ((float *) (workBuffer + GWEdgeTransform));
			x3 = ((sqInt)(((((transform3[0]) * xValue3) + ((transform3[1]) * yValue3)) + (transform3[2])) * (((double) (workBuffer[GWAALevel]) ))));
			y3 = ((sqInt)(((((transform3[3]) * xValue3) + ((transform3[4]) * yValue3)) + (transform3[5])) * (((double) (workBuffer[GWAALevel]) ))));
			(((int *) point3))[0] = x3;
			(((int *) point3))[1] = y3;
		}
		else {

			/* Multiply each component by aaLevel and add a half pixel */
			point3[0] = (((point3[0]) + (workBuffer[GWDestOffsetX])) * (workBuffer[GWAALevel]));
			point3[1] = (((point3[1]) + (workBuffer[GWDestOffsetY])) * (workBuffer[GWAALevel]));
		}
	}
	deltaX = ((double) (((((int *) (workBuffer + GWPoint2)))[0]) - ((((int *) (workBuffer + GWPoint1)))[0])) );
	deltaY = ((double) (((((int *) (workBuffer + GWPoint2)))[1]) - ((((int *) (workBuffer + GWPoint1)))[1])) );
	dstWidth = ((((sqInt)(sqrt((deltaX * deltaX) + (deltaY * deltaY))))) + 128) / 256;
	deltaX = ((double) (((((int *) (workBuffer + GWPoint3)))[0]) - ((((int *) (workBuffer + GWPoint1)))[0])) );
	deltaY = ((double) (((((int *) (workBuffer + GWPoint3)))[1]) - ((((int *) (workBuffer + GWPoint1)))[1])) );
	dstWidth2 = ((((sqInt)(sqrt((deltaX * deltaX) + (deltaY * deltaY))))) + 128) / 256;
	if (dstWidth2 < dstWidth) {
		dstWidth = dstWidth2;
	}
	if (dstWidth == 0) {
		return 1;
	}
	else {
		return dstWidth;
	}
}

	/* BalloonEngineBase>>#uncheckedTransformColor: */
static sqInt
uncheckedTransformColor(sqInt fillIndex)
{
    sqInt a;
    sqInt b;
    sqInt g;
    sqInt r;
    float *transform;

	if (!((workBuffer[GWHasColorTransform]) != 0)) {
		return fillIndex;
	}
	b = fillIndex & 0xFF;
	g = (((usqInt) fillIndex) >> 8) & 0xFF;
	r = (((usqInt) fillIndex) >> 16) & 0xFF;
	a = (((usqInt) fillIndex) >> 24) & 0xFF;
	/* begin colorTransform */
	transform = ((float *) (workBuffer + GWColorTransform));
	r = ((sqInt)((r * (transform[0])) + (transform[1])));
	g = ((sqInt)((g * (transform[2])) + (transform[3])));
	b = ((sqInt)((b * (transform[4])) + (transform[5])));
	a = ((sqInt)((a * (transform[6])) + (transform[7])));
	r = ((r < 0) ? 0 : r);
	r = ((r < 0xFF) ? r : 0xFF);
	g = ((g < 0) ? 0 : g);
	g = ((g < 0xFF) ? g : 0xFF);
	b = ((b < 0) ? 0 : b);
	b = ((b < 0xFF) ? b : 0xFF);
	a = ((a < 0) ? 0 : a);
	a = ((a < 0xFF) ? a : 0xFF);
	if (a < 16) {
		return 0;
	}
	return ((b + (((sqInt)((usqInt)(g) << 8)))) + (((sqInt)((usqInt)(r) << 16)))) + (((sqInt)((usqInt)(a) << 24)));
}

	/* BalloonEngineBase>>#wbSizeGet */
static sqInt
wbSizeGet(void)
{
	return workBuffer[GWSize];
}

	/* BalloonEngineBase>>#wbSizePut: */
static sqInt
wbSizePut(sqInt value)
{
	return workBuffer[GWSize] = value;
}

	/* BalloonEngineBase>>#wbStackClear */
static sqInt
wbStackClear(void)
{
	/* begin wbTopPut: */
	workBuffer[GWBufferTop] = (workBuffer[GWSize]);
	return 0;
}

	/* BalloonEngineBase>>#wbStackPop: */
static sqInt
wbStackPop(sqInt nItems)
{
	/* begin wbTopPut: */
	workBuffer[GWBufferTop] = ((workBuffer[GWBufferTop]) + nItems);
	return 0;
}

	/* BalloonEngineBase>>#wbStackPush: */
static sqInt
wbStackPush(sqInt nItems)
{
	if (!(needAvailableSpace(nItems))) {
		return 0;
	}
	/* begin wbTopPut: */
	workBuffer[GWBufferTop] = ((workBuffer[GWBufferTop]) - nItems);
	return 1;
}

	/* BalloonEngineBase>>#wbStackSize */
static sqInt
wbStackSize(void)
{
	return (workBuffer[GWSize]) - (workBuffer[GWBufferTop]);
}

	/* BalloonEngineBase>>#wbStackValue: */
static sqInt
wbStackValue(sqInt index)
{
	return workBuffer[(workBuffer[GWBufferTop]) + index];
}

	/* BalloonEngineBase>>#wbStackValue:put: */
static sqInt
wbStackValueput(sqInt index, sqInt value)
{
	return workBuffer[(workBuffer[GWBufferTop]) + index] = value;
}

	/* BalloonEngineBase>>#wbTopGet */
static sqInt
wbTopGet(void)
{
	return workBuffer[GWBufferTop];
}

	/* BalloonEngineBase>>#wbTopPut: */
static sqInt
wbTopPut(sqInt value)
{
	return workBuffer[GWBufferTop] = value;
}

	/* BalloonEnginePlugin>>#wideBezierEntryOf: */
static sqInt
wideBezierEntryOf(sqInt line)
{
	/* begin obj:at: */
	return objBuffer[line + GBWideEntry];
}

	/* BalloonEnginePlugin>>#wideBezierEntryOf:put: */
static sqInt
wideBezierEntryOfput(sqInt line, sqInt value)
{
	/* begin obj:at:put: */
	return objBuffer[line + GBWideEntry] = value;
}

	/* BalloonEnginePlugin>>#wideBezierExitOf: */
static sqInt
wideBezierExitOf(sqInt line)
{
	/* begin obj:at: */
	return objBuffer[line + GBWideExit];
}

	/* BalloonEnginePlugin>>#wideBezierExitOf:put: */
static sqInt
wideBezierExitOfput(sqInt line, sqInt value)
{
	/* begin obj:at:put: */
	return objBuffer[line + GBWideExit] = value;
}

	/* BalloonEnginePlugin>>#wideBezierExtentOf: */
static sqInt
wideBezierExtentOf(sqInt bezier)
{
	/* begin obj:at: */
	return objBuffer[bezier + GBWideExtent];
}

	/* BalloonEnginePlugin>>#wideBezierExtentOf:put: */
static sqInt
wideBezierExtentOfput(sqInt bezier, sqInt value)
{
	/* begin obj:at:put: */
	return objBuffer[bezier + GBWideExtent] = value;
}

	/* BalloonEnginePlugin>>#wideBezierFillOf: */
static sqInt
wideBezierFillOf(sqInt bezier)
{
	/* begin obj:at: */
	return objBuffer[bezier + GBWideFill];
}

	/* BalloonEnginePlugin>>#wideBezierFillOf:put: */
static sqInt
wideBezierFillOfput(sqInt bezier, sqInt value)
{
	/* begin obj:at:put: */
	return objBuffer[bezier + GBWideFill] = value;
}

	/* BalloonEnginePlugin>>#wideBezierUpdateDataOf: */
static int *
wideBezierUpdateDataOf(sqInt bezier)
{
	return (objBuffer + bezier) + GBWideUpdateData;
}

	/* BalloonEnginePlugin>>#wideBezierWidthOf: */
static sqInt
wideBezierWidthOf(sqInt line)
{
	/* begin obj:at: */
	return objBuffer[line + GBWideWidth];
}

	/* BalloonEnginePlugin>>#wideBezierWidthOf:put: */
static sqInt
wideBezierWidthOfput(sqInt line, sqInt value)
{
	/* begin obj:at:put: */
	return objBuffer[line + GBWideWidth] = value;
}

	/* BalloonEnginePlugin>>#wideLineEntryOf: */
static sqInt
wideLineEntryOf(sqInt line)
{
	/* begin obj:at: */
	return objBuffer[line + GLWideEntry];
}

	/* BalloonEnginePlugin>>#wideLineEntryOf:put: */
static sqInt
wideLineEntryOfput(sqInt line, sqInt value)
{
	/* begin obj:at:put: */
	return objBuffer[line + GLWideEntry] = value;
}

	/* BalloonEnginePlugin>>#wideLineExitOf: */
static sqInt
wideLineExitOf(sqInt line)
{
	/* begin obj:at: */
	return objBuffer[line + GLWideExit];
}

	/* BalloonEnginePlugin>>#wideLineExitOf:put: */
static sqInt
wideLineExitOfput(sqInt line, sqInt value)
{
	/* begin obj:at:put: */
	return objBuffer[line + GLWideExit] = value;
}

	/* BalloonEnginePlugin>>#wideLineExtentOf: */
static sqInt
wideLineExtentOf(sqInt line)
{
	/* begin obj:at: */
	return objBuffer[line + GLWideExtent];
}

	/* BalloonEnginePlugin>>#wideLineExtentOf:put: */
static sqInt
wideLineExtentOfput(sqInt line, sqInt value)
{
	/* begin obj:at:put: */
	return objBuffer[line + GLWideExtent] = value;
}

	/* BalloonEnginePlugin>>#wideLineFillOf: */
static sqInt
wideLineFillOf(sqInt line)
{
	/* begin obj:at: */
	return objBuffer[line + GLWideFill];
}

	/* BalloonEnginePlugin>>#wideLineFillOf:put: */
static sqInt
wideLineFillOfput(sqInt line, sqInt value)
{
	/* begin obj:at:put: */
	return objBuffer[line + GLWideFill] = value;
}

	/* BalloonEnginePlugin>>#wideLineWidthOf: */
static sqInt
wideLineWidthOf(sqInt line)
{
	/* begin obj:at: */
	return objBuffer[line + GLWideWidth];
}

	/* BalloonEnginePlugin>>#wideLineWidthOf:put: */
static sqInt
wideLineWidthOfput(sqInt line, sqInt value)
{
	/* begin obj:at:put: */
	return objBuffer[line + GLWideWidth] = value;
}

	/* BalloonEngineBase>>#workBufferPut: */
static sqInt
workBufferPut(sqInt wbOop)
{
	workBuffer = firstIndexableField(wbOop);
	return 0;
}


#ifdef SQUEAK_BUILTIN_PLUGIN

static char _m[] = "B2DPlugin";
void* B2DPlugin_exports[][3] = {
	{(void*)_m, "getModuleName", (void*)getModuleName},
	{(void*)_m, "initialiseModule", (void*)initialiseModule},
	{(void*)_m, "moduleUnloaded", (void*)moduleUnloaded},
	{(void*)_m, "primitiveAbortProcessing\000\002", (void*)primitiveAbortProcessing},
	{(void*)_m, "primitiveAddActiveEdgeEntry\000\003", (void*)primitiveAddActiveEdgeEntry},
	{(void*)_m, "primitiveAddBezier\000\002", (void*)primitiveAddBezier},
	{(void*)_m, "primitiveAddBezierShape\000\003", (void*)primitiveAddBezierShape},
	{(void*)_m, "primitiveAddBitmapFill\000\002", (void*)primitiveAddBitmapFill},
	{(void*)_m, "primitiveAddCompressedShape\000\002", (void*)primitiveAddCompressedShape},
	{(void*)_m, "primitiveAddGradientFill\000\002", (void*)primitiveAddGradientFill},
	{(void*)_m, "primitiveAddLine\000\002", (void*)primitiveAddLine},
	{(void*)_m, "primitiveAddOval\000\002", (void*)primitiveAddOval},
	{(void*)_m, "primitiveAddPolygon\000\002", (void*)primitiveAddPolygon},
	{(void*)_m, "primitiveAddRect\000\002", (void*)primitiveAddRect},
	{(void*)_m, "primitiveChangedActiveEdgeEntry\000\002", (void*)primitiveChangedActiveEdgeEntry},
	{(void*)_m, "primitiveCopyBuffer\000\001", (void*)primitiveCopyBuffer},
	{(void*)_m, "primitiveDisplaySpanBuffer\000\002", (void*)primitiveDisplaySpanBuffer},
	{(void*)_m, "primitiveDoProfileStats\000\000", (void*)primitiveDoProfileStats},
	{(void*)_m, "primitiveFinishedProcessing\000\002", (void*)primitiveFinishedProcessing},
	{(void*)_m, "primitiveGetAALevel\000\002", (void*)primitiveGetAALevel},
	{(void*)_m, "primitiveGetBezierStats\000\002", (void*)primitiveGetBezierStats},
	{(void*)_m, "primitiveGetClipRect\000\002", (void*)primitiveGetClipRect},
	{(void*)_m, "primitiveGetCounts\000\002", (void*)primitiveGetCounts},
	{(void*)_m, "primitiveGetDepth\000\002", (void*)primitiveGetDepth},
	{(void*)_m, "primitiveGetFailureReason\000\002", (void*)primitiveGetFailureReason},
	{(void*)_m, "primitiveGetOffset\000\002", (void*)primitiveGetOffset},
	{(void*)_m, "primitiveGetTimes\000\002", (void*)primitiveGetTimes},
	{(void*)_m, "primitiveInitializeBuffer\000\001", (void*)primitiveInitializeBuffer},
	{(void*)_m, "primitiveInitializeProcessing\000\002", (void*)primitiveInitializeProcessing},
	{(void*)_m, "primitiveMergeFillFrom\000\002", (void*)primitiveMergeFillFrom},
	{(void*)_m, "primitiveNeedsFlush\000\002", (void*)primitiveNeedsFlush},
	{(void*)_m, "primitiveNeedsFlushPut\000\002", (void*)primitiveNeedsFlushPut},
	{(void*)_m, "primitiveNextActiveEdgeEntry\000\002", (void*)primitiveNextActiveEdgeEntry},
	{(void*)_m, "primitiveNextFillEntry\000\003", (void*)primitiveNextFillEntry},
	{(void*)_m, "primitiveNextGlobalEdgeEntry\000\002", (void*)primitiveNextGlobalEdgeEntry},
	{(void*)_m, "primitiveRegisterExternalEdge\000\002", (void*)primitiveRegisterExternalEdge},
	{(void*)_m, "primitiveRegisterExternalFill\000\002", (void*)primitiveRegisterExternalFill},
	{(void*)_m, "primitiveRenderImage\000\003", (void*)primitiveRenderImage},
	{(void*)_m, "primitiveRenderScanline\000\003", (void*)primitiveRenderScanline},
	{(void*)_m, "primitiveSetAALevel\000\002", (void*)primitiveSetAALevel},
	{(void*)_m, "primitiveSetBitBltPlugin\000\001", (void*)primitiveSetBitBltPlugin},
	{(void*)_m, "primitiveSetClipRect\000\002", (void*)primitiveSetClipRect},
	{(void*)_m, "primitiveSetColorTransform\000\002", (void*)primitiveSetColorTransform},
	{(void*)_m, "primitiveSetDepth\000\002", (void*)primitiveSetDepth},
	{(void*)_m, "primitiveSetEdgeTransform\000\002", (void*)primitiveSetEdgeTransform},
	{(void*)_m, "primitiveSetOffset\000\002", (void*)primitiveSetOffset},
	{(void*)_m, "setInterpreter", (void*)setInterpreter},
	{NULL, NULL, NULL}
};

#else /* ifdef SQ_BUILTIN_PLUGIN */

EXPORT(signed char) primitiveAbortProcessingAccessorDepth = 2;
EXPORT(signed char) primitiveAddActiveEdgeEntryAccessorDepth = 3;
EXPORT(signed char) primitiveAddBezierAccessorDepth = 2;
EXPORT(signed char) primitiveAddBezierShapeAccessorDepth = 3;
EXPORT(signed char) primitiveAddBitmapFillAccessorDepth = 2;
EXPORT(signed char) primitiveAddCompressedShapeAccessorDepth = 2;
EXPORT(signed char) primitiveAddGradientFillAccessorDepth = 2;
EXPORT(signed char) primitiveAddLineAccessorDepth = 2;
EXPORT(signed char) primitiveAddOvalAccessorDepth = 2;
EXPORT(signed char) primitiveAddPolygonAccessorDepth = 2;
EXPORT(signed char) primitiveAddRectAccessorDepth = 2;
EXPORT(signed char) primitiveChangedActiveEdgeEntryAccessorDepth = 2;
EXPORT(signed char) primitiveCopyBufferAccessorDepth = 1;
EXPORT(signed char) primitiveDisplaySpanBufferAccessorDepth = 2;
EXPORT(signed char) primitiveDoProfileStatsAccessorDepth = 0;
EXPORT(signed char) primitiveFinishedProcessingAccessorDepth = 2;
EXPORT(signed char) primitiveGetAALevelAccessorDepth = 2;
EXPORT(signed char) primitiveGetBezierStatsAccessorDepth = 2;
EXPORT(signed char) primitiveGetClipRectAccessorDepth = 2;
EXPORT(signed char) primitiveGetCountsAccessorDepth = 2;
EXPORT(signed char) primitiveGetDepthAccessorDepth = 2;
EXPORT(signed char) primitiveGetFailureReasonAccessorDepth = 2;
EXPORT(signed char) primitiveGetOffsetAccessorDepth = 2;
EXPORT(signed char) primitiveGetTimesAccessorDepth = 2;
EXPORT(signed char) primitiveInitializeBufferAccessorDepth = 1;
EXPORT(signed char) primitiveInitializeProcessingAccessorDepth = 2;
EXPORT(signed char) primitiveMergeFillFromAccessorDepth = 2;
EXPORT(signed char) primitiveNeedsFlushAccessorDepth = 2;
EXPORT(signed char) primitiveNeedsFlushPutAccessorDepth = 2;
EXPORT(signed char) primitiveNextActiveEdgeEntryAccessorDepth = 2;
EXPORT(signed char) primitiveNextFillEntryAccessorDepth = 3;
EXPORT(signed char) primitiveNextGlobalEdgeEntryAccessorDepth = 2;
EXPORT(signed char) primitiveRegisterExternalEdgeAccessorDepth = 2;
EXPORT(signed char) primitiveRegisterExternalFillAccessorDepth = 2;
EXPORT(signed char) primitiveRenderImageAccessorDepth = 3;
EXPORT(signed char) primitiveRenderScanlineAccessorDepth = 3;
EXPORT(signed char) primitiveSetAALevelAccessorDepth = 2;
EXPORT(signed char) primitiveSetBitBltPluginAccessorDepth = 1;
EXPORT(signed char) primitiveSetClipRectAccessorDepth = 2;
EXPORT(signed char) primitiveSetColorTransformAccessorDepth = 2;
EXPORT(signed char) primitiveSetDepthAccessorDepth = 2;
EXPORT(signed char) primitiveSetEdgeTransformAccessorDepth = 2;
EXPORT(signed char) primitiveSetOffsetAccessorDepth = 2;

#endif /* ifdef SQ_BUILTIN_PLUGIN */
