4 * Copyright David W. Metcalfe, 1994
5 * Copyright Niels de Carpentier, 1996
6 * Copyright Albrecht Kleine, 1996
7 * Copyright Huw Davies, 1996
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "wine/winbase16.h"
30 #include "wine/wingdi16.h"
35 #include "gdi_private.h"
36 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(metafile
);
40 /******************************************************************
43 * Returns ptr to METAHEADER associated with HMETAFILE16
44 * Should be followed by call to MF_ReleaseMetaHeader16
46 static METAHEADER
*MF_GetMetaHeader16( HMETAFILE16 hmf
)
48 return GlobalLock16(hmf
);
51 /******************************************************************
52 * MF_ReleaseMetaHeader16
54 * Releases METAHEADER associated with HMETAFILE16
56 static BOOL16
MF_ReleaseMetaHeader16( HMETAFILE16 hmf
)
58 return GlobalUnlock16( hmf
);
61 /******************************************************************
62 * DeleteMetaFile (GDI.127)
64 BOOL16 WINAPI
DeleteMetaFile16( HMETAFILE16 hmf
)
66 return !GlobalFree16( hmf
);
69 /******************************************************************
70 * GetMetaFile (GDI.124)
72 HMETAFILE16 WINAPI
GetMetaFile16( LPCSTR lpFilename
)
77 TRACE("%s\n", lpFilename
);
82 if((hFile
= CreateFileA(lpFilename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
83 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
)
86 mh
= MF_ReadMetaFile(hFile
);
89 return MF_Create_HMETAFILE16( mh
);
92 /******************************************************************
93 * CopyMetaFile (GDI.151)
95 HMETAFILE16 WINAPI
CopyMetaFile16( HMETAFILE16 hSrcMetaFile
, LPCSTR lpFilename
)
97 METAHEADER
*mh
= MF_GetMetaHeader16( hSrcMetaFile
);
98 METAHEADER
*mh2
= NULL
;
101 TRACE("(%08x,%s)\n", hSrcMetaFile
, lpFilename
);
105 if(mh
->mtType
== METAFILE_DISK
)
106 mh2
= MF_LoadDiskBasedMetaFile(mh
);
108 mh2
= HeapAlloc( GetProcessHeap(), 0, mh
->mtSize
* 2 );
109 memcpy( mh2
, mh
, mh
->mtSize
* 2 );
111 MF_ReleaseMetaHeader16( hSrcMetaFile
);
113 if(lpFilename
) { /* disk based metafile */
115 if((hFile
= CreateFileA(lpFilename
, GENERIC_WRITE
, 0, NULL
,
116 CREATE_ALWAYS
, 0, 0)) == INVALID_HANDLE_VALUE
) {
117 HeapFree( GetProcessHeap(), 0, mh2
);
120 WriteFile(hFile
, mh2
, mh2
->mtSize
* 2, &w
, NULL
);
122 mh2
= MF_CreateMetaHeaderDisk(mh2
, lpFilename
, FALSE
);
125 return MF_Create_HMETAFILE16( mh2
);
128 /******************************************************************
129 * IsValidMetaFile (GDI.410)
131 * Attempts to check if a given metafile is correctly formatted.
132 * Currently, the only things verified are several properties of the
136 * TRUE if hmf passes some tests for being a valid metafile, FALSE otherwise.
139 * This is not exactly what windows does, see _Undocumented_Windows_
142 BOOL16 WINAPI
IsValidMetaFile16(HMETAFILE16 hmf
)
145 METAHEADER
*mh
= MF_GetMetaHeader16(hmf
);
147 if (mh
->mtType
== METAFILE_MEMORY
|| mh
->mtType
== METAFILE_DISK
)
148 if (mh
->mtHeaderSize
== MFHEADERSIZE
/sizeof(INT16
))
149 if (mh
->mtVersion
== MFVERSION
)
151 MF_ReleaseMetaHeader16(hmf
);
153 TRACE("IsValidMetaFile %x => %d\n",hmf
,res
);
157 /******************************************************************
158 * PlayMetaFile (GDI.123)
161 BOOL16 WINAPI
PlayMetaFile16( HDC16 hdc
, HMETAFILE16 hmf
)
164 METAHEADER
*mh
= MF_GetMetaHeader16( hmf
);
165 ret
= MF_PlayMetaFile( HDC_32(hdc
), mh
);
166 MF_ReleaseMetaHeader16( hmf
);
171 /******************************************************************
172 * EnumMetaFile (GDI.175)
175 BOOL16 WINAPI
EnumMetaFile16( HDC16 hdc16
, HMETAFILE16 hmf
,
176 MFENUMPROC16 lpEnumFunc
, LPARAM lpData
)
178 METAHEADER
*mh
= MF_GetMetaHeader16(hmf
);
181 HDC hdc
= HDC_32(hdc16
);
184 unsigned int offset
= 0;
190 BOOL16 result
= TRUE
, loaded
= FALSE
;
192 TRACE("(%p, %04x, %p, %08lx)\n", hdc
, hmf
, lpEnumFunc
, lpData
);
194 if(!mh
) return FALSE
;
195 if(mh
->mtType
== METAFILE_DISK
) { /* Create a memory-based copy */
196 mh
= MF_LoadDiskBasedMetaFile(mh
);
197 if(!mh
) return FALSE
;
201 /* save the current pen, brush and font */
202 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
203 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
204 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
206 /* create the handle table */
208 hHT
= GlobalAlloc16(GMEM_MOVEABLE
| GMEM_ZEROINIT
,
209 sizeof(HANDLETABLE16
) * mh
->mtNoObjects
);
210 spht
= WOWGlobalLock16(hHT
);
213 offset
= mh
->mtHeaderSize
* 2;
215 /* loop through metafile records */
218 args
[6] = SELECTOROF(spht
);
219 args
[5] = OFFSETOF(spht
);
220 args
[4] = seg
+ (HIWORD(offset
) << __AHSHIFT
);
221 args
[3] = LOWORD(offset
);
222 args
[2] = mh
->mtNoObjects
;
223 args
[1] = HIWORD(lpData
);
224 args
[0] = LOWORD(lpData
);
226 while (offset
< (mh
->mtSize
* 2))
230 mr
= (METARECORD
*)((char *)mh
+ offset
);
232 WOWCallback16Ex( (DWORD
)lpEnumFunc
, WCB16_PASCAL
, sizeof(args
), args
, &ret
);
239 offset
+= (mr
->rdSize
* 2);
240 args
[4] = seg
+ (HIWORD(offset
) << __AHSHIFT
);
241 args
[3] = LOWORD(offset
);
244 SelectObject(hdc
, hBrush
);
245 SelectObject(hdc
, hPen
);
246 SelectObject(hdc
, hFont
);
248 ht
= (HANDLETABLE16
*)GlobalLock16(hHT
);
250 /* free objects in handle table */
251 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
252 if(*(ht
->objectHandle
+ i
) != 0)
253 DeleteObject( (HGDIOBJ
)(ULONG_PTR
)(*(ht
->objectHandle
+ i
) ));
255 /* free handle table */
258 HeapFree( GetProcessHeap(), 0, mh
);
259 MF_ReleaseMetaHeader16(hmf
);
263 /******************************************************************
264 * GetMetaFileBits (GDI.159)
266 * Trade in a metafile object handle for a handle to the metafile memory.
269 * hmf [I] metafile handle
272 HGLOBAL16 WINAPI
GetMetaFileBits16( HMETAFILE16 hmf
)
274 TRACE("hMem out: %04x\n", hmf
);
278 /******************************************************************
279 * SetMetaFileBits (GDI.160)
281 * Trade in a metafile memory handle for a handle to a metafile object.
282 * The memory region should hold a proper metafile, otherwise
283 * problems will occur when it is used. Validity of the memory is not
284 * checked. The function is essentially just the identity function.
287 * hMem [I] handle to a memory region holding a metafile
290 * Handle to a metafile on success, NULL on failure..
292 HMETAFILE16 WINAPI
SetMetaFileBits16( HGLOBAL16 hMem
)
294 TRACE("hmf out: %04x\n", hMem
);
299 /******************************************************************
300 * SetMetaFileBitsBetter (GDI.196)
302 * Trade in a metafile memory handle for a handle to a metafile object,
303 * making a cursory check (using IsValidMetaFile()) that the memory
304 * handle points to a valid metafile.
307 * Handle to a metafile on success, NULL on failure..
309 HMETAFILE16 WINAPI
SetMetaFileBitsBetter16( HMETAFILE16 hMeta
)
311 if( IsValidMetaFile16( hMeta
) )
312 return (HMETAFILE16
)GlobalReAlloc16( hMeta
, 0,
313 GMEM_SHARE
| GMEM_NODISCARD
| GMEM_MODIFY
);
314 return (HMETAFILE16
)0;