summaryrefslogtreecommitdiffstats
path: root/private/mvdm/wow16/gdi/meta.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/mvdm/wow16/gdi/meta.c')
-rw-r--r--private/mvdm/wow16/gdi/meta.c1835
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