/* $Revision Header * Header built automatically - do not edit! *************
 *
 *	(C) Copyright 1990 by Olaf 'Olsen' Barthel & MXM
 *
 *	Name .....: Scale.c
 *	Created ..: Monday 21-Jan-91 20:12
 *	Revision .: 0
 *
 *	Date            Author          Comment
 *	=========       ========        ====================
 *	21-Jan-91       Olsen           Created this file!
 *
 * $Revision Header ********************************************************/

#include "TermGlobal.h"

	/* Some static data required by the bitmap scaling routine. */

STATIC struct RastPort		*ScaleRPort;
STATIC struct BitMap		*ScaleSrcBitMap,*ScaleDstBitMap;
STATIC struct BitScaleArgs	*ScaleArgs;

STATIC struct TextFont		*ScaleFontType = NULL;

	/* DeleteScale():
	 *
	 *	Frees all the data associated with font scaling.
	 */

VOID
DeleteScale()
{
	if(ScaleArgs)
		FreeMem(ScaleArgs,sizeof(struct BitScaleArgs));

	ScaleArgs = NULL;

	if(ScaleDstBitMap)
	{
		if(ScaleDstBitMap -> Planes[0])
			FreeMem(ScaleDstBitMap -> Planes[0],2 * 16 * ScaleDstBitMap -> Depth);

		FreeMem(ScaleDstBitMap,sizeof(struct BitMap));
	}

	ScaleDstBitMap = NULL;

	if(ScaleSrcBitMap)
	{
		if(ScaleSrcBitMap -> Planes[0])
			FreeMem(ScaleSrcBitMap -> Planes[0],2 * 8 * ScaleSrcBitMap -> Depth);

		FreeMem(ScaleSrcBitMap,sizeof(struct BitMap));
	}

	ScaleSrcBitMap = NULL;

	if(ScaleRPort)
		FreeMem(ScaleRPort,sizeof(struct RastPort));

	ScaleRPort = NULL;
}

	/* CreateScale():
	 *
	 *	Sets up the data required for real-time font scaling
	 *	(bitmaps, rastports, etc.).
	 */

BYTE
CreateScale()
{
	SHORT i;

	if(ScaleRPort = (struct RastPort *)AllocMem(sizeof(struct RastPort),MEMF_PUBLIC|MEMF_CLEAR))
	{
		InitRastPort(ScaleRPort);

		if(ScaleSrcBitMap = (struct BitMap *)AllocMem(sizeof(struct BitMap),MEMF_PUBLIC|MEMF_CLEAR))
		{
			InitBitMap(ScaleSrcBitMap,Screen -> RastPort . BitMap -> Depth,16,8);

			if(ScaleDstBitMap = (struct BitMap *)AllocMem(sizeof(struct BitMap),MEMF_PUBLIC|MEMF_CLEAR))
			{
				InitBitMap(ScaleDstBitMap,Screen -> RastPort . BitMap -> Depth,16,16);

				ScaleRPort -> BitMap = ScaleSrcBitMap;

				if(ScaleSrcBitMap -> Planes[0] = (PLANEPTR)AllocMem(2 * 8 * ScaleSrcBitMap -> Depth,MEMF_CHIP|MEMF_CLEAR))
				{
					for(i = 1 ; i < ScaleSrcBitMap -> Depth ; i++)
						ScaleSrcBitMap -> Planes[i] = ScaleSrcBitMap -> Planes[0] + i * 2 * 8;

					if(ScaleDstBitMap -> Planes[0] = (PLANEPTR)AllocMem(2 * 16 * ScaleDstBitMap -> Depth,MEMF_CHIP|MEMF_CLEAR))
					{
						for(i = 1 ; i < ScaleDstBitMap -> Depth ; i++)
							ScaleDstBitMap -> Planes[i] = ScaleDstBitMap -> Planes[0] + i * 2 * 16;

						SetFont(ScaleRPort,CurrentFont);

						ScaleFontType = CurrentFont;

						SetDrMd(ScaleRPort,JAM2);
						SetAPen(ScaleRPort,1);
						SetBPen(ScaleRPort,0);

						if(ScaleArgs = (struct BitScaleArgs *)AllocMem(sizeof(struct BitScaleArgs),MEMF_PUBLIC|MEMF_CLEAR))
						{
							ScaleArgs -> bsa_SrcWidth	= 8;
							ScaleArgs -> bsa_SrcHeight	= 8;

							ScaleArgs -> bsa_SrcBitMap	= ScaleSrcBitMap;
							ScaleArgs -> bsa_DestBitMap	= ScaleDstBitMap;

							return(TRUE);
						}
					}
				}
			}
		}
	}

	return(FALSE);
}

	/* PrintScaled(UBYTE Char,UBYTE Scale):
	 *
	 *	This is the big one: since VT100 supports a number of
	 *	font sizes (double height, double width, 132 columns),
	 *	the approriate characters are scaled in real-time before
	 *	they are displayed.
	 */

