blob: d0c7b1091a96d8c42f6f8d871755543f2640575f [file] [log] [blame]
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001/*
2 Enhanced metafile functions
3 Copyright 1998, Douglas Ridgway
4*/
5
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00006#include <string.h>
Marcus Meissnerae0a73d1999-01-20 14:11:07 +00007#include <assert.h>
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00008#include "winbase.h"
Marcus Meissner6b9dd2e1999-03-18 17:39:57 +00009#include "wingdi.h"
Marcus Meissner61afa331999-02-22 10:16:00 +000010#include "wine/winestring.h"
Charles Suprin41043011998-11-07 12:56:31 +000011#include "winerror.h"
Marcus Meissner6b9dd2e1999-03-18 17:39:57 +000012#include "debug.h"
Alexandre Julliarda69b88b1998-03-15 20:29:56 +000013
14/*****************************************************************************
15 * GetEnhMetaFile32A (GDI32.174)
16 *
17 *
18 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000019HENHMETAFILE WINAPI GetEnhMetaFileA(
Alexandre Julliarda69b88b1998-03-15 20:29:56 +000020 LPCSTR lpszMetaFile /* filename of enhanced metafile */
21 )
22{
Alexandre Julliarda3960291999-02-26 11:11:13 +000023 HENHMETAFILE hmf = 0;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +000024 ENHMETAHEADER h;
Alexandre Julliard46ea8b31998-05-03 19:01:20 +000025 BYTE *p;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +000026 DWORD read;
Alexandre Julliarda3960291999-02-26 11:11:13 +000027 HFILE hf = CreateFileA(lpszMetaFile, GENERIC_READ, 0, 0,
Alexandre Julliard54c27111998-03-29 19:44:57 +000028 OPEN_EXISTING, 0, 0);
Alexandre Julliarda3960291999-02-26 11:11:13 +000029 if (hf == INVALID_HANDLE_VALUE) {
Marcus Meissnerae0a73d1999-01-20 14:11:07 +000030 FIXME(metafile,"could not open %s\n",lpszMetaFile);
31 return 0;
32 }
Marcus Meissner16af9ba1999-01-23 12:20:41 +000033 if (!ReadFile(hf, &h, sizeof(ENHMETAHEADER), &read, NULL)) {
34 FIXME(metafile,"%s can't be read.\n",lpszMetaFile);
35 CloseHandle(hf);
Alexandre Julliard54c27111998-03-29 19:44:57 +000036 return 0;
Marcus Meissner16af9ba1999-01-23 12:20:41 +000037 }
38 if (read!=sizeof(ENHMETAHEADER)) {
39 FIXME(metafile,"%s is not long enough.\n",lpszMetaFile);
40 CloseHandle(hf);
41 return 0;
42 }
43 if (h.iType!=1) {
44 FIXME(metafile,"%s has invalid emf header (type 0x%08lx).\n",lpszMetaFile,h.iType);
45 CloseHandle(hf);
46 return 0;
47 }
48 if (memcmp(&(h.dSignature)," EMF",4)) {
49 FIXME(metafile,"%s has invalid EMF header (dSignature 0x%08lx).\n",lpszMetaFile,h.dSignature);
50 CloseHandle(hf);
51 return 0;
52 }
Alexandre Julliarda69b88b1998-03-15 20:29:56 +000053 SetFilePointer(hf, 0, NULL, FILE_BEGIN);
54 /* hmf = CreateFileMapping32A( hf, NULL, NULL, NULL, NULL, "temp"); */
Alexandre Julliarda3960291999-02-26 11:11:13 +000055 hmf = GlobalAlloc(GPTR, h.nBytes);
56 p = GlobalLock(hmf);
Marcus Meissner16af9ba1999-01-23 12:20:41 +000057 if (!ReadFile(hf, p, h.nBytes, &read, NULL)) {
58 FIXME(metafile,"%s could not be read.\n",lpszMetaFile);
Alexandre Julliarda3960291999-02-26 11:11:13 +000059 GlobalFree(hmf);
Marcus Meissner16af9ba1999-01-23 12:20:41 +000060 CloseHandle(hf);
61 return 0;
62 }
63 if (read!=h.nBytes) {
64 FIXME(metafile,"%s is not long enough (%ld expected, %ld got).\n",lpszMetaFile,h.nBytes,read);
Alexandre Julliarda3960291999-02-26 11:11:13 +000065 GlobalFree(hmf);
Marcus Meissner16af9ba1999-01-23 12:20:41 +000066 CloseHandle(hf);
67 return 0;
68 }
Alexandre Julliarda3960291999-02-26 11:11:13 +000069 GlobalUnlock(hmf);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +000070 return hmf;
71}
72
73/*****************************************************************************
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +000074 * GetEnhMetaFile32W (GDI32.180)
75 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000076HENHMETAFILE WINAPI GetEnhMetaFileW(
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +000077 LPCWSTR lpszMetaFile) /* filename of enhanced metafile */
78{
79 FIXME(metafile, "(%p): stub\n", lpszMetaFile);
Huw D M Davies5a502731998-12-11 10:17:31 +000080 return 0;
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +000081}
82
83/*****************************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +000084 * GetEnhMetaFileHeader (GDI32.178)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +000085 *
86 * If _buf_ is NULL, returns the size of buffer required.
87 * Otherwise, copy up to _bufsize_ bytes of enhanced metafile header into
88 * _buf.
89 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000090UINT WINAPI GetEnhMetaFileHeader(
91 HENHMETAFILE hmf, /* enhanced metafile */
92 UINT bufsize, /* size of buffer */
Alexandre Julliarda69b88b1998-03-15 20:29:56 +000093 LPENHMETAHEADER buf /* buffer */
94 )
95{
Alexandre Julliarda3960291999-02-26 11:11:13 +000096 LPENHMETAHEADER p = GlobalLock(hmf);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +000097 if (!buf) return sizeof(ENHMETAHEADER);
98 memmove(buf, p, MIN(sizeof(ENHMETAHEADER), bufsize));
Alexandre Julliarda3960291999-02-26 11:11:13 +000099 GlobalUnlock(hmf);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000100 return MIN(sizeof(ENHMETAHEADER), bufsize);
101}
102
103
104/*****************************************************************************
105 * GetEnhMetaFileDescription32A (GDI32.176)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000106 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000107UINT WINAPI GetEnhMetaFileDescriptionA(
108 HENHMETAFILE hmf, /* enhanced metafile */
109 UINT size, /* size of buf */
Alexandre Julliard54c27111998-03-29 19:44:57 +0000110 LPSTR buf /* buffer to receive description */
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000111 )
112{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000113 LPENHMETAHEADER p = GlobalLock(hmf);
114 INT first = lstrlenW( (void *)p+p->offDescription);
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000115
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000116 if (!buf || !size) return p->nDescription;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000117
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000118 lstrcpynWtoA(buf, (void *)p+p->offDescription, size);
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000119 buf += first +1;
120 lstrcpynWtoA(buf, (void *)p+p->offDescription+2*(first+1), size-first-1);
121
122 /* memmove(buf, (void *)p+p->offDescription, MIN(size,p->nDescription)); */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000123 GlobalUnlock(hmf);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000124 return MIN(size,p->nDescription);
125}
126
127/*****************************************************************************
Alexandre Julliard642d3131998-07-12 19:29:36 +0000128 * GetEnhMetaFileDescription32W (GDI32.177)
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000129 *
130 * Copies the description string of an enhanced metafile into a buffer
131 * _buf_.
132 *
133 * If _buf_ is NULL, returns size of _buf_ required. Otherwise, returns
134 * number of characters copied.
135 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000136UINT WINAPI GetEnhMetaFileDescriptionW(
137 HENHMETAFILE hmf, /* enhanced metafile */
138 UINT size, /* size of buf */
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000139 LPWSTR buf /* buffer to receive description */
140 )
141{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000142 LPENHMETAHEADER p = GlobalLock(hmf);
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000143
144 if (!buf || !size) return p->nDescription;
145
146 memmove(buf, (void *)p+p->offDescription, MIN(size,p->nDescription));
Alexandre Julliarda3960291999-02-26 11:11:13 +0000147 GlobalUnlock(hmf);
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000148 return MIN(size,p->nDescription);
149}
150
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000151/****************************************************************************
152 * SetEnhMetaFileBits (GDI32.315)
153 *
154 * Creates an enhanced metafile by copying _bufsize_ bytes from _buf_.
155 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000156HENHMETAFILE WINAPI SetEnhMetaFileBits(UINT bufsize, const BYTE *buf)
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000157{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000158 HENHMETAFILE hmf = GlobalAlloc(GPTR, bufsize);
159 LPENHMETAHEADER h = GlobalLock(hmf);
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000160 memmove(h, buf, bufsize);
Alexandre Julliarda3960291999-02-26 11:11:13 +0000161 GlobalUnlock(hmf);
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000162 return hmf;
163}
164
165/*****************************************************************************
166 * GetEnhMetaFileBits (GDI32.175)
167 *
168 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000169UINT WINAPI GetEnhMetaFileBits(
170 HENHMETAFILE hmf,
171 UINT bufsize,
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000172 LPBYTE buf
173) {
174 return 0;
175}
176
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000177/*****************************************************************************
178 * PlayEnhMetaFileRecord (GDI32.264)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000179 *
180 * Render a single enhanced metafile record in the device context hdc.
181 *
182 * RETURNS
183 * TRUE on success, FALSE on error.
184 * BUGS
Alexandre Julliard54c27111998-03-29 19:44:57 +0000185 * Many unimplemented records.
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000186 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000187BOOL WINAPI PlayEnhMetaFileRecord(
188 HDC hdc, /* device context in which to render EMF record */
189 LPHANDLETABLE handletable, /* array of handles to be used in rendering record */
Alexandre Julliard54c27111998-03-29 19:44:57 +0000190 const ENHMETARECORD *mr, /* EMF record to render */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000191 UINT handles /* size of handle array */
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000192 )
193{
194 int type;
Alexandre Julliard54c27111998-03-29 19:44:57 +0000195 TRACE(metafile,
196 "hdc = %08x, handletable = %p, record = %p, numHandles = %d\n",
197 hdc, handletable, mr, handles);
198 if (!mr) return FALSE;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000199
Alexandre Julliard54c27111998-03-29 19:44:57 +0000200 type = mr->iType;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000201
Alexandre Julliard54c27111998-03-29 19:44:57 +0000202 TRACE(metafile, " type=%d\n", type);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000203 switch(type)
204 {
205 case EMR_HEADER:
Alexandre Julliard54c27111998-03-29 19:44:57 +0000206 {
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000207 /* ENHMETAHEADER *h = (LPENHMETAHEADER) mr; */
Alexandre Julliard54c27111998-03-29 19:44:57 +0000208 break;
209 }
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000210 case EMR_EOF:
Alexandre Julliard54c27111998-03-29 19:44:57 +0000211 break;
Alexandre Julliard54c27111998-03-29 19:44:57 +0000212 case EMR_GDICOMMENT:
213 /* application defined and processed */
214 break;
Alexandre Julliard54c27111998-03-29 19:44:57 +0000215 case EMR_SETMAPMODE:
216 {
217 DWORD mode = mr->dParm[0];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000218 SetMapMode(hdc, mode);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000219 break;
220 }
221 case EMR_SETBKMODE:
222 {
223 DWORD mode = mr->dParm[0];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000224 SetBkMode(hdc, mode);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000225 break;
226 }
227 case EMR_SETBKCOLOR:
228 {
229 DWORD mode = mr->dParm[0];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000230 SetBkColor(hdc, mode);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000231 break;
232 }
233 case EMR_SETPOLYFILLMODE:
234 {
235 DWORD mode = mr->dParm[0];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000236 SetPolyFillMode(hdc, mode);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000237 break;
238 }
239 case EMR_SETROP2:
240 {
241 DWORD mode = mr->dParm[0];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000242 SetROP2(hdc, mode);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000243 break;
244 }
245 case EMR_SETSTRETCHBLTMODE:
246 {
247 DWORD mode = mr->dParm[0];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000248 SetStretchBltMode(hdc, mode);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000249 break;
250 }
251 case EMR_SETTEXTALIGN:
252 {
253 DWORD align = mr->dParm[0];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000254 SetTextAlign(hdc, align);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000255 break;
256 }
257 case EMR_SETTEXTCOLOR:
258 {
259 DWORD color = mr->dParm[0];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000260 SetTextColor(hdc, color);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000261 break;
262 }
263 case EMR_SAVEDC:
264 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000265 SaveDC(hdc);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000266 break;
267 }
268 case EMR_RESTOREDC:
269 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000270 RestoreDC(hdc, mr->dParm[0]);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000271 break;
272 }
273 case EMR_INTERSECTCLIPRECT:
274 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000275 INT left = mr->dParm[0], top = mr->dParm[1], right = mr->dParm[2],
Alexandre Julliard54c27111998-03-29 19:44:57 +0000276 bottom = mr->dParm[3];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000277 IntersectClipRect(hdc, left, top, right, bottom);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000278 break;
279 }
Alexandre Julliard54c27111998-03-29 19:44:57 +0000280 case EMR_SELECTOBJECT:
281 {
282 DWORD obj = mr->dParm[0];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000283 SelectObject(hdc, (handletable->objectHandle)[obj]);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000284 break;
285 }
286 case EMR_DELETEOBJECT:
287 {
288 DWORD obj = mr->dParm[0];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000289 DeleteObject( (handletable->objectHandle)[obj]);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000290 (handletable->objectHandle)[obj] = 0;
291 break;
292 }
Alexandre Julliard54c27111998-03-29 19:44:57 +0000293 case EMR_SETWINDOWORGEX:
294 {
295 DWORD x = mr->dParm[0], y = mr->dParm[1];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000296 SetWindowOrgEx(hdc, x, y, NULL);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000297 break;
298 }
299 case EMR_SETWINDOWEXTEX:
300 {
301 DWORD x = mr->dParm[0], y = mr->dParm[1];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000302 SetWindowExtEx(hdc, x, y, NULL);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000303 break;
304 }
305 case EMR_SETVIEWPORTORGEX:
306 {
307 DWORD x = mr->dParm[0], y = mr->dParm[1];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000308 SetViewportOrgEx(hdc, x, y, NULL);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000309 break;
310 }
311 case EMR_SETVIEWPORTEXTEX:
312 {
313 DWORD x = mr->dParm[0], y = mr->dParm[1];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000314 SetViewportExtEx(hdc, x, y, NULL);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000315 break;
316 }
Alexandre Julliard54c27111998-03-29 19:44:57 +0000317 case EMR_CREATEPEN:
318 {
319 DWORD obj = mr->dParm[0];
320 (handletable->objectHandle)[obj] =
Alexandre Julliarda3960291999-02-26 11:11:13 +0000321 CreatePenIndirect((LOGPEN *) &(mr->dParm[1]));
Alexandre Julliard54c27111998-03-29 19:44:57 +0000322 break;
323 }
324 case EMR_EXTCREATEPEN:
325 {
326 DWORD obj = mr->dParm[0];
327 DWORD style = mr->dParm[1], brush = mr->dParm[2];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000328 LOGBRUSH *b = (LOGBRUSH *) &mr->dParm[3];
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000329 FIXME(metafile, "Some ExtCreatePen args not handled\n");
Alexandre Julliard54c27111998-03-29 19:44:57 +0000330 (handletable->objectHandle)[obj] =
Alexandre Julliarda3960291999-02-26 11:11:13 +0000331 ExtCreatePen(style, brush, b, 0, NULL);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000332 break;
333 }
334 case EMR_CREATEBRUSHINDIRECT:
335 {
336 DWORD obj = mr->dParm[0];
337 (handletable->objectHandle)[obj] =
Alexandre Julliarda3960291999-02-26 11:11:13 +0000338 CreateBrushIndirect((LOGBRUSH *) &(mr->dParm[1]));
Alexandre Julliard54c27111998-03-29 19:44:57 +0000339 break;
340 }
341 case EMR_EXTCREATEFONTINDIRECTW:
342 {
343 DWORD obj = mr->dParm[0];
344 (handletable->objectHandle)[obj] =
Alexandre Julliarda3960291999-02-26 11:11:13 +0000345 CreateFontIndirectW((LOGFONTW *) &(mr->dParm[1]));
Alexandre Julliard54c27111998-03-29 19:44:57 +0000346 break;
347 }
Alexandre Julliard54c27111998-03-29 19:44:57 +0000348 case EMR_MOVETOEX:
349 {
350 DWORD x = mr->dParm[0], y = mr->dParm[1];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000351 MoveToEx(hdc, x, y, NULL);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000352 break;
353 }
354 case EMR_LINETO:
355 {
356 DWORD x = mr->dParm[0], y = mr->dParm[1];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000357 LineTo(hdc, x, y);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000358 break;
359 }
360 case EMR_RECTANGLE:
361 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000362 INT left = mr->dParm[0], top = mr->dParm[1], right = mr->dParm[2],
Alexandre Julliard54c27111998-03-29 19:44:57 +0000363 bottom = mr->dParm[3];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000364 Rectangle(hdc, left, top, right, bottom);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000365 break;
366 }
367 case EMR_ELLIPSE:
368 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000369 INT left = mr->dParm[0], top = mr->dParm[1], right = mr->dParm[2],
Alexandre Julliard54c27111998-03-29 19:44:57 +0000370 bottom = mr->dParm[3];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000371 Ellipse(hdc, left, top, right, bottom);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000372 break;
373 }
Alexandre Julliard54c27111998-03-29 19:44:57 +0000374 case EMR_POLYGON16:
375 {
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000376 /* 0-3 : a bounding rectangle? */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000377 INT count = mr->dParm[4];
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000378 FIXME(metafile, "Some Polygon16 args not handled\n");
Alexandre Julliard54c27111998-03-29 19:44:57 +0000379 Polygon16(hdc, (POINT16 *)&mr->dParm[5], count);
380 break;
381 }
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000382 case EMR_POLYLINE16:
383 {
384 /* 0-3 : a bounding rectangle? */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000385 INT count = mr->dParm[4];
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000386 FIXME(metafile, "Some Polyline16 args not handled\n");
387 Polyline16(hdc, (POINT16 *)&mr->dParm[5], count);
388 break;
389 }
390
Alexandre Julliard54c27111998-03-29 19:44:57 +0000391#if 0
392 case EMR_POLYPOLYGON16:
393 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000394 INT polygons = mr->dParm[z];
Alexandre Julliard54c27111998-03-29 19:44:57 +0000395 LPPOINT16 pts = (LPPOINT16) &mr->dParm[x];
396 LPINT16 counts = (LPINT16) &mr->dParm[y];
397 PolyPolygon16(hdc, pts, counts, polygons);
398 break;
399 }
400#endif
Jason McMullane113b091999-02-09 14:08:57 +0000401 case EMR_STRETCHDIBITS:
402 {
403 LONG xDest = mr->dParm[4];
404 LONG yDest = mr->dParm[5];
405 LONG xSrc = mr->dParm[6];
406 LONG ySrc = mr->dParm[7];
407 LONG cxSrc = mr->dParm[8];
408 LONG cySrc = mr->dParm[9];
409 DWORD offBmiSrc = mr->dParm[10];
410 DWORD offBitsSrc = mr->dParm[12];
411 DWORD iUsageSrc = mr->dParm[14];
412 DWORD dwRop = mr->dParm[15];
413 LONG cxDest = mr->dParm[16];
414 LONG cyDest = mr->dParm[17];
415
Alexandre Julliarda3960291999-02-26 11:11:13 +0000416 StretchDIBits(hdc,xDest,yDest,cxDest,cyDest,
Jason McMullane113b091999-02-09 14:08:57 +0000417 xSrc,ySrc,cxSrc,cySrc,
418 ((char *)mr)+offBitsSrc,
419 (const BITMAPINFO *)(((char *)mr)+offBmiSrc),
420 iUsageSrc,dwRop);
421 break;
422 }
Alexandre Julliard54c27111998-03-29 19:44:57 +0000423 case EMR_EXTTEXTOUTW:
424 {
425 /* 0-3: ??? */
426 DWORD flags = mr->dParm[4];
427 /* 5, 6: ??? */
428 DWORD x = mr->dParm[7], y = mr->dParm[8];
429 DWORD count = mr->dParm[9];
430 /* 10-16: ??? */
431 LPWSTR str = (LPWSTR)& mr->dParm[17];
432 /* trailing info: dx array? */
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000433 FIXME(metafile, "Many ExtTextOut args not handled\n");
Alexandre Julliarda3960291999-02-26 11:11:13 +0000434 ExtTextOutW(hdc, x, y, flags, /* lpRect */ NULL,
Alexandre Julliard54c27111998-03-29 19:44:57 +0000435 str, count, /* lpDx */ NULL);
436 break;
437 }
438
439 default:
440 FIXME(metafile, "type %d is unimplemented\n", type);
441 /* SetLastError(E_NOTIMPL); */
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000442 break;
443 }
Alexandre Julliard54c27111998-03-29 19:44:57 +0000444 return TRUE;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000445}
446
447
448/*****************************************************************************
449 *
450 * EnumEnhMetaFile32 (GDI32.79)
451 *
452 * Walk an enhanced metafile, calling a user-specified function _EnhMetaFunc_
453 * for each
454 * record. Returns when either every record has been used or
455 * when _EnhMetaFunc_ returns FALSE.
456 *
457 *
458 * RETURNS
459 * TRUE if every record is used, FALSE if any invocation of _EnhMetaFunc_
460 * returns FALSE.
461 *
462 * BUGS
Alexandre Julliard54c27111998-03-29 19:44:57 +0000463 * Ignores rect.
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000464 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000465BOOL WINAPI EnumEnhMetaFile(
466 HDC hdc, /* device context to pass to _EnhMetaFunc_ */
467 HENHMETAFILE hmf, /* EMF to walk */
468 ENHMFENUMPROC callback, /* callback function */
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000469 LPVOID data, /* optional data for callback function */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000470 const RECT *rect /* bounding rectangle for rendered metafile */
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000471 )
472{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000473 BOOL ret = TRUE;
474 LPENHMETARECORD p = GlobalLock(hmf);
475 INT count = ((LPENHMETAHEADER) p)->nHandles;
476 HANDLETABLE *ht = (HANDLETABLE *)GlobalAlloc(GPTR, sizeof(HANDLETABLE)*count);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000477 ht->objectHandle[0] = hmf;
478 while (ret) {
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000479 ret = (*callback)(hdc, ht, p, count, data);
480 if (p->iType == EMR_EOF) break;
481 p = (void *) p + p->nSize;
482 }
Alexandre Julliarda3960291999-02-26 11:11:13 +0000483 GlobalFree((HGLOBAL)ht);
484 GlobalUnlock(hmf);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000485 return ret;
486}
487
488
489/**************************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000490 * PlayEnhMetaFile (GDI32.263)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000491 *
492 * Renders an enhanced metafile into a specified rectangle *lpRect
493 * in device context hdc.
494 *
495 * BUGS
496 * Almost entirely unimplemented
497 *
498 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000499BOOL WINAPI PlayEnhMetaFile(
500 HDC hdc, /* DC to render into */
501 HENHMETAFILE hmf, /* metafile to render */
502 const RECT *lpRect /* rectangle to place metafile inside */
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000503 )
504{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000505 LPENHMETARECORD p = GlobalLock(hmf);
506 INT count = ((LPENHMETAHEADER) p)->nHandles;
507 HANDLETABLE *ht = (HANDLETABLE *)GlobalAlloc(GPTR,
508 sizeof(HANDLETABLE)*count);
509 BOOL ret = FALSE;
510 INT savedMode = 0;
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000511 if (lpRect) {
512 LPENHMETAHEADER h = (LPENHMETAHEADER) p;
513 FLOAT xscale = (h->rclBounds.right-h->rclBounds.left)/(lpRect->right-lpRect->left);
514 FLOAT yscale = (h->rclBounds.bottom-h->rclBounds.top)/(lpRect->bottom-lpRect->top);
515 XFORM xform = {xscale, 0, 0, yscale, 0, 0};
Alexandre Julliardf90efa91998-06-14 15:24:15 +0000516 xform.eDx = lpRect->left;
517 xform.eDy = lpRect->top;
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000518 FIXME(metafile, "play into rect doesn't work\n");
Alexandre Julliardf90efa91998-06-14 15:24:15 +0000519 savedMode = SetGraphicsMode(hdc, GM_ADVANCED);
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000520 if (!SetWorldTransform(hdc, &xform)) {
521 WARN(metafile, "World transform failed!\n");
522 }
523 }
524
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000525 ht->objectHandle[0] = hmf;
526 while (1) {
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000527 PlayEnhMetaFileRecord(hdc, ht, p, count);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000528 if (p->iType == EMR_EOF) break;
529 p = (void *) p + p->nSize; /* casted so that arithmetic is in bytes */
530 }
Alexandre Julliarda3960291999-02-26 11:11:13 +0000531 GlobalUnlock(hmf);
Alexandre Julliardf90efa91998-06-14 15:24:15 +0000532 if (savedMode) SetGraphicsMode(hdc, savedMode);
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000533 ret = TRUE; /* FIXME: calculate a more accurate return value */
534 return ret;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000535}
536
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000537/*****************************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000538 * DeleteEnhMetaFile (GDI32.68)
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000539 *
540 * Deletes an enhanced metafile and frees the associated storage.
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000541 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000542BOOL WINAPI DeleteEnhMetaFile(HENHMETAFILE hmf) {
543 return !GlobalFree(hmf);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000544}
545
546/*****************************************************************************
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000547 * CopyEnhMetaFileA (GDI32.21) Duplicate an enhanced metafile
548 *
549 *
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000550 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000551HENHMETAFILE WINAPI CopyEnhMetaFileA(
552 HENHMETAFILE hmf,
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000553 LPCSTR file)
554{
555 if (!file) {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000556 LPENHMETAHEADER h = GlobalLock(hmf);
557 HENHMETAFILE hmf2 = GlobalAlloc(GPTR, h->nBytes);
558 LPENHMETAHEADER h2 = GlobalLock(hmf2);
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000559 if (!h2) return 0;
560 memmove(h2, h, h->nBytes);
Alexandre Julliarda3960291999-02-26 11:11:13 +0000561 GlobalUnlock(hmf2);
562 GlobalUnlock(hmf);
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000563 return hmf2;
564 } else {
565 FIXME(metafile, "write to file not implemented\n");
566 return 0;
567 }
Alexandre Julliard54c27111998-03-29 19:44:57 +0000568}
569
Charles Suprin41043011998-11-07 12:56:31 +0000570/*****************************************************************************
571 * GetEnhMetaFilePaletteEntries (GDI32.179)
572 *
573 * Copy the palette and report size
574 */
575
Alexandre Julliarda3960291999-02-26 11:11:13 +0000576UINT WINAPI GetEnhMetaFilePaletteEntries(HENHMETAFILE hemf,
577 UINT cEntries,
Charles Suprin41043011998-11-07 12:56:31 +0000578 LPPALETTEENTRY lppe)
579{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000580 LPENHMETAHEADER h = GlobalLock(hemf);
Huw D M Davies7b06d981998-11-14 17:13:51 +0000581
Charles Suprin41043011998-11-07 12:56:31 +0000582 if ( h == NULL ){
Alexandre Julliarda3960291999-02-26 11:11:13 +0000583 GlobalUnlock(hemf);
Charles Suprin41043011998-11-07 12:56:31 +0000584 return(0);
585 } else {
586 if ((lppe)&&(cEntries>0)){
587 FIXME(metafile,"Stub\n");
Alexandre Julliarda3960291999-02-26 11:11:13 +0000588 GlobalUnlock(hemf);
Charles Suprin41043011998-11-07 12:56:31 +0000589 return(GDI_ERROR);
590 } else{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000591 GlobalUnlock(hemf);
Charles Suprin41043011998-11-07 12:56:31 +0000592 return(0);
593 }
594 }
595}
596
597
598
599/******************************************************************
600 * SetWinMetaFileBits (GDI32.343)
601 *
602 * Translate from old style to new style.
603 */
604
Alexandre Julliarda3960291999-02-26 11:11:13 +0000605HENHMETAFILE WINAPI SetWinMetaFileBits(UINT cbBuffer,
Charles Suprin41043011998-11-07 12:56:31 +0000606 CONST BYTE *lpbBuffer,
Alexandre Julliarda3960291999-02-26 11:11:13 +0000607 HDC hdcRef,
608 CONST METAFILEPICT *lpmfp
Charles Suprin41043011998-11-07 12:56:31 +0000609 )
610{
611 FIXME(metafile,"Stub\n");
Huw D M Davies7b06d981998-11-14 17:13:51 +0000612 return 0;
Charles Suprin41043011998-11-07 12:56:31 +0000613
614}
615
616
617
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000618