diff --git a/graphics/metafiledrv/bitblt.c b/graphics/metafiledrv/bitblt.c
index f77b2282043422d3382530fc8401bf0142371aa3..bceef2504f51c276484e4da24bdcbe75ffc9e142 100644
--- a/graphics/metafiledrv/bitblt.c
+++ b/graphics/metafiledrv/bitblt.c
@@ -5,8 +5,9 @@
  */
 
 #include "gdi.h"
-#include "metafile.h"
 #include "metafiledrv.h"
+#include "heap.h"
+#include "debug.h"
 
 /***********************************************************************
  *           MFDRV_PatBlt
@@ -14,8 +15,8 @@
 BOOL MFDRV_PatBlt( DC *dc, INT left, INT top,
                      INT width, INT height, DWORD rop )
 {
-    MF_MetaParam6( dc, META_PATBLT, left, top, width, height,
-                   HIWORD(rop), LOWORD(rop) );
+    MFDRV_MetaParam6( dc, META_PATBLT, left, top, width, height,
+		      HIWORD(rop), LOWORD(rop) );
     return TRUE;
 }
 
@@ -23,23 +24,127 @@ BOOL MFDRV_PatBlt( DC *dc, INT left, INT top,
 /***********************************************************************
  *           MFDRV_BitBlt
  */
-BOOL MFDRV_BitBlt( DC *dcDst, INT xDst, INT yDst,
-                      INT width, INT height, DC *dcSrc,
-                      INT xSrc, INT ySrc, DWORD rop )
+BOOL MFDRV_BitBlt( DC *dcDst, INT xDst, INT yDst, INT width, INT height,
+		   DC *dcSrc, INT xSrc, INT ySrc, DWORD rop )
 {
-    return MF_BitBlt( dcDst, xDst, yDst, width, height,
-                      dcSrc, xSrc, ySrc, rop );
+    BOOL ret;
+    DWORD len;
+    METARECORD *mr;
+    BITMAP16  BM;
+
+    GetObject16(dcSrc->w.hBitmap, sizeof(BITMAP16), &BM);
+    len = sizeof(METARECORD) + 12 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
+    if (!(mr = HeapAlloc(SystemHeap, 0, len)))
+	return FALSE;
+    mr->rdFunction = META_BITBLT;
+    *(mr->rdParm + 7) = BM.bmWidth;
+    *(mr->rdParm + 8) = BM.bmHeight;
+    *(mr->rdParm + 9) = BM.bmWidthBytes;
+    *(mr->rdParm +10) = BM.bmPlanes;
+    *(mr->rdParm +11) = BM.bmBitsPixel;
+    TRACE(metafile,"len = %ld  rop=%lx  \n",len,rop);
+    if (GetBitmapBits(dcSrc->w.hBitmap,BM.bmWidthBytes * BM.bmHeight,
+                        mr->rdParm +12))
+    {
+      mr->rdSize = len / sizeof(INT16);
+      *(mr->rdParm) = HIWORD(rop);
+      *(mr->rdParm + 1) = ySrc;
+      *(mr->rdParm + 2) = xSrc;
+      *(mr->rdParm + 3) = height;
+      *(mr->rdParm + 4) = width;
+      *(mr->rdParm + 5) = yDst;
+      *(mr->rdParm + 6) = xDst;
+      ret = MFDRV_WriteRecord( dcDst, mr, mr->rdSize * 2);
+    } 
+    else
+        ret = FALSE;
+    HeapFree( SystemHeap, 0, mr);
+    return ret;
 }
 
 
+
 /***********************************************************************
  *           MFDRV_StretchBlt
+ * this function contains TWO ways for procesing StretchBlt in metafiles,
+ * decide between rdFunction values  META_STRETCHBLT or META_DIBSTRETCHBLT
+ * via #define STRETCH_VIA_DIB
  */
-BOOL MFDRV_StretchBlt( DC *dcDst, INT xDst, INT yDst,
-                          INT widthDst, INT heightDst,
-                          DC *dcSrc, INT xSrc, INT ySrc,
-                          INT widthSrc, INT heightSrc, DWORD rop )
+#define STRETCH_VIA_DIB
+#undef  STRETCH_VIA_DIB
+
+BOOL MFDRV_StretchBlt( DC *dcDst, INT xDst, INT yDst, INT widthDst,
+		       INT heightDst, DC *dcSrc, INT xSrc, INT ySrc,
+		       INT widthSrc, INT heightSrc, DWORD rop )
 {
-    return MF_StretchBlt( dcDst, xDst, yDst, widthDst, heightDst,
-                          dcSrc, xSrc, ySrc, widthSrc, heightSrc, rop );
+    BOOL ret;
+    DWORD len;
+    METARECORD *mr;
+    BITMAP16  BM;
+#ifdef STRETCH_VIA_DIB    
+    LPBITMAPINFOHEADER lpBMI;
+    WORD nBPP;
+#endif  
+    GetObject16(dcSrc->w.hBitmap, sizeof(BITMAP16), &BM);
+#ifdef STRETCH_VIA_DIB
+    nBPP = BM.bmPlanes * BM.bmBitsPixel;
+    len = sizeof(METARECORD) + 10 * sizeof(INT16) 
+            + sizeof(BITMAPINFOHEADER) + (nBPP != 24 ? 1 << nBPP: 0) * sizeof(RGBQUAD) 
+              + ((BM.bmWidth * nBPP + 31) / 32) * 4 * BM.bmHeight;
+    if (!(mr = HeapAlloc( SystemHeap, 0, len)))
+	return FALSE;
+    mr->rdFunction = META_DIBSTRETCHBLT;
+    lpBMI=(LPBITMAPINFOHEADER)(mr->rdParm+10);
+    lpBMI->biSize      = sizeof(BITMAPINFOHEADER);
+    lpBMI->biWidth     = BM.bmWidth;
+    lpBMI->biHeight    = BM.bmHeight;
+    lpBMI->biPlanes    = 1;
+    lpBMI->biBitCount  = nBPP;                              /* 1,4,8 or 24 */
+    lpBMI->biClrUsed   = nBPP != 24 ? 1 << nBPP : 0;
+    lpBMI->biSizeImage = ((lpBMI->biWidth * nBPP + 31) / 32) * 4 * lpBMI->biHeight;
+    lpBMI->biCompression = BI_RGB;
+    lpBMI->biXPelsPerMeter = MulDiv(GetDeviceCaps(dcSrc->hSelf,LOGPIXELSX),3937,100);
+    lpBMI->biYPelsPerMeter = MulDiv(GetDeviceCaps(dcSrc->hSelf,LOGPIXELSY),3937,100);
+    lpBMI->biClrImportant  = 0;                          /* 1 meter  = 39.37 inch */
+
+    TRACE(metafile,"MF_StretchBltViaDIB->len = %ld  rop=%lx  PixYPM=%ld Caps=%d\n",
+               len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(hdcSrc,LOGPIXELSY));
+    if (GetDIBits(hdcSrc,dcSrc->w.hBitmap,0,(UINT)lpBMI->biHeight,
+                  (LPSTR)lpBMI + DIB_BitmapInfoSize( (BITMAPINFO *)lpBMI,
+                                                     DIB_RGB_COLORS ),
+                  (LPBITMAPINFO)lpBMI, DIB_RGB_COLORS))
+#else
+    len = sizeof(METARECORD) + 15 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
+    if (!(mr = HeapAlloc( SystemHeap, 0, len )))
+	return FALSE;
+    mr->rdFunction = META_STRETCHBLT;
+    *(mr->rdParm +10) = BM.bmWidth;
+    *(mr->rdParm +11) = BM.bmHeight;
+    *(mr->rdParm +12) = BM.bmWidthBytes;
+    *(mr->rdParm +13) = BM.bmPlanes;
+    *(mr->rdParm +14) = BM.bmBitsPixel;
+    TRACE(metafile,"len = %ld  rop=%lx  \n",len,rop);
+    if (GetBitmapBits( dcSrc->w.hBitmap, BM.bmWidthBytes * BM.bmHeight,
+                         mr->rdParm +15))
+#endif    
+    {
+      mr->rdSize = len / sizeof(INT16);
+      *(mr->rdParm) = LOWORD(rop);
+      *(mr->rdParm + 1) = HIWORD(rop);
+      *(mr->rdParm + 2) = heightSrc;
+      *(mr->rdParm + 3) = widthSrc;
+      *(mr->rdParm + 4) = ySrc;
+      *(mr->rdParm + 5) = xSrc;
+      *(mr->rdParm + 6) = heightDst;
+      *(mr->rdParm + 7) = widthDst;
+      *(mr->rdParm + 8) = yDst;
+      *(mr->rdParm + 9) = xDst;
+      ret = MFDRV_WriteRecord( dcDst, mr, mr->rdSize * 2);
+    }  
+    else
+        ret = FALSE;
+    HeapFree( SystemHeap, 0, mr);
+    return ret;
 }
+
+
diff --git a/graphics/metafiledrv/graphics.c b/graphics/metafiledrv/graphics.c
index 8bc0a221c24a892d910a7954f11436099e05daec..d744bc48abb0cd3456fd8379ec8bb079d078cd38 100644
--- a/graphics/metafiledrv/graphics.c
+++ b/graphics/metafiledrv/graphics.c
@@ -7,10 +7,10 @@
 #include <stdlib.h>
 #include "gdi.h"
 #include "dc.h"
-#include "metafile.h"
 #include "region.h"
 #include "xmalloc.h"
 #include "metafiledrv.h"
+#include "heap.h"
 #include "debug.h"
 
 /**********************************************************************
@@ -19,7 +19,7 @@
 BOOL
 MFDRV_MoveToEx(DC *dc,INT x,INT y,LPPOINT pt)
 {
-    if (!MF_MetaParam2(dc,META_MOVETO,x,y))
+    if (!MFDRV_MetaParam2(dc,META_MOVETO,x,y))
     	return FALSE;
 
     if (pt)
@@ -38,7 +38,7 @@ MFDRV_MoveToEx(DC *dc,INT x,INT y,LPPOINT pt)
 BOOL
 MFDRV_LineTo( DC *dc, INT x, INT y )
 {
-     return MF_MetaParam2(dc, META_LINETO, x, y);
+     return MFDRV_MetaParam2(dc, META_LINETO, x, y);
 }
 
 
@@ -49,8 +49,8 @@ BOOL
 MFDRV_Arc( DC *dc, INT left, INT top, INT right, INT bottom,
            INT xstart, INT ystart, INT xend, INT yend )
 {
-     return MF_MetaParam8(dc, META_ARC, left, top, right, bottom,
-			  xstart, ystart, xend, yend);
+     return MFDRV_MetaParam8(dc, META_ARC, left, top, right, bottom,
+			     xstart, ystart, xend, yend);
 }
 
 
@@ -61,8 +61,8 @@ BOOL
 MFDRV_Pie( DC *dc, INT left, INT top, INT right, INT bottom,
            INT xstart, INT ystart, INT xend, INT yend )
 {
-    return MF_MetaParam8(dc, META_PIE, left, top, right, bottom,
-			 xstart, ystart, xend, yend);
+    return MFDRV_MetaParam8(dc, META_PIE, left, top, right, bottom,
+			    xstart, ystart, xend, yend);
 }
 
 
@@ -73,8 +73,8 @@ BOOL
 MFDRV_Chord( DC *dc, INT left, INT top, INT right, INT bottom,
              INT xstart, INT ystart, INT xend, INT yend )
 {
-    return MF_MetaParam8(dc, META_CHORD, left, top, right, bottom,
-			 xstart, ystart, xend, yend);
+    return MFDRV_MetaParam8(dc, META_CHORD, left, top, right, bottom,
+			    xstart, ystart, xend, yend);
 }
 
 /***********************************************************************
@@ -83,7 +83,7 @@ MFDRV_Chord( DC *dc, INT left, INT top, INT right, INT bottom,
 BOOL
 MFDRV_Ellipse( DC *dc, INT left, INT top, INT right, INT bottom )
 {
-    return MF_MetaParam4(dc, META_ELLIPSE, left, top, right, bottom);
+    return MFDRV_MetaParam4(dc, META_ELLIPSE, left, top, right, bottom);
 }
 
 /***********************************************************************
@@ -92,7 +92,7 @@ MFDRV_Ellipse( DC *dc, INT left, INT top, INT right, INT bottom )
 BOOL
 MFDRV_Rectangle(DC *dc, INT left, INT top, INT right, INT bottom)
 {
-    return MF_MetaParam4(dc, META_RECTANGLE, left, top, right, bottom);
+    return MFDRV_MetaParam4(dc, META_RECTANGLE, left, top, right, bottom);
 }
 
 /***********************************************************************
@@ -102,8 +102,8 @@ BOOL
 MFDRV_RoundRect( DC *dc, INT left, INT top, INT right,
                  INT bottom, INT ell_width, INT ell_height )
 {
-    return MF_MetaParam6(dc, META_ROUNDRECT, left, top, right, bottom,
-			 ell_width, ell_height);
+    return MFDRV_MetaParam6(dc, META_ROUNDRECT, left, top, right, bottom,
+			    ell_width, ell_height);
 }
 
 /***********************************************************************
@@ -112,7 +112,31 @@ MFDRV_RoundRect( DC *dc, INT left, INT top, INT right,
 COLORREF
 MFDRV_SetPixel( DC *dc, INT x, INT y, COLORREF color )
 {
-    return MF_MetaParam4(dc, META_SETPIXEL, x, y,HIWORD(color),LOWORD(color)); 
+    return MFDRV_MetaParam4(dc, META_SETPIXEL, x, y,HIWORD(color),
+			    LOWORD(color)); 
+}
+
+
+/******************************************************************
+ *         MFDRV_MetaPoly - implements Polygon and Polyline
+ */
+static BOOL MFDRV_MetaPoly(DC *dc, short func, LPPOINT16 pt, short count)
+{
+    BOOL ret;
+    DWORD len;
+    METARECORD *mr;
+
+    len = sizeof(METARECORD) + (count * 4); 
+    if (!(mr = HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY, len )))
+	return FALSE;
+
+    mr->rdSize = len / 2;
+    mr->rdFunction = func;
+    *(mr->rdParm) = count;
+    memcpy(mr->rdParm + 1, pt, count * 4);
+    ret = MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
+    HeapFree( SystemHeap, 0, mr);
+    return ret;
 }
 
 
@@ -128,7 +152,7 @@ MFDRV_Polyline( DC *dc, const POINT* pt, INT count )
 
     pt16 = (LPPOINT16)xmalloc(sizeof(POINT16)*count);
     for (i=count;i--;) CONV_POINT32TO16(&(pt[i]),&(pt16[i]));
-    ret = MF_MetaPoly(dc, META_POLYLINE, pt16, count); 
+    ret = MFDRV_MetaPoly(dc, META_POLYLINE, pt16, count); 
 
     free(pt16);
     return ret;
@@ -147,7 +171,7 @@ MFDRV_Polygon( DC *dc, const POINT* pt, INT count )
 
     pt16 = (LPPOINT16)xmalloc(sizeof(POINT16)*count);
     for (i=count;i--;) CONV_POINT32TO16(&(pt[i]),&(pt16[i]));
-    ret = MF_MetaPoly(dc, META_POLYGON, pt16, count); 
+    ret = MFDRV_MetaPoly(dc, META_POLYGON, pt16, count); 
 
     free(pt16);
     return ret;
@@ -155,7 +179,7 @@ MFDRV_Polygon( DC *dc, const POINT* pt, INT count )
 
 
 /**********************************************************************
- *          PolyPolygon
+ *          MFDRV_PolyPolygon
  */
 BOOL 
 MFDRV_PolyPolygon( DC *dc, const POINT* pt, const INT* counts, UINT polygons)
