implementation module osbitmap





//	PA: other version of bitmaps: create a bitmap handle instead of continuesly copying String to OS



import	StdArray, StdBool, StdChar, StdClass, StdInt, StdFile, StdTuple

import	ospicture, ostoolbox, pictCCall_12





::	Bitmap

	=	OSBitmap !OSBitmap

::	OSBitmap

	=	{	originalSize	:: !(!Int,!Int)		// The size of the bitmap

		,	reSize			:: !(!Int,!Int)		// to store values passed to resizeBitmap

		,	bitmapContents	:: !{#Char}			// The (device independent) bitmap information (for printing)

		,	bitmapHandle	:: !Int				// The handle to the screen bitmap (for screen)

		}



toBitmap :: !OSBitmap -> Bitmap

toBitmap osBitmap = OSBitmap osBitmap



fromBitmap :: !Bitmap -> OSBitmap

fromBitmap (OSBitmap osBitmap) = osBitmap



//	osReadBitmap reads a bitmap from a file. See page 176 of Programming Windows 95 (Charles Petzold)

osReadBitmap :: !*File -> (!Bool,!OSBitmap,!*File)

osReadBitmap file

	# (_, c1,file) = freadc file

	# (ok,c2,file) = freadc file      // read first two bytes

	| not ok || c1<>'B' || c2<>'M'	  // are they "BM"? 

		= (False,noBitmap,file)

	# (_,  fileSize,file)	= freadi file // read file size

	# (_,  _,       file)	= freadi file // skip bfReserved1 & 2

	# (_,  _,       file)	= freadi file // skip bfOffBits

	# (_,  _,       file)	= freadi file // skip biSize

	# (_,  w,       file)	= freadi file // read width

	# (ok1,h,       file)	= freadi file // read height

	# (ok2,         file)	= fseek  file 0 FSeekSet

	| not ok1 || not ok2

		= (False,noBitmap,file)

	# (data,file)			= freads file fileSize

	| size data <> fileSize

		= (False,noBitmap,file)

	| otherwise

		# (hdc, tb)			= winCreateScreenHDC OSNewToolbox

		# (hbmp,tb)			= winCreateBitmap w data hdc tb

		# tb				= winDestroyScreenHDC (hdc,tb)

		= (if (tb==OSDummyToolbox) True True,{originalSize=(w,h),reSize=(w,h),bitmapContents=data,bitmapHandle=hbmp},file)

where

	noBitmap = {originalSize=(0,0),reSize=(0,0),bitmapContents={},bitmapHandle=0}



//	osGetBitmapSize returns the size of the bitmap.

osGetBitmapSize :: !OSBitmap -> (!Int,!Int)

osGetBitmapSize {reSize}

	= reSize



//	osGetBitmapContent returns the content string of the bitmap

osGetBitmapContent :: !OSBitmap -> {#Char}

osGetBitmapContent {bitmapContents}

	= bitmapContents



//	osGetBitmapHandle returns the handle of the bitmap

osGetBitmapHandle :: !OSBitmap -> Int

osGetBitmapHandle {bitmapHandle}

	= bitmapHandle





/*	osResizeBitmap (w,h) bitmap

		resizes the argument bitmap to the given size.

	It is assumed that w and h are not negative.

*/

osResizeBitmap :: !(!Int,!Int) !OSBitmap -> OSBitmap

osResizeBitmap size bitmap

	= {bitmap & reSize=size}



/*	osDrawBitmap bitmap pos origin pictContext

		draws the argument bitmap with the left top corner at pos, given the current origin and drawing context.

*/

osDrawBitmap :: !OSBitmap !(!Int,!Int) !(!Int,!Int) !Bool !OSPictContext !*OSToolbox -> (!OSPictContext,!*OSToolbox)

osDrawBitmap {originalSize,reSize,bitmapContents,bitmapHandle} pos=:(px,py) origin=:(ox,oy) isScreenOutput pictContext tb

	| isScreenOutput

		| originalSize==reSize

			= winDrawBitmap  originalSize destination bitmapHandle (pictContext,tb)

		// otherwise

			= winDrawResizedBitmap  originalSize destination reSize bitmapHandle (pictContext,tb)

	| otherwise

		= winPrintResizedBitmap originalSize destination reSize bitmapContents (pictContext,tb)

where

	destination	= (px-ox,py-oy)

