
#include <OSIncludes.h>

#pragma header

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

#include "freetype.h"

#define FLOOR(x) ((x) & -64)
#define CEILING(x) (((x) + 63) & -64)

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Window *window;
struct BitMap *bitmap;

TT_Raster_Map rastermap;
TT_Engine engine;
TT_Face face;
TT_Instance instance;
TT_Glyph glyph;
TT_CharMap char_map;
TT_Glyph_Metrics metrics;
TT_Outline outline;
TT_Face_Properties properties;
TT_Instance_Metrics imetrics;

WORD xmin,xmax,ymin,ymax,width,height,width8,i;

static void Cleanup(char *msg)
{
	if (msg)
	{
		printf("Error: %s\n",msg);
	}
	
	TT_Done_Instance(instance);
	TT_Done_Glyph(glyph);
	TT_Close_Face(face);
	TT_Done_FreeType(engine);

	if (window) CloseWindow(window);
	if (bitmap)
	{
		WaitBlit();
		FreeBitMap(bitmap);
	}

	if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
	if (GfxBase) CloseLibrary((struct Library *)GfxBase);
	
	exit(0);	
}

static void OpenLibs(void)
{
	if (!(IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",39)))
	{
		Cleanup("Can't open intuition.library V39!");
	}
	
	if (!(GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",39)))
	{
		Cleanup("Can't open graphics.library V39!");
	}
}

static void MakeWindow(void)
{
	if (!(window=OpenWindowTags(0,
		WA_Left,0,
		WA_Top,20,
		WA_Width,600,
		WA_Height,300,
		WA_Title,"Freetype Test",
		WA_Flags,WFLG_CLOSEGADGET | WFLG_DEPTHGADGET | WFLG_DRAGBAR,
		WA_IDCMP,IDCMP_CLOSEWINDOW,
		TAG_DONE)))
	{
		Cleanup("Can't open window!");
	}
}

static void WaitForQuit(void)
{
	WaitPort(window->UserPort);
}

void main(void)
{
	OpenLibs();
	MakeWindow();
	
	if (TT_Init_FreeType(&engine) != 0)
	{
		Cleanup("InitFreeType failed!");
	}
	
	if (TT_Open_Face(engine,"fonts:_truetype/arial.ttf",&face) != 0)
	{
		Cleanup("Open_Face failed!");
	}
	
	TT_Get_Face_Properties(face,&properties);
	
	printf("numGlyphs: %ld\n",properties.num_Glyphs);
	printf("maxPoints: %ld\n",properties.max_Points);
	printf("maxContours: %ld\n",properties.max_Contours);
	printf("numCharMaps: %ld\n",properties.num_CharMaps);
	printf("numNames: %ld\n",properties.num_Names);
	printf("numFaces: %ld\n",properties.num_Faces);

	
	if (TT_New_Instance(face,&instance) != 0)
	{
		Cleanup("NewInstance failed!");
	}

//	if (TT_Set_Instance_Resolutions(instance,72,72) != 0)
//	{
//		Cleanup("SetInstanceResolutions failed!");
//	}


	if (TT_Set_Instance_CharSize(instance,100*64) != 0)
	{
		Cleanup("SetInstanceCharSize failed!");
	}

	if (TT_New_Glyph(face,&glyph) != 0)
	{
		Cleanup("NewGlyph failed!");
	}
		
	SetWriteMask(window->RPort,1);

for (i=0;i<properties.num_Glyphs;i++)
{


	if (TT_Load_Glyph(instance,glyph,i,TTLOAD_DEFAULT) != 0)
	{
		Cleanup("LoadGlyph failed!");
	}
	
	TT_Get_Glyph_Metrics(glyph,&metrics);
	
	xmin=FLOOR(metrics.bbox.xMin);
	ymin=FLOOR(metrics.bbox.yMin);
	xmax=CEILING(metrics.bbox.xMax);
	ymax=CEILING(metrics.bbox.yMax);
	
		width=(xmax-xmin)/64;
		width8=(width+15) & -16;
		height=(ymax-ymin)/64;

	printf("Pixel size: %d x %d\n",width,height);

	if (width && height)
	{
		
		
		if (!(bitmap=AllocBitMap(width8,height,1,BMF_STANDARD|BMF_CLEAR,0)))
		{
			Cleanup("Can't alloc bitmap!");
		}
		
		rastermap.rows=height;
		rastermap.cols=width8/8;
		rastermap.width=width;
		rastermap.flow=TT_Flow_Down;
		rastermap.bitmap=bitmap->Planes[0];
		
		if (TT_Get_Glyph_Bitmap(glyph,&rastermap,-xmin,-ymin) != 0)
		{
			Cleanup("GetGlyphBitmap failed!");
		}
		
		SetAPen(window->RPort,0);
		RectFill(window->RPort,
					window->BorderLeft,
					window->BorderRight,
					window->Width-window->BorderRight,
					window->Height-window->BorderBottom);
		
		BltBitMapRastPort(bitmap,0,0,window->RPort,20,20,width,height,192);
	
//		Delay(25);
		WaitBlit();
		FreeBitMap(bitmap);bitmap=0;
	}
//	TT_Done_Glyph(glyph);glyph.z=0;

	if (CheckSignal(SIGBREAKF_CTRL_C)) break;
}

	WaitForQuit();	

	Cleanup(0);
}

