diff options
Diffstat (limited to 'private/mvdm/wow16/gdi/meta.c')
-rw-r--r-- | private/mvdm/wow16/gdi/meta.c | 1835 |
1 files changed, 1835 insertions, 0 deletions
diff --git a/private/mvdm/wow16/gdi/meta.c b/private/mvdm/wow16/gdi/meta.c new file mode 100644 index 000000000..7e98d8682 --- /dev/null +++ b/private/mvdm/wow16/gdi/meta.c @@ -0,0 +1,1835 @@ +/****************************** Module Header ******************************\ +* Module Name: Meta.c +* +* This file contains the routines for playing the GDI metafile. Most of these +* routines are adopted from windows gdi code. Most of the code is from +* win3.0 except for the GetEvent code which is taken from win2.1 +* +* Created: 11-Oct-1989 +* +* Copyright (c) 1985, 1986, 1987, 1988, 1989 Microsoft Corporation +* +* +* Public Functions: +* PlayMetaFile +* PlayMetaFileRecord +* GetMetaFile +* DeleteMetaFile +* Private Functions: +* GetEvent +* IsDIBBlackAndWhite +* +* History: +* 02-Jul-1991 -by- John Colleran [johnc] +* Combined From Win 3.1 and WLO 1.0 sources +\***************************************************************************/ + +#include <windows.h> +#include <string.h> +#ifdef WIN32 +#include "firewall.h" +#endif +#include "gdi16.h" + +HDC hScreenDC = 0; +METACACHE MetaCache = { 0, 0, 0, 0 }; + +UINT INTERNAL GetFileNumber (LPMETAFILE lpMF); +HANDLE INTERNAL CreateBitmapForDC (HDC hMemDC, LPBITMAPINFOHEADER lpDIBInfo); +WORD INTERNAL GetSizeOfColorTable (LPBITMAPINFOHEADER lpDIBInfo); + +#define MAX_META_DISPATCH 0x48 +FARPROC alpfnMetaFunc[MAX_META_DISPATCH+1] = +/* 00 */ {(FARPROC)ScaleWindowExt, +/* 01 */ (FARPROC)SetBkColor, +/* 02 */ (FARPROC)SetBkMode, +/* 03 */ (FARPROC)SetMapMode, +/* 04 */ (FARPROC)SetROP2, +/* 05 */ DEFIFWIN16((FARPROC)SetRelAbs), +/* 06 */ (FARPROC)SetPolyFillMode, +/* 07 */ (FARPROC)SetStretchBltMode, +/* 08 */ (FARPROC)SetTextCharacterExtra, +/* 09 */ (FARPROC)SetTextColor, +/* 0A */ (FARPROC)SetTextJustification, +/* 0B */ (FARPROC)SetWindowOrg, +/* 0C */ (FARPROC)SetWindowExt, +/* 0D */ (FARPROC)SetViewportOrg, +/* 0E */ (FARPROC)SetViewportExt, +/* 0F */ (FARPROC)OffsetWindowOrg, +/* 10 */ 0, +/* 11 */ DEFIFWIN16((FARPROC)OffsetViewportOrg), +/* 12 */ DEFIFWIN16((FARPROC)ScaleViewportExt), +/* 13 */ (FARPROC)LineTo, +/* 14 */ DEFIFWIN16((FARPROC)MoveTo), +/* 15 */ (FARPROC)ExcludeClipRect, +/* 16 */ (FARPROC)IntersectClipRect, +/* 17 */ (FARPROC)Arc, +/* 18 */ (FARPROC)Ellipse, +/* 19 */ (FARPROC)FloodFill, +/* 1A */ (FARPROC)Pie, +/* 1B */ (FARPROC)Rectangle, +/* 1C */ (FARPROC)RoundRect, +/* 1D */ (FARPROC)PatBlt, +/* 1E */ (FARPROC)SaveDC, +/* 1F */ (FARPROC)SetPixel, +/* 20 */ (FARPROC)OffsetClipRgn, +/* 21 */ 0, // TextOut, +/* 22 */ 0, // BitBlt, +/* 23 */ 0, // StretchBlt. +/* 24 */ 0, // Polygon, +/* 25 */ 0, // Polyline, +/* 26 */ 0, // Escape, +/* 27 */ (FARPROC)RestoreDC, +/* 28 */ 0, // FillRegion, +/* 29 */ 0, // FrameRegion, +/* 2A */ 0, // InvertRegion, +/* 2B */ 0, // PaintRegion, +/* 2C */ (FARPROC)SelectClipRgn, +/* 2D */ 0, // SelectObject, +/* 2E */ (FARPROC)SetTextAlign, +/* 2F */ 0, // DrawText, +/* 30 */ (FARPROC)Chord, +/* 31 */ (FARPROC)SetMapperFlags, +/* 32 */ 0, // ExtTextOut, +/* 33 */ 0, // SetDibsToDevice, +/* 34 */ 0, // SelectPalette, +/* 35 */ 0, // RealizePalette, +/* 36 */ 0, // AnimatePalette, +/* 37 */ 0, // SetPaletteEntries, +/* 38 */ 0, // PolyPolygon, +/* 39 */ 0, // ResizePalette, +/* 3A */ 0, +/* 3B */ 0, +/* 3C */ 0, +/* 3D */ 0, +/* 3E */ 0, +/* 3F */ 0, +/* 40 */ 0, // DIBBitblt, +/* 41 */ 0, // DIBStretchBlt, +/* 42 */ 0, // DIBCreatePatternBrush, +/* 43 */ 0, // StretchDIB, +/* 44 */ 0, +/* 45 */ 0, +/* 46 */ 0, +/* 47 */ 0, +/* 48 */ (FARPROC)ExtFloodFill }; + + +#if 0 // this is going to gdi.dll + +/***************************** Public Function ****************************\ +* BOOL APIENTRY PlayMetaFile(hdc, hmf) +* HDC hDC; +* HMETAFILE hMF; +* +* Play a windows metafile. +* +* History: +* Tue 27-Mar-1990 11:11:45 -by- Paul Klingler [paulk] +* Ported from Windows +\***************************************************************************/ + +BOOL GDIENTRY PlayMetaFile(HDC hdc, HMETAFILE hmf) +{ + WORD i; + WORD noObjs; + BOOL bPrint=FALSE; + LPMETAFILE lpmf; + int oldMapMode = -1; + LPMETARECORD lpmr = NULL; + LPHANDLETABLE pht = NULL; + HANDLE hht = NULL; +#ifndef WIN32 + HFONT hLFont; + HBRUSH hLBrush; + HPALETTE hLPal; + HPEN hLPen; + HRGN hClipRgn; + HRGN hRegion; + DWORD oldWndExt; + DWORD oldVprtExt; +#endif //WIN32 + + GdiLogFunc("PlayMetaFile"); + + if(!IsValidMetaFile(hmf)) + goto exitPlayMetaFile; + + if(lpmf = (LPMETAFILE)GlobalLock(hmf)) + { + if((noObjs = lpmf->MetaFileHeader.mtNoObjects) > 0) + { + if(!(hht = GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE, + (sizeof(HANDLE) * lpmf->MetaFileHeader.mtNoObjects) + sizeof(WORD )))) + { + goto exitPlayMetaFile10; + } + pht = (LPHANDLETABLE)GlobalLock(hht); + } +#ifdef CR1 +IMP: Optmizations playing into another metafile. Look at the win3.0 +IMP: code +#endif + +// !!!!! what if this is a metafile DC +#ifndef WIN32 + /* save the old objects so we can put them back */ + hLPen = GetCurrentObject( hdc, OBJ_PEN ); + hLBrush = GetCurrentObject( hdc, OBJ_BRUSH); + hLFont = GetCurrentObject( hdc, OBJ_FONT); + hClipRgn = GetCurrentObject( hdc, OBJ_RGN); + hLPal = GetCurrentObject( hdc, OBJ_PALETTE); + + if(hRegion = GetCurrentObject( hdc, OBJ_RGN)) + { + if(hClipRgn = CreateRectRgn(0,0,0,0)) + CombineRgn(hClipRgn,hRegion,hRegion,RGN_COPY); + } +#endif // WIN32 + + // we should really remove this abort proc thing. + + while(lpmr = GetEvent(lpmf,lpmr,FALSE)) + { +#if 0 //!!!!! + if(GET_pAbortProc(pdc)) +#else + if( 0 ) +#endif //!!!!! + { +//!!!!! if((bPrint = (*(pdc->pAbortProc))(hdc,0)) == FALSE) + { + GetEvent(lpmf,lpmr,TRUE); + RestoreDC(hdc,0); + goto exitPlayMetaFile20; + } + } + PlayMetaFileRecord(hdc,pht,lpmr,noObjs); + } + + bPrint = TRUE; +exitPlayMetaFile20: + /* if we fail restoring an object, we need to select some + default object so that we can DeleteObject any Metafile- + selected objects */ + +#ifndef WIN32 + if(!SelectObject(hdc,hLPen)) + SelectObject(hdc,GetStockObject(BLACK_PEN)); + if(!SelectObject(hdc,hLBrush)) + SelectObject(hdc,GetStockObject(BLACK_BRUSH)); + if(!SelectPalette(hdc, GetCurrentObject( hdc, OBJ_PALETTE), FALSE)) + SelectPalette(hdc, GetStockObject(DEFAULT_PALETTE), FALSE); + + if(!SelectObject(hdc,hLFont)) + { + /* if we cannot select the original font back in, we + ** select the system font. this will allow us to delete + ** the metafile font selected. to insure that the system + ** font gets selected, we reset the DC's transform to + ** default. after the selection, we restore this stuff + */ + oldVprtExt = GetViewportExt(hdc); + oldWndExt = GetWindowExt(hdc); + oldMapMode = SetMapMode(hdc,MM_TEXT); + + SelectObject(hdc,GetStockObject(SYSTEM_FONT)); + + SetMapMode(hdc,oldMapMode); + SetWindowExt(hdc,LOWORD (oldWndExt),HIWORD (oldWndExt)); + SetViewportExt(hdc,LOWORD (oldVprtExt),HIWORD (oldVprtExt)); + } + + if(hClipRgn) + { + SelectObject(hdc,hClipRgn); + DeleteObject(hClipRgn); + } +#endif // WIN32 + + for(i = 0; i < lpmf->MetaFileHeader.mtNoObjects; ++i) + { + if(pht->objectHandle[i]) + DeleteObject(pht->objectHandle[i]); + } + +#ifndef WIN32 + /* if we fiddled with the map mode because we could not + ** restore the original font, then maybe we can restore the + ** font now */ + if(oldMapMode > 0) + SelectObject(hdc,hLFont); +#endif // WIN32 + + if(hht) + { + GlobalUnlock(hht); + GlobalFree(hht); + } + +exitPlayMetaFile10: + GlobalUnlock(hmf); + } + +exitPlayMetaFile: + return(bPrint); +} +#endif // this is going to gdi.dll + +/***************************** Internal Function **************************\ +* BOOL NEAR PASCAL IsDIBBlackAndWhite +* +* Check to see if this DIB is a black and white DIB (and should be +* converted into a mono bitmap as opposed to a color bitmap). +* +* Returns: TRUE it is a B&W bitmap +* FALSE this sucker is for color +* +* Effects: ? +* +* Warnings: ? +* +* History: +\***************************************************************************/ + +BOOL INTERNAL IsDIBBlackAndWhite(LPBITMAPINFOHEADER lpDIBInfo) +{ + LPDWORD lpRGB; + + GdiLogFunc3( " IsDIBBlackAndWhite"); + + /* pointer color table */ + lpRGB = (LPDWORD)((LPBITMAPINFO)lpDIBInfo)->bmiColors; + + if ((lpDIBInfo->biBitCount == 1 && lpDIBInfo->biPlanes == 1) + && (lpRGB[0] == (DWORD)0) + && (lpRGB[1] == (DWORD)0xFFFFFF)) + return(TRUE); + else + return(FALSE); +} + + +/***************************** Internal Function **************************\ +* BigRead +* +* allows reads of greater than 64K +* +* Returns: Number of bytes read +* +\***************************************************************************/ + +DWORD INTERNAL BigRead(UINT fileNumber, LPSTR lpRecord, DWORD dwSizeRec) +{ + DWORD dwRead = dwSizeRec; + HPBYTE hpStuff; + + GdiLogFunc2( " BigRead"); + + hpStuff = (HPBYTE)lpRecord; + + while (dwRead > MAXFILECHUNK) + { + if (_lread(fileNumber, (LPSTR)hpStuff, MAXFILECHUNK) != MAXFILECHUNK) + return(0); + + dwRead -= MAXFILECHUNK; + hpStuff += MAXFILECHUNK; + } + + if (_lread(fileNumber, (LPSTR)hpStuff, (UINT)dwRead) != (UINT)dwRead) + return(0); + + return(dwSizeRec); +} + + +/***************************** Internal Function **************************\ +* UseStretchDIBits +* +* set this directly to the device using StretchDIBits. +* if DIB is black&white, don't do this. +* +* Returns: +* TRUE --- operation successful +* FALSE -- decided not to use StretchDIBits +* +* Effects: ? +* +* Warnings: ? +* +* History: +\***************************************************************************/ + +BOOL INTERNAL UseStretchDIB(HDC hDC, WORD magic, LPMETARECORD lpMR) +{ + LPBITMAPINFOHEADER lpDIBInfo; + int sExtX, sExtY; + int sSrcX, sSrcY; + int DstX, DstY, DstXE, DstYE; + + if (magic == META_DIBBITBLT) + { + lpDIBInfo = (LPBITMAPINFOHEADER)&lpMR->rdParm[8]; + + DstX = lpMR->rdParm[7]; + DstY = lpMR->rdParm[6]; + + sSrcX = lpMR->rdParm[3]; + sSrcY = lpMR->rdParm[2]; + DstXE = sExtX = lpMR->rdParm[5]; + DstYE = sExtY = lpMR->rdParm[4]; + } + else + { + lpDIBInfo = (LPBITMAPINFOHEADER)&lpMR->rdParm[10]; + + DstX = lpMR->rdParm[9]; + DstY = lpMR->rdParm[8]; + DstXE = lpMR->rdParm[7]; + DstYE = lpMR->rdParm[6]; + + sSrcX = lpMR->rdParm[5]; + sSrcY = lpMR->rdParm[4]; + sExtX = lpMR->rdParm[3]; + sExtY = lpMR->rdParm[2]; + } + + /* if DIB is black&white, we don't really want to do this */ + if (IsDIBBlackAndWhite(lpDIBInfo)) + return(FALSE); + + StretchDIBits(hDC, DstX, DstY, DstXE, DstYE, + sSrcX, sSrcY, sExtX, sExtY, + (LPBYTE)((LPSTR)lpDIBInfo + lpDIBInfo->biSize + + GetSizeOfColorTable(lpDIBInfo)), + (LPBITMAPINFO)lpDIBInfo, DIB_RGB_COLORS, + (MAKELONG(lpMR->rdParm[1], lpMR->rdParm[0]))); + return(TRUE); +} + +/***************************** Internal Function **************************\ +* GetEvent +* +* This routine will now open a disk metafile in READ_ONLY mode. This will +* allow us to play read-only metafiles or to share such file. +* +* [amitc: 06/19/91] +\***************************************************************************/ + +LPMETARECORD INTERNAL GetEvent(LPMETAFILE lpMF, HPMETARECORD lpMR, BOOL bFree) +// BOOL bFree; /* non-zero ==> done with metafile */ +{ + int fileNumber = 0; + WORD i; + LPWORD lpCache = NULL; + LPWORD lpMRbuf; + HANDLE hMF; + DWORD rdSize; + + GdiLogFunc2( " GetEvent"); + +#ifdef WIN32 + hMF = GlobalHandle(lpMF); +#else + hMF = LOWORD(GlobalHandle(HIWORD((DWORD)(lpMF)))); +#endif + + ASSERTGDI( hMF != (HANDLE)NULL, "GetEvent: Global Handle failed"); + + if (lpMF->MetaFileHeader.mtType == MEMORYMETAFILE) + { + /* Are we at the end of the metafile */ + if(lpMR && lpMR->rdFunction == 0) + return((LPMETARECORD)0); + + /* done with metafile, so free up the temp selector */ + else if (bFree) + { + if (lpMR) + #ifndef WIN32 + FreeSelector(HIWORD(lpMR)); + #endif + return((LPMETARECORD)0); + } + else + { + /* if we don't already have a selector, get one */ + if (lpMR == NULL) + { + #ifdef WIN32 + lpMR = (HPMETARECORD)((LPMETADATA)lpMF)->metaDataStuff; + // lpMR = (LPMETARECORD)GlobalLock(lpMF->hMetaData); + #else + lpMR = (LPMETARECORD)MAKELP(AllocSelector(HIWORD((DWORD)&lpMF->MetaFileNumber)),LOWORD((DWORD)&lpMF->MetaFileNumber)); + #endif + } + else + lpMR = (LPMETARECORD) (((HPWORD)lpMR)+lpMR->rdSize); + + /* end of the metafile. free up the selector we were using */ + if (lpMR->rdFunction == 0) + { + #ifndef WIN32 + FreeSelector(HIWORD(lpMR)); + #endif + return((LPMETARECORD)0); + } + } + return(lpMR); + } + else if (lpMF->MetaFileHeader.mtType == DISKMETAFILE) + { + if (bFree) + goto errGetEvent; /* never TRUE on the first call to GetEvent */ + + if (lpMR == NULL) + { + if ((fileNumber = OpenFile((LPSTR)lpMF->MetaFileBuffer.szPathName, (LPOFSTRUCT)&(lpMF->MetaFileBuffer), (WORD)OF_PROMPT|OF_REOPEN|OF_READ)) != -1) + { + if (lpMF->MetaFileRecordHandle = GlobalAlloc(GMEM_DDESHARE|GMEM_MOVEABLE,(DWORD)(lpMF->MetaFileHeader.mtMaxRecord * sizeof(WORD)))) + { + lpMR = (LPMETARECORD)GlobalLock(lpMF->MetaFileRecordHandle); + lpMF->MetaFilePosition = _lread(lpMF->MetaFileNumber = fileNumber, (LPSTR)&lpMF->MetaFileHeader, sizeof(METAHEADER)); + + // Check for an Aldus header + if (*((LPDWORD)&(lpMF->MetaFileHeader)) == 0x9AC6CDD7) + { + _llseek( fileNumber, 22, 0); + lpMF->MetaFilePosition = 22 + _lread(fileNumber,(LPSTR)(&(lpMF->MetaFileHeader)),sizeof(METAHEADER)); + } + + lpMF->MetaFileHeader.mtType = DISKMETAFILE; + + if (!MetaCache.hCache) + { + MetaCache.hCache = AllocBuffer(&MetaCache.wCacheSize); + MetaCache.wCacheSize >>= 1; + MetaCache.hMF = hMF; + + /* force cache fill on first access */ + MetaCache.wCachePos = MetaCache.wCacheSize; + } + + if (!(lpMF->MetaFileBuffer.fFixedDisk)) + { + _lclose(fileNumber); + + /* need to update the following for floppy files -- amitc */ + fileNumber = 0 ; + lpMF->MetaFileNumber = 0 ; + } + } + } + else + return((LPMETARECORD)0); + } + + /* update fileNumber, this is so that floopy based files can be closed + and not left open -- amitc */ + + fileNumber = lpMF->MetaFileNumber ; + + if (lpMR) + { + if (MetaCache.hMF == hMF) + { + + lpCache = (LPWORD) GlobalLock(MetaCache.hCache); + lpMRbuf = (LPWORD) lpMR; + + // Make sure we can read the size and function fields + if (MetaCache.wCachePos >= (WORD)(MetaCache.wCacheSize - 2)) + { + WORD cwCopy; + + if (!fileNumber) + if ((fileNumber = GetFileNumber(lpMF)) == -1) + goto errGetEvent; + + // We need to fill up the cache but save any data already + // in the cache + cwCopy = MetaCache.wCacheSize - MetaCache.wCachePos; + for (i = 0; i < cwCopy; i++) + { + lpCache[i] = lpCache[MetaCache.wCacheSize-(cwCopy-i)]; + } + lpMF->MetaFilePosition += _lread(fileNumber, + (LPSTR) (lpCache + cwCopy), + (MetaCache.wCacheSize-cwCopy) << 1); + MetaCache.wCachePos = 0; + } + + lpCache += MetaCache.wCachePos; + rdSize = ((LPMETARECORD)lpCache)->rdSize; + + /* Check for end */ + if (!((LPMETARECORD)lpCache)->rdFunction) + goto errGetEvent; + + // Make sure we can read the rest of the metafile record + if (rdSize + MetaCache.wCachePos > MetaCache.wCacheSize) + { + if (!fileNumber) + if ((fileNumber = GetFileNumber(lpMF)) + == -1) + goto errGetEvent; + + for (i=MetaCache.wCachePos; i < MetaCache.wCacheSize; ++i) + *lpMRbuf++ = *lpCache++; + + lpMF->MetaFilePosition += + BigRead(fileNumber, (LPSTR) lpMRbuf, + (DWORD)(rdSize + + (DWORD)MetaCache.wCachePos + - (DWORD)MetaCache.wCacheSize) << 1); + + // Mark the cache as depleted because we just read + // directly into the metafile record rather than the cache + MetaCache.wCachePos = MetaCache.wCacheSize; + } + else + { + ASSERTGDI( HIWORD(rdSize) == 0, "Huge rdsize"); + for (i = 0; i < LOWORD(rdSize); ++i) + *lpMRbuf++ = *lpCache++; + + MetaCache.wCachePos += LOWORD(rdSize); + } + + GlobalUnlock(MetaCache.hCache); + + return lpMR; + } + + if ((fileNumber = GetFileNumber(lpMF)) == -1) + goto errGetEvent; + + lpMF->MetaFilePosition += _lread(fileNumber, (LPSTR)&lpMR->rdSize, sizeof(DWORD)); + lpMF->MetaFilePosition += BigRead(fileNumber, (LPSTR)&lpMR->rdFunction, (DWORD)(lpMR->rdSize * sizeof(WORD)) - sizeof(DWORD)); + if (!(lpMF->MetaFileBuffer.fFixedDisk)) + { + _lclose(fileNumber); + lpMF->MetaFileNumber = 0 ; + fileNumber = 0 ; + } + + if (lpMR->rdFunction == 0) + { +errGetEvent:; + + if (lpMF->MetaFileBuffer.fFixedDisk || fileNumber) + _lclose(lpMF->MetaFileNumber); + GlobalUnlock(lpMF->MetaFileRecordHandle); + GlobalFree(lpMF->MetaFileRecordHandle); + lpMF->MetaFileNumber = 0; + + if (MetaCache.hMF == hMF) + { + if (lpCache) + GlobalUnlock(MetaCache.hCache); + GlobalFree(MetaCache.hCache); + MetaCache.hCache = MetaCache.hMF = 0; + } + + return((LPMETARECORD)0); + } + } + return(lpMR); + + } + + return((LPMETARECORD)0); +} + + +/***************************** Internal Function **************************\ +* void GDIENTRY PlayMetaFileRecord +* +* Plays a metafile record by executing the GDI function call contained +* withing the metafile record +* +* Effects: +* +\***************************************************************************/ +#if 0 // this is going to gdi.dll + +void +GDIENTRY PlayMetaFileRecord( + HDC hdc, + LPHANDLETABLE lpHandleTable, + LPMETARECORD lpMR, + WORD noObjs + ) + +{ + WORD magic; + HANDLE hObject; + HANDLE hOldObject; + HBRUSH hBrush; + HRGN hRgn; + HANDLE hPal; + BOOL bExtraSel = FALSE; + + dprintf( 3," PlayMetaFileRecord 0x%lX", lpMR); + + if (!ISDCVALID(hdc)) + return; + + magic = lpMR->rdFunction; + + /* being safe, make sure that the lp will give us full access to + ** the record header without overstepping a segment boundary. + */ + #ifndef WIN32 + if ((unsigned)(LOWORD((DWORD)lpMR)) > 0x7000) + { + lpMR = (LPMETARECORD)MAKELP(AllocSelector(HIWORD((DWORD)lpMR)),LOWORD((DWORD)lpMR)); + bExtraSel = TRUE; + } + #endif // WIN32 + + switch (magic & 255) + { + case (META_BITBLT & 255): + case (META_STRETCHBLT & 255): + { + HDC hSDC; + HANDLE hBitmap; + LPBITMAP lpBitmap; + int delta = 0; + + /* if playing into another Metafile, do direct copy */ + if (PlayIntoAMetafile(lpMR, hdc)) + goto errPlayMetaFileRecord20; + + if ((lpMR->rdSize - 3) == (magic >> 8)) + { + hSDC = hdc; + delta = 1; + } + else + { + if (hSDC = CreateCompatibleDC(hdc)) + { + if (magic == META_BITBLT) + lpBitmap = (LPBITMAP)&lpMR->rdParm[8]; + else + lpBitmap = (LPBITMAP)&lpMR->rdParm[10]; + + //!!!!! ALERT DWORD align on NT + if (hBitmap = CreateBitmap(lpBitmap->bmWidth, + lpBitmap->bmHeight, + lpBitmap->bmPlanes, + lpBitmap->bmBitsPixel, + (LPBYTE)&lpBitmap->bmBits)) + hOldObject = SelectObject(hSDC, hBitmap); + else + goto errPlayMetaFileRecord10; + } + else + goto errPlayMetaFileRecord20; + } + + if (hSDC) + { + if (magic == META_BITBLT) + BitBlt(hdc, lpMR->rdParm[7 + delta], + lpMR->rdParm[6 + delta], + lpMR->rdParm[5 + delta], + lpMR->rdParm[4 + delta], + hSDC, + lpMR->rdParm[3], + lpMR->rdParm[2], + MAKELONG(lpMR->rdParm[0], lpMR->rdParm[1])); + else + StretchBlt(hdc, lpMR->rdParm[9 + delta], + lpMR->rdParm[8 + delta], + lpMR->rdParm[7 + delta], + lpMR->rdParm[6 + delta], + hSDC, + lpMR->rdParm[5], + lpMR->rdParm[4], + lpMR->rdParm[3], + lpMR->rdParm[2], + MAKELONG(lpMR->rdParm[0], lpMR->rdParm[1])); + } + if (hSDC != hdc) + { + if (SelectObject(hSDC, hOldObject)) + DeleteObject(hBitmap); +errPlayMetaFileRecord10:; + DeleteDC(hSDC); +errPlayMetaFileRecord20:; + } + } + break; + + case (META_DIBBITBLT & 255): + case (META_DIBSTRETCHBLT & 255): + { + HDC hSDC; + HANDLE hBitmap; + LPBITMAPINFOHEADER lpDIBInfo ; + int delta = 0; + HANDLE hOldPal; + + /* if playing into another metafile, do direct copy */ + if (PlayIntoAMetafile(lpMR, hdc)) + goto errPlayMetaFileRecord40; + + if ((lpMR->rdSize - 3) == (magic >> 8)) + { + hSDC = hdc; + delta = 1; + } + else + { + if( (magic & 255) == (META_DIBSTRETCHBLT & 255) ) + if (UseStretchDIB(hdc, magic, lpMR)) + goto errPlayMetaFileRecord40; + + if (hSDC = CreateCompatibleDC(hdc)) + { + /* set up the memDC to have the same palette */ + hOldPal = SelectPalette(hSDC, GetCurrentObject(hdc,OBJ_PALETTE), TRUE); + + if (magic == META_DIBBITBLT) + lpDIBInfo = (LPBITMAPINFOHEADER)&lpMR->rdParm[8]; + else + lpDIBInfo = (LPBITMAPINFOHEADER)&lpMR->rdParm[10]; + + /* now create the bitmap for the MemDC and fill in the bits */ + + /* the processing for old and new format of metafiles is + different here (till hBitmap is obtained) */ + + /* new metafile version */ + hBitmap = CreateBitmapForDC (hdc,lpDIBInfo); + + if (hBitmap) + hOldObject = SelectObject (hSDC, hBitmap) ; + else + goto errPlayMetaFileRecord30 ; + } + else + goto errPlayMetaFileRecord40; + } + + if (hSDC) + { + if (magic == META_DIBBITBLT) + BitBlt(hdc, lpMR->rdParm[7 + delta], + lpMR->rdParm[6 + delta], + lpMR->rdParm[5 + delta], + lpMR->rdParm[4 + delta], + hSDC, + lpMR->rdParm[3], + lpMR->rdParm[2], + MAKELONG(lpMR->rdParm[0], lpMR->rdParm[1])); + else + StretchBlt(hdc, lpMR->rdParm[9 + delta], + lpMR->rdParm[8 + delta], + lpMR->rdParm[7 + delta], + lpMR->rdParm[6 + delta], + hSDC, + lpMR->rdParm[5], + lpMR->rdParm[4], + lpMR->rdParm[3], + lpMR->rdParm[2], + MAKELONG(lpMR->rdParm[0], lpMR->rdParm[1])); + } + + if (hSDC != hdc) + { + /* Deselect hDC's palette from memDC */ + SelectPalette(hSDC, hOldPal, TRUE); + if (SelectObject(hSDC, hOldObject)) + DeleteObject(hBitmap); +errPlayMetaFileRecord30:; + DeleteDC(hSDC); +errPlayMetaFileRecord40:; + } + } + break; + + case (META_SELECTOBJECT & 255): + { + HANDLE hObject; + + if (hObject = lpHandleTable->objectHandle[lpMR->rdParm[0]]) + SelectObject(hdc, hObject); + } + break; + + case (META_CREATEPENINDIRECT & 255): + { + #ifdef WIN32 + LOGPEN lp; + + lp.lopnStyle = lpMR->rdParm[0]; + lp.lopnWidth.x = lpMR->rdParm[1]; + lp.lopnColor = *((COLORREF *)&lpMR->rdParm[3]); + if (hObject = CreatePenIndirect(&lp)) + #else + if (hObject = CreatePenIndirect((LPLOGPEN)&lpMR->rdParm[0])) + #endif + AddToHandleTable(lpHandleTable, hObject, noObjs); + break; + } + + case (META_CREATEFONTINDIRECT & 255): + { + LOGFONT lf; + LPLOGFONT lplf = &lf; + + LOGFONT32FROM16( lplf, ((LPLOGFONT)&lpMR->rdParm[0])); + if (hObject = CreateFontIndirect(lplf)) + AddToHandleTable(lpHandleTable, hObject, noObjs); + } + break; + + case (META_CREATEPATTERNBRUSH & 255): + { + HANDLE hBitmap; + LPBITMAP lpBitmap; + + lpBitmap = (LPBITMAP)lpMR->rdParm; + + //!!!!! ALERT DWORD align on NT + if (hBitmap = CreateBitmapIndirect(lpBitmap)) + { + LPBITMAPINFO lpbmInfo; + HANDLE hmemInfo; + + hmemInfo = GlobalAlloc( GMEM_ZEROINIT | GMEM_MOVEABLE, + sizeof(BITMAPINFO) + 2<<(lpBitmap->bmPlanes*lpBitmap->bmBitsPixel)); + + lpbmInfo = (LPBITMAPINFO)GlobalLock( hmemInfo); + + lpbmInfo->bmiHeader.biPlanes = lpBitmap->bmPlanes; + lpbmInfo->bmiHeader.biBitCount = lpBitmap->bmBitsPixel; + SetDIBits( (HDC)NULL, hBitmap, 0, lpBitmap->bmHeight, + (LPBYTE)&lpMR->rdParm[8], lpbmInfo, DIB_RGB_COLORS ); + + if (hObject = CreatePatternBrush(hBitmap)) + AddToHandleTable(lpHandleTable, hObject, noObjs); + + GlobalUnlock(hmemInfo); + GlobalFree(hmemInfo); + DeleteObject(hBitmap); + } + } + break; + + case (META_DIBCREATEPATTERNBRUSH & 255): + { + HDC hMemDC ; + HANDLE hBitmap; + LPBITMAPINFOHEADER lpDIBInfo ; + WORD nDIBSize; /* number of WORDs in packed DIB */ + HANDLE hDIB; + LPWORD lpDIB; + LPWORD lpSourceDIB; + WORD i; + + + if (lpMR->rdParm[0] == BS_PATTERN) + { + /* the address of the second paramter is the address of the DIB + header, extract it */ + lpDIBInfo = (BITMAPINFOHEADER FAR *) &lpMR->rdParm[2]; + + /* now create a device dependend bitmap compatible to the default + screen DC - hScreenDC and extract the bits from the DIB into it. + The following function does all these, and returns a HANDLE + to the device dependent BItmap. */ + + /* we will use a dummy memory DC compatible to the screen DC */ + hMemDC = CreateCompatibleDC (hScreenDC) ; + + hBitmap = CreateBitmapForDC (hScreenDC,lpDIBInfo) ; + + if (hBitmap) + { + if (hObject = CreatePatternBrush(hBitmap)) + AddToHandleTable(lpHandleTable, hObject, noObjs); + DeleteObject(hBitmap); + } + + /* delete the dummy memory DC for new version Metafiles*/ + DeleteDC (hMemDC) ; + } + + /* this is a DIBPattern brush */ + else + { + /* get size of just the packed DIB */ + nDIBSize = (WORD) (lpMR->rdSize - 4); + if ((hDIB = GlobalAlloc(GMEM_DDESHARE|GMEM_MOVEABLE,(LONG)(nDIBSize << 1)))) + { + lpDIB = (WORD FAR *) GlobalLock (hDIB); + lpSourceDIB = (WORD FAR *)&lpMR->rdParm[2]; + + /* copy the DIB into our new memory block */ + for (i = 0; i < nDIBSize; i++) + *lpDIB++ = *lpSourceDIB++; + + GlobalUnlock (hDIB); + + if (hObject = CreateDIBPatternBrush(hDIB, lpMR->rdParm[1])) + AddToHandleTable(lpHandleTable, hObject, noObjs); + + GlobalFree(hDIB); + } + } + } + break; + + case (META_CREATEBRUSHINDIRECT & 255): + { + #ifdef WIN32 + LOGBRUSH lb; + + lb.lbStyle = lpMR->rdParm[0]; + lb.lbColor = *((COLORREF *)&lpMR->rdParm[1]); + lb.lbHatch = lpMR->rdParm[3]; + + if (hObject = CreateBrushIndirect(&lb)) + #else + if (hObject = CreateBrushIndirect((LPLOGBRUSH)&lpMR->rdParm[0])) + #endif + AddToHandleTable(lpHandleTable, hObject, noObjs); + break; + } + + case (META_POLYLINE & 255): + { + LPPOINT lppt; + Polyline(hdc, (lppt=CONVERTPTS(&lpMR->rdParm[1],lpMR->rdParm[0])), lpMR->rdParm[0]); + FREECONVERT(lppt); + break; + } + + case (META_POLYGON & 255): + { + LPPOINT lppt; + Polygon(hdc, (lppt=CONVERTPTS(&lpMR->rdParm[1],lpMR->rdParm[0])), lpMR->rdParm[0]); + FREECONVERT(lppt); + break; + } + + case (META_POLYPOLYGON & 255): + { + LPPOINT lppt; + #ifdef WIN32 + WORD cPts=0; + WORD ii; + + for(ii=0; ii<lpMR->rdParm[0]; ii++) + cPts += ((LPWORD)&lpMR->rdParm[1])[ii]; + #endif // WIN32 + + PolyPolygon(hdc, + (lppt=CONVERTPTS(&lpMR->rdParm[1] + lpMR->rdParm[0], cPts)), + (LPINT)&lpMR->rdParm[1], + lpMR->rdParm[0]); + FREECONVERT(lppt); + } + break; + + case (META_EXTTEXTOUT & 255): + { + LPWORD lpdx; + LPSTR lpch; + LPRECT lprt; + + lprt = (lpMR->rdParm[3] & (ETO_OPAQUE|ETO_CLIPPED)) ? (LPRECT)&lpMR->rdParm[4] : 0; + lpch = (LPSTR)&lpMR->rdParm[4] + ((lprt) ? sizeof(RECT) : 0); + + /* dx array starts at next word boundary after char string */ + lpdx = (LPWORD)(lpch + ((lpMR->rdParm[2] + 1) & 0xFFFE)); + + /* check to see if there is a Dx array by seeing if + structure ends after the string itself + */ + if ( ((DWORD)((LPWORD)lpdx - (LPWORD)(lpMR))) >= lpMR->rdSize) + lpdx = NULL; + else + lpdx = (LPWORD)CONVERTINTS((signed short FAR *)lpdx, lpMR->rdParm[2]); + + ExtTextOut(hdc, lpMR->rdParm[1], lpMR->rdParm[0], lpMR->rdParm[3], + lprt, (LPSTR)lpch, lpMR->rdParm[2], (LPINT)lpdx); + if (lpdx != (LPWORD)NULL) + FREECONVERT(lpdx); + break; + } + + case (META_TEXTOUT & 255): + TextOut(hdc, lpMR->rdParm[lpMR->rdSize-4], lpMR->rdParm[lpMR->rdSize-5], (LPSTR)&lpMR->rdParm[1], lpMR->rdParm[0]); + break; + + case (META_ESCAPE & 255): + { + LPSTR lpStuff; + + if (lpMR->rdParm[0] != MFCOMMENT) + { + lpStuff = (LPSTR)&lpMR->rdParm[2]; +#ifdef OLDEXTTEXTOUT + if (lpMR->rdParm[0] == EXTTEXTOUT) + { + EXTTEXTDATA ExtData; + + ExtData.xPos = lpMR->rdParm[2]; + ExtData.yPos = lpMR->rdParm[3]; + ExtData.cch = lpMR->rdParm[4]; + ExtData.rcClip = *((LPRECT)&lpMR->rdParm[5]); + ExtData.lpString = (LPSTR)&lpMR->rdParm[9]; + ExtData.lpWidths = (WORD FAR *)&lpMR->rdParm[9+((ExtData.cch+1)/2)]; + lpStuff = (LPSTR)&ExtData; + } +#endif + Escape(hdc, lpMR->rdParm[0], lpMR->rdParm[1], lpStuff, (LPSTR)0); + } + } + break; + + case (META_FRAMEREGION & 255): + if((hRgn = lpHandleTable->objectHandle[lpMR->rdParm[0]]) + && (hBrush = lpHandleTable->objectHandle[lpMR->rdParm[1]])) + FrameRgn(hdc, hRgn, hBrush, lpMR->rdParm[3], lpMR->rdParm[2]); + break; + + case (META_PAINTREGION & 255): + if(hRgn = lpHandleTable->objectHandle[lpMR->rdParm[0]]) + PaintRgn(hdc, hRgn); + break; + + case (META_INVERTREGION & 255): + if(hRgn = lpHandleTable->objectHandle[lpMR->rdParm[0]]) + InvertRgn(hdc, hRgn); + break; + + case (META_FILLREGION & 255): + if((hRgn = lpHandleTable->objectHandle[lpMR->rdParm[0]]) + && (hBrush = lpHandleTable->objectHandle[lpMR->rdParm[1]])) + FillRgn(hdc, hRgn, hBrush); + break; + +#ifdef DEADCODE +#ifdef GDI104 + case (META_DRAWTEXT & 255): + MFDrawText(hdc, (LPPOINT)&lpMR->rdParm[6], lpMR->rdParm[1], (LPPOINT)&lpMR->rdParm[2], lpMR->rdParm[0]); + break; +#endif +#endif + +/* +*** in win2, METACREATEREGION records contained an entire region object, +*** including the full header. this header changed in win3. +*** +*** to remain compatible, the region records will be saved with the +*** win2 header. here we read a win2 header with region, and actually +*** create a win3 header with same region internals +*/ + + case (META_CREATEREGION & 255): + { +#if 0 //!!!!! + HANDLE hRgn; + WORD *pRgn; + WORD iChar; + LPWORD *lpTemp; + + iChar = lpMR->rdSize*2 - sizeof(WIN2OBJHEAD) - RECHDRSIZE; + if (hRgn = LocalAlloc(LMEM_ZEROINIT, iChar + sizeof(ILOBJHEAD))) + + { + pRgn = (WORD *)Lock IT(hRgn); + + *((WIN2OBJHEAD *)pRgn) = *((WIN2OBJHEAD FAR *)&lpMR->rdParm[0]); + ((ILOBJHEAD *)pRgn)->ilObjMetaList = 0; + + lpTemp = (LPWORD)&(lpMR->rdParm[0]); + ((WIN2OBJHEAD FAR *)lpTemp)++; + + ((ILOBJHEAD *)pRgn)++; /* --> actual region */ + + for(i = 0; i < (iChar >> 1) ; i++) + *pRgn++ = *lpTemp++; + pRgn = (WORD *)lock IT(hRgn); + ((PRGN)pRgn)->rgnSize = iChar + sizeof(ILOBJHEAD); + + AddToHandleTable(lpHandleTable, hRgn, noObjs); + } +#endif //!!!!! + HANDLE hRgn = NULL; + HANDLE hRgn2 = NULL; + WORD cScans; + WORD cPnts; + WORD cbIncr; + LPWIN3REGION lpW3Rgn = (LPWIN3REGION)lpMR->rdParm; + LPSCAN lpScan = lpW3Rgn->aScans; + LPWORD lpXs; + + for( cScans=lpW3Rgn->cScans; cScans>0; cScans--) + { + + // If this is the first scan then hRgn2 IS the region + // otherwise OR it in + if( hRgn == NULL ) + { + // Create the first region in this scan + hRgn = CreateRectRgn( lpScan->scnPntsX[0], lpScan->scnPntTop, + lpScan->scnPntsX[1], lpScan->scnPntBottom); + + // Allocate a worker region + hRgn2 = CreateRectRgn( 1, 1, 2, 2); + } + else + { + SetRectRgn( hRgn2, lpScan->scnPntsX[0], lpScan->scnPntTop, + lpScan->scnPntsX[1], lpScan->scnPntBottom ); + CombineRgn( hRgn, hRgn, hRgn2, RGN_OR ); + } + + lpXs = &lpScan->scnPntsX[2]; + + // If there are more regions on this scan OR them in + for(cPnts = (WORD)(lpScan->scnPntCnt-2); cPnts>0; cPnts-=2) + { + SetRectRgn( hRgn2, *lpXs++, lpScan->scnPntTop, + *lpXs++, lpScan->scnPntBottom ); + + CombineRgn( hRgn, hRgn, hRgn2, RGN_OR ); + } + + cbIncr = (WORD)sizeof(SCAN) + (WORD)(lpScan->scnPntCnt-2); + cbIncr = (WORD)sizeof(WORD)*(WORD)(lpScan->scnPntCnt-2); + cbIncr = (WORD)sizeof(SCAN) + (WORD)sizeof(WORD)*(WORD)(lpScan->scnPntCnt-2); + cbIncr = (WORD)sizeof(SCAN) + (WORD)(sizeof(WORD)*(lpScan->scnPntCnt-2)); + lpScan = (LPSCAN)((LPBYTE)lpScan + cbIncr); + } + + if( hRgn2 != NULL ) + DeleteObject( hRgn2 ); + + AddToHandleTable(lpHandleTable, hRgn, noObjs); + } + break; + + case (META_DELETEOBJECT & 255): + { + HANDLE h; + + if (h = lpHandleTable->objectHandle[lpMR->rdParm[0]]) + { + DeleteObjectPriv(h); + lpHandleTable->objectHandle[lpMR->rdParm[0]] = NULL; + } + } + break; + + case (META_CREATEPALETTE & 255): + if (hObject = CreatePalette((LPLOGPALETTE)&lpMR->rdParm[0])) + AddToHandleTable(lpHandleTable, hObject, noObjs); + break; + + case (META_SELECTPALETTE & 255): + if(hPal = lpHandleTable->objectHandle[lpMR->rdParm[0]]) + { + SelectPalette(hdc, hPal, 0); + } + break; + + case (META_REALIZEPALETTE & 255): + RealizePalette(hdc); + break; + + case (META_SETPALENTRIES & 255): + /* we know the palette being set is the current palette */ + SetPaletteEntriesPriv(GetCurrentObject(hdc,OBJ_PALETTE), lpMR->rdParm[0], + lpMR->rdParm[1], (LPPALETTEENTRY)&lpMR->rdParm[2]); + break; + + case (META_ANIMATEPALETTE & 255): + AnimatePalettePriv(GetCurrentObject(hdc,OBJ_PALETTE), lpMR->rdParm[0], + lpMR->rdParm[1], (LPPALETTEENTRY)&lpMR->rdParm[2]); + + break; + + case (META_RESIZEPALETTE & 255): + ResizePalettePriv(GetCurrentObject(hdc,OBJ_PALETTE), lpMR->rdParm[0]); + break; + + case (META_SETDIBTODEV & 255): + { + LPBITMAPINFOHEADER lpBitmapInfo; + WORD ColorSize; + + /* if playing into another metafile, do direct copy */ + if (PlayIntoAMetafile(lpMR, hdc)) + goto DontReallyPlay; + + lpBitmapInfo = (LPBITMAPINFOHEADER)&(lpMR->rdParm[9]); + + if (lpBitmapInfo->biClrUsed) + { + ColorSize = ((WORD)lpBitmapInfo->biClrUsed) * + (WORD)(lpMR->rdParm[0] == DIB_RGB_COLORS ? + sizeof(RGBQUAD) : + sizeof(WORD)); + } + else if (lpBitmapInfo->biBitCount == 24) + ColorSize = 0; + else + ColorSize = (WORD)(1 << lpBitmapInfo->biBitCount) * + (WORD)(lpMR->rdParm[0] == DIB_RGB_COLORS ? + sizeof(RGBQUAD) : + sizeof(WORD)); + + ColorSize += sizeof(BITMAPINFOHEADER); + + SetDIBitsToDevice(hdc, lpMR->rdParm[8], lpMR->rdParm[7], + lpMR->rdParm[6], lpMR->rdParm[5], + lpMR->rdParm[4], lpMR->rdParm[3], + lpMR->rdParm[2], lpMR->rdParm[1], + (BYTE FAR *)(((BYTE FAR *)lpBitmapInfo) + ColorSize), + (LPBITMAPINFO) lpBitmapInfo, + lpMR->rdParm[0]); +DontReallyPlay:; + } + break; + + case (META_STRETCHDIB & 255): + { + LPBITMAPINFOHEADER lpBitmapInfo; + WORD ColorSize; + + /* if playing into another metafile, do direct copy */ + if (PlayIntoAMetafile(lpMR, hdc)) + goto DontReallyPlay2; + + lpBitmapInfo = (LPBITMAPINFOHEADER)&(lpMR->rdParm[11]); + + if (lpBitmapInfo->biClrUsed) + { + ColorSize = ((WORD)lpBitmapInfo->biClrUsed) * + (WORD)(lpMR->rdParm[2] == DIB_RGB_COLORS ? + sizeof(RGBQUAD) : + sizeof(WORD)); + } + else if (lpBitmapInfo->biBitCount == 24) + ColorSize = 0; + else + ColorSize = (WORD)(1 << lpBitmapInfo->biBitCount) * + (WORD)(lpMR->rdParm[2] == DIB_RGB_COLORS ? + sizeof(RGBQUAD) : + sizeof(WORD)); + + ColorSize += sizeof(BITMAPINFOHEADER); + + StretchDIBits(hdc, lpMR->rdParm[10], lpMR->rdParm[9], + lpMR->rdParm[8], lpMR->rdParm[7], + lpMR->rdParm[6], lpMR->rdParm[5], + lpMR->rdParm[4], lpMR->rdParm[3], + (LPBYTE)(((BYTE FAR *)lpBitmapInfo) + ColorSize), + (LPBITMAPINFO) lpBitmapInfo, + lpMR->rdParm[2], + MAKELONG(lpMR->rdParm[1], lpMR->rdParm[0])); +DontReallyPlay2:; + } + break; + +// Function that have new parameters on WIN32 +// Or have DWORDs that stayed DWORDs; all other INTs to DWORDs +#ifdef WIN32 + case (META_MOVETO & 255): + MoveTo( hdc, (long)lpMR->rdParm[1], (long)lpMR->rdParm[0], NULL ); + break; + + case (META_RESTOREDC & 255): + RestoreDC( hdc, (long)(signed short)lpMR->rdParm[0] ); + break; + + case (META_SETBKCOLOR & 255): + SetBkColor( hdc, (UINT)*((LPDWORD)lpMR->rdParm) ); + break; + + case (META_SETTEXTCOLOR & 255): + SetTextColor( hdc, (UINT)*((LPDWORD)lpMR->rdParm) ); + break; + + case (META_SETPIXEL & 255): + SetPixel( hdc, (UINT)lpMR->rdParm[3], (UINT)lpMR->rdParm[2], + (UINT)*((LPDWORD)lpMR->rdParm) ); + break; + + case (META_SETMAPPERFLAGS & 255): + SetMapperFlags( hdc, (UINT)*((LPDWORD)lpMR->rdParm) ); + break; + + case (META_FLOODFILL & 255): + FloodFill( hdc, (UINT)lpMR->rdParm[3], (UINT)lpMR->rdParm[2], + (UINT)*((LPDWORD)lpMR->rdParm) ); + break; + + case (META_EXTFLOODFILL & 255): + ExtFloodFill( hdc, (UINT)lpMR->rdParm[4], (UINT)lpMR->rdParm[3], + (UINT)*((LPDWORD)&lpMR->rdParm[1]), (UINT)lpMR->rdParm[0] ); + break; + + // These puppies all got a new NULL and have only two parameters and a DC. + case (META_SETWINDOWORG & 255): + case (META_SETWINDOWEXT & 255): + case (META_SETVIEWPORTORG & 255): + case (META_SETVIEWPORTEXT & 255): + case (META_OFFSETWINDOWORG & 255): + case (META_SCALEWINDOWEXT & 255): + case (META_OFFSETVIEWPORTORG & 255): + case (META_SCALEVIEWPORTEXT & 255): + { + FARPROC lpProc; + + ASSERTGDI((magic&0x00ff) <= MAX_META_DISPATCH, "Unknown function to dispatch1"); + + lpProc = alpfnMetaFunc[magic&0x00ff]; + + ASSERTGDI( lpProc != (FARPROC)NULL, "function not in dispatch table1 "); + + if (lpProc != (FARPROC)NULL) + (*lpProc)(hdc, (long)(short)lpMR->rdParm[1], (long)(short)lpMR->rdParm[0], NULL ); + } + break; +#endif // WIN32 + + default: + { + FARPROC lpProc; + signed short *pshort; + + ASSERTGDI((magic&0x00ff) <= MAX_META_DISPATCH, "Unknown function to dispatch"); + + lpProc = alpfnMetaFunc[magic&0x00ff]; + + ASSERTGDI( (lpProc != (FARPROC)NULL) || (magic == META_SETRELABS), "function not in dispatch table"); + + if ((lpProc == (FARPROC)NULL)) + return; + + // Switch to the corresponding dispatcher by number of parameters + // The number of parameters in the dispatch number does not include the DC. + switch (magic >> 8) + { + typedef int (FAR PASCAL *META1PROC)(HDC); + typedef int (FAR PASCAL *META2PROC)(HDC, int); + typedef int (FAR PASCAL *META3PROC)(HDC, int, int); + typedef int (FAR PASCAL *META4PROC)(HDC, int, int, int); + typedef int (FAR PASCAL *META5PROC)(HDC, int, int, int, int); + typedef int (FAR PASCAL *META6PROC)(HDC, int, int, int, int, int); + typedef int (FAR PASCAL *META7PROC)(HDC, int, int, int, int, int, int); + typedef int (FAR PASCAL *META9PROC)(HDC, int, int, int, int, int, int, int, int); + + case 0: + (*((META1PROC)lpProc))(hdc); + break; + case 1: + (*((META2PROC)lpProc))(hdc,lpMR->rdParm[0]); + break; + case 2: + (*((META3PROC)lpProc))(hdc,lpMR->rdParm[1],lpMR->rdParm[0]); + break; + case 3: + (*((META4PROC)lpProc))(hdc,lpMR->rdParm[2],lpMR->rdParm[1],lpMR->rdParm[0]); + break; + case 4: + (*((META5PROC)lpProc))(hdc,lpMR->rdParm[3],lpMR->rdParm[2],lpMR->rdParm[1],lpMR->rdParm[0]); + break; + case 5: + (*((META6PROC)lpProc))(hdc,lpMR->rdParm[4],lpMR->rdParm[3],lpMR->rdParm[2],lpMR->rdParm[1],lpMR->rdParm[0]); + break; + case 6: + (*((META7PROC)lpProc))(hdc,lpMR->rdParm[5],lpMR->rdParm[4],lpMR->rdParm[3],lpMR->rdParm[2],lpMR->rdParm[1],lpMR->rdParm[0]); + break; + case 8: + (*((META9PROC)lpProc))(hdc,lpMR->rdParm[7],lpMR->rdParm[6],lpMR->rdParm[5],lpMR->rdParm[4],lpMR->rdParm[3],lpMR->rdParm[2],lpMR->rdParm[1],lpMR->rdParm[0]); + break; + + default: + ASSERTGDI( FALSE, "No dispatch for this count of args"); + break; + } + } + break; + } +#ifndef WIN32 + if (bExtraSel) + FreeSelector(HIWORD(lpMR)); +#endif // WIN32 +} + +#endif // this is going to gdi.dll + +/****************************** Internal Function **************************\ +* AddToHandleTable +* +* Adds an object to the metafile table of objects +* +* +\***************************************************************************/ + +VOID INTERNAL AddToHandleTable(LPHANDLETABLE lpHandleTable, HANDLE hObject, WORD noObjs) +{ + WORD i; + + GdiLogFunc3( " AddToHandleTable"); + + /* linear search through table for first open slot */ + for (i = 0; ((lpHandleTable->objectHandle[i] != NULL) && (i < noObjs)); + ++i); + + if (i < noObjs) /* ok index */ + lpHandleTable->objectHandle[i] = hObject; + else + { + ASSERTGDI( 0, "Too many objects in table"); + FatalExit(METAEXITCODE); /* Why can't we store the handle? */ + } +} + + +/****************************** Internal Function **************************\ +* GetFileNumber +* +* Returns the DOS file number for a metafiles file +* -1 if failure +* +\***************************************************************************/ + +UINT INTERNAL GetFileNumber(LPMETAFILE lpMF) +{ + int fileNumber; + + GdiLogFunc3( " GetFileNumber"); + + if (!(fileNumber = lpMF->MetaFileNumber)) + { + if ((fileNumber = OpenFile((LPSTR) lpMF->MetaFileBuffer.szPathName, + (LPOFSTRUCT) &(lpMF->MetaFileBuffer), + (WORD)OF_PROMPT | OF_REOPEN | OF_READ) + ) != -1) + { + _llseek(fileNumber, (long)lpMF->MetaFilePosition, 0); + + /* need to update MetaFileNumber for floppy files -- amitc */ + lpMF->MetaFileNumber = fileNumber ; + } + } + + return fileNumber; +} + +#if 0 +/****************************** Internal Function **************************\ +* IsValidMetaFile(HANDLE hMetaData) +* +* Validates a metafile +* +* Returns TRUE iff hMetaData is a valid metafile +* +\***************************************************************************/ + +BOOL GDIENTRY IsValidMetaFile(HANDLE hMetaData) +{ + LPMETADATA lpMetaData; + BOOL status = FALSE; + + GdiLogFunc3( " IsValidMetaFile"); + + /* if this is a valid metafile we will save the version in a global variable */ + + if (hMetaData && (lpMetaData = (LPMETADATA) GlobalLock(hMetaData))) + { + status = ( + (lpMetaData->dataHeader.mtType == MEMORYMETAFILE || + lpMetaData->dataHeader.mtType == DISKMETAFILE) && + (lpMetaData->dataHeader.mtHeaderSize == HEADERSIZE) && + ((lpMetaData->dataHeader.mtVersion ==METAVERSION) || + (lpMetaData->dataHeader.mtVersion ==METAVERSION100)) + ); + GlobalUnlock(hMetaData); + } + return status; +} +#endif + +#define INITIALBUFFERSIZE 16384 + +/****************************** Internal Function **************************\ +* +* AllocBuffer - Allocates a buffer as "large" as possible +* +\***************************************************************************/ + +HANDLE INTERNAL AllocBuffer(LPWORD piBufferSize) +{ + WORD iCurBufferSize = INITIALBUFFERSIZE; + HANDLE hBuffer; + + GdiLogFunc3( " AllocBuffer"); + + while (!(hBuffer = GlobalAlloc(GMEM_MOVEABLE | + GMEM_NODISCARD, (LONG) iCurBufferSize)) + && iCurBufferSize) + iCurBufferSize >>= 1; + + *piBufferSize = iCurBufferSize; + return (iCurBufferSize) ? hBuffer : NULL; +} + + +/****************************** Internal Function **************************\ +* CreateBitmapForDC (HDC hMemDC, LPBITMAPINFOHEADER lpDIBInfo) +* +* This routine takes a memory device context and a DIB bitmap, creates a +* compatible bitmap for the DC and fills it with the bits from the DIB (co- +* -nverting to the device dependent format). The pointer to the DIB bits +* start immediately after the color table in the INFO header. ** +* ** +* The routine returns the handle to the bitmap with the bits filled in if +* everything goes well else it returns NULL. ** +\***************************************************************************/ + +HANDLE INTERNAL CreateBitmapForDC (HDC hMemDC, LPBITMAPINFOHEADER lpDIBInfo) +{ + HBITMAP hBitmap ; + LPBYTE lpDIBits ; + + GdiLogFunc3( " CreateBitmapForDC"); + + /* preserve monochrome if it started out as monochrome + ** and check for REAL Black&white monochrome as opposed + ** to a 2-color DIB + */ + if (IsDIBBlackAndWhite(lpDIBInfo)) + hBitmap = CreateBitmap ((WORD)lpDIBInfo->biWidth, + (WORD)lpDIBInfo->biHeight, + 1, 1, (LPBYTE) NULL); + else + /* otherwise, make a compatible bitmap */ + hBitmap = CreateCompatibleBitmap (hMemDC, + (WORD)lpDIBInfo->biWidth, + (WORD)lpDIBInfo->biHeight); + + if (!hBitmap) + goto CreateBitmapForDCErr ; + + /* take a pointer past the header of the DIB, to the start of the color + table */ + lpDIBits = (LPBYTE) lpDIBInfo + sizeof (BITMAPINFOHEADER) ; + + /* take the pointer past the color table */ + lpDIBits += GetSizeOfColorTable (lpDIBInfo) ; + + /* get the bits from the DIB into the Bitmap */ + if (!SetDIBits (hMemDC, hBitmap, 0, (WORD)lpDIBInfo->biHeight, + lpDIBits, (LPBITMAPINFO)lpDIBInfo, 0)) + { + DeleteObject(hBitmap); + goto CreateBitmapForDCErr ; + } + + /* return success */ + return (hBitmap) ; + +CreateBitmapForDCErr: + + /* returm failure for function */ + return (NULL) ; +} + + +/****************************** Internal Function **************************\ +* GetSizeOfColorTable (LPBITMAPINFOHEADER lpDIBInfo) +* +* Returns the number of bytes in the color table for the giving info header +* +\***************************************************************************/ + +WORD INTERNAL GetSizeOfColorTable (LPBITMAPINFOHEADER lpDIBInfo) +{ + + GdiLogFunc3( "GetSizeOfColorTable"); + + if (lpDIBInfo->biClrUsed) + return((WORD)lpDIBInfo->biClrUsed * (WORD)sizeof(RGBQUAD)); + else + { + switch (lpDIBInfo->biBitCount) + { + case 1: + return (2 * sizeof (RGBQUAD)) ; + break ; + case 4: + return (16 * sizeof (RGBQUAD)) ; + break ; + case 8: + return (256 * sizeof (RGBQUAD)) ; + break ; + default: + return (0) ; + break ; + } + } +} + +#if 0 // this is going to gdi.dll + +/***************************** Public Function ****************************\ +* BOOL APIENTRY DeleteMetaFile(hmf) +* +* Frees a metafile handle. +* +* Effects: +* +\***************************************************************************/ + +BOOL GDIENTRY DeleteMetaFile(HMETAFILE hmf) +{ + GdiLogFunc("DeleteMetaFile"); + + GlobalFree(hmf); + + return(TRUE); +} + + +/***************************** Public Function ****************************\ +* HMETAFILE APIENTRY GetMetaFile(pzFilename) +* +* Returns a metafile handle for a disk based metafile. +* +* Effects: +* +* History: +* Sat 14-Oct-1989 14:21:37 -by- Paul Klingler [paulk] +* Wrote it. +\***************************************************************************/ + +HMETAFILE GDIENTRY GetMetaFile(LPSTR pzFilename) +{ + BOOL status=FALSE; + UINT cBytes; + int file; + HMETAFILE hmf; + LPMETAFILE lpmf; + + GdiLogFunc("GetMetaFile"); + + // Allocate the Metafile + if(hmf = GlobalAlloc(GMEM_DDESHARE|GMEM_MOVEABLE,(DWORD)sizeof(METAFILE))) + { + lpmf = (LPMETAFILE)GlobalLock(hmf); + + // Make sure the file Exists + if((file = OpenFile(pzFilename, + &(lpmf->MetaFileBuffer), + (WORD)OF_PROMPT | OF_EXIST)) == -1L) + { + ASSERTGDI( FALSE, "GetMetaFile: Metafile does not exist"); + goto exitGetMetaFile; + } + + // Open the file + if((file = OpenFile(pzFilename, + &(lpmf->MetaFileBuffer), + (WORD)OF_PROMPT | OF_REOPEN | OF_READWRITE)) == -1) + { + ASSERTGDI( FALSE, "GetMetaFile: Unable to open Metafile"); + goto exitGetMetaFile; + } + + cBytes = (UINT)_lread(file,(LPSTR)(&(lpmf->MetaFileHeader)),sizeof(METAHEADER)); + + // Check for an Aldus header + if (*((LPDWORD)&(lpmf->MetaFileHeader)) == 0x9AC6CDD7) + { + + _llseek( file, 22, 0); + cBytes = (UINT)_lread(file,(LPSTR)(&(lpmf->MetaFileHeader)),sizeof(METAHEADER)); + } + + _lclose(file); + + // Validate the metafile + if(cBytes == sizeof(METAHEADER)) + { + lpmf->MetaFileHeader.mtType = DISKMETAFILE; + status = TRUE; + } + + exitGetMetaFile: + GlobalUnlock(hmf); + } + + if(status == FALSE) + { + GlobalFree(hmf); + hmf = NULL; + } + + return(hmf); +} +#endif // this is going to gdi.dll + +#ifdef WIN32 +#undef GetViewportExt +DWORD GetViewportExt32(HDC hdc) +{ + SIZE sz; + GetViewportExt( hdc, &sz ); + return(MAKELONG(LOWORD(sz.cx),LOWORD(sz.cy))); +} + +#undef GetWindowExt +DWORD GetWindowExt32(HDC hdc) +{ + SIZE sz; + GetWindowExt( hdc, &sz ); + return(MAKELONG(LOWORD(sz.cx),LOWORD(sz.cy))); +} + +#undef SetViewportExt +DWORD SetViewportExt32(HDC hdc, UINT x, UINT y) +{ + SIZE sz; + SetViewportExt( hdc, x, y, &sz ); + return(MAKELONG(LOWORD(sz.cx),LOWORD(sz.cy))); +} + +#undef SetWindowExt +DWORD SetWindowExt32(HDC hdc, UINT x, UINT y) +{ + SIZE sz; + SetWindowExt( hdc, x, y, &sz ); + return(MAKELONG(LOWORD(sz.cx),LOWORD(sz.cy))); +} + +/* Convert WORD arrays into DWORDs */ +LPINT ConvertInts( signed short * pWord, UINT cWords ) +{ + UINT ii; + LPINT pInt; + + pInt = (LPINT)LocalAlloc( LMEM_FIXED, cWords * sizeof(UINT)); + + for( ii=0; ii<cWords; ii++) + { + pInt[ii] = (long)(signed)pWord[ii]; + } + + return(pInt); +} + +#endif // WIN32 |