Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Metafile driver initialisation functions |
| 3 | * |
| 4 | * Copyright 1996 Alexandre Julliard |
| 5 | */ |
| 6 | |
Marcus Meissner | 317af32 | 1999-02-17 13:51:06 +0000 | [diff] [blame] | 7 | #include "windef.h" |
| 8 | #include "wine/winbase16.h" |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 9 | #include "dc.h" |
| 10 | #include "heap.h" |
| 11 | #include "global.h" |
| 12 | #include "metafile.h" |
Marcus Meissner | 317af32 | 1999-02-17 13:51:06 +0000 | [diff] [blame] | 13 | #include "metafiledrv.h" |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 14 | #include "debug.h" |
| 15 | |
Patrik Stridvall | b4b9fae | 1999-04-19 14:56:29 +0000 | [diff] [blame] | 16 | DEFAULT_DEBUG_CHANNEL(metafile) |
| 17 | |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 18 | #include <string.h> |
| 19 | |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 20 | static const DC_FUNCTIONS MFDRV_Funcs = |
| 21 | { |
Huw D M Davies | e39b676 | 1999-05-17 16:20:51 +0000 | [diff] [blame^] | 22 | NULL, /* pAbortDoc */ |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 23 | MFDRV_Arc, /* pArc */ |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 24 | MFDRV_BitBlt, /* pBitBlt */ |
Huw D M Davies | 87f87bf | 1998-10-28 09:53:53 +0000 | [diff] [blame] | 25 | NULL, /* pBitmapBits */ |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 26 | MFDRV_Chord, /* pChord */ |
Huw D M Davies | 87f87bf | 1998-10-28 09:53:53 +0000 | [diff] [blame] | 27 | NULL, /* pCreateBitmap */ |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 28 | NULL, /* no implementation */ /* pCreateDC */ |
Patrik Stridvall | b87fe2e | 1999-04-01 08:16:08 +0000 | [diff] [blame] | 29 | NULL, /* pCreateDIBSection */ |
| 30 | NULL, /* pCreateDIBSection16 */ |
Huw D M Davies | e39b676 | 1999-05-17 16:20:51 +0000 | [diff] [blame^] | 31 | NULL, /* no implementation */ /* pDeleteDC */ |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 32 | NULL, /* pDeleteObject */ |
Huw D M Davies | e39b676 | 1999-05-17 16:20:51 +0000 | [diff] [blame^] | 33 | NULL, /* pDeviceCapabilities */ |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 34 | MFDRV_Ellipse, /* pEllipse */ |
Huw D M Davies | e39b676 | 1999-05-17 16:20:51 +0000 | [diff] [blame^] | 35 | NULL, /* pEndDoc */ |
| 36 | NULL, /* pEndPage */ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 37 | NULL, /* pEnumDeviceFonts */ |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 38 | NULL, /* pEscape */ |
Huw D M Davies | 7603dea | 1999-04-25 09:24:23 +0000 | [diff] [blame] | 39 | MFDRV_ExcludeClipRect, /* pExcludeClipRect */ |
Huw D M Davies | e39b676 | 1999-05-17 16:20:51 +0000 | [diff] [blame^] | 40 | NULL, /* pExtDeviceMode */ |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 41 | MFDRV_ExtFloodFill, /* pExtFloodFill */ |
| 42 | MFDRV_ExtTextOut, /* pExtTextOut */ |
Huw D M Davies | 7603dea | 1999-04-25 09:24:23 +0000 | [diff] [blame] | 43 | MFDRV_FillRgn, /* pFillRgn */ |
| 44 | MFDRV_FrameRgn, /* pFrameRgn */ |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 45 | NULL, /* pGetCharWidth */ |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 46 | NULL, /* no implementation */ /* pGetPixel */ |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 47 | NULL, /* pGetTextExtentPoint */ |
| 48 | NULL, /* pGetTextMetrics */ |
Huw D M Davies | 7603dea | 1999-04-25 09:24:23 +0000 | [diff] [blame] | 49 | MFDRV_IntersectClipRect, /* pIntersectClipRect */ |
| 50 | MFDRV_InvertRgn, /* pInvertRgn */ |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 51 | MFDRV_LineTo, /* pLineTo */ |
Huw D M Davies | d6a91b7 | 1998-12-02 10:29:04 +0000 | [diff] [blame] | 52 | NULL, /* pLoadOEMResource */ |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 53 | MFDRV_MoveToEx, /* pMoveToEx */ |
Huw D M Davies | 7603dea | 1999-04-25 09:24:23 +0000 | [diff] [blame] | 54 | MFDRV_OffsetClipRgn, /* pOffsetClipRgn */ |
Alexandre Julliard | 7ebe1a4 | 1996-12-22 18:27:48 +0000 | [diff] [blame] | 55 | MFDRV_OffsetViewportOrg, /* pOffsetViewportOrg */ |
| 56 | MFDRV_OffsetWindowOrg, /* pOffsetWindowOrg */ |
Alexandre Julliard | 0623a6f | 1998-01-18 18:01:49 +0000 | [diff] [blame] | 57 | MFDRV_PaintRgn, /* pPaintRgn */ |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 58 | MFDRV_PatBlt, /* pPatBlt */ |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 59 | MFDRV_Pie, /* pPie */ |
| 60 | MFDRV_PolyPolygon, /* pPolyPolygon */ |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 61 | NULL, /* pPolyPolyline */ |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 62 | MFDRV_Polygon, /* pPolygon */ |
| 63 | MFDRV_Polyline, /* pPolyline */ |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame] | 64 | NULL, /* pPolyBezier */ |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 65 | NULL, /* pRealizePalette */ |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 66 | MFDRV_Rectangle, /* pRectangle */ |
Huw D M Davies | 7603dea | 1999-04-25 09:24:23 +0000 | [diff] [blame] | 67 | MFDRV_RestoreDC, /* pRestoreDC */ |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 68 | MFDRV_RoundRect, /* pRoundRect */ |
Huw D M Davies | 7603dea | 1999-04-25 09:24:23 +0000 | [diff] [blame] | 69 | MFDRV_SaveDC, /* pSaveDC */ |
Alexandre Julliard | 7ebe1a4 | 1996-12-22 18:27:48 +0000 | [diff] [blame] | 70 | MFDRV_ScaleViewportExt, /* pScaleViewportExt */ |
| 71 | MFDRV_ScaleWindowExt, /* pScaleWindowExt */ |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 72 | NULL, /* pSelectClipRgn */ |
Alexandre Julliard | 349a953 | 1997-02-02 19:01:52 +0000 | [diff] [blame] | 73 | MFDRV_SelectObject, /* pSelectObject */ |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 74 | NULL, /* pSelectPalette */ |
Alexandre Julliard | a0d7731 | 1998-09-13 16:32:00 +0000 | [diff] [blame] | 75 | MFDRV_SetBkColor, /* pSetBkColor */ |
Huw D M Davies | 7603dea | 1999-04-25 09:24:23 +0000 | [diff] [blame] | 76 | MFDRV_SetBkMode, /* pSetBkMode */ |
Alexandre Julliard | 530ee84 | 1996-10-23 16:59:13 +0000 | [diff] [blame] | 77 | NULL, /* pSetDeviceClipping */ |
Huw D M Davies | 56166a6 | 1999-04-19 16:45:24 +0000 | [diff] [blame] | 78 | MFDRV_SetDIBitsToDevice, /* pSetDIBitsToDevice */ |
Alexandre Julliard | 7ebe1a4 | 1996-12-22 18:27:48 +0000 | [diff] [blame] | 79 | MFDRV_SetMapMode, /* pSetMapMode */ |
Huw D M Davies | 7603dea | 1999-04-25 09:24:23 +0000 | [diff] [blame] | 80 | MFDRV_SetMapperFlags, /* pSetMapperFlags */ |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 81 | MFDRV_SetPixel, /* pSetPixel */ |
Huw D M Davies | 7603dea | 1999-04-25 09:24:23 +0000 | [diff] [blame] | 82 | MFDRV_SetPolyFillMode, /* pSetPolyFillMode */ |
| 83 | MFDRV_SetROP2, /* pSetROP2 */ |
| 84 | MFDRV_SetRelAbs, /* pSetRelAbs */ |
| 85 | MFDRV_SetStretchBltMode, /* pSetStretchBltMode */ |
| 86 | MFDRV_SetTextAlign, /* pSetTextAlign */ |
| 87 | MFDRV_SetTextCharacterExtra, /* pSetTextCharacterExtra */ |
Alexandre Julliard | a0d7731 | 1998-09-13 16:32:00 +0000 | [diff] [blame] | 88 | MFDRV_SetTextColor, /* pSetTextColor */ |
Huw D M Davies | 7603dea | 1999-04-25 09:24:23 +0000 | [diff] [blame] | 89 | MFDRV_SetTextJustification, /* pSetTextJustification */ |
Alexandre Julliard | 7ebe1a4 | 1996-12-22 18:27:48 +0000 | [diff] [blame] | 90 | MFDRV_SetViewportExt, /* pSetViewportExt */ |
| 91 | MFDRV_SetViewportOrg, /* pSetViewportOrg */ |
| 92 | MFDRV_SetWindowExt, /* pSetWindowExt */ |
| 93 | MFDRV_SetWindowOrg, /* pSetWindowOrg */ |
Huw D M Davies | e39b676 | 1999-05-17 16:20:51 +0000 | [diff] [blame^] | 94 | NULL, /* pStartDoc */ |
| 95 | NULL, /* pStartPage */ |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 96 | MFDRV_StretchBlt, /* pStretchBlt */ |
Huw D M Davies | 56166a6 | 1999-04-19 16:45:24 +0000 | [diff] [blame] | 97 | MFDRV_StretchDIBits /* pStretchDIBits */ |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 98 | }; |
| 99 | |
| 100 | |
| 101 | |
| 102 | /********************************************************************** |
| 103 | * MFDRV_AllocMetaFile |
| 104 | */ |
| 105 | static DC *MFDRV_AllocMetaFile(void) |
| 106 | { |
| 107 | DC *dc; |
| 108 | METAFILEDRV_PDEVICE *physDev; |
| 109 | |
| 110 | if (!(dc = DC_AllocDC( &MFDRV_Funcs ))) return NULL; |
| 111 | dc->header.wMagic = METAFILE_DC_MAGIC; |
| 112 | |
| 113 | physDev = (METAFILEDRV_PDEVICE *)HeapAlloc(SystemHeap,0,sizeof(*physDev)); |
| 114 | if (!physDev) |
| 115 | { |
| 116 | GDI_HEAP_FREE( dc->hSelf ); |
| 117 | return NULL; |
| 118 | } |
| 119 | dc->physDev = physDev; |
| 120 | |
| 121 | if (!(physDev->mh = HeapAlloc( SystemHeap, 0, sizeof(*physDev->mh) ))) |
| 122 | { |
| 123 | HeapFree( SystemHeap, 0, physDev ); |
| 124 | GDI_HEAP_FREE( dc->hSelf ); |
| 125 | return NULL; |
| 126 | } |
| 127 | |
| 128 | physDev->nextHandle = 0; |
Huw D M Davies | b94e433 | 1999-04-15 16:46:51 +0000 | [diff] [blame] | 129 | physDev->hFile = 0; |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 130 | |
| 131 | physDev->mh->mtHeaderSize = sizeof(METAHEADER) / sizeof(WORD); |
| 132 | physDev->mh->mtVersion = 0x0300; |
| 133 | physDev->mh->mtSize = physDev->mh->mtHeaderSize; |
| 134 | physDev->mh->mtNoObjects = 0; |
| 135 | physDev->mh->mtMaxRecord = 0; |
| 136 | physDev->mh->mtNoParameters = 0; |
| 137 | |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 138 | return dc; |
| 139 | } |
| 140 | |
| 141 | |
| 142 | /********************************************************************** |
Huw D M Davies | b94e433 | 1999-04-15 16:46:51 +0000 | [diff] [blame] | 143 | * MFDRV_DeleteDC |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 144 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 145 | static BOOL MFDRV_DeleteDC( DC *dc ) |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 146 | { |
| 147 | METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dc->physDev; |
| 148 | |
| 149 | if (physDev->mh) HeapFree( SystemHeap, 0, physDev->mh ); |
| 150 | HeapFree( SystemHeap, 0, physDev ); |
| 151 | dc->physDev = NULL; |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 152 | GDI_FreeObject(dc->hSelf); |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 153 | return TRUE; |
| 154 | } |
| 155 | |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 156 | /********************************************************************** |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 157 | * CreateMetaFile16 (GDI.125) |
| 158 | * |
| 159 | * Create a new DC and associate it with a metafile. Pass a filename |
| 160 | * to create a disk-based metafile, NULL to create a memory metafile. |
| 161 | * |
| 162 | * RETURNS |
| 163 | * A handle to the metafile DC if successful, NULL on failure. |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 164 | */ |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 165 | HDC16 WINAPI CreateMetaFile16( |
| 166 | LPCSTR filename /* Filename of disk metafile */ |
| 167 | ) |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 168 | { |
| 169 | DC *dc; |
| 170 | METAFILEDRV_PDEVICE *physDev; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 171 | HFILE hFile; |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 172 | |
Alexandre Julliard | a69b88b | 1998-03-15 20:29:56 +0000 | [diff] [blame] | 173 | TRACE(metafile, "'%s'\n", filename ); |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 174 | |
| 175 | if (!(dc = MFDRV_AllocMetaFile())) return 0; |
| 176 | physDev = (METAFILEDRV_PDEVICE *)dc->physDev; |
| 177 | |
| 178 | if (filename) /* disk based metafile */ |
| 179 | { |
| 180 | physDev->mh->mtType = METAFILE_DISK; |
Huw D M Davies | b94e433 | 1999-04-15 16:46:51 +0000 | [diff] [blame] | 181 | if ((hFile = CreateFileA(filename, GENERIC_WRITE, 0, NULL, |
| 182 | CREATE_ALWAYS, 0, -1)) == HFILE_ERROR) { |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 183 | MFDRV_DeleteDC( dc ); |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 184 | return 0; |
| 185 | } |
Huw D M Davies | b94e433 | 1999-04-15 16:46:51 +0000 | [diff] [blame] | 186 | if (!WriteFile( hFile, (LPSTR)physDev->mh, sizeof(*physDev->mh), NULL, |
| 187 | NULL )) { |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 188 | MFDRV_DeleteDC( dc ); |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 189 | return 0; |
| 190 | } |
Huw D M Davies | b94e433 | 1999-04-15 16:46:51 +0000 | [diff] [blame] | 191 | physDev->hFile = hFile; |
| 192 | |
| 193 | /* Grow METAHEADER to include filename */ |
| 194 | physDev->mh = MF_CreateMetaHeaderDisk(physDev->mh, filename); |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 195 | } |
| 196 | else /* memory based metafile */ |
| 197 | physDev->mh->mtType = METAFILE_MEMORY; |
Huw D M Davies | b94e433 | 1999-04-15 16:46:51 +0000 | [diff] [blame] | 198 | |
Alexandre Julliard | a69b88b | 1998-03-15 20:29:56 +0000 | [diff] [blame] | 199 | TRACE(metafile, "returning %04x\n", dc->hSelf); |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 200 | return dc->hSelf; |
| 201 | } |
| 202 | |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 203 | /********************************************************************** |
Huw D M Davies | b94e433 | 1999-04-15 16:46:51 +0000 | [diff] [blame] | 204 | * CreateMetaFileA (GDI32.51) |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 205 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 206 | HDC WINAPI CreateMetaFileA( |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 207 | LPCSTR filename /* Filename of disk metafile */ |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 208 | ) |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 209 | { |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 210 | return CreateMetaFile16( filename ); |
| 211 | } |
| 212 | |
Alexandre Julliard | 0c0e3be | 1998-12-10 15:49:22 +0000 | [diff] [blame] | 213 | /********************************************************************** |
Huw D M Davies | b94e433 | 1999-04-15 16:46:51 +0000 | [diff] [blame] | 214 | * CreateMetaFileW (GDI32.52) |
Alexandre Julliard | 0c0e3be | 1998-12-10 15:49:22 +0000 | [diff] [blame] | 215 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 216 | HDC WINAPI CreateMetaFileW(LPCWSTR filename) |
Alexandre Julliard | 0c0e3be | 1998-12-10 15:49:22 +0000 | [diff] [blame] | 217 | { |
| 218 | LPSTR filenameA; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 219 | HDC hReturnDC; |
Alexandre Julliard | 0c0e3be | 1998-12-10 15:49:22 +0000 | [diff] [blame] | 220 | |
| 221 | filenameA = HEAP_strdupWtoA( GetProcessHeap(), 0, filename ); |
| 222 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 223 | hReturnDC = CreateMetaFileA(filenameA); |
Alexandre Julliard | 0c0e3be | 1998-12-10 15:49:22 +0000 | [diff] [blame] | 224 | |
| 225 | HeapFree( GetProcessHeap(), 0, filenameA ); |
| 226 | |
| 227 | return hReturnDC; |
| 228 | } |
| 229 | |
Huw D M Davies | b94e433 | 1999-04-15 16:46:51 +0000 | [diff] [blame] | 230 | |
| 231 | /********************************************************************** |
| 232 | * MFDRV_CloseMetaFile |
| 233 | */ |
| 234 | static DC *MFDRV_CloseMetaFile( HDC hdc ) |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 235 | { |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 236 | DC *dc; |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 237 | METAFILEDRV_PDEVICE *physDev; |
| 238 | |
Alexandre Julliard | a69b88b | 1998-03-15 20:29:56 +0000 | [diff] [blame] | 239 | TRACE(metafile, "(%04x)\n", hdc ); |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 240 | |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 241 | if (!(dc = (DC *) GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC ))) return 0; |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 242 | physDev = (METAFILEDRV_PDEVICE *)dc->physDev; |
| 243 | |
| 244 | /* Construct the end of metafile record - this is documented |
| 245 | * in SDK Knowledgebase Q99334. |
| 246 | */ |
| 247 | |
Huw D M Davies | b94e433 | 1999-04-15 16:46:51 +0000 | [diff] [blame] | 248 | if (!MFDRV_MetaParam0(dc, META_EOF)) |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 249 | { |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 250 | MFDRV_DeleteDC( dc ); |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 251 | return 0; |
| 252 | } |
| 253 | |
| 254 | if (physDev->mh->mtType == METAFILE_DISK) /* disk based metafile */ |
| 255 | { |
Huw D M Davies | b94e433 | 1999-04-15 16:46:51 +0000 | [diff] [blame] | 256 | if (SetFilePointer(physDev->hFile, 0, NULL, FILE_BEGIN) != 0) { |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 257 | MFDRV_DeleteDC( dc ); |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 258 | return 0; |
| 259 | } |
Huw D M Davies | b94e433 | 1999-04-15 16:46:51 +0000 | [diff] [blame] | 260 | |
| 261 | physDev->mh->mtType = METAFILE_MEMORY; /* This is what windows does */ |
| 262 | if (!WriteFile(physDev->hFile, (LPSTR)physDev->mh, |
| 263 | sizeof(*physDev->mh), NULL, NULL)) { |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 264 | MFDRV_DeleteDC( dc ); |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 265 | return 0; |
| 266 | } |
Huw D M Davies | b94e433 | 1999-04-15 16:46:51 +0000 | [diff] [blame] | 267 | CloseHandle(physDev->hFile); |
| 268 | physDev->mh->mtType = METAFILE_DISK; |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 269 | } |
| 270 | |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 271 | return dc; |
| 272 | } |
| 273 | |
| 274 | /****************************************************************** |
| 275 | * CloseMetaFile16 (GDI.126) |
| 276 | */ |
| 277 | HMETAFILE16 WINAPI CloseMetaFile16( |
| 278 | HDC16 hdc /* Metafile DC to close */ |
| 279 | ) |
| 280 | { |
| 281 | HMETAFILE16 hmf; |
| 282 | METAFILEDRV_PDEVICE *physDev; |
Huw D M Davies | b94e433 | 1999-04-15 16:46:51 +0000 | [diff] [blame] | 283 | DC *dc = MFDRV_CloseMetaFile(hdc); |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 284 | if (!dc) return 0; |
| 285 | physDev = (METAFILEDRV_PDEVICE *)dc->physDev; |
| 286 | |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 287 | /* Now allocate a global handle for the metafile */ |
| 288 | |
Huw D M Davies | b94e433 | 1999-04-15 16:46:51 +0000 | [diff] [blame] | 289 | hmf = MF_Create_HMETAFILE16( physDev->mh ); |
| 290 | |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 291 | physDev->mh = NULL; /* So it won't be deleted */ |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 292 | MFDRV_DeleteDC( dc ); |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 293 | return hmf; |
| 294 | } |
| 295 | |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 296 | /****************************************************************** |
Huw D M Davies | b94e433 | 1999-04-15 16:46:51 +0000 | [diff] [blame] | 297 | * CloseMetaFile (GDI32.17) |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 298 | * |
| 299 | * Stop recording graphics operations in metafile associated with |
| 300 | * hdc and retrieve metafile. |
| 301 | * |
| 302 | * RETURNS |
| 303 | * Handle of newly created metafile on success, NULL on failure. |
| 304 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 305 | HMETAFILE WINAPI CloseMetaFile( |
| 306 | HDC hdc /* Metafile DC to close */ |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 307 | ) |
| 308 | { |
Huw D M Davies | b94e433 | 1999-04-15 16:46:51 +0000 | [diff] [blame] | 309 | HMETAFILE hmf; |
| 310 | METAFILEDRV_PDEVICE *physDev; |
| 311 | DC *dc = MFDRV_CloseMetaFile(hdc); |
| 312 | if (!dc) return 0; |
| 313 | physDev = (METAFILEDRV_PDEVICE *)dc->physDev; |
| 314 | |
| 315 | /* Now allocate a global handle for the metafile */ |
| 316 | |
| 317 | hmf = MF_Create_HMETAFILE( physDev->mh ); |
| 318 | |
| 319 | physDev->mh = NULL; /* So it won't be deleted */ |
| 320 | MFDRV_DeleteDC( dc ); |
| 321 | return hmf; |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 322 | } |
| 323 | |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 324 | |
| 325 | /****************************************************************** |
Huw D M Davies | b94e433 | 1999-04-15 16:46:51 +0000 | [diff] [blame] | 326 | * MFDRV_WriteRecord |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 327 | * |
Huw D M Davies | b94e433 | 1999-04-15 16:46:51 +0000 | [diff] [blame] | 328 | * Warning: this function can change the pointer to the metafile header. |
| 329 | */ |
| 330 | BOOL MFDRV_WriteRecord( DC *dc, METARECORD *mr, DWORD rlen) |
| 331 | { |
| 332 | DWORD len; |
| 333 | METAHEADER *mh; |
| 334 | METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dc->physDev; |
| 335 | |
| 336 | switch(physDev->mh->mtType) |
| 337 | { |
| 338 | case METAFILE_MEMORY: |
| 339 | len = physDev->mh->mtSize * 2 + rlen; |
| 340 | mh = HeapReAlloc( SystemHeap, 0, physDev->mh, len ); |
| 341 | if (!mh) return FALSE; |
| 342 | physDev->mh = mh; |
| 343 | memcpy((WORD *)physDev->mh + physDev->mh->mtSize, mr, rlen); |
| 344 | break; |
| 345 | case METAFILE_DISK: |
| 346 | TRACE(metafile,"Writing record to disk\n"); |
| 347 | if (!WriteFile(physDev->hFile, (char *)mr, rlen, NULL, NULL)) |
| 348 | return FALSE; |
| 349 | break; |
| 350 | default: |
| 351 | ERR(metafile, "Unknown metafile type %d\n", physDev->mh->mtType ); |
| 352 | return FALSE; |
| 353 | } |
| 354 | |
| 355 | physDev->mh->mtSize += rlen / 2; |
| 356 | physDev->mh->mtMaxRecord = MAX(physDev->mh->mtMaxRecord, rlen / 2); |
| 357 | return TRUE; |
| 358 | } |
| 359 | |
| 360 | |
| 361 | /****************************************************************** |
| 362 | * MFDRV_MetaParam0 |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 363 | */ |
| 364 | |
Huw D M Davies | b94e433 | 1999-04-15 16:46:51 +0000 | [diff] [blame] | 365 | BOOL MFDRV_MetaParam0(DC *dc, short func) |
| 366 | { |
| 367 | char buffer[8]; |
| 368 | METARECORD *mr = (METARECORD *)&buffer; |
| 369 | |
| 370 | mr->rdSize = 3; |
| 371 | mr->rdFunction = func; |
| 372 | return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2); |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 373 | } |
| 374 | |
Huw D M Davies | b94e433 | 1999-04-15 16:46:51 +0000 | [diff] [blame] | 375 | |
| 376 | /****************************************************************** |
| 377 | * MFDRV_MetaParam1 |
| 378 | */ |
| 379 | BOOL MFDRV_MetaParam1(DC *dc, short func, short param1) |
| 380 | { |
| 381 | char buffer[8]; |
| 382 | METARECORD *mr = (METARECORD *)&buffer; |
| 383 | |
| 384 | mr->rdSize = 4; |
| 385 | mr->rdFunction = func; |
| 386 | *(mr->rdParm) = param1; |
| 387 | return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2); |
| 388 | } |
| 389 | |
| 390 | |
| 391 | /****************************************************************** |
| 392 | * MFDRV_MetaParam2 |
| 393 | */ |
| 394 | BOOL MFDRV_MetaParam2(DC *dc, short func, short param1, short param2) |
| 395 | { |
| 396 | char buffer[10]; |
| 397 | METARECORD *mr = (METARECORD *)&buffer; |
| 398 | |
| 399 | mr->rdSize = 5; |
| 400 | mr->rdFunction = func; |
| 401 | *(mr->rdParm) = param2; |
| 402 | *(mr->rdParm + 1) = param1; |
| 403 | return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2); |
| 404 | } |
| 405 | |
| 406 | |
| 407 | /****************************************************************** |
| 408 | * MFDRV_MetaParam4 |
| 409 | */ |
| 410 | |
| 411 | BOOL MFDRV_MetaParam4(DC *dc, short func, short param1, short param2, |
| 412 | short param3, short param4) |
| 413 | { |
| 414 | char buffer[14]; |
| 415 | METARECORD *mr = (METARECORD *)&buffer; |
| 416 | |
| 417 | mr->rdSize = 7; |
| 418 | mr->rdFunction = func; |
| 419 | *(mr->rdParm) = param4; |
| 420 | *(mr->rdParm + 1) = param3; |
| 421 | *(mr->rdParm + 2) = param2; |
| 422 | *(mr->rdParm + 3) = param1; |
| 423 | return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2); |
| 424 | } |
| 425 | |
| 426 | |
| 427 | /****************************************************************** |
| 428 | * MFDRV_MetaParam6 |
| 429 | */ |
| 430 | |
| 431 | BOOL MFDRV_MetaParam6(DC *dc, short func, short param1, short param2, |
| 432 | short param3, short param4, short param5, short param6) |
| 433 | { |
| 434 | char buffer[18]; |
| 435 | METARECORD *mr = (METARECORD *)&buffer; |
| 436 | |
| 437 | mr->rdSize = 9; |
| 438 | mr->rdFunction = func; |
| 439 | *(mr->rdParm) = param6; |
| 440 | *(mr->rdParm + 1) = param5; |
| 441 | *(mr->rdParm + 2) = param4; |
| 442 | *(mr->rdParm + 3) = param3; |
| 443 | *(mr->rdParm + 4) = param2; |
| 444 | *(mr->rdParm + 5) = param1; |
| 445 | return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2); |
| 446 | } |
| 447 | |
| 448 | |
| 449 | /****************************************************************** |
| 450 | * MFDRV_MetaParam8 |
| 451 | */ |
| 452 | BOOL MFDRV_MetaParam8(DC *dc, short func, short param1, short param2, |
| 453 | short param3, short param4, short param5, |
| 454 | short param6, short param7, short param8) |
| 455 | { |
| 456 | char buffer[22]; |
| 457 | METARECORD *mr = (METARECORD *)&buffer; |
| 458 | |
| 459 | mr->rdSize = 11; |
| 460 | mr->rdFunction = func; |
| 461 | *(mr->rdParm) = param8; |
| 462 | *(mr->rdParm + 1) = param7; |
| 463 | *(mr->rdParm + 2) = param6; |
| 464 | *(mr->rdParm + 3) = param5; |
| 465 | *(mr->rdParm + 4) = param4; |
| 466 | *(mr->rdParm + 5) = param3; |
| 467 | *(mr->rdParm + 6) = param2; |
| 468 | *(mr->rdParm + 7) = param1; |
| 469 | return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2); |
| 470 | } |
| 471 | |
| 472 | |
| 473 | /****************************************************************** |
| 474 | * MFDRV_AddHandleDC |
| 475 | * |
| 476 | * Note: this function assumes that we never delete objects. |
| 477 | * If we do someday, we'll need to maintain a table to re-use deleted |
| 478 | * handles. |
| 479 | */ |
| 480 | int MFDRV_AddHandleDC( DC *dc ) |
| 481 | { |
| 482 | METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dc->physDev; |
| 483 | physDev->mh->mtNoObjects++; |
| 484 | return physDev->nextHandle++; |
| 485 | } |
| 486 | |
| 487 | |