/****************************************************************************************/
/*  FONT.C                                                                              */
/*                                                                                      */
/*  Author: Thom Robertson                                                              */
/*  Description: Bitmapped font support implementation                                  */
/*               This implementation supports any TrueType fonts provided by Windows    */
/*                                                                                      */
/*  The contents of this file are subject to the Jet3D Public License                   */
/*  Version 1.02 (the "License"); you may not use this file except in                   */
/*  compliance with the License. You may obtain a copy of the License at                */
/*  http://www.jet3d.com                                                                */
/*                                                                                      */
/*  Software distributed under the License is distributed on an "AS IS"                 */
/*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
/*  the License for the specific language governing rights and limitations              */
/*  under the License.                                                                  */
/*                                                                                      */
/*  The Original Code is Jet3D, released December 12, 1999.                             */
/*  Copyright (C) 1996-1999 Eclipse Entertainment, L.L.C. All Rights Reserved           */
/*                                                                                      */
/****************************************************************************************/

#define	WIN32_LEAN_AND_MEAN
#pragma warning(disable : 4201 4214 4115)
#include <windows.h>
#include <windowsx.h>
#pragma warning(default : 4201 4214 4115)

#include "extbox.h"
#include "ram.h"
#include "wgClip.h"

#include <assert.h>
#include <string.h>

#include "font.h"

#pragma warning (disable:4514)	// unreferenced inline function (caused by Windows)

// @@ TIME THIS :

#if 1 // @@
#define FONT_BITMAP_TYPE	JE_ENGINE_BITMAP_TYPE_2D
#define FONT_DRAWBITMAP		jeEngine_DrawBitmap
#else
#define FONT_BITMAP_TYPE	JE_ENGINE_BITMAP_TYPE_3D
#define FONT_DRAWBITMAP		jeEngine_DrawBitmap3D
#endif

//*************************************************************************************** 
JETAPI jeBoolean  JETCC jeFont_TestDraw(jeFont *font, int16 x, int16 y, int16 index);
	// This is a debugging function that you shouldn't have to use.  It outputs an entire
	// bitmap full of characters to the screen and the x,y location.

	// ARGUMENTS:
	// font - pointer to the font to draw with.
	// x and y - screen location to draw the upper left corner of the bitamp at.
	// index - which bitmap to draw.

	// RETURNS:
	// success: JE_TRUE
	// failure: JE_FALSE

	// NOTES:
	// Since fonts can be of an arbitrary point size, an arbitrary amount of 256x256
	// bitmaps is required to represent all of the characters.  The index argument lets you
	// pick which bitmap in the list to display.



//*******************************************************************************
typedef struct jeFontBitmap
{
	void *next;
	jeBitmap *map;
	int16 freeX, freeY;  // place the next character here.

} jeFontBitmap;

//*******************************************************************************
typedef struct jeFontCharacterRecord
{
	jeFontBitmap *bitmapUsed;  // NULL == not initialized yet.
	JE_Rect bitmapRect;
	int32 offsetX, offsetY, fullWidth;

} jeFontCharacterRecord;

//*******************************************************************************
typedef struct jeFont 
{
	char fontNameString[64];
	int16 fontSize;
	int16 fontWeight;
	jeFontBitmap *bitmapList;
	jeFontCharacterRecord characterArray[256];
	const jeEngine *Engine;
	jeBitmap *buffer;

	jeBoolean antialiased;

	int32 refCount;

} jeFont;



JETAPI jeBoolean JETCC jeFont_DrawUsingDIB(jeFont *font, const char *textString, 
																	RECT box, jeBitmap *targetBitmap,
																	const JE_RGBA *Color, uint32 flags);

//*******************************************************************************
//*******************************************************************************
JETAPI jeFont *JETCC jeFont_Create(const jeEngine *Engine, const char *fontNameString, 
															  const int fontSize, const int fontWeight,
															  const jeBoolean anti)
{
	jeFont *font;
	int i;

	// create a new font
	font = JE_RAM_ALLOCATE_STRUCT(jeFont);
	assert(font);

	// initalize the new font to having no data in it.
	font->bitmapList = NULL;
	for (i = 0; i < 256; i++)
		font->characterArray[i].bitmapUsed = NULL;

	strncpy(font->fontNameString, fontNameString,64);
	font->fontNameString[63] = 0;

	font->fontSize = fontSize;
	font->fontWeight = fontWeight;

	font->Engine = Engine;

	font->buffer = NULL;

	font->refCount = 1;

	font->antialiased = anti;

	return font;
}

//*************************************************************************************** 
JETAPI void JETCC jeFont_CreateRef(jeFont *font)
{
	assert(font);
	font->refCount++;

//	return font;
}


//*******************************************************************************
JETAPI void JETCC jeFont_Destroy(jeFont **font)
{

	jeFontBitmap *curFontBitmap, *tempFontBitmap;

	assert(*font);

	(*font)->refCount--;

	// don't destroy this font if there's still a reference out there.
	if ((*font)->refCount > 0)
		return;

	jeFont_DestroyBitmapBuffer(*font);

	curFontBitmap = (*font)->bitmapList;
	while (curFontBitmap)
	{
		tempFontBitmap = curFontBitmap->next;

		jeEngine_RemoveBitmap((jeEngine *) (*font)->Engine, curFontBitmap->map);

		jeBitmap_Destroy(&(curFontBitmap->map));
		jeRam_Free(curFontBitmap);
		curFontBitmap = tempFontBitmap;
	}

	jeRam_Free(*font);
	(*font) = NULL;

}

//****************************************************************************
FIXED PASCAL NEAR FixedFromDouble(double d)
{
	 long l;

	 l = (long) (d * 65536L);
	 return *(FIXED *)&l;
}

//*******************************************************************************
static	void	IdentityMat(LPMAT2 lpMat)
{
	 lpMat->eM11 = FixedFromDouble(1);
	 lpMat->eM12 = FixedFromDouble(0);
	 lpMat->eM21 = FixedFromDouble(0);
	 lpMat->eM22 = FixedFromDouble(1);
}

