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
27 #include "wine/winbase16.h"
28 #include "wine/wingdi16.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(metafile
);
35 #define METAFILE_MEMORY 1
36 #define METAFILE_DISK 2
37 #define MFHEADERSIZE (sizeof(METAHEADER))
38 #define MFVERSION 0x300
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 /******************************************************************
64 * Create a 16-bit metafile from a 32-bit one. The 32-bit one is deleted.
66 static HMETAFILE16
create_metafile16( HMETAFILE hmf
)
72 size
= GetMetaFileBitsEx( hmf
, 0, NULL
);
73 hmf16
= GlobalAlloc16( GMEM_MOVEABLE
, size
);
76 void *buffer
= GlobalLock16( hmf16
);
77 GetMetaFileBitsEx( hmf
, size
, buffer
);
78 GlobalUnlock16( hmf16
);
80 DeleteMetaFile( hmf
);
84 /******************************************************************
87 * Create a 32-bit metafile from a 16-bit one.
89 static HMETAFILE
create_metafile32( HMETAFILE16 hmf16
)
91 METAHEADER
*mh
= MF_GetMetaHeader16( hmf16
);
93 return SetMetaFileBitsEx( mh
->mtSize
* 2, (BYTE
*)mh
);
96 /**********************************************************************
97 * CreateMetaFile (GDI.125)
99 HDC16 WINAPI
CreateMetaFile16( LPCSTR filename
)
101 return HDC_16( CreateMetaFileA( filename
) );
104 /******************************************************************
105 * CloseMetaFile (GDI.126)
107 HMETAFILE16 WINAPI
CloseMetaFile16(HDC16 hdc
)
109 return create_metafile16( CloseMetaFile( HDC_32(hdc
) ));
112 /******************************************************************
113 * DeleteMetaFile (GDI.127)
115 BOOL16 WINAPI
DeleteMetaFile16( HMETAFILE16 hmf
)
117 return !GlobalFree16( hmf
);
120 /******************************************************************
121 * GetMetaFile (GDI.124)
123 HMETAFILE16 WINAPI
GetMetaFile16( LPCSTR lpFilename
)
125 return create_metafile16( GetMetaFileA( lpFilename
));
128 /******************************************************************
129 * CopyMetaFile (GDI.151)
131 HMETAFILE16 WINAPI
CopyMetaFile16( HMETAFILE16 hSrcMetaFile
, LPCSTR lpFilename
)
133 HMETAFILE hmf
= create_metafile32( hSrcMetaFile
);
134 HMETAFILE hmf2
= CopyMetaFileA( hmf
, lpFilename
);
135 DeleteMetaFile( hmf
);
136 return create_metafile16( hmf2
);
139 /******************************************************************
140 * IsValidMetaFile (GDI.410)
142 * Attempts to check if a given metafile is correctly formatted.
143 * Currently, the only things verified are several properties of the
147 * TRUE if hmf passes some tests for being a valid metafile, FALSE otherwise.
150 * This is not exactly what windows does, see _Undocumented_Windows_
153 BOOL16 WINAPI
IsValidMetaFile16(HMETAFILE16 hmf
)
156 METAHEADER
*mh
= MF_GetMetaHeader16(hmf
);
158 if (mh
->mtType
== METAFILE_MEMORY
|| mh
->mtType
== METAFILE_DISK
)
159 if (mh
->mtHeaderSize
== MFHEADERSIZE
/sizeof(INT16
))
160 if (mh
->mtVersion
== MFVERSION
)
162 MF_ReleaseMetaHeader16(hmf
);
164 TRACE("IsValidMetaFile %x => %d\n",hmf
,res
);
168 /******************************************************************
169 * PlayMetaFile (GDI.123)
172 BOOL16 WINAPI
PlayMetaFile16( HDC16 hdc
, HMETAFILE16 hmf16
)
174 HMETAFILE hmf
= create_metafile32( hmf16
);
175 BOOL ret
= PlayMetaFile( HDC_32(hdc
), hmf
);
176 DeleteMetaFile( hmf
);
181 /******************************************************************
182 * EnumMetaFile (GDI.175)
185 BOOL16 WINAPI
EnumMetaFile16( HDC16 hdc16
, HMETAFILE16 hmf
,
186 MFENUMPROC16 lpEnumFunc
, LPARAM lpData
)
188 METAHEADER
*mh
= MF_GetMetaHeader16(hmf
);
191 HDC hdc
= HDC_32(hdc16
);
194 unsigned int offset
= 0;
200 BOOL16 result
= TRUE
;
202 TRACE("(%p, %04x, %p, %08lx)\n", hdc
, hmf
, lpEnumFunc
, lpData
);
204 if(!mh
) return FALSE
;
206 /* save the current pen, brush and font */
207 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
208 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
209 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
211 /* create the handle table */
213 hHT
= GlobalAlloc16(GMEM_MOVEABLE
| GMEM_ZEROINIT
,
214 FIELD_OFFSET(HANDLETABLE16
, objectHandle
[mh
->mtNoObjects
]));
215 spht
= WOWGlobalLock16(hHT
);
218 offset
= mh
->mtHeaderSize
* 2;
220 /* loop through metafile records */
223 args
[6] = SELECTOROF(spht
);
224 args
[5] = OFFSETOF(spht
);
225 args
[4] = seg
+ (HIWORD(offset
) << __AHSHIFT
);
226 args
[3] = LOWORD(offset
);
227 args
[2] = mh
->mtNoObjects
;
228 args
[1] = HIWORD(lpData
);
229 args
[0] = LOWORD(lpData
);
231 while (offset
< (mh
->mtSize
* 2))
235 mr
= (METARECORD
*)((char *)mh
+ offset
);
237 WOWCallback16Ex( (DWORD
)lpEnumFunc
, WCB16_PASCAL
, sizeof(args
), args
, &ret
);
244 offset
+= (mr
->rdSize
* 2);
245 args
[4] = seg
+ (HIWORD(offset
) << __AHSHIFT
);
246 args
[3] = LOWORD(offset
);
249 SelectObject(hdc
, hBrush
);
250 SelectObject(hdc
, hPen
);
251 SelectObject(hdc
, hFont
);
253 ht
= GlobalLock16(hHT
);
255 /* free objects in handle table */
256 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
257 if(*(ht
->objectHandle
+ i
) != 0)
258 DeleteObject( (HGDIOBJ
)(ULONG_PTR
)(*(ht
->objectHandle
+ i
) ));
260 /* free handle table */
262 MF_ReleaseMetaHeader16(hmf
);
266 /******************************************************************
267 * GetMetaFileBits (GDI.159)
269 * Trade in a metafile object handle for a handle to the metafile memory.
272 * hmf [I] metafile handle
275 HGLOBAL16 WINAPI
GetMetaFileBits16( HMETAFILE16 hmf
)
277 TRACE("hMem out: %04x\n", hmf
);
281 /******************************************************************
282 * SetMetaFileBits (GDI.160)
284 * Trade in a metafile memory handle for a handle to a metafile object.
285 * The memory region should hold a proper metafile, otherwise
286 * problems will occur when it is used. Validity of the memory is not
287 * checked. The function is essentially just the identity function.
290 * hMem [I] handle to a memory region holding a metafile
293 * Handle to a metafile on success, NULL on failure..
295 HMETAFILE16 WINAPI
SetMetaFileBits16( HGLOBAL16 hMem
)
297 TRACE("hmf out: %04x\n", hMem
);
302 /******************************************************************
303 * SetMetaFileBitsBetter (GDI.196)
305 * Trade in a metafile memory handle for a handle to a metafile object,
306 * making a cursory check (using IsValidMetaFile()) that the memory
307 * handle points to a valid metafile.
310 * Handle to a metafile on success, NULL on failure..
312 HMETAFILE16 WINAPI
SetMetaFileBitsBetter16( HMETAFILE16 hMeta
)
314 if( IsValidMetaFile16( hMeta
) )
315 return GlobalReAlloc16( hMeta
, 0, GMEM_SHARE
| GMEM_NODISCARD
| GMEM_MODIFY
);