From b94e43303ad78becf1f2108b8536f763fd902306 Mon Sep 17 00:00:00 2001 From: Huw D M Davies Date: Thu, 15 Apr 1999 16:46:51 +0000 Subject: [PATCH] Change (32 bit) HMETAFILEs to GDI objects (HMETAFILE16s remain as global memory handles). Fixed disk-based MetaFiles. Better separation between MetaFile playback and the metafiledrv. --- graphics/metafiledrv/bitblt.c | 133 +++- graphics/metafiledrv/graphics.c | 160 +++- graphics/metafiledrv/init.c | 254 ++++-- graphics/metafiledrv/mapping.c | 20 +- graphics/metafiledrv/objects.c | 174 +++- graphics/metafiledrv/text.c | 61 +- include/metafile.h | 49 +- include/metafiledrv.h | 22 +- objects/clipping.c | 8 +- objects/dc.c | 8 +- objects/dcvalues.c | 6 +- objects/metafile.c | 1330 +++++++++++-------------------- 12 files changed, 1218 insertions(+), 1007 deletions(-) diff --git a/graphics/metafiledrv/bitblt.c b/graphics/metafiledrv/bitblt.c index f77b2282043..bceef2504f5 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 8bc0a221c24..d744bc48abb 100644 --- a/graphics/metafiledrv/graphics.c +++ b/graphics/metafiledrv/graphics.c @@ -7,10 +7,10 @@ #include #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 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 c7195d35173..de9c9322996 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) - */ -BOOL16 WINAPI DeleteMetaFile16( - HMETAFILE16 hmf - /* Handle of memory metafile to delete */ -) -{ - return !GlobalFree16( hmf ); -} - -/****************************************************************** - * DeleteMetaFile32 (GDI32.69) + * MFDRV_WriteRecord * - * Delete a memory-based metafile. + * Warning: this function can change the pointer to the metafile header. + */ +BOOL MFDRV_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 (!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; +} + + +/****************************************************************** + * 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 d49b5029fca..497ca26f364 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 3e52734f4f0..ebdb49d07bb 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 ffee2a616f9..2f155dddad2 100644 --- a/graphics/metafiledrv/text.c +++ b/graphics/metafiledrv/text.c @@ -5,11 +5,50 @@ * */ -#include #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 1abef44c8b4..ae2f952346b 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 29048d1c2e3..96cb1c6a073 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 428aa272169..a6d623fa37a 100644 --- a/objects/clipping.c +++ b/objects/clipping.c @@ -6,7 +6,7 @@ #include #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 fc10681aaf5..5f8a41fa0c6 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 b1c60760259..89e5fea9c67 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 3f7f13bb99a..8f35e12bc5e 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 #include #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 * - * 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. + * Creates a (32 bit) HMETAFILE object from a METAHEADER + * + * HMETAFILEs are GDI objects. */ -static int MF_AddHandleDC( DC *dc ) +HMETAFILE MF_Create_HMETAFILE(METAHEADER *mh) { - METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dc->physDev; - physDev->mh->mtNoObjects++; - return physDev->nextHandle++; + 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 + * + * Releases METAHEADER associated with HMETAFILE16 + */ +static BOOL16 MF_ReleaseMetaHeader16( HMETAFILE16 hmf ) +{ + 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); + METAHEADER *mh; + HFILE hFile; + + TRACE(metafile,"%s\n", lpFilename); - if (!lpFilename) - return 0; + 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; + 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 ); } +/****************************************************************** + * 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; + + 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) +{ + 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 ) +HMETAFILE16 WINAPI CopyMetaFile16( HMETAFILE16 hSrcMetaFile, LPCSTR lpFilename) { - return CopyMetaFileA( hSrcMetaFile, 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) - 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); - } + 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 ); - GlobalUnlock16(hSrcMetaFile); - return handle; + 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_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; } +/****************************************************************** + * PlayMetaFile16 (GDI.123) + * + */ +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) + * + * 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 */ +) +{ + BOOL ret; + METAHEADER *mh = MF_GetMetaHeader( hmf ); + ret = MF_PlayMetaFile( hdc, mh ); + MF_ReleaseMetaHeader( hmf ); + return ret; +} + /****************************************************************** * EnumMetaFile16 (GDI.175) * - * 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 */ -BOOL16 WINAPI EnumMetaFile16( - HDC16 hdc, - HMETAFILE16 hmf, - MFENUMPROC16 lpEnumFunc, - LPARAM lpData -) +BOOL16 WINAPI EnumMetaFile16( HDC16 hdc, HMETAFILE16 hmf, + MFENUMPROC16 lpEnumFunc, LPARAM lpData ) { - METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf); + 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; iobjectHandle[i] = handletable->objectHandle[i]; - PlayMetaFileRecord16(hdc, ht, metarecord, handles); - for (i=0; iobjectHandle[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; iobjectHandle[i] = handletable->objectHandle[i]; + PlayMetaFileRecord16(hdc, ht, metarecord, handles); + for (i=0; iobjectHandle[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; + METAHEADER *mh = MF_GetMetaHeader(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); + 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. +/* LocalWords: capatibility */ - -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 - */ - -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 ); -}