//*******************************************************************************
void PlaceLetter(int16 locX, int16 locY, jeFont *font, jeFontBitmap *fontMap, 
					  uint32 asciiValue, unsigned char *cellBuffer, DWORD bufferSize)
{
	GLYPHMETRICS glyphMetrics;
	HDC hdc; 
	MAT2 mat2;
	int32 success, bufferReturnSize;
	uint32 x,y;
	unsigned char *destBits;
	int bufferWidth, possibleH;
	char c;
	int16 mapWidth, mapHeight;
	HFONT win32Font, win32OldFont;
	jeBitmap *lock;
	jeBitmap_Info Info;
	jeBitmap_Info SecondaryInfo;

	uint32 ggoFormat;

	IdentityMat(&mat2);
/*
	mat2.eM11.fract = 0;
	mat2.eM11.value = 1;
	mat2.eM12.fract = 0;
	mat2.eM12.value = 0;
	mat2.eM21.fract = 0;
	mat2.eM21.value = 0;
	mat2.eM22.fract = 0;
	mat2.eM22.value = 1;
*/
	mapWidth  = jeBitmap_Width (fontMap->map);
	mapHeight = jeBitmap_Height(fontMap->map);
	/*
	{
	jeBitmap *testBM;
	jeVFile  *file;
	file = jeVFile_OpenNewSystem(NULL, JE_VFILE_TYPE_DOS, 
														"c:\\crap.bmp", 
														NULL, JE_VFILE_OPEN_READONLY);
	testBM = jeBitmap_CreateFromFile(file);
	jeVFile_Close(file);

	jeBitmap_BlitBitmap(testBM, fontMap->map);
	jeBitmap_Destroy(&testBM);
	return;
	}
	 */
//	NEWTEXTMETRIC

	win32Font = CreateFont( -1 * font->fontSize,
	 						 0,0,0, font->fontWeight,
	 						 0,0,0,0,OUT_TT_ONLY_PRECIS ,0,0,0, font->fontNameString);

	hdc = GetDC(GetDesktopWindow());
	assert(hdc);

	c = (char)asciiValue;

	if (font->antialiased)
		ggoFormat = GGO_GRAY8_BITMAP;
	else
		ggoFormat = GGO_BITMAP;								

	win32OldFont = SelectObject( hdc, win32Font); 
	bufferReturnSize	 = GetGlyphOutline( hdc, asciiValue, ggoFormat, 
											&glyphMetrics, 0, NULL, &mat2);
	success	 = GetGlyphOutline( hdc, asciiValue, ggoFormat, 
											&glyphMetrics, bufferSize, cellBuffer, &mat2);
	assert(GDI_ERROR != success);
//	success	 = GetGlyphOutline( hdc, asciiValue, GGO_METRICS, &glyphMetrics, 0, NULL, &mat2);
//	assert(GDI_ERROR != success);
	SelectObject( hdc, win32OldFont); 

	ReleaseDC(GetDesktopWindow(),hdc);

	DeleteObject(win32Font);

	// get buffer width
//	bufferWidth = glyphMetrics.gmCellIncX - glyphMetrics.gmptGlyphOrigin.x;
//	bufferWidth = glyphMetrics.gmBlackBoxX;
	if (glyphMetrics.gmBlackBoxY)
	{
		possibleH = glyphMetrics.gmBlackBoxY-1;
		do 
		{
			possibleH++;
			bufferWidth = bufferReturnSize / possibleH;
		} while (bufferWidth * possibleH != bufferReturnSize);
	}
	else
	bufferWidth = glyphMetrics.gmBlackBoxX;

	if (GGO_BITMAP == ggoFormat)
	{
		bufferWidth/= 8;
		if (bufferWidth <= 0)
			bufferWidth = 1;
	}


	// make sure it's double-word aligned.
	while (bufferWidth%4)
		bufferWidth++;

	font->characterArray[asciiValue].bitmapUsed = fontMap;
	font->characterArray[asciiValue].bitmapRect.Left	= fontMap->freeX;
	font->characterArray[asciiValue].bitmapRect.Top	 = fontMap->freeY;
	font->characterArray[asciiValue].bitmapRect.Right  = fontMap->freeX +
																	glyphMetrics.gmBlackBoxX;
	font->characterArray[asciiValue].bitmapRect.Bottom = fontMap->freeY +
																			glyphMetrics.gmBlackBoxY;
	font->characterArray[asciiValue].offsetX	= glyphMetrics.gmptGlyphOrigin.x;
	font->characterArray[asciiValue].offsetY	= glyphMetrics.gmptGlyphOrigin.y;
	font->characterArray[asciiValue].fullWidth = glyphMetrics.gmCellIncX;

	glyphMetrics.gmptGlyphOrigin.y  = glyphMetrics.gmptGlyphOrigin.y - glyphMetrics.gmBlackBoxY;


	// lock the fontMap surface...
	success = jeBitmap_LockForWrite(	fontMap->map, &lock,
												0,0);
	success = jeBitmap_GetInfo(lock, &Info, &SecondaryInfo);
	mapWidth  = Info.Stride;

	destBits = jeBitmap_GetBits(lock);

	// clear the character space to 0s...
/*	for (y = locY; y < locY + glyphMetrics.gmBlackBoxY; y++)
	{
		for (x = locX; x < locX + glyphMetrics.gmCellIncX; x++)
		{
			destBits[y] = 128; // black/transparent
		}
	}
*/
	// and write the character to it.
	/*
	for ( y = locY + glyphMetrics.gmptGlyphOrigin.y; 
			y < locY + glyphMetrics.gmptGlyphOrigin.y + glyphMetrics.gmBlackBoxY; 
			y++)
	{
		for (x = locX + glyphMetrics.gmptGlyphOrigin.x;
			  x < locX + glyphMetrics.gmptGlyphOrigin.x + glyphMetrics.gmBlackBoxX; 
			  x++)
		{
			destBits[y*mapWidth + x] = cellBuffer[ 
																(y-(locY + glyphMetrics.gmptGlyphOrigin.y)) * 
																bufferWidth +
																(x-(locX + glyphMetrics.gmptGlyphOrigin.x))
															 ];
		}
	}
*/
	/*
	for ( y = locY; 
			y < locY + glyphMetrics.gmBlackBoxY; 
			y++)
	{
		for (x = locX;
			  x < locX + glyphMetrics.gmBlackBoxX; 
			  x++)
		{
			destBits[y*mapWidth + x] = cellBuffer[ 
																(y-locY) * 
																bufferWidth +
																(x-locX)
															 ];
		}
	}
	*/
	if (GGO_BITMAP == ggoFormat)								
	{

		for ( y = 0; 
				y < glyphMetrics.gmBlackBoxY; 
				y++)
		{
			for (x = 0;
				  x < glyphMetrics.gmBlackBoxX; 
				  x++)
			{
				uint8 temp, mask;
				temp = cellBuffer[y * bufferWidth + x/8];
				mask = 1 << (7 - (x % 8));

				if (mask&temp)
					destBits[(y+locY)*mapWidth + (x+locX)] = 255;
				else
					destBits[(y+locY)*mapWidth + (x+locX)] = 0;
			}
		}
	}
	else
	{
		for ( y = 0; 
				y < glyphMetrics.gmBlackBoxY; 
				y++)
		{
			for (x = 0;
				  x < glyphMetrics.gmBlackBoxX; 
				  x++)
			{
					int temp;
					temp = 4 * cellBuffer[y * bufferWidth + x];
					if (temp> 255)
						temp = 255;
				destBits[(y+locY)*mapWidth + (x+locX)] = temp;
			}
		}
	}
	success = jeBitmap_UnLock(lock);
	
}