@@ -168,7 +192,7 @@ MFDRV_PolyPolygon( DC *dc, const POINT* pt, const INT* counts, UINT polygons)
     for (i=0;i<polygons;i++) {
     	pt16=(LPPOINT16)xmalloc(sizeof(POINT16)*counts[i]);
 	for (j=counts[i];j--;) CONV_POINT32TO16(&(curpt[j]),&(pt16[j]));
-	ret = MF_MetaPoly(dc, META_POLYGON, pt16, counts[i]);
+	ret = MFDRV_MetaPoly(dc, META_POLYGON, pt16, counts[i]);
 	free(pt16);
 	if (!ret)
 	    return FALSE;
@@ -184,7 +208,96 @@ MFDRV_PolyPolygon( DC *dc, const POINT* pt, const INT* counts, UINT polygons)
 BOOL 
 MFDRV_ExtFloodFill( DC *dc, INT x, INT y, COLORREF color, UINT fillType )
 {
-    return MF_MetaParam4(dc,META_FLOODFILL,x,y,HIWORD(color),LOWORD(color)); 
+    return MFDRV_MetaParam4(dc,META_FLOODFILL,x,y,HIWORD(color),
+			    LOWORD(color)); 
+}
+
+
+/******************************************************************
+ *         MFDRV_CreateRegion
+ *
+ * For explanation of the format of the record see MF_Play_MetaCreateRegion in
+ * objects/metafile.c 
+ */
+static INT16 MFDRV_CreateRegion(DC *dc, HRGN hrgn)
+{
+    DWORD len;
+    METARECORD *mr;
+    RGNDATA *rgndata;
+    RECT *pCurRect, *pEndRect;
+    WORD Bands = 0, MaxBands = 0;
+    WORD *Param, *StartBand;
+    BOOL ret;
+
+    len = GetRegionData( hrgn, 0, NULL );
+    if( !(rgndata = HeapAlloc( SystemHeap, 0, len )) ) {
+        WARN(metafile, "Can't alloc rgndata buffer\n");
+	return -1;
+    }
+    GetRegionData( hrgn, len, rgndata );
+
+    /* Overestimate of length:
+     * Assume every rect is a separate band -> 6 WORDs per rect
+     */
+    len = sizeof(METARECORD) + 20 + (rgndata->rdh.nCount * 12);
+    if( !(mr = HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY, len )) ) {
+        WARN(metafile, "Can't alloc METARECORD buffer\n");
+	HeapFree( SystemHeap, 0, rgndata );
+	return -1;
+    }
+
+    Param = mr->rdParm + 11;
+    StartBand = NULL;
+
+    pEndRect = (RECT *)rgndata->Buffer + rgndata->rdh.nCount;
+    for(pCurRect = (RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++)
+    {
+        if( StartBand && pCurRect->top == *(StartBand + 1) )
+        {
+	    *Param++ = pCurRect->left;
+	    *Param++ = pCurRect->right;
+	}
+	else
+	{
+	    if(StartBand)
+	    {
+	        *StartBand = Param - StartBand - 3;
+		*Param++ = *StartBand;
+		if(*StartBand > MaxBands)
+		    MaxBands = *StartBand;
+		Bands++;
+	    }
+	    StartBand = Param++;
+	    *Param++ = pCurRect->top;
+	    *Param++ = pCurRect->bottom;
+	    *Param++ = pCurRect->left;
+	    *Param++ = pCurRect->right;
+	}
+    }
+    len = Param - (WORD *)mr;
+    
+    mr->rdParm[0] = 0;
+    mr->rdParm[1] = 6;
+    mr->rdParm[2] = 0x1234;
+    mr->rdParm[3] = 0;
+    mr->rdParm[4] = len * 2;
+    mr->rdParm[5] = Bands;
+    mr->rdParm[6] = MaxBands;
+    mr->rdParm[7] = rgndata->rdh.rcBound.left;
+    mr->rdParm[8] = rgndata->rdh.rcBound.top;
+    mr->rdParm[9] = rgndata->rdh.rcBound.right;
+    mr->rdParm[10] = rgndata->rdh.rcBound.bottom;
+    mr->rdFunction = META_CREATEREGION;
+    mr->rdSize = len / 2;
+    ret = MFDRV_WriteRecord( dc, mr, mr->rdSize * 2 );	
+    HeapFree( SystemHeap, 0, mr );
+    HeapFree( SystemHeap, 0, rgndata );
+    if(!ret) 
+    {
+        WARN(metafile, "MFDRV_WriteRecord failed\n");
+	return -1;
+    }
+    return MFDRV_AddHandleDC( dc );
 }
 
 
@@ -195,10 +308,10 @@ BOOL
 MFDRV_PaintRgn( DC *dc, HRGN hrgn )
 {
     INT16 index;
-    index = MF_CreateRegion( dc, hrgn );
+    index = MFDRV_CreateRegion( dc, hrgn );
     if(index == -1)
         return FALSE;
-    return MF_MetaParam1( dc, META_PAINTREGION, index );
+    return MFDRV_MetaParam1( dc, META_PAINTREGION, index );
 }
 
 
@@ -208,7 +321,7 @@ MFDRV_PaintRgn( DC *dc, HRGN hrgn )
 COLORREF
 MFDRV_SetBkColor( DC *dc, COLORREF color )
 {
-    return MF_MetaParam2(dc, META_SETBKCOLOR, HIWORD(color), LOWORD(color));
+    return MFDRV_MetaParam2(dc, META_SETBKCOLOR, HIWORD(color), LOWORD(color));
 }
 
 
@@ -218,6 +331,7 @@ MFDRV_SetBkColor( DC *dc, COLORREF color )
 COLORREF
 MFDRV_SetTextColor( DC *dc, COLORREF color )
 {
-    return MF_MetaParam2(dc, META_SETTEXTCOLOR, HIWORD(color), LOWORD(color));
+    return MFDRV_MetaParam2(dc, META_SETTEXTCOLOR, HIWORD(color),
+			    LOWORD(color));
 }
 
diff --git a/graphics/metafiledrv/init.c b/graphics/metafiledrv/init.c
index c7195d3517382b129fde080415c9c2bb193b5e26..de9c9322996f9da8762645be828730132cbe954e 100644
--- a/graphics/metafiledrv/init.c
+++ b/graphics/metafiledrv/init.c
@@ -116,6 +116,7 @@ static DC *MFDRV_AllocMetaFile(void)
     }
 
     physDev->nextHandle = 0;
+    physDev->hFile = 0;
 
     physDev->mh->mtHeaderSize   = sizeof(METAHEADER) / sizeof(WORD);
     physDev->mh->mtVersion      = 0x0300;
@@ -124,13 +125,12 @@ static DC *MFDRV_AllocMetaFile(void)
     physDev->mh->mtMaxRecord    = 0;
     physDev->mh->mtNoParameters = 0;
 
-/*    DC_InitDC( dc ); */
     return dc;
 }
 
 
 /**********************************************************************
-*	     MFDRV_DeleteDC
+ *	     MFDRV_DeleteDC
  */
 static BOOL MFDRV_DeleteDC( DC *dc )
 {
@@ -143,7 +143,6 @@ static BOOL MFDRV_DeleteDC( DC *dc )
     return TRUE;
 }
 
