2 Enhanced metafile functions
3 Copyright 1998, Douglas Ridgway
14 /*****************************************************************************
15 * GetEnhMetaFile32A (GDI32.174)
19 HENHMETAFILE32 GetEnhMetaFile32A(
20 LPCSTR lpszMetaFile /* filename of enhanced metafile */
23 HENHMETAFILE32 hmf = 0;
27 HFILE32 hf = CreateFile32A(lpszMetaFile, GENERIC_READ, 0, 0,
29 if (!ReadFile(hf, &h, sizeof(ENHMETAHEADER), &read, NULL))
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(GHND, h.nBytes);
35 p = GlobalLock32(hmf);
36 if (!ReadFile(hf, p, h.nBytes, &read, NULL)) return 0;
41 /*****************************************************************************
42 * GetEnhMetaFileHeader32 (GDI32.178)
44 * If _buf_ is NULL, returns the size of buffer required.
45 * Otherwise, copy up to _bufsize_ bytes of enhanced metafile header into
48 UINT32 GetEnhMetaFileHeader32(
49 HENHMETAFILE32 hmf, /* enhanced metafile */
50 UINT32 bufsize, /* size of buffer */
51 LPENHMETAHEADER buf /* buffer */
54 LPENHMETAHEADER p = GlobalLock32(hmf);
55 if (!buf) return sizeof(ENHMETAHEADER);
56 memmove(buf, p, MIN(sizeof(ENHMETAHEADER), bufsize));
57 return MIN(sizeof(ENHMETAHEADER), bufsize);
61 /*****************************************************************************
62 * GetEnhMetaFileDescription32A (GDI32.176)
64 * Copies the description string of an enhanced metafile into a buffer
68 * doesn't work. description is wide, with substructure
70 UINT32 GetEnhMetaFileDescription32A(
71 HENHMETAFILE32 hmf, /* enhanced metafile */
72 UINT32 size, /* size of buf */
73 LPSTR buf /* buffer to receive description */
76 LPENHMETAHEADER p = GlobalLock32(hmf);
78 if (!buf || !size) return p->nDescription;
79 lstrcpynWtoA(buf, (void *)p+p->offDescription, size);
80 /* memmove(buf, (void *)p+p->offDescription, MIN(size,p->nDescription));*/
81 return MIN(size,p->nDescription);
84 /*****************************************************************************
85 * PlayEnhMetaFileRecord32 (GDI32.264)
87 * Render a single enhanced metafile record in the device context hdc.
90 * TRUE on success, FALSE on error.
92 * Many unimplemented records.
94 BOOL32 PlayEnhMetaFileRecord32(
96 /* device context in which to render EMF record */
97 LPHANDLETABLE32 handletable,
98 /* array of handles to be used in rendering record */
99 const ENHMETARECORD *mr, /* EMF record to render */
100 UINT32 handles /* size of handle array */
105 "hdc = %08x, handletable = %p, record = %p, numHandles = %d\n",
106 hdc, handletable, mr, handles);
107 if (!mr) return FALSE;
111 TRACE(metafile, " type=%d\n", type);
116 ENHMETAHEADER *h = (LPENHMETAHEADER) mr;
123 /* application defined and processed */
128 DWORD mode = mr->dParm[0];
129 SetMapMode32(hdc, mode);
134 DWORD mode = mr->dParm[0];
135 SetBkMode32(hdc, mode);
140 DWORD mode = mr->dParm[0];
141 SetBkColor32(hdc, mode);
144 case EMR_SETPOLYFILLMODE:
146 DWORD mode = mr->dParm[0];
147 SetPolyFillMode32(hdc, mode);
152 DWORD mode = mr->dParm[0];
153 SetROP232(hdc, mode);
156 case EMR_SETSTRETCHBLTMODE:
158 DWORD mode = mr->dParm[0];
159 SetStretchBltMode32(hdc, mode);
162 case EMR_SETTEXTALIGN:
164 DWORD align = mr->dParm[0];
165 SetTextAlign32(hdc, align);
168 case EMR_SETTEXTCOLOR:
170 DWORD color = mr->dParm[0];
171 SetTextColor32(hdc, color);
181 RestoreDC32(hdc, mr->dParm[0]);
184 case EMR_INTERSECTCLIPRECT:
186 INT32 left = mr->dParm[0], top = mr->dParm[1], right = mr->dParm[2],
187 bottom = mr->dParm[3];
188 IntersectClipRect32(hdc, left, top, right, bottom);
192 case EMR_SELECTOBJECT:
194 DWORD obj = mr->dParm[0];
195 SelectObject32(hdc, (handletable->objectHandle)[obj]);
198 case EMR_DELETEOBJECT:
200 DWORD obj = mr->dParm[0];
201 DeleteObject32( (handletable->objectHandle)[obj]);
202 (handletable->objectHandle)[obj] = 0;
206 case EMR_SETWINDOWORGEX:
208 DWORD x = mr->dParm[0], y = mr->dParm[1];
209 SetWindowOrgEx32(hdc, x, y, NULL);
212 case EMR_SETWINDOWEXTEX:
214 DWORD x = mr->dParm[0], y = mr->dParm[1];
215 SetWindowExtEx32(hdc, x, y, NULL);
218 case EMR_SETVIEWPORTORGEX:
220 DWORD x = mr->dParm[0], y = mr->dParm[1];
221 SetViewportOrgEx32(hdc, x, y, NULL);
224 case EMR_SETVIEWPORTEXTEX:
226 DWORD x = mr->dParm[0], y = mr->dParm[1];
227 SetViewportExtEx32(hdc, x, y, NULL);
233 DWORD obj = mr->dParm[0];
234 (handletable->objectHandle)[obj] =
235 CreatePenIndirect32((LOGPEN32 *) &(mr->dParm[1]));
238 case EMR_EXTCREATEPEN:
240 DWORD obj = mr->dParm[0];
241 DWORD style = mr->dParm[1], brush = mr->dParm[2];
242 LOGBRUSH32 *b = (LOGBRUSH32 *) &mr->dParm[3];
243 /* FIXME: other args not handled */
244 (handletable->objectHandle)[obj] =
245 ExtCreatePen32(style, brush, b, 0, NULL);
248 case EMR_CREATEBRUSHINDIRECT:
250 DWORD obj = mr->dParm[0];
251 (handletable->objectHandle)[obj] =
252 CreateBrushIndirect32((LOGBRUSH32 *) &(mr->dParm[1]));
255 case EMR_EXTCREATEFONTINDIRECTW:
257 DWORD obj = mr->dParm[0];
258 (handletable->objectHandle)[obj] =
259 CreateFontIndirect32W((LOGFONT32W *) &(mr->dParm[1]));
265 DWORD x = mr->dParm[0], y = mr->dParm[1];
266 MoveToEx32(hdc, x, y, NULL);
271 DWORD x = mr->dParm[0], y = mr->dParm[1];
277 INT32 left = mr->dParm[0], top = mr->dParm[1], right = mr->dParm[2],
278 bottom = mr->dParm[3];
279 Rectangle32(hdc, left, top, right, bottom);
284 INT32 left = mr->dParm[0], top = mr->dParm[1], right = mr->dParm[2],
285 bottom = mr->dParm[3];
286 Ellipse32(hdc, left, top, right, bottom);
292 /* FIXME: 0-3 : a bounding rectangle? */
293 INT32 count = mr->dParm[4];
294 Polygon16(hdc, (POINT16 *)&mr->dParm[5], count);
298 case EMR_POLYPOLYGON16:
300 INT32 polygons = mr->dParm[z];
301 LPPOINT16 pts = (LPPOINT16) &mr->dParm[x];
302 LPINT16 counts = (LPINT16) &mr->dParm[y];
303 PolyPolygon16(hdc, pts, counts, polygons);
307 case EMR_EXTTEXTOUTW:
310 DWORD flags = mr->dParm[4];
312 DWORD x = mr->dParm[7], y = mr->dParm[8];
313 DWORD count = mr->dParm[9];
315 LPWSTR str = (LPWSTR)& mr->dParm[17];
316 /* trailing info: dx array? */
317 ExtTextOut32W(hdc, x, y, flags, /* lpRect */ NULL,
318 str, count, /* lpDx */ NULL);
323 FIXME(metafile, "type %d is unimplemented\n", type);
324 /* SetLastError(E_NOTIMPL); */
331 /*****************************************************************************
333 * EnumEnhMetaFile32 (GDI32.79)
335 * Walk an enhanced metafile, calling a user-specified function _EnhMetaFunc_
337 * record. Returns when either every record has been used or
338 * when _EnhMetaFunc_ returns FALSE.
342 * TRUE if every record is used, FALSE if any invocation of _EnhMetaFunc_
348 BOOL32 EnumEnhMetaFile32(
349 HDC32 hdc, /* device context to pass to _EnhMetaFunc_ */
350 HENHMETAFILE32 hmf, /* EMF to walk */
351 ENHMFENUMPROC32 callback, /* callback function */
352 LPVOID data, /* optional data for callback function */
353 const RECT32 *rect /* bounding rectangle for rendered metafile */
357 LPENHMETARECORD p = GlobalLock32(hmf);
358 INT32 count = ((LPENHMETAHEADER) p)->nHandles;
359 HANDLETABLE32 *ht = (HANDLETABLE32 *)GlobalAlloc32(GPTR, sizeof(HANDLETABLE32)*count);
360 ht->objectHandle[0] = hmf;
362 ret = (*callback)(hdc, ht, p, count, data);
363 if (p->iType == EMR_EOF) break;
364 p = (void *) p + p->nSize;
372 /**************************************************************************
373 * PlayEnhMetaFile32 (GDI32.263)
375 * Renders an enhanced metafile into a specified rectangle *lpRect
376 * in device context hdc.
379 * Almost entirely unimplemented
382 BOOL32 PlayEnhMetaFile32(
383 HDC32 hdc, /* DC to render into */
384 HENHMETAFILE32 hmf, /* metafile to render */
385 const RECT32 *lpRect /* rectangle to place metafile inside */
388 LPENHMETARECORD p = GlobalLock32(hmf);
389 INT32 count = ((LPENHMETAHEADER) p)->nHandles;
390 HANDLETABLE32 *ht = (HANDLETABLE32 *)GlobalAlloc32(GPTR,
391 sizeof(HANDLETABLE32)*count);
392 ht->objectHandle[0] = hmf;
394 PlayEnhMetaFileRecord32(hdc, ht, p, count);
395 if (p->iType == EMR_EOF) break;
396 p = (void *) p + p->nSize; /* casted so that arithmetic is in bytes */
401 /*****************************************************************************
402 * DeleteEnhMetaFile32 (GDI32.68)
404 BOOL32 DeleteEnhMetaFile32(HENHMETAFILE32 hmf) {
405 return !GlobalFree32(hmf);
408 /*****************************************************************************
409 * CopyEnhMetaFileA (GDI32.21)
411 HENHMETAFILE32 CopyEnhMetaFile32A(HENHMETAFILE32 hmf, LPCSTR file) {