//*******************************************************************************
JETAPI jeBoolean JETCC jeFont_AddCharacters(jeFont *font, 
																  unsigned char leastIndex, 
																  unsigned char mostIndex
																  )
{
	MAT2 mat2;
	GLYPHMETRICS glyphMetrics;
	HDC hdc;
	DWORD success;
	unsigned char asciiValue;
	int placedLetter;
	int16 mapWidth, mapHeight;
	HFONT win32Font, win32OldFont;
	jeFontBitmap *fontBitmap;
	jeBitmap_Palette *Palette;
	int i;
	unsigned char *cellBuffer;
	DWORD bufferSize;

	uint32 ggoFormat;


//	int32 *pBits;
//	int size;
//	jePixelFormat Format;

//	int32 palBuff[256];
//	jeBitmap_Info Info;
//	jeBitmap_Info SecondaryInfo;
//	jeBitmap *lock;


	mat2.eM11.fract = 0;
	mat2.eM11.value = 1;
	mat2.eM12.fract = 0;
	mat2.eM12.value = 0;
	mat2.eM21.fract = 0;
	mat2.eM21.value = 0;
	mat2.eM22.fract = 0;
	mat2.eM22.value = 1;

	// get the character bitmap
	bufferSize = 32768;
	cellBuffer = JE_RAM_ALLOCATE_ARRAY(unsigned char, bufferSize);
	memset(cellBuffer,0xee,bufferSize);

/*	asciiValue = 65; // "a" just for grins

	hdc = GetDC(GetDesktopWindow());
	assert(hdc);
	success	 = GetGlyphOutline( hdc, asciiValue, GGO_METRICS, &glyphMetrics, 0, NULL, &mat2);
	ReleaseDC(GetDesktopWindow(),hdc);
*/

	for (asciiValue = leastIndex; asciiValue <= mostIndex; asciiValue++)
	{
		placedLetter = FALSE;

		if (font->antialiased)
			ggoFormat = GGO_GRAY8_BITMAP;
		else
			ggoFormat = GGO_BITMAP;								

		// find out the dimensions of the character
		win32Font = CreateFont( -1 * font->fontSize,
	 						 0,0,0, font->fontWeight,
	 						 0,0,0,0,OUT_TT_ONLY_PRECIS ,0,0,0, font->fontNameString);

//		font = CreateFont( font->fontSize,
//	 							 0,0,0, font->fontWeight,
//	 							 0,0,0,0,0,0,0,0, font->fontNameString);

		hdc = GetDC(GetDesktopWindow());
		assert(hdc);

		win32OldFont = SelectObject( hdc, win32Font); 
		success	 = GetGlyphOutline( hdc, asciiValue, ggoFormat, 
											&glyphMetrics, bufferSize, cellBuffer, &mat2);
//		success	 = GetGlyphOutline( hdc, asciiValue, GGO_METRICS, &glyphMetrics, 0, NULL, &mat2);
		SelectObject( hdc, win32OldFont); 

		ReleaseDC(GetDesktopWindow(),hdc);

		DeleteObject(win32Font);

		fontBitmap = font->bitmapList;
		while (fontBitmap)
		{
			// will it fit into the current bitmap?
			mapWidth  = jeBitmap_Width (fontBitmap->map);
			mapHeight = jeBitmap_Height(fontBitmap->map);

			// if there's enough vertical space...
			if ((int32)glyphMetrics.gmBlackBoxY <= (mapHeight-1) - fontBitmap->freeY)
			{
				// if there's enough horizontal space...
				if (glyphMetrics.gmCellIncX <= (mapWidth-1) - fontBitmap->freeX)
				{
					// place the letter!
					PlaceLetter(fontBitmap->freeX, fontBitmap->freeY, font,
									fontBitmap, asciiValue, cellBuffer, bufferSize); 
	/*				font->characterArray[asciiValue].bitmapUsed = fontBitmap;
					font->characterArray[asciiValue].bitmapRect.Left	= fontBitmap->freeX;
					font->characterArray[asciiValue].bitmapRect.Top	 = fontBitmap->freeY;
					font->characterArray[asciiValue].bitmapRect.Right  = fontBitmap->freeX +
																					glyphMetrics.gmCellIncX;
					font->characterArray[asciiValue].bitmapRect.Bottom = fontBitmap->freeY +
																					glyphMetrics.gmBlackBoxY;
																					*/
					placedLetter = TRUE;
					fontBitmap->freeX = fontBitmap->freeX + glyphMetrics.gmBlackBoxX;
				}
				else
				{
					fontBitmap->freeY = fontBitmap->freeY + font->fontSize;
					fontBitmap->freeX = 0;
					// if there's enough vertical space...
					if ((int32)glyphMetrics.gmBlackBoxY <= (mapHeight-1) - fontBitmap->freeY)
					{
						// if there's enough horizontal space...
						if (glyphMetrics.gmCellIncX <= (mapWidth-1) - fontBitmap->freeX)
						{
							// place the letter!
							PlaceLetter(fontBitmap->freeX, fontBitmap->freeY, font,
											fontBitmap, asciiValue, cellBuffer, bufferSize);
							/*
							font->characterArray[asciiValue].bitmapUsed = fontBitmap;
							font->characterArray[asciiValue].bitmapRect.Left	= fontBitmap->freeX;
							font->characterArray[asciiValue].bitmapRect.Top	 = fontBitmap->freeY;
							font->characterArray[asciiValue].bitmapRect.Right  = fontBitmap->freeX +
																							glyphMetrics.gmCellIncX;
							font->characterArray[asciiValue].bitmapRect.Bottom = fontBitmap->freeY +
																							glyphMetrics.gmBlackBoxY;
																							*/
							placedLetter = TRUE;
							fontBitmap->freeX = fontBitmap->freeX + glyphMetrics.gmBlackBoxX;
						}
					}
				}
			}
			fontBitmap = fontBitmap->next;
		}

		if (!placedLetter)
		{
			// gotta create a new font bitmap.
			fontBitmap = JE_RAM_ALLOCATE_STRUCT(jeFontBitmap);
			assert(fontBitmap);
			fontBitmap->next = font->bitmapList;
			font->bitmapList = fontBitmap;
			fontBitmap->freeX = 0;
			fontBitmap->freeY = 0;
			fontBitmap->map = jeBitmap_Create(256,256, 1, JE_PIXELFORMAT_8BIT); 

			// and a pallette for it.
			Palette = jeBitmap_Palette_Create(JE_PIXELFORMAT_32BIT_XRGB, 256);

			for (i = 0; i < 256; i++)
			{
				success = jeBitmap_Palette_SetEntryColor(Palette, i, i, i, i, 255);
				assert(success);

			}

			success = jeBitmap_SetPalette(fontBitmap->map, Palette);
			assert(success);

		success = jeBitmap_SetColorKey(fontBitmap->map, TRUE, 0 ,FALSE );


/*
			success = jeBitmap_LockForWrite(	fontBitmap->map, &lock,
														0,0);
			success = jeBitmap_GetInfo(lock, &Info, &SecondaryInfo);

			success = jeBitmap_UnLock(lock);

			success = jeBitmap_Palette_Lock(Palette, &pBits, &Format,&size);

			success = jeBitmap_Palette_GetData(Palette, palBuff, JE_PIXELFORMAT_8BIT, 256);

			success = jeBitmap_Palette_UnLock(Palette);
*/

			success = jeBitmap_Palette_Destroy(&Palette);			
			assert(success);


			success = jeEngine_AddBitmap((jeEngine *)font->Engine, fontBitmap->map, FONT_BITMAP_TYPE);
			assert(success);

			PlaceLetter(fontBitmap->freeX, fontBitmap->freeY,  font,
							fontBitmap, asciiValue, cellBuffer, bufferSize);
			fontBitmap->freeX = fontBitmap->freeX + glyphMetrics.gmBlackBoxX;

	  
		}

	}

	jeRam_Free(cellBuffer);

	return TRUE;
}

