GDI: Merge the mfdrv into one .c file.
Dimitrie O. Paun
dpaun at rogers.com
Thu Apr 1 19:47:16 CST 2004
Identical rationale as for the enhmfdrv one.
Remove dlls/gdi/mfdrv/*:
$ cvs rm -f dlls/gdi/mfdrv/*.[hc]
ChangeLog
Merge the mfdrv into one .c file.
--- orig/dlls/gdi/Makefile.in
+++ mod/dlls/gdi/Makefile.in
@@ -38,13 +38,7 @@
gdi_main.c \
icm.c \
mapping.c \
- mfdrv/bitblt.c \
- mfdrv/dc.c \
- mfdrv/graphics.c \
- mfdrv/init.c \
- mfdrv/mapping.c \
- mfdrv/objects.c \
- mfdrv/text.c \
+ mfdrv.c \
painting.c \
path.c \
printdrv.c
@@ -61,9 +55,7 @@
SUBDIRS = tests
-EXTRASUBDIRS = \
- $(TOPOBJDIR)/objects \
- mfdrv
+EXTRASUBDIRS = $(TOPOBJDIR)/objects
@MAKE_DLL_RULES@
--- /dev/null 2003-01-30 05:24:37.000000000 -0500
+++ dlls/gdi/mfdrv.c 2004-04-01 17:15:39.000000000 -0500
@@ -0,0 +1,2004 @@
+/*
+ * Metafile driver
+ *
+ * Copyright 1996 Alexandre Julliard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "gdi.h"
+#include "wownt32.h"
+#include "gdi_private.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(metafile);
+
+/* Metafile driver physical DC */
+
+typedef struct
+{
+ HDC hdc;
+ DC *dc;
+ METAHEADER *mh; /* Pointer to metafile header */
+ UINT handles_size, cur_handles;
+ HGDIOBJ *handles;
+ HANDLE hFile; /* Handle for disk based MetaFile */
+} METAFILEDRV_PDEVICE;
+
+#define HANDLE_LIST_INC 20
+
+
+extern BOOL MFDRV_MetaParam0(PHYSDEV dev, short func);
+extern BOOL MFDRV_MetaParam1(PHYSDEV dev, short func, short param1);
+extern BOOL MFDRV_MetaParam2(PHYSDEV dev, short func, short param1, short param2);
+extern BOOL MFDRV_MetaParam4(PHYSDEV dev, short func, short param1, short param2,
+ short param3, short param4);
+extern BOOL MFDRV_MetaParam6(PHYSDEV dev, short func, short param1, short param2,
+ short param3, short param4, short param5,
+ short param6);
+extern BOOL MFDRV_MetaParam8(PHYSDEV dev, short func, short param1, short param2,
+ short param3, short param4, short param5,
+ short param6, short param7, short param8);
+extern BOOL MFDRV_WriteRecord(PHYSDEV dev, METARECORD *mr, DWORD rlen);
+extern UINT MFDRV_AddHandle( PHYSDEV dev, HGDIOBJ obj );
+extern INT16 MFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush );
+
+extern INT MFDRV_ExtEscape( PHYSDEV dev, INT nEscape, INT cbInput, LPCVOID in_data,
+ INT cbOutput, LPVOID out_data );
+extern INT MFDRV_GetDeviceCaps( PHYSDEV dev , INT cap );
+extern BOOL MFDRV_StretchBlt( PHYSDEV devDst, INT xDst, INT yDst, INT widthDst,
+ INT heightDst, PHYSDEV devSrc, INT xSrc, INT ySrc,
+ INT widthSrc, INT heightSrc, DWORD rop );
+/*********************/
+/* Bitblt operations */
+/*********************/
+
+/***********************************************************************
+ * MFDRV_PatBlt
+ */
+BOOL MFDRV_PatBlt( PHYSDEV dev, INT left, INT top, INT width, INT height, DWORD rop )
+{
+ MFDRV_MetaParam6( dev, META_PATBLT, left, top, width, height, HIWORD(rop), LOWORD(rop) );
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * MFDRV_BitBlt
+ */
+BOOL MFDRV_BitBlt( PHYSDEV devDst, INT xDst, INT yDst, INT width, INT height,
+ PHYSDEV devSrc, INT xSrc, INT ySrc, DWORD rop )
+{
+ return MFDRV_StretchBlt(devDst, xDst, yDst, width, height, devSrc,
+ xSrc, ySrc, width, height, rop);
+}
+
+
+
+/***********************************************************************
+ * 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
+ */
+#define STRETCH_VIA_DIB
+
+BOOL MFDRV_StretchBlt( PHYSDEV devDst, INT xDst, INT yDst, INT widthDst,
+ INT heightDst, PHYSDEV devSrc, INT xSrc, INT ySrc,
+ INT widthSrc, INT heightSrc, DWORD rop )
+{
+ BOOL ret;
+ DWORD len;
+ METARECORD *mr;
+ BITMAP BM;
+ METAFILEDRV_PDEVICE *physDevSrc = (METAFILEDRV_PDEVICE *)devSrc;
+ DC *dcSrc = physDevSrc->dc;
+#ifdef STRETCH_VIA_DIB
+ LPBITMAPINFOHEADER lpBMI;
+ WORD nBPP;
+#endif
+ GetObjectA(dcSrc->hBitmap, sizeof(BITMAP), &BM);
+#ifdef STRETCH_VIA_DIB
+ nBPP = BM.bmPlanes * BM.bmBitsPixel;
+ if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */
+ len = sizeof(METARECORD) + 10 * sizeof(INT16)
+ + sizeof(BITMAPINFOHEADER) + (nBPP <= 8 ? 1 << nBPP: 0) * sizeof(RGBQUAD)
+ + DIB_GetDIBWidthBytes(BM.bmWidth, nBPP) * BM.bmHeight;
+ if (!(mr = HeapAlloc( GetProcessHeap(), 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;
+ lpBMI->biSizeImage = DIB_GetDIBWidthBytes(BM.bmWidth, nBPP) * lpBMI->biHeight;
+ lpBMI->biClrUsed = nBPP <= 8 ? 1 << nBPP : 0;
+ 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("MF_StretchBltViaDIB->len = %ld rop=%lx PixYPM=%ld Caps=%d\n",
+ len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(dcSrc->hSelf,
+ LOGPIXELSY));
+ if (GetDIBits(dcSrc->hSelf,dcSrc->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( GetProcessHeap(), 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("len = %ld rop=%lx \n",len,rop);
+ if (GetBitmapBits( dcSrc->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( devDst, mr, mr->rdSize * 2);
+ }
+ else
+ ret = FALSE;
+ HeapFree( GetProcessHeap(), 0, mr);
+ return ret;
+}
+
+
+/***********************************************************************
+ * MFDRV_StretchDIBits
+ */
+INT MFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
+ INT heightDst, INT xSrc, INT ySrc, INT widthSrc,
+ INT heightSrc, const void *bits,
+ const BITMAPINFO *info, UINT wUsage, DWORD dwRop )
+{
+ DWORD len, infosize, imagesize;
+ METARECORD *mr;
+
+ infosize = DIB_BitmapInfoSize(info, wUsage);
+ imagesize = DIB_GetDIBImageBytes( info->bmiHeader.biWidth,
+ info->bmiHeader.biHeight,
+ info->bmiHeader.biBitCount );
+
+ len = sizeof(METARECORD) + 10 * sizeof(WORD) + infosize + imagesize;
+ mr = (METARECORD *)HeapAlloc( GetProcessHeap(), 0, len );
+ if(!mr) return 0;
+
+ mr->rdSize = len / 2;
+ mr->rdFunction = META_STRETCHDIB;
+ mr->rdParm[0] = LOWORD(dwRop);
+ mr->rdParm[1] = HIWORD(dwRop);
+ mr->rdParm[2] = wUsage;
+ mr->rdParm[3] = (INT16)heightSrc;
+ mr->rdParm[4] = (INT16)widthSrc;
+ mr->rdParm[5] = (INT16)ySrc;
+ mr->rdParm[6] = (INT16)xSrc;
+ mr->rdParm[7] = (INT16)heightDst;
+ mr->rdParm[8] = (INT16)widthDst;
+ mr->rdParm[9] = (INT16)yDst;
+ mr->rdParm[10] = (INT16)xDst;
+ memcpy(mr->rdParm + 11, info, infosize);
+ memcpy(mr->rdParm + 11 + infosize / 2, bits, imagesize);
+ MFDRV_WriteRecord( dev, mr, mr->rdSize * 2 );
+ HeapFree( GetProcessHeap(), 0, mr );
+ return heightSrc;
+}
+
+
+/***********************************************************************
+ * MFDRV_SetDIBitsToDeivce
+ */
+INT MFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDst, INT yDst, DWORD cx,
+ DWORD cy, INT xSrc, INT ySrc, UINT startscan,
+ UINT lines, LPCVOID bits, const BITMAPINFO *info,
+ UINT coloruse )
+
+{
+ DWORD len, infosize, imagesize;
+ METARECORD *mr;
+
+ infosize = DIB_BitmapInfoSize(info, coloruse);
+ imagesize = DIB_GetDIBImageBytes( info->bmiHeader.biWidth,
+ info->bmiHeader.biHeight,
+ info->bmiHeader.biBitCount );
+
+ len = sizeof(METARECORD) + 8 * sizeof(WORD) + infosize + imagesize;
+ mr = (METARECORD *)HeapAlloc( GetProcessHeap(), 0, len );
+ if(!mr) return 0;
+
+ mr->rdSize = len / 2;
+ mr->rdFunction = META_SETDIBTODEV;
+ mr->rdParm[0] = coloruse;
+ mr->rdParm[1] = lines;
+ mr->rdParm[2] = startscan;
+ mr->rdParm[3] = (INT16)ySrc;
+ mr->rdParm[4] = (INT16)xSrc;
+ mr->rdParm[5] = (INT16)cy;
+ mr->rdParm[6] = (INT16)cx;
+ mr->rdParm[7] = (INT16)yDst;
+ mr->rdParm[8] = (INT16)xDst;
+ memcpy(mr->rdParm + 9, info, infosize);
+ memcpy(mr->rdParm + 9 + infosize / 2, bits, imagesize);
+ MFDRV_WriteRecord( dev, mr, mr->rdSize * 2 );
+ HeapFree( GetProcessHeap(), 0, mr );
+ return lines;
+}
+
+/**********************/
+/* DC value functions */
+/**********************/
+
+INT MFDRV_SaveDC( PHYSDEV dev )
+{
+ return MFDRV_MetaParam0( dev, META_SAVEDC );
+}
+
+BOOL MFDRV_RestoreDC( PHYSDEV dev, INT level )
+{
+ if(level != -1) return FALSE;
+ return MFDRV_MetaParam1( dev, META_RESTOREDC, level );
+}
+
+UINT MFDRV_SetTextAlign( PHYSDEV dev, UINT align )
+{
+ return MFDRV_MetaParam2( dev, META_SETTEXTALIGN, HIWORD(align), LOWORD(align));
+}
+
+INT MFDRV_SetBkMode( PHYSDEV dev, INT mode )
+{
+ return MFDRV_MetaParam1( dev, META_SETBKMODE, (WORD)mode);
+}
+
+INT MFDRV_SetROP2( PHYSDEV dev, INT rop )
+{
+ return MFDRV_MetaParam1( dev, META_SETROP2, (WORD)rop);
+}
+
+INT MFDRV_SetRelAbs( PHYSDEV dev, INT mode )
+{
+ return MFDRV_MetaParam1( dev, META_SETRELABS, (WORD)mode);
+}
+
+INT MFDRV_SetPolyFillMode( PHYSDEV dev, INT mode )
+{
+ return MFDRV_MetaParam1( dev, META_SETPOLYFILLMODE, (WORD)mode);
+}
+
+INT MFDRV_SetStretchBltMode( PHYSDEV dev, INT mode )
+{
+ return MFDRV_MetaParam1( dev, META_SETSTRETCHBLTMODE, (WORD)mode);
+}
+
+INT MFDRV_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
+{
+ return MFDRV_MetaParam4( dev, META_INTERSECTCLIPRECT, left, top, right,
+ bottom );
+}
+
+INT MFDRV_ExcludeClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
+{
+ return MFDRV_MetaParam4( dev, META_EXCLUDECLIPRECT, left, top, right,
+ bottom );
+}
+
+INT MFDRV_OffsetClipRgn( PHYSDEV dev, INT x, INT y )
+{
+ return MFDRV_MetaParam2( dev, META_OFFSETCLIPRGN, x, y );
+}
+
+INT MFDRV_SetTextJustification( PHYSDEV dev, INT extra, INT breaks )
+{
+ return MFDRV_MetaParam2( dev, META_SETTEXTJUSTIFICATION, extra, breaks );
+}
+
+INT MFDRV_SetTextCharacterExtra( PHYSDEV dev, INT extra )
+{
+ if(!MFDRV_MetaParam1( dev, META_SETTEXTCHAREXTRA, extra ))
+ return 0x80000000;
+ return TRUE;
+}
+
+DWORD MFDRV_SetMapperFlags( PHYSDEV dev, DWORD flags )
+{
+ return MFDRV_MetaParam2( dev, META_SETMAPPERFLAGS, HIWORD(flags),
+ LOWORD(flags) );
+}
+
+BOOL MFDRV_AbortPath( PHYSDEV dev )
+{
+ return FALSE;
+}
+
+BOOL MFDRV_BeginPath( PHYSDEV dev )
+{
+ return FALSE;
+}
+
+BOOL MFDRV_CloseFigure( PHYSDEV dev )
+{
+ return FALSE;
+}
+
+BOOL MFDRV_EndPath( PHYSDEV dev )
+{
+ return FALSE;
+}
+
+BOOL MFDRV_FillPath( PHYSDEV dev )
+{
+ return FALSE;
+}
+
+BOOL MFDRV_FlattenPath( PHYSDEV dev )
+{
+ return FALSE;
+}
+
+BOOL MFDRV_SelectClipPath( PHYSDEV dev, INT iMode )
+{
+ return FALSE;
+}
+
+BOOL MFDRV_StrokeAndFillPath( PHYSDEV dev )
+{
+ return FALSE;
+}
+
+BOOL MFDRV_StrokePath( PHYSDEV dev )
+{
+ return FALSE;
+}
+
+BOOL MFDRV_WidenPath( PHYSDEV dev )
+{
+ return FALSE;
+}
+
+/**********************/
+/* Graphics functions */
+/**********************/
+
+/**********************************************************************
+ * MFDRV_MoveTo
+ */
+BOOL
+MFDRV_MoveTo(PHYSDEV dev, INT x, INT y)
+{
+ return MFDRV_MetaParam2(dev,META_MOVETO,x,y);
+}
+
+/***********************************************************************
+ * MFDRV_LineTo
+ */
+BOOL
+MFDRV_LineTo( PHYSDEV dev, INT x, INT y )
+{
+ return MFDRV_MetaParam2(dev, META_LINETO, x, y);
+}
+
+
+/***********************************************************************
+ * MFDRV_Arc
+ */
+BOOL
+MFDRV_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
+ INT xstart, INT ystart, INT xend, INT yend )
+{
+ return MFDRV_MetaParam8(dev, META_ARC, left, top, right, bottom,
+ xstart, ystart, xend, yend);
+}
+
+
+/***********************************************************************
+ * MFDRV_Pie
+ */
+BOOL
+MFDRV_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
+ INT xstart, INT ystart, INT xend, INT yend )
+{
+ return MFDRV_MetaParam8(dev, META_PIE, left, top, right, bottom,
+ xstart, ystart, xend, yend);
+}
+
+
+/***********************************************************************
+ * MFDRV_Chord
+ */
+BOOL
+MFDRV_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
+ INT xstart, INT ystart, INT xend, INT yend )
+{
+ return MFDRV_MetaParam8(dev, META_CHORD, left, top, right, bottom,
+ xstart, ystart, xend, yend);
+}
+
+/***********************************************************************
+ * MFDRV_Ellipse
+ */
+BOOL
+MFDRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
+{
+ return MFDRV_MetaParam4(dev, META_ELLIPSE, left, top, right, bottom);
+}
+
+/***********************************************************************
+ * MFDRV_Rectangle
+ */
+BOOL
+MFDRV_Rectangle(PHYSDEV dev, INT left, INT top, INT right, INT bottom)
+{
+ return MFDRV_MetaParam4(dev, META_RECTANGLE, left, top, right, bottom);
+}
+
+/***********************************************************************
+ * MFDRV_RoundRect
+ */
+BOOL
+MFDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right,
+ INT bottom, INT ell_width, INT ell_height )
+{
+ return MFDRV_MetaParam6(dev, META_ROUNDRECT, left, top, right, bottom,
+ ell_width, ell_height);
+}
+
+/***********************************************************************
+ * MFDRV_SetPixel
+ */
+COLORREF
+MFDRV_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color )
+{
+ return MFDRV_MetaParam4(dev, META_SETPIXEL, x, y,HIWORD(color),
+ LOWORD(color));
+}
+
+
+/******************************************************************
+ * MFDRV_MetaPoly - implements Polygon and Polyline
+ */
+static BOOL MFDRV_MetaPoly(PHYSDEV dev, short func, LPPOINT16 pt, short count)
+{
+ BOOL ret;
+ DWORD len;
+ METARECORD *mr;
+
+ len = sizeof(METARECORD) + (count * 4);
+ if (!(mr = HeapAlloc( GetProcessHeap(), 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( dev, mr, mr->rdSize * 2);
+ HeapFree( GetProcessHeap(), 0, mr);
+ return ret;
+}
+
+
+/**********************************************************************
+ * MFDRV_Polyline
+ */
+BOOL
+MFDRV_Polyline( PHYSDEV dev, const POINT* pt, INT count )
+{
+ register int i;
+ LPPOINT16 pt16;
+ BOOL16 ret;
+
+ pt16 = (LPPOINT16)HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16)*count );
+ if(!pt16) return FALSE;
+ for (i=count;i--;) CONV_POINT32TO16(&(pt[i]),&(pt16[i]));
+ ret = MFDRV_MetaPoly(dev, META_POLYLINE, pt16, count);
+
+ HeapFree( GetProcessHeap(), 0, pt16 );
+ return ret;
+}
+
+
+/**********************************************************************
+ * MFDRV_Polygon
+ */
+BOOL
+MFDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count )
+{
+ register int i;
+ LPPOINT16 pt16;
+ BOOL16 ret;
+
+ pt16 = (LPPOINT16) HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16)*count );
+ if(!pt16) return FALSE;
+ for (i=count;i--;) CONV_POINT32TO16(&(pt[i]),&(pt16[i]));
+ ret = MFDRV_MetaPoly(dev, META_POLYGON, pt16, count);
+
+ HeapFree( GetProcessHeap(), 0, pt16 );
+ return ret;
+}
+
+
+/**********************************************************************
+ * MFDRV_PolyPolygon
+ */
+BOOL
+MFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polygons)
+{
+ BOOL ret;
+ DWORD len;
+ METARECORD *mr;
+ int i,j;
+ LPPOINT16 pt16;
+ INT16 totalpoint16 = 0;
+ INT16 * pointcounts;
+
+ for (i=0;i<polygons;i++) {
+ totalpoint16 += counts[i];
+ }
+
+ /* allocate space for all points */
+ pt16=(LPPOINT16)HeapAlloc( GetProcessHeap(), 0,
+ sizeof(POINT16) * totalpoint16 );
+ pointcounts = (INT16*)HeapAlloc( GetProcessHeap(), 0,
+ sizeof(INT16) * totalpoint16 );
+
+ /* copy point counts */
+ for (i=0;i<polygons;i++) {
+ pointcounts[i] = counts[i];
+ }
+
+ /* convert all points */
+ for (j = totalpoint16; j--;){
+ CONV_POINT32TO16(&(pt[j]),&(pt16[j]));
+ }
+
+ len = sizeof(METARECORD) + sizeof(WORD) + polygons*sizeof(INT16) + totalpoint16*sizeof(POINT16);
+
+ if (!(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len ))) {
+ HeapFree( GetProcessHeap(), 0, pt16 );
+ HeapFree( GetProcessHeap(), 0, pointcounts );
+ return FALSE;
+ }
+
+ mr->rdSize = len /2;
+ mr->rdFunction = META_POLYPOLYGON;
+ *(mr->rdParm) = polygons;
+ memcpy(mr->rdParm + 1, pointcounts, polygons*sizeof(INT16));
+ memcpy(mr->rdParm + 1+polygons, pt16 , totalpoint16*sizeof(POINT16));
+ ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
+
+ HeapFree( GetProcessHeap(), 0, pt16 );
+ HeapFree( GetProcessHeap(), 0, pointcounts );
+ HeapFree( GetProcessHeap(), 0, mr);
+ return ret;
+}
+
+
+/**********************************************************************
+ * MFDRV_ExtFloodFill
+ */
+BOOL
+MFDRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillType )
+{
+ return MFDRV_MetaParam4(dev,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(PHYSDEV dev, HRGN hrgn)
+{
+ DWORD len;
+ METARECORD *mr;
+ RGNDATA *rgndata;
+ RECT *pCurRect, *pEndRect;
+ WORD Bands = 0, MaxBands = 0;
+ WORD *Param, *StartBand;
+ BOOL ret;
+
+ if (!(len = GetRegionData( hrgn, 0, NULL ))) return -1;
+ if( !(rgndata = HeapAlloc( GetProcessHeap(), 0, len )) ) {
+ WARN("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( GetProcessHeap(), HEAP_ZERO_MEMORY, len )) ) {
+ WARN("Can't alloc METARECORD buffer\n");
+ HeapFree( GetProcessHeap(), 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( dev, mr, mr->rdSize * 2 );
+ HeapFree( GetProcessHeap(), 0, mr );
+ HeapFree( GetProcessHeap(), 0, rgndata );
+ if(!ret)
+ {
+ WARN("MFDRV_WriteRecord failed\n");
+ return -1;
+ }
+ return MFDRV_AddHandle( dev, hrgn );
+}
+
+
+/**********************************************************************
+ * MFDRV_PaintRgn
+ */
+BOOL
+MFDRV_PaintRgn( PHYSDEV dev, HRGN hrgn )
+{
+ INT16 index;
+ index = MFDRV_CreateRegion( dev, hrgn );
+ if(index == -1)
+ return FALSE;
+ return MFDRV_MetaParam1( dev, META_PAINTREGION, index );
+}
+
+
+/**********************************************************************
+ * MFDRV_InvertRgn
+ */
+BOOL
+MFDRV_InvertRgn( PHYSDEV dev, HRGN hrgn )
+{
+ INT16 index;
+ index = MFDRV_CreateRegion( dev, hrgn );
+ if(index == -1)
+ return FALSE;
+ return MFDRV_MetaParam1( dev, META_INVERTREGION, index );
+}
+
+
+/**********************************************************************
+ * MFDRV_FillRgn
+ */
+BOOL
+MFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush )
+{
+ INT16 iRgn, iBrush;
+ iRgn = MFDRV_CreateRegion( dev, hrgn );
+ if(iRgn == -1)
+ return FALSE;
+ iBrush = MFDRV_CreateBrushIndirect( dev, hbrush );
+ if(!iBrush)
+ return FALSE;
+ return MFDRV_MetaParam2( dev, META_FILLREGION, iRgn, iBrush );
+}
+
+/**********************************************************************
+ * MFDRV_FrameRgn
+ */
+BOOL
+MFDRV_FrameRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush, INT x, INT y )
+{
+ INT16 iRgn, iBrush;
+ iRgn = MFDRV_CreateRegion( dev, hrgn );
+ if(iRgn == -1)
+ return FALSE;
+ iBrush = MFDRV_CreateBrushIndirect( dev, hbrush );
+ if(!iBrush)
+ return FALSE;
+ return MFDRV_MetaParam4( dev, META_FRAMEREGION, iRgn, iBrush, x, y );
+}
+
+
+/**********************************************************************
+ * MFDRV_ExtSelectClipRgn
+ */
+INT MFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode )
+{
+ INT16 iRgn;
+ INT ret;
+
+ if (mode != RGN_COPY) return ERROR;
+ if (!hrgn) return NULLREGION;
+ iRgn = MFDRV_CreateRegion( dev, hrgn );
+ if(iRgn == -1) return ERROR;
+ ret = MFDRV_MetaParam1( dev, META_SELECTCLIPREGION, iRgn ) ? NULLREGION : ERROR;
+ MFDRV_MetaParam1( dev, META_DELETEOBJECT, iRgn );
+ return ret;
+}
+
+
+/**********************************************************************
+ * MFDRV_SetBkColor
+ */
+COLORREF
+MFDRV_SetBkColor( PHYSDEV dev, COLORREF color )
+{
+ return MFDRV_MetaParam2(dev, META_SETBKCOLOR, HIWORD(color),
+ LOWORD(color)) ? color : CLR_INVALID;
+}
+
+
+/**********************************************************************
+ * MFDRV_SetTextColor
+ */
+COLORREF
+MFDRV_SetTextColor( PHYSDEV dev, COLORREF color )
+{
+ return MFDRV_MetaParam2(dev, META_SETTEXTCOLOR, HIWORD(color),
+ LOWORD(color)) ? color : CLR_INVALID;
+}
+
+
+/**********************************************************************
+ * MFDRV_PolyBezier
+ * Since MetaFiles don't record Beziers and they don't even record
+ * approximations to them using lines, we need this stub function.
+ */
+BOOL
+MFDRV_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD count )
+{
+ return FALSE;
+}
+
+/**********************************************************************
+ * MFDRV_PolyBezierTo
+ * Since MetaFiles don't record Beziers and they don't even record
+ * approximations to them using lines, we need this stub function.
+ */
+BOOL
+MFDRV_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD count )
+{
+ return FALSE;
+}
+
+/**************************/
+/* Mapping mode functions */
+/**************************/
+
+/***********************************************************************
+ * MFDRV_SetMapMode
+ */
+INT MFDRV_SetMapMode( PHYSDEV dev, INT mode )
+{
+ if(!MFDRV_MetaParam1( dev, META_SETMAPMODE, mode ))
+ return FALSE;
+ return GDI_NO_MORE_WORK;
+}
+
+
+/***********************************************************************
+ * MFDRV_SetViewportExt
+ */
+INT MFDRV_SetViewportExt( PHYSDEV dev, INT x, INT y )
+{
+ if(!MFDRV_MetaParam2( dev, META_SETVIEWPORTEXT, x, y ))
+ return FALSE;
+ return GDI_NO_MORE_WORK;
+}
+
+
+/***********************************************************************
+ * MFDRV_SetViewportOrg
+ */
+INT MFDRV_SetViewportOrg( PHYSDEV dev, INT x, INT y )
+{
+ if(!MFDRV_MetaParam2( dev, META_SETVIEWPORTORG, x, y ))
+ return FALSE;
+ return GDI_NO_MORE_WORK;
+}
+
+
+/***********************************************************************
+ * MFDRV_SetWindowExt
+ */
+INT MFDRV_SetWindowExt( PHYSDEV dev, INT x, INT y )
+{
+ if(!MFDRV_MetaParam2( dev, META_SETWINDOWEXT, x, y ))
+ return FALSE;
+ return GDI_NO_MORE_WORK;
+}
+
+
+/***********************************************************************
+ * MFDRV_SetWindowOrg
+ */
+INT MFDRV_SetWindowOrg( PHYSDEV dev, INT x, INT y )
+{
+ if(!MFDRV_MetaParam2( dev, META_SETWINDOWORG, x, y ))
+ return FALSE;
+ return GDI_NO_MORE_WORK;
+}
+
+
+/***********************************************************************
+ * MFDRV_OffsetViewportOrg
+ */
+INT MFDRV_OffsetViewportOrg( PHYSDEV dev, INT x, INT y )
+{
+ if(!MFDRV_MetaParam2( dev, META_OFFSETVIEWPORTORG, x, y ))
+ return FALSE;
+ return GDI_NO_MORE_WORK;
+}
+
+
+/***********************************************************************
+ * MFDRV_OffsetWindowOrg
+ */
+INT MFDRV_OffsetWindowOrg( PHYSDEV dev, INT x, INT y )
+{
+ if(!MFDRV_MetaParam2( dev, META_OFFSETWINDOWORG, x, y ))
+ return FALSE;
+ return GDI_NO_MORE_WORK;
+}
+
+
+/***********************************************************************
+ * MFDRV_ScaleViewportExt
+ */
+INT MFDRV_ScaleViewportExt( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom )
+{
+ if(!MFDRV_MetaParam4( dev, META_SCALEVIEWPORTEXT, xNum, xDenom, yNum, yDenom ))
+ return FALSE;
+ return GDI_NO_MORE_WORK;
+}
+
+
+/***********************************************************************
+ * MFDRV_ScaleWindowExt
+ */
+INT MFDRV_ScaleWindowExt( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom )
+{
+ if(!MFDRV_MetaParam4( dev, META_SCALEWINDOWEXT, xNum, xDenom, yNum, yDenom ))
+ return FALSE;
+ return GDI_NO_MORE_WORK;
+}
+
+/***************/
+/* GDI objects */
+/***************/
+
+/******************************************************************
+ * MFDRV_AddHandle
+ */
+UINT MFDRV_AddHandle( PHYSDEV dev, HGDIOBJ obj )
+{
+ METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
+ INT16 index;
+
+ for(index = 0; index < physDev->handles_size; index++)
+ if(physDev->handles[index] == 0) break;
+ if(index == physDev->handles_size) {
+ physDev->handles_size += HANDLE_LIST_INC;
+ physDev->handles = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ physDev->handles,
+ physDev->handles_size * sizeof(physDev->handles[0]));
+ }
+ physDev->handles[index] = obj;
+
+ physDev->cur_handles++;
+ if(physDev->cur_handles > physDev->mh->mtNoObjects)
+ physDev->mh->mtNoObjects++;
+
+ return index ; /* index 0 is not reserved for metafiles */
+}
+
+/******************************************************************
+ * MFDRV_FindObject
+ */
+static INT16 MFDRV_FindObject( PHYSDEV dev, HGDIOBJ obj )
+{
+ METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
+ INT16 index;
+
+ for(index = 0; index < physDev->handles_size; index++)
+ if(physDev->handles[index] == obj) break;
+
+ if(index == physDev->handles_size) return -1;
+
+ return index ;
+}
+
+
+/******************************************************************
+ * MFDRV_DeleteObject
+ */
+BOOL MFDRV_DeleteObject( PHYSDEV dev, HGDIOBJ obj )
+{
+ METARECORD mr;
+ METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
+ INT16 index;
+ BOOL ret = TRUE;
+
+ index = MFDRV_FindObject(dev, obj);
+ if( index < 0 )
+ return 0;
+
+ mr.rdSize = sizeof mr / 2;
+ mr.rdFunction = META_DELETEOBJECT;
+ mr.rdParm[0] = index;
+
+ if(!MFDRV_WriteRecord( dev, &mr, mr.rdSize*2 ))
+ ret = FALSE;
+
+ physDev->handles[index] = 0;
+ physDev->cur_handles--;
+ return ret;
+}
+
+
+/***********************************************************************
+ * MFDRV_SelectObject
+ */
+static BOOL MFDRV_SelectObject( PHYSDEV dev, INT16 index)
+{
+ METARECORD mr;
+
+ mr.rdSize = sizeof mr / 2;
+ mr.rdFunction = META_SELECTOBJECT;
+ mr.rdParm[0] = index;
+
+ return MFDRV_WriteRecord( dev, &mr, mr.rdSize*2 );
+}
+
+
+/***********************************************************************
+ * MFDRV_SelectBitmap
+ */
+HBITMAP MFDRV_SelectBitmap( PHYSDEV dev, HBITMAP hbitmap )
+{
+ return 0;
+}
+
+
+/******************************************************************
+ * MFDRV_CreateBrushIndirect
+ */
+
+INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush )
+{
+ DWORD size;
+ METARECORD *mr;
+ LOGBRUSH logbrush;
+ METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
+ BOOL r;
+
+ if (!GetObjectA( hBrush, sizeof(logbrush), &logbrush )) return -1;
+
+ switch(logbrush.lbStyle)
+ {
+ case BS_SOLID:
+ case BS_NULL:
+ case BS_HATCHED:
+ {
+ LOGBRUSH16 lb16;
+
+ lb16.lbStyle = logbrush.lbStyle;
+ lb16.lbColor = logbrush.lbColor;
+ lb16.lbHatch = logbrush.lbHatch;
+ size = sizeof(METARECORD) + sizeof(LOGBRUSH16) - 2;
+ mr = HeapAlloc( GetProcessHeap(), 0, size );
+ mr->rdSize = size / 2;
+ mr->rdFunction = META_CREATEBRUSHINDIRECT;
+ memcpy( mr->rdParm, &lb16, sizeof(LOGBRUSH16));
+ break;
+ }
+ case BS_PATTERN:
+ {
+ BITMAP bm;
+ BYTE *bits;
+ BITMAPINFO *info;
+ DWORD bmSize;
+
+ GetObjectA((HANDLE)logbrush.lbHatch, sizeof(bm), &bm);
+ if(bm.bmBitsPixel != 1 || bm.bmPlanes != 1) {
+ FIXME("Trying to store a colour pattern brush\n");
+ goto done;
+ }
+
+ bmSize = DIB_GetDIBImageBytes(bm.bmWidth, bm.bmHeight, 1);
+
+ size = sizeof(METARECORD) + sizeof(WORD) + sizeof(BITMAPINFO) +
+ sizeof(RGBQUAD) + bmSize;
+
+ mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
+ if(!mr) goto done;
+ mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
+ mr->rdSize = size / 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(physDev->hdc, (HANDLE)logbrush.lbHatch, 0, bm.bmHeight,
+ bits, info, DIB_RGB_COLORS);
+ *(DWORD *)info->bmiColors = 0;
+ *(DWORD *)(info->bmiColors + 1) = 0xffffff;
+ break;
+ }
+
+ case BS_DIBPATTERN:
+ {
+ BITMAPINFO *info;
+ DWORD bmSize, biSize;
+
+ info = GlobalLock16((HGLOBAL16)logbrush.lbHatch);
+ if (info->bmiHeader.biCompression)
+ bmSize = info->bmiHeader.biSizeImage;
+ else
+ bmSize = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
+ info->bmiHeader.biHeight,
+ info->bmiHeader.biBitCount);
+ biSize = DIB_BitmapInfoSize(info, LOWORD(logbrush.lbColor));
+ size = sizeof(METARECORD) + biSize + bmSize + 2;
+ mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
+ if(!mr) goto done;
+ mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
+ mr->rdSize = size / 2;
+ *(mr->rdParm) = logbrush.lbStyle;
+ *(mr->rdParm + 1) = LOWORD(logbrush.lbColor);
+ memcpy(mr->rdParm + 2, info, biSize + bmSize);
+ break;
+ }
+ default:
+ FIXME("Unkonwn brush style %x\n", logbrush.lbStyle);
+ return 0;
+ }
+ r = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
+ HeapFree(GetProcessHeap(), 0, mr);
+ if( !r )
+ return -1;
+done:
+ return MFDRV_AddHandle( dev, hBrush );
+}
+
+
+/***********************************************************************
+ * MFDRV_SelectBrush
+ */
+HBRUSH MFDRV_SelectBrush( PHYSDEV dev, HBRUSH hbrush )
+{
+ METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
+ INT16 index;
+
+ index = MFDRV_FindObject(dev, hbrush);
+ if( index < 0 )
+ {
+ index = MFDRV_CreateBrushIndirect( dev, hbrush );
+ if( index < 0 )
+ return 0;
+ GDI_hdc_using_object(hbrush, physDev->hdc);
+ }
+ return MFDRV_SelectObject( dev, index ) ? hbrush : HGDI_ERROR;
+}
+
+/******************************************************************
+ * MFDRV_CreateFontIndirect
+ */
+
+static UINT16 MFDRV_CreateFontIndirect(PHYSDEV dev, HFONT hFont, LOGFONT16 *logfont)
+{
+ 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( dev, mr, mr->rdSize * 2)))
+ return 0;
+ return MFDRV_AddHandle( dev, hFont );
+}
+
+
+/***********************************************************************
+ * MFDRV_SelectFont
+ */
+HFONT MFDRV_SelectFont( PHYSDEV dev, HFONT hfont, HANDLE gdiFont )
+{
+ METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
+ LOGFONT16 lf16;
+ INT16 index;
+
+ index = MFDRV_FindObject(dev, hfont);
+ if( index < 0 )
+ {
+ if (!GetObject16( HFONT_16(hfont), sizeof(lf16), &lf16 ))
+ return HGDI_ERROR;
+ index = MFDRV_CreateFontIndirect(dev, hfont, &lf16);
+ if( index < 0 )
+ return HGDI_ERROR;
+ GDI_hdc_using_object(hfont, physDev->hdc);
+ }
+ return MFDRV_SelectObject( dev, index ) ? hfont : HGDI_ERROR;
+}
+
+/******************************************************************
+ * MFDRV_CreatePenIndirect
+ */
+static UINT16 MFDRV_CreatePenIndirect(PHYSDEV dev, HPEN hPen, LOGPEN16 *logpen)
+{
+ 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( dev, mr, mr->rdSize * 2)))
+ return 0;
+ return MFDRV_AddHandle( dev, hPen );
+}
+
+
+/***********************************************************************
+ * MFDRV_SelectPen
+ */
+HPEN MFDRV_SelectPen( PHYSDEV dev, HPEN hpen )
+{
+ METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
+ LOGPEN16 logpen;
+ INT16 index;
+
+ index = MFDRV_FindObject(dev, hpen);
+ if( index < 0 )
+ {
+ if (!GetObject16( HPEN_16(hpen), sizeof(logpen), &logpen ))
+ return 0;
+ index = MFDRV_CreatePenIndirect( dev, hpen, &logpen );
+ if( index < 0 )
+ return 0;
+ GDI_hdc_using_object(hpen, physDev->hdc);
+ }
+ return MFDRV_SelectObject( dev, index ) ? hpen : HGDI_ERROR;
+}
+
+
+/******************************************************************
+ * MFDRV_CreatePalette
+ */
+static BOOL MFDRV_CreatePalette(PHYSDEV dev, HPALETTE hPalette, LOGPALETTE* logPalette, int sizeofPalette)
+{
+ int index;
+ BOOL ret;
+ METARECORD *mr;
+
+ mr = HeapAlloc( GetProcessHeap(), 0, sizeof(METARECORD) + sizeofPalette - sizeof(WORD) );
+ mr->rdSize = (sizeof(METARECORD) + sizeofPalette - sizeof(WORD)) / sizeof(WORD);
+ mr->rdFunction = META_CREATEPALETTE;
+ memcpy(&(mr->rdParm), logPalette, sizeofPalette);
+ if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD))))
+ {
+ HeapFree(GetProcessHeap(), 0, mr);
+ return FALSE;
+ }
+
+ mr->rdSize = sizeof(METARECORD) / sizeof(WORD);
+ mr->rdFunction = META_SELECTPALETTE;
+
+ if ((index = MFDRV_AddHandle( dev, hPalette )) == -1) ret = FALSE;
+ else
+ {
+ *(mr->rdParm) = index;
+ ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD));
+ }
+ HeapFree(GetProcessHeap(), 0, mr);
+ return ret;
+}
+
+
+/***********************************************************************
+ * MFDRV_SelectPalette
+ */
+HPALETTE MFDRV_SelectPalette( PHYSDEV dev, HPALETTE hPalette, BOOL bForceBackground )
+{
+#define PALVERSION 0x0300
+
+ PLOGPALETTE logPalette;
+ WORD wNumEntries = 0;
+ BOOL creationSucceed;
+ int sizeofPalette;
+
+ GetObjectA(hPalette, sizeof(WORD), (LPSTR) &wNumEntries);
+
+ if (wNumEntries == 0) return 0;
+
+ sizeofPalette = sizeof(LOGPALETTE) + ((wNumEntries-1) * sizeof(PALETTEENTRY));
+ logPalette = HeapAlloc( GetProcessHeap(), 0, sizeofPalette );
+
+ if (logPalette == NULL) return 0;
+
+ logPalette->palVersion = PALVERSION;
+ logPalette->palNumEntries = wNumEntries;
+
+ GetPaletteEntries(hPalette, 0, wNumEntries, logPalette->palPalEntry);
+
+ creationSucceed = MFDRV_CreatePalette( dev, hPalette, logPalette, sizeofPalette );
+
+ HeapFree( GetProcessHeap(), 0, logPalette );
+
+ if (creationSucceed)
+ return hPalette;
+
+ return 0;
+}
+
+/***********************************************************************
+ * MFDRV_RealizePalette
+ */
+UINT MFDRV_RealizePalette(PHYSDEV dev, HPALETTE hPalette, BOOL dummy)
+{
+ char buffer[sizeof(METARECORD) - sizeof(WORD)];
+ METARECORD *mr = (METARECORD *)&buffer;
+
+ mr->rdSize = (sizeof(METARECORD) - sizeof(WORD)) / sizeof(WORD);
+ mr->rdFunction = META_REALIZEPALETTE;
+
+ if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD)))) return 0;
+
+ /* The return value is suppose to be the number of entries
+ in the logical palette mapped to the system palette or 0
+ if the function failed. Since it's not trivial here to
+ get that kind of information and since it's of little
+ use in the case of metafiles, we'll always return 1. */
+ return 1;
+}
+
+/******************/
+/* Text functions */
+/******************/
+
+/******************************************************************
+ * MFDRV_MetaExtTextOut
+ */
+static BOOL MFDRV_MetaExtTextOut( PHYSDEV dev, short x, short y, UINT16 flags,
+ const RECT16 *rect, LPCSTR str, short count,
+ const INT16 *lpDx)
+{
+ BOOL ret;
+ DWORD len;
+ METARECORD *mr;
+ BOOL isrect = flags & (ETO_CLIPPED | ETO_OPAQUE);
+
+ len = sizeof(METARECORD) + (((count + 1) >> 1) * 2) + 2 * sizeof(short)
+ + sizeof(UINT16);
+ if (isrect)
+ len += sizeof(RECT16);
+ if (lpDx)
+ len+=count*sizeof(INT16);
+ if (!(mr = HeapAlloc( GetProcessHeap(), 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 (isrect) memcpy(mr->rdParm + 4, rect, sizeof(RECT16));
+ memcpy(mr->rdParm + (isrect ? 8 : 4), str, count);
+ if (lpDx)
+ memcpy(mr->rdParm + (isrect ? 8 : 4) + ((count + 1) >> 1),lpDx,
+ count*sizeof(INT16));
+ ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
+ HeapFree( GetProcessHeap(), 0, mr);
+ return ret;
+}
+
+
+
+/***********************************************************************
+ * MFDRV_ExtTextOut
+ */
+BOOL
+MFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
+ const RECT *lprect, LPCWSTR str, UINT count,
+ const INT *lpDx, INT breakExtra )
+{
+ RECT16 rect16;
+ LPINT16 lpdx16 = NULL;
+ BOOL ret;
+ int i, j;
+ LPSTR ascii;
+ DWORD len;
+ CHARSETINFO csi;
+ METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
+ int charset = GetTextCharset(physDev->hdc);
+ UINT cp = CP_ACP;
+
+ if(TranslateCharsetInfo((DWORD*)charset, &csi, TCI_SRCCHARSET))
+ cp = csi.ciACP;
+ else {
+ switch(charset) {
+ case OEM_CHARSET:
+ cp = GetOEMCP();
+ break;
+ case DEFAULT_CHARSET:
+ cp = GetACP();
+ break;
+
+ case VISCII_CHARSET:
+ case TCVN_CHARSET:
+ case KOI8_CHARSET:
+ case ISO3_CHARSET:
+ case ISO4_CHARSET:
+ case ISO10_CHARSET:
+ case CELTIC_CHARSET:
+ /* FIXME: These have no place here, but because x11drv
+ enumerates fonts with these (made up) charsets some apps
+ might use them and then the FIXME below would become
+ annoying. Now we could pick the intended codepage for
+ each of these, but since it's broken anyway we'll just
+ use CP_ACP and hope it'll go away...
+ */
+ cp = CP_ACP;
+ break;
+
+
+ default:
+ FIXME("Can't find codepage for charset %d\n", charset);
+ break;
+ }
+ }
+
+
+ TRACE("cp == %d\n", cp);
+ len = WideCharToMultiByte(cp, 0, str, count, NULL, 0, NULL, NULL);
+ ascii = HeapAlloc(GetProcessHeap(), 0, len);
+ WideCharToMultiByte(cp, 0, str, count, ascii, len, NULL, NULL);
+ TRACE("mapped %s -> %s\n", debugstr_wn(str, count), debugstr_an(ascii, len));
+
+
+ if (lprect) CONV_RECT32TO16(lprect,&rect16);
+
+ if(lpDx) {
+ lpdx16 = HeapAlloc( GetProcessHeap(), 0, sizeof(INT16)*len );
+ for(i = j = 0; i < len; )
+ if(IsDBCSLeadByteEx(cp, ascii[i])) {
+ lpdx16[i++] = lpDx[j++];
+ lpdx16[i++] = 0;
+ } else
+ lpdx16[i++] = lpDx[j++];
+ }
+
+ ret = MFDRV_MetaExtTextOut(dev,x,y,flags,lprect?&rect16:NULL,ascii,len,lpdx16);
+ HeapFree( GetProcessHeap(), 0, ascii );
+ if (lpdx16) HeapFree( GetProcessHeap(), 0, lpdx16 );
+ return ret;
+}
+
+/****************************/
+/* Initialisation functions */
+/****************************/
+
+static const DC_FUNCTIONS MFDRV_Funcs =
+{
+ NULL, /* pAbortDoc */
+ MFDRV_AbortPath, /* pAbortPath */
+ NULL, /* pAngleArc */
+ MFDRV_Arc, /* pArc */
+ NULL, /* pArcTo */
+ MFDRV_BeginPath, /* pBeginPath */
+ MFDRV_BitBlt, /* pBitBlt */
+ NULL, /* pChoosePixelFormat */
+ MFDRV_Chord, /* pChord */
+ MFDRV_CloseFigure, /* pCloseFigure */
+ NULL, /* pCreateBitmap */
+ NULL, /* pCreateDC */
+ NULL, /* pCreateDIBSection */
+ NULL, /* pDeleteBitmap */
+ NULL, /* pDeleteDC */
+ MFDRV_DeleteObject, /* pDeleteObject */
+ NULL, /* pDescribePixelFormat */
+ NULL, /* pDeviceCapabilities */
+ MFDRV_Ellipse, /* pEllipse */
+ NULL, /* pEndDoc */
+ NULL, /* pEndPage */
+ MFDRV_EndPath, /* pEndPath */
+ NULL, /* pEnumDeviceFonts */
+ MFDRV_ExcludeClipRect, /* pExcludeClipRect */
+ NULL, /* pExtDeviceMode */
+ MFDRV_ExtEscape, /* pExtEscape */
+ MFDRV_ExtFloodFill, /* pExtFloodFill */
+ MFDRV_ExtSelectClipRgn, /* pExtSelectClipRgn */
+ MFDRV_ExtTextOut, /* pExtTextOut */
+ MFDRV_FillPath, /* pFillPath */
+ MFDRV_FillRgn, /* pFillRgn */
+ MFDRV_FlattenPath, /* pFlattenPath */
+ MFDRV_FrameRgn, /* pFrameRgn */
+ NULL, /* pGdiComment */
+ NULL, /* pGetBitmapBits */
+ NULL, /* pGetCharWidth */
+ NULL, /* pGetDCOrgEx */
+ NULL, /* pGetDIBColorTable */
+ NULL, /* pGetDIBits */
+ MFDRV_GetDeviceCaps, /* pGetDeviceCaps */
+ NULL, /* pGetDeviceGammaRamp */
+ NULL, /* pGetNearestColor */
+ NULL, /* pGetPixel */
+ NULL, /* pGetPixelFormat */
+ NULL, /* pGetSystemPaletteEntries */
+ NULL, /* pGetTextExtentPoint */
+ NULL, /* pGetTextMetrics */
+ MFDRV_IntersectClipRect, /* pIntersectClipRect */
+ MFDRV_InvertRgn, /* pInvertRgn */
+ MFDRV_LineTo, /* pLineTo */
+ NULL, /* pModifyWorldTransform */
+ MFDRV_MoveTo, /* pMoveTo */
+ MFDRV_OffsetClipRgn, /* pOffsetClipRgn */
+ MFDRV_OffsetViewportOrg, /* pOffsetViewportOrg */
+ MFDRV_OffsetWindowOrg, /* pOffsetWindowOrg */
+ MFDRV_PaintRgn, /* pPaintRgn */
+ MFDRV_PatBlt, /* pPatBlt */
+ MFDRV_Pie, /* pPie */
+ MFDRV_PolyBezier, /* pPolyBezier */
+ MFDRV_PolyBezierTo, /* pPolyBezierTo */
+ NULL, /* pPolyDraw */
+ MFDRV_PolyPolygon, /* pPolyPolygon */
+ NULL, /* pPolyPolyline */
+ MFDRV_Polygon, /* pPolygon */
+ MFDRV_Polyline, /* pPolyline */
+ NULL, /* pPolylineTo */
+ NULL, /* pRealizeDefaultPalette */
+ MFDRV_RealizePalette, /* pRealizePalette */
+ MFDRV_Rectangle, /* pRectangle */
+ NULL, /* pResetDC */
+ MFDRV_RestoreDC, /* pRestoreDC */
+ MFDRV_RoundRect, /* pRoundRect */
+ MFDRV_SaveDC, /* pSaveDC */
+ MFDRV_ScaleViewportExt, /* pScaleViewportExt */
+ MFDRV_ScaleWindowExt, /* pScaleWindowExt */
+ MFDRV_SelectBitmap, /* pSelectBitmap */
+ MFDRV_SelectBrush, /* pSelectBrush */
+ MFDRV_SelectClipPath, /* pSelectClipPath */
+ MFDRV_SelectFont, /* pSelectFont */
+ MFDRV_SelectPalette, /* pSelectPalette */
+ MFDRV_SelectPen, /* pSelectPen */
+ NULL, /* pSetArcDirection */
+ NULL, /* pSetBitmapBits */
+ MFDRV_SetBkColor, /* pSetBkColor */
+ MFDRV_SetBkMode, /* pSetBkMode */
+ NULL, /* pSetDCBrushColor*/
+ NULL, /* pSetDCOrg */
+ NULL, /* pSetDCPenColor*/
+ NULL, /* pSetDIBColorTable */
+ NULL, /* pSetDIBits */
+ MFDRV_SetDIBitsToDevice, /* pSetDIBitsToDevice */
+ NULL, /* pSetDeviceClipping */
+ NULL, /* pSetDeviceGammaRamp */
+ MFDRV_SetMapMode, /* pSetMapMode */
+ MFDRV_SetMapperFlags, /* pSetMapperFlags */
+ MFDRV_SetPixel, /* pSetPixel */
+ NULL, /* pSetPixelFormat */
+ MFDRV_SetPolyFillMode, /* pSetPolyFillMode */
+ MFDRV_SetROP2, /* pSetROP2 */
+ MFDRV_SetRelAbs, /* pSetRelAbs */
+ MFDRV_SetStretchBltMode, /* pSetStretchBltMode */
+ MFDRV_SetTextAlign, /* pSetTextAlign */
+ MFDRV_SetTextCharacterExtra, /* pSetTextCharacterExtra */
+ MFDRV_SetTextColor, /* pSetTextColor */
+ MFDRV_SetTextJustification, /* pSetTextJustification */
+ MFDRV_SetViewportExt, /* pSetViewportExt */
+ MFDRV_SetViewportOrg, /* pSetViewportOrg */
+ MFDRV_SetWindowExt, /* pSetWindowExt */
+ MFDRV_SetWindowOrg, /* pSetWindowOrg */
+ NULL, /* pSetWorldTransform */
+ NULL, /* pStartDoc */
+ NULL, /* pStartPage */
+ MFDRV_StretchBlt, /* pStretchBlt */
+ MFDRV_StretchDIBits, /* pStretchDIBits */
+ MFDRV_StrokeAndFillPath, /* pStrokeAndFillPath */
+ MFDRV_StrokePath, /* pStrokePath */
+ NULL, /* pSwapBuffers */
+ MFDRV_WidenPath /* pWidenPath */
+};
+
+
+
+/**********************************************************************
+ * MFDRV_AllocMetaFile
+ */
+static DC *MFDRV_AllocMetaFile(void)
+{
+ DC *dc;
+ METAFILEDRV_PDEVICE *physDev;
+
+ if (!(dc = DC_AllocDC( &MFDRV_Funcs, METAFILE_DC_MAGIC ))) return NULL;
+
+ physDev = (METAFILEDRV_PDEVICE *)HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
+ if (!physDev)
+ {
+ GDI_FreeObject( dc->hSelf, dc );
+ return NULL;
+ }
+ dc->physDev = (PHYSDEV)physDev;
+ physDev->hdc = dc->hSelf;
+ physDev->dc = dc;
+
+ if (!(physDev->mh = HeapAlloc( GetProcessHeap(), 0, sizeof(*physDev->mh) )))
+ {
+ HeapFree( GetProcessHeap(), 0, physDev );
+ GDI_FreeObject( dc->hSelf, dc );
+ return NULL;
+ }
+
+ physDev->handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, HANDLE_LIST_INC * sizeof(physDev->handles[0]));
+ physDev->handles_size = HANDLE_LIST_INC;
+ physDev->cur_handles = 0;
+
+ physDev->hFile = 0;
+
+ physDev->mh->mtHeaderSize = sizeof(METAHEADER) / sizeof(WORD);
+ physDev->mh->mtVersion = 0x0300;
+ physDev->mh->mtSize = physDev->mh->mtHeaderSize;
+ physDev->mh->mtNoObjects = 0;
+ physDev->mh->mtMaxRecord = 0;
+ physDev->mh->mtNoParameters = 0;
+
+ return dc;
+}
+
+
+/**********************************************************************
+ * MFDRV_DeleteDC
+ */
+static BOOL MFDRV_DeleteDC( PHYSDEV dev )
+{
+ METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
+ DC *dc = physDev->dc;
+ DWORD index;
+
+ if (physDev->mh) HeapFree( GetProcessHeap(), 0, physDev->mh );
+ for(index = 0; index < physDev->handles_size; index++)
+ if(physDev->handles[index])
+ GDI_hdc_not_using_object(physDev->handles[index], physDev->hdc);
+ HeapFree( GetProcessHeap(), 0, physDev->handles );
+ HeapFree( GetProcessHeap(), 0, physDev );
+ dc->physDev = NULL;
+ GDI_FreeObject( dc->hSelf, dc );
+ return TRUE;
+}
+
+
+/**********************************************************************
+ * CreateMetaFileW (GDI32.@)
+ *
+ * Create a new DC and associate it with a metafile. Pass a filename
+ * to create a disk-based metafile, NULL to create a memory metafile.
+ *
+ * RETURNS
+ * A handle to the metafile DC if successful, NULL on failure.
+ */
+HDC WINAPI CreateMetaFileW( LPCWSTR filename ) /* [in] Filename of disk metafile */
+{
+ HDC ret;
+ DC *dc;
+ METAFILEDRV_PDEVICE *physDev;
+ HANDLE hFile;
+
+ TRACE("'%s'\n", debugstr_w(filename) );
+
+ if (!(dc = MFDRV_AllocMetaFile())) return 0;
+ physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
+
+ if (filename) /* disk based metafile */
+ {
+ physDev->mh->mtType = METAFILE_DISK;
+ if ((hFile = CreateFileW(filename, GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) {
+ MFDRV_DeleteDC( dc->physDev );
+ return 0;
+ }
+ if (!WriteFile( hFile, physDev->mh, sizeof(*physDev->mh), NULL,
+ NULL )) {
+ MFDRV_DeleteDC( dc->physDev );
+ return 0;
+ }
+ physDev->hFile = hFile;
+
+ /* Grow METAHEADER to include filename */
+ physDev->mh = MF_CreateMetaHeaderDisk(physDev->mh, filename, TRUE);
+ }
+ else /* memory based metafile */
+ physDev->mh->mtType = METAFILE_MEMORY;
+
+ TRACE("returning %p\n", dc->hSelf);
+ ret = dc->hSelf;
+ GDI_ReleaseObj( dc->hSelf );
+ return ret;
+}
+
+/**********************************************************************
+ * CreateMetaFileA (GDI32.@)
+ */
+HDC WINAPI CreateMetaFileA(LPCSTR filename)
+{
+ LPWSTR filenameW;
+ DWORD len;
+ HDC hReturnDC;
+
+ if (!filename) return CreateMetaFileW(NULL);
+
+ len = MultiByteToWideChar( CP_ACP, 0, filename, -1, NULL, 0 );
+ filenameW = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
+ MultiByteToWideChar( CP_ACP, 0, filename, -1, filenameW, len );
+
+ hReturnDC = CreateMetaFileW(filenameW);
+
+ HeapFree( GetProcessHeap(), 0, filenameW );
+
+ return hReturnDC;
+}
+
+
+/**********************************************************************
+ * MFDRV_CloseMetaFile
+ */
+static DC *MFDRV_CloseMetaFile( HDC hdc )
+{
+ DC *dc;
+ METAFILEDRV_PDEVICE *physDev;
+
+ TRACE("(%p)\n", hdc );
+
+ if (!(dc = (DC *) GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC ))) return 0;
+ physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
+
+ /* Construct the end of metafile record - this is documented
+ * in SDK Knowledgebase Q99334.
+ */
+
+ if (!MFDRV_MetaParam0(dc->physDev, META_EOF))
+ {
+ MFDRV_DeleteDC( dc->physDev );
+ return 0;
+ }
+
+ if (physDev->mh->mtType == METAFILE_DISK) /* disk based metafile */
+ {
+ if (SetFilePointer(physDev->hFile, 0, NULL, FILE_BEGIN) != 0) {
+ MFDRV_DeleteDC( dc->physDev );
+ return 0;
+ }
+
+ 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->physDev );
+ return 0;
+ }
+ CloseHandle(physDev->hFile);
+ physDev->mh->mtType = METAFILE_DISK;
+ }
+
+ return dc;
+}
+
+/******************************************************************
+ * CloseMetaFile (GDI.126)
+ */
+HMETAFILE16 WINAPI CloseMetaFile16(
+ HDC16 hdc /* [in] Metafile DC to close */
+)
+{
+ HMETAFILE16 hmf;
+ METAFILEDRV_PDEVICE *physDev;
+ DC *dc = MFDRV_CloseMetaFile(HDC_32(hdc));
+ if (!dc) return 0;
+ physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
+
+ /* Now allocate a global handle for the metafile */
+
+ hmf = MF_Create_HMETAFILE16( physDev->mh );
+
+ physDev->mh = NULL; /* So it won't be deleted */
+ MFDRV_DeleteDC( dc->physDev );
+ return hmf;
+}
+
+/******************************************************************
+ * CloseMetaFile (GDI32.@)
+ *
+ * Stop recording graphics operations in metafile associated with
+ * hdc and retrieve metafile.
+ *
+ * RETURNS
+ * Handle of newly created metafile on success, NULL on failure.
+ */
+HMETAFILE WINAPI CloseMetaFile(
+ HDC hdc /* [in] Metafile DC to close */
+)
+{
+ 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->physDev );
+ return hmf;
+}
+
+
+/******************************************************************
+ * MFDRV_WriteRecord
+ *
+ * Warning: this function can change the pointer to the metafile header.
+ */
+BOOL MFDRV_WriteRecord( PHYSDEV dev, METARECORD *mr, DWORD rlen)
+{
+ DWORD len, size;
+ METAHEADER *mh;
+ METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
+
+ switch(physDev->mh->mtType)
+ {
+ case METAFILE_MEMORY:
+ len = physDev->mh->mtSize * 2 + rlen;
+ /* reallocate memory if needed */
+ size = HeapSize( GetProcessHeap(), 0, physDev->mh );
+ if (len > size)
+ {
+ /*expand size*/
+ size += size / 2 + rlen;
+ mh = HeapReAlloc( GetProcessHeap(), 0, physDev->mh, size);
+ if (!mh) return FALSE;
+ physDev->mh = mh;
+ TRACE("Reallocated metafile: new size is %ld\n",size);
+ }
+ memcpy((WORD *)physDev->mh + physDev->mh->mtSize, mr, rlen);
+ break;
+ case METAFILE_DISK:
+ TRACE("Writing record to disk\n");
+ if (!WriteFile(physDev->hFile, (char *)mr, rlen, NULL, NULL))
+ return FALSE;
+ break;
+ default:
+ ERR("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 MFDRV_MetaParam0(PHYSDEV dev, short func)
+{
+ char buffer[8];
+ METARECORD *mr = (METARECORD *)&buffer;
+
+ mr->rdSize = 3;
+ mr->rdFunction = func;
+ return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ * MFDRV_MetaParam1
+ */
+BOOL MFDRV_MetaParam1(PHYSDEV dev, short func, short param1)
+{
+ char buffer[8];
+ METARECORD *mr = (METARECORD *)&buffer;
+
+ mr->rdSize = 4;
+ mr->rdFunction = func;
+ *(mr->rdParm) = param1;
+ return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ * MFDRV_MetaParam2
+ */
+BOOL MFDRV_MetaParam2(PHYSDEV dev, 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( dev, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ * MFDRV_MetaParam4
+ */
+
+BOOL MFDRV_MetaParam4(PHYSDEV dev, 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( dev, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ * MFDRV_MetaParam6
+ */
+
+BOOL MFDRV_MetaParam6(PHYSDEV dev, 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( dev, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ * MFDRV_MetaParam8
+ */
+BOOL MFDRV_MetaParam8(PHYSDEV dev, 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( dev, mr, mr->rdSize * 2);
+}
+
+
+/**********************************************************************
+ * MFDRV_ExtEscape
+ */
+INT MFDRV_ExtEscape( PHYSDEV dev, INT nEscape, INT cbInput, LPCVOID in_data,
+ INT cbOutput, LPVOID out_data )
+{
+ METARECORD *mr;
+ DWORD len;
+ INT ret;
+
+ len = sizeof(*mr) + sizeof(WORD) + ((cbInput + 1) & ~1);
+ mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
+ mr->rdSize = len / 2;
+ mr->rdFunction = META_ESCAPE;
+ mr->rdParm[0] = nEscape;
+ mr->rdParm[1] = cbInput;
+ memcpy(&(mr->rdParm[2]), in_data, cbInput);
+ ret = MFDRV_WriteRecord( dev, mr, len);
+ HeapFree(GetProcessHeap(), 0, mr);
+ return ret;
+}
+
+
+/******************************************************************
+ * MFDRV_GetDeviceCaps
+ *
+ *A very simple implementation that returns DT_METAFILE
+ */
+INT MFDRV_GetDeviceCaps(PHYSDEV dev, INT cap)
+{
+ switch(cap)
+ {
+ case TECHNOLOGY:
+ return DT_METAFILE;
+ case TEXTCAPS:
+ return 0;
+ default:
+ TRACE(" unsupported capability %d, will return 0\n", cap );
+ }
+ return 0;
+}
--
Dimi.
More information about the wine-patches
mailing list