VOID
PrintScaled(UBYTE *Buffer,LONG Size,UBYTE Scale)
{
	STATIC UBYTE LocalFgPen = 1,LocalBgPen = 0;

	LONG i;
	
	ULONG srcY,destX,destY,sizeX;

		/* Look for the font type to scale. */

	if(CurrentFont != ScaleFontType)
	{
		SetFont(ScaleRPort,CurrentFont);

		ScaleFontType = CurrentFont;
	}

		/* Set the approriate colours. */

	if(ScaleRPort -> FgPen != LocalFgPen)
	{
		SetAPen(ScaleRPort,FgPen);

		LocalFgPen = FgPen;
	}

	if(ScaleRPort -> BgPen != LocalBgPen)
	{
		LocalBgPen = BgPen;

		SetBPen(ScaleRPort,BgPen);
	}

		/* Determine the scale of the destination character. */

	ScaleArgs -> bsa_YSrcFactor = 1;

	if((Config . FontScale == SCALE_HALF) && (Scale == SCALE_ATTR_NORMAL))
	{
		ScaleArgs -> bsa_XSrcFactor = 2;

		destX = CursorX << 2;

		sizeX = 4;
	} else
	{
		ScaleArgs -> bsa_XSrcFactor = 1;

		destX = CursorX << 3;

		sizeX = 8;

		if(Config . FontScale == SCALE_NORMAL)
			if(Scale != SCALE_ATTR_NORMAL)
			{
				sizeX = 16;
				destX <<= 1;
			}
	}

	srcY = 0;
	destY = CursorY << 3;

	ScaleArgs -> bsa_XDestFactor = 1;
	ScaleArgs -> bsa_YDestFactor = 1;

	switch(Scale)
	{
			/* Twice as wide as the source data. */

		case SCALE_ATTR_2X:

			if(Config . FontScale == SCALE_NORMAL)
				ScaleArgs -> bsa_XDestFactor = 2;

			ScaleArgs -> bsa_YDestFactor = 1;

			break;

			/* Twice as high as the source data. */

		case SCALE_ATTR_BOT2X:

			srcY = 8;

		case SCALE_ATTR_TOP2X:

			if(Config . FontScale == SCALE_NORMAL)
				ScaleArgs -> bsa_XDestFactor = 2;

			ScaleArgs -> bsa_YDestFactor = 2;

			break;
	}

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

			/* Print the character to be scaled into the
			 * invisible drawing area.
			 */

		Move(ScaleRPort,0,6);

		Text(ScaleRPort,Buffer++,1);

			/* Scale the font. */

		BitMapScale(ScaleArgs);

			/* Render the character. */

		BltBitMapRastPort(ScaleDstBitMap,0,srcY,RPort,destX,destY,sizeX,8,0xC0);

		destX += sizeX;
	}
}
