Moved ADVAPI32 files to dlls/advapi32.
[wine/multimedia.git] / objects / enhmetafile.c
blobb4d8b83735799d7c39266118204e931fcc6854ef
1 /*
2 Enhanced metafile functions
3 Copyright 1998, Douglas Ridgway
4 */
6 #include <string.h>
7 #include "windows.h"
8 #include "gdi.h"
9 #include "winbase.h"
10 #include "winnt.h"
11 #include "debug.h"
12 #include "winerror.h"
14 /*****************************************************************************
15 * GetEnhMetaFile32A (GDI32.174)
19 HENHMETAFILE32 WINAPI GetEnhMetaFile32A(
20 LPCSTR lpszMetaFile /* filename of enhanced metafile */
23 HENHMETAFILE32 hmf = 0;
24 ENHMETAHEADER h;
25 BYTE *p;
26 DWORD read;
27 HFILE32 hf = CreateFile32A(lpszMetaFile, GENERIC_READ, 0, 0,
28 OPEN_EXISTING, 0, 0);
29 if (!ReadFile(hf, &h, sizeof(ENHMETAHEADER), &read, NULL))
30 return 0;
31 if (read!=sizeof(ENHMETAHEADER)) return 0;
32 SetFilePointer(hf, 0, NULL, FILE_BEGIN);
33 /* hmf = CreateFileMapping32A( hf, NULL, NULL, NULL, NULL, "temp"); */
34 hmf = GlobalAlloc32(GPTR, h.nBytes);
35 p = GlobalLock32(hmf);
36 if (!ReadFile(hf, p, h.nBytes, &read, NULL)) return 0;
37 GlobalUnlock32(hmf);
38 return hmf;
41 /*****************************************************************************
42 * GetEnhMetaFile32W (GDI32.180)
44 HENHMETAFILE32 WINAPI GetEnhMetaFile32W(
45 LPCWSTR lpszMetaFile) /* filename of enhanced metafile */
47 FIXME(metafile, "(%p): stub\n", lpszMetaFile);
48 return 0;
51 /*****************************************************************************
52 * GetEnhMetaFileHeader (GDI32.178)
54 * If _buf_ is NULL, returns the size of buffer required.
55 * Otherwise, copy up to _bufsize_ bytes of enhanced metafile header into
56 * _buf.
58 UINT32 WINAPI GetEnhMetaFileHeader(
59 HENHMETAFILE32 hmf, /* enhanced metafile */
60 UINT32 bufsize, /* size of buffer */
61 LPENHMETAHEADER buf /* buffer */
64 LPENHMETAHEADER p = GlobalLock32(hmf);
65 if (!buf) return sizeof(ENHMETAHEADER);
66 memmove(buf, p, MIN(sizeof(ENHMETAHEADER), bufsize));
67 GlobalUnlock32(hmf);
68 return MIN(sizeof(ENHMETAHEADER), bufsize);
72 /*****************************************************************************
73 * GetEnhMetaFileDescription32A (GDI32.176)
75 UINT32 WINAPI GetEnhMetaFileDescription32A(
76 HENHMETAFILE32 hmf, /* enhanced metafile */
77 UINT32 size, /* size of buf */
78 LPSTR buf /* buffer to receive description */
81 LPENHMETAHEADER p = GlobalLock32(hmf);
82 INT32 first = lstrlen32W( (void *)p+p->offDescription);
84 if (!buf || !size) return p->nDescription;
86 lstrcpynWtoA(buf, (void *)p+p->offDescription, size);
87 buf += first +1;
88 lstrcpynWtoA(buf, (void *)p+p->offDescription+2*(first+1), size-first-1);
90 /* memmove(buf, (void *)p+p->offDescription, MIN(size,p->nDescription)); */
91 GlobalUnlock32(hmf);
92 return MIN(size,p->nDescription);
95 /*****************************************************************************
96 * GetEnhMetaFileDescription32W (GDI32.177)
98 * Copies the description string of an enhanced metafile into a buffer
99 * _buf_.
101 * If _buf_ is NULL, returns size of _buf_ required. Otherwise, returns
102 * number of characters copied.
104 UINT32 WINAPI GetEnhMetaFileDescription32W(
105 HENHMETAFILE32 hmf, /* enhanced metafile */
106 UINT32 size, /* size of buf */
107 LPWSTR buf /* buffer to receive description */
110 LPENHMETAHEADER p = GlobalLock32(hmf);
112 if (!buf || !size) return p->nDescription;
114 memmove(buf, (void *)p+p->offDescription, MIN(size,p->nDescription));
115 GlobalUnlock32(hmf);
116 return MIN(size,p->nDescription);
119 /****************************************************************************
120 * SetEnhMetaFileBits (GDI32.315)
122 * Creates an enhanced metafile by copying _bufsize_ bytes from _buf_.
124 HENHMETAFILE32 WINAPI SetEnhMetaFileBits(UINT32 bufsize, const BYTE *buf)
126 HENHMETAFILE32 hmf = GlobalAlloc32(GPTR, bufsize);
127 LPENHMETAHEADER h = GlobalLock32(hmf);
128 memmove(h, buf, bufsize);
129 GlobalUnlock32(hmf);
130 return hmf;
133 /*****************************************************************************
134 * GetEnhMetaFileBits (GDI32.175)
137 UINT32 WINAPI GetEnhMetaFileBits(
138 HENHMETAFILE32 hmf,
139 UINT32 bufsize,
140 LPBYTE buf
142 return 0;
145 /*****************************************************************************
146 * PlayEnhMetaFileRecord (GDI32.264)
148 * Render a single enhanced metafile record in the device context hdc.
150 * RETURNS
151 * TRUE on success, FALSE on error.
152 * BUGS
153 * Many unimplemented records.
155 BOOL32 WINAPI PlayEnhMetaFileRecord(
156 HDC32 hdc, /* device context in which to render EMF record */
157 LPHANDLETABLE32 handletable, /* array of handles to be used in rendering record */
158 const ENHMETARECORD *mr, /* EMF record to render */
159 UINT32 handles /* size of handle array */
162 int type;
163 TRACE(metafile,
164 "hdc = %08x, handletable = %p, record = %p, numHandles = %d\n",
165 hdc, handletable, mr, handles);
166 if (!mr) return FALSE;
168 type = mr->iType;
170 TRACE(metafile, " type=%d\n", type);
171 switch(type)
173 case EMR_HEADER:
175 /* ENHMETAHEADER *h = (LPENHMETAHEADER) mr; */
176 break;
178 case EMR_EOF:
179 break;
180 case EMR_GDICOMMENT:
181 /* application defined and processed */
182 break;
183 case EMR_SETMAPMODE:
185 DWORD mode = mr->dParm[0];
186 SetMapMode32(hdc, mode);
187 break;
189 case EMR_SETBKMODE:
191 DWORD mode = mr->dParm[0];
192 SetBkMode32(hdc, mode);
193 break;
195 case EMR_SETBKCOLOR:
197 DWORD mode = mr->dParm[0];
198 SetBkColor32(hdc, mode);
199 break;
201 case EMR_SETPOLYFILLMODE:
203 DWORD mode = mr->dParm[0];
204 SetPolyFillMode32(hdc, mode);
205 break;
207 case EMR_SETROP2:
209 DWORD mode = mr->dParm[0];
210 SetROP232(hdc, mode);
211 break;
213 case EMR_SETSTRETCHBLTMODE:
215 DWORD mode = mr->dParm[0];
216 SetStretchBltMode32(hdc, mode);
217 break;
219 case EMR_SETTEXTALIGN:
221 DWORD align = mr->dParm[0];
222 SetTextAlign32(hdc, align);
223 break;
225 case EMR_SETTEXTCOLOR:
227 DWORD color = mr->dParm[0];
228 SetTextColor32(hdc, color);
229 break;
231 case EMR_SAVEDC:
233 SaveDC32(hdc);
234 break;
236 case EMR_RESTOREDC:
238 RestoreDC32(hdc, mr->dParm[0]);
239 break;
241 case EMR_INTERSECTCLIPRECT:
243 INT32 left = mr->dParm[0], top = mr->dParm[1], right = mr->dParm[2],
244 bottom = mr->dParm[3];
245 IntersectClipRect32(hdc, left, top, right, bottom);
246 break;
248 case EMR_SELECTOBJECT:
250 DWORD obj = mr->dParm[0];
251 SelectObject32(hdc, (handletable->objectHandle)[obj]);
252 break;
254 case EMR_DELETEOBJECT:
256 DWORD obj = mr->dParm[0];
257 DeleteObject32( (handletable->objectHandle)[obj]);
258 (handletable->objectHandle)[obj] = 0;
259 break;
261 case EMR_SETWINDOWORGEX:
263 DWORD x = mr->dParm[0], y = mr->dParm[1];
264 SetWindowOrgEx32(hdc, x, y, NULL);
265 break;
267 case EMR_SETWINDOWEXTEX:
269 DWORD x = mr->dParm[0], y = mr->dParm[1];
270 SetWindowExtEx32(hdc, x, y, NULL);
271 break;
273 case EMR_SETVIEWPORTORGEX:
275 DWORD x = mr->dParm[0], y = mr->dParm[1];
276 SetViewportOrgEx32(hdc, x, y, NULL);
277 break;
279 case EMR_SETVIEWPORTEXTEX:
281 DWORD x = mr->dParm[0], y = mr->dParm[1];
282 SetViewportExtEx32(hdc, x, y, NULL);
283 break;
285 case EMR_CREATEPEN:
287 DWORD obj = mr->dParm[0];
288 (handletable->objectHandle)[obj] =
289 CreatePenIndirect32((LOGPEN32 *) &(mr->dParm[1]));
290 break;
292 case EMR_EXTCREATEPEN:
294 DWORD obj = mr->dParm[0];
295 DWORD style = mr->dParm[1], brush = mr->dParm[2];
296 LOGBRUSH32 *b = (LOGBRUSH32 *) &mr->dParm[3];
297 FIXME(metafile, "Some ExtCreatePen args not handled\n");
298 (handletable->objectHandle)[obj] =
299 ExtCreatePen32(style, brush, b, 0, NULL);
300 break;
302 case EMR_CREATEBRUSHINDIRECT:
304 DWORD obj = mr->dParm[0];
305 (handletable->objectHandle)[obj] =
306 CreateBrushIndirect32((LOGBRUSH32 *) &(mr->dParm[1]));
307 break;
309 case EMR_EXTCREATEFONTINDIRECTW:
311 DWORD obj = mr->dParm[0];
312 (handletable->objectHandle)[obj] =
313 CreateFontIndirect32W((LOGFONT32W *) &(mr->dParm[1]));
314 break;
316 case EMR_MOVETOEX:
318 DWORD x = mr->dParm[0], y = mr->dParm[1];
319 MoveToEx32(hdc, x, y, NULL);
320 break;
322 case EMR_LINETO:
324 DWORD x = mr->dParm[0], y = mr->dParm[1];
325 LineTo32(hdc, x, y);
326 break;
328 case EMR_RECTANGLE:
330 INT32 left = mr->dParm[0], top = mr->dParm[1], right = mr->dParm[2],
331 bottom = mr->dParm[3];
332 Rectangle32(hdc, left, top, right, bottom);
333 break;
335 case EMR_ELLIPSE:
337 INT32 left = mr->dParm[0], top = mr->dParm[1], right = mr->dParm[2],
338 bottom = mr->dParm[3];
339 Ellipse32(hdc, left, top, right, bottom);
340 break;
342 case EMR_POLYGON16:
344 /* 0-3 : a bounding rectangle? */
345 INT32 count = mr->dParm[4];
346 FIXME(metafile, "Some Polygon16 args not handled\n");
347 Polygon16(hdc, (POINT16 *)&mr->dParm[5], count);
348 break;
350 case EMR_POLYLINE16:
352 /* 0-3 : a bounding rectangle? */
353 INT32 count = mr->dParm[4];
354 FIXME(metafile, "Some Polyline16 args not handled\n");
355 Polyline16(hdc, (POINT16 *)&mr->dParm[5], count);
356 break;
359 #if 0
360 case EMR_POLYPOLYGON16:
362 INT32 polygons = mr->dParm[z];
363 LPPOINT16 pts = (LPPOINT16) &mr->dParm[x];
364 LPINT16 counts = (LPINT16) &mr->dParm[y];
365 PolyPolygon16(hdc, pts, counts, polygons);
366 break;
368 #endif
369 case EMR_EXTTEXTOUTW:
371 /* 0-3: ??? */
372 DWORD flags = mr->dParm[4];
373 /* 5, 6: ??? */
374 DWORD x = mr->dParm[7], y = mr->dParm[8];
375 DWORD count = mr->dParm[9];
376 /* 10-16: ??? */
377 LPWSTR str = (LPWSTR)& mr->dParm[17];
378 /* trailing info: dx array? */
379 FIXME(metafile, "Many ExtTextOut args not handled\n");
380 ExtTextOut32W(hdc, x, y, flags, /* lpRect */ NULL,
381 str, count, /* lpDx */ NULL);
382 break;
385 default:
386 FIXME(metafile, "type %d is unimplemented\n", type);
387 /* SetLastError(E_NOTIMPL); */
388 break;
390 return TRUE;
394 /*****************************************************************************
396 * EnumEnhMetaFile32 (GDI32.79)
398 * Walk an enhanced metafile, calling a user-specified function _EnhMetaFunc_
399 * for each
400 * record. Returns when either every record has been used or
401 * when _EnhMetaFunc_ returns FALSE.
404 * RETURNS
405 * TRUE if every record is used, FALSE if any invocation of _EnhMetaFunc_
406 * returns FALSE.
408 * BUGS
409 * Ignores rect.
411 BOOL32 WINAPI EnumEnhMetaFile32(
412 HDC32 hdc, /* device context to pass to _EnhMetaFunc_ */
413 HENHMETAFILE32 hmf, /* EMF to walk */
414 ENHMFENUMPROC32 callback, /* callback function */
415 LPVOID data, /* optional data for callback function */
416 const RECT32 *rect /* bounding rectangle for rendered metafile */
419 BOOL32 ret = TRUE;
420 LPENHMETARECORD p = GlobalLock32(hmf);
421 INT32 count = ((LPENHMETAHEADER) p)->nHandles;
422 HANDLETABLE32 *ht = (HANDLETABLE32 *)GlobalAlloc32(GPTR, sizeof(HANDLETABLE32)*count);
423 ht->objectHandle[0] = hmf;
424 while (ret) {
425 ret = (*callback)(hdc, ht, p, count, data);
426 if (p->iType == EMR_EOF) break;
427 p = (void *) p + p->nSize;
429 GlobalFree32((HGLOBAL32)ht);
430 GlobalUnlock32(hmf);
431 return ret;
435 /**************************************************************************
436 * PlayEnhMetaFile (GDI32.263)
438 * Renders an enhanced metafile into a specified rectangle *lpRect
439 * in device context hdc.
441 * BUGS
442 * Almost entirely unimplemented
445 BOOL32 WINAPI PlayEnhMetaFile(
446 HDC32 hdc, /* DC to render into */
447 HENHMETAFILE32 hmf, /* metafile to render */
448 const RECT32 *lpRect /* rectangle to place metafile inside */
451 LPENHMETARECORD p = GlobalLock32(hmf);
452 INT32 count = ((LPENHMETAHEADER) p)->nHandles;
453 HANDLETABLE32 *ht = (HANDLETABLE32 *)GlobalAlloc32(GPTR,
454 sizeof(HANDLETABLE32)*count);
455 BOOL32 ret = FALSE;
456 INT32 savedMode = 0;
457 if (lpRect) {
458 LPENHMETAHEADER h = (LPENHMETAHEADER) p;
459 FLOAT xscale = (h->rclBounds.right-h->rclBounds.left)/(lpRect->right-lpRect->left);
460 FLOAT yscale = (h->rclBounds.bottom-h->rclBounds.top)/(lpRect->bottom-lpRect->top);
461 XFORM xform = {xscale, 0, 0, yscale, 0, 0};
462 xform.eDx = lpRect->left;
463 xform.eDy = lpRect->top;
464 FIXME(metafile, "play into rect doesn't work\n");
465 savedMode = SetGraphicsMode(hdc, GM_ADVANCED);
466 if (!SetWorldTransform(hdc, &xform)) {
467 WARN(metafile, "World transform failed!\n");
471 ht->objectHandle[0] = hmf;
472 while (1) {
473 PlayEnhMetaFileRecord(hdc, ht, p, count);
474 if (p->iType == EMR_EOF) break;
475 p = (void *) p + p->nSize; /* casted so that arithmetic is in bytes */
477 GlobalUnlock32(hmf);
478 if (savedMode) SetGraphicsMode(hdc, savedMode);
479 ret = TRUE; /* FIXME: calculate a more accurate return value */
480 return ret;
483 /*****************************************************************************
484 * DeleteEnhMetaFile (GDI32.68)
486 * Deletes an enhanced metafile and frees the associated storage.
488 BOOL32 WINAPI DeleteEnhMetaFile(HENHMETAFILE32 hmf) {
489 return !GlobalFree32(hmf);
492 /*****************************************************************************
493 * CopyEnhMetaFileA (GDI32.21) Duplicate an enhanced metafile
497 HENHMETAFILE32 WINAPI CopyEnhMetaFile32A(
498 HENHMETAFILE32 hmf,
499 LPCSTR file)
501 if (!file) {
502 LPENHMETAHEADER h = GlobalLock32(hmf);
503 HENHMETAFILE32 hmf2 = GlobalAlloc32(GPTR, h->nBytes);
504 LPENHMETAHEADER h2 = GlobalLock32(hmf2);
505 if (!h2) return 0;
506 memmove(h2, h, h->nBytes);
507 GlobalUnlock32(hmf2);
508 GlobalUnlock32(hmf);
509 return hmf2;
510 } else {
511 FIXME(metafile, "write to file not implemented\n");
512 return 0;
516 /*****************************************************************************
517 * GetEnhMetaFilePaletteEntries (GDI32.179)
519 * Copy the palette and report size
522 UINT32 WINAPI GetEnhMetaFilePaletteEntries(HENHMETAFILE32 hemf,
523 UINT32 cEntries,
524 LPPALETTEENTRY lppe)
526 LPENHMETAHEADER h = GlobalLock32(hemf);
528 if ( h == NULL ){
529 GlobalUnlock32(hemf);
530 return(0);
531 } else {
532 if ((lppe)&&(cEntries>0)){
533 FIXME(metafile,"Stub\n");
534 GlobalUnlock32(hemf);
535 return(GDI_ERROR);
536 } else{
537 GlobalUnlock32(hemf);
538 return(0);
545 /******************************************************************
546 * SetWinMetaFileBits (GDI32.343)
548 * Translate from old style to new style.
551 HENHMETAFILE32 WINAPI SetWinMetaFileBits(UINT32 cbBuffer,
552 CONST BYTE *lpbBuffer,
553 HDC32 hdcRef,
554 CONST METAFILEPICT32 *lpmfp
557 FIXME(metafile,"Stub\n");
558 return 0;