//*******************************************************************************
JETAPI jeBoolean JETCC jeFont_DrawText(jeFont *font, const char *textString, 
														 const JE_Rect *Rect, const JE_RGBA *Color, 
														 uint32 flags, const JE_Rect *clipRect)
{

	int32 x,y,i;
	int32 tempX;//, tempY;
	int32 lineLen;

	uint32 colorArray[256];
	float  fcolorX, fcolorR, fcolorG, fcolorB;
//	int32  colorX, colorR, colorG, colorB;

	int32 stringLen;
	int32 currentCharIndex;
	int32 lineEndIndex;
	jeFontCharacterRecord *charRec;
//	jeRect Source;

	jeBoolean success;
	jeBoolean longEnough, endOfText;

	JE_Rect artRect;
	RECT box;
	int32 resultX, resultY;

	jeFontBitmap *lastBitmap;
	jeBitmap_Palette * palette;
//	jeBitmap *targetBitmap;

	// unimplemented flags which we don't want you to use yet.
	assert(!(flags & JE_FONT_WRAP			  ));
	assert(!(flags & JE_FONT_JUST_RETURN_FIT));
	assert(!(flags & JE_FONT_JUSTIFY_RIGHT  ));
	assert(!(flags & JE_FONT_JUSTIFY_CENTER ));

	lastBitmap = NULL;
	x = 0;
	y = 0;
	stringLen = strlen(textString);
	currentCharIndex = 0;

	if (font->bitmapList)  // if this font has character bitmaps...
	{

		while (currentCharIndex < stringLen)
		{
			// skip leading white space for this line.
			while (isspace(textString[currentCharIndex]) && currentCharIndex < stringLen)
				currentCharIndex++;

			// if, because of the whitespace skip, we're out of text, exit the loop.
			if (currentCharIndex >= stringLen)
				break;

			lineLen = 0;
			lineEndIndex = currentCharIndex;
			longEnough = FALSE;
			endOfText = FALSE;
			while (!longEnough)
			{
				charRec = &(font->characterArray[textString[lineEndIndex]]);

				// if the character has art...
				if (charRec->bitmapUsed)
				{

					if (Rect->Left + lineLen + (charRec->fullWidth) >
						 Rect->Right)
						 longEnough = TRUE;
					else
					{
						lineLen = lineLen + (charRec->fullWidth);
						lineEndIndex++;
						if (lineEndIndex >= stringLen)
						{
							longEnough = TRUE;
							endOfText = TRUE;
						}
					}
				}
				else
				{
					lineEndIndex++;
					if (lineEndIndex >= stringLen)
					{
						longEnough = TRUE;
						endOfText = TRUE;
					}
				}
	//	jeFontBitmap *bitmapUsed;  // NULL == not initialized yet.
	//	JE_Rect bitmapRect;


			}

			// if we're word-wrapping, back up to BEFORE the last hunk of whitespace.
			if (flags & JE_FONT_WORDWRAP && !endOfText)
			{
				tempX = lineEndIndex;
				while (tempX > currentCharIndex && !isspace(textString[tempX]))
					tempX--;

				if (isspace(textString[tempX]))
				{
					while (tempX > currentCharIndex && isspace(textString[tempX]))
						tempX--;

					lineEndIndex = tempX;
				}
			}

			// aaannnddd,  DRAW!
			for (; currentCharIndex <= lineEndIndex && currentCharIndex < stringLen; currentCharIndex++)
			{
				charRec = &(font->characterArray[textString[currentCharIndex]]);

	//	JE_Rect bitmapRect;
	//	int16 offsetX, offsetY, fullWidth;

				if (charRec->bitmapUsed)
				{

					if (charRec->bitmapUsed != lastBitmap)
					{

						lastBitmap = charRec->bitmapUsed;

						palette = jeBitmap_GetPalette(lastBitmap->map);
						assert(palette);

						for (i = 0; i < 256; i++)
						{

							fcolorR = Color->r * i / 255;
							fcolorG = Color->g * i / 255;
							fcolorB = Color->b * i / 255;
							fcolorX = Color->a * i / 255;

							colorArray[i] = jePixelFormat_ComposePixel(	JE_PIXELFORMAT_32BIT_XRGB, (int)fcolorR, (int)fcolorG, (int)fcolorB, (int)fcolorX);
						}

						success = jeBitmap_Palette_SetData(	palette ,colorArray,JE_PIXELFORMAT_32BIT_XRGB, 256);
			  
						success = jeBitmap_SetPalette(lastBitmap->map, palette);
						assert(success);

					}
				
				
					if (clipRect)
					{
						artRect = charRec->bitmapRect;

						if ( CalculateClipping( &artRect, &resultX, &resultY, 
										Rect->Left + x + charRec->offsetX, 
										Rect->Top + y + (font->fontSize - charRec->offsetY),
										*clipRect, JE_CLIP_CORNER)
							)
						{
							success = FONT_DRAWBITMAP(font->Engine, charRec->bitmapUsed->map,
		  								&artRect, resultX, resultY);
						}

					}
					else
					{
					  success = FONT_DRAWBITMAP(font->Engine, charRec->bitmapUsed->map,
 										&(charRec->bitmapRect), Rect->Left + x + charRec->offsetX, 
										Rect->Top + y + (font->fontSize - charRec->offsetY));
					}
					x += charRec->fullWidth;
				}
				else
				{
					// we reached this point because we're trying to draw a character that
					// hasn't been added to the font yet using jeFont_AddCharacters().
					assert(0);
				}
			
			}
			y += font->fontSize;
			x = 0;
		}
	}
	else // this font has no attached bitmaps, sooo, we do it another way!
	{

		// at this point, we're trying to put text to the screen using DrawText() and
		// a DIB.  This process REQUIRES an initialized jeBitmap as a go-between.
		// Is it initialized?
		assert(font->buffer);

		box.left	= 0;
		box.right  = Rect->Right - Rect->Left;
		box.top	 = 0;
		box.bottom = Rect->Bottom - Rect->Top;

		// does the buffer have sufficient dimensions?
		assert (box.right  <= jeBitmap_Width (font->buffer)); 
		assert (box.bottom <= jeBitmap_Height(font->buffer)); 

//		success = jeFont_DrawUsingDIB(font, textString, box, font->buffer, Color, flags);

		artRect.Left	= box.left;
		artRect.Right  = box.right;
		artRect.Top	 = box.top;
		artRect.Bottom = box.bottom;

//		success = jeFont_DrawUsingDIB(font, textString, box, font->buffer, Color, flags);

		success = jeFont_DrawTextToBitmap(font, textString, &artRect, Color,
														flags, NULL, font->buffer);

		if (clipRect)
		{
			if ( CalculateClipping( &artRect, &resultX, &resultY, 
							Rect->Left, 
							Rect->Top,
							*clipRect, JE_CLIP_CORNER)
				)
			{
				success = FONT_DRAWBITMAP(font->Engine, font->buffer,
		  					&artRect, resultX, resultY);
			}
		}
		else
		{
			success = FONT_DRAWBITMAP(font->Engine, font->buffer,
 							&artRect, Rect->Left, Rect->Top);
		}
	}

	return lineEndIndex;
}


