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"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(metafile
);
37 #define METAFILE_MEMORY 1
38 #define METAFILE_DISK 2
39 #define MFHEADERSIZE (sizeof(METAHEADER))
40 #define MFVERSION 0x300
42 /******************************************************************
45 * Returns ptr to METAHEADER associated with HMETAFILE16
46 * Should be followed by call to MF_ReleaseMetaHeader16
48 static METAHEADER
*MF_GetMetaHeader16( HMETAFILE16 hmf
)
50 return GlobalLock16(hmf
);
53 /******************************************************************
54 * MF_ReleaseMetaHeader16
56 * Releases METAHEADER associated with HMETAFILE16
58 static BOOL16
MF_ReleaseMetaHeader16( HMETAFILE16 hmf
)
60 return GlobalUnlock16( hmf
);
63 /******************************************************************
66 * Create a 16-bit metafile from a 32-bit one. The 32-bit one is deleted.
68 static HMETAFILE16
create_metafile16( HMETAFILE hmf
)
74 size
= GetMetaFileBitsEx( hmf
, 0, NULL
);
75 hmf16
= GlobalAlloc16( GMEM_MOVEABLE
, size
);
78 void *buffer
= GlobalLock16( hmf16
);
79 GetMetaFileBitsEx( hmf
, size
, buffer
);
80 GlobalUnlock16( hmf16
);
82 DeleteMetaFile( hmf
);
86 /******************************************************************
89 * Create a 32-bit metafile from a 16-bit one.
91 static HMETAFILE
create_metafile32( HMETAFILE16 hmf16
)
93 METAHEADER
*mh
= MF_GetMetaHeader16( hmf16
);
95 return SetMetaFileBitsEx( mh
->mtSize
* 2, (BYTE
*)mh
);
98 /**********************************************************************
99 * CreateMetaFile (GDI.125)
101 HDC16 WINAPI
CreateMetaFile16( LPCSTR filename
)
103 return HDC_16( CreateMetaFileA( filename
) );
106 /******************************************************************
107 * CloseMetaFile (GDI.126)
109 HMETAFILE16 WINAPI
CloseMetaFile16(HDC16 hdc
)
111 return create_metafile16( CloseMetaFile( HDC_32(hdc
) ));
114 /******************************************************************
115 * DeleteMetaFile (GDI.127)
117 BOOL16 WINAPI
DeleteMetaFile16( HMETAFILE16 hmf
)
119 return !GlobalFree16( hmf
);
122 /******************************************************************
123 * GetMetaFile (GDI.124)
125 HMETAFILE16 WINAPI
GetMetaFile16( LPCSTR lpFilename
)
127 return create_metafile16( GetMetaFileA( lpFilename
));
130 /******************************************************************
131 * CopyMetaFile (GDI.151)
133 HMETAFILE16 WINAPI
CopyMetaFile16( HMETAFILE16 hSrcMetaFile
, LPCSTR lpFilename
)
135 HMETAFILE hmf
= create_metafile32( hSrcMetaFile
);
136 HMETAFILE hmf2
= CopyMetaFileA( hmf
, lpFilename
);
137 DeleteMetaFile( hmf
);
138 return create_metafile16( hmf2
);
141 /******************************************************************
142 * IsValidMetaFile (GDI.410)
144 * Attempts to check if a given metafile is correctly formatted.
145 * Currently, the only things verified are several properties of the
149 * TRUE if hmf passes some tests for being a valid metafile, FALSE otherwise.
152 * This is not exactly what windows does, see _Undocumented_Windows_
155 BOOL16 WINAPI
IsValidMetaFile16(HMETAFILE16 hmf
)
158 METAHEADER
*mh
= MF_GetMetaHeader16(hmf
);
160 if (mh
->mtType
== METAFILE_MEMORY
|| mh
->mtType
== METAFILE_DISK
)
161 if (mh
->mtHeaderSize
== MFHEADERSIZE
/sizeof(INT16
))
162 if (mh
->mtVersion
== MFVERSION
)
164 MF_ReleaseMetaHeader16(hmf
);
166 TRACE("IsValidMetaFile %x => %d\n",hmf
,res
);
170 /******************************************************************
171 * PlayMetaFile (GDI.123)
174 BOOL16 WINAPI
PlayMetaFile16( HDC16 hdc
, HMETAFILE16 hmf16
)
176 HMETAFILE hmf
= create_metafile32( hmf16
);
177 BOOL ret
= PlayMetaFile( HDC_32(hdc
), hmf
);
178 DeleteMetaFile( hmf
);
183 /******************************************************************
184 * EnumMetaFile (GDI.175)
187 BOOL16 WINAPI
EnumMetaFile16( HDC16 hdc16
, HMETAFILE16 hmf
,
188 MFENUMPROC16 lpEnumFunc
, LPARAM lpData
)
190 METAHEADER
*mh
= MF_GetMetaHeader16(hmf
);
193 HDC hdc
= HDC_32(hdc16
);
196 unsigned int offset
= 0;
202 BOOL16 result
= TRUE
;
204 TRACE("(%p, %04x, %p, %08lx)\n", hdc
, hmf
, lpEnumFunc
, lpData
);
206 if(!mh
) return FALSE
;
208 /* save the current pen, brush and font */
209 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
210 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
211 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
213 /* create the handle table */
215 hHT
= GlobalAlloc16(GMEM_MOVEABLE
| GMEM_ZEROINIT
,
216 FIELD_OFFSET(HANDLETABLE16
, objectHandle
[mh
->mtNoObjects
]));
217 spht
= WOWGlobalLock16(hHT
);
220 offset
= mh
->mtHeaderSize
* 2;
222 /* loop through metafile records */
225 args
[6] = SELECTOROF(spht
);
226 args
[5] = OFFSETOF(spht
);
227 args
[4] = seg
+ (HIWORD(offset
) << __AHSHIFT
);
228 args
[3] = LOWORD(offset
);
229 args
[2] = mh
->mtNoObjects
;
230 args
[1] = HIWORD(lpData
);
231 args
[0] = LOWORD(lpData
);
233 while (offset
< (mh
->mtSize
* 2))
237 mr
= (METARECORD
*)((char *)mh
+ offset
);
239 WOWCallback16Ex( (DWORD
)lpEnumFunc
, WCB16_PASCAL
, sizeof(args
), args
, &ret
);
246 offset
+= (mr
->rdSize
* 2);
247 args
[4] = seg
+ (HIWORD(offset
) << __AHSHIFT
);
248 args
[3] = LOWORD(offset
);
251 SelectObject(hdc
, hBrush
);
252 SelectObject(hdc
, hPen
);
253 SelectObject(hdc
, hFont
);
255 ht
= GlobalLock16(hHT
);
257 /* free objects in handle table */
258 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
259 if(*(ht
->objectHandle
+ i
) != 0)
260 DeleteObject( (HGDIOBJ
)(ULONG_PTR
)(*(ht
->objectHandle
+ i
) ));
262 /* free handle table */
264 MF_ReleaseMetaHeader16(hmf
);
268 /******************************************************************
269 * GetMetaFileBits (GDI.159)
271 * Trade in a metafile object handle for a handle to the metafile memory.
274 * hmf [I] metafile handle
277 HGLOBAL16 WINAPI
GetMetaFileBits16( HMETAFILE16 hmf
)
279 TRACE("hMem out: %04x\n", hmf
);
283 /******************************************************************
284 * SetMetaFileBits (GDI.160)
286 * Trade in a metafile memory handle for a handle to a metafile object.
287 * The memory region should hold a proper metafile, otherwise
288 * problems will occur when it is used. Validity of the memory is not
289 * checked. The function is essentially just the identity function.
292 * hMem [I] handle to a memory region holding a metafile
295 * Handle to a metafile on success, NULL on failure..
297 HMETAFILE16 WINAPI
SetMetaFileBits16( HGLOBAL16 hMem
)
299 TRACE("hmf out: %04x\n", hMem
);
304 /******************************************************************
305 * SetMetaFileBitsBetter (GDI.196)
307 * Trade in a metafile memory handle for a handle to a metafile object,
308 * making a cursory check (using IsValidMetaFile()) that the memory
309 * handle points to a valid metafile.
312 * Handle to a metafile on success, NULL on failure..
314 HMETAFILE16 WINAPI
SetMetaFileBitsBetter16( HMETAFILE16 hMeta
)
316 if( IsValidMetaFile16( hMeta
) )
317 return GlobalReAlloc16( hMeta
, 0, GMEM_SHARE
| GMEM_NODISCARD
| GMEM_MODIFY
);