ReactOS  0.4.15-dev-3294-ge98684e
metafile.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS system libraries
4  * FILE: win32ss/gdi/gdi32/objects/metafile.c
5  * PURPOSE: metafile and enhanced metafile support
6  * PROGRAMMERS: Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
7  */
8 #include <precomp.h>
9 
10 #define NDEBUG
11 #include <debug.h>
12 
13 /* FUNCTIONS *****************************************************************/
14 
15 /*
16  * @implemented
17  */
18 BOOL
19 WINAPI
21 {
22  PDC_ATTR pdcattr = GdiGetDcAttr(hdc);
23 
24  if ( pdcattr )
25  {
26  return !!( pdcattr->ulDirty_ & DC_PLAYMETAFILE );
27  }
28  return FALSE;
29 }
30 
31 /*
32  * @implemented
33  */
34 BOOL
35 WINAPI
37 {
38  ULONG ulObjType;
39 
40  ulObjType = GDI_HANDLE_GET_TYPE(hdc);
41  if (ulObjType == GDILoObjType_LO_METADC16_TYPE)
42  {
43  return TRUE;
44  }
45 
46  if (ulObjType == GDILoObjType_LO_ALTDC_TYPE)
47  {
48  PLDC pLDC = GdiGetLDC(hdc);
49  if ( !pLDC )
50  {
52  return FALSE;
53  }
54  return !!( pLDC->iType == LDC_EMFLDC );
55  }
56 
57  return FALSE;
58 }
59 
60 /*
61  * @implemented
62  */
63 BOOL
64 WINAPI
66 {
67  ULONG hType = GDI_HANDLE_GET_TYPE(hdc);
68 
69  if ( hType != GDILoObjType_LO_DC_TYPE )
70  {
71  if ( hType == GDILoObjType_LO_METADC16_TYPE )
72  return FALSE;
73  else
74  {
75  PLDC pLDC = GdiGetLDC(hdc);
76  if ( !pLDC )
77  {
79  return FALSE;
80  }
81  return !!( pLDC->Flags & LDC_META_PRINT );
82  }
83  }
84  return FALSE;
85 }
86 
87 // NOTE: I wanna use GdiCreateLocalMetaFilePict and GdiConvertMetaFilePict
88 // functions for clipboard data conversion. --- katahiromz
89 
90 /*
91  * @implemented
92  */
93 HGLOBAL
94 WINAPI
96 {
97  HGLOBAL hMetaFilePict;
98  METAFILEPICT * pInfo;
99  HMETAFILE hMF = NULL;
100  BYTE * Buffer = NULL;
101  BYTE * BufNew = NULL;
102  HDC hDC = NULL;
103  UINT nSize, cSize;
104  DWORD iType;
105 
106  // NOTE: On Win32, there is no difference between the local heap and
107  // the global heap. GlobalAlloc and LocalAlloc have same effect.
108 
109  // allocate for METAFILEPICT
110  hMetaFilePict = GlobalAlloc(GHND | GMEM_SHARE, sizeof(METAFILEPICT));
111  pInfo = (METAFILEPICT *)GlobalLock(hMetaFilePict);
112  if (pInfo == NULL)
113  goto Exit;
114 
116 
117  // allocate buffer
119  if (Buffer == NULL)
120  goto Exit;
121 
122  // store to buffer
123  nSize = NtGdiGetServerMetaFileBits( hmo, nSize, Buffer, &iType, (PDWORD)&pInfo->mm, (PDWORD)&pInfo->xExt, (PDWORD)&pInfo->yExt );
124  if (nSize == 0)
125  goto Exit;
126 
127  if ( iType == GDITAG_TYPE_EMF ) // handle conversion to MFP
128  {
129  static const WCHAR szDisplayW[] = { 'D','I','S','P','L','A','Y','\0' };
130  HENHMETAFILE hEMF;
131  ENHMETAHEADER emh;
132 
134  if (hEMF == NULL)
135  goto Exit;
136 
137  if (!GetEnhMetaFileHeader( hEMF, sizeof(emh), &emh ))
138  {
139  DeleteEnhMetaFile(hEMF);
140  goto Exit;
141  }
142 
143  pInfo->mm = MM_ANISOTROPIC; // wine uses MM_ISOTROPIC.
144  pInfo->xExt = emh.rclFrame.right - emh.rclFrame.left; // Width
145  pInfo->yExt = emh.rclFrame.bottom - emh.rclFrame.top; // Height
146 
147  hDC = CreateDCW(szDisplayW, NULL, NULL, NULL);
148  if (hDC)
149  {
150  cSize = GetWinMetaFileBits( hEMF, 0, NULL, MM_ANISOTROPIC, hDC );
151  if (cSize)
152  {
153  BufNew = (BYTE *)LocalAlloc(LPTR, cSize);
154  if (BufNew)
155  {
156  nSize = GetWinMetaFileBits( hEMF, cSize, (LPBYTE)BufNew, MM_ANISOTROPIC, hDC );
157  if (nSize == cSize)
158  {
159  if (Buffer) LocalFree(Buffer);
160  Buffer = BufNew;
161  }
162  }
163  }
164  DeleteDC(hDC);
165  }
166  DeleteEnhMetaFile(hEMF);
167 
168  if (Buffer != BufNew)
169  goto Exit;
170  }
171 
172  // create metafile from buffer
174  if (hMF == NULL)
175  goto Exit;
176 
177  // set metafile handle
178  pInfo->hMF = hMF;
179 
180 Exit:
181  // clean up
182  if (Buffer)
183  LocalFree(Buffer);
184  if (pInfo)
185  GlobalUnlock(hMetaFilePict);
186  if (hMF == NULL)
187  {
188  // failure
189  GlobalFree(hMetaFilePict);
190  hMetaFilePict = NULL;
191  }
192 
193  return hMetaFilePict; // success if non-NULL
194 }
195 
196 /*
197  * @implemented
198  */
199 HANDLE
200 WINAPI
202 {
203  HMETAFILE hMF;
204  UINT nSize;
205  HANDLE hmo = NULL;
206  BYTE * Buffer = NULL;
207  METAFILEPICT * pInfo = NULL;
208 
209  // get METAFILEPICT pointer
210  pInfo = (METAFILEPICT *)GlobalLock(hMetaFilePict);
211  if (pInfo == NULL)
212  goto Exit;
213 
214  // get metafile handle
215  hMF = pInfo->hMF;
216 
217  // get size of buffer
218  nSize = GetMetaFileBitsEx(hMF, 0, NULL);
219  if (nSize == 0)
220  goto Exit;
221 
222  // allocate buffer
224  if (Buffer == NULL)
225  goto Exit;
226 
227  // store to buffer
229  if (nSize == 0)
230  goto Exit;
231 
232  hmo = NtGdiCreateServerMetaFile( GDITAG_TYPE_MFP, nSize, Buffer, pInfo->mm, pInfo->xExt, pInfo->yExt);
233 
234 Exit:
235  // clean up
236  if (pInfo)
237  GlobalUnlock(hMetaFilePict);
238  if (Buffer)
239  LocalFree(Buffer);
240  return hmo; // success if non-NULL
241 }
HANDLE WINAPI GdiConvertMetaFilePict(HGLOBAL hMetaFilePict)
Definition: metafile.c:201
HMETAFILE hMF
Definition: wingdi.h:2608
HANDLE APIENTRY NtGdiCreateServerMetaFile(IN DWORD iType, IN ULONG cjData, IN PBYTE pjData, IN DWORD mm, IN DWORD xExt, IN DWORD yExt)
Definition: metafile.c:51
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
#define TRUE
Definition: types.h:120
ULONG APIENTRY NtGdiGetServerMetaFileBits(IN HANDLE hmo, IN ULONG cjData, OUT OPTIONAL PBYTE pjData, OUT PDWORD piType, OUT PDWORD pmm, OUT PDWORD pxExt, OUT PDWORD pyExt)
Definition: metafile.c:107
_In_ ULONG iType
Definition: winddi.h:3748
FORCEINLINE PDC_ATTR GdiGetDcAttr(HDC hdc)
Definition: gdi32p.h:451
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2053
static HDC
Definition: imagelist.c:92
long bottom
Definition: polytest.cpp:53
HENHMETAFILE WINAPI SetEnhMetaFileBits(_In_ UINT nSize, _In_reads_bytes_(nSize) const BYTE *pb)
#define GMEM_SHARE
Definition: winbase.h:302
HGLOBAL WINAPI GdiCreateLocalMetaFilePict(HANDLE hmo)
Definition: metafile.c:95
ULONG Flags
Definition: ntgdihdl.h:287
BOOL WINAPI GdiIsMetaPrintDC(HDC hdc)
Definition: metafile.c:65
long right
Definition: polytest.cpp:53
#define GHND
Definition: winbase.h:294
HMETAFILE WINAPI SetMetaFileBitsEx(UINT size, const BYTE *lpData)
Definition: metafile.c:1049
unsigned char * LPBYTE
Definition: typedefs.h:53
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL WINAPI GdiIsPlayMetafileDC(HDC hdc)
Definition: metafile.c:20
long top
Definition: polytest.cpp:53
Definition: bufpool.h:45
BOOL WINAPI DeleteEnhMetaFile(_In_opt_ HENHMETAFILE)
UINT WINAPI GetMetaFileBitsEx(HMETAFILE hmf, UINT nSize, LPVOID buf)
Definition: metafile.c:1091
long left
Definition: polytest.cpp:53
ULONG ulDirty_
Definition: ntgdihdl.h:312
#define GDI_HANDLE_GET_TYPE(h)
Definition: gdi.h:31
#define GDITAG_TYPE_MFP
Definition: ntgdityp.h:247
PLDC FASTCALL GdiGetLDC(HDC hDC)
Definition: misc.c:785
RECTL rclFrame
Definition: wingdi.h:2323
__wchar_t WCHAR
Definition: xmlstorage.h:180
static void Exit(void)
Definition: sock.c:1331
#define WINAPI
Definition: msvc.h:6
#define LDC_META_PRINT
Definition: ntgdihdl.h:181
#define DC_PLAYMETAFILE
Definition: ntgdihdl.h:156
unsigned long DWORD
Definition: ntddk_ex.h:95
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
#define SetLastError(x)
Definition: compat.h:611
BOOL WINAPI GdiIsMetaFileDC(HDC hdc)
Definition: metafile.c:36
Definition: ntgdihdl.h:284
INT iType
Definition: ntgdihdl.h:288
UINT WINAPI GetEnhMetaFileHeader(_In_ HENHMETAFILE hemf, _In_ UINT nSize, _Out_writes_bytes_opt_(nSize) LPENHMETAHEADER lpEnhMetaHeader)
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
HDC hdc
Definition: main.c:9
#define MM_ANISOTROPIC
Definition: wingdi.h:867
#define GDITAG_TYPE_EMF
Definition: ntgdityp.h:246
unsigned char BYTE
Definition: xxhash.c:193
static HDC hDC
Definition: 3dtext.c:33
BOOL WINAPI DeleteDC(_In_ HDC)
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
UINT WINAPI GetWinMetaFileBits(HENHMETAFILE hemf, UINT cbBuffer, LPBYTE lpbBuffer, INT map_mode, HDC hdcRef)
Definition: metafile.c:1257
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
DWORD * PDWORD
Definition: pedump.c:68
HDC WINAPI CreateDCW(_In_opt_ LPCWSTR pszDriver, _In_opt_ LPCWSTR pszDevice, _In_opt_ LPCWSTR psz, _In_opt_ const DEVMODEW *pdmInit)
unsigned int ULONG
Definition: retypes.h:1
#define LPTR
Definition: winbase.h:378
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1373
#define LDC_EMFLDC
Definition: gdi_private.h:105