d890d4bcaef850448d5762e58c13bd4759d3604d
[reactos.git] / reactos / dll / win32 / gdi32 / objects / metafile.c
1 #include "precomp.h"
2
3 /*
4 * @unimplemented
5 */
6 HENHMETAFILE
7 STDCALL
8 CloseEnhMetaFile(
9 HDC hdc)
10 {
11 return NtGdiCloseEnhMetaFile(hdc);
12 }
13
14 /*
15 * @implemented
16 */
17 HMETAFILE
18 STDCALL
19 CopyMetaFileW(
20 HMETAFILE hmfSrc,
21 LPCWSTR lpszFile
22 )
23 {
24 return NtGdiCopyMetaFile (hmfSrc, lpszFile);
25 }
26
27
28 /*
29 * @implemented
30 */
31 HMETAFILE
32 STDCALL
33 CopyMetaFileA(
34 HMETAFILE hmfSrc,
35 LPCSTR lpszFile
36 )
37 {
38 NTSTATUS Status;
39 PWSTR lpszFileW;
40 HMETAFILE rc = 0;
41
42 Status = HEAP_strdupA2W ( &lpszFileW, lpszFile );
43 if (!NT_SUCCESS (Status))
44 SetLastError (RtlNtStatusToDosError(Status));
45 else
46 {
47 rc = NtGdiCopyMetaFile ( hmfSrc, lpszFileW );
48
49 HEAP_free ( lpszFileW );
50 }
51
52 return rc;
53 }
54
55
56 /*
57 * @implemented
58 */
59 HDC
60 STDCALL
61 CreateMetaFileW(
62 LPCWSTR lpszFile
63 )
64 {
65 return NtGdiCreateMetaFile ( lpszFile );
66 }
67
68
69 /*
70 * @implemented
71 */
72 HDC
73 STDCALL
74 CreateMetaFileA(
75 LPCSTR lpszFile
76 )
77 {
78 NTSTATUS Status;
79 PWSTR lpszFileW;
80 HDC rc = 0;
81
82 Status = HEAP_strdupA2W ( &lpszFileW, lpszFile );
83 if (!NT_SUCCESS (Status))
84 SetLastError (RtlNtStatusToDosError(Status));
85 else
86 {
87 rc = NtGdiCreateMetaFile ( lpszFileW );
88
89 HEAP_free ( lpszFileW );
90 }
91 return rc;
92 }
93
94
95 /*
96 * @implemented
97 */
98 HMETAFILE
99 STDCALL
100 GetMetaFileW(
101 LPCWSTR lpszMetaFile
102 )
103 {
104 return NtGdiGetMetaFile ( lpszMetaFile );
105 }
106
107
108 /*
109 * @implemented
110 */
111 HMETAFILE
112 STDCALL
113 GetMetaFileA(
114 LPCSTR lpszMetaFile
115 )
116 {
117 NTSTATUS Status;
118 LPWSTR lpszMetaFileW;
119 HMETAFILE rc = 0;
120
121 Status = HEAP_strdupA2W ( &lpszMetaFileW, lpszMetaFile );
122 if (!NT_SUCCESS (Status))
123 SetLastError (RtlNtStatusToDosError(Status));
124 else
125 {
126 rc = NtGdiGetMetaFile ( lpszMetaFileW );
127
128 HEAP_free ( lpszMetaFileW );
129 }
130
131 return rc;
132 }
133
134 #if 0
135
136 HDC WINAPI CreateEnhMetaFileW(
137 HDC hDC, /* [in] optional reference DC */
138 LPCWSTR filename, /* [in] optional filename for disk metafiles */
139 const RECT* rect, /* [in] optional bounding rectangle */
140 LPCWSTR description /* [in] optional description */
141 )
142 {
143 HDC mDC;
144 PDC_ATTR Dc_Attr;
145 PLDC pLDC;
146 HANDLE hFile;
147 PENHMETAFILE EmfDC;
148 DWORD size = 0, length = 0;
149
150 mDC = NtGdiCreateMetafileDC( hDC ); // Basically changes the handle from 1xxxx to 46xxxx.
151 // If hDC == NULL, works just like createdc in win32k.
152
153 if ( !GdiGetHandleUserData((HGDIOBJ) mDC, (PVOID) &Dc_Attr))
154 {
155 SetLastError (ERROR_INVALID_PARAMETER);
156 return NULL; // need to delete the handle?
157 }
158
159 pLDC = LocalAlloc(LMEM_ZEROINIT, sizeof(LDC));
160
161 Dc_Attr->pvLDC = pLDC;
162 pLDC->hDC = mDC;
163 pLDC->iType = LDC_EMFDC
164
165
166 if (description)
167 { /* App name\0Title\0\0 */
168 length = lstrlenW(description);
169 length += lstrlenW(description + length + 1);
170 length += 3;
171 length *= 2;
172 }
173
174 size = sizeof(ENHMETAFILE) + (length + 3) / 4 * 4;
175
176 //Allocate ENHMETAFILE structure
177 EmfDC = LocalAlloc(LMEM_ZEROINIT, sizeof(ENHMETAFILE));
178 pLDC->pvEmfDC = EmfDC;
179
180 EmfDC->handles_size = HANDLE_LIST_INC;
181 EmfDC->cur_handles = 1;
182
183 EmfDC->horzres = GetDeviceCaps(mDC, HORZRES);
184 EmfDC->vertres = GetDeviceCaps(mDC, VERTRES);
185 EmfDC->logpixelsx = GetDeviceCaps(mDC, LOGPIXELSX);
186 EmfDC->logpixelsy = GetDeviceCaps(mDC, LOGPIXELSY);
187 EmfDC->horzsize = GetDeviceCaps(mDC, HORZSIZE);
188 EmfDC->vertsize = GetDeviceCaps(mDC, VERTSIZE);
189 EmfDC->bitspixel = GetDeviceCaps(mDC, BITSPIXEL);
190 EmfDC->textcaps = GetDeviceCaps(mDC, TEXTCAPS);
191 EmfDC->rastercaps = GetDeviceCaps(mDC, RASTERCAPS);
192 EmfDC->technology = GetDeviceCaps(mDC, TECHNOLOGY);
193 EmfDC->planes = GetDeviceCaps(mDC, PLANES);
194
195 EmfDC->emf = LocalAlloc(LMEM_ZEROINIT, size);
196
197 EmfDC->emf->iType = EMR_HEADER;
198 EmfDC->emf->nSize = size;
199
200 EmfDC->emf->rclBounds.left = EmfDC->emf->rclBounds.top = 0;
201 EmfDC->emf->rclBounds.right = EmfDC->emf->rclBounds.bottom = -1;
202
203 if(rect)
204 {
205 EmfDC->emf->rclFrame.left = rect->left;
206 EmfDC->emf->rclFrame.top = rect->top;
207 EmfDC->emf->rclFrame.right = rect->right;
208 EmfDC->emf->rclFrame.bottom = rect->bottom;
209 }
210 else
211 { /* Set this to {0,0 - -1,-1} and update it at the end */
212 EmfDC->emf->rclFrame.left = EmfDC->emf->rclFrame.top = 0;
213 EmfDC->emf->rclFrame.right = EmfDC->emf->rclFrame.bottom = -1;
214 }
215
216 EmfDC->emf->dSignature = ENHMETA_SIGNATURE;
217 EmfDC->emf->nVersion = 0x10000;
218 EmfDC->emf->nBytes = pLDC->pvEmfDC->nSize;
219 EmfDC->emf->nRecords = 1;
220 EmfDC->emf->nHandles = 1;
221
222 EmfDC->emf->sReserved = 0; /* According to docs, this is reserved and must be 0 */
223 EmfDC->emf->nDescription = length / 2;
224
225 EmfDC->emf->offDescription = length ? sizeof(ENHMETAHEADER) : 0;
226
227 EmfDC->emf->nPalEntries = 0; /* I guess this should start at 0 */
228
229 /* Size in pixels */
230 EmfDC->emf->szlDevice.cx = EmfDC->horzres;
231 EmfDC->emf->szlDevice.cy = EmfDC->vertres;
232
233 /* Size in millimeters */
234 EmfDC->emf->szlMillimeters.cx = EmfDC->horzsize;
235 EmfDC->emf->szlMillimeters.cy = EmfDC->vertsize;
236
237 /* Size in micrometers */
238 EmfDC->emf->szlMicrometers.cx = EmfDC->horzsize * 1000;
239 EmfDC->emf->szlMicrometers.cy = EmfDC->vertsize * 1000;
240
241 RtlCopyMemory((char *)EmfDC->emf + sizeof(ENHMETAHEADER), description, length);
242
243 if (filename) /* disk based metafile */
244 {
245 if ((hFile = CreateFileW(filename, GENERIC_WRITE | GENERIC_READ, 0,
246 NULL, CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE)
247 {
248 EMFDRV_DeleteDC( EmfDC );
249 return NULL;
250 }
251 if (!WriteFile( hFile, (LPSTR)EmfDC->emf, size, NULL, NULL ))
252 {
253 EMFDRV_DeleteDC( EmfDC );
254 return NULL;
255 }
256 EmfDC.hFile = hFile;
257 EmfDC.iType = 2;
258 }
259 else
260 EmfDC.iType = 1;
261
262 return mDC;
263 }
264 #endif
265
266 /*
267 * @implemented
268 */
269 HENHMETAFILE
270 STDCALL
271 CopyEnhMetaFileW(
272 HENHMETAFILE hemfSrc,
273 LPCWSTR lpszFile
274 )
275 {
276 return NtGdiCopyEnhMetaFile ( hemfSrc, lpszFile );
277 }
278
279
280 /*
281 * @implemented
282 */
283 HENHMETAFILE
284 STDCALL
285 CopyEnhMetaFileA(
286 HENHMETAFILE hemfSrc,
287 LPCSTR lpszFile
288 )
289 {
290 NTSTATUS Status;
291 LPWSTR lpszFileW;
292 HENHMETAFILE rc = 0;
293
294 Status = HEAP_strdupA2W ( &lpszFileW, lpszFile );
295 if (!NT_SUCCESS (Status))
296 SetLastError (RtlNtStatusToDosError(Status));
297 else
298 {
299 rc = NtGdiCopyEnhMetaFile ( hemfSrc, lpszFileW );
300
301 HEAP_free ( lpszFileW );
302 }
303 return rc;
304 }
305
306
307 /*
308 * @implemented
309 */
310 HDC
311 STDCALL
312 CreateEnhMetaFileW(
313 HDC hdcRef,
314 LPCWSTR lpFileName,
315 CONST RECT *lpRect,
316 LPCWSTR lpDescription
317 )
318 {
319 return NtGdiCreateEnhMetaFile ( hdcRef, lpFileName, (CONST LPRECT)lpRect, lpDescription );
320 }
321
322
323 /*
324 * @implemented
325 */
326 HDC
327 STDCALL
328 CreateEnhMetaFileA(
329 HDC hdcRef,
330 LPCSTR lpFileName,
331 CONST RECT *lpRect,
332 LPCSTR lpDescription
333 )
334 {
335 NTSTATUS Status;
336 LPWSTR lpFileNameW, lpDescriptionW;
337 HDC rc = 0;
338
339 lpFileNameW = NULL;
340 if (lpFileName != NULL)
341 {
342 Status = HEAP_strdupA2W ( &lpFileNameW, lpFileName );
343 if (!NT_SUCCESS (Status))
344 SetLastError (RtlNtStatusToDosError(Status));
345
346 return rc;
347 }
348
349 lpDescriptionW = NULL;
350 if (lpDescription != NULL)
351 {
352 Status = HEAP_strdupA2W ( &lpDescriptionW, lpDescription );
353 if (!NT_SUCCESS (Status))
354 SetLastError (RtlNtStatusToDosError(Status));
355
356 return rc;
357 }
358
359 rc = NtGdiCreateEnhMetaFile (hdcRef, lpFileNameW, (CONST LPRECT)lpRect, lpDescriptionW );
360
361 if (lpDescriptionW != NULL)
362 HEAP_free ( lpDescriptionW );
363
364 if (lpFileNameW != NULL)
365 HEAP_free ( lpFileNameW );
366
367 return rc;
368 }
369
370 /*
371 * @implemented
372 */
373 HENHMETAFILE
374 STDCALL
375 GetEnhMetaFileW(
376 LPCWSTR lpszMetaFile
377 )
378 {
379 return NtGdiGetEnhMetaFile ( lpszMetaFile );
380 }
381
382
383 /*
384 * @implemented
385 */
386 HENHMETAFILE
387 STDCALL
388 GetEnhMetaFileA(
389 LPCSTR lpszMetaFile
390 )
391 {
392 NTSTATUS Status;
393 LPWSTR lpszMetaFileW;
394 HENHMETAFILE rc = 0;
395
396 Status = HEAP_strdupA2W ( &lpszMetaFileW, lpszMetaFile );
397 if (!NT_SUCCESS (Status))
398 SetLastError (RtlNtStatusToDosError(Status));
399 else
400 {
401 rc = NtGdiGetEnhMetaFile ( lpszMetaFileW );
402
403 HEAP_free ( lpszMetaFileW );
404 }
405
406 return rc;
407 }
408
409
410 /*
411 * @implemented
412 */
413 UINT
414 STDCALL
415 GetEnhMetaFileDescriptionW(
416 HENHMETAFILE hemf,
417 UINT cchBuffer,
418 LPWSTR lpszDescription
419 )
420 {
421 return NtGdiGetEnhMetaFileDescription ( hemf, cchBuffer, lpszDescription );
422 }
423
424
425 /*
426 * @implemented
427 */
428 UINT
429 STDCALL
430 GetEnhMetaFileDescriptionA(
431 HENHMETAFILE hemf,
432 UINT cchBuffer,
433 LPSTR lpszDescription
434 )
435 {
436 NTSTATUS Status;
437 LPWSTR lpszDescriptionW;
438 UINT rc;
439
440 if ( lpszDescription && cchBuffer )
441 {
442 lpszDescriptionW = (LPWSTR)HEAP_alloc ( cchBuffer*sizeof(WCHAR) );
443 if ( !lpszDescriptionW )
444 {
445 SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY));
446 return 0;
447 }
448 }
449 else
450 lpszDescriptionW = NULL;
451
452 rc = NtGdiGetEnhMetaFileDescription ( hemf, cchBuffer, lpszDescriptionW );
453
454 if ( lpszDescription && cchBuffer )
455 {
456 Status = RtlUnicodeToMultiByteN ( lpszDescription,
457 cchBuffer,
458 NULL,
459 lpszDescriptionW,
460 cchBuffer );
461 HEAP_free ( lpszDescriptionW );
462 if ( !NT_SUCCESS(Status) )
463 {
464 SetLastError (RtlNtStatusToDosError(Status));
465 return 0;
466 }
467 }
468
469 return rc;
470 }
471