2 Enhanced metafile functions
3 Copyright 1998, Douglas Ridgway
15 /*****************************************************************************
16 * GetEnhMetaFile32A (GDI32.174)
20 HENHMETAFILE32 WINAPI
GetEnhMetaFile32A(
21 LPCSTR lpszMetaFile
/* filename of enhanced metafile */
24 HENHMETAFILE32 hmf
= 0;
28 HFILE32 hf
= CreateFile32A(lpszMetaFile
, GENERIC_READ
, 0, 0,
30 if (hf
== INVALID_HANDLE_VALUE32
) {
31 FIXME(metafile
,"could not open %s\n",lpszMetaFile
);
34 if (!ReadFile(hf
, &h
, sizeof(ENHMETAHEADER
), &read
, NULL
))
36 if (read
!=sizeof(ENHMETAHEADER
)) return 0;
37 SetFilePointer(hf
, 0, NULL
, FILE_BEGIN
);
38 /* hmf = CreateFileMapping32A( hf, NULL, NULL, NULL, NULL, "temp"); */
39 hmf
= GlobalAlloc32(GPTR
, h
.nBytes
);
40 p
= GlobalLock32(hmf
);
41 if (!ReadFile(hf
, p
, h
.nBytes
, &read
, NULL
)) return 0;
42 assert(read
==h
.nBytes
);
47 /*****************************************************************************
48 * GetEnhMetaFile32W (GDI32.180)
50 HENHMETAFILE32 WINAPI
GetEnhMetaFile32W(
51 LPCWSTR lpszMetaFile
) /* filename of enhanced metafile */
53 FIXME(metafile
, "(%p): stub\n", lpszMetaFile
);
57 /*****************************************************************************
58 * GetEnhMetaFileHeader (GDI32.178)
60 * If _buf_ is NULL, returns the size of buffer required.
61 * Otherwise, copy up to _bufsize_ bytes of enhanced metafile header into
64 UINT32 WINAPI
GetEnhMetaFileHeader(
65 HENHMETAFILE32 hmf
, /* enhanced metafile */
66 UINT32 bufsize
, /* size of buffer */
67 LPENHMETAHEADER buf
/* buffer */
70 LPENHMETAHEADER p
= GlobalLock32(hmf
);
71 if (!buf
) return sizeof(ENHMETAHEADER
);
72 memmove(buf
, p
, MIN(sizeof(ENHMETAHEADER
), bufsize
));
74 return MIN(sizeof(ENHMETAHEADER
), bufsize
);
78 /*****************************************************************************
79 * GetEnhMetaFileDescription32A (GDI32.176)
81 UINT32 WINAPI
GetEnhMetaFileDescription32A(
82 HENHMETAFILE32 hmf
, /* enhanced metafile */
83 UINT32 size
, /* size of buf */
84 LPSTR buf
/* buffer to receive description */
87 LPENHMETAHEADER p
= GlobalLock32(hmf
);
88 INT32 first
= lstrlen32W( (void *)p
+p
->offDescription
);
90 if (!buf
|| !size
) return p
->nDescription
;
92 lstrcpynWtoA(buf
, (void *)p
+p
->offDescription
, size
);
94 lstrcpynWtoA(buf
, (void *)p
+p
->offDescription
+2*(first
+1), size
-first
-1);
96 /* memmove(buf, (void *)p+p->offDescription, MIN(size,p->nDescription)); */
98 return MIN(size
,p
->nDescription
);
101 /*****************************************************************************
102 * GetEnhMetaFileDescription32W (GDI32.177)
104 * Copies the description string of an enhanced metafile into a buffer
107 * If _buf_ is NULL, returns size of _buf_ required. Otherwise, returns
108 * number of characters copied.
110 UINT32 WINAPI
GetEnhMetaFileDescription32W(
111 HENHMETAFILE32 hmf
, /* enhanced metafile */
112 UINT32 size
, /* size of buf */
113 LPWSTR buf
/* buffer to receive description */
116 LPENHMETAHEADER p
= GlobalLock32(hmf
);
118 if (!buf
|| !size
) return p
->nDescription
;
120 memmove(buf
, (void *)p
+p
->offDescription
, MIN(size
,p
->nDescription
));
122 return MIN(size
,p
->nDescription
);
125 /****************************************************************************
126 * SetEnhMetaFileBits (GDI32.315)
128 * Creates an enhanced metafile by copying _bufsize_ bytes from _buf_.
130 HENHMETAFILE32 WINAPI
SetEnhMetaFileBits(UINT32 bufsize
, const BYTE
*buf
)
132 HENHMETAFILE32 hmf
= GlobalAlloc32(GPTR
, bufsize
);
133 LPENHMETAHEADER h
= GlobalLock32(hmf
);
134 memmove(h
, buf
, bufsize
);
139 /*****************************************************************************
140 * GetEnhMetaFileBits (GDI32.175)
143 UINT32 WINAPI
GetEnhMetaFileBits(
151 /*****************************************************************************
152 * PlayEnhMetaFileRecord (GDI32.264)
154 * Render a single enhanced metafile record in the device context hdc.
157 * TRUE on success, FALSE on error.
159 * Many unimplemented records.
161 BOOL32 WINAPI
PlayEnhMetaFileRecord(
162 HDC32 hdc
, /* device context in which to render EMF record */
163 LPHANDLETABLE32 handletable
, /* array of handles to be used in rendering record */
164 const ENHMETARECORD
*mr
, /* EMF record to render */
165 UINT32 handles
/* size of handle array */
170 "hdc = %08x, handletable = %p, record = %p, numHandles = %d\n",
171 hdc
, handletable
, mr
, handles
);
172 if (!mr
) return FALSE
;
176 TRACE(metafile
, " type=%d\n", type
);
181 /* ENHMETAHEADER *h = (LPENHMETAHEADER) mr; */
187 /* application defined and processed */
191 DWORD mode
= mr
->dParm
[0];
192 SetMapMode32(hdc
, mode
);
197 DWORD mode
= mr
->dParm
[0];
198 SetBkMode32(hdc
, mode
);
203 DWORD mode
= mr
->dParm
[0];
204 SetBkColor32(hdc
, mode
);
207 case EMR_SETPOLYFILLMODE
:
209 DWORD mode
= mr
->dParm
[0];
210 SetPolyFillMode32(hdc
, mode
);
215 DWORD mode
= mr
->dParm
[0];
216 SetROP232(hdc
, mode
);
219 case EMR_SETSTRETCHBLTMODE
:
221 DWORD mode
= mr
->dParm
[0];
222 SetStretchBltMode32(hdc
, mode
);
225 case EMR_SETTEXTALIGN
:
227 DWORD align
= mr
->dParm
[0];
228 SetTextAlign32(hdc
, align
);
231 case EMR_SETTEXTCOLOR
:
233 DWORD color
= mr
->dParm
[0];
234 SetTextColor32(hdc
, color
);
244 RestoreDC32(hdc
, mr
->dParm
[0]);
247 case EMR_INTERSECTCLIPRECT
:
249 INT32 left
= mr
->dParm
[0], top
= mr
->dParm
[1], right
= mr
->dParm
[2],
250 bottom
= mr
->dParm
[3];
251 IntersectClipRect32(hdc
, left
, top
, right
, bottom
);
254 case EMR_SELECTOBJECT
:
256 DWORD obj
= mr
->dParm
[0];
257 SelectObject32(hdc
, (handletable
->objectHandle
)[obj
]);
260 case EMR_DELETEOBJECT
:
262 DWORD obj
= mr
->dParm
[0];
263 DeleteObject32( (handletable
->objectHandle
)[obj
]);
264 (handletable
->objectHandle
)[obj
] = 0;
267 case EMR_SETWINDOWORGEX
:
269 DWORD x
= mr
->dParm
[0], y
= mr
->dParm
[1];
270 SetWindowOrgEx32(hdc
, x
, y
, NULL
);
273 case EMR_SETWINDOWEXTEX
:
275 DWORD x
= mr
->dParm
[0], y
= mr
->dParm
[1];
276 SetWindowExtEx32(hdc
, x
, y
, NULL
);
279 case EMR_SETVIEWPORTORGEX
:
281 DWORD x
= mr
->dParm
[0], y
= mr
->dParm
[1];
282 SetViewportOrgEx32(hdc
, x
, y
, NULL
);
285 case EMR_SETVIEWPORTEXTEX
:
287 DWORD x
= mr
->dParm
[0], y
= mr
->dParm
[1];
288 SetViewportExtEx32(hdc
, x
, y
, NULL
);
293 DWORD obj
= mr
->dParm
[0];
294 (handletable
->objectHandle
)[obj
] =
295 CreatePenIndirect32((LOGPEN32
*) &(mr
->dParm
[1]));
298 case EMR_EXTCREATEPEN
:
300 DWORD obj
= mr
->dParm
[0];
301 DWORD style
= mr
->dParm
[1], brush
= mr
->dParm
[2];
302 LOGBRUSH32
*b
= (LOGBRUSH32
*) &mr
->dParm
[3];
303 FIXME(metafile
, "Some ExtCreatePen args not handled\n");
304 (handletable
->objectHandle
)[obj
] =
305 ExtCreatePen32(style
, brush
, b
, 0, NULL
);
308 case EMR_CREATEBRUSHINDIRECT
:
310 DWORD obj
= mr
->dParm
[0];
311 (handletable
->objectHandle
)[obj
] =
312 CreateBrushIndirect32((LOGBRUSH32
*) &(mr
->dParm
[1]));
315 case EMR_EXTCREATEFONTINDIRECTW
:
317 DWORD obj
= mr
->dParm
[0];
318 (handletable
->objectHandle
)[obj
] =
319 CreateFontIndirect32W((LOGFONT32W
*) &(mr
->dParm
[1]));
324 DWORD x
= mr
->dParm
[0], y
= mr
->dParm
[1];
325 MoveToEx32(hdc
, x
, y
, NULL
);
330 DWORD x
= mr
->dParm
[0], y
= mr
->dParm
[1];
336 INT32 left
= mr
->dParm
[0], top
= mr
->dParm
[1], right
= mr
->dParm
[2],
337 bottom
= mr
->dParm
[3];
338 Rectangle32(hdc
, left
, top
, right
, bottom
);
343 INT32 left
= mr
->dParm
[0], top
= mr
->dParm
[1], right
= mr
->dParm
[2],
344 bottom
= mr
->dParm
[3];
345 Ellipse32(hdc
, left
, top
, right
, bottom
);
350 /* 0-3 : a bounding rectangle? */
351 INT32 count
= mr
->dParm
[4];
352 FIXME(metafile
, "Some Polygon16 args not handled\n");
353 Polygon16(hdc
, (POINT16
*)&mr
->dParm
[5], count
);
358 /* 0-3 : a bounding rectangle? */
359 INT32 count
= mr
->dParm
[4];
360 FIXME(metafile
, "Some Polyline16 args not handled\n");
361 Polyline16(hdc
, (POINT16
*)&mr
->dParm
[5], count
);
366 case EMR_POLYPOLYGON16
:
368 INT32 polygons
= mr
->dParm
[z
];
369 LPPOINT16 pts
= (LPPOINT16
) &mr
->dParm
[x
];
370 LPINT16 counts
= (LPINT16
) &mr
->dParm
[y
];
371 PolyPolygon16(hdc
, pts
, counts
, polygons
);
375 case EMR_EXTTEXTOUTW
:
378 DWORD flags
= mr
->dParm
[4];
380 DWORD x
= mr
->dParm
[7], y
= mr
->dParm
[8];
381 DWORD count
= mr
->dParm
[9];
383 LPWSTR str
= (LPWSTR
)& mr
->dParm
[17];
384 /* trailing info: dx array? */
385 FIXME(metafile
, "Many ExtTextOut args not handled\n");
386 ExtTextOut32W(hdc
, x
, y
, flags
, /* lpRect */ NULL
,
387 str
, count
, /* lpDx */ NULL
);
392 FIXME(metafile
, "type %d is unimplemented\n", type
);
393 /* SetLastError(E_NOTIMPL); */
400 /*****************************************************************************
402 * EnumEnhMetaFile32 (GDI32.79)
404 * Walk an enhanced metafile, calling a user-specified function _EnhMetaFunc_
406 * record. Returns when either every record has been used or
407 * when _EnhMetaFunc_ returns FALSE.
411 * TRUE if every record is used, FALSE if any invocation of _EnhMetaFunc_
417 BOOL32 WINAPI
EnumEnhMetaFile32(
418 HDC32 hdc
, /* device context to pass to _EnhMetaFunc_ */
419 HENHMETAFILE32 hmf
, /* EMF to walk */
420 ENHMFENUMPROC32 callback
, /* callback function */
421 LPVOID data
, /* optional data for callback function */
422 const RECT32
*rect
/* bounding rectangle for rendered metafile */
426 LPENHMETARECORD p
= GlobalLock32(hmf
);
427 INT32 count
= ((LPENHMETAHEADER
) p
)->nHandles
;
428 HANDLETABLE32
*ht
= (HANDLETABLE32
*)GlobalAlloc32(GPTR
, sizeof(HANDLETABLE32
)*count
);
429 ht
->objectHandle
[0] = hmf
;
431 ret
= (*callback
)(hdc
, ht
, p
, count
, data
);
432 if (p
->iType
== EMR_EOF
) break;
433 p
= (void *) p
+ p
->nSize
;
435 GlobalFree32((HGLOBAL32
)ht
);
441 /**************************************************************************
442 * PlayEnhMetaFile (GDI32.263)
444 * Renders an enhanced metafile into a specified rectangle *lpRect
445 * in device context hdc.
448 * Almost entirely unimplemented
451 BOOL32 WINAPI
PlayEnhMetaFile(
452 HDC32 hdc
, /* DC to render into */
453 HENHMETAFILE32 hmf
, /* metafile to render */
454 const RECT32
*lpRect
/* rectangle to place metafile inside */
457 LPENHMETARECORD p
= GlobalLock32(hmf
);
458 INT32 count
= ((LPENHMETAHEADER
) p
)->nHandles
;
459 HANDLETABLE32
*ht
= (HANDLETABLE32
*)GlobalAlloc32(GPTR
,
460 sizeof(HANDLETABLE32
)*count
);
464 LPENHMETAHEADER h
= (LPENHMETAHEADER
) p
;
465 FLOAT xscale
= (h
->rclBounds
.right
-h
->rclBounds
.left
)/(lpRect
->right
-lpRect
->left
);
466 FLOAT yscale
= (h
->rclBounds
.bottom
-h
->rclBounds
.top
)/(lpRect
->bottom
-lpRect
->top
);
467 XFORM xform
= {xscale
, 0, 0, yscale
, 0, 0};
468 xform
.eDx
= lpRect
->left
;
469 xform
.eDy
= lpRect
->top
;
470 FIXME(metafile
, "play into rect doesn't work\n");
471 savedMode
= SetGraphicsMode(hdc
, GM_ADVANCED
);
472 if (!SetWorldTransform(hdc
, &xform
)) {
473 WARN(metafile
, "World transform failed!\n");
477 ht
->objectHandle
[0] = hmf
;
479 PlayEnhMetaFileRecord(hdc
, ht
, p
, count
);
480 if (p
->iType
== EMR_EOF
) break;
481 p
= (void *) p
+ p
->nSize
; /* casted so that arithmetic is in bytes */
484 if (savedMode
) SetGraphicsMode(hdc
, savedMode
);
485 ret
= TRUE
; /* FIXME: calculate a more accurate return value */
489 /*****************************************************************************
490 * DeleteEnhMetaFile (GDI32.68)
492 * Deletes an enhanced metafile and frees the associated storage.
494 BOOL32 WINAPI
DeleteEnhMetaFile(HENHMETAFILE32 hmf
) {
495 return !GlobalFree32(hmf
);
498 /*****************************************************************************
499 * CopyEnhMetaFileA (GDI32.21) Duplicate an enhanced metafile
503 HENHMETAFILE32 WINAPI
CopyEnhMetaFile32A(
508 LPENHMETAHEADER h
= GlobalLock32(hmf
);
509 HENHMETAFILE32 hmf2
= GlobalAlloc32(GPTR
, h
->nBytes
);
510 LPENHMETAHEADER h2
= GlobalLock32(hmf2
);
512 memmove(h2
, h
, h
->nBytes
);
513 GlobalUnlock32(hmf2
);
517 FIXME(metafile
, "write to file not implemented\n");
522 /*****************************************************************************
523 * GetEnhMetaFilePaletteEntries (GDI32.179)
525 * Copy the palette and report size
528 UINT32 WINAPI
GetEnhMetaFilePaletteEntries(HENHMETAFILE32 hemf
,
532 LPENHMETAHEADER h
= GlobalLock32(hemf
);
535 GlobalUnlock32(hemf
);
538 if ((lppe
)&&(cEntries
>0)){
539 FIXME(metafile
,"Stub\n");
540 GlobalUnlock32(hemf
);
543 GlobalUnlock32(hemf
);
551 /******************************************************************
552 * SetWinMetaFileBits (GDI32.343)
554 * Translate from old style to new style.
557 HENHMETAFILE32 WINAPI
SetWinMetaFileBits(UINT32 cbBuffer
,
558 CONST BYTE
*lpbBuffer
,
560 CONST METAFILEPICT32
*lpmfp
563 FIXME(metafile
,"Stub\n");