//*******************************************************************************
JETAPI void JETCC jeFont_DestroyBitmapBuffer( jeFont *font ) 
{
	jeBoolean success;
	assert(font);
	if (font->buffer)
	{
		success = jeEngine_RemoveBitmap((jeEngine *)font->Engine, font->buffer);
		assert(success);

		jeBitmap_Destroy(&font->buffer);
	}

}

//*******************************************************************************
JETAPI jeBoolean JETCC jeFont_AddBitmapBuffer(
											 jeFont *font, const uint32 width, const uint32 height) 
{
	jeBoolean success;
	jeBitmap_Palette * palette;
	int i;

	assert(font);

	assert(width  < 1000);  // just checking for absurd values that indicate 
	assert(height < 1000);  // an un-initialized state.

	if (font->buffer)
		jeFont_DestroyBitmapBuffer( font );

	font->buffer = jeBitmap_Create(width, height, 1, JE_PIXELFORMAT_8BIT); 
	assert(font->buffer);

	// and a pallette for it.
	palette = jeBitmap_Palette_Create(JE_PIXELFORMAT_32BIT_XRGB, 256);
	assert(palette);

	for (i = 0; i < 256; i++)
	{
		success = jeBitmap_Palette_SetEntryColor(palette, i, i, i, i, 255);
		assert(success);

	}

	success = jeBitmap_SetPalette(font->buffer, palette);
	assert(success);

	// bitmap refcounts it, so get rid of our copy.
	jeBitmap_Palette_Destroy (&palette);

	success = jeBitmap_SetColorKey(font->buffer, TRUE, 0 ,FALSE );


//	success = jeBitmap_Palette_Destroy(&palette);			
//	assert(success);


	success = jeEngine_AddBitmap((jeEngine *)font->Engine, font->buffer, FONT_BITMAP_TYPE);
	assert(success);

	return JE_TRUE;

}

