e1a51fb69f447cf2735ebc9713d26fa588810254
[reactos.git] / win32ss / gdi / gdi32 / objects / metafile.c
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
20 GdiIsPlayMetafileDC(HDC hDC)
21 {
22 #if 0
23 PLDC pLDC = GdiGetLDC(hDC);
24 if ( pLDC )
25 {
26 if ( pLDC->Flags & LDC_PLAY_MFDC ) return TRUE;
27 }
28 return FALSE;
29 #else
30 UNIMPLEMENTED;
31 return FALSE;
32 #endif
33 }
34
35 /*
36 * @implemented
37 */
38 BOOL
39 WINAPI
40 GdiIsMetaFileDC(HDC hdc)
41 {
42 ULONG ulObjType;
43
44 ulObjType = GDI_HANDLE_GET_TYPE(hdc);
45 if (ulObjType == GDILoObjType_LO_METADC16_TYPE)
46 {
47 return TRUE;
48 }
49
50 if (ulObjType == GDILoObjType_LO_ALTDC_TYPE)
51 {
52 #if 0
53 PLDC pLDC = GdiGetLDC(hdc);
54 if ( !pLDC )
55 {
56 SetLastError(ERROR_INVALID_HANDLE);
57 return FALSE;
58 }
59 if ( pLDC->iType == LDC_EMFLDC) return TRUE;
60 return FALSE;
61 #endif
62 return TRUE;
63 }
64
65 return FALSE;
66 }
67
68 /*
69 * @implemented
70 */
71 BOOL
72 WINAPI
73 GdiIsMetaPrintDC(HDC hDC)
74 {
75 #if 0
76 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
77 {
78 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
79 return FALSE;
80 else
81 {
82 PLDC pLDC = GdiGetLDC(hDC);
83 if ( !pLDC )
84 {
85 SetLastError(ERROR_INVALID_HANDLE);
86 return FALSE;
87 }
88 if ( pLDC->Flags & LDC_META_PRINT) return TRUE;
89 }
90 }
91 return FALSE;
92 #else
93 UNIMPLEMENTED;
94 return FALSE;
95 #endif
96 }
97
98 // NOTE: I wanna use GdiCreateLocalMetaFilePict and GdiConvertMetaFilePict
99 // functions for clipboard data conversion. --- katahiromz
100
101 /*
102 * @implemented
103 */
104 HGLOBAL
105 WINAPI
106 GdiCreateLocalMetaFilePict(HANDLE hmo)
107 {
108 HGLOBAL hMetaFilePict;
109 METAFILEPICT * pInfo;
110 HMETAFILE hMF = NULL;
111 BYTE * Buffer = NULL;
112 BYTE * BufNew = NULL;
113 HDC hDC = NULL;
114 UINT nSize, cSize;
115 DWORD iType;
116
117 // NOTE: On Win32, there is no difference between the local heap and
118 // the global heap. GlobalAlloc and LocalAlloc have same effect.
119
120 // allocate for METAFILEPICT
121 hMetaFilePict = GlobalAlloc(GHND | GMEM_SHARE, sizeof(METAFILEPICT));
122 pInfo = (METAFILEPICT *)GlobalLock(hMetaFilePict);
123 if (pInfo == NULL)
124 goto Exit;
125
126 nSize = NtGdiGetServerMetaFileBits( hmo, 0, NULL, NULL, NULL, NULL, NULL );
127
128 // allocate buffer
129 Buffer = (BYTE *)LocalAlloc(LPTR, nSize);
130 if (Buffer == NULL)
131 goto Exit;
132
133 // store to buffer
134 nSize = NtGdiGetServerMetaFileBits( hmo, nSize, Buffer, &iType, (PDWORD)&pInfo->mm, (PDWORD)&pInfo->xExt, (PDWORD)&pInfo->yExt );
135 if (nSize == 0)
136 goto Exit;
137
138 if ( iType == GDITAG_TYPE_EMF ) // handle conversion to MFP
139 {
140 static const WCHAR szDisplayW[] = { 'D','I','S','P','L','A','Y','\0' };
141 HENHMETAFILE hEMF;
142 PENHMETAHEADER pemh = (PENHMETAHEADER)Buffer;
143
144 pInfo->mm = MM_ANISOTROPIC;
145 pInfo->xExt = pemh->rclFrame.right - pemh->rclFrame.left; // Width
146 pInfo->yExt = pemh->rclFrame.bottom - pemh->rclFrame.top; // Height
147
148 hEMF = SetEnhMetaFileBits(nSize, Buffer);
149 if (hEMF == NULL)
150 goto Exit;
151
152 hDC = CreateDCW(szDisplayW, NULL, NULL, NULL);
153 if (hDC)
154 {
155 cSize = GetWinMetaFileBits( hEMF, 0, NULL, MM_ANISOTROPIC, hDC );
156 if (cSize)
157 {
158 BufNew = (BYTE *)LocalAlloc(LPTR, cSize);
159 if (BufNew)
160 {
161 nSize = GetWinMetaFileBits( hEMF, cSize, (LPBYTE)BufNew, MM_ANISOTROPIC, hDC );
162 if (nSize == cSize)
163 {
164 if (Buffer) LocalFree(Buffer);
165 Buffer = BufNew;
166 }
167 }
168 }
169 DeleteDC(hDC);
170 }
171 DeleteEnhMetaFile(hEMF);
172
173 if (Buffer != BufNew)
174 goto Exit;
175 }
176
177 // create metafile from buffer
178 hMF = SetMetaFileBitsEx(nSize, Buffer);
179 if (hMF == NULL)
180 goto Exit;
181
182 // set metafile handle
183 pInfo->hMF = hMF;
184
185 Exit:
186 // clean up
187 if (Buffer)
188 LocalFree(Buffer);
189 if (pInfo)
190 GlobalUnlock(hMetaFilePict);
191 if (hMF == NULL)
192 {
193 // failure
194 GlobalFree(hMetaFilePict);
195 hMetaFilePict = NULL;
196 }
197
198 return hMetaFilePict; // success if non-NULL
199 }
200
201 /*
202 * @implemented
203 */
204 HANDLE
205 WINAPI
206 GdiConvertMetaFilePict(HGLOBAL hMetaFilePict)
207 {
208 HMETAFILE hMF;
209 UINT nSize;
210 HANDLE hmo = NULL;
211 BYTE * Buffer = NULL;
212 METAFILEPICT * pInfo = NULL;
213
214 // get METAFILEPICT pointer
215 pInfo = (METAFILEPICT *)GlobalLock(hMetaFilePict);
216 if (pInfo == NULL)
217 goto Exit;
218
219 // get metafile handle
220 hMF = pInfo->hMF;
221
222 // get size of buffer
223 nSize = GetMetaFileBitsEx(hMF, 0, NULL);
224 if (nSize == 0)
225 goto Exit;
226
227 // allocate buffer
228 Buffer = (BYTE *)LocalAlloc(LPTR, nSize);
229 if (Buffer == NULL)
230 goto Exit;
231
232 // store to buffer
233 nSize = GetMetaFileBitsEx(hMF, nSize, Buffer);
234 if (nSize == 0)
235 goto Exit;
236
237 hmo = NtGdiCreateServerMetaFile( GDITAG_TYPE_MFP, nSize, Buffer, pInfo->mm, pInfo->xExt, pInfo->yExt);
238
239 Exit:
240 // clean up
241 if (pInfo)
242 GlobalUnlock(hMetaFilePict);
243 if (Buffer)
244 LocalFree(Buffer);
245 return hmo; // success if non-NULL
246 }