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"
34 #include "gdi_private.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(metafile
);
39 /******************************************************************
42 * Returns ptr to METAHEADER associated with HMETAFILE16
43 * Should be followed by call to MF_ReleaseMetaHeader16
45 static METAHEADER
*MF_GetMetaHeader16( HMETAFILE16 hmf
)
47 return GlobalLock16(hmf
);
50 /******************************************************************
51 * MF_ReleaseMetaHeader16
53 * Releases METAHEADER associated with HMETAFILE16
55 static BOOL16
MF_ReleaseMetaHeader16( HMETAFILE16 hmf
)
57 return GlobalUnlock16( hmf
);
60 /******************************************************************
61 * DeleteMetaFile (GDI.127)
63 BOOL16 WINAPI
DeleteMetaFile16( HMETAFILE16 hmf
)
65 return !GlobalFree16( hmf
);
68 /******************************************************************
69 * GetMetaFile (GDI.124)
71 HMETAFILE16 WINAPI
GetMetaFile16( LPCSTR lpFilename
)
76 TRACE("%s\n", lpFilename
);
81 if((hFile
= CreateFileA(lpFilename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
82 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
)
85 mh
= MF_ReadMetaFile(hFile
);
88 return MF_Create_HMETAFILE16( mh
);
91 /******************************************************************
92 * CopyMetaFile (GDI.151)
94 HMETAFILE16 WINAPI
CopyMetaFile16( HMETAFILE16 hSrcMetaFile
, LPCSTR lpFilename
)
96 METAHEADER
*mh
= MF_GetMetaHeader16( hSrcMetaFile
);
97 METAHEADER
*mh2
= NULL
;
100 TRACE("(%08x,%s)\n", hSrcMetaFile
, lpFilename
);
104 if(mh
->mtType
== METAFILE_DISK
)
105 mh2
= MF_LoadDiskBasedMetaFile(mh
);
107 mh2
= HeapAlloc( GetProcessHeap(), 0, mh
->mtSize
* 2 );
108 memcpy( mh2
, mh
, mh
->mtSize
* 2 );
110 MF_ReleaseMetaHeader16( hSrcMetaFile
);
112 if(lpFilename
) { /* disk based metafile */
114 if((hFile
= CreateFileA(lpFilename
, GENERIC_WRITE
, 0, NULL
,
115 CREATE_ALWAYS
, 0, 0)) == INVALID_HANDLE_VALUE
) {
116 HeapFree( GetProcessHeap(), 0, mh2
);
119 WriteFile(hFile
, mh2
, mh2
->mtSize
* 2, &w
, NULL
);
121 mh2
= MF_CreateMetaHeaderDisk(mh2
, lpFilename
, FALSE
);
124 return MF_Create_HMETAFILE16( mh2
);
127 /******************************************************************
128 * IsValidMetaFile (GDI.410)
130 * Attempts to check if a given metafile is correctly formatted.
131 * Currently, the only things verified are several properties of the
135 * TRUE if hmf passes some tests for being a valid metafile, FALSE otherwise.
138 * This is not exactly what windows does, see _Undocumented_Windows_
141 BOOL16 WINAPI
IsValidMetaFile16(HMETAFILE16 hmf
)
144 METAHEADER
*mh
= MF_GetMetaHeader16(hmf
);
146 if (mh
->mtType
== METAFILE_MEMORY
|| mh
->mtType
== METAFILE_DISK
)
147 if (mh
->mtHeaderSize
== MFHEADERSIZE
/sizeof(INT16
))
148 if (mh
->mtVersion
== MFVERSION
)
150 MF_ReleaseMetaHeader16(hmf
);
152 TRACE("IsValidMetaFile %x => %d\n",hmf
,res
);
156 /******************************************************************
157 * PlayMetaFile (GDI.123)
160 BOOL16 WINAPI
PlayMetaFile16( HDC16 hdc
, HMETAFILE16 hmf
)
163 METAHEADER
*mh
= MF_GetMetaHeader16( hmf
);
164 ret
= MF_PlayMetaFile( HDC_32(hdc
), mh
);
165 MF_ReleaseMetaHeader16( hmf
);
170 /******************************************************************
171 * EnumMetaFile (GDI.175)
174 BOOL16 WINAPI
EnumMetaFile16( HDC16 hdc16
, HMETAFILE16 hmf
,
175 MFENUMPROC16 lpEnumFunc
, LPARAM lpData
)
177 METAHEADER
*mh
= MF_GetMetaHeader16(hmf
);
180 HDC hdc
= HDC_32(hdc16
);
183 unsigned int offset
= 0;
189 BOOL16 result
= TRUE
, loaded
= FALSE
;
191 TRACE("(%p, %04x, %p, %08lx)\n", hdc
, hmf
, lpEnumFunc
, lpData
);
193 if(!mh
) return FALSE
;
194 if(mh
->mtType
== METAFILE_DISK
) { /* Create a memory-based copy */
195 mh
= MF_LoadDiskBasedMetaFile(mh
);
196 if(!mh
) return FALSE
;
200 /* save the current pen, brush and font */
201 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
202 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
203 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
205 /* create the handle table */
207 hHT
= GlobalAlloc16(GMEM_MOVEABLE
| GMEM_ZEROINIT
,
208 sizeof(HANDLETABLE16
) * mh
->mtNoObjects
);
209 spht
= WOWGlobalLock16(hHT
);
212 offset
= mh
->mtHeaderSize
* 2;
214 /* loop through metafile records */
217 args
[6] = SELECTOROF(spht
);
218 args
[5] = OFFSETOF(spht
);
219 args
[4] = seg
+ (HIWORD(offset
) << __AHSHIFT
);
220 args
[3] = LOWORD(offset
);
221 args
[2] = mh
->mtNoObjects
;
222 args
[1] = HIWORD(lpData
);
223 args
[0] = LOWORD(lpData
);
225 while (offset
< (mh
->mtSize
* 2))
229 mr
= (METARECORD
*)((char *)mh
+ offset
);
231 WOWCallback16Ex( (DWORD
)lpEnumFunc
, WCB16_PASCAL
, sizeof(args
), args
, &ret
);
238 offset
+= (mr
->rdSize
* 2);
239 args
[4] = seg
+ (HIWORD(offset
) << __AHSHIFT
);
240 args
[3] = LOWORD(offset
);
243 SelectObject(hdc
, hBrush
);
244 SelectObject(hdc
, hPen
);
245 SelectObject(hdc
, hFont
);
247 ht
= (HANDLETABLE16
*)GlobalLock16(hHT
);
249 /* free objects in handle table */
250 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
251 if(*(ht
->objectHandle
+ i
) != 0)
252 DeleteObject( (HGDIOBJ
)(ULONG_PTR
)(*(ht
->objectHandle
+ i
) ));
254 /* free handle table */
257 HeapFree( GetProcessHeap(), 0, mh
);
258 MF_ReleaseMetaHeader16(hmf
);
262 /******************************************************************
263 * GetMetaFileBits (GDI.159)
265 * Trade in a metafile object handle for a handle to the metafile memory.
268 * hmf [I] metafile handle
271 HGLOBAL16 WINAPI
GetMetaFileBits16( HMETAFILE16 hmf
)
273 TRACE("hMem out: %04x\n", hmf
);
277 /******************************************************************
278 * SetMetaFileBits (GDI.160)
280 * Trade in a metafile memory handle for a handle to a metafile object.
281 * The memory region should hold a proper metafile, otherwise
282 * problems will occur when it is used. Validity of the memory is not
283 * checked. The function is essentially just the identity function.
286 * hMem [I] handle to a memory region holding a metafile
289 * Handle to a metafile on success, NULL on failure..
291 HMETAFILE16 WINAPI
SetMetaFileBits16( HGLOBAL16 hMem
)
293 TRACE("hmf out: %04x\n", hMem
);
298 /******************************************************************
299 * SetMetaFileBitsBetter (GDI.196)
301 * Trade in a metafile memory handle for a handle to a metafile object,
302 * making a cursory check (using IsValidMetaFile()) that the memory
303 * handle points to a valid metafile.
306 * Handle to a metafile on success, NULL on failure..
308 HMETAFILE16 WINAPI
SetMetaFileBitsBetter16( HMETAFILE16 hMeta
)
310 if( IsValidMetaFile16( hMeta
) )
311 return GlobalReAlloc16( hMeta
, 0, GMEM_SHARE
| GMEM_NODISCARD
| GMEM_MODIFY
);
312 return (HMETAFILE16
)0;