-
 /**********************************************************************
  *	     CreateMetaFile16   (GDI.125)
  *
@@ -169,29 +168,30 @@ HDC16 WINAPI CreateMetaFile16(
     if (filename)  /* disk based metafile */
     {
         physDev->mh->mtType = METAFILE_DISK;
-        if ((hFile = _lcreat( filename, 0 )) == HFILE_ERROR)
-        {
+        if ((hFile = CreateFileA(filename, GENERIC_WRITE, 0, NULL,
+				CREATE_ALWAYS, 0, -1)) == HFILE_ERROR) {
             MFDRV_DeleteDC( dc );
             return 0;
         }
-        if (_lwrite( hFile, (LPSTR)physDev->mh,
-                       sizeof(*physDev->mh)) == HFILE_ERROR)
-	{
+        if (!WriteFile( hFile, (LPSTR)physDev->mh, sizeof(*physDev->mh), NULL,
+			NULL )) {
             MFDRV_DeleteDC( dc );
             return 0;
 	}
-	physDev->mh->mtNoParameters = hFile; /* store file descriptor here */
-	                            /* windows probably uses this too*/
+	physDev->hFile = hFile;
+
+	/* Grow METAHEADER to include filename */
+	physDev->mh = MF_CreateMetaHeaderDisk(physDev->mh, filename);
     }
     else  /* memory based metafile */
 	physDev->mh->mtType = METAFILE_MEMORY;
-
+	
     TRACE(metafile, "returning %04x\n", dc->hSelf);
     return dc->hSelf;
 }
 
 /**********************************************************************
- *	     CreateMetaFile32A   (GDI32.51)
+ *	     CreateMetaFileA   (GDI32.51)
  */
 HDC WINAPI CreateMetaFileA( 
 			      LPCSTR filename /* Filename of disk metafile */
@@ -201,7 +201,7 @@ HDC WINAPI CreateMetaFileA(
 }
 
 /**********************************************************************
- *          CreateMetaFile32W   (GDI32.52)
+ *          CreateMetaFileW   (GDI32.52)
  */
 HDC WINAPI CreateMetaFileW(LPCWSTR filename)
 {
@@ -217,10 +217,13 @@ HDC WINAPI CreateMetaFileW(LPCWSTR filename)
     return hReturnDC;
 }
 
-static DC *METAFILE_CloseMetaFile( HDC hdc ) 
+
+/**********************************************************************
+ *          MFDRV_CloseMetaFile
+ */
+static DC *MFDRV_CloseMetaFile( HDC hdc ) 
 {
     DC *dc;
-    HFILE hFile;
     METAFILEDRV_PDEVICE *physDev;
     
     TRACE(metafile, "(%04x)\n", hdc );
@@ -232,7 +235,7 @@ static DC *METAFILE_CloseMetaFile( HDC hdc )
      * in SDK Knowledgebase Q99334.
      */
 
-    if (!MF_MetaParam0(dc, META_EOF))
+    if (!MFDRV_MetaParam0(dc, META_EOF))
     {
         MFDRV_DeleteDC( dc );
 	return 0;
@@ -240,20 +243,19 @@ static DC *METAFILE_CloseMetaFile( HDC hdc )
 
     if (physDev->mh->mtType == METAFILE_DISK)  /* disk based metafile */
     {
-        hFile = physDev->mh->mtNoParameters;
-	physDev->mh->mtNoParameters = 0;
-        if (_llseek(hFile, 0L, 0) == HFILE_ERROR)
-        {
+        if (SetFilePointer(physDev->hFile, 0, NULL, FILE_BEGIN) != 0) {
             MFDRV_DeleteDC( dc );
             return 0;
         }
-        if (_lwrite( hFile, (LPSTR)physDev->mh,
-                       sizeof(*physDev->mh)) == HFILE_ERROR)
-        {
+
+	physDev->mh->mtType = METAFILE_MEMORY; /* This is what windows does */
+        if (!WriteFile(physDev->hFile, (LPSTR)physDev->mh,
+                       sizeof(*physDev->mh), NULL, NULL)) {
             MFDRV_DeleteDC( dc );
             return 0;
         }
-        _lclose(hFile);
+        CloseHandle(physDev->hFile);
+	physDev->mh->mtType = METAFILE_DISK;
     }
 
     return dc;
@@ -268,22 +270,21 @@ HMETAFILE16 WINAPI CloseMetaFile16(
 {
     HMETAFILE16 hmf;
     METAFILEDRV_PDEVICE *physDev;
-    DC *dc = METAFILE_CloseMetaFile(hdc);
+    DC *dc = MFDRV_CloseMetaFile(hdc);
     if (!dc) return 0;
     physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
 
     /* Now allocate a global handle for the metafile */
 
-    hmf = GLOBAL_CreateBlock( GMEM_MOVEABLE, physDev->mh,
-                              physDev->mh->mtSize * sizeof(WORD),
-                              GetCurrentPDB16(), FALSE, FALSE, FALSE, NULL );
+    hmf = MF_Create_HMETAFILE16( physDev->mh );
+
     physDev->mh = NULL;  /* So it won't be deleted */
     MFDRV_DeleteDC( dc );
     return hmf;
 }
 
 /******************************************************************
- *	     CloseMetaFile32   (GDI32.17)
+ *	     CloseMetaFile   (GDI32.17)
  *
  *  Stop recording graphics operations in metafile associated with
  *  hdc and retrieve metafile.
@@ -295,33 +296,192 @@ HMETAFILE WINAPI CloseMetaFile(
 				   HDC hdc /* Metafile DC to close */
 )
 {
-  return CloseMetaFile16(hdc);
+    HMETAFILE hmf;
+    METAFILEDRV_PDEVICE *physDev;
+    DC *dc = MFDRV_CloseMetaFile(hdc);
+    if (!dc) return 0;
+    physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
+
+    /* Now allocate a global handle for the metafile */
+
+    hmf = MF_Create_HMETAFILE( physDev->mh );
+
+    physDev->mh = NULL;  /* So it won't be deleted */
+    MFDRV_DeleteDC( dc );
+    return hmf;
 }
 
 
 /******************************************************************
- *	     DeleteMetaFile16   (GDI.127)
+ *         MFDRV_WriteRecord
+ *
+ * Warning: this function can change the pointer to the metafile header.
  */
-BOOL16 WINAPI DeleteMetaFile16( 
-			       HMETAFILE16 hmf 
-			       /* Handle of memory metafile to delete */
-)
+BOOL MFDRV_WriteRecord( DC *dc, METARECORD *mr, DWORD rlen)
 {
-    return !GlobalFree16( hmf );
+    DWORD len;
+    METAHEADER *mh;
+    METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
+
+    switch(physDev->mh->mtType)
+    {
+    case METAFILE_MEMORY:
+	len = physDev->mh->mtSize * 2 + rlen;
+	mh = HeapReAlloc( SystemHeap, 0, physDev->mh, len );
+        if (!mh) return FALSE;
+        physDev->mh = mh;
+	memcpy((WORD *)physDev->mh + physDev->mh->mtSize, mr, rlen);
+        break;
+    case METAFILE_DISK:
+        TRACE(metafile,"Writing record to disk\n");
+	if (!WriteFile(physDev->hFile, (char *)mr, rlen, NULL, NULL))
+	    return FALSE;
+        break;
+    default:
+        ERR(metafile, "Unknown metafile type %d\n", physDev->mh->mtType );
+        return FALSE;
+    }
+
+    physDev->mh->mtSize += rlen / 2;
+    physDev->mh->mtMaxRecord = MAX(physDev->mh->mtMaxRecord, rlen / 2);
+    return TRUE;
 }
 
+
 /******************************************************************
- *          DeleteMetaFile32  (GDI32.69)
- *
- *  Delete a memory-based metafile.
+ *         MFDRV_MetaParam0
  */
 
-BOOL WINAPI DeleteMetaFile(
-	      HMETAFILE hmf
-) {
-  return !GlobalFree16( hmf );
+BOOL MFDRV_MetaParam0(DC *dc, short func)
+{
+    char buffer[8];
+    METARECORD *mr = (METARECORD *)&buffer;
+    
+    mr->rdSize = 3;
+    mr->rdFunction = func;
+    return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
 }
 
+
+/******************************************************************
+ *         MFDRV_MetaParam1
+ */
+BOOL MFDRV_MetaParam1(DC *dc, short func, short param1)
+{
+    char buffer[8];
+    METARECORD *mr = (METARECORD *)&buffer;
+    
+    mr->rdSize = 4;
+    mr->rdFunction = func;
+    *(mr->rdParm) = param1;
+    return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MFDRV_MetaParam2
+ */
+BOOL MFDRV_MetaParam2(DC *dc, short func, short param1, short param2)
+{
+    char buffer[10];
+    METARECORD *mr = (METARECORD *)&buffer;
+    
+    mr->rdSize = 5;
+    mr->rdFunction = func;
+    *(mr->rdParm) = param2;
+    *(mr->rdParm + 1) = param1;
+    return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MFDRV_MetaParam4
+ */
+
+BOOL MFDRV_MetaParam4(DC *dc, short func, short param1, short param2, 
+		      short param3, short param4)
+{
+    char buffer[14];
+    METARECORD *mr = (METARECORD *)&buffer;
+    
+    mr->rdSize = 7;
+    mr->rdFunction = func;
+    *(mr->rdParm) = param4;
+    *(mr->rdParm + 1) = param3;
+    *(mr->rdParm + 2) = param2;
+    *(mr->rdParm + 3) = param1;
+    return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MFDRV_MetaParam6
+ */
+
+BOOL MFDRV_MetaParam6(DC *dc, short func, short param1, short param2, 
+		      short param3, short param4, short param5, short param6)
+{
+    char buffer[18];
+    METARECORD *mr = (METARECORD *)&buffer;
+    
+    mr->rdSize = 9;
+    mr->rdFunction = func;
+    *(mr->rdParm) = param6;
+    *(mr->rdParm + 1) = param5;
+    *(mr->rdParm + 2) = param4;
+    *(mr->rdParm + 3) = param3;
+    *(mr->rdParm + 4) = param2;
+    *(mr->rdParm + 5) = param1;
+    return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MFDRV_MetaParam8
+ */
+BOOL MFDRV_MetaParam8(DC *dc, short func, short param1, short param2, 
+		      short param3, short param4, short param5,
+		      short param6, short param7, short param8)
+{
+    char buffer[22];
+    METARECORD *mr = (METARECORD *)&buffer;
+    
+    mr->rdSize = 11;
+    mr->rdFunction = func;
+    *(mr->rdParm) = param8;
+    *(mr->rdParm + 1) = param7;
+    *(mr->rdParm + 2) = param6;
+    *(mr->rdParm + 3) = param5;
+    *(mr->rdParm + 4) = param4;
+    *(mr->rdParm + 5) = param3;
+    *(mr->rdParm + 6) = param2;
+    *(mr->rdParm + 7) = param1;
+    return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MFDRV_AddHandleDC
+ *
+ * Note: this function assumes that we never delete objects.
+ * If we do someday, we'll need to maintain a table to re-use deleted
+ * handles.
+ */
+int MFDRV_AddHandleDC( DC *dc )
+{
+    METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
+    physDev->mh->mtNoObjects++;
+    return physDev->nextHandle++;
+}
+
+
+
+
+
+
+
+
+
 /********************************************************************
 
        Enhanced Metafile driver initializations
diff --git a/graphics/metafiledrv/mapping.c b/graphics/metafiledrv/mapping.c
index d49b5029fcab10da0b06bdc3cb308647d39b3e88..497ca26f364ab6c1eb8bba17aa6d48ca30cb6584 100644
--- a/graphics/metafiledrv/mapping.c
+++ b/graphics/metafiledrv/mapping.c
@@ -5,7 +5,6 @@
  */
 
 #include "gdi.h"
-#include "metafile.h"
 #include "metafiledrv.h"
 
 
@@ -15,7 +14,7 @@
 INT MFDRV_SetMapMode( DC *dc, INT mode )
 {
     INT prevMode = dc->w.MapMode;
-    MF_MetaParam1( dc, META_SETMAPMODE, mode );
+    MFDRV_MetaParam1( dc, META_SETMAPMODE, mode );
     return prevMode;
 }
 
@@ -25,7 +24,7 @@ INT MFDRV_SetMapMode( DC *dc, INT mode )
  */
 BOOL MFDRV_SetViewportExt( DC *dc, INT x, INT y )
 {
-    MF_MetaParam2( dc, META_SETVIEWPORTEXT, x, y );
+    MFDRV_MetaParam2( dc, META_SETVIEWPORTEXT, x, y );
     return TRUE;
 }
 
@@ -35,7 +34,7 @@ BOOL MFDRV_SetViewportExt( DC *dc, INT x, INT y )
  */
 BOOL MFDRV_SetViewportOrg( DC *dc, INT x, INT y )
 {
-    MF_MetaParam2( dc, META_SETVIEWPORTORG, x, y );
+    MFDRV_MetaParam2( dc, META_SETVIEWPORTORG, x, y );
     return TRUE;
 }
 
@@ -45,7 +44,7 @@ BOOL MFDRV_SetViewportOrg( DC *dc, INT x, INT y )
  */
 BOOL MFDRV_SetWindowExt( DC *dc, INT x, INT y )
 {
-    MF_MetaParam2( dc, META_SETWINDOWEXT, x, y );
+    MFDRV_MetaParam2( dc, META_SETWINDOWEXT, x, y );
     return TRUE;
 }
 
@@ -55,7 +54,7 @@ BOOL MFDRV_SetWindowExt( DC *dc, INT x, INT y )
  */
 BOOL MFDRV_SetWindowOrg( DC *dc, INT x, INT y )
 {
-    MF_MetaParam2( dc, META_SETWINDOWORG, x, y );
+    MFDRV_MetaParam2( dc, META_SETWINDOWORG, x, y );
     return TRUE;
 }
 
@@ -65,7 +64,7 @@ BOOL MFDRV_SetWindowOrg( DC *dc, INT x, INT y )
  */
 BOOL MFDRV_OffsetViewportOrg( DC *dc, INT x, INT y )
 {
-    MF_MetaParam2( dc, META_OFFSETVIEWPORTORG, x, y );
+    MFDRV_MetaParam2( dc, META_OFFSETVIEWPORTORG, x, y );
     return TRUE;
 }
 
@@ -75,7 +74,7 @@ BOOL MFDRV_OffsetViewportOrg( DC *dc, INT x, INT y )
  */
 BOOL MFDRV_OffsetWindowOrg( DC *dc, INT x, INT y )
 {
-    MF_MetaParam2( dc, META_OFFSETWINDOWORG, x, y );
+    MFDRV_MetaParam2( dc, META_OFFSETWINDOWORG, x, y );
     return TRUE;
 }
 
@@ -86,7 +85,7 @@ BOOL MFDRV_OffsetWindowOrg( DC *dc, INT x, INT y )
 BOOL MFDRV_ScaleViewportExt( DC *dc, INT xNum, INT xDenom,
                                INT yNum, INT yDenom )
 {
-    MF_MetaParam4( dc, META_SCALEVIEWPORTEXT, xNum, xDenom, yNum, yDenom );
+    MFDRV_MetaParam4( dc, META_SCALEVIEWPORTEXT, xNum, xDenom, yNum, yDenom );
     return TRUE;
 }
 
@@ -97,6 +96,7 @@ BOOL MFDRV_ScaleViewportExt( DC *dc, INT xNum, INT xDenom,
 BOOL MFDRV_ScaleWindowExt( DC *dc, INT xNum, INT xDenom,
                              INT yNum, INT yDenom )
 {
-    MF_MetaParam4( dc, META_SCALEWINDOWEXT, xNum, xDenom, yNum, yDenom );
+    MFDRV_MetaParam4( dc, META_SCALEWINDOWEXT, xNum, xDenom, yNum, yDenom );
     return TRUE;
 }
+
diff --git a/graphics/metafiledrv/objects.c b/graphics/metafiledrv/objects.c
index 3e52734f4f07f652989c4a1605bb3f7ade7d4a1d..ebdb49d07bb765bfbc5ee974067a3e752c8a2054 100644
--- a/graphics/metafiledrv/objects.c
+++ b/graphics/metafiledrv/objects.c
@@ -9,11 +9,10 @@
 #include "bitmap.h"
 #include "brush.h"
 #include "font.h"
-#include "metafile.h"
 #include "metafiledrv.h"
 #include "pen.h"
 #include "debug.h"
-
+#include "heap.h"
 
 /***********************************************************************
  *           MFDRV_BITMAP_SelectObject
@@ -25,6 +24,121 @@ static HBITMAP16 MFDRV_BITMAP_SelectObject( DC * dc, HBITMAP16 hbitmap,
 }
 
 
+/******************************************************************
+ *         MFDRV_CreateBrushIndirect
+ */
+
+static BOOL MFDRV_CreateBrushIndirect(DC *dc, HBRUSH16 hBrush,
+				      LOGBRUSH16 *logbrush)
+{
+    int index;
+    char buffer[sizeof(METARECORD) - 2 + sizeof(*logbrush)];
+    METARECORD *mr = (METARECORD *)&buffer;
+
+    mr->rdSize = (sizeof(METARECORD) + sizeof(*logbrush) - 2) / 2;
+    mr->rdFunction = META_CREATEBRUSHINDIRECT;
+    memcpy(&(mr->rdParm), logbrush, sizeof(*logbrush));
+    if (!(MFDRV_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
+
+    mr->rdSize = sizeof(METARECORD) / 2;
+    mr->rdFunction = META_SELECTOBJECT;
+
+    if ((index = MFDRV_AddHandleDC( dc )) == -1) return FALSE;
+    *(mr->rdParm) = index;
+    return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MFDRV_CreatePatternBrush
+ */
+static BOOL MFDRV_CreatePatternBrush(DC *dc, HBRUSH16 hBrush,
+				     LOGBRUSH16 *logbrush)
+{
+    DWORD len, bmSize, biSize;
+    METARECORD *mr;
+    BITMAPINFO *info;
+    int index;
+    char buffer[sizeof(METARECORD)];
+
+    switch (logbrush->lbStyle)
+    {
+    case BS_PATTERN:
+        {
+	    BITMAP bm;
+	    BYTE *bits;
+
+	    GetObjectA(logbrush->lbHatch, sizeof(bm), &bm);
+	    if(bm.bmBitsPixel != 1 || bm.bmPlanes != 1) {
+	        FIXME(metafile, "Trying to store a colour pattern brush\n");
+		return FALSE;
+	    }
+
+	    bmSize = bm.bmHeight * DIB_GetDIBWidthBytes(bm.bmWidth, 1);
+
+	    len = sizeof(METARECORD) +  sizeof(WORD) + sizeof(BITMAPINFO) + 
+	      sizeof(RGBQUAD) + bmSize;
+	     
+	    mr = HeapAlloc(SystemHeap, HEAP_ZERO_MEMORY, len);
+	    if(!mr) return FALSE;
+	    mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
+	    mr->rdSize = len / 2;
+	    mr->rdParm[0] = BS_PATTERN;
+	    mr->rdParm[1] = DIB_RGB_COLORS;
+	    info = (BITMAPINFO *)(mr->rdParm + 2);
+
+	    info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+	    info->bmiHeader.biWidth = bm.bmWidth;
+	    info->bmiHeader.biHeight = bm.bmHeight;
+	    info->bmiHeader.biPlanes = 1;
+	    info->bmiHeader.biBitCount = 1;
+	    bits = ((BYTE *)info) + sizeof(BITMAPINFO) + sizeof(RGBQUAD);
+
+	    GetDIBits(dc->hSelf, logbrush->lbHatch, 0, bm.bmHeight, bits,
+		      info, DIB_RGB_COLORS);
+	    *(DWORD *)info->bmiColors = 0;
+	    *(DWORD *)(info->bmiColors + 1) = 0xffffff;
+	    break;
+	}
+
+    case BS_DIBPATTERN:
+	info = (BITMAPINFO *)GlobalLock16((HGLOBAL16)logbrush->lbHatch);
+	if (info->bmiHeader.biCompression)
+            bmSize = info->bmiHeader.biSizeImage;
+        else
+	    bmSize = DIB_GetDIBWidthBytes(info->bmiHeader.biWidth,
+					  info->bmiHeader.biBitCount) 
+	               * info->bmiHeader.biHeight;
+	biSize = DIB_BitmapInfoSize(info, LOWORD(logbrush->lbColor)); 
+	len = sizeof(METARECORD) + biSize + bmSize + 2;
+	mr = HeapAlloc(SystemHeap, HEAP_ZERO_MEMORY, len);
+	if(!mr) return FALSE;
+	mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
+	mr->rdSize = len / 2;
+	*(mr->rdParm) = logbrush->lbStyle;
+	*(mr->rdParm + 1) = LOWORD(logbrush->lbColor);
+	memcpy(mr->rdParm + 2, info, biSize + bmSize);
+	break;
+    default:
+        return FALSE;
+    }
+    if (!(MFDRV_WriteRecord(dc, mr, len)))
+    {
+	HeapFree(SystemHeap, 0, mr);
+	return FALSE;
+    }
+
+    HeapFree(SystemHeap, 0, mr);
+    
+    mr = (METARECORD *)&buffer;
+    mr->rdSize = sizeof(METARECORD) / 2;
+    mr->rdFunction = META_SELECTOBJECT;
+
+    if ((index = MFDRV_AddHandleDC( dc )) == -1) return FALSE;
+    *(mr->rdParm) = index;
+    return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
+}
+
 /***********************************************************************
  *           MFDRV_BRUSH_SelectObject
  */
@@ -39,16 +153,39 @@ static HBRUSH MFDRV_BRUSH_SelectObject( DC * dc, HBRUSH hbrush,
     case BS_SOLID:
     case BS_HATCHED:
     case BS_HOLLOW:
-        if (!MF_CreateBrushIndirect( dc, hbrush, &logbrush )) return 0;
+        if (!MFDRV_CreateBrushIndirect( dc, hbrush, &logbrush )) return 0;
         break;
     case BS_PATTERN:
     case BS_DIBPATTERN:
-        if (!MF_CreatePatternBrush( dc, hbrush, &logbrush )) return 0;
+        if (!MFDRV_CreatePatternBrush( dc, hbrush, &logbrush )) return 0;
         break;
     }
     return 1;  /* FIXME? */
 }
 
+/******************************************************************
+ *         MFDRV_CreateFontIndirect
+ */
+
+static BOOL MFDRV_CreateFontIndirect(DC *dc, HFONT16 hFont, LOGFONT16 *logfont)
+{
+    int index;
+    char buffer[sizeof(METARECORD) - 2 + sizeof(LOGFONT16)];
+    METARECORD *mr = (METARECORD *)&buffer;
+
+    mr->rdSize = (sizeof(METARECORD) + sizeof(LOGFONT16) - 2) / 2;
+    mr->rdFunction = META_CREATEFONTINDIRECT;
+    memcpy(&(mr->rdParm), logfont, sizeof(LOGFONT16));
+    if (!(MFDRV_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
+
+    mr->rdSize = sizeof(METARECORD) / 2;
+    mr->rdFunction = META_SELECTOBJECT;
+
+    if ((index = MFDRV_AddHandleDC( dc )) == -1) return FALSE;
+    *(mr->rdParm) = index;
+    return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
+}
+
 
 /***********************************************************************
  *           MFDRV_FONT_SelectObject
@@ -57,10 +194,33 @@ static HFONT16 MFDRV_FONT_SelectObject( DC * dc, HFONT16 hfont,
                                         FONTOBJ * font )
 {
     HFONT16 prevHandle = dc->w.hFont;
-    if (MF_CreateFontIndirect(dc, hfont, &(font->logfont))) return prevHandle;
+    if (MFDRV_CreateFontIndirect(dc, hfont, &(font->logfont)))
+        return prevHandle;
     return 0;
 }
 
+/******************************************************************
+ *         MFDRV_CreatePenIndirect
+ */
+static BOOL MFDRV_CreatePenIndirect(DC *dc, HPEN16 hPen, LOGPEN16 *logpen)
+{
+    int index;
+    char buffer[sizeof(METARECORD) - 2 + sizeof(*logpen)];
+    METARECORD *mr = (METARECORD *)&buffer;
+
+    mr->rdSize = (sizeof(METARECORD) + sizeof(*logpen) - 2) / 2;
+    mr->rdFunction = META_CREATEPENINDIRECT;
+    memcpy(&(mr->rdParm), logpen, sizeof(*logpen));
+    if (!(MFDRV_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
+
+    mr->rdSize = sizeof(METARECORD) / 2;
+    mr->rdFunction = META_SELECTOBJECT;
+
+    if ((index = MFDRV_AddHandleDC( dc )) == -1) return FALSE;
+    *(mr->rdParm) = index;
+    return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
+}
+
 
 /***********************************************************************
  *           MFDRV_PEN_SelectObject
@@ -71,7 +231,7 @@ static HPEN MFDRV_PEN_SelectObject( DC * dc, HPEN hpen, PENOBJ * pen )
     LOGPEN16 logpen = { pen->logpen.lopnStyle,
                         { pen->logpen.lopnWidth.x, pen->logpen.lopnWidth.y },
                         pen->logpen.lopnColor };
-    if (MF_CreatePenIndirect( dc, hpen, &logpen )) return prevHandle;
+    if (MFDRV_CreatePenIndirect( dc, hpen, &logpen )) return prevHandle;
     return 0;
 }
 
@@ -108,3 +268,5 @@ HGDIOBJ MFDRV_SelectObject( DC *dc, HGDIOBJ handle )
     GDI_HEAP_UNLOCK( handle );
     return ret;
 }
+
+
diff --git a/graphics/metafiledrv/text.c b/graphics/metafiledrv/text.c
index ffee2a616f9974be17dc9100c200ec0502162aa6..2f155dddad24cd948c8f893494d53341a63ef23b 100644
--- a/graphics/metafiledrv/text.c
+++ b/graphics/metafiledrv/text.c
@@ -5,11 +5,50 @@
  *
  */
 
-#include <stdlib.h>
 #include "windef.h"
-#include "metafile.h"
+#include "metafiledrv.h"
 #include "debug.h"
-#include "xmalloc.h"
+#include "heap.h"
+
+
+/******************************************************************
+ *         MFDRV_MetaExtTextOut
+ */
+static BOOL MFDRV_MetaExtTextOut(DC*dc, short x, short y, UINT16 flags,
+				 const RECT16 *rect, LPCSTR str, short count,
+				 const INT16 *lpDx)
+{
+    BOOL ret;
+    DWORD len;
+    METARECORD *mr;
+    
+    if((!flags && rect) || (flags && !rect))
+	WARN(metafile, "Inconsistent flags and rect\n");
+    len = sizeof(METARECORD) + (((count + 1) >> 1) * 2) + 2 * sizeof(short)
+	    + sizeof(UINT16);
+    if(rect)
+        len += sizeof(RECT16);
+    if (lpDx)
+     len+=count*sizeof(INT16);
+    if (!(mr = HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY, len)))
+	return FALSE;
+
+    mr->rdSize = len / 2;
+    mr->rdFunction = META_EXTTEXTOUT;
+    *(mr->rdParm) = y;
+    *(mr->rdParm + 1) = x;
+    *(mr->rdParm + 2) = count;
+    *(mr->rdParm + 3) = flags;
+    if (rect) memcpy(mr->rdParm + 4, rect, sizeof(RECT16));
+    memcpy(mr->rdParm + (rect ? 8 : 4), str, count);
+    if (lpDx)
+     memcpy(mr->rdParm + (rect ? 8 : 4) + ((count + 1) >> 1),lpDx,
+      count*sizeof(INT16));
+    ret = MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
+    HeapFree( SystemHeap, 0, mr);
+    return ret;
+}
+
 
 
 /***********************************************************************
@@ -21,13 +60,21 @@ MFDRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
                   const INT *lpDx )
 {
     RECT16	rect16;
-    LPINT16	lpdx16 = lpDx?(LPINT16)xmalloc(sizeof(INT16)*count):NULL;
+    LPINT16	lpdx16 = NULL;
     BOOL	ret;
     int		i;
 
+    if(lpDx)
+        lpdx16 = HeapAlloc( SystemHeap, 0, sizeof(INT16)*count );
     if (lprect)	CONV_RECT32TO16(lprect,&rect16);
-    if (lpdx16)	for (i=count;i--;) lpdx16[i]=lpDx[i];
-    ret=MF_ExtTextOut(dc,x,y,flags,lprect?&rect16:NULL,str,count,lpdx16);
-    if (lpdx16)	free(lpdx16);
+    if (lpdx16)
+        for (i=count;i--;)
+	    lpdx16[i]=lpDx[i];
+    ret = MFDRV_MetaExtTextOut(dc,x,y,flags,lprect?&rect16:NULL,str,count,
+			       lpdx16);
+    if (lpdx16)	HeapFree( SystemHeap, 0, lpdx16 );
     return ret;
 }
+
+
+
diff --git a/include/metafile.h b/include/metafile.h
index 1abef44c8b48c6526a61fd1a3d4d4a8a199db646..ae2f952346b7ccf44197bbf0ba622dcc271c71a3 100644
--- a/include/metafile.h
+++ b/include/metafile.h
@@ -10,33 +10,34 @@
 #include "wingdi.h"
 #include "gdi.h"
 
+  /* GDI32 metafile object */
+typedef struct
+{
+    GDIOBJHDR   header;
+    METAHEADER  *mh;
+} METAFILEOBJ;
+
+#pragma pack(1)
+typedef struct {
+    DWORD dw1, dw2, dw3;
+    WORD w4;
+    CHAR filename[0x100];
+} METAHEADERDISK;
+#pragma pack(4)
+
 #define MFHEADERSIZE (sizeof(METAHEADER))
 #define MFVERSION 0x300
 #define META_EOF 0x0000
 
-BOOL MF_MetaParam0(DC *dc, short func);
-BOOL MF_MetaParam1(DC *dc, short func, short param1);
-BOOL MF_MetaParam2(DC *dc, short func, short param1, short param2);
-BOOL MF_MetaParam4(DC *dc, short func, short param1, short param2, 
-		   short param3, short param4);
-BOOL MF_MetaParam6(DC *dc, short func, short param1, short param2, 
-		   short param3, short param4, short param5, short param6);
-BOOL MF_MetaParam8(DC *dc, short func, short param1, short param2, 
-		   short param3, short param4, short param5,
-		   short param6, short param7, short param8);
-BOOL MF_CreateBrushIndirect(DC *dc, HBRUSH16 hBrush, LOGBRUSH16 *logbrush);
-BOOL MF_CreatePatternBrush(DC *dc, HBRUSH16 hBrush, LOGBRUSH16 *logbrush);
-BOOL MF_CreatePenIndirect(DC *dc, HPEN16 hPen, LOGPEN16 *logpen);
-BOOL MF_CreateFontIndirect(DC *dc, HFONT16 hFont, LOGFONT16 *logfont);
-BOOL MF_TextOut(DC *dc, short x, short y, LPCSTR str, short count);
-BOOL MF_ExtTextOut(DC *dc, short x, short y, UINT16 flags, const RECT16 *rect,
-                   LPCSTR str, short count, const INT16 *lpDx);
-BOOL MF_MetaPoly(DC *dc, short func, LPPOINT16 pt, short count);
-BOOL MF_BitBlt(DC *dcDest, short xDest, short yDest, short width,
-	       short height, DC *dcSrc, short xSrc, short ySrc, DWORD rop);
-BOOL MF_StretchBlt(DC *dcDest, short xDest, short yDest, short widthDest,
-		   short heightDest, DC *dcSrc, short xSrc, short ySrc, 
-		   short widthSrc, short heightSrc, DWORD rop);
-INT16 MF_CreateRegion(DC *dc, HRGN hrgn);
+
+/* values of mtType in METAHEADER.  Note however that the disk image of a disk
+   based metafile has mtType == 1 */
+#define METAFILE_MEMORY 1
+#define METAFILE_DISK   2
+
+extern HMETAFILE MF_Create_HMETAFILE(METAHEADER *mh);
+extern HMETAFILE16 MF_Create_HMETAFILE16(METAHEADER *mh);
+extern METAHEADER *MF_CreateMetaHeaderDisk(METAHEADER *mr, LPCSTR filename);
+
 #endif   /* __WINE_METAFILE_H */
 
diff --git a/include/metafiledrv.h b/include/metafiledrv.h
index 29048d1c2e3f890e1f3afadd6df14c0b6c0ed8f7..96cb1c6a07353b1ea456131bbb1c64e6d3c72197 100644
--- a/include/metafiledrv.h
+++ b/include/metafiledrv.h
@@ -8,20 +8,30 @@
 #include "wingdi.h"
 #include "gdi.h"
 
-/* FIXME: SDK docs says these should be 1 and 2 */
-/*  DR 980322: most wmf's have 1, so I think 0 and 1 is correct */
-#define METAFILE_MEMORY 0
-#define METAFILE_DISK   1
-
 /* Metafile driver physical DC */
 
 typedef struct
 {
     METAHEADER  *mh;           /* Pointer to metafile header */
-    UINT       nextHandle;   /* Next handle number */
+    UINT       nextHandle;     /* Next handle number */
+    HFILE      hFile;          /* HFILE for disk based MetaFile */ 
 } METAFILEDRV_PDEVICE;
 
 
+extern BOOL MFDRV_MetaParam0(DC *dc, short func);
+extern BOOL MFDRV_MetaParam1(DC *dc, short func, short param1);
+extern BOOL MFDRV_MetaParam2(DC *dc, short func, short param1, short param2);
+extern BOOL MFDRV_MetaParam4(DC *dc, short func, short param1, short param2, 
+			     short param3, short param4);
+extern BOOL MFDRV_MetaParam6(DC *dc, short func, short param1, short param2, 
+			     short param3, short param4, short param5,
+			     short param6);
+extern BOOL MFDRV_MetaParam8(DC *dc, short func, short param1, short param2, 
+			     short param3, short param4, short param5,
+			     short param6, short param7, short param8);
+extern BOOL MFDRV_WriteRecord(DC *dc, METARECORD *mr, DWORD rlen);
+extern int MFDRV_AddHandleDC( DC *dc );
+
 /* Metafile driver functions */
 
 extern BOOL MFDRV_BitBlt( struct tagDC *dcDst, INT xDst, INT yDst,
diff --git a/objects/clipping.c b/objects/clipping.c
index 428aa272169235de875485e9c37efc4877ea19f6..a6d623fa37ad5f4175509fbbbecb9d57e6859422 100644
--- a/objects/clipping.c
+++ b/objects/clipping.c
@@ -6,7 +6,7 @@
 
 #include <stdlib.h>
 #include "dc.h"
-#include "metafile.h"
+#include "metafiledrv.h"
 #include "region.h"
 #include "debug.h"
 #include "wine/winuser16.h"
@@ -152,7 +152,7 @@ INT WINAPI OffsetClipRgn( HDC hdc, INT x, INT y )
     {
 	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
 	if (!dc) return ERROR;
-	MF_MetaParam2(dc, META_OFFSETCLIPRGN, x, y);
+	MFDRV_MetaParam2(dc, META_OFFSETCLIPRGN, x, y);
 	GDI_HEAP_UNLOCK( hdc );
 	return NULLREGION;   /* ?? */
     }
@@ -257,7 +257,7 @@ INT WINAPI ExcludeClipRect( HDC hdc, INT left, INT top,
     {
 	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
 	if (!dc) return ERROR;
-	MF_MetaParam4(dc, META_EXCLUDECLIPRECT, left, top, right, bottom);
+	MFDRV_MetaParam4(dc, META_EXCLUDECLIPRECT, left, top, right, bottom);
 	GDI_HEAP_UNLOCK( hdc );
 	return NULLREGION;   /* ?? */
     }
@@ -297,7 +297,7 @@ INT WINAPI IntersectClipRect( HDC hdc, INT left, INT top,
     {
 	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
 	if (!dc) return ERROR;
-	MF_MetaParam4(dc, META_INTERSECTCLIPRECT, left, top, right, bottom);
+	MFDRV_MetaParam4(dc, META_INTERSECTCLIPRECT, left, top, right, bottom);
 	GDI_HEAP_UNLOCK( hdc );
 	return NULLREGION;   /* ?? */
     }
diff --git a/objects/dc.c b/objects/dc.c
index fc10681aaf5e5af2a30822a862d5752328d4af5a..5f8a41fa0c6ee7cc635fb5c4ae97d6d9adc3f4b9 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -15,7 +15,7 @@
 #include "dc.h"
 #include "gdi.h"
 #include "heap.h"
-#include "metafile.h"
+#include "metafiledrv.h"
 #include "debug.h"
 #include "font.h"
 #include "winerror.h"
@@ -410,7 +410,7 @@ INT WINAPI SaveDC( HDC hdc )
     {
 	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
 	if (!dc) return 0;
-	MF_MetaParam0(dc, META_SAVEDC);
+	MFDRV_MetaParam0(dc, META_SAVEDC);
 	GDI_HEAP_UNLOCK( hdc );
 	return 1;  /* ?? */
     }
@@ -473,7 +473,7 @@ BOOL WINAPI RestoreDC( HDC hdc, INT level )
 	  GDI_HEAP_UNLOCK( hdc );
 	  return FALSE;
 	}
-	MF_MetaParam1(dc, META_RESTOREDC, level);
+	MFDRV_MetaParam1(dc, META_RESTOREDC, level);
 	GDI_HEAP_UNLOCK( hdc );
 	return TRUE;
     }
@@ -841,7 +841,7 @@ UINT WINAPI SetTextAlign( HDC hdc, UINT textAlign )
     if (!dc)
     {
 	if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC ))) return 0;
-	MF_MetaParam1( dc, META_SETTEXTALIGN, textAlign );
+	MFDRV_MetaParam1( dc, META_SETTEXTALIGN, textAlign );
 	GDI_HEAP_UNLOCK( hdc );
 	return 1;
     }
diff --git a/objects/dcvalues.c b/objects/dcvalues.c
index b1c6076025955c01cc09172aa5afc6803860e0d6..89e5fea9c67f7d63a457196f158165a94b7c1984 100644
--- a/objects/dcvalues.c
+++ b/objects/dcvalues.c
@@ -6,7 +6,7 @@
  */
 
 #include "gdi.h"
-#include "metafile.h"
+#include "metafiledrv.h"
 
 
 #define DC_GET_VAL_16( func_type, func_name, dc_field ) \
@@ -65,7 +65,7 @@ INT16 WINAPI func_name( HDC16 hdc, INT16 mode ) \
     if (!dc) { \
 	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC); \
 	if (!dc) return 0; \
-	MF_MetaParam1(dc, meta_func, mode); \
+	MFDRV_MetaParam1(dc, meta_func, mode); \
 	return 1; \
     } \
     prevMode = dc->dc_field; \
@@ -82,7 +82,7 @@ INT WINAPI func_name( HDC hdc, INT mode ) \
     if (!dc) { \
 	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC); \
 	if (!dc) return 0; \
-	MF_MetaParam1(dc, meta_func, mode); \
+	MFDRV_MetaParam1(dc, meta_func, mode); \
 	return 1; \
     } \
     prevMode = dc->dc_field; \
diff --git a/objects/metafile.c b/objects/metafile.c
index 3f7f13bb99ab9879e0eacffaf4d2888d72dea029..8f35e12bc5e5e5469e52774f361b9d108732054e 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -6,22 +6,46 @@
  *
  */
 
+/*
+ * These functions are primarily involved with metafile playback or anything
+ * that touches a HMETAFILE.
+ * For recording of metafiles look in graphics/metafiledrv/
+ *
+ * Note that (32 bit) HMETAFILEs are GDI objects, while HMETAFILE16s are 
+ * global memory handles so these cannot be interchanged.
+ *
+ * Memory-based metafiles are just stored as a continuous block of memory with
+ * a METAHEADER at the head with METARECORDs appended to it.  mtType is
+ * METAFILE_MEMORY (1).  Note this is indentical to the disk image of a
+ * disk-based metafile - even mtType is METAFILE_MEMORY.
+ * 16bit HMETAFILE16s are global handles to this block
+ * 32bit HMETAFILEs are GDI handles METAFILEOBJs, which contains a ptr to
+ * the memory.
+ * Disk-based metafiles are rather different. HMETAFILE16s point to a
+ * METAHEADER which has mtType equal to METAFILE_DISK (2).  Following the 9
+ * WORDs of the METAHEADER there are a further 3 WORDs of 0, 1 of 0x117, 1
+ * more 0, then 2 which may be a time stamp of the file and then the path of
+ * the file (METAHEADERDISK). I've copied this for 16bit compatibility.
+ *
+ * HDMD - 14/4/1999
+ */  
+
+
 #include <string.h>
 #include <fcntl.h>
 #include "wine/winbase16.h"
-#include "metafiledrv.h"
 #include "metafile.h"
 #include "bitmap.h"
 #include "heap.h"
 #include "toolhelp.h"
 #include "debug.h"
+#include "global.h"
 
 /******************************************************************
  *         MF_AddHandle
  *
  *    Add a handle to an external handle table and return the index
  */
-
 static int MF_AddHandle(HANDLETABLE16 *ht, WORD htlen, HGDIOBJ16 hobj)
 {
     int i;
@@ -39,129 +63,307 @@ static int MF_AddHandle(HANDLETABLE16 *ht, WORD htlen, HGDIOBJ16 hobj)
 
 
 /******************************************************************
- *         MF_AddHandleDC
+ *         MF_Create_HMETATFILE
+ *
+ * Creates a (32 bit) HMETAFILE object from a METAHEADER
+ *
+ * HMETAFILEs are GDI objects.
+ */
+HMETAFILE MF_Create_HMETAFILE(METAHEADER *mh)
+{
+    HMETAFILE hmf = GDI_AllocObject( sizeof(METAFILEOBJ), METAFILE_MAGIC );
+    METAFILEOBJ *metaObj = (METAFILEOBJ *)GDI_HEAP_LOCK( hmf );
+    metaObj->mh = mh;
+    GDI_HEAP_UNLOCK( hmf );
+    return hmf;
+}
+
+/******************************************************************
+ *         MF_Create_HMETATFILE16
+ *
+ * Creates a HMETAFILE16 object from a METAHEADER
+ *
+ * HMETAFILE16s are Global memory handles.
+ */
+HMETAFILE16 MF_Create_HMETAFILE16(METAHEADER *mh)
+{
+    HMETAFILE16 hmf;
+    DWORD size;
+
+    if(mh->mtType == METAFILE_MEMORY)
+        size = mh->mtSize * sizeof(WORD);
+    else
+        size = sizeof(METAHEADER) + sizeof(METAHEADERDISK);
+
+    hmf = GLOBAL_CreateBlock( GMEM_MOVEABLE, mh, mh->mtSize * sizeof(WORD),
+                              GetCurrentPDB16(), FALSE, FALSE, FALSE, NULL );
+    return hmf;
+}
+
+/******************************************************************
+ *         MF_GetMetaHeader
+ *
+ * Returns ptr to METAHEADER associated with HMETAFILE
+ * Should be followed by call to MF_ReleaseMetaHeader
+ */
+static METAHEADER *MF_GetMetaHeader( HMETAFILE hmf )
+{
+    METAFILEOBJ *metaObj = (METAFILEOBJ *)GDI_GetObjPtr( hmf, METAFILE_MAGIC );
+    return metaObj->mh;
+}
+
+/******************************************************************
+ *         MF_GetMetaHeader16
+ *
+ * Returns ptr to METAHEADER associated with HMETAFILE16
+ * Should be followed by call to MF_ReleaseMetaHeader16
+ */
+static METAHEADER *MF_GetMetaHeader16( HMETAFILE16 hmf )
+{
+    return GlobalLock16(hmf);
+}
+
+/******************************************************************
+ *         MF_ReleaseMetaHeader
+ *
+ * Releases METAHEADER associated with HMETAFILE
+ */
+static BOOL MF_ReleaseMetaHeader( HMETAFILE hmf )
+{
+    return GDI_HEAP_UNLOCK( hmf );
+}
+
+/******************************************************************
+ *         MF_ReleaseMetaHeader16
  *
- * Note: this function assumes that we never delete objects.
- * If we do someday, we'll need to maintain a table to re-use deleted
- * handles.
+ * Releases METAHEADER associated with HMETAFILE16
  */
-static int MF_AddHandleDC( DC *dc )
+static BOOL16 MF_ReleaseMetaHeader16( HMETAFILE16 hmf )
 {
-    METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
-    physDev->mh->mtNoObjects++;
-    return physDev->nextHandle++;
+    return GlobalUnlock16( hmf );
 }
 
 
+/******************************************************************
+ *	     DeleteMetaFile16   (GDI.127)
+ */
+BOOL16 WINAPI DeleteMetaFile16(  HMETAFILE16 hmf )
+{
+    return !GlobalFree16( hmf );
+}
+
+/******************************************************************
+ *          DeleteMetaFile  (GDI32.69)
+ *
+ *  Delete a memory-based metafile.
+ */
+
+BOOL WINAPI DeleteMetaFile( HMETAFILE hmf )
+{
+    METAHEADER *mh = MF_GetMetaHeader( hmf );
+
+    if(!mh) return FALSE;
+    HeapFree( SystemHeap, 0, mh );
+    GDI_FreeObject( hmf );
+    return TRUE;
+}
+
+/******************************************************************
+ *         MF_ReadMetaFile
+ *
+ * Returns a pointer to a memory based METAHEADER read in from file HFILE
+ *
+ */
+static METAHEADER *MF_ReadMetaFile(HFILE hfile)
+{
+    METAHEADER *mh;
+    DWORD BytesRead, size;
+
+    size = sizeof(METAHEADER);
+    mh = HeapAlloc( SystemHeap, 0, size );
+    if(!mh) return NULL;
+    if(ReadFile( hfile, mh, size, &BytesRead, NULL) == 0 ||
+       BytesRead != size) {
+        HeapFree( SystemHeap, 0, mh );
+	return NULL;
+    }
+    size = mh->mtSize * 2;
+    mh = HeapReAlloc( SystemHeap, 0, mh, size );
+    if(!mh) return NULL;
+    size -= sizeof(METAHEADER);
+    if(ReadFile( hfile, (char *)mh + sizeof(METAHEADER), size, &BytesRead,
+		 NULL) == 0 ||
+       BytesRead != size) {
+        HeapFree( SystemHeap, 0, mh );
+	return NULL;
+    }
+
+    if (mh->mtType != METAFILE_MEMORY) {
+        WARN(metafile, "Disk metafile had mtType = %04x\n", mh->mtType);
+	mh->mtType = METAFILE_MEMORY;
+    }
+    return mh;
+}
+
 /******************************************************************
  *         GetMetaFile16   (GDI.124)
  */
 HMETAFILE16 WINAPI GetMetaFile16( LPCSTR lpFilename )
 {
-    return GetMetaFileA( lpFilename );
-}
+    METAHEADER *mh;
+    HFILE hFile;
+ 
+    TRACE(metafile,"%s\n", lpFilename);
+
+    if(!lpFilename)
+        return 0;
 
+    if((hFile = CreateFileA(lpFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
+			    0, -1)) == HFILE_ERROR)
+        return 0;
+
+    mh = MF_ReadMetaFile(hFile);
+    CloseHandle(hFile);
+    if(!mh) return 0;
+    return MF_Create_HMETAFILE16( mh );
+}
 
 /******************************************************************
- *         GetMetaFile32A   (GDI32.197)
+ *         GetMetaFileA   (GDI32.197)
  *
- *  Read a metafile from a file. Returns handle to a disk-based metafile.
+ *  Read a metafile from a file. Returns handle to a memory-based metafile.
  */
-HMETAFILE WINAPI GetMetaFileA( 
-				  LPCSTR lpFilename 
-		      /* pointer to string containing filename to read */
-)
+HMETAFILE WINAPI GetMetaFileA( LPCSTR lpFilename )
 {
-  HMETAFILE16 hmf;
-  METAHEADER *mh;
-  HFILE hFile;
-  DWORD size;
-  
-  TRACE(metafile,"%s\n", lpFilename);
-
-  if (!lpFilename)
-    return 0;
-
-  hmf = GlobalAlloc16(GMEM_MOVEABLE, MFHEADERSIZE);
-  mh = (METAHEADER *)GlobalLock16(hmf);
-  
-  if (!mh)
-  {
-    GlobalFree16(hmf);
-    return 0;
-  }
-  
-  if ((hFile = _lopen(lpFilename, OF_READ)) == HFILE_ERROR)
-  {
-    GlobalFree16(hmf);
-    return 0;
-  }
-  
-  if (_lread(hFile, (char *)mh, MFHEADERSIZE) == HFILE_ERROR)
-  {
-    _lclose( hFile );
-    GlobalFree16(hmf);
-    return 0;
-  }
-  
-  size = mh->mtSize * 2;         /* alloc memory for whole metafile */
-  GlobalUnlock16(hmf);
-  hmf = GlobalReAlloc16(hmf,size,GMEM_MOVEABLE);
-  mh = (METAHEADER *)GlobalLock16(hmf);
-  
-  if (!mh)
-  {
-    _lclose( hFile );
-    GlobalFree16(hmf);
-    return 0;
-  }
-  
-  if (_lread(hFile, (char*)mh + mh->mtHeaderSize * 2, 
-	        size - mh->mtHeaderSize * 2) == HFILE_ERROR)
-  {
-    _lclose( hFile );
-    GlobalFree16(hmf);
-    return 0;
-  }
-  
-  _lclose(hFile);
-
-  if (mh->mtType != 1)
-  {
-    GlobalFree16(hmf);
-    return 0;
-  }
-  
-  GlobalUnlock16(hmf);
-  return hmf;
+    METAHEADER *mh;
+    HFILE hFile;
+ 
+    TRACE(metafile,"%s\n", lpFilename);
+
+    if(!lpFilename)
+        return 0;
 
+    if((hFile = CreateFileA(lpFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
+			    0, -1)) == HFILE_ERROR)
+        return 0;
+
+    mh = MF_ReadMetaFile(hFile);
+    CloseHandle(hFile);
+    if(!mh) return 0;
+    return MF_Create_HMETAFILE( mh );
 }
 
 
+
 /******************************************************************
- *         GetMetaFile32W   (GDI32.199)
+ *         GetMetaFileW   (GDI32.199)
  */
 HMETAFILE WINAPI GetMetaFileW( LPCWSTR lpFilename )
 {
-    LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, lpFilename );
-    HMETAFILE ret = GetMetaFileA( p );
-    HeapFree( GetProcessHeap(), 0, p );
-    return ret;
+    METAHEADER *mh;
+    HFILE hFile;
+ 
+    TRACE(metafile,"%s\n", debugstr_w(lpFilename));
+
+    if(!lpFilename)
+        return 0;
+
+    if((hFile = CreateFileW(lpFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
+			    0, -1)) == HFILE_ERROR)
+        return 0;
+
+    mh = MF_ReadMetaFile(hFile);
+    CloseHandle(hFile);
+    if(!mh) return 0;
+    return MF_Create_HMETAFILE( mh );
 }
 
 
 /******************************************************************
- *         CopyMetaFile16   (GDI.151)
+ *         MF_LoadDiskBasedMetaFile
+ *
+ * Creates a new memory-based metafile from a disk-based one.
  */
+static METAHEADER *MF_LoadDiskBasedMetaFile(METAHEADER *mh)
+{
+    METAHEADERDISK *mhd;
+    HFILE hfile;
+    METAHEADER *mh2;
 
-HMETAFILE16 WINAPI CopyMetaFile16( HMETAFILE16 hSrcMetaFile, LPCSTR lpFilename )
+    if(mh->mtType != METAFILE_DISK) {
+        ERR(metafile, "Not a disk based metafile\n");
+	return NULL;
+    }
+    mhd = (METAHEADERDISK *)((char *)mh + sizeof(METAHEADER));
+
+    if((hfile = CreateFileA(mhd->filename, GENERIC_READ, 0, NULL,
+			    OPEN_EXISTING, 0, -1)) == HFILE_ERROR) {
+        WARN(metafile, "Can't open file of disk based metafile\n");
+        return NULL;
+    }
+    mh2 = MF_ReadMetaFile(hfile);
+    CloseHandle(hfile);
+    return mh2;
+}
+
+/******************************************************************
+ *         MF_CreateMetaHeaderDisk
+ *
+ * Take a memory based METAHEADER and change it to a disk based METAHEADER
+ * assosiated with filename.  Note: Trashes contents of old one. 
+ */
+METAHEADER *MF_CreateMetaHeaderDisk(METAHEADER *mh, LPCSTR filename)
 {
-    return CopyMetaFileA( hSrcMetaFile, lpFilename );
+    METAHEADERDISK *mhd;
+    DWORD size;
+
+    mh = HeapReAlloc( SystemHeap, 0, mh,
+		      sizeof(METAHEADER) + sizeof(METAHEADERDISK));
+    mh->mtType = METAFILE_DISK;
+    size = HeapSize( SystemHeap, 0, mh );
+    mhd = (METAHEADERDISK *)((char *)mh + sizeof(METAHEADER));
+    strcpy(mhd->filename, filename);
+    return mh;
+}
+
+/******************************************************************
+ *         CopyMetaFile16   (GDI.151)
+ */
+HMETAFILE16 WINAPI CopyMetaFile16( HMETAFILE16 hSrcMetaFile, LPCSTR lpFilename)
+{
+    METAHEADER *mh = MF_GetMetaHeader16( hSrcMetaFile );
+    METAHEADER *mh2 = NULL;
+    HFILE hFile;
+
+    TRACE(metafile,"(%08x,%s)\n", hSrcMetaFile, lpFilename);
+    
+    if(!mh) return 0;
+    
+    if(mh->mtType == METAFILE_DISK)
+        mh2 = MF_LoadDiskBasedMetaFile(mh);
+    else {
+        mh2 = HeapAlloc( SystemHeap, 0, mh->mtSize * 2 );
+        memcpy( mh2, mh, mh->mtSize * 2 );
+    }
+    MF_ReleaseMetaHeader16( hSrcMetaFile );
+
+    if(lpFilename) {         /* disk based metafile */
+        if((hFile = CreateFileA(lpFilename, GENERIC_WRITE, 0, NULL,
+				CREATE_ALWAYS, 0, -1)) == HFILE_ERROR) {
+	    HeapFree( SystemHeap, 0, mh2 );
+	    return 0;
+	}
+	WriteFile(hFile, mh2, mh2->mtSize * 2, NULL, NULL);
+	CloseHandle(hFile);
+	mh2 = MF_CreateMetaHeaderDisk(mh2, lpFilename);
+    }
+
+    return MF_Create_HMETAFILE16( mh2 );
 }
 
 
 /******************************************************************
- *         CopyMetaFile32A   (GDI32.23)
+ *         CopyMetaFileA   (GDI32.23)
  *
  *  Copies the metafile corresponding to hSrcMetaFile to either
  *  a disk file, if a filename is given, or to a new memory based
@@ -179,46 +381,39 @@ HMETAFILE WINAPI CopyMetaFileA(
 		   HMETAFILE hSrcMetaFile, /* handle of metafile to copy */
 		   LPCSTR lpFilename /* filename if copying to a file */
 ) {
-    HMETAFILE16 handle = 0;
-    METAHEADER *mh;
-    METAHEADER *mh2;
+    METAHEADER *mh = MF_GetMetaHeader( hSrcMetaFile );
+    METAHEADER *mh2 = NULL;
     HFILE hFile;
-    
+
     TRACE(metafile,"(%08x,%s)\n", hSrcMetaFile, lpFilename);
     
-    mh = (METAHEADER *)GlobalLock16(hSrcMetaFile);
+    if(!mh) return 0;
     
-    if (!mh)
-      return 0;
-    
-    if (lpFilename)          /* disk based metafile */
-        {
-        int i,j;
-	hFile = _lcreat(lpFilename, 0);
-	j=mh->mtType;
-	mh->mtType=1;        /* disk file version stores 1 here */
-	i=_lwrite(hFile, (char *)mh, mh->mtSize * 2) ;
-	mh->mtType=j;        /* restore old value  [0 or 1] */	
-        _lclose(hFile);
-	if (i == -1)
+    if(mh->mtType == METAFILE_DISK)
+        mh2 = MF_LoadDiskBasedMetaFile(mh);
+    else {
+        mh2 = HeapAlloc( SystemHeap, 0, mh->mtSize * 2 );
+        memcpy( mh2, mh, mh->mtSize * 2 );
+    }
+    MF_ReleaseMetaHeader( hSrcMetaFile );
+
+    if(lpFilename) {         /* disk based metafile */
+        if((hFile = CreateFileA(lpFilename, GENERIC_WRITE, 0, NULL,
+				CREATE_ALWAYS, 0, -1)) == HFILE_ERROR) {
+	    HeapFree( SystemHeap, 0, mh2 );
 	    return 0;
-        /* FIXME: return value */
-        }
-    else                     /* memory based metafile */
-        {
-	handle = GlobalAlloc16(GMEM_MOVEABLE,mh->mtSize * 2);
-	mh2 = (METAHEADER *)GlobalLock16(handle);
-	memcpy(mh2,mh, mh->mtSize * 2);
-	GlobalUnlock16(handle);
-        }
+	}
+	WriteFile(hFile, mh2, mh2->mtSize * 2, NULL, NULL);
+	CloseHandle(hFile);
+	mh2 = MF_CreateMetaHeaderDisk(mh2, lpFilename);
+    }
 
-    GlobalUnlock16(hSrcMetaFile);
-    return handle;
+    return MF_Create_HMETAFILE( mh2 );
 }
 
 
 /******************************************************************
- *         CopyMetaFile32W   (GDI32.24)
+ *         CopyMetaFileW   (GDI32.24)
  */
 HMETAFILE WINAPI CopyMetaFileW( HMETAFILE hSrcMetaFile,
                                     LPCWSTR lpFilename )
@@ -244,56 +439,46 @@ HMETAFILE WINAPI CopyMetaFileW( HMETAFILE hSrcMetaFile,
  *  This is not exactly what windows does, see _Undocumented_Windows_
  *  for details.
  */
-
 BOOL16 WINAPI IsValidMetaFile16(HMETAFILE16 hmf)
 {
-    BOOL16 resu=FALSE;
-    METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
+    BOOL16 res=FALSE;
+    METAHEADER *mh = MF_GetMetaHeader16(hmf);
     if (mh) {
-      if (mh->mtType == 1 || mh->mtType == 0) 
-        if (mh->mtHeaderSize == MFHEADERSIZE/sizeof(INT16))
-          if (mh->mtVersion == MFVERSION)
-            resu=TRUE;
-      GlobalUnlock16(hmf);
+        if (mh->mtType == METAFILE_MEMORY || mh->mtType == METAFILE_DISK) 
+	    if (mh->mtHeaderSize == MFHEADERSIZE/sizeof(INT16))
+	        if (mh->mtVersion == MFVERSION)
+		    res=TRUE;
+	MF_ReleaseMetaHeader16(hmf);
     }
-    TRACE(metafile,"IsValidMetaFile %x => %d\n",hmf,resu);
-    return resu;         
+    TRACE(metafile,"IsValidMetaFile %x => %d\n",hmf,res);
+    return res;         
 }
 
 
-/******************************************************************
- *         PlayMetaFile16   (GDI.123)
+/*******************************************************************
+ *         MF_PlayMetaFile
  *
+ * Helper for PlayMetaFile
  */
-BOOL16 WINAPI PlayMetaFile16( HDC16 hdc, HMETAFILE16 hmf )
+static BOOL MF_PlayMetaFile( HDC hdc, METAHEADER *mh)
 {
-    return PlayMetaFile( hdc, hmf );
-}
 
-/******************************************************************
- *         PlayMetaFile32   (GDI32.265)
- *
- *  Renders the metafile specified by hmf in the DC specified by
- *  hdc. Returns FALSE on failure, TRUE on success.
- */
-BOOL WINAPI PlayMetaFile( 
-			     HDC hdc, /* handle of DC to render in */
-			     HMETAFILE hmf /* handle of metafile to render */
-)
-{
-    METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
     METARECORD *mr;
     HANDLETABLE16 *ht;
-    HGLOBAL16 hHT;
     int offset = 0;
     WORD i;
     HPEN hPen;
     HBRUSH hBrush;
     HFONT hFont;
     DC *dc;
-    
-    TRACE(metafile,"(%04x %04x)\n",hdc,hmf);
+    BOOL loaded = FALSE;
+
     if (!mh) return FALSE;
+    if(mh->mtType == METAFILE_DISK) { /* Create a memoery-based copy */
+        mh = MF_LoadDiskBasedMetaFile(mh);
+	if(!mh) return FALSE;
+	loaded = TRUE;
+    }
 
     /* save the current pen, brush and font */
     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
@@ -302,10 +487,9 @@ BOOL WINAPI PlayMetaFile(
     hFont = dc->w.hFont;
     GDI_HEAP_UNLOCK(hdc);
     /* create the handle table */
-    hHT = GlobalAlloc16(GMEM_MOVEABLE|GMEM_ZEROINIT,
-		      sizeof(HANDLETABLE16) * mh->mtNoObjects);
-    ht = (HANDLETABLE16 *)GlobalLock16(hHT);
-
+    ht = HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY,
+		    sizeof(HANDLETABLE16) * mh->mtNoObjects);
+    if(!ht) return FALSE;
     
     /* loop through metafile playing records */
     offset = mh->mtHeaderSize * 2;
@@ -315,8 +499,9 @@ BOOL WINAPI PlayMetaFile(
 	TRACE(metafile,"offset=%04x,size=%08lx\n",
             offset, mr->rdSize);
 	if (!mr->rdSize) {
-            TRACE(metafile,"Entry got size 0 at offset %d, total mf length is %ld\n",
-                offset,mh->mtSize*2);
+            TRACE(metafile,
+		  "Entry got size 0 at offset %d, total mf length is %ld\n",
+		  offset,mh->mtSize*2);
 		break; /* would loop endlessly otherwise */
 	}
 	offset += mr->rdSize * 2;
@@ -333,34 +518,52 @@ BOOL WINAPI PlayMetaFile(
         DeleteObject(*(ht->objectHandle + i));
     
     /* free handle table */
-    GlobalFree16(hHT);
-
+    HeapFree( SystemHeap, 0, ht );
+    if(loaded)
+        HeapFree( SystemHeap, 0, mh );
     return TRUE;
 }
 
-
 /******************************************************************
- *            EnumMetaFile16   (GDI.175)
+ *         PlayMetaFile16   (GDI.123)
  *
- *  Loop through the metafile records in hmf, calling the user-specified
- *  function for each one, stopping when the user's function returns FALSE
- *  (which is considered to be failure)
- *  or when no records are left (which is considered to be success). 
+ */
+BOOL16 WINAPI PlayMetaFile16( HDC16 hdc, HMETAFILE16 hmf )
+{
+    BOOL16 ret;
+    METAHEADER *mh = MF_GetMetaHeader16( hmf );
+    ret = MF_PlayMetaFile( hdc, mh );
+    MF_ReleaseMetaHeader16( hmf );
+    return ret;
+}
+
+/******************************************************************
+ *         PlayMetaFile   (GDI32.265)
  *
- * RETURNS
- *  TRUE on success, FALSE on failure.
- * 
- * HISTORY
- *   Niels de carpentier, april 1996
+ *  Renders the metafile specified by hmf in the DC specified by
+ *  hdc. Returns FALSE on failure, TRUE on success.
  */
-BOOL16 WINAPI EnumMetaFile16( 
-			     HDC16 hdc, 
-			     HMETAFILE16 hmf,
-			     MFENUMPROC16 lpEnumFunc, 
-			     LPARAM lpData 
+BOOL WINAPI PlayMetaFile( 
+			     HDC hdc, /* handle of DC to render in */
+			     HMETAFILE hmf /* handle of metafile to render */
 )
 {
-    METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
+    BOOL ret;
+    METAHEADER *mh = MF_GetMetaHeader( hmf );
+    ret = MF_PlayMetaFile( hdc, mh );
+    MF_ReleaseMetaHeader( hmf );
+    return ret;
+}
+
+
+/******************************************************************
+ *            EnumMetaFile16   (GDI.175)
+ *
+ */
+BOOL16 WINAPI EnumMetaFile16( HDC16 hdc, HMETAFILE16 hmf,
+			      MFENUMPROC16 lpEnumFunc, LPARAM lpData )
+{
+    METAHEADER *mh = MF_GetMetaHeader16(hmf);
     METARECORD *mr;
     HANDLETABLE16 *ht;
     HGLOBAL16 hHT;
@@ -371,11 +574,19 @@ BOOL16 WINAPI EnumMetaFile16(
     HBRUSH hBrush;
     HFONT hFont;
     DC *dc;
-    BOOL16 result = TRUE;
-    
+    BOOL16 result = TRUE, loaded = FALSE;
+
     TRACE(metafile,"(%04x, %04x, %08lx, %08lx)\n",
 		     hdc, hmf, (DWORD)lpEnumFunc, lpData);
 
+
+    if(!mh) return FALSE;
+    if(mh->mtType == METAFILE_DISK) { /* Create a memoery-based copy */
+        mh = MF_LoadDiskBasedMetaFile(mh);
+	if(!mh) return FALSE;
+	loaded = TRUE;
+    }
+
     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
     hPen = dc->w.hPen;
     hBrush = dc->w.hBrush;
@@ -421,20 +632,36 @@ BOOL16 WINAPI EnumMetaFile16(
 
     /* free handle table */
     GlobalFree16(hHT);
-    GlobalUnlock16(hmf);
+    if(loaded)
+        HeapFree( SystemHeap, 0, mh );
+    MF_ReleaseMetaHeader16(hmf);
     return result;
 }
 
+/******************************************************************
+ *            EnumMetaFile   (GDI32.88)
+ *
+ *  Loop through the metafile records in hmf, calling the user-specified
+ *  function for each one, stopping when the user's function returns FALSE
+ *  (which is considered to be failure)
+ *  or when no records are left (which is considered to be success). 
+ *
+ * RETURNS
+ *  TRUE on success, FALSE on failure.
+ * 
+ * HISTORY
+ *   Niels de carpentier, april 1996
+ */
 BOOL WINAPI EnumMetaFile( 
 			     HDC hdc, 
 			     HMETAFILE hmf,
 			     MFENUMPROC lpEnumFunc, 
 			     LPARAM lpData 
 ) {
-    METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
+    METAHEADER *mh = MF_GetMetaHeader(hmf);
     METARECORD *mr;
     HANDLETABLE *ht;
-    BOOL result = TRUE;
+    BOOL result = TRUE, loaded = FALSE;
     int i, offset = 0;
     DC *dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     HPEN hPen;
@@ -444,7 +671,12 @@ BOOL WINAPI EnumMetaFile(
     TRACE(metafile,"(%08x,%08x,%p,%p)\n",
 		     hdc, hmf, lpEnumFunc, (void*)lpData);
     if (!mh) return 0;
-
+    if(mh->mtType == METAFILE_DISK) { /* Create a memoery-based copy */
+        mh = MF_LoadDiskBasedMetaFile(mh);
+	if(!mh) return 0;
+	loaded = TRUE;
+    }
+    
     /* save the current pen, brush and font */
     if (!dc) return 0;
     hPen = dc->w.hPen;
@@ -453,9 +685,9 @@ BOOL WINAPI EnumMetaFile(
     GDI_HEAP_UNLOCK(hdc);
 
 
-    ht = (HANDLETABLE *) GlobalAlloc(GPTR, 
+    ht = HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY, 
 			    sizeof(HANDLETABLE) * mh->mtNoObjects);
-    
+
     /* loop through metafile records */
     offset = mh->mtHeaderSize * 2;
     
@@ -482,12 +714,14 @@ BOOL WINAPI EnumMetaFile(
         DeleteObject(*(ht->objectHandle + i));
 
     /* free handle table */
-    GlobalFree((HGLOBAL)ht);
-    GlobalUnlock16(hmf);
+    HeapFree( SystemHeap, 0, ht);
+    if(loaded)
+        HeapFree( SystemHeap, 0, mh );
+    MF_ReleaseMetaHeader(hmf);
     return result;
 }
 
-static BOOL MF_Meta_CreateRegion( METARECORD *mr, HRGN hrgn );
+static BOOL MF_Play_MetaCreateRegion( METARECORD *mr, HRGN hrgn );
 
 /******************************************************************
  *             PlayMetaFileRecord16   (GDI.176)
@@ -742,7 +976,6 @@ void WINAPI PlayMetaFileRecord16(
 		     CreateBrushIndirect16((LOGBRUSH16 *)(&(mr->rdParm))));
 	break;
 
-    /* W. Magro: Some new metafile operations.  Not all debugged. */
     case META_CREATEPALETTE:
 	MF_AddHandle(ht, nHandles, 
 		     CreatePalette16((LPLOGPALETTE)mr->rdParm));
@@ -753,7 +986,8 @@ void WINAPI PlayMetaFileRecord16(
 	break;
 
     case META_SELECTPALETTE:
-	SelectPalette16(hdc, *(ht->objectHandle + *(mr->rdParm+1)),*(mr->rdParm));
+	SelectPalette16(hdc, *(ht->objectHandle + *(mr->rdParm+1)),
+			*(mr->rdParm));
 	break;
 
     case META_SETMAPPERFLAGS:
@@ -768,7 +1002,6 @@ void WINAPI PlayMetaFileRecord16(
 	FIXME(metafile, "META_ESCAPE unimplemented.\n");
         break;
 
-        /* --- Begin of fixed or new metafile operations. July 1996 ----*/
     case META_EXTTEXTOUT:
       {
         LPINT16 dxx;
@@ -849,7 +1082,7 @@ void WINAPI PlayMetaFileRecord16(
       }
       break;
 
-    case META_BITBLT:            /* <-- not yet debugged */
+    case META_BITBLT:
       {
        HDC16 hdcSrc=CreateCompatibleDC16(hdc);
        HBITMAP hbitmap=CreateBitmap(mr->rdParm[7]/*Width */,
@@ -866,34 +1099,33 @@ void WINAPI PlayMetaFileRecord16(
       }
       break;
 
-       /* --- Begin of new metafile operations. April, 1997 (ak) ----*/
     case META_CREATEREGION:
       {
 	HRGN hrgn = CreateRectRgn(0,0,0,0);
  
-	MF_Meta_CreateRegion(mr, hrgn);
+	MF_Play_MetaCreateRegion(mr, hrgn);
 	MF_AddHandle(ht, nHandles, hrgn);
       }
       break;
 
-     case META_FILLREGION:
+    case META_FILLREGION:
         FillRgn16(hdc, *(ht->objectHandle + *(mr->rdParm)),
 		       *(ht->objectHandle + *(mr->rdParm+1)));
         break;
 
-     case META_INVERTREGION:
+    case META_INVERTREGION:
         InvertRgn16(hdc, *(ht->objectHandle + *(mr->rdParm)));
         break; 
 
-     case META_PAINTREGION:
+    case META_PAINTREGION:
         PaintRgn16(hdc, *(ht->objectHandle + *(mr->rdParm)));
         break;
 
-     case META_SELECTCLIPREGION:
+    case META_SELECTCLIPREGION:
        	SelectClipRgn(hdc, *(ht->objectHandle + *(mr->rdParm)));
 	break;
 
-     case META_DIBCREATEPATTERNBRUSH:
+    case META_DIBCREATEPATTERNBRUSH:
 	/*  *(mr->rdParm) may be BS_PATTERN or BS_DIBPATTERN: but there's no difference */
         TRACE(metafile,"%d\n",*(mr->rdParm));
 	s1 = mr->rdSize * 2 - sizeof(METARECORD) - 2;
@@ -934,12 +1166,12 @@ void WINAPI PlayMetaFileRecord16(
         }
         break;	
        
-     case META_SETTEXTCHAREXTRA:
-	    SetTextCharacterExtra16(hdc, (INT16)*(mr->rdParm));
-	    break;
+    case META_SETTEXTCHAREXTRA:
+        SetTextCharacterExtra16(hdc, (INT16)*(mr->rdParm));
+	break;
 
-     case META_SETTEXTJUSTIFICATION:
-       	SetTextJustification(hdc, *(mr->rdParm + 1), *(mr->rdParm));
+    case META_SETTEXTJUSTIFICATION:
+        SetTextJustification(hdc, *(mr->rdParm + 1), *(mr->rdParm));
 	break;
 
     case META_EXTFLOODFILL:
@@ -971,25 +1203,24 @@ void WINAPI PlayMetaFileRecord16(
     }
 }
 
-
-BOOL WINAPI PlayMetaFileRecord( 
-     HDC hdc, 
-     HANDLETABLE *handletable, 
-     METARECORD *metarecord, 
-     UINT handles  
-    )
+/******************************************************************
+ *         PlayMetaFileRecord   (GDI32.266)
+ */
+BOOL WINAPI PlayMetaFileRecord( HDC hdc,  HANDLETABLE *handletable, 
+				METARECORD *metarecord, UINT handles )
 {
-  HANDLETABLE16 * ht = (void *)GlobalAlloc(GPTR, 
-                               handles*sizeof(HANDLETABLE16));
-  int i = 0;
-  TRACE(metafile, "(%08x,%p,%p,%d)\n", hdc, handletable, metarecord, handles); 
-  for (i=0; i<handles; i++)  
-    ht->objectHandle[i] =  handletable->objectHandle[i];
-  PlayMetaFileRecord16(hdc, ht, metarecord, handles);
-  for (i=0; i<handles; i++) 
-    handletable->objectHandle[i] = ht->objectHandle[i];
-  GlobalFree((HGLOBAL)ht);
-  return TRUE;
+    HANDLETABLE16 * ht = (void *)GlobalAlloc(GPTR, 
+					     handles*sizeof(HANDLETABLE16));
+    int i = 0;
+    TRACE(metafile, "(%08x,%p,%p,%d)\n", hdc, handletable, metarecord,
+	  handles); 
+    for (i=0; i<handles; i++)  
+        ht->objectHandle[i] =  handletable->objectHandle[i];
+    PlayMetaFileRecord16(hdc, ht, metarecord, handles);
+    for (i=0; i<handles; i++) 
+        handletable->objectHandle[i] = ht->objectHandle[i];
+    GlobalFree((HGLOBAL)ht);
+    return TRUE;
 }
 
 /******************************************************************
@@ -1054,13 +1285,10 @@ HMETAFILE WINAPI SetMetaFileBitsEx(
      const BYTE *lpData /* pointer to metafile data */  
     )
 {
-  HMETAFILE hmf = GlobalAlloc16(GHND, size);
-  BYTE *p = GlobalLock16(hmf) ;
-  TRACE(metafile, "(%d,%p) returning %08x\n", size, lpData, hmf);
-  if (!hmf || !p) return 0;
-  memcpy(p, lpData, size);
-  GlobalUnlock16(hmf);
-  return hmf;
+    METAHEADER *mh = HeapAlloc( SystemHeap, 0, size );
+    if (!mh) return 0;
+    memcpy(mh, lpData, size);
+    return MF_Create_HMETAFILE(mh);
 }
 
 /*****************************************************************
@@ -1075,21 +1303,23 @@ UINT WINAPI GetMetaFileBitsEx(
      UINT nSize, /* size of buf */ 
      LPVOID buf   /* buffer to receive raw metafile data */  
 ) {
-  METAHEADER *h = GlobalLock16(hmf);
-  UINT mfSize;
-
-  TRACE(metafile, "(%08x,%d,%p)\n", hmf, nSize, buf);
-  if (!h) return 0;  /* FIXME: error code */
-  mfSize = h->mtSize * 2;
-  if (!buf) {
-    GlobalUnlock16(hmf);
-    TRACE(metafile,"returning size %d\n", mfSize);
+    METAHEADER *mh = MF_GetMetaHeader(hmf);
+    UINT mfSize;
+
+    TRACE(metafile, "(%08x,%d,%p)\n", hmf, nSize, buf);
+    if (!mh) return 0;  /* FIXME: error code */
+    if(mh->mtType == METAFILE_DISK)
+        FIXME(metafile, "Disk-based metafile?\n");
+    mfSize = mh->mtSize * 2;
+    if (!buf) {
+        MF_ReleaseMetaHeader(hmf);
+	TRACE(metafile,"returning size %d\n", mfSize);
+	return mfSize;
+    }
+    if(mfSize > nSize) mfSize = nSize;
+    memmove(buf, mh, mfSize);
+    MF_ReleaseMetaHeader(hmf);
     return mfSize;
-  }
-  if(mfSize > nSize) mfSize = nSize;
-  memmove(buf, h, mfSize);
-  GlobalUnlock16(hmf);
-  return mfSize;
 }
 
 /******************************************************************
@@ -1105,7 +1335,7 @@ UINT WINAPI GetWinMetaFileBits(HENHMETAFILE hemf,
 }
 
 /******************************************************************
- *         MF_Meta_CreateRegion
+ *         MF_Play_MetaCreateRegion
  *
  *  Handles META_CREATEREGION for PlayMetaFileRecord().
  */
@@ -1136,7 +1366,7 @@ UINT WINAPI GetWinMetaFileBits(HENHMETAFILE hemf,
  *
  */
 
-static BOOL MF_Meta_CreateRegion( METARECORD *mr, HRGN hrgn )
+static BOOL MF_Play_MetaCreateRegion( METARECORD *mr, HRGN hrgn )
 {
     WORD band, pair;
     WORD *start, *end;
@@ -1177,623 +1407,5 @@ static BOOL MF_Meta_CreateRegion( METARECORD *mr, HRGN hrgn )
  }
  
 
-/******************************************************************
- *         MF_WriteRecord
- *
- * Warning: this function can change the metafile handle.
- */
-
-static BOOL MF_WriteRecord( DC *dc, METARECORD *mr, DWORD rlen)
-{
-    DWORD len;
-    METAHEADER *mh;
-    METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
-
-    switch(physDev->mh->mtType)
-    {
-    case METAFILE_MEMORY:
-	len = physDev->mh->mtSize * 2 + rlen;
-	mh = HeapReAlloc( SystemHeap, 0, physDev->mh, len );
-        if (!mh) return FALSE;
-        physDev->mh = mh;
-	memcpy((WORD *)physDev->mh + physDev->mh->mtSize, mr, rlen);
-        break;
-    case METAFILE_DISK:
-        TRACE(metafile,"Writing record to disk\n");
-	if (_lwrite(physDev->mh->mtNoParameters, (char *)mr, rlen) == -1)
-	    return FALSE;
-        break;
-    default:
-        ERR(metafile, "Unknown metafile type %d\n", physDev->mh->mtType );
-        return FALSE;
-    }
-
-    physDev->mh->mtSize += rlen / 2;
-    physDev->mh->mtMaxRecord = MAX(physDev->mh->mtMaxRecord, rlen / 2);
-    return TRUE;
-}
-
-
-/******************************************************************
- *         MF_MetaParam0
+/*  LocalWords:  capatibility
  */
-
-BOOL MF_MetaParam0(DC *dc, short func)
-{
-    char buffer[8];
-    METARECORD *mr = (METARECORD *)&buffer;
-    
-    mr->rdSize = 3;
-    mr->rdFunction = func;
-    return MF_WriteRecord( dc, mr, mr->rdSize * 2);
-}
-
-
-/******************************************************************
- *         MF_MetaParam1
- */
-BOOL MF_MetaParam1(DC *dc, short func, short param1)
-{
-    char buffer[8];
-    METARECORD *mr = (METARECORD *)&buffer;
-    
-    mr->rdSize = 4;
-    mr->rdFunction = func;
-    *(mr->rdParm) = param1;
-    return MF_WriteRecord( dc, mr, mr->rdSize * 2);
-}
-
-
-/******************************************************************
- *         MF_MetaParam2
- */
-BOOL MF_MetaParam2(DC *dc, short func, short param1, short param2)
-{
-    char buffer[10];
-    METARECORD *mr = (METARECORD *)&buffer;
-    
-    mr->rdSize = 5;
-    mr->rdFunction = func;
-    *(mr->rdParm) = param2;
-    *(mr->rdParm + 1) = param1;
-    return MF_WriteRecord( dc, mr, mr->rdSize * 2);
-}
-
-
-/******************************************************************
- *         MF_MetaParam4
- */
-
-BOOL MF_MetaParam4(DC *dc, short func, short param1, short param2, 
-		   short param3, short param4)
-{
-    char buffer[14];
-    METARECORD *mr = (METARECORD *)&buffer;
-    
-    mr->rdSize = 7;
-    mr->rdFunction = func;
-    *(mr->rdParm) = param4;
-    *(mr->rdParm + 1) = param3;
-    *(mr->rdParm + 2) = param2;
-    *(mr->rdParm + 3) = param1;
-    return MF_WriteRecord( dc, mr, mr->rdSize * 2);
-}
-
-
-/******************************************************************
- *         MF_MetaParam6
- */
-
-BOOL MF_MetaParam6(DC *dc, short func, short param1, short param2, 
-		   short param3, short param4, short param5, short param6)
-{
-    char buffer[18];
-    METARECORD *mr = (METARECORD *)&buffer;
-    
-    mr->rdSize = 9;
-    mr->rdFunction = func;
-    *(mr->rdParm) = param6;
-    *(mr->rdParm + 1) = param5;
-    *(mr->rdParm + 2) = param4;
-    *(mr->rdParm + 3) = param3;
-    *(mr->rdParm + 4) = param2;
-    *(mr->rdParm + 5) = param1;
-    return MF_WriteRecord( dc, mr, mr->rdSize * 2);
-}
-
-
-/******************************************************************
- *         MF_MetaParam8
- */
-BOOL MF_MetaParam8(DC *dc, short func, short param1, short param2, 
-		   short param3, short param4, short param5,
-		   short param6, short param7, short param8)
-{
-    char buffer[22];
-    METARECORD *mr = (METARECORD *)&buffer;
-    
-    mr->rdSize = 11;
-    mr->rdFunction = func;
-    *(mr->rdParm) = param8;
-    *(mr->rdParm + 1) = param7;
-    *(mr->rdParm + 2) = param6;
-    *(mr->rdParm + 3) = param5;
-    *(mr->rdParm + 4) = param4;
-    *(mr->rdParm + 5) = param3;
-    *(mr->rdParm + 6) = param2;
-    *(mr->rdParm + 7) = param1;
-    return MF_WriteRecord( dc, mr, mr->rdSize * 2);
-}
-
-
-/******************************************************************
- *         MF_CreateBrushIndirect
- */
-
-BOOL MF_CreateBrushIndirect(DC *dc, HBRUSH16 hBrush, LOGBRUSH16 *logbrush)
-{
-    int index;
-    char buffer[sizeof(METARECORD) - 2 + sizeof(*logbrush)];
-    METARECORD *mr = (METARECORD *)&buffer;
-
-    mr->rdSize = (sizeof(METARECORD) + sizeof(*logbrush) - 2) / 2;
-    mr->rdFunction = META_CREATEBRUSHINDIRECT;
-    memcpy(&(mr->rdParm), logbrush, sizeof(*logbrush));
-    if (!(MF_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
-
-    mr->rdSize = sizeof(METARECORD) / 2;
-    mr->rdFunction = META_SELECTOBJECT;
-
-    if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
-    *(mr->rdParm) = index;
-    return MF_WriteRecord( dc, mr, mr->rdSize * 2);
-}
-
-
-/******************************************************************
- *         MF_CreatePatternBrush
- */
-
-BOOL MF_CreatePatternBrush(DC *dc, HBRUSH16 hBrush, LOGBRUSH16 *logbrush)
-{
-    DWORD len, bmSize, biSize;
-    METARECORD *mr;
-    BITMAPINFO *info;
-    int index;
-    char buffer[sizeof(METARECORD)];
-
-    switch (logbrush->lbStyle)
-    {
-    case BS_PATTERN:
-        {
-	    BITMAP bm;
-	    BYTE *bits;
-
-	    GetObjectA(logbrush->lbHatch, sizeof(bm), &bm);
-	    if(bm.bmBitsPixel != 1 || bm.bmPlanes != 1) {
-	        FIXME(metafile, "Trying to store a colour pattern brush\n");
-		return FALSE;
-	    }
-
-	    bmSize = bm.bmHeight * DIB_GetDIBWidthBytes(bm.bmWidth, 1);
-
-	    len = sizeof(METARECORD) +  sizeof(WORD) + sizeof(BITMAPINFO) + 
-	      sizeof(RGBQUAD) + bmSize;
-	     
-	    mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
-	    if(!mr) return FALSE;
-	    mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
-	    mr->rdSize = len / 2;
-	    mr->rdParm[0] = BS_PATTERN;
-	    mr->rdParm[1] = DIB_RGB_COLORS;
-	    info = (BITMAPINFO *)(mr->rdParm + 2);
-
-	    info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
-	    info->bmiHeader.biWidth = bm.bmWidth;
-	    info->bmiHeader.biHeight = bm.bmHeight;
-	    info->bmiHeader.biPlanes = 1;
-	    info->bmiHeader.biBitCount = 1;
-	    bits = ((BYTE *)info) + sizeof(BITMAPINFO) + sizeof(RGBQUAD);
-
-	    GetDIBits(dc->hSelf, logbrush->lbHatch, 0, bm.bmHeight, bits,
-		      info, DIB_RGB_COLORS);
-	    *(DWORD *)info->bmiColors = 0;
-	    *(DWORD *)(info->bmiColors + 1) = 0xffffff;
-	    break;
-	}
-
-    case BS_DIBPATTERN:
-	info = (BITMAPINFO *)GlobalLock16((HGLOBAL16)logbrush->lbHatch);
-	if (info->bmiHeader.biCompression)
-            bmSize = info->bmiHeader.biSizeImage;
-        else
-	    bmSize = DIB_GetDIBWidthBytes(info->bmiHeader.biWidth,
-					  info->bmiHeader.biBitCount) 
-	               * info->bmiHeader.biHeight;
-	biSize = DIB_BitmapInfoSize(info, LOWORD(logbrush->lbColor)); 
-	len = sizeof(METARECORD) + biSize + bmSize + 2;
-	mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
-	if(!mr) return FALSE;
-	mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
-	mr->rdSize = len / 2;
-	*(mr->rdParm) = logbrush->lbStyle;
-	*(mr->rdParm + 1) = LOWORD(logbrush->lbColor);
-	memcpy(mr->rdParm + 2, info, biSize + bmSize);
-	break;
-    default:
-        return FALSE;
-    }
-    if (!(MF_WriteRecord(dc, mr, len)))
-    {
-	HeapFree(GetProcessHeap(), 0, mr);
-	return FALSE;
-    }
-
-    HeapFree(GetProcessHeap(), 0, mr);
-    
-    mr = (METARECORD *)&buffer;
-    mr->rdSize = sizeof(METARECORD) / 2;
-    mr->rdFunction = META_SELECTOBJECT;
-
-    if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
-    *(mr->rdParm) = index;
-    return MF_WriteRecord( dc, mr, mr->rdSize * 2);
-}
-
-
-/******************************************************************
- *         MF_CreatePenIndirect
- */
-
-BOOL MF_CreatePenIndirect(DC *dc, HPEN16 hPen, LOGPEN16 *logpen)
-{
-    int index;
-    char buffer[sizeof(METARECORD) - 2 + sizeof(*logpen)];
-    METARECORD *mr = (METARECORD *)&buffer;
-
-    mr->rdSize = (sizeof(METARECORD) + sizeof(*logpen) - 2) / 2;
-    mr->rdFunction = META_CREATEPENINDIRECT;
-    memcpy(&(mr->rdParm), logpen, sizeof(*logpen));
-    if (!(MF_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
-
-    mr->rdSize = sizeof(METARECORD) / 2;
-    mr->rdFunction = META_SELECTOBJECT;
-
-    if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
-    *(mr->rdParm) = index;
-    return MF_WriteRecord( dc, mr, mr->rdSize * 2);
-}
-
-
-/******************************************************************
- *         MF_CreateFontIndirect
- */
-
-BOOL MF_CreateFontIndirect(DC *dc, HFONT16 hFont, LOGFONT16 *logfont)
-{
-    int index;
-    char buffer[sizeof(METARECORD) - 2 + sizeof(LOGFONT16)];
-    METARECORD *mr = (METARECORD *)&buffer;
-
-    mr->rdSize = (sizeof(METARECORD) + sizeof(LOGFONT16) - 2) / 2;
-    mr->rdFunction = META_CREATEFONTINDIRECT;
-    memcpy(&(mr->rdParm), logfont, sizeof(LOGFONT16));
-    if (!(MF_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
-
-    mr->rdSize = sizeof(METARECORD) / 2;
-    mr->rdFunction = META_SELECTOBJECT;
-
-    if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
-    *(mr->rdParm) = index;
-    return MF_WriteRecord( dc, mr, mr->rdSize * 2);
-}
-
-
-/******************************************************************
- *         MF_TextOut
- */
-BOOL MF_TextOut(DC *dc, short x, short y, LPCSTR str, short count)
-{
-    BOOL ret;
-    DWORD len;
-    HGLOBAL16 hmr;
-    METARECORD *mr;
-
-    len = sizeof(METARECORD) + (((count + 1) >> 1) * 2) + 4;
-    if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
-	return FALSE;
-    mr = (METARECORD *)GlobalLock16(hmr);
-    memset(mr, 0, len);
-
-    mr->rdSize = len / 2;
-    mr->rdFunction = META_TEXTOUT;
-    *(mr->rdParm) = count;
-    memcpy(mr->rdParm + 1, str, count);
-    *(mr->rdParm + ((count + 1) >> 1) + 1) = y;
-    *(mr->rdParm + ((count + 1) >> 1) + 2) = x;
-    ret = MF_WriteRecord( dc, mr, mr->rdSize * 2);
-    GlobalFree16(hmr);
-    return ret;
-}
-
-/******************************************************************
- *         MF_ExtTextOut
- */
-BOOL MF_ExtTextOut(DC*dc, short x, short y, UINT16 flags, const RECT16 *rect,
-                     LPCSTR str, short count, const INT16 *lpDx)
-{
-    BOOL ret;
-    DWORD len;
-    HGLOBAL16 hmr;
-    METARECORD *mr;
-    
-    if((!flags && rect) || (flags && !rect))
-	WARN(metafile, "Inconsistent flags and rect\n");
-    len = sizeof(METARECORD) + (((count + 1) >> 1) * 2) + 2 * sizeof(short)
-	    + sizeof(UINT16);
-    if(rect)
-        len += sizeof(RECT16);
-    if (lpDx)
-     len+=count*sizeof(INT16);
-    if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
-	return FALSE;
-    mr = (METARECORD *)GlobalLock16(hmr);
-    memset(mr, 0, len);
-
-    mr->rdSize = len / 2;
-    mr->rdFunction = META_EXTTEXTOUT;
-    *(mr->rdParm) = y;
-    *(mr->rdParm + 1) = x;
-    *(mr->rdParm + 2) = count;
-    *(mr->rdParm + 3) = flags;
-    if (rect) memcpy(mr->rdParm + 4, rect, sizeof(RECT16));
-    memcpy(mr->rdParm + (rect ? 8 : 4), str, count);
-    if (lpDx)
-     memcpy(mr->rdParm + (rect ? 8 : 4) + ((count + 1) >> 1),lpDx,
-      count*sizeof(INT16));
-    ret = MF_WriteRecord( dc, mr, mr->rdSize * 2);
-    GlobalFree16(hmr);
-    return ret;
-}
-
-/******************************************************************
- *         MF_MetaPoly - implements Polygon and Polyline
- */
-BOOL MF_MetaPoly(DC *dc, short func, LPPOINT16 pt, short count)
-{
-    BOOL ret;
-    DWORD len;
-    HGLOBAL16 hmr;
-    METARECORD *mr;
-
-    len = sizeof(METARECORD) + (count * 4); 
-    if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
-	return FALSE;
-    mr = (METARECORD *)GlobalLock16(hmr);
-    memset(mr, 0, len);
-
-    mr->rdSize = len / 2;
-    mr->rdFunction = func;
-    *(mr->rdParm) = count;
-    memcpy(mr->rdParm + 1, pt, count * 4);
-    ret = MF_WriteRecord( dc, mr, mr->rdSize * 2);
-    GlobalFree16(hmr);
-    return ret;
-}
-
-
-/******************************************************************
- *         MF_BitBlt
- */
-BOOL MF_BitBlt(DC *dcDest, short xDest, short yDest, short width,
-                 short height, DC *dcSrc, short xSrc, short ySrc, DWORD rop)
-{
-    BOOL ret;
-    DWORD len;
-    HGLOBAL16 hmr;
-    METARECORD *mr;
-    BITMAP16  BM;
-
-    GetObject16(dcSrc->w.hBitmap, sizeof(BITMAP16), &BM);
-    len = sizeof(METARECORD) + 12 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
-    if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
-	return FALSE;
-    mr = (METARECORD *)GlobalLock16(hmr);
-    mr->rdFunction = META_BITBLT;
-    *(mr->rdParm + 7) = BM.bmWidth;
-    *(mr->rdParm + 8) = BM.bmHeight;
-    *(mr->rdParm + 9) = BM.bmWidthBytes;
-    *(mr->rdParm +10) = BM.bmPlanes;
-    *(mr->rdParm +11) = BM.bmBitsPixel;
-    TRACE(metafile,"MF_StretchBlt->len = %ld  rop=%lx  \n",len,rop);
-    if (GetBitmapBits(dcSrc->w.hBitmap,BM.bmWidthBytes * BM.bmHeight,
-                        mr->rdParm +12))
-    {
-      mr->rdSize = len / sizeof(INT16);
-      *(mr->rdParm) = HIWORD(rop);
-      *(mr->rdParm + 1) = ySrc;
-      *(mr->rdParm + 2) = xSrc;
-      *(mr->rdParm + 3) = height;
-      *(mr->rdParm + 4) = width;
-      *(mr->rdParm + 5) = yDest;
-      *(mr->rdParm + 6) = xDest;
-      ret = MF_WriteRecord( dcDest, mr, mr->rdSize * 2);
-    }  
-    else
-        ret = FALSE;
-    GlobalFree16(hmr);
-    return ret;
-}
-
-
-/**********************************************************************
- *         MF_StretchBlt         
- * this function contains TWO ways for procesing StretchBlt in metafiles,
- * decide between rdFunction values  META_STRETCHBLT or META_DIBSTRETCHBLT
- * via #define STRETCH_VIA_DIB
- */
-#define STRETCH_VIA_DIB
-#undef  STRETCH_VIA_DIB
-BOOL MF_StretchBlt(DC *dcDest, short xDest, short yDest, short widthDest,
-                     short heightDest, DC *dcSrc, short xSrc, short ySrc, 
-                     short widthSrc, short heightSrc, DWORD rop)
-{
-    BOOL ret;
-    DWORD len;
-    HGLOBAL16 hmr;
-    METARECORD *mr;
-    BITMAP16  BM;
-#ifdef STRETCH_VIA_DIB    
-    LPBITMAPINFOHEADER lpBMI;
-    WORD nBPP;
-#endif  
-    GetObject16(dcSrc->w.hBitmap, sizeof(BITMAP16), &BM);
-#ifdef STRETCH_VIA_DIB
-    nBPP = BM.bmPlanes * BM.bmBitsPixel;
-    len = sizeof(METARECORD) + 10 * sizeof(INT16) 
-            + sizeof(BITMAPINFOHEADER) + (nBPP != 24 ? 1 << nBPP: 0) * sizeof(RGBQUAD) 
-              + ((BM.bmWidth * nBPP + 31) / 32) * 4 * BM.bmHeight;
-    if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
-	return FALSE;
-    mr = (METARECORD *)GlobalLock16(hmr);
-    mr->rdFunction = META_DIBSTRETCHBLT;
-    lpBMI=(LPBITMAPINFOHEADER)(mr->rdParm+10);
-    lpBMI->biSize      = sizeof(BITMAPINFOHEADER);
-    lpBMI->biWidth     = BM.bmWidth;
-    lpBMI->biHeight    = BM.bmHeight;
-    lpBMI->biPlanes    = 1;
-    lpBMI->biBitCount  = nBPP;                              /* 1,4,8 or 24 */
-    lpBMI->biClrUsed   = nBPP != 24 ? 1 << nBPP : 0;
-    lpBMI->biSizeImage = ((lpBMI->biWidth * nBPP + 31) / 32) * 4 * lpBMI->biHeight;
-    lpBMI->biCompression = BI_RGB;
-    lpBMI->biXPelsPerMeter = MulDiv(GetDeviceCaps(dcSrc->hSelf,LOGPIXELSX),3937,100);
-    lpBMI->biYPelsPerMeter = MulDiv(GetDeviceCaps(dcSrc->hSelf,LOGPIXELSY),3937,100);
-    lpBMI->biClrImportant  = 0;                          /* 1 meter  = 39.37 inch */
-
-    TRACE(metafile,"MF_StretchBltViaDIB->len = %ld  rop=%lx  PixYPM=%ld Caps=%d\n",
-               len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(hdcSrc,LOGPIXELSY));
-    if (GetDIBits(hdcSrc,dcSrc->w.hBitmap,0,(UINT)lpBMI->biHeight,
-                  (LPSTR)lpBMI + DIB_BitmapInfoSize( (BITMAPINFO *)lpBMI,
-                                                     DIB_RGB_COLORS ),
-                  (LPBITMAPINFO)lpBMI, DIB_RGB_COLORS))
-#else
-    len = sizeof(METARECORD) + 15 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
-    if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
-	return FALSE;
-    mr = (METARECORD *)GlobalLock16(hmr);
-    mr->rdFunction = META_STRETCHBLT;
-    *(mr->rdParm +10) = BM.bmWidth;
-    *(mr->rdParm +11) = BM.bmHeight;
-    *(mr->rdParm +12) = BM.bmWidthBytes;
-    *(mr->rdParm +13) = BM.bmPlanes;
-    *(mr->rdParm +14) = BM.bmBitsPixel;
-    TRACE(metafile,"MF_StretchBlt->len = %ld  rop=%lx  \n",len,rop);
-    if (GetBitmapBits( dcSrc->w.hBitmap, BM.bmWidthBytes * BM.bmHeight,
-                         mr->rdParm +15))
-#endif    
-    {
-      mr->rdSize = len / sizeof(INT16);
-      *(mr->rdParm) = LOWORD(rop);
-      *(mr->rdParm + 1) = HIWORD(rop);
-      *(mr->rdParm + 2) = heightSrc;
-      *(mr->rdParm + 3) = widthSrc;
-      *(mr->rdParm + 4) = ySrc;
-      *(mr->rdParm + 5) = xSrc;
-      *(mr->rdParm + 6) = heightDest;
-      *(mr->rdParm + 7) = widthDest;
-      *(mr->rdParm + 8) = yDest;
-      *(mr->rdParm + 9) = xDest;
-      ret = MF_WriteRecord( dcDest, mr, mr->rdSize * 2);
-    }  
-    else
-        ret = FALSE;
-    GlobalFree16(hmr);
-    return ret;
-}
-
-
-/******************************************************************
- *         MF_CreateRegion
- */
-INT16 MF_CreateRegion(DC *dc, HRGN hrgn)
-{
-    DWORD len;
-    METARECORD *mr;
-    RGNDATA *rgndata;
-    RECT *pCurRect, *pEndRect;
-    WORD Bands = 0, MaxBands = 0;
-    WORD *Param, *StartBand;
-    BOOL ret;
-
-    len = GetRegionData( hrgn, 0, NULL );
-    if( !(rgndata = HeapAlloc( SystemHeap, 0, len )) ) {
-        WARN(metafile, "MF_CreateRegion: can't alloc rgndata buffer\n");
-	return -1;
-    }
-    GetRegionData( hrgn, len, rgndata );
-
-    /* Overestimate of length:
-     * Assume every rect is a separate band -> 6 WORDs per rect
-     */
-    len = sizeof(METARECORD) + 20 + (rgndata->rdh.nCount * 12);
-    if( !(mr = HeapAlloc( SystemHeap, 0, len )) ) {
-        WARN(metafile, "MF_CreateRegion: can't alloc METARECORD buffer\n");
-	HeapFree( SystemHeap, 0, rgndata );
-	return -1;
-    }
-
-    memset(mr, 0, len);
-        
-    Param = mr->rdParm + 11;
-    StartBand = NULL;
-
-    pEndRect = (RECT *)rgndata->Buffer + rgndata->rdh.nCount;
-    for(pCurRect = (RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++)
-    {
-        if( StartBand && pCurRect->top == *(StartBand + 1) )
-        {
-	    *Param++ = pCurRect->left;
-	    *Param++ = pCurRect->right;
-	}
-	else
-	{
-	    if(StartBand)
-	    {
-	        *StartBand = Param - StartBand - 3;
-		*Param++ = *StartBand;
-		if(*StartBand > MaxBands)
-		    MaxBands = *StartBand;
-		Bands++;
-	    }
-	    StartBand = Param++;
-	    *Param++ = pCurRect->top;
-	    *Param++ = pCurRect->bottom;
-	    *Param++ = pCurRect->left;
-	    *Param++ = pCurRect->right;
-	}
-    }
-    len = Param - (WORD *)mr;
-    
-    mr->rdParm[0] = 0;
-    mr->rdParm[1] = 6;
-    mr->rdParm[2] = 0x1234;
-    mr->rdParm[3] = 0;
-    mr->rdParm[4] = len * 2;
-    mr->rdParm[5] = Bands;
-    mr->rdParm[6] = MaxBands;
-    mr->rdParm[7] = rgndata->rdh.rcBound.left;
-    mr->rdParm[8] = rgndata->rdh.rcBound.top;
-    mr->rdParm[9] = rgndata->rdh.rcBound.right;
-    mr->rdParm[10] = rgndata->rdh.rcBound.bottom;
-    mr->rdFunction = META_CREATEREGION;
-    mr->rdSize = len / 2;
-    ret = MF_WriteRecord( dc, mr, mr->rdSize * 2 );	
-    HeapFree( SystemHeap, 0, mr );
-    HeapFree( SystemHeap, 0, rgndata );
-    if(!ret) 
-    {
-        WARN(metafile, "MF_CreateRegion: MF_WriteRecord failed\n");
-	return -1;
-    }
-    return MF_AddHandleDC( dc );
-}