//*******************************************************************************
JETAPI jeBoolean JETCC jeFont_DrawTextToBitmap(jeFont *font, const char *textString, 
														 const JE_Rect *Rect, const JE_RGBA *Color, 
														 uint32 flags, const JE_Rect *clipRect,
														 jeBitmap *targetBitmap)
{

	int32 x,y,i;
	int32 tempX;//, tempY;
	int32 lineLen;

	uint32 colorArray[256];
	float  fcolorX, fcolorR, fcolorG, fcolorB;
//	int32  colorX, colorR, colorG, colorB;

	int32 stringLen;
	int32 currentCharIndex;
	int32 lineEndIndex;
	jeFontCharacterRecord *charRec;
//	jeRect Source;

	jeBoolean success;
	jeBoolean longEnough, endOfText;

	JE_Rect artRect;
	RECT box;
	int32 resultX, resultY;

	jeFontBitmap *lastBitmap;
	jeBitmap_Palette * palette;


	// unimplemented flags which we don't want you to use yet.
	assert(!(flags & JE_FONT_WRAP			  ));
	assert(!(flags & JE_FONT_JUST_RETURN_FIT));
	assert(!(flags & JE_FONT_JUSTIFY_RIGHT  ));
	assert(!(flags & JE_FONT_JUSTIFY_CENTER ));

	assert(targetBitmap);

	lastBitmap = NULL;
	x = 0;
	y = 0;
	stringLen = strlen(textString);
	currentCharIndex = 0;

	if (font->bitmapList)  // if this font has character bitmaps...
	{

		while (currentCharIndex < stringLen)
		{
			// skip leading white space for this line.
			while (isspace(textString[currentCharIndex]) && currentCharIndex < stringLen)
				currentCharIndex++;

			// if, because of the whitespace skip, we're out of text, exit the loop.
			if (currentCharIndex >= stringLen)
				break;

			lineLen = 0;
			lineEndIndex = currentCharIndex;
			longEnough = FALSE;
			endOfText = FALSE;
			while (!longEnough)
			{
				charRec = &(font->characterArray[textString[lineEndIndex]]);

				// if the character has art...
				if (charRec->bitmapUsed)
				{

					if (Rect->Left + lineLen + (charRec->fullWidth) >
						 Rect->Right)
						 longEnough = TRUE;
					else
					{
						lineLen = lineLen + (charRec->fullWidth);
						lineEndIndex++;
						if (lineEndIndex >= stringLen)
						{
							longEnough = TRUE;
							endOfText = TRUE;
						}
					}
				}
				else
				{
					lineEndIndex++;
					if (lineEndIndex >= stringLen)
					{
						longEnough = TRUE;
						endOfText = TRUE;
					}
				}
	//	jeFontBitmap *bitmapUsed;  // NULL == not initialized yet.
	//	JE_Rect bitmapRect;


			}

			// if we're word-wrapping, back up to BEFORE the last hunk of whitespace.
			if (flags & JE_FONT_WORDWRAP && !endOfText)
			{
				tempX = lineEndIndex;
				while (tempX > currentCharIndex && !isspace(textString[tempX]))
					tempX--;

				if (isspace(textString[tempX]))
				{
					while (tempX > currentCharIndex && isspace(textString[tempX]))
						tempX--;

					lineEndIndex = tempX;
				}
			}

			// aaannnddd,  DRAW!
			for (; currentCharIndex <= lineEndIndex && currentCharIndex < stringLen; currentCharIndex++)
			{
				charRec = &(font->characterArray[textString[currentCharIndex]]);

	//	JE_Rect bitmapRect;
	//	int16 offsetX, offsetY, fullWidth;

				if (charRec->bitmapUsed)
				{

					if (charRec->bitmapUsed != lastBitmap)
					{

						lastBitmap = charRec->bitmapUsed;

						palette = jeBitmap_GetPalette(lastBitmap->map);
						assert(palette);

						for (i = 0; i < 256; i++)
						{

							fcolorR = Color->r * i / 255;
							fcolorG = Color->g * i / 255;
							fcolorB = Color->b * i / 255;
							fcolorX = Color->a * i / 255;

							colorArray[i] = jePixelFormat_ComposePixel(	JE_PIXELFORMAT_32BIT_XRGB, (int)fcolorR, (int)fcolorG, (int)fcolorB, (int)fcolorX);
						}

						success = jeBitmap_Palette_SetData(	palette ,colorArray,JE_PIXELFORMAT_32BIT_XRGB, 256);
			  
						success = jeBitmap_SetPalette(lastBitmap->map, palette);
						assert(success);

					}
				
				
					if (clipRect)
					{
						artRect = charRec->bitmapRect;

						if ( CalculateClipping( &artRect, &resultX, &resultY, 
										Rect->Left + x + charRec->offsetX, 
										Rect->Top + y + (font->fontSize - charRec->offsetY),
										*clipRect, JE_CLIP_CORNER)
							)
						{
							success = jeBitmap_Blit(charRec->bitmapUsed->map, artRect.Left, artRect.Top,
											targetBitmap, resultX, resultY,
											artRect.Right - artRect.Left, artRect.Bottom - artRect.Top );
						}

					}
					else
					{
						success = jeBitmap_Blit(charRec->bitmapUsed->map, charRec->bitmapRect.Left, 
										charRec->bitmapRect.Top, targetBitmap, 
										Rect->Left + x + charRec->offsetX, Rect->Top + y + (font->fontSize - charRec->offsetY),
										charRec->bitmapRect.Right  - charRec->bitmapRect.Left, 
										charRec->bitmapRect.Bottom - charRec->bitmapRect.Top );
					}
					x += charRec->fullWidth;
				}
				else
				{
					// we reached this point because we're trying to draw a character that
					// hasn't been added to the font yet using jeFont_AddCharacters().
					assert(0);
				}
			
			}
			y += font->fontSize;
			x = 0;
		}
	}
	else // this font has no attached bitmaps, sooo, we do it another way!
	{
		box.left	= Rect->Left;
		box.right  = Rect->Right;
		box.top	 = Rect->Top;
		box.bottom = Rect->Bottom;
		success = jeFont_DrawUsingDIB(font, textString, box, targetBitmap, Color, flags);


		// change the colors in the palette of targetBitmap;
		//  WOOPS!  Can't do that within a BeginFrame() - EndFrame() pair!
		/*
		palette = jeBitmap_GetPalette(targetBitmap);
		assert(palette);

		for (i = 0; i < 256; i++)
		{
			fcolorR = Color->r * i / 255;
			fcolorG = Color->g * i / 255;
			fcolorB = Color->b * i / 255;
			fcolorX = Color->a * i / 255;

			success = jeBitmap_Palette_SetEntryColor(palette, i, (int)fcolorR, (int)fcolorG, (int)fcolorB, (int)fcolorX);
			assert(success);

		}

		success = jeBitmap_SetPalette(targetBitmap, palette);
		assert(success);
		*/
/*
		for (i = 0; i < 256; i++)
		{

			fcolorR = Color->r * i / 255;
			fcolorG = Color->g * i / 255;
			fcolorB = Color->b * i / 255;
			fcolorX = Color->a * i / 255;

			colorArray[i] = jePixelFormat_ComposePixel(	JE_PIXELFORMAT_32BIT_XRGB, (int)fcolorR, (int)fcolorG, (int)fcolorB, (int)fcolorX);
		}

		success = jeBitmap_Palette_SetData(	palette ,colorArray,JE_PIXELFORMAT_32BIT_XRGB, 256);

		success = jeBitmap_SetPalette(targetBitmap, palette);
		assert(success);
*/
	}

	return lineEndIndex;
}


//*******************************************************************************
JETAPI jeBoolean JETCC jeFont_TestDraw(jeFont *font, int16 x, int16 y, int16 index)
{
	jeRect Source;
	jeFontBitmap *fontBitmap;
	jeBoolean success;

	fontBitmap = font->bitmapList;
	for (; index > 0 && fontBitmap->next; index--)
		fontBitmap = fontBitmap->next;

	assert(fontBitmap);

	Source.Top	 = 0;
	Source.Left	= 0;
	Source.Right  = 255;
	Source.Bottom = 255;

	success = FONT_DRAWBITMAP(font->Engine, fontBitmap->map,
 								&Source, x, y);

	return success;
}




//*******************************************************************************
JETAPI jeBoolean JETCC jeFont_DrawUsingDIB(jeFont *font, const char *textString, 
																	RECT box, jeBitmap *targetBitmap,
																	const JE_RGBA *Color, uint32 flags)
{
	jeBoolean success;

	HDC		hdc, drawDC;

	float  fcolorR, fcolorG, fcolorB;

	int32			 x,y;

	uint8			 *lpDIBBuffer;				  // DIB image buffer
	HBITMAP	  hDIB, oldMap;							// Handle returned from CreateDIBSection
	HPALETTE	 hPalette;					  // Handle to palette if 8-bit mode in use
	HFONT oldFont, winFont;
	LOGPALETTE		 *pLogPal;				// LOGPALETTE structure
	BITMAPINFO		 *pbmi;					// BITMAPINFO structure
	BITMAPINFOHEADER *pbmih;				  // Pointer to pbmi header

	jeBitmap *lock;
	jeBitmap_Info Info;
	jeBitmap_Info SecondaryInfo;

	unsigned char *destBits;
	int16 mapWidth;


	int i;

	int desktop_bpp, display_bpp;

	int targetSizeX, targetSizeY;

	//
	// Init DIB stuff
	//

	desktop_bpp = 8;
	display_bpp = 8;

	targetSizeX = jeBitmap_Width (targetBitmap) + ( 4 - ( jeBitmap_Width (targetBitmap) % 4 ) );
	targetSizeY = jeBitmap_Height(targetBitmap);

	hDIB		  = NULL;
	lpDIBBuffer = NULL;
	hPalette	 = NULL;

	pLogPal = (LOGPALETTE *) 
				 JE_RAM_ALLOCATE_ARRAY (char, sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256));

	assert(pLogPal);

	memset(pLogPal,0, sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256));

	pLogPal->palVersion	 = 0x300;
	pLogPal->palNumEntries = 256;

	pbmi = (BITMAPINFO *) 
			 JE_RAM_ALLOCATE_ARRAY(char,sizeof (BITMAPINFOHEADER) + (sizeof (RGBQUAD) * 256));

	if (pbmi == NULL)
	{
		jeRam_Free(pLogPal);
		assert(0);
	}
 
	memset(pbmi, 0, sizeof (BITMAPINFOHEADER) + (sizeof (RGBQUAD) * 256));

	pbmih = &(pbmi->bmiHeader);

	pbmih->biSize			 =  sizeof(BITMAPINFOHEADER);
	pbmih->biWidth			=  (targetSizeX);
	pbmih->biHeight		  = -(targetSizeY);
	pbmih->biPlanes		  =  1;
	pbmih->biBitCount		=  (uint16) 8;
	pbmih->biSizeImage	  =  0;
	pbmih->biXPelsPerMeter =  0;
	pbmih->biYPelsPerMeter =  0;
	pbmih->biClrUsed		 =  0;
	pbmih->biClrImportant  =  0;
  
	pbmih->biCompression = BI_RGB;


	// set palette entries
	for (i = 0; i < 256; i++)
	{
//		pLogPal->palPalEntry[i].peRed	= (unsigned char) i;
//		pLogPal->palPalEntry[i].peGreen = (unsigned char) i;
//		pLogPal->palPalEntry[i].peBlue  = (unsigned char) i;
//		pLogPal->palPalEntry[i].peFlags = NULL;
		fcolorR = Color->r * i / 255;
		fcolorG = Color->g * i / 255;
		fcolorB = Color->b * i / 255;
//		fcolorX = Color->a * i / 255;

//		colorArray[i] = jePixelFormat_ComposePixel(	JE_PIXELFORMAT_32BIT_XRGB, (int)fcolorR, (int)fcolorG, (int)fcolorB, (int)fcolorX);

		pbmi->bmiColors[i].rgbRed	= (unsigned char) fcolorR;
		pbmi->bmiColors[i].rgbGreen = (unsigned char) fcolorG;
		pbmi->bmiColors[i].rgbBlue  = (unsigned char) fcolorB;
	
	}

	hPalette = CreatePalette(pLogPal);
//	palette_change_request = TRUE;

	//
	// Allocate the DIB section ("back buffer")
	//

	hdc = GetDC(GetDesktopWindow());

	hDIB = CreateDIBSection(hdc,				 // Device context
									pbmi,				// BITMAPINFO structure
									DIB_RGB_COLORS,  // Color data type
					 (void **) &lpDIBBuffer,	  // Address of image map pointer
									NULL,				// File
									0);				  // Bitmap file offset

	ReleaseDC(GetDesktopWindow(), hdc);
	
	assert(hDIB);

	// now we DrawText to the DIB

	drawDC = CreateCompatibleDC(NULL);

	winFont = CreateFont( -1 * font->fontSize,
	 						 0,0,0, font->fontWeight,
	 						 0,0,0,0,OUT_TT_ONLY_PRECIS ,0,0,0, font->fontNameString);
	assert(winFont);

	oldFont = SelectObject( drawDC, winFont); 
	oldMap  = SelectObject( drawDC, hDIB); 

	SetTextColor(drawDC, RGB(Color->r,Color->g,Color->b));
	SetBkColor  (drawDC, RGB(0,0,0));

 	SetBkMode( drawDC, OPAQUE );

	// we are accounting for the fact that Windows GDI stuff doesn't seem to draw on the end of a rect
	box.bottom++;
	box.right++;

	if (flags & JE_FONT_WORDWRAP)
		DrawText(drawDC, textString, strlen(textString), &box, DT_WORDBREAK);
	else
		DrawText(drawDC, textString, strlen(textString), &box, 0);

	// undoing the for-windows hack
	box.bottom--;
	box.right--;

	SelectObject(drawDC,oldMap);
	SelectObject(drawDC,oldFont);

	DeleteDC(drawDC);

	DeleteObject(winFont);

	// 4-9-99 : CB re-wrote this blitter
	// this is a blit from 8bit pal CK -> anything
	// 

	success = jeBitmap_GetInfo(targetBitmap, &Info, &SecondaryInfo);
	assert(success);

	if ( Info.Format == JE_PIXELFORMAT_8BIT || jePixelFormat_IsRaw(Info.Format) )
	{
		// now we copy the bits in the DIB to the targetBitmap
		success = jeBitmap_LockForWriteFormat(	targetBitmap, &lock,
										0,0, Info.Format);
	}
	else
	{
		if ( SecondaryInfo.Format == JE_PIXELFORMAT_8BIT ||
				jePixelFormat_IsRaw(SecondaryInfo.Format) )
		{
			success = jeBitmap_LockForWriteFormat(	targetBitmap, &lock,0,0, SecondaryInfo.Format);
			assert(success);
			Info = SecondaryInfo;
		}
		else
		{
			success = jeBitmap_SetFormat(targetBitmap, JE_PIXELFORMAT_16BIT_1555_ARGB, JE_TRUE, 0, NULL);
			assert(success);
			success = jeBitmap_SetColorKey(targetBitmap, JE_TRUE, 0, JE_FALSE);
			assert(success);
			success = jeBitmap_LockForWrite(targetBitmap, &lock,0,0);
			assert(success);
			success = jeBitmap_GetInfo(lock, &Info, NULL);
			assert(success);
		}
	}

	mapWidth  = Info.Stride;

	destBits = jeBitmap_GetBits(lock);

	if (JE_PIXELFORMAT_8BIT == Info.Format)
	{
	uint8 * psrc,*pdst;
	int w;

		w = box.right - box.left;

		destBits += box.left;
		lpDIBBuffer += box.left;

		if ( ! Info.HasColorKey || Info.ColorKey == 0 )
		{
		#ifdef _DEBUG
		if ( ! Info.HasColorKey )
		{
		int r,g,b,a;
			jeBitmap_Palette_GetEntryColor(Info.Palette,0,&r,&g,&b,&a);
		}
		#endif

			for ( y = box.top; y <= box.bottom;  y++)
			{
				psrc = lpDIBBuffer + y * targetSizeX;
				pdst = destBits + y*mapWidth;
				memcpy(pdst,psrc,w);
			}
		}
		else
		{
		int p,ck;
			ck = Info.ColorKey;
			for ( y = box.top; y <= box.bottom;  y++)
			{
				psrc = lpDIBBuffer + y * targetSizeX;
				pdst = destBits + y*mapWidth;
				for(x=w;x--;)
				{
					p = *psrc++;
					if ( p == 0 )
					{
						p = ck;
					}
					else if ( p == ck )
					{
						p ^= 1;
					}
					*pdst++ = p;
				}
			}
		}
	}
  	else
	{
	uint8 * psrc,*pdst;
	int w,bpp,p;
	uint32 Pixels[256];
	jePixelFormat_PixelPutter pfPutPixel;
	const jePixelFormat_Operations *ops;

		ops = jePixelFormat_GetOperations(Info.Format);
		pfPutPixel = ops->PutPixel;

		w = box.right - box.left;

		bpp = jePixelFormat_BytesPerPel(Info.Format);
		mapWidth *= bpp;

		destBits += box.left * bpp;
		lpDIBBuffer += box.left;

		for(p=0;p<256;p++)
		{
		int r,g,b,a;
			if ( p == 0 )
			{
				if ( Info.HasColorKey )
					Pixels[0] = Info.ColorKey;
				else
					Pixels[0] = jePixelFormat_ComposePixel(Info.Format,0,0,0,0);
			}
			else
			{
				r = pbmi->bmiColors[p].rgbRed;
				g = pbmi->bmiColors[p].rgbGreen;
				b = pbmi->bmiColors[p].rgbBlue;
				a = 255;
				Pixels[p] = jePixelFormat_ComposePixel(Info.Format,r,g,b,a);
			}
		}

		for ( y = box.top; y <= box.bottom;  y++)
		{
			psrc = lpDIBBuffer + y * targetSizeX;
			pdst = destBits + y*mapWidth;
			for( x = w; x--; )
			{
				p = *psrc ++;
				pfPutPixel(&pdst,Pixels[p]);
			}
		}
	}


	success = jeBitmap_UnLock(lock);


	// finally, clean up!
	DeleteObject(hDIB);
	DeleteObject(hPalette);


	jeRam_Free(pbmi);
	jeRam_Free(pLogPal);

	return TRUE;
}


//*******************************************************************************
JETAPI int32 JETCC jeFont_GetStringPixelWidth (jeFont *font, const char *textString)
{

	if (font->bitmapList)
	{
		int32 i, width;

		width = 0;
		for (i = 0; i < (int32)strlen(textString); i++)
		{
			assert (font->characterArray[textString[i]].bitmapUsed);

			width += font->characterArray[textString[i]].fullWidth;
		}

		return width;
	}
	else
	{
		SIZE sizeInfo;
		HDC hdc;
		HFONT oldFont, winFont;

		hdc = GetDC(GetDesktopWindow());
		winFont = CreateFont( -1 * font->fontSize,
	 						 0,0,0, font->fontWeight,
	 						 0,0,0,0,OUT_TT_ONLY_PRECIS ,0,0,0, font->fontNameString);
		assert(winFont);

		oldFont = SelectObject( hdc, winFont); 

		GetTextExtentPoint32(  hdc, textString, strlen(textString), &sizeInfo);

		SelectObject(hdc,oldFont);
		DeleteObject(winFont);

		ReleaseDC(GetDesktopWindow(), hdc);

		return sizeInfo.cx;
	}
}

//*******************************************************************************
JETAPI int32 JETCC jeFont_GetStringPixelHeight(jeFont *font, const char *textString)
{

		SIZE sizeInfo;
		HDC hdc;
		HFONT oldFont, winFont;

		hdc = GetDC(GetDesktopWindow());
		winFont = CreateFont( -1 * font->fontSize,
	 						 0,0,0, font->fontWeight,
	 						 0,0,0,0,OUT_TT_ONLY_PRECIS ,0,0,0, font->fontNameString);
		assert(winFont);

		oldFont = SelectObject( hdc, winFont); 

		GetTextExtentPoint32(  hdc, textString, strlen(textString), &sizeInfo);

		SelectObject(hdc,oldFont);
		DeleteObject(winFont);

		ReleaseDC(GetDesktopWindow(), hdc);

		return sizeInfo.cy;


//	return font->fontSize;
}

//*******************************************************************************
JETAPI jeBitmap* JETCC jeFont_GetBuffer(jeFont *font)
{

	return font->buffer;
}


//*******************************************************************************
JETAPI jeBoolean JETCC jeFont_GetCharMap(jeFont *font, uint8 character, JE_Rect *Rect, 
												 jeBitmap **targetBitmap, int32 *fullWidth, int32 *fullHeight, 
												 int32 *offsetX, int32 *offsetY)
{


	assert(font);
	assert(font->characterArray[character].bitmapUsed);

	*targetBitmap = font->characterArray[character].bitmapUsed->map;

	*Rect = font->characterArray[character].bitmapRect;

//		int32 offsetX, offsetY, fullWidth;
	*fullWidth = font->characterArray[character].fullWidth;
	*fullHeight = font->fontSize;
	*offsetX = font->characterArray[character].offsetX;
	*offsetY = font->characterArray[character].offsetY;

	return JE_TRUE;
}


//*******************************************************************************
JETAPI void JETCC jeFont_EnableAntialiasing(jeFont *font, const jeBoolean anti)
{
	font->antialiased = anti;
}

//*******************************************************************************
JETAPI jeBoolean JETCC jeFont_IsAntialiased(jeFont *font)
{
	return font->antialiased;
}

/* end of file */
