ReactOS 0.4.16-dev-197-g92996da
metafile.c
Go to the documentation of this file.
1/*
2 * Unit tests for metafile functions
3 *
4 * Copyright (c) 2002 Dmitry Timoshkov
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include <assert.h>
22#include <stdio.h>
23#include <math.h>
24
25#include "wine/test.h"
26#include "winbase.h"
27#include "wingdi.h"
28#include "winuser.h"
29#include "winerror.h"
30
31#ifndef M_PI
32#define M_PI 3.14159265358979323846
33#endif
34
37
38/* Arbitrarily chosen values for the second co-ordinate of a metafile line */
39#define LINE_X 55.0f
40#define LINE_Y 15.0f
41
42static INT (WINAPI * pGetRelAbs)(HDC, DWORD);
43static INT (WINAPI * pSetRelAbs)(HDC, INT);
44static COLORREF (WINAPI *pSetDCBrushColor)(HDC,COLORREF);
45static COLORREF (WINAPI *pSetDCPenColor)(HDC,COLORREF);
46
47#define GDI_GET_PROC(func) \
48 p ## func = (void *)GetProcAddress(hGDI, #func); \
49 if(!p ## func) \
50 trace("GetProcAddress(hGDI, \"%s\") failed\n", #func); \
51
52static void init_function_pointers(void)
53{
54 HMODULE hGDI;
55
56 pGetRelAbs = NULL;
57 pSetRelAbs = NULL;
58
59 hGDI = GetModuleHandleA("gdi32.dll");
60 assert(hGDI);
65}
66
68{
69 DWORD size;
71
72 if (!hrgn) return 0;
73 if (!(size = GetRegionData(hrgn, 0, NULL))) return 0;
74 if (!(data = HeapAlloc(GetProcessHeap(), 0, size))) return 0;
76 size = data->rdh.nCount;
78 return size;
79}
80
82 const ENHMETARECORD *emr, int n_objs, LPARAM param)
83{
84 static int n_record;
85 DWORD i;
86 const INT *dx;
87 INT *orig_dx = (INT *)param;
88 LOGFONTA device_lf;
89 INT ret;
90
91 if(!hdc) return 1;
92
94
95 switch (emr->iType)
96 {
97 case EMR_HEADER:
98 ok(GetTextAlign(hdc) == 0, "text align %08x\n", GetTextAlign(hdc));
99 ok(GetBkColor(hdc) == RGB(0xff, 0xff, 0xff), "bk color %08x\n", GetBkColor(hdc));
100 ok(GetTextColor(hdc) == RGB(0x0, 0x0, 0x0), "text color %08x\n", GetTextColor(hdc));
101 ok(GetROP2(hdc) == R2_COPYPEN, "rop %d\n", GetROP2(hdc));
103 ok(GetPolyFillMode(hdc) == ALTERNATE, "poly fill %d\n", GetPolyFillMode(hdc));
104 ok(GetStretchBltMode(hdc) == BLACKONWHITE, "stretchblt mode %d\n", GetStretchBltMode(hdc));
105
106 /* GetBkMode, GetRelAbs do not get reset to the default value */
107 ok(GetBkMode(hdc) == OPAQUE, "bk mode %d\n", GetBkMode(hdc));
108 if(pSetRelAbs && pGetRelAbs)
109 ok(pGetRelAbs(hdc, 0) == RELATIVE, "relabs %d\n", pGetRelAbs(hdc, 0));
110
111 n_record = 0;
112 break;
113
114 case EMR_EXTTEXTOUTA:
115 {
116 const EMREXTTEXTOUTA *emr_ExtTextOutA = (const EMREXTTEXTOUTA *)emr;
117 dx = (const INT *)((const char *)emr + emr_ExtTextOutA->emrtext.offDx);
118
119 ret = GetObjectA(GetCurrentObject(hdc, OBJ_FONT), sizeof(device_lf), &device_lf);
120 ok( ret == sizeof(device_lf), "GetObjectA error %d\n", GetLastError());
121
122 /* compare up to lfOutPrecision, other values are not interesting,
123 * and in fact sometimes arbitrary adapted by Win9x.
124 */
125 ok(!memcmp(&orig_lf, &device_lf, FIELD_OFFSET(LOGFONTA, lfOutPrecision)), "fonts don't match\n");
126 ok(!lstrcmpA(orig_lf.lfFaceName, device_lf.lfFaceName), "font names don't match\n");
127
128 for(i = 0; i < emr_ExtTextOutA->emrtext.nChars; i++)
129 {
130 ok(orig_dx[i] == dx[i], "pass %d: dx[%d] (%d) didn't match %d\n",
131 n_record, i, dx[i], orig_dx[i]);
132 }
133 n_record++;
135 break;
136 }
137
138 case EMR_EXTTEXTOUTW:
139 {
140 const EMREXTTEXTOUTW *emr_ExtTextOutW = (const EMREXTTEXTOUTW *)emr;
141 dx = (const INT *)((const char *)emr + emr_ExtTextOutW->emrtext.offDx);
142
143 SetLastError(0xdeadbeef);
144 ret = GetObjectA(GetCurrentObject(hdc, OBJ_FONT), sizeof(device_lf), &device_lf);
145 ok( ret == sizeof(device_lf) ||
146 broken(ret == (sizeof(device_lf) - LF_FACESIZE + strlen(device_lf.lfFaceName) + 1)), /* NT4 */
147 "GetObjectA error %d\n", GetLastError());
148
149 /* compare up to lfOutPrecision, other values are not interesting,
150 * and in fact sometimes arbitrary adapted by Win9x.
151 */
152 ok(!memcmp(&orig_lf, &device_lf, FIELD_OFFSET(LOGFONTA, lfOutPrecision)), "fonts don't match\n");
153 ok(!lstrcmpA(orig_lf.lfFaceName, device_lf.lfFaceName), "font names don't match\n");
154
155 ok(!emr_ExtTextOutW->rclBounds.left, "emr_ExtTextOutW->rclBounds.left = %d\n",
156 emr_ExtTextOutW->rclBounds.left);
157 ok(emr_ExtTextOutW->rclBounds.right != -1, "emr_ExtTextOutW->rclBounds.right = %d\n",
158 emr_ExtTextOutW->rclBounds.right);
159 ok(emr_ExtTextOutW->rclBounds.bottom != -1, "emr_ExtTextOutW->rclBounds.bottom = %d\n",
160 emr_ExtTextOutW->rclBounds.bottom);
161
162 for(i = 0; i < emr_ExtTextOutW->emrtext.nChars; i++)
163 {
164 ok(orig_dx[i] == dx[i], "pass %d: dx[%d] (%d) didn't match %d\n",
165 n_record, i, dx[i], orig_dx[i]);
166 }
167 n_record++;
169 break;
170 }
171
172 default:
173 break;
174 }
175
176 return 1;
177}
178
179static void test_ExtTextOut(void)
180{
181 HWND hwnd;
182 HDC hdcDisplay, hdcMetafile;
183 HENHMETAFILE hMetafile;
184 HFONT hFont;
185 static const char text[] = "Simple text to test ExtTextOut on metafiles";
186 INT i, len, dx[256];
187 static const RECT rc = { 0, 0, 100, 100 };
188 BOOL ret;
189
190 assert(sizeof(dx)/sizeof(dx[0]) >= lstrlenA(text));
191
192 /* Win9x doesn't play EMFs on invisible windows */
193 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
194 0, 0, 200, 200, 0, 0, 0, NULL);
195 ok(hwnd != 0, "CreateWindowExA error %d\n", GetLastError());
196
197 hdcDisplay = GetDC(hwnd);
198 ok(hdcDisplay != 0, "GetDC error %d\n", GetLastError());
199
200 trace("hdcDisplay %p\n", hdcDisplay);
201
202 SetMapMode(hdcDisplay, MM_TEXT);
203
204 memset(&orig_lf, 0, sizeof(orig_lf));
205
209 orig_lf.lfHeight = 7;
211 lstrcpyA(orig_lf.lfFaceName, "Arial");
213 ok(hFont != 0, "CreateFontIndirectA error %d\n", GetLastError());
214
215 hFont = SelectObject(hdcDisplay, hFont);
216
217 len = lstrlenA(text);
218 for (i = 0; i < len; i++)
219 {
220 ret = GetCharWidthA(hdcDisplay, text[i], text[i], &dx[i]);
221 ok( ret, "GetCharWidthA error %d\n", GetLastError());
222 }
223 hFont = SelectObject(hdcDisplay, hFont);
224
225 hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
226 ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
227
228 trace("hdcMetafile %p\n", hdcMetafile);
229
230 ok(GetDeviceCaps(hdcMetafile, TECHNOLOGY) == DT_RASDISPLAY,
231 "GetDeviceCaps(TECHNOLOGY) has to return DT_RASDISPLAY for a display based EMF\n");
232
233 hFont = SelectObject(hdcMetafile, hFont);
234
235 /* 1. pass NULL lpDx */
236 ret = ExtTextOutA(hdcMetafile, 0, 0, 0, &rc, text, lstrlenA(text), NULL);
237 ok( ret, "ExtTextOutA error %d\n", GetLastError());
238
239 /* 2. pass custom lpDx */
240 ret = ExtTextOutA(hdcMetafile, 0, 20, 0, &rc, text, lstrlenA(text), dx);
241 ok( ret, "ExtTextOutA error %d\n", GetLastError());
242
243 /* 3. pass NULL lprc */
244 ret = ExtTextOutA(hdcMetafile, 0, 40, 0, NULL, text, lstrlenA(text), NULL);
245 ok( ret, "ExtTextOutA error %d\n", GetLastError());
246
247 /* 4. test with unmatched BeginPath/EndPath calls */
248 ret = BeginPath(hdcMetafile);
249 ok( ret, "BeginPath error %d\n", GetLastError());
250 ret = BeginPath(hdcMetafile);
251 ok( ret, "BeginPath error %d\n", GetLastError());
252 ret = EndPath(hdcMetafile);
253 ok( ret, "BeginPath error %d\n", GetLastError());
254 ret = ExtTextOutA(hdcMetafile, 0, 60, 0, NULL, text, lstrlenA(text), NULL);
255 ok( ret, "ExtTextOutA error %d\n", GetLastError());
256
257 hFont = SelectObject(hdcMetafile, hFont);
259 ok( ret, "DeleteObject error %d\n", GetLastError());
260
261 hMetafile = CloseEnhMetaFile(hdcMetafile);
262 ok(hMetafile != 0, "CloseEnhMetaFile error %d\n", GetLastError());
263
264 ok(!GetObjectType(hdcMetafile), "CloseEnhMetaFile has to destroy metafile hdc\n");
265
266 ret = PlayEnhMetaFile(hdcDisplay, hMetafile, &rc);
267 ok( ret, "PlayEnhMetaFile error %d\n", GetLastError());
268
270 SetBkColor(hdcDisplay, RGB(0xff, 0, 0));
271 SetTextColor(hdcDisplay, RGB(0, 0xff, 0));
272 SetROP2(hdcDisplay, R2_NOT);
273 SetArcDirection(hdcDisplay, AD_CLOCKWISE);
274 SetPolyFillMode(hdcDisplay, WINDING);
275 SetStretchBltMode(hdcDisplay, HALFTONE);
276
277 if(pSetRelAbs) pSetRelAbs(hdcDisplay, RELATIVE);
278 SetBkMode(hdcDisplay, OPAQUE);
279
280 ret = EnumEnhMetaFile(hdcDisplay, hMetafile, eto_emf_enum_proc, dx, &rc);
281 ok( ret, "EnumEnhMetaFile error %d\n", GetLastError());
282
284 "text align %08x\n", GetTextAlign(hdcDisplay));
285 ok( GetBkColor(hdcDisplay) == RGB(0xff, 0, 0), "bk color %08x\n", GetBkColor(hdcDisplay));
286 ok( GetTextColor(hdcDisplay) == RGB(0, 0xff, 0), "text color %08x\n", GetTextColor(hdcDisplay));
287 ok( GetROP2(hdcDisplay) == R2_NOT, "rop2 %d\n", GetROP2(hdcDisplay));
288 ok( GetArcDirection(hdcDisplay) == AD_CLOCKWISE, "arc dir %d\n", GetArcDirection(hdcDisplay));
289 ok( GetPolyFillMode(hdcDisplay) == WINDING, "poly fill %d\n", GetPolyFillMode(hdcDisplay));
290 ok( GetStretchBltMode(hdcDisplay) == HALFTONE, "stretchblt mode %d\n", GetStretchBltMode(hdcDisplay));
291
292 ok(emr_processed, "EnumEnhMetaFile couldn't find EMR_EXTTEXTOUTA or EMR_EXTTEXTOUTW record\n");
293
294 ok(!EnumEnhMetaFile(hdcDisplay, hMetafile, eto_emf_enum_proc, dx, NULL),
295 "A valid hdc has to require a valid rc\n");
296
298 "A null hdc does not require a valid rc\n");
299
300 ret = DeleteEnhMetaFile(hMetafile);
301 ok( ret, "DeleteEnhMetaFile error %d\n", GetLastError());
302 ret = ReleaseDC(hwnd, hdcDisplay);
303 ok( ret, "ReleaseDC error %d\n", GetLastError());
305}
306
308{
311 double ex_scale;
312 double ey_scale;
314};
315
317 const ENHMETARECORD *emr, int n_objs, LPARAM param)
318{
320
321 if (emr->iType == EMR_EXTTEXTOUTW)
322 {
323 const EMREXTTEXTOUTW *pExtTextOutW = (const EMREXTTEXTOUTW *)emr;
324 ok(fabs(test->ex_scale - pExtTextOutW->exScale) < 0.001,
325 "Got exScale %f, expected %f\n", pExtTextOutW->exScale, test->ex_scale);
326 ok(fabs(test->ey_scale - pExtTextOutW->eyScale) < 0.001,
327 "Got eyScale %f, expected %f\n", pExtTextOutW->eyScale, test->ey_scale);
328 test->processed = TRUE;
329 }
330
331 return 1;
332}
333
334static void test_ExtTextOutScale(void)
335{
336 const RECT rc = { 0, 0, 100, 100 };
337 const WCHAR str[] = {'a',0 };
339 HDC hdcDisplay, hdcMetafile;
340 HENHMETAFILE hMetafile;
341 HWND hwnd;
342 SIZE wndext, vportext;
343 int horzSize, vertSize, horzRes, vertRes;
344 int ret;
345 int i;
346
347 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
348 0, 0, 200, 200, 0, 0, 0, NULL);
349 ok(hwnd != 0, "CreateWindowExA failed\n");
350
351 hdcDisplay = GetDC(hwnd);
352 ok(hdcDisplay != 0, "GetDC failed\n");
353
354 horzSize = GetDeviceCaps(hdcDisplay, HORZSIZE);
355 horzRes = GetDeviceCaps(hdcDisplay, HORZRES);
356 vertSize = GetDeviceCaps(hdcDisplay, VERTSIZE);
357 vertRes = GetDeviceCaps(hdcDisplay, VERTRES);
358 ok(horzSize && horzRes && vertSize && vertRes, "GetDeviceCaps failed\n");
359
360 for (i = 0; i < 16; i++)
361 {
362 test.graphics_mode = i / 8 + 1;
363 test.map_mode = i % 8 + 1;
364
365 ret = SetGraphicsMode(hdcDisplay, test.graphics_mode);
366 ok(ret, "SetGraphicsMode failed\n");
367 ret = SetMapMode(hdcDisplay, test.map_mode);
368 ok(ret, "SetMapMode failed\n");
369
370 if ((test.map_mode == MM_ISOTROPIC) || (test.map_mode == MM_ANISOTROPIC))
371 {
372 ret = SetWindowExtEx(hdcDisplay, 1, 1, NULL);
373 ok(ret, "SetWindowExtEx failed\n");
374 ret = SetViewportExtEx(hdcDisplay, -20, -10, NULL);
375 ok(ret, "SetViewportExtEx failed\n");
376 }
377
378 ret = GetViewportExtEx(hdcDisplay, &vportext);
379 ok(ret, "GetViewportExtEx failed\n");
380 ret = GetWindowExtEx(hdcDisplay, &wndext);
381 ok(ret, "GetWindowExtEx failed\n");
382
383 trace("gm %d, mm %d, wnd %d,%d, vp %d,%d horz %d,%d vert %d,%d\n",
384 test.graphics_mode, test.map_mode,
385 wndext.cx, wndext.cy, vportext.cx, vportext.cy,
386 horzSize, horzRes, vertSize, vertRes);
387
388 if (test.graphics_mode == GM_COMPATIBLE)
389 {
390 test.ex_scale = 100.0 * ((FLOAT)horzSize / (FLOAT)horzRes) /
391 ((FLOAT)wndext.cx / (FLOAT)vportext.cx);
392 test.ey_scale = 100.0 * ((FLOAT)vertSize / (FLOAT)vertRes) /
393 ((FLOAT)wndext.cy / (FLOAT)vportext.cy);
394 }
395 else
396 {
397 test.ex_scale = 0.0;
398 test.ey_scale = 0.0;
399 }
400
401 hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
402 ok(hdcMetafile != 0, "CreateEnhMetaFileA failed\n");
403
404 ret = SetGraphicsMode(hdcMetafile, test.graphics_mode);
405 ok(ret, "SetGraphicsMode failed\n");
406 ret = SetMapMode(hdcMetafile, test.map_mode);
407 ok(ret, "SetMapMode failed\n");
408
409 if ((test.map_mode == MM_ISOTROPIC) || (test.map_mode == MM_ANISOTROPIC))
410 {
411 ret = SetWindowExtEx(hdcMetafile, 1, 1, NULL);
412 ok(ret, "SetWindowExtEx failed\n");
413 ret = SetViewportExtEx(hdcMetafile, -20, -10, NULL);
414 ok(ret, "SetViewportExtEx failed\n");
415 }
416
417 ret = ExtTextOutW(hdcMetafile, 0, 0, 0, 0, str, 1, NULL);
418 ok(ret, "ExtTextOutW failed\n");
419
420 hMetafile = CloseEnhMetaFile(hdcMetafile);
421 ok(hMetafile != 0, "CloseEnhMetaFile failed\n");
422
423 test.processed = 0;
424 ret = EnumEnhMetaFile(hdcDisplay, hMetafile, eto_scale_enum_proc, &test, &rc);
425 ok(ret, "EnumEnhMetaFile failed\n");
426 ok(test.processed, "EnumEnhMetaFile couldn't find EMR_EXTTEXTOUTW record\n");
427
428 ret = DeleteEnhMetaFile(hMetafile);
429 ok(ret, "DeleteEnhMetaFile failed\n");
430 }
431
432 ret = ReleaseDC(hwnd, hdcDisplay);
433 ok(ret, "ReleaseDC failed\n");
435}
436
437
438static void check_dc_state(HDC hdc, int restore_no,
439 int wnd_org_x, int wnd_org_y, int wnd_ext_x, int wnd_ext_y,
440 int vp_org_x, int vp_org_y, int vp_ext_x, int vp_ext_y)
441{
442 BOOL ret;
443 XFORM xform;
444 POINT vp_org, win_org;
445 SIZE vp_size, win_size;
446 FLOAT xscale, yscale, edx, edy;
447
448 SetLastError(0xdeadbeef);
449 ret = GetWorldTransform(hdc, &xform);
450 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) goto win9x_here;
451 ok(ret, "GetWorldTransform error %u\n", GetLastError());
452
453 trace("%d: eM11 %f, eM22 %f, eDx %f, eDy %f\n", restore_no, xform.eM11, xform.eM22, xform.eDx, xform.eDy);
454
455 ok(xform.eM12 == 0.0, "%d: expected eM12 0.0, got %f\n", restore_no, xform.eM12);
456 ok(xform.eM21 == 0.0, "%d: expected eM21 0.0, got %f\n", restore_no, xform.eM21);
457
458 xscale = (FLOAT)vp_ext_x / (FLOAT)wnd_ext_x;
459 trace("x scale %f\n", xscale);
460 ok(fabs(xscale - xform.eM11) < 0.01, "%d: vp_ext_x %d, wnd_ext_cx %d, eM11 %f\n",
461 restore_no, vp_ext_x, wnd_ext_x, xform.eM11);
462
463 yscale = (FLOAT)vp_ext_y / (FLOAT)wnd_ext_y;
464 trace("y scale %f\n", yscale);
465 ok(fabs(yscale - xform.eM22) < 0.01, "%d: vp_ext_y %d, wnd_ext_y %d, eM22 %f\n",
466 restore_no, vp_ext_y, wnd_ext_y, xform.eM22);
467
468 edx = (FLOAT)vp_org_x - xform.eM11 * (FLOAT)wnd_org_x;
469 ok(fabs(edx - xform.eDx) < 0.01, "%d: edx %f != eDx %f\n", restore_no, edx, xform.eDx);
470 edy = (FLOAT)vp_org_y - xform.eM22 * (FLOAT)wnd_org_y;
471 ok(fabs(edy - xform.eDy) < 0.01, "%d: edy %f != eDy %f\n", restore_no, edy, xform.eDy);
472
473 return;
474
475win9x_here:
476
477 GetWindowOrgEx(hdc, &win_org);
478 GetViewportOrgEx(hdc, &vp_org);
479 GetWindowExtEx(hdc, &win_size);
480 GetViewportExtEx(hdc, &vp_size);
481
482 ok(wnd_org_x == win_org.x, "%d: wnd_org_x: %d != %d\n", restore_no, wnd_org_x, win_org.x);
483 ok(wnd_org_y == win_org.y, "%d: wnd_org_y: %d != %d\n", restore_no, wnd_org_y, win_org.y);
484
485 ok(vp_org_x == vp_org.x, "%d: vport_org_x: %d != %d\n", restore_no, vp_org_x, vp_org.x);
486 ok(vp_org_y == vp_org.y, "%d: vport_org_y: %d != %d\n", restore_no, vp_org_y, vp_org.y);
487
488 ok(wnd_ext_x == win_size.cx, "%d: wnd_ext_x: %d != %d\n", restore_no, wnd_ext_x, win_size.cx);
489 ok(wnd_ext_y == win_size.cy, "%d: wnd_ext_y: %d != %d\n", restore_no, wnd_ext_y, win_size.cy);
490
491 ok(vp_ext_x == vp_size.cx, "%d: vport_ext_x: %d != %d\n", restore_no, vp_ext_x, vp_size.cx);
492 ok(vp_ext_y == vp_size.cy, "%d: vport_ext_y: %d != %d\n", restore_no, vp_ext_y, vp_size.cy);
493}
494
496 const ENHMETARECORD *emr, int n_objs, LPARAM param)
497{
498 BOOL ret;
499 XFORM xform;
500 POINT pt;
501 SIZE size;
502 static int save_state;
503 static int restore_no;
504 static int select_no;
505
506 trace("hdc %p, emr->iType %d, emr->nSize %d, param %p\n",
507 hdc, emr->iType, emr->nSize, (void *)param);
508
509 SetLastError(0xdeadbeef);
510 ret = GetWorldTransform(hdc, &xform);
512 {
514 ok(ret, "GetWindowOrgEx error %u\n", GetLastError());
515 trace("window org (%d,%d)\n", pt.x, pt.y);
517 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
518 trace("vport org (%d,%d)\n", pt.x, pt.y);
520 ok(ret, "GetWindowExtEx error %u\n", GetLastError());
521 trace("window ext (%d,%d)\n", size.cx, size.cy);
523 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
524 trace("vport ext (%d,%d)\n", size.cx, size.cy);
525 }
526 else
527 {
528 ok(ret, "GetWorldTransform error %u\n", GetLastError());
529 trace("eM11 %f, eM22 %f, eDx %f, eDy %f\n", xform.eM11, xform.eM22, xform.eDx, xform.eDy);
530 }
531
533
534 switch (emr->iType)
535 {
536 case EMR_HEADER:
537 {
538 static RECT exp_bounds = { 0, 0, 150, 150 };
539 RECT bounds;
540 const ENHMETAHEADER *emf = (const ENHMETAHEADER *)emr;
541
542 trace("bounds %d,%d-%d,%d, frame %d,%d-%d,%d\n",
543 emf->rclBounds.left, emf->rclBounds.top, emf->rclBounds.right, emf->rclBounds.bottom,
544 emf->rclFrame.left, emf->rclFrame.top, emf->rclFrame.right, emf->rclFrame.bottom);
545 trace("mm %d x %d, device %d x %d\n", emf->szlMillimeters.cx, emf->szlMillimeters.cy,
546 emf->szlDevice.cx, emf->szlDevice.cy);
547
548 SetRect(&bounds, emf->rclBounds.left, emf->rclBounds.top, emf->rclBounds.right, emf->rclBounds.bottom);
549 ok(EqualRect(&bounds, &exp_bounds), "wrong bounds\n");
550
551 save_state = 0;
552 restore_no = 0;
553 select_no = 0;
554 check_dc_state(hdc, restore_no, 0, 0, 1, 1, 0, 0, 1, 1);
555 break;
556 }
557
558 case EMR_LINETO:
559 {
560 const EMRLINETO *line = (const EMRLINETO *)emr;
561 trace("EMR_LINETO %d,%d\n", line->ptl.x, line->ptl.x);
562 break;
563 }
565 {
566 const EMRSETWINDOWORGEX *org = (const EMRSETWINDOWORGEX *)emr;
567 trace("EMR_SETWINDOWORGEX: %d,%d\n", org->ptlOrigin.x, org->ptlOrigin.y);
568 break;
569 }
571 {
572 const EMRSETWINDOWEXTEX *ext = (const EMRSETWINDOWEXTEX *)emr;
573 trace("EMR_SETWINDOWEXTEX: %d,%d\n", ext->szlExtent.cx, ext->szlExtent.cy);
574 break;
575 }
577 {
578 const EMRSETVIEWPORTORGEX *org = (const EMRSETVIEWPORTORGEX *)emr;
579 trace("EMR_SETVIEWPORTORGEX: %d,%d\n", org->ptlOrigin.x, org->ptlOrigin.y);
580 break;
581 }
583 {
584 const EMRSETVIEWPORTEXTEX *ext = (const EMRSETVIEWPORTEXTEX *)emr;
585 trace("EMR_SETVIEWPORTEXTEX: %d,%d\n", ext->szlExtent.cx, ext->szlExtent.cy);
586 break;
587 }
588 case EMR_SAVEDC:
589 save_state++;
590 trace("EMR_SAVEDC\n");
591 break;
592
593 case EMR_RESTOREDC:
594 {
595 const EMRRESTOREDC *restoredc = (const EMRRESTOREDC *)emr;
596 trace("EMR_RESTOREDC: %d\n", restoredc->iRelative);
597
598 switch(++restore_no)
599 {
600 case 1:
601 ok(restoredc->iRelative == -1, "first restore %d\n", restoredc->iRelative);
602 check_dc_state(hdc, restore_no, -2, -2, 8192, 8192, 20, 20, 20479, 20478);
603 break;
604 case 2:
605 ok(restoredc->iRelative == -3, "second restore %d\n", restoredc->iRelative);
606 check_dc_state(hdc, restore_no, 0, 0, 16384, 16384, 0, 0, 17873, 17872);
607 break;
608 case 3:
609 ok(restoredc->iRelative == -2, "third restore %d\n", restoredc->iRelative);
610 check_dc_state(hdc, restore_no, -4, -4, 32767, 32767, 40, 40, 3276, 3276);
611 break;
612 }
613 ok(restore_no <= 3, "restore_no %d\n", restore_no);
614 save_state += restoredc->iRelative;
615 break;
616 }
617 case EMR_SELECTOBJECT:
618 {
619 const EMRSELECTOBJECT *selectobj = (const EMRSELECTOBJECT*)emr;
620 trace("EMR_SELECTOBJECT: %x\n",selectobj->ihObject);
621 select_no ++;
622 break;
623 }
624 case EMR_EOF:
625 ok(save_state == 0, "EOF save_state %d\n", save_state);
626 ok(select_no == 3, "Too many/few selects %i\n",select_no);
627 break;
628 }
629
630 SetLastError(0xdeadbeef);
631 ret = GetWorldTransform(hdc, &xform);
633 {
635 ok(ret, "GetWindowOrgEx error %u\n", GetLastError());
636 trace("window org (%d,%d)\n", pt.x, pt.y);
638 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
639 trace("vport org (%d,%d)\n", pt.x, pt.y);
641 ok(ret, "GetWindowExtEx error %u\n", GetLastError());
642 trace("window ext (%d,%d)\n", size.cx, size.cy);
644 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
645 trace("vport ext (%d,%d)\n", size.cx, size.cy);
646 }
647 else
648 {
649 ok(ret, "GetWorldTransform error %u\n", GetLastError());
650 trace("eM11 %f, eM22 %f, eDx %f, eDy %f\n", xform.eM11, xform.eM22, xform.eDx, xform.eDy);
651 }
652
653 return 1;
654}
655
656static void test_SaveDC(void)
657{
658 HDC hdcMetafile, hdcDisplay;
659 HENHMETAFILE hMetafile;
660 HWND hwnd;
661 int ret;
662 POINT pt;
663 SIZE size;
664 HFONT hFont,hFont2,hFontOld,hFontCheck;
665 static const RECT rc = { 0, 0, 150, 150 };
666
667 /* Win9x doesn't play EMFs on invisible windows */
668 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
669 0, 0, 200, 200, 0, 0, 0, NULL);
670 ok(hwnd != 0, "CreateWindowExA error %d\n", GetLastError());
671
672 hdcDisplay = GetDC(hwnd);
673 ok(hdcDisplay != 0, "GetDC error %d\n", GetLastError());
674
675 hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
676 ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
677
678 SetMapMode(hdcMetafile, MM_ANISOTROPIC);
679
680 /* Need to write something to the emf, otherwise Windows won't play it back */
681 LineTo(hdcMetafile, 150, 150);
682
683 SetWindowOrgEx(hdcMetafile, 0, 0, NULL);
684 SetViewportOrgEx(hdcMetafile, 0, 0, NULL);
685 SetWindowExtEx(hdcMetafile, 110, 110, NULL );
686 SetViewportExtEx(hdcMetafile, 120, 120, NULL );
687
688 /* Force Win9x to update DC state */
689 SetPixelV(hdcMetafile, 50, 50, 0);
690
691 ret = GetViewportOrgEx(hdcMetafile, &pt);
692 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
693 ok(pt.x == 0,"Expecting ViewportOrg x of 0, got %i\n",pt.x);
694 ret = GetViewportExtEx(hdcMetafile, &size);
695 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
696 ok(size.cx == 120,"Expecting ViewportExt cx of 120, got %i\n",size.cx);
697 ret = SaveDC(hdcMetafile);
698 ok(ret == 1, "ret = %d\n", ret);
699
700 SetWindowOrgEx(hdcMetafile, -1, -1, NULL);
701 SetViewportOrgEx(hdcMetafile, 10, 10, NULL);
702 SetWindowExtEx(hdcMetafile, 150, 150, NULL );
703 SetViewportExtEx(hdcMetafile, 200, 200, NULL );
704
705 /* Force Win9x to update DC state */
706 SetPixelV(hdcMetafile, 50, 50, 0);
707
708 ret = GetViewportOrgEx(hdcMetafile, &pt);
709 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
710 ok(pt.x == 10,"Expecting ViewportOrg x of 10, got %i\n",pt.x);
711 ret = GetViewportExtEx(hdcMetafile, &size);
712 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
713 ok(size.cx == 200,"Expecting ViewportExt cx of 200, got %i\n",size.cx);
714 ret = SaveDC(hdcMetafile);
715 ok(ret == 2, "ret = %d\n", ret);
716
717 SetWindowOrgEx(hdcMetafile, -2, -2, NULL);
718 SetViewportOrgEx(hdcMetafile, 20, 20, NULL);
719 SetWindowExtEx(hdcMetafile, 120, 120, NULL );
720 SetViewportExtEx(hdcMetafile, 300, 300, NULL );
721 SetPolyFillMode( hdcMetafile, ALTERNATE );
722 SetBkColor( hdcMetafile, 0 );
723
724 /* Force Win9x to update DC state */
725 SetPixelV(hdcMetafile, 50, 50, 0);
726
727 ret = GetViewportOrgEx(hdcMetafile, &pt);
728 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
729 ok(pt.x == 20,"Expecting ViewportOrg x of 20, got %i\n",pt.x);
730 ret = GetViewportExtEx(hdcMetafile, &size);
731 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
732 ok(size.cx == 300,"Expecting ViewportExt cx of 300, got %i\n",size.cx);
733 ret = SaveDC(hdcMetafile);
734 ok(ret == 3, "ret = %d\n", ret);
735
736 SetWindowOrgEx(hdcMetafile, -3, -3, NULL);
737 SetViewportOrgEx(hdcMetafile, 30, 30, NULL);
738 SetWindowExtEx(hdcMetafile, 200, 200, NULL );
739 SetViewportExtEx(hdcMetafile, 400, 400, NULL );
740
741 SetPolyFillMode( hdcMetafile, WINDING );
742 SetBkColor( hdcMetafile, 0x123456 );
743 ok( GetPolyFillMode( hdcMetafile ) == WINDING, "PolyFillMode not restored\n" );
744 ok( GetBkColor( hdcMetafile ) == 0x123456, "Background color not restored\n" );
745
746 /* Force Win9x to update DC state */
747 SetPixelV(hdcMetafile, 50, 50, 0);
748
749 ret = GetViewportOrgEx(hdcMetafile, &pt);
750 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
751 ok(pt.x == 30,"Expecting ViewportOrg x of 30, got %i\n",pt.x);
752 ret = GetViewportExtEx(hdcMetafile, &size);
753 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
754 ok(size.cx == 400,"Expecting ViewportExt cx of 400, got %i\n",size.cx);
755 ret = RestoreDC(hdcMetafile, -1);
756 ok(ret, "ret = %d\n", ret);
757
758 ret = GetViewportOrgEx(hdcMetafile, &pt);
759 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
760 ok(pt.x == 20,"Expecting ViewportOrg x of 20, got %i\n",pt.x);
761 ret = GetViewportExtEx(hdcMetafile, &size);
762 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
763 ok(size.cx == 300,"Expecting ViewportExt cx of 300, got %i\n",size.cx);
764 ok( GetPolyFillMode( hdcMetafile ) == ALTERNATE, "PolyFillMode not restored\n" );
765 ok( GetBkColor( hdcMetafile ) == 0, "Background color not restored\n" );
766 ret = SaveDC(hdcMetafile);
767 ok(ret == 3, "ret = %d\n", ret);
768
769 ret = GetViewportOrgEx(hdcMetafile, &pt);
770 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
771 ok(pt.x == 20,"Expecting ViewportOrg x of 20, got %i\n",pt.x);
772 ret = GetViewportExtEx(hdcMetafile, &size);
773 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
774 ok(size.cx == 300,"Expecting ViewportExt cx of 300, got %i\n",size.cx);
775 ret = RestoreDC(hdcMetafile, 1);
776 ok(ret, "ret = %d\n", ret);
777 ret = GetViewportOrgEx(hdcMetafile, &pt);
778 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
779 ok(pt.x == 0,"Expecting ViewportOrg x of 0, got %i\n",pt.x);
780 ret = GetViewportExtEx(hdcMetafile, &size);
781 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
782 ok(size.cx == 120,"Expecting ViewportExt cx of 120, got %i\n",size.cx);
783
784 SetWindowOrgEx(hdcMetafile, -4, -4, NULL);
785 SetViewportOrgEx(hdcMetafile, 40, 40, NULL);
786 SetWindowExtEx(hdcMetafile, 500, 500, NULL );
787 SetViewportExtEx(hdcMetafile, 50, 50, NULL );
788
789 /* Force Win9x to update DC state */
790 SetPixelV(hdcMetafile, 50, 50, 0);
791
792 ret = GetViewportOrgEx(hdcMetafile, &pt);
793 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
794 ok(pt.x == 40,"Expecting ViewportOrg x of 40, got %i\n",pt.x);
795 ret = GetViewportExtEx(hdcMetafile, &size);
796 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
797 ok(size.cx == 50,"Expecting ViewportExt cx of 50, got %i\n",size.cx);
798 ret = SaveDC(hdcMetafile);
799 ok(ret == 1, "ret = %d\n", ret);
800
801 ret = GetViewportOrgEx(hdcMetafile, &pt);
802 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
803 ok(pt.x == 40,"Expecting ViewportOrg x of 40, got %i\n",pt.x);
804 ret = GetViewportExtEx(hdcMetafile, &size);
805 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
806 ok(size.cx == 50,"Expecting ViewportExt cx of 50, got %i\n",size.cx);
807 ret = SaveDC(hdcMetafile);
808 ok(ret == 2, "ret = %d\n", ret);
809
810 memset(&orig_lf, 0, sizeof(orig_lf));
814 orig_lf.lfHeight = 7;
816 lstrcpyA(orig_lf.lfFaceName, "Arial");
818 ok(hFont != 0, "CreateFontIndirectA error %d\n", GetLastError());
819
820 hFontOld = SelectObject(hdcMetafile, hFont);
821
822 hFont2 = CreateFontIndirectA(&orig_lf);
823 ok(hFont2 != 0, "CreateFontIndirectA error %d\n", GetLastError());
824 hFontCheck = SelectObject(hdcMetafile, hFont2);
825 ok(hFontCheck == hFont, "Font not selected\n");
826
827 /* Force Win9x to update DC state */
828 SetPixelV(hdcMetafile, 50, 50, 0);
829
830 ret = RestoreDC(hdcMetafile, 1);
831 ok(ret, "ret = %d\n", ret);
832 ret = GetViewportOrgEx(hdcMetafile, &pt);
833 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
834 ok(pt.x == 40,"Expecting ViewportOrg x of 40, got %i\n",pt.x);
835 ret = GetViewportExtEx(hdcMetafile, &size);
836 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
837 ok(size.cx == 50,"Expecting ViewportExt cx of 50, got %i\n",size.cx);
838
839 hFontCheck = SelectObject(hdcMetafile, hFontOld);
840 ok(hFontOld == hFontCheck && hFontCheck != hFont && hFontCheck != hFont2,
841 "Font not reverted with DC Restore\n");
842
843 ret = RestoreDC(hdcMetafile, -20);
844 ok(!ret, "ret = %d\n", ret);
845 ret = RestoreDC(hdcMetafile, 20);
846 ok(!ret, "ret = %d\n", ret);
847
848 hMetafile = CloseEnhMetaFile(hdcMetafile);
849 ok(hMetafile != 0, "CloseEnhMetaFile error %d\n", GetLastError());
850
851 ret = EnumEnhMetaFile(hdcDisplay, hMetafile, savedc_emf_enum_proc, 0, &rc);
852 ok( ret == 1, "EnumEnhMetaFile rets %d\n", ret);
853
855 ok( ret, "DeleteObject error %d\n", GetLastError());
856 ret = DeleteObject(hFont2);
857 ok( ret, "DeleteObject error %d\n", GetLastError());
858 ret = DeleteEnhMetaFile(hMetafile);
859 ok( ret, "DeleteEnhMetaFile error %d\n", GetLastError());
860 ret = ReleaseDC(hwnd, hdcDisplay);
861 ok( ret, "ReleaseDC error %d\n", GetLastError());
863}
864
865static void test_mf_SaveDC(void)
866{
867 HDC hdcMetafile;
868 HMETAFILE hMetafile;
869 int ret;
870 POINT pt;
871 SIZE size;
872 HFONT hFont,hFont2,hFontOld,hFontCheck;
873
874 hdcMetafile = CreateMetaFileA(NULL);
875 ok(hdcMetafile != 0, "CreateMetaFileA error %d\n", GetLastError());
876
877 ret = SetMapMode(hdcMetafile, MM_ANISOTROPIC);
878 ok (ret, "SetMapMode should not fail\n");
879
880 /* Need to write something to the emf, otherwise Windows won't play it back */
881 LineTo(hdcMetafile, 150, 150);
882
883 pt.x = pt.y = 5555;
884 SetWindowOrgEx(hdcMetafile, 0, 0, &pt);
885 ok( pt.x == 5555 && pt.y == 5555, "wrong origin %d,%d\n", pt.x, pt.y);
886 pt.x = pt.y = 5555;
887 SetViewportOrgEx(hdcMetafile, 0, 0, &pt);
888 ok( pt.x == 5555 && pt.y == 5555, "wrong origin %d,%d\n", pt.x, pt.y);
889 size.cx = size.cy = 5555;
890 SetWindowExtEx(hdcMetafile, 110, 110, &size );
891 ok( size.cx == 5555 && size.cy == 5555, "wrong size %d,%d\n", size.cx, size.cy );
892 size.cx = size.cy = 5555;
893 SetViewportExtEx(hdcMetafile, 120, 120, &size );
894 ok( size.cx == 5555 && size.cy == 5555, "wrong size %d,%d\n", size.cx, size.cy );
895
896 /* Force Win9x to update DC state */
897 SetPixelV(hdcMetafile, 50, 50, 0);
898
899 ret = GetViewportOrgEx(hdcMetafile, &pt);
900 todo_wine ok (!ret, "GetViewportOrgEx should fail\n");
901 ret = GetViewportExtEx(hdcMetafile, &size);
902 todo_wine ok (!ret, "GetViewportExtEx should fail\n");
903 ret = SaveDC(hdcMetafile);
904 ok(ret == 1, "ret = %d\n", ret);
905
906 SetWindowOrgEx(hdcMetafile, -1, -1, NULL);
907 SetViewportOrgEx(hdcMetafile, 10, 10, NULL);
908 SetWindowExtEx(hdcMetafile, 150, 150, NULL );
909 SetViewportExtEx(hdcMetafile, 200, 200, NULL );
910
911 /* Force Win9x to update DC state */
912 SetPixelV(hdcMetafile, 50, 50, 0);
913
914 ret = SaveDC(hdcMetafile);
915 ok(ret == 1, "ret = %d\n", ret);
916
917 SetWindowOrgEx(hdcMetafile, -2, -2, NULL);
918 SetViewportOrgEx(hdcMetafile, 20, 20, NULL);
919 SetWindowExtEx(hdcMetafile, 120, 120, NULL );
920 SetViewportExtEx(hdcMetafile, 300, 300, NULL );
921
922 /* Force Win9x to update DC state */
923 SetPixelV(hdcMetafile, 50, 50, 0);
924 SetPolyFillMode( hdcMetafile, ALTERNATE );
925 SetBkColor( hdcMetafile, 0 );
926
927 ret = SaveDC(hdcMetafile);
928 ok(ret == 1, "ret = %d\n", ret);
929
930 SetWindowOrgEx(hdcMetafile, -3, -3, NULL);
931 SetViewportOrgEx(hdcMetafile, 30, 30, NULL);
932 SetWindowExtEx(hdcMetafile, 200, 200, NULL );
933 SetViewportExtEx(hdcMetafile, 400, 400, NULL );
934
935 SetPolyFillMode( hdcMetafile, WINDING );
936 SetBkColor( hdcMetafile, 0x123456 );
937 todo_wine ok( !GetPolyFillMode( hdcMetafile ), "GetPolyFillMode succeeded\n" );
938 todo_wine ok( GetBkColor( hdcMetafile ) == CLR_INVALID, "GetBkColor succeeded\n" );
939
940 /* Force Win9x to update DC state */
941 SetPixelV(hdcMetafile, 50, 50, 0);
942
943 ret = RestoreDC(hdcMetafile, -1);
944 ok(ret, "ret = %d\n", ret);
945
946 ret = SaveDC(hdcMetafile);
947 ok(ret == 1, "ret = %d\n", ret);
948
949 ret = RestoreDC(hdcMetafile, 1);
950 ok(ret, "ret = %d\n", ret);
951
952 SetWindowOrgEx(hdcMetafile, -4, -4, NULL);
953 SetViewportOrgEx(hdcMetafile, 40, 40, NULL);
954 SetWindowExtEx(hdcMetafile, 500, 500, NULL );
955 SetViewportExtEx(hdcMetafile, 50, 50, NULL );
956
957 /* Force Win9x to update DC state */
958 SetPixelV(hdcMetafile, 50, 50, 0);
959
960 ret = SaveDC(hdcMetafile);
961 ok(ret == 1, "ret = %d\n", ret);
962
963 ret = SaveDC(hdcMetafile);
964 ok(ret == 1, "ret = %d\n", ret);
965
966 memset(&orig_lf, 0, sizeof(orig_lf));
970 orig_lf.lfHeight = 7;
972 lstrcpyA(orig_lf.lfFaceName, "Arial");
974 ok(hFont != 0, "CreateFontIndirectA error %d\n", GetLastError());
975
976 hFontOld = SelectObject(hdcMetafile, hFont);
977
978 hFont2 = CreateFontIndirectA(&orig_lf);
979 ok(hFont2 != 0, "CreateFontIndirectA error %d\n", GetLastError());
980 hFontCheck = SelectObject(hdcMetafile, hFont2);
981 ok(hFontCheck == hFont, "Font not selected\n");
982
983 /* Force Win9x to update DC state */
984 SetPixelV(hdcMetafile, 50, 50, 0);
985
986 ret = RestoreDC(hdcMetafile, 1);
987 ok(ret, "ret = %d\n", ret);
988
989 hFontCheck = SelectObject(hdcMetafile, hFontOld);
990 ok(hFontOld != hFontCheck && hFontCheck == hFont2, "Font incorrectly reverted with DC Restore\n");
991
992 /* restore level is ignored */
993 ret = RestoreDC(hdcMetafile, -20);
994 ok(ret, "ret = %d\n", ret);
995 ret = RestoreDC(hdcMetafile, 20);
996 ok(ret, "ret = %d\n", ret);
997 ret = RestoreDC(hdcMetafile, 0);
998 ok(ret, "ret = %d\n", ret);
999
1000 hMetafile = CloseMetaFile(hdcMetafile);
1001 ok(hMetafile != 0, "CloseEnhMetaFile error %d\n", GetLastError());
1002
1003 ret = DeleteMetaFile(hMetafile);
1004 ok( ret, "DeleteMetaFile error %d\n", GetLastError());
1006 ok( ret, "DeleteObject error %d\n", GetLastError());
1007 ret = DeleteObject(hFont2);
1008 ok( ret, "DeleteObject error %d\n", GetLastError());
1009}
1010
1011
1012/* Win-format metafile (mfdrv) tests */
1013/* These tests compare the generated metafiles byte-by-byte */
1014/* with the nominal results. */
1015
1016/* Maximum size of sample metafiles in bytes. */
1017#define MF_BUFSIZE 1024
1018
1019/* 8x8 bitmap data for a pattern brush */
1020static const unsigned char SAMPLE_PATTERN_BRUSH[] = {
1021 0x01, 0x00, 0x02, 0x00,
1022 0x03, 0x00, 0x04, 0x00,
1023 0x05, 0x00, 0x06, 0x00,
1024 0x07, 0x00, 0x08, 0x00
1025};
1026
1027/* Sample metafiles to be compared to the outputs of the
1028 * test functions.
1029 */
1030
1031static const unsigned char MF_BLANK_BITS[] = {
1032 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x0c, 0x00,
1033 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1034 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
1035};
1036
1037static const unsigned char MF_GRAPHICS_BITS[] = {
1038 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x22, 0x00,
1039 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1040 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x02,
1041 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00,
1042 0x13, 0x02, 0x02, 0x00, 0x02, 0x00, 0x05, 0x00,
1043 0x00, 0x00, 0x14, 0x02, 0x01, 0x00, 0x01, 0x00,
1044 0x07, 0x00, 0x00, 0x00, 0x18, 0x04, 0x02, 0x00,
1045 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
1046 0x00, 0x00, 0x00, 0x00
1047};
1048
1049static const unsigned char MF_PATTERN_BRUSH_BITS[] = {
1050 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x3d, 0x00,
1051 0x00, 0x00, 0x01, 0x00, 0x2d, 0x00, 0x00, 0x00,
1052 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x42, 0x01,
1053 0x03, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
1054 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1055 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
1056 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1057 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1058 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1059 0xff, 0xff, 0xff, 0x00, 0x08, 0x00, 0x00, 0x00,
1060 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
1061 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1062 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1063 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1064 0x2d, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1065 0x00, 0x00
1066};
1067
1068static const unsigned char MF_DCBRUSH_BITS[] =
1069{
1070 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x2a, 0x00,
1071 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00,
1072 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xfc, 0x02,
1073 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
1074 0x04, 0x00, 0x00, 0x00, 0x2d, 0x01, 0x00, 0x00,
1075 0x08, 0x00, 0x00, 0x00, 0xfa, 0x02, 0x00, 0x00,
1076 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1077 0x04, 0x00, 0x00, 0x00, 0x2d, 0x01, 0x01, 0x00,
1078 0x07, 0x00, 0x00, 0x00, 0x1b, 0x04, 0x14, 0x00,
1079 0x14, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x03, 0x00,
1080 0x00, 0x00, 0x00, 0x00
1081};
1082
1083static const unsigned char MF_TEXTOUT_ON_PATH_BITS[] =
1084{
1085 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x19, 0x00,
1086 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
1087 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x0a,
1088 0x16, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x00, 0x00,
1089 0x54, 0x65, 0x73, 0x74, 0x03, 0x00, 0x05, 0x00,
1090 0x08, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x00,
1091 0x00, 0x00
1092};
1093
1094static const unsigned char EMF_TEXTOUT_ON_PATH_BITS[] =
1095{
1096 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1097 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1098 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1099 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1100 0xe7, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xff,
1101 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1102 0xf4, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1103 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1105 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1106 0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
1107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1108 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
1109 0x80, 0xa9, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00,
1110 0x08, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
1111 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1112 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
1113 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
1114 0x00, 0x00, 0xc8, 0x41, 0x00, 0x80, 0xbb, 0x41,
1115 0x0b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
1116 0x04, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
1117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1118 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
1119 0xff, 0xff, 0xff, 0xff, 0x54, 0x00, 0x00, 0x00,
1120 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
1121 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1122 0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1123 0x3c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1124 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1125 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1126 0x14, 0x00, 0x00, 0x00
1127};
1128
1129static const unsigned char EMF_TEXTOUT_OUTLINE_ON_PATH_BITS[] =
1130{
1131 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1133 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1135 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff,
1136 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1137 0x0c, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1138 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1140 0x90, 0x06, 0x00, 0x00, 0x1a, 0x04, 0x00, 0x00,
1141 0x51, 0x02, 0x00, 0x00, 0x72, 0x01, 0x00, 0x00,
1142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1143 0x00, 0x00, 0x00, 0x00, 0x1a, 0x0b, 0x09, 0x00,
1144 0xf0, 0xa6, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00,
1145 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x80,
1146 0x3b, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1147 0x54, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
1148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1149 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1150 0x01, 0x00, 0x00, 0x00, 0xc3, 0x30, 0x0d, 0x42,
1151 0xcf, 0xf3, 0x0c, 0x42, 0x0b, 0x00, 0x00, 0x00,
1152 0x16, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1153 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1155 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1156 0x54, 0x00, 0x00, 0x00, 0x54, 0x00, 0x65, 0x00,
1157 0x73, 0x00, 0x74, 0x00, 0x03, 0x00, 0x00, 0x00,
1158 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1159 0x0c, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
1160 0x08, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
1161 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x80,
1162 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1163 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1164 0x14, 0x00, 0x00, 0x00
1165};
1166
1167static const unsigned char MF_LINETO_BITS[] = {
1168 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x11, 0x00,
1169 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1170 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x13, 0x02,
1171 0x0f, 0x00, 0x37, 0x00, 0x03, 0x00, 0x00, 0x00,
1172 0x00, 0x00
1173};
1174
1175static const unsigned char EMF_LINETO_BITS[] = {
1176 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1178 0x37, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1180 0x61, 0x06, 0x00, 0x00, 0xb7, 0x01, 0x00, 0x00,
1181 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1182 0x38, 0x01, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1183 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1185 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1186 0x7c, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00,
1187 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1188 0x00, 0x00, 0x00, 0x00, 0x60, 0xcc, 0x05, 0x00,
1189 0xe0, 0x93, 0x04, 0x00, 0x46, 0x00, 0x00, 0x00,
1190 0x48, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00,
1191 0x47, 0x44, 0x49, 0x43, 0x01, 0x00, 0x00, 0x80,
1192 0x00, 0x03, 0x00, 0x00, 0x60, 0xe5, 0xf4, 0x73,
1193 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
1194 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x11, 0x00,
1195 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1196 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x13, 0x02,
1197 0x0f, 0x00, 0x37, 0x00, 0x03, 0x00, 0x00, 0x00,
1198 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
1199 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1200 0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1201 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1202 0x09, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1203 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1204 0x36, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1205 0x37, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1206 0x25, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1207 0x07, 0x00, 0x00, 0x80, 0x25, 0x00, 0x00, 0x00,
1208 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
1209 0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1210 0x0f, 0x00, 0x00, 0x80, 0x4b, 0x00, 0x00, 0x00,
1211 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1212 0x05, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
1213 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1214 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
1215};
1216
1217static const unsigned char EMF_LINETO_MM_ANISOTROPIC_BITS[] = {
1218 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1220 0x37, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1221 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1222 0x64, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
1223 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1224 0x38, 0x01, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1225 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1227 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1228 0x7c, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00,
1229 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1230 0x00, 0x00, 0x00, 0x00, 0x60, 0xcc, 0x05, 0x00,
1231 0xe0, 0x93, 0x04, 0x00, 0x46, 0x00, 0x00, 0x00,
1232 0x48, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00,
1233 0x47, 0x44, 0x49, 0x43, 0x01, 0x00, 0x00, 0x80,
1234 0x00, 0x03, 0x00, 0x00, 0xa4, 0xfe, 0xf4, 0x73,
1235 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
1236 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x11, 0x00,
1237 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1238 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x13, 0x02,
1239 0x0f, 0x00, 0x37, 0x00, 0x03, 0x00, 0x00, 0x00,
1240 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
1241 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1242 0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1243 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1244 0x09, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1245 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1246 0x36, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1247 0x37, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1248 0x25, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1249 0x07, 0x00, 0x00, 0x80, 0x25, 0x00, 0x00, 0x00,
1250 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
1251 0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1252 0x0f, 0x00, 0x00, 0x80, 0x4b, 0x00, 0x00, 0x00,
1253 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1254 0x05, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
1255 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1256 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
1257};
1258
1259static const unsigned char EMF_LINETO_MM_TEXT_BITS[] = {
1260 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1261 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1262 0x37, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1263 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1264 0x61, 0x06, 0x00, 0x00, 0xb7, 0x01, 0x00, 0x00,
1265 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1266 0xe4, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1267 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1268 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1269 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1270 0x7c, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00,
1271 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1272 0x00, 0x00, 0x00, 0x00, 0x60, 0xcc, 0x05, 0x00,
1273 0xe0, 0x93, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00,
1274 0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
1275 0x00, 0x04, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1276 0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
1277 0x00, 0x04, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
1278 0x10, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00,
1279 0x0f, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
1280 0x0c, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x80,
1281 0x25, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1282 0x00, 0x00, 0x00, 0x80, 0x30, 0x00, 0x00, 0x00,
1283 0x0c, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x80,
1284 0x4b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1285 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1286 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1287 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1288 0x14, 0x00, 0x00, 0x00
1289};
1290
1291static const unsigned char EMF_BITBLT[] =
1292{
1293 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1294 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1295 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1297 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
1298 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1299 0x64, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1300 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1301 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1302 0x80, 0x07, 0x00, 0x00, 0xb0, 0x04, 0x00, 0x00,
1303 0xfc, 0x01, 0x00, 0x00, 0x3e, 0x01, 0x00, 0x00,
1304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1305 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
1306 0x30, 0xda, 0x04, 0x00, 0x4c, 0x00, 0x00, 0x00,
1307 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1308 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1309 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1310 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1311 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0xcc, 0x00,
1312 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1313 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
1314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
1315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1316 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
1317 0x64, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
1318 0x8c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
1319 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1320 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00,
1321 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
1322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1326 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1327 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1328 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1329 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1330 0x4c, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
1331 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1332 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1334 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1335 0x62, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
1336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
1337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1338 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
1339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1342 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00,
1343 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1344 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1345 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1346 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1347 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0xcc, 0x00,
1348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1349 0x0a, 0xd7, 0xa3, 0x3b, 0x00, 0x00, 0x00, 0x00,
1350 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0x23, 0x3c,
1351 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1352 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
1353 0x6c, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
1354 0x94, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
1355 0x90, 0x01, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
1356 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1357 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00,
1358 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
1359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1363 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1364 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1365 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1366 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1367 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1368 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1369 0x14, 0x00, 0x00, 0x00
1370};
1371
1372static const unsigned char EMF_DCBRUSH_BITS[] =
1373{
1374 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1375 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1376 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
1377 0x39, 0x01, 0x00, 0x00, 0x39, 0x01, 0x00, 0x00,
1378 0x52, 0x02, 0x00, 0x00, 0x52, 0x02, 0x00, 0x00,
1379 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1380 0x44, 0x01, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
1381 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1382 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1383 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
1384 0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
1385 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1386 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
1387 0x80, 0xa9, 0x03, 0x00, 0x25, 0x00, 0x00, 0x00,
1388 0x0c, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x80,
1389 0x25, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1390 0x13, 0x00, 0x00, 0x80, 0x27, 0x00, 0x00, 0x00,
1391 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1392 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x00,
1393 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
1394 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1395 0x26, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
1396 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1398 0x33, 0x44, 0x55, 0x00, 0x25, 0x00, 0x00, 0x00,
1399 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1400 0x2b, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
1401 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1402 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
1403 0x28, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1404 0x01, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
1405 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1406 0x00, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x00,
1407 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
1408 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1409 0x28, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1410 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
1411 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1412 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1413 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1414 0x14, 0x00, 0x00, 0x00
1415};
1416
1417static const unsigned char EMF_BEZIER_BITS[] =
1418{
1419 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1421 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00,
1422 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1423 0x1a, 0x2a, 0x0d, 0x00, 0x1a, 0x2f, 0x0d, 0x00,
1424 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1425 0x44, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
1426 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1427 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1428 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1429 0x51, 0x01, 0x00, 0x00, 0x0e, 0x01, 0x00, 0x00,
1430 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1431 0x00, 0x00, 0x00, 0x00, 0x68, 0x24, 0x05, 0x00,
1432 0xb0, 0x1e, 0x04, 0x00, 0x58, 0x00, 0x00, 0x00,
1433 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1434 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1435 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1436 0x0a, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x14, 0x00,
1437 0x0f, 0x00, 0x0f, 0x00, 0x55, 0x00, 0x00, 0x00,
1438 0x2c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1439 0x0a, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
1440 0x19, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1441 0x0a, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x14, 0x00,
1442 0x0f, 0x00, 0x0f, 0x00, 0x19, 0x00, 0x19, 0x00,
1443 0x02, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
1444 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1445 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00,
1446 0x04, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00,
1447 0x01, 0x80, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1448 0x14, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1449 0x0f, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
1450 0x19, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1451 0x34, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1452 0x0f, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00,
1453 0x01, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1454 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00,
1455 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1456 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1457 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1458 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1459 0x14, 0x00, 0x00, 0x00
1460};
1461
1462static const unsigned char EMF_POLYPOLYLINE_BITS[] =
1463{
1464 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1465 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1466 0x00, 0x90, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00,
1467 0x61, 0x01, 0x00, 0x00, 0xc2, 0x02, 0x00, 0x00,
1468 0x7a, 0xd4, 0x13, 0x00, 0xe8, 0x44, 0x00, 0x00,
1469 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1470 0x84, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1471 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1472 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1473 0xa1, 0x05, 0x00, 0x00, 0x47, 0x03, 0x00, 0x00,
1474 0xfc, 0x01, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00,
1475 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1476 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc1, 0x07, 0x00,
1477 0x2c, 0x84, 0x04, 0x00, 0x5a, 0x00, 0x00, 0x00,
1478 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1479 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
1480 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
1481 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00,
1482 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1483 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
1484 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00,
1485 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1486 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00,
1487 0x5a, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
1488 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1489 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1490 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1491 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1492 0x0a, 0x00, 0x14, 0x00, 0x64, 0x00, 0xc8, 0x00,
1493 0x07, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
1494 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1495 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1496 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1497 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1498 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1499 0x64, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00,
1500 0x00, 0x90, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00,
1501 0x07, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
1502 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1503 0x00, 0x90, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00,
1504 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1505 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1506 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1507 0x64, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00,
1508 0x00, 0x90, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00,
1509 0x90, 0x01, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00,
1510 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1511 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1512 0x14, 0x00, 0x00, 0x00
1513};
1514
1515static const unsigned char EMF_GRADIENTFILL_BITS[] =
1516{
1517 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1518 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1519 0x2b, 0x01, 0x00, 0x00, 0x35, 0x01, 0x00, 0x00,
1520 0x23, 0x00, 0x00, 0x00, 0x61, 0x01, 0x00, 0x00,
1521 0x31, 0x29, 0x00, 0x00, 0xa3, 0x2a, 0x00, 0x00,
1522 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1523 0x0c, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1524 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1525 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1526 0x40, 0x05, 0x00, 0x00, 0x46, 0x03, 0x00, 0x00,
1527 0xda, 0x01, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00,
1528 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1529 0x00, 0x00, 0x00, 0x00, 0x15, 0x3c, 0x07, 0x00,
1530 0xcb, 0x82, 0x04, 0x00, 0x76, 0x00, 0x00, 0x00,
1531 0x8c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1532 0x0a, 0x00, 0x00, 0x00, 0x2b, 0x01, 0x00, 0x00,
1533 0x35, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1534 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1535 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1536 0x00, 0xff, 0x00, 0x80, 0x00, 0x00, 0x01, 0x80,
1537 0xc8, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00,
1538 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
1539 0xb4, 0x00, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00,
1540 0x34, 0x12, 0x78, 0x56, 0xbc, 0x9a, 0xf0, 0xde,
1541 0x2c, 0x01, 0x00, 0x00, 0x36, 0x01, 0x00, 0x00,
1542 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00,
1543 0x90, 0x01, 0x00, 0x00, 0x9a, 0x01, 0x00, 0x00,
1544 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00,
1545 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1546 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1547 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1548 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1549 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1550 0x14, 0x00, 0x00, 0x00
1551};
1552
1553/* For debugging or dumping the raw metafiles produced by
1554 * new test functions.
1555 */
1557 INT nobj, LPARAM param)
1558{
1559 trace("hdc %p, mr->rdFunction %04x, mr->rdSize %u, param %p\n",
1560 hdc, mr->rdFunction, mr->rdSize, (void *)param);
1561 return TRUE;
1562}
1563
1564/* For debugging or dumping the raw metafiles produced by
1565 * new test functions.
1566 */
1567
1568static void dump_mf_bits (const HMETAFILE mf, const char *desc)
1569{
1571 UINT mfsize, i;
1572
1573 if (!winetest_debug) return;
1574
1575 mfsize = GetMetaFileBitsEx (mf, MF_BUFSIZE, buf);
1576 ok (mfsize > 0, "%s: GetMetaFileBitsEx failed.\n", desc);
1577
1578 printf ("MetaFile %s has bits:\n{\n ", desc);
1579 for (i=0; i<mfsize; i++)
1580 {
1581 printf ("0x%02x", buf[i]);
1582 if (i == mfsize-1)
1583 printf ("\n");
1584 else if (i % 8 == 7)
1585 printf (",\n ");
1586 else
1587 printf (", ");
1588 }
1589 printf ("};\n");
1590}
1591
1592/* Compare the metafile produced by a test function with the
1593 * expected raw metafile data in "bits".
1594 * Return value is 0 for a perfect match,
1595 * -1 if lengths aren't equal,
1596 * otherwise returns the number of non-matching bytes.
1597 */
1598
1599static int compare_mf_bits (const HMETAFILE mf, const unsigned char *bits, UINT bsize,
1600 const char *desc)
1601{
1602 unsigned char buf[MF_BUFSIZE];
1603 UINT mfsize, i;
1604 int diff;
1605
1606 mfsize = GetMetaFileBitsEx (mf, MF_BUFSIZE, buf);
1607 ok (mfsize > 0, "%s: GetMetaFileBitsEx failed.\n", desc);
1608 if (mfsize < MF_BUFSIZE)
1609 ok (mfsize == bsize, "%s: mfsize=%d, bsize=%d.\n",
1610 desc, mfsize, bsize);
1611 else
1612 ok (bsize >= MF_BUFSIZE, "%s: mfsize > bufsize (%d bytes), bsize=%d.\n",
1613 desc, mfsize, bsize);
1614 if (mfsize != bsize)
1615 return -1;
1616
1617 diff = 0;
1618 for (i=0; i<bsize; i++)
1619 {
1620 if (buf[i] != bits[i])
1621 diff++;
1622 }
1623 ok (diff == 0, "%s: mfsize=%d, bsize=%d, diff=%d\n",
1624 desc, mfsize, bsize, diff);
1625
1626 return diff;
1627}
1628
1629static int compare_mf_disk_bits(LPCSTR name, const BYTE *bits, UINT bsize, const char *desc)
1630{
1631 unsigned char buf[MF_BUFSIZE];
1632 DWORD mfsize, rd_size, i;
1633 int diff;
1634 HANDLE hfile;
1635 BOOL ret;
1636
1638 assert(hfile != INVALID_HANDLE_VALUE);
1639
1640 mfsize = GetFileSize(hfile, NULL);
1641 assert(mfsize <= MF_BUFSIZE);
1642
1643 ret = ReadFile(hfile, buf, sizeof(buf), &rd_size, NULL);
1644 ok( ret && rd_size == mfsize, "ReadFile: error %d\n", GetLastError());
1645
1646 CloseHandle(hfile);
1647
1648 ok(mfsize == bsize, "%s: mfsize=%d, bsize=%d.\n", desc, mfsize, bsize);
1649
1650 if (mfsize != bsize)
1651 return -1;
1652
1653 diff = 0;
1654 for (i=0; i<bsize; i++)
1655 {
1656 if (buf[i] != bits[i])
1657 diff++;
1658 }
1659 ok(diff == 0, "%s: mfsize=%d, bsize=%d, diff=%d\n",
1660 desc, mfsize, bsize, diff);
1661
1662 return diff;
1663}
1664
1665/* For debugging or dumping the raw EMFs produced by
1666 * new test functions.
1667 */
1668static void dump_emf_bits(const HENHMETAFILE mf, const char *desc)
1669{
1671 UINT mfsize, i;
1672
1673 if (!winetest_debug) return;
1674
1675 mfsize = GetEnhMetaFileBits(mf, MF_BUFSIZE, buf);
1676 ok (mfsize > 0, "%s: GetEnhMetaFileBits failed\n", desc);
1677
1678 printf("EMF %s has bits:\n{\n ", desc);
1679 for (i = 0; i < mfsize; i++)
1680 {
1681 printf ("0x%02x", buf[i]);
1682 if (i == mfsize-1)
1683 printf ("\n");
1684 else if (i % 8 == 7)
1685 printf (",\n ");
1686 else
1687 printf (", ");
1688 }
1689 printf ("};\n");
1690}
1691
1692static void dump_emf_records(const HENHMETAFILE mf, const char *desc)
1693{
1694 BYTE *emf;
1696 UINT mfsize, offset;
1697
1698 if (!winetest_debug) return;
1699
1700 mfsize = GetEnhMetaFileBits(mf, MF_BUFSIZE, buf);
1701 ok (mfsize > 0, "%s: GetEnhMetaFileBits error %d\n", desc, GetLastError());
1702
1703 printf("EMF %s has records:\n", desc);
1704
1705 emf = buf;
1706 offset = 0;
1707 while(offset < mfsize)
1708 {
1709 EMR *emr = (EMR *)(emf + offset);
1710 printf("emr->iType %d, emr->nSize %u\n", emr->iType, emr->nSize);
1711 /*trace("emr->iType 0x%04lx, emr->nSize 0x%04lx\n", emr->iType, emr->nSize);*/
1712 offset += emr->nSize;
1713 }
1714}
1715
1716static void dump_emf_record(const ENHMETARECORD *emr, const char *desc)
1717{
1718 const BYTE *buf;
1719 DWORD i;
1720
1721 if (!winetest_debug) return;
1722
1723 printf ("%s: EMF record %u has bits:\n{\n", desc, emr->iType);
1724 buf = (const BYTE *)emr;
1725 for (i = 0; i < emr->nSize; i++)
1726 {
1727 printf ("0x%02x", buf[i]);
1728 if (i == emr->nSize - 1)
1729 printf ("\n");
1730 else if (i % 8 == 7)
1731 printf (",\n");
1732 else
1733 printf (", ");
1734 }
1735 printf ("};\n");
1736}
1737
1738static void dump_EMREXTTEXTOUT(const EMREXTTEXTOUTW *eto)
1739{
1740 trace("rclBounds %d,%d - %d,%d\n", eto->rclBounds.left, eto->rclBounds.top,
1741 eto->rclBounds.right, eto->rclBounds.bottom);
1742 trace("iGraphicsMode %u\n", eto->iGraphicsMode);
1743 trace("exScale: %f\n", eto->exScale);
1744 trace("eyScale: %f\n", eto->eyScale);
1745 trace("emrtext.ptlReference %d,%d\n", eto->emrtext.ptlReference.x, eto->emrtext.ptlReference.y);
1746 trace("emrtext.nChars %u\n", eto->emrtext.nChars);
1747 trace("emrtext.offString %#x\n", eto->emrtext.offString);
1748 trace("emrtext.fOptions %#x\n", eto->emrtext.fOptions);
1749 trace("emrtext.rcl %d,%d - %d,%d\n", eto->emrtext.rcl.left, eto->emrtext.rcl.top,
1750 eto->emrtext.rcl.right, eto->emrtext.rcl.bottom);
1751 trace("emrtext.offDx %#x\n", eto->emrtext.offDx);
1752}
1753
1754static BOOL match_emf_record(const ENHMETARECORD *emr1, const ENHMETARECORD *emr2,
1755 const char *desc, BOOL ignore_scaling)
1756{
1757 int diff;
1758
1759 ok(emr1->iType == emr2->iType, "%s: emr->iType %u != %u\n",
1760 desc, emr1->iType, emr2->iType);
1761
1762 ok(emr1->nSize == emr2->nSize, "%s: emr->nSize %u != %u\n",
1763 desc, emr1->nSize, emr2->nSize);
1764
1765 /* iType and nSize mismatches are fatal */
1766 if (emr1->iType != emr2->iType || emr1->nSize != emr2->nSize) return FALSE;
1767
1768 /* contents of EMR_GDICOMMENT are not interesting */
1769 if (emr1->iType == EMR_GDICOMMENT) return TRUE;
1770
1771 /* different Windows versions setup DC scaling differently when
1772 * converting an old style metafile to an EMF.
1773 */
1774 if (ignore_scaling && (emr1->iType == EMR_SETWINDOWEXTEX ||
1775 emr1->iType == EMR_SETVIEWPORTEXTEX))
1776 return TRUE;
1777
1778 if (emr1->iType == EMR_EXTTEXTOUTW || emr1->iType == EMR_EXTTEXTOUTA)
1779 {
1780 EMREXTTEXTOUTW *eto1, *eto2;
1781
1782 eto1 = HeapAlloc(GetProcessHeap(), 0, emr1->nSize);
1783 memcpy(eto1, emr1, emr1->nSize);
1784 eto2 = HeapAlloc(GetProcessHeap(), 0, emr2->nSize);
1785 memcpy(eto2, emr2, emr2->nSize);
1786
1787 /* different Windows versions setup DC scaling differently */
1788 eto1->exScale = eto1->eyScale = 0.0;
1789 eto2->exScale = eto2->eyScale = 0.0;
1790
1791 diff = memcmp(eto1, eto2, emr1->nSize);
1792 if (diff)
1793 {
1794 dump_EMREXTTEXTOUT(eto1);
1795 dump_EMREXTTEXTOUT(eto2);
1796 }
1797 HeapFree(GetProcessHeap(), 0, eto1);
1798 HeapFree(GetProcessHeap(), 0, eto2);
1799 }
1800 else if (emr1->iType == EMR_EXTSELECTCLIPRGN && !lstrcmpA(desc, "emf_clipping"))
1801 {
1802 /* We have to take care of NT4 differences here */
1803 diff = memcmp(emr1, emr2, emr1->nSize);
1804 if (diff)
1805 {
1806 ENHMETARECORD *emr_nt4;
1807
1808 emr_nt4 = HeapAlloc(GetProcessHeap(), 0, emr2->nSize);
1809 memcpy(emr_nt4, emr2, emr2->nSize);
1810 /* Correct the nRgnSize field */
1811 emr_nt4->dParm[5] = sizeof(RECT);
1812
1813 diff = memcmp(emr1, emr_nt4, emr1->nSize);
1814 if (!diff)
1815 win_skip("Catered for NT4 differences\n");
1816
1817 HeapFree(GetProcessHeap(), 0, emr_nt4);
1818 }
1819 }
1820 else if (emr1->iType == EMR_POLYBEZIERTO16 || emr1->iType == EMR_POLYBEZIER16)
1821 {
1822 EMRPOLYBEZIER16 *eto1, *eto2;
1823
1824 eto1 = (EMRPOLYBEZIER16*)emr1;
1825 eto2 = (EMRPOLYBEZIER16*)emr2;
1826
1827 diff = eto1->cpts != eto2->cpts;
1828 if(!diff)
1829 diff = memcmp(eto1->apts, eto2->apts, eto1->cpts * sizeof(POINTS));
1830 }
1831 else if (emr1->iType == EMR_POLYBEZIERTO || emr1->iType == EMR_POLYBEZIER)
1832 {
1833 EMRPOLYBEZIER *eto1, *eto2;
1834
1835 eto1 = (EMRPOLYBEZIER*)emr1;
1836 eto2 = (EMRPOLYBEZIER*)emr2;
1837
1838 diff = eto1->cptl != eto2->cptl;
1839 if(!diff)
1840 diff = memcmp(eto1->aptl, eto2->aptl, eto1->cptl * sizeof(POINTL));
1841 }
1842 else
1843 diff = memcmp(emr1, emr2, emr1->nSize);
1844
1845 ok(diff == 0, "%s: contents of record %u don't match\n", desc, emr1->iType);
1846
1847 if (diff)
1848 {
1849 dump_emf_record(emr1, "expected bits");
1850 dump_emf_record(emr2, "actual bits");
1851 }
1852
1853 return diff == 0; /* report all non-fatal record mismatches */
1854}
1855
1856/* Compare the EMF produced by a test function with the
1857 * expected raw EMF data in "bits".
1858 * Return value is 0 for a perfect match,
1859 * -1 if lengths aren't equal,
1860 * otherwise returns the number of non-matching bytes.
1861 */
1862static int compare_emf_bits(const HENHMETAFILE mf, const unsigned char *bits,
1863 UINT bsize, const char *desc,
1864 BOOL ignore_scaling)
1865{
1866 unsigned char buf[MF_BUFSIZE];
1867 UINT mfsize, offset1, offset2, diff_nt4, diff_9x;
1868 const ENHMETAHEADER *emh1, *emh2;
1869
1870 mfsize = GetEnhMetaFileBits(mf, MF_BUFSIZE, buf);
1871 ok (mfsize > 0, "%s: GetEnhMetaFileBits error %d\n", desc, GetLastError());
1872
1873 /* ENHMETAHEADER size could differ, depending on platform */
1874 diff_nt4 = sizeof(SIZEL);
1875 diff_9x = sizeof(SIZEL) + 3 * sizeof(DWORD);
1876
1877 if (mfsize < MF_BUFSIZE)
1878 {
1879 ok(mfsize == bsize ||
1880 broken(mfsize == bsize - diff_nt4) || /* NT4 */
1881 broken(mfsize == bsize - diff_9x), /* Win9x/WinME */
1882 "%s: mfsize=%d, bsize=%d\n", desc, mfsize, bsize);
1883 }
1884 else
1885 ok(bsize >= MF_BUFSIZE, "%s: mfsize > bufsize (%d bytes), bsize=%d\n",
1886 desc, mfsize, bsize);
1887
1888 /* basic things must match */
1889 emh1 = (const ENHMETAHEADER *)bits;
1890 emh2 = (const ENHMETAHEADER *)buf;
1891 ok(emh1->iType == EMR_HEADER, "expected EMR_HEADER, got %u\n", emh1->iType);
1892 ok(emh1->nSize == sizeof(ENHMETAHEADER), "expected sizeof(ENHMETAHEADER), got %u\n", emh1->nSize);
1893 ok(emh2->nBytes == mfsize, "expected emh->nBytes %u, got %u\n", mfsize, emh2->nBytes);
1894 ok(emh1->dSignature == ENHMETA_SIGNATURE, "expected ENHMETA_SIGNATURE, got %u\n", emh1->dSignature);
1895
1896 ok(emh1->iType == emh2->iType, "expected EMR_HEADER, got %u\n", emh2->iType);
1897 ok(emh1->nSize == emh2->nSize ||
1898 broken(emh1->nSize - diff_nt4 == emh2->nSize) ||
1899 broken(emh1->nSize - diff_9x == emh2->nSize),
1900 "expected nSize %u, got %u\n", emh1->nSize, emh2->nSize);
1901 ok(emh1->rclBounds.left == emh2->rclBounds.left, "%s: expected rclBounds.left = %d, got %d\n",
1902 desc, emh1->rclBounds.left, emh2->rclBounds.left);
1903 ok(emh1->rclBounds.top == emh2->rclBounds.top, "%s: expected rclBounds.top = %d, got %d\n",
1904 desc, emh1->rclBounds.top, emh2->rclBounds.top);
1905 ok(emh1->rclBounds.right == emh2->rclBounds.right, "%s: expected rclBounds.right = %d, got %d\n",
1906 desc, emh1->rclBounds.right, emh2->rclBounds.right);
1907 ok(emh1->rclBounds.bottom == emh2->rclBounds.bottom, "%s: expected rclBounds.bottom = %d, got %d\n",
1908 desc, emh1->rclBounds.bottom, emh2->rclBounds.bottom);
1909 ok(emh1->dSignature == emh2->dSignature, "expected dSignature %u, got %u\n", emh1->dSignature, emh2->dSignature);
1910 ok(emh1->nBytes == emh2->nBytes ||
1911 broken(emh1->nBytes - diff_nt4 == emh2->nBytes) ||
1912 broken(emh1->nBytes - diff_9x == emh2->nBytes),
1913 "expected nBytes %u, got %u\n", emh1->nBytes, emh2->nBytes);
1914 ok(emh1->nRecords == emh2->nRecords, "expected nRecords %u, got %u\n", emh1->nRecords, emh2->nRecords);
1915
1916 offset1 = emh1->nSize;
1917 offset2 = emh2->nSize; /* Needed for Win9x/WinME/NT4 */
1918 while (offset1 < emh1->nBytes)
1919 {
1920 const ENHMETARECORD *emr1 = (const ENHMETARECORD *)(bits + offset1);
1921 const ENHMETARECORD *emr2 = (const ENHMETARECORD *)(buf + offset2);
1922
1923 trace("%s: EMF record %u, size %u/record %u, size %u\n",
1924 desc, emr1->iType, emr1->nSize, emr2->iType, emr2->nSize);
1925
1926 if (!match_emf_record(emr1, emr2, desc, ignore_scaling)) return -1;
1927
1928 /* We have already bailed out if iType or nSize don't match */
1929 offset1 += emr1->nSize;
1930 offset2 += emr2->nSize;
1931 }
1932 return 0;
1933}
1934
1935
1936/* tests blitting to an EMF */
1937static void test_emf_BitBlt(void)
1938{
1939 HDC hdcDisplay, hdcMetafile, hdcBitmap;
1940 HBITMAP hBitmap, hOldBitmap;
1941 HENHMETAFILE hMetafile;
1942#define BMP_DIM 4
1943 BITMAPINFOHEADER bmih =
1944 {
1945 sizeof(BITMAPINFOHEADER),
1946 BMP_DIM,/* biWidth */
1947 BMP_DIM,/* biHeight */
1948 1, /* biPlanes */
1949 24, /* biBitCount */
1950 BI_RGB, /* biCompression */
1951 0, /* biXPelsPerMeter */
1952 0, /* biYPelsPerMeter */
1953 0, /* biClrUsed */
1954 0, /* biClrImportant */
1955 };
1956 void *bits;
1957 XFORM xform;
1958 BOOL ret;
1959
1960 hdcDisplay = CreateDCA("DISPLAY", NULL, NULL, NULL);
1961 ok( hdcDisplay != 0, "CreateDCA error %d\n", GetLastError() );
1962
1963 hdcBitmap = CreateCompatibleDC(hdcDisplay);
1964 ok( hdcBitmap != 0, "CreateCompatibleDC failed\n" );
1965 ok(SetGraphicsMode(hdcBitmap, GM_ADVANCED), "SetGraphicsMode failed\n");
1966 bmih.biXPelsPerMeter = MulDiv(GetDeviceCaps(hdcDisplay, LOGPIXELSX), 100, 3937);
1967 bmih.biYPelsPerMeter = MulDiv(GetDeviceCaps(hdcDisplay, LOGPIXELSY), 100, 3937);
1968 hBitmap = CreateDIBSection(hdcDisplay, (const BITMAPINFO *)&bmih,
1969 DIB_RGB_COLORS, &bits, NULL, 0);
1970 hOldBitmap = SelectObject(hdcBitmap, hBitmap);
1971
1972 hdcMetafile = CreateEnhMetaFileA(hdcBitmap, NULL, NULL, NULL);
1973 ok( hdcMetafile != 0, "CreateEnhMetaFileA failed\n" );
1974
1975 /* First fill the bitmap DC with something recognizable, like BLACKNESS */
1976 ret = BitBlt(hdcBitmap, 0, 0, BMP_DIM, BMP_DIM, 0, 0, 0, BLACKNESS);
1977 ok( ret, "BitBlt(BLACKNESS) failed\n" );
1978
1979 ret = BitBlt(hdcMetafile, 0, 0, BMP_DIM, BMP_DIM, hdcBitmap, 0, 0, SRCCOPY);
1980 ok( ret, "BitBlt(SRCCOPY) failed\n" );
1981 ret = BitBlt(hdcMetafile, 0, 0, BMP_DIM, BMP_DIM, 0, 0, 0, WHITENESS);
1982 ok( ret, "BitBlt(WHITENESS) failed\n" );
1983
1984 ok(SetMapMode(hdcBitmap, MM_ANISOTROPIC), "SetMapMode failed\n");
1985 ok(SetWindowOrgEx(hdcBitmap, 0, 0, NULL), "SetWindowOrgEx failed\n");
1986 ok(SetWindowExtEx(hdcBitmap, 400, 400, NULL), "SetWindowExtEx failed\n");
1987 ok(SetViewportOrgEx(hdcBitmap, 0, 0, NULL), "SetViewportOrgEx failed\n");
1988 ok(SetViewportExtEx(hdcBitmap, BMP_DIM, BMP_DIM, NULL), "SetViewportExtEx failed\n");
1989 memset(&xform, 0, sizeof(xform));
1990 xform.eM11 = 0.5;
1991 xform.eM22 = 1.0;
1992 ok(SetWorldTransform(hdcBitmap, &xform), "SetWorldTransform failed\n");
1993
1994 ret = StretchBlt(hdcMetafile, 0, 0, BMP_DIM, BMP_DIM, hdcBitmap, 0, 0, 400, 400, SRCCOPY);
1995 ok( ret, "StretchBlt(SRCCOPY) failed\n" );
1996
1997 hMetafile = CloseEnhMetaFile(hdcMetafile);
1998 ok( hMetafile != 0, "CloseEnhMetaFile failed\n" );
1999
2000 if(compare_emf_bits(hMetafile, EMF_BITBLT, sizeof(EMF_BITBLT),
2001 "emf_BitBlt", FALSE) != 0)
2002 {
2003 dump_emf_bits(hMetafile, "emf_BitBlt");
2004 dump_emf_records(hMetafile, "emf_BitBlt");
2005 }
2006
2007 SelectObject(hdcBitmap, hOldBitmap);
2010 DeleteDC(hdcDisplay);
2011#undef BMP_DIM
2012}
2013
2014static void test_emf_DCBrush(void)
2015{
2016 HDC hdcMetafile;
2017 HENHMETAFILE hMetafile;
2018 HBRUSH hBrush;
2019 HPEN hPen;
2020 BOOL ret;
2022
2023 if (!pSetDCBrushColor || !pSetDCPenColor)
2024 {
2025 win_skip( "SetDCBrush/PenColor not supported\n" );
2026 return;
2027 }
2028
2029 hdcMetafile = CreateEnhMetaFileA(GetDC(0), NULL, NULL, NULL);
2030 ok( hdcMetafile != 0, "CreateEnhMetaFileA failed\n" );
2031
2032 hBrush = SelectObject(hdcMetafile, GetStockObject(DC_BRUSH));
2033 ok(hBrush != 0, "SelectObject error %d.\n", GetLastError());
2034
2035 hPen = SelectObject(hdcMetafile, GetStockObject(DC_PEN));
2036 ok(hPen != 0, "SelectObject error %d.\n", GetLastError());
2037
2038 color = pSetDCBrushColor( hdcMetafile, RGB(0x55,0x55,0x55) );
2039 ok( color == 0xffffff, "SetDCBrushColor returned %x\n", color );
2040
2041 color = pSetDCPenColor( hdcMetafile, RGB(0x33,0x44,0x55) );
2042 ok( color == 0, "SetDCPenColor returned %x\n", color );
2043
2044 Rectangle( hdcMetafile, 10, 10, 20, 20 );
2045
2046 color = pSetDCBrushColor( hdcMetafile, RGB(0x12,0x34,0x56) );
2047 ok( color == 0x555555, "SetDCBrushColor returned %x\n", color );
2048
2049 hMetafile = CloseEnhMetaFile(hdcMetafile);
2050 ok( hMetafile != 0, "CloseEnhMetaFile failed\n" );
2051
2052 if (compare_emf_bits (hMetafile, EMF_DCBRUSH_BITS, sizeof(EMF_DCBRUSH_BITS),
2053 "emf_DC_Brush", FALSE ) != 0)
2054 {
2055 dump_emf_bits(hMetafile, "emf_DC_Brush");
2056 dump_emf_records(hMetafile, "emf_DC_Brush");
2057 }
2058 ret = DeleteEnhMetaFile(hMetafile);
2059 ok( ret, "DeleteEnhMetaFile error %d\n", GetLastError());
2060 ret = DeleteObject(hBrush);
2061 ok( ret, "DeleteObject(HBRUSH) error %d\n", GetLastError());
2062 ret = DeleteObject(hPen);
2063 ok( ret, "DeleteObject(HPEN) error %d\n", GetLastError());
2064}
2065
2066/* Test a blank metafile. May be used as a template for new tests. */
2067
2068static void test_mf_Blank(void)
2069{
2070 HDC hdcMetafile;
2071 HMETAFILE hMetafile;
2072 INT caps;
2073 BOOL ret;
2074 INT type;
2075
2076 hdcMetafile = CreateMetaFileA(NULL);
2077 ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %d\n", GetLastError());
2078 trace("hdcMetafile %p\n", hdcMetafile);
2079
2080/* Tests on metafile initialization */
2081 caps = GetDeviceCaps (hdcMetafile, TECHNOLOGY);
2082 ok (caps == DT_METAFILE,
2083 "GetDeviceCaps: TECHNOLOGY=%d != DT_METAFILE.\n", caps);
2084
2085 hMetafile = CloseMetaFile(hdcMetafile);
2086 ok(hMetafile != 0, "CloseMetaFile error %d\n", GetLastError());
2087 type = GetObjectType(hMetafile);
2088 ok(type == OBJ_METAFILE, "CloseMetaFile created object with type %d\n", type);
2089 ok(!GetObjectType(hdcMetafile), "CloseMetaFile has to destroy metafile hdc\n");
2090
2091 if (compare_mf_bits (hMetafile, MF_BLANK_BITS, sizeof(MF_BLANK_BITS),
2092 "mf_blank") != 0)
2093 {
2094 dump_mf_bits(hMetafile, "mf_Blank");
2095 EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
2096 }
2097
2098 ret = DeleteMetaFile(hMetafile);
2099 ok( ret, "DeleteMetaFile(%p) error %d\n", hMetafile, GetLastError());
2100}
2101
2102static void test_CopyMetaFile(void)
2103{
2104 HDC hdcMetafile;
2105 HMETAFILE hMetafile, hmf_copy;
2106 BOOL ret;
2107 char temp_path[MAX_PATH];
2108 char mf_name[MAX_PATH];
2109 INT type;
2110
2111 hdcMetafile = CreateMetaFileA(NULL);
2112 ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %d\n", GetLastError());
2113 trace("hdcMetafile %p\n", hdcMetafile);
2114
2115 hMetafile = CloseMetaFile(hdcMetafile);
2116 ok(hMetafile != 0, "CloseMetaFile error %d\n", GetLastError());
2117 type = GetObjectType(hMetafile);
2118 ok(type == OBJ_METAFILE, "CloseMetaFile created object with type %d\n", type);
2119
2120 if (compare_mf_bits (hMetafile, MF_BLANK_BITS, sizeof(MF_BLANK_BITS),
2121 "mf_blank") != 0)
2122 {
2123 dump_mf_bits(hMetafile, "mf_Blank");
2124 EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
2125 }
2126
2128 GetTempFileNameA(temp_path, "wmf", 0, mf_name);
2129
2130 hmf_copy = CopyMetaFileA(hMetafile, mf_name);
2131 ok(hmf_copy != 0, "CopyMetaFile error %d\n", GetLastError());
2132
2133 type = GetObjectType(hmf_copy);
2134 ok(type == OBJ_METAFILE, "CopyMetaFile created object with type %d\n", type);
2135
2136 ret = DeleteMetaFile(hMetafile);
2137 ok( ret, "DeleteMetaFile(%p) error %d\n", hMetafile, GetLastError());
2138
2139 if (compare_mf_disk_bits(mf_name, MF_BLANK_BITS, sizeof(MF_BLANK_BITS), "mf_blank") != 0)
2140 {
2141 dump_mf_bits(hmf_copy, "mf_Blank");
2142 EnumMetaFile(0, hmf_copy, mf_enum_proc, 0);
2143 }
2144
2145 ret = DeleteMetaFile(hmf_copy);
2146 ok( ret, "DeleteMetaFile(%p) error %d\n", hmf_copy, GetLastError());
2147
2148 DeleteFileA(mf_name);
2149}
2150
2151static void test_SetMetaFileBits(void)
2152{
2153 HMETAFILE hmf;
2154 INT type;
2155 BOOL ret;
2156 BYTE buf[256];
2157 METAHEADER *mh;
2158
2160 trace("hmf %p\n", hmf);
2161 ok(hmf != 0, "SetMetaFileBitsEx error %d\n", GetLastError());
2162 type = GetObjectType(hmf);
2163 ok(type == OBJ_METAFILE, "SetMetaFileBitsEx created object with type %d\n", type);
2164
2165 if (compare_mf_bits(hmf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0)
2166 {
2167 dump_mf_bits(hmf, "mf_Graphics");
2168 EnumMetaFile(0, hmf, mf_enum_proc, 0);
2169 }
2170
2171 ret = DeleteMetaFile(hmf);
2172 ok(ret, "DeleteMetaFile(%p) error %d\n", hmf, GetLastError());
2173
2174 /* NULL data crashes XP SP1 */
2175 /*hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), NULL);*/
2176
2177 /* Now with zero size */
2178 SetLastError(0xdeadbeef);
2180 trace("hmf %p\n", hmf);
2181 ok(!hmf, "SetMetaFileBitsEx should fail\n");
2184 "wrong error %d\n", GetLastError());
2185
2186 /* Now with odd size */
2187 SetLastError(0xdeadbeef);
2189 trace("hmf %p\n", hmf);
2190 ok(!hmf, "SetMetaFileBitsEx should fail\n");
2191 ok(GetLastError() == 0xdeadbeef /* XP SP1 */, "wrong error %d\n", GetLastError());
2192
2193 /* Now with zeroed out header fields */
2194 assert(sizeof(buf) >= sizeof(MF_GRAPHICS_BITS));
2196 mh = (METAHEADER *)buf;
2197 /* corruption of any of the below fields leads to a failure */
2198 mh->mtType = 0;
2199 mh->mtVersion = 0;
2200 mh->mtHeaderSize = 0;
2201 SetLastError(0xdeadbeef);
2202 hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), buf);
2203 trace("hmf %p\n", hmf);
2204 ok(!hmf, "SetMetaFileBitsEx should fail\n");
2207 "wrong error %d\n", GetLastError());
2208
2209 /* Now with corrupted mtSize field */
2211 mh = (METAHEADER *)buf;
2212 /* corruption of mtSize doesn't lead to a failure */
2213 mh->mtSize *= 2;
2214 hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), buf);
2215 trace("hmf %p\n", hmf);
2216 ok(hmf != 0, "SetMetaFileBitsEx error %d\n", GetLastError());
2217
2218 if (compare_mf_bits(hmf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0)
2219 {
2220 dump_mf_bits(hmf, "mf_Graphics");
2221 EnumMetaFile(0, hmf, mf_enum_proc, 0);
2222 }
2223
2224 ret = DeleteMetaFile(hmf);
2225 ok(ret, "DeleteMetaFile(%p) error %d\n", hmf, GetLastError());
2226
2227#ifndef _WIN64 /* Generates access violation on XP x64 and Win2003 x64 */
2228 /* Now with zeroed out mtSize field */
2230 mh = (METAHEADER *)buf;
2231 /* zeroing mtSize doesn't lead to a failure */
2232 mh->mtSize = 0;
2233 hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), buf);
2234 trace("hmf %p\n", hmf);
2235 ok(hmf != 0, "SetMetaFileBitsEx error %d\n", GetLastError());
2236
2237 if (compare_mf_bits(hmf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0)
2238 {
2239 dump_mf_bits(hmf, "mf_Graphics");
2240 EnumMetaFile(0, hmf, mf_enum_proc, 0);
2241 }
2242
2243 ret = DeleteMetaFile(hmf);
2244 ok(ret, "DeleteMetaFile(%p) error %d\n", hmf, GetLastError());
2245#endif
2246}
2247
2248/* Simple APIs from mfdrv/graphics.c
2249 */
2250
2251static void test_mf_Graphics(void)
2252{
2253 HDC hdcMetafile;
2254 HMETAFILE hMetafile;
2255 POINT oldpoint;
2256 BOOL ret;
2257
2258 hdcMetafile = CreateMetaFileA(NULL);
2259 ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %d\n", GetLastError());
2260 trace("hdcMetafile %p\n", hdcMetafile);
2261
2262 ret = MoveToEx(hdcMetafile, 1, 1, NULL);
2263 ok( ret, "MoveToEx error %d.\n", GetLastError());
2264 ret = LineTo(hdcMetafile, 2, 2);
2265 ok( ret, "LineTo error %d.\n", GetLastError());
2266 ret = MoveToEx(hdcMetafile, 1, 1, &oldpoint);
2267 ok( ret, "MoveToEx error %d.\n", GetLastError());
2268
2269/* oldpoint gets garbage under Win XP, so the following test would
2270 * work under Wine but fails under Windows:
2271 *
2272 * ok((oldpoint.x == 2) && (oldpoint.y == 2),
2273 * "MoveToEx: (x, y) = (%ld, %ld), should be (2, 2).\n",
2274 * oldpoint.x, oldpoint.y);
2275 */
2276
2277 ret = Ellipse(hdcMetafile, 0, 0, 2, 2);
2278 ok( ret, "Ellipse error %d.\n", GetLastError());
2279
2280 hMetafile = CloseMetaFile(hdcMetafile);
2281 ok(hMetafile != 0, "CloseMetaFile error %d\n", GetLastError());
2282 ok(!GetObjectType(hdcMetafile), "CloseMetaFile has to destroy metafile hdc\n");
2283
2284 if (compare_mf_bits (hMetafile, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS),
2285 "mf_Graphics") != 0)
2286 {
2287 dump_mf_bits(hMetafile, "mf_Graphics");
2288 EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
2289 }
2290
2291 ret = DeleteMetaFile(hMetafile);
2292 ok( ret, "DeleteMetaFile(%p) error %d\n",
2293 hMetafile, GetLastError());
2294}
2295
2296static void test_mf_PatternBrush(void)
2297{
2298 HDC hdcMetafile;
2299 HMETAFILE hMetafile;
2300 LOGBRUSH *orig_lb;
2301 HBRUSH hBrush;
2302 BOOL ret;
2303
2304 orig_lb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LOGBRUSH));
2305
2306 orig_lb->lbStyle = BS_PATTERN;
2307 orig_lb->lbColor = RGB(0, 0, 0);
2308 orig_lb->lbHatch = (ULONG_PTR)CreateBitmap (8, 8, 1, 1, SAMPLE_PATTERN_BRUSH);
2309 ok((HBITMAP)orig_lb->lbHatch != NULL, "CreateBitmap error %d.\n", GetLastError());
2310
2311 hBrush = CreateBrushIndirect (orig_lb);
2312 ok(hBrush != 0, "CreateBrushIndirect error %d\n", GetLastError());
2313
2314 hdcMetafile = CreateMetaFileA(NULL);
2315 ok(hdcMetafile != 0, "CreateMetaFileA error %d\n", GetLastError());
2316 trace("hdcMetafile %p\n", hdcMetafile);
2317
2318 hBrush = SelectObject(hdcMetafile, hBrush);
2319 ok(hBrush != 0, "SelectObject error %d.\n", GetLastError());
2320
2321 hMetafile = CloseMetaFile(hdcMetafile);
2322 ok(hMetafile != 0, "CloseMetaFile error %d\n", GetLastError());
2323 ok(!GetObjectType(hdcMetafile), "CloseMetaFile has to destroy metafile hdc\n");
2324
2326 "mf_Pattern_Brush") != 0)
2327 {
2328 dump_mf_bits(hMetafile, "mf_Pattern_Brush");
2329 EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
2330 }
2331
2332 ret = DeleteMetaFile(hMetafile);
2333 ok( ret, "DeleteMetaFile error %d\n", GetLastError());
2334 ret = DeleteObject(hBrush);
2335 ok( ret, "DeleteObject(HBRUSH) error %d\n", GetLastError());
2336 ret = DeleteObject((HBITMAP)orig_lb->lbHatch);
2337 ok( ret, "DeleteObject(HBITMAP) error %d\n",
2338 GetLastError());
2339 HeapFree (GetProcessHeap(), 0, orig_lb);
2340}
2341
2342static void test_mf_DCBrush(void)
2343{
2344 HDC hdcMetafile;
2345 HMETAFILE hMetafile;
2346 HBRUSH hBrush;
2347 HPEN hPen;
2348 BOOL ret;
2350
2351 if (!pSetDCBrushColor || !pSetDCPenColor)
2352 {
2353 win_skip( "SetDCBrush/PenColor not supported\n" );
2354 return;
2355 }
2356
2357 hdcMetafile = CreateMetaFileA(NULL);
2358 ok( hdcMetafile != 0, "CreateMetaFileA failed\n" );
2359
2360 hBrush = SelectObject(hdcMetafile, GetStockObject(DC_BRUSH));
2361 ok(hBrush != 0, "SelectObject error %d.\n", GetLastError());
2362
2363 hPen = SelectObject(hdcMetafile, GetStockObject(DC_PEN));
2364 ok(hPen != 0, "SelectObject error %d.\n", GetLastError());
2365
2366 color = pSetDCBrushColor( hdcMetafile, RGB(0x55,0x55,0x55) );
2367 ok( color == CLR_INVALID, "SetDCBrushColor returned %x\n", color );
2368
2369 color = pSetDCPenColor( hdcMetafile, RGB(0x33,0x44,0x55) );
2370 ok( color == CLR_INVALID, "SetDCPenColor returned %x\n", color );
2371
2372 Rectangle( hdcMetafile, 10, 10, 20, 20 );
2373
2374 color = pSetDCBrushColor( hdcMetafile, RGB(0x12,0x34,0x56) );
2375 ok( color == CLR_INVALID, "SetDCBrushColor returned %x\n", color );
2376
2377 hMetafile = CloseMetaFile(hdcMetafile);
2378 ok( hMetafile != 0, "CloseMetaFile failed\n" );
2379
2380 if (compare_mf_bits(hMetafile, MF_DCBRUSH_BITS, sizeof(MF_DCBRUSH_BITS), "mf_DCBrush") != 0)
2381 {
2382 dump_mf_bits(hMetafile, "mf_DCBrush");
2383 EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
2384 }
2385 ret = DeleteMetaFile(hMetafile);
2386 ok(ret, "DeleteMetaFile(%p) error %d\n", hMetafile, GetLastError());
2387}
2388
2390{
2391 HDC hdcMetafile;
2392 HMETAFILE hMetafile;
2393 BOOL ret;
2394 static const INT dx[4] = { 3, 5, 8, 12 };
2395
2396 hdcMetafile = CreateMetaFileA(NULL);
2397 ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %d\n", GetLastError());
2398 trace("hdcMetafile %p\n", hdcMetafile);
2399
2400 ret = BeginPath(hdcMetafile);
2401 ok(!ret, "BeginPath on metafile DC should fail\n");
2402
2403 ret = ExtTextOutA(hdcMetafile, 11, 22, 0, NULL, "Test", 4, dx);
2404 ok(ret, "ExtTextOut error %d\n", GetLastError());
2405
2406 ret = EndPath(hdcMetafile);
2407 ok(!ret, "EndPath on metafile DC should fail\n");
2408
2409 hMetafile = CloseMetaFile(hdcMetafile);
2410 ok(hMetafile != 0, "CloseMetaFile error %d\n", GetLastError());
2411
2413 "mf_TextOut_on_path") != 0)
2414 {
2415 dump_mf_bits(hMetafile, "mf_TextOut_on_path");
2416 EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
2417 }
2418
2419 ret = DeleteMetaFile(hMetafile);
2420 ok(ret, "DeleteMetaFile(%p) error %d\n", hMetafile, GetLastError());
2421}
2422
2424{
2425 HWND hwnd;
2426 HDC hdcDisplay, hdcMetafile;
2427 HENHMETAFILE hMetafile;
2428 BOOL ret;
2429 LOGFONTA lf;
2430 HFONT hFont;
2431 static const INT dx[4] = { 3, 5, 8, 12 };
2432
2433 /* Win9x doesn't play EMFs on invisible windows */
2434 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
2435 0, 0, 200, 200, 0, 0, 0, NULL);
2436 ok(hwnd != 0, "CreateWindowExA error %d\n", GetLastError());
2437
2438 hdcDisplay = GetDC(hwnd);
2439 ok(hdcDisplay != 0, "GetDC error %d\n", GetLastError());
2440
2441 /* with default font */
2442 ret = BeginPath(hdcDisplay);
2443 ok(ret, "BeginPath error %d\n", GetLastError());
2444
2445 ret = ExtTextOutA(hdcDisplay, 11, 22, 0, NULL, "Test", 4, dx);
2446 ok(ret, "ExtTextOut error %d\n", GetLastError());
2447
2448 ret = EndPath(hdcDisplay);
2449 ok(ret, "EndPath error %d\n", GetLastError());
2450
2451 ret = GetPath(hdcDisplay, NULL, NULL, 0);
2452 ok(!ret, "expected 0, got %d\n", ret);
2453
2454 hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
2455 ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
2456
2457 ret = BeginPath(hdcMetafile);
2458 ok(ret, "BeginPath error %d\n", GetLastError());
2459
2460 ret = ExtTextOutA(hdcMetafile, 11, 22, 0, NULL, "Test", 4, dx);
2461 ok(ret, "ExtTextOut error %d\n", GetLastError());
2462
2463 ret = EndPath(hdcMetafile);
2464 ok(ret, "EndPath error %d\n", GetLastError());
2465
2466 ret = GetPath(hdcMetafile, NULL, NULL, 0);
2467 ok(!ret, "expected 0, got %d\n", ret);
2468
2469 hMetafile = CloseEnhMetaFile(hdcMetafile);
2470 ok(hMetafile != 0, "CloseEnhMetaFile error %d\n", GetLastError());
2471
2472 /* this doesn't succeed yet: EMF has correct size, all EMF records
2473 * are there, but their contents don't match for different reasons.
2474 */
2476 "emf_TextOut_on_path", FALSE) != 0)
2477 {
2478 dump_emf_bits(hMetafile, "emf_TextOut_on_path");
2479 dump_emf_records(hMetafile, "emf_TextOut_on_path");
2480 }
2481
2482 ret = DeleteEnhMetaFile(hMetafile);
2483 ok(ret, "DeleteEnhMetaFile error %d\n", GetLastError());
2484
2485 /* with outline font */
2486 memset(&lf, 0, sizeof(lf));
2489 lf.lfWeight = FW_DONTCARE;
2490 lf.lfHeight = 7;
2492 lstrcpyA(lf.lfFaceName, "Tahoma");
2494 ok(hFont != 0, "CreateFontIndirectA error %d\n", GetLastError());
2495 hFont = SelectObject(hdcDisplay, hFont);
2496
2497 ret = BeginPath(hdcDisplay);
2498 ok(ret, "BeginPath error %d\n", GetLastError());
2499
2500 ret = ExtTextOutA(hdcDisplay, 11, 22, 0, NULL, "Test", 4, dx);
2501 ok(ret, "ExtTextOut error %d\n", GetLastError());
2502
2503 ret = EndPath(hdcDisplay);
2504 ok(ret, "EndPath error %d\n", GetLastError());
2505
2506 ret = GetPath(hdcDisplay, NULL, NULL, 0);
2507 ok(ret != 0, "expected != 0\n");
2508
2509 SelectObject(hdcDisplay, hFont);
2510
2511 hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
2512 ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
2513
2514 hFont = SelectObject(hdcMetafile, hFont);
2515
2516 ret = BeginPath(hdcMetafile);
2517 ok(ret, "BeginPath error %d\n", GetLastError());
2518
2519 ret = ExtTextOutA(hdcMetafile, 11, 22, 0, NULL, "Test", 4, dx);
2520 ok(ret, "ExtTextOut error %d\n", GetLastError());
2521
2522 ret = EndPath(hdcMetafile);
2523 ok(ret, "EndPath error %d\n", GetLastError());
2524
2525 ret = GetPath(hdcMetafile, NULL, NULL, 0);
2526 ok(!ret, "expected 0, got %d\n", ret);
2527
2528 hFont = SelectObject(hdcMetafile, hFont);
2530
2531 hMetafile = CloseEnhMetaFile(hdcMetafile);
2532 ok(hMetafile != 0, "CloseEnhMetaFile error %d\n", GetLastError());
2533
2535 "emf_TextOut_on_path", FALSE) != 0)
2536 {
2537 dump_emf_bits(hMetafile, "emf_TextOut_outline_on_path");
2538 dump_emf_records(hMetafile, "emf_TextOut_outline_on_path");
2539 }
2540
2541 ret = DeleteEnhMetaFile(hMetafile);
2542 ok(ret, "DeleteEnhMetaFile error %d\n", GetLastError());
2543
2544 ret = ReleaseDC(hwnd, hdcDisplay);
2545 ok(ret, "ReleaseDC error %d\n", GetLastError());
2547}
2548
2549static const unsigned char EMF_CLIPPING[] =
2550{
2551 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
2552 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2553 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
2554 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2555 0x1a, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
2556 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
2557 0x04, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
2558 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2559 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2560 0x80, 0x07, 0x00, 0x00, 0xb0, 0x04, 0x00, 0x00,
2561 0xfc, 0x01, 0x00, 0x00, 0x3e, 0x01, 0x00, 0x00,
2562 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2563 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
2564 0x30, 0xda, 0x04, 0x00, 0x36, 0x00, 0x00, 0x00,
2565 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
2566 0x01, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00,
2567 0x40, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
2568 0x05, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
2569 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
2570 0x10, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
2571 0x64, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
2572 0x00, 0x04, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
2573 0x64, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
2574 0x00, 0x04, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00,
2575 0x08, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
2576 0x18, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
2577 0x64, 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00,
2578 0xff, 0x03, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
2579 0x08, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00,
2580 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
2581 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
2582 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
2583 0x14, 0x00, 0x00, 0x00
2584};
2585
2586static void translate( POINT *pt, UINT count, const XFORM *xform )
2587{
2588 while (count--)
2589 {
2590 FLOAT x = (FLOAT)pt->x;
2591 FLOAT y = (FLOAT)pt->y;
2592 pt->x = (LONG)floor( x * xform->eM11 + y * xform->eM21 + xform->eDx + 0.5 );
2593 pt->y = (LONG)floor( x * xform->eM12 + y * xform->eM22 + xform->eDy + 0.5 );
2594 pt++;
2595 }
2596}
2597
2598/* Compare rectangles allowing rounding errors */
2599static BOOL is_equal_rect(const RECT *rc1, const RECT *rc2)
2600{
2601 return abs(rc1->left - rc2->left) <= 1 &&
2602 abs(rc1->top - rc2->top) <= 1 &&
2603 abs(rc1->right - rc2->right) <= 1 &&
2604 abs(rc1->bottom - rc2->bottom) <= 1;
2605}
2606
2608 const ENHMETARECORD *emr, int n_objs, LPARAM param)
2609{
2610 if (emr->iType == EMR_EXTSELECTCLIPRGN)
2611 {
2612 const EMREXTSELECTCLIPRGN *clip = (const EMREXTSELECTCLIPRGN *)emr;
2613 union _rgn
2614 {
2615 RGNDATA data;
2616 char buf[sizeof(RGNDATAHEADER) + sizeof(RECT)];
2617 };
2618 const union _rgn *rgn1;
2619 union _rgn rgn2;
2620 RECT rect, rc_transformed;
2621 const RECT *rc = (const RECT *)param;
2622 HRGN hrgn;
2623 XFORM xform;
2624 INT ret;
2625 BOOL is_win9x;
2626
2627 trace("EMR_EXTSELECTCLIPRGN: cbRgnData %#x, iMode %u\n",
2628 clip->cbRgnData, clip->iMode);
2629
2630 ok(clip->iMode == RGN_COPY, "expected RGN_COPY, got %u\n", clip->iMode);
2631 ok(clip->cbRgnData >= sizeof(RGNDATAHEADER) + sizeof(RECT),
2632 "too small data block: %u bytes\n", clip->cbRgnData);
2633 if (clip->cbRgnData < sizeof(RGNDATAHEADER) + sizeof(RECT))
2634 return 0;
2635
2636 rgn1 = (const union _rgn *)clip->RgnData;
2637
2638 trace("size %u, type %u, count %u, rgn size %u, bound %s\n",
2639 rgn1->data.rdh.dwSize, rgn1->data.rdh.iType,
2640 rgn1->data.rdh.nCount, rgn1->data.rdh.nRgnSize,
2641 wine_dbgstr_rect(&rgn1->data.rdh.rcBound));
2642
2643 ok(EqualRect(&rgn1->data.rdh.rcBound, rc), "rects don't match\n");
2644
2645 rect = *(const RECT *)rgn1->data.Buffer;
2646 trace("rect %s\n", wine_dbgstr_rect(&rect));
2647 ok(EqualRect(&rect, rc), "rects don't match\n");
2648
2649 ok(rgn1->data.rdh.dwSize == sizeof(rgn1->data.rdh), "expected sizeof(rdh), got %u\n", rgn1->data.rdh.dwSize);
2650 ok(rgn1->data.rdh.iType == RDH_RECTANGLES, "expected RDH_RECTANGLES, got %u\n", rgn1->data.rdh.iType);
2651 ok(rgn1->data.rdh.nCount == 1, "expected 1, got %u\n", rgn1->data.rdh.nCount);
2652 ok(rgn1->data.rdh.nRgnSize == sizeof(RECT) ||
2653 broken(rgn1->data.rdh.nRgnSize == 168), /* NT4 */
2654 "expected sizeof(RECT), got %u\n", rgn1->data.rdh.nRgnSize);
2655
2656 hrgn = CreateRectRgn(0, 0, 0, 0);
2657
2658 memset(&xform, 0, sizeof(xform));
2659 SetLastError(0xdeadbeef);
2660 ret = GetWorldTransform(hdc, &xform);
2662 if (!is_win9x)
2663 ok(ret, "GetWorldTransform error %u\n", GetLastError());
2664
2665 trace("xform.eM11 %f, xform.eM22 %f\n", xform.eM11, xform.eM22);
2666
2667 ret = GetClipRgn(hdc, hrgn);
2668 ok(ret == 0, "GetClipRgn returned %d, expected 0\n", ret);
2669
2670 PlayEnhMetaFileRecord(hdc, handle_table, emr, n_objs);
2671
2672 ret = GetClipRgn(hdc, hrgn);
2673 ok(ret == 1, "GetClipRgn returned %d, expected 1\n", ret);
2674
2675 /* Win9x returns empty clipping region */
2676 if (is_win9x) return 1;
2677
2678 ret = GetRegionData(hrgn, 0, NULL);
2679 ok(ret == sizeof(rgn2.data.rdh) + sizeof(RECT), "expected sizeof(rgn), got %u\n", ret);
2680
2681 ret = GetRegionData(hrgn, sizeof(rgn2), &rgn2.data);
2682 ok(ret == sizeof(rgn2), "expected sizeof(rgn2), got %u\n", ret);
2683
2684 trace("size %u, type %u, count %u, rgn size %u, bound %s\n", rgn2.data.rdh.dwSize,
2685 rgn2.data.rdh.iType, rgn2.data.rdh.nCount, rgn2.data.rdh.nRgnSize,
2686 wine_dbgstr_rect(&rgn2.data.rdh.rcBound));
2687
2688 rect = rgn2.data.rdh.rcBound;
2689 rc_transformed = *rc;
2690 translate((POINT *)&rc_transformed, 2, &xform);
2691 trace("transformed %s\n", wine_dbgstr_rect(&rc_transformed));
2692 ok(is_equal_rect(&rect, &rc_transformed), "rects don't match\n");
2693
2694 rect = *(const RECT *)rgn2.data.Buffer;
2695 trace("rect %s\n", wine_dbgstr_rect(&rect));
2696 rc_transformed = *rc;
2697 translate((POINT *)&rc_transformed, 2, &xform);
2698 trace("transformed %s\n", wine_dbgstr_rect(&rc_transformed));
2699 ok(is_equal_rect(&rect, &rc_transformed), "rects don't match\n");
2700
2701 ok(rgn2.data.rdh.dwSize == sizeof(rgn1->data.rdh), "expected sizeof(rdh), got %u\n", rgn2.data.rdh.dwSize);
2702 ok(rgn2.data.rdh.iType == RDH_RECTANGLES, "expected RDH_RECTANGLES, got %u\n", rgn2.data.rdh.iType);
2703 ok(rgn2.data.rdh.nCount == 1, "expected 1, got %u\n", rgn2.data.rdh.nCount);
2704 ok(rgn2.data.rdh.nRgnSize == sizeof(RECT) ||
2705 broken(rgn2.data.rdh.nRgnSize == 168), /* NT4 */
2706 "expected sizeof(RECT), got %u\n", rgn2.data.rdh.nRgnSize);
2707
2709 }
2710 return 1;
2711}
2712
2713static void test_emf_clipping(void)
2714{
2715 static const RECT rc = { 0, 0, 100, 100 };
2716 RECT rc_clip = { 100, 100, 1024, 1024 };
2717 HWND hwnd;
2718 HDC hdc;
2719 HENHMETAFILE hemf;
2720 HRGN hrgn;
2721 INT ret;
2722 RECT rc_res, rc_sclip;
2723
2724 SetLastError(0xdeadbeef);
2726 ok(hdc != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
2727
2728 /* Need to write something to the emf, otherwise Windows won't play it back */
2729 LineTo(hdc, 1, 1);
2730
2731 hrgn = CreateRectRgn(rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
2733 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
2734
2735 BeginPath(hdc);
2736 Rectangle(hdc, rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
2737 EndPath(hdc);
2739 ok(ret, "SelectClipPath error %d\n", GetLastError());
2740
2741 SetLastError(0xdeadbeef);
2742 hemf = CloseEnhMetaFile(hdc);
2743 ok(hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError());
2744
2745 if (compare_emf_bits(hemf, EMF_CLIPPING, sizeof(EMF_CLIPPING),
2746 "emf_clipping", FALSE) != 0)
2747 {
2748 dump_emf_bits(hemf, "emf_clipping");
2749 dump_emf_records(hemf, "emf_clipping");
2750 }
2751
2753
2754 /* Win9x doesn't play EMFs on invisible windows */
2755 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
2756 0, 0, 200, 200, 0, 0, 0, NULL);
2757 ok(hwnd != 0, "CreateWindowExA error %d\n", GetLastError());
2758
2759 hdc = GetDC(hwnd);
2760
2761 ret = EnumEnhMetaFile(hdc, hemf, clip_emf_enum_proc, &rc_clip, &rc);
2762 ok(ret, "EnumEnhMetaFile error %d\n", GetLastError());
2763
2764 DeleteEnhMetaFile(hemf);
2765 ReleaseDC(hwnd, hdc);
2767
2769
2771 hrgn = CreateRectRgn(rc_sclip.left, rc_sclip.top, rc_sclip.right, rc_sclip.bottom);
2773 SetRect(&rc_res, -1, -1, -1, -1);
2774 ret = GetClipBox(hdc, &rc_res);
2775 ok(ret == SIMPLEREGION, "got %d\n", ret);
2776 ok(EqualRect(&rc_res, &rc_sclip), "expected %s, got %s\n", wine_dbgstr_rect(&rc_sclip),
2777 wine_dbgstr_rect(&rc_res));
2778
2779 OffsetRect(&rc_sclip, -100, -100);
2780 ret = OffsetClipRgn(hdc, -100, -100);
2781 ok(ret == SIMPLEREGION, "got %d\n", ret);
2782 SetRect(&rc_res, -1, -1, -1, -1);
2783 ret = GetClipBox(hdc, &rc_res);
2784 ok(ret == SIMPLEREGION, "got %d\n", ret);
2785 ok(EqualRect(&rc_res, &rc_sclip), "expected %s, got %s\n", wine_dbgstr_rect(&rc_sclip),
2786 wine_dbgstr_rect(&rc_res));
2787
2788 ret = IntersectClipRect(hdc, 0, 0, 100, 100);
2789 ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION) /* XP */, "got %d\n", ret);
2790 if (ret == COMPLEXREGION)
2791 {
2792 /* XP returns COMPLEXREGION although region contains only 1 rect */
2793 ret = GetClipRgn(hdc, hrgn);
2794 ok(ret == 1, "expected 1, got %d\n", ret);
2796 ok(ret == 1, "expected 1, got %d\n", ret);
2797 }
2798 SetRect(&rc_res, -1, -1, -1, -1);
2799 ret = GetClipBox(hdc, &rc_res);
2800 ok(ret == SIMPLEREGION, "got %d\n", ret);
2801 ok(EqualRect(&rc_res, &rc), "expected %s, got %s\n", wine_dbgstr_rect(&rc),
2802 wine_dbgstr_rect(&rc_res));
2803
2804 SetRect(&rc_sclip, 0, 0, 100, 50);
2805 ret = ExcludeClipRect(hdc, 0, 50, 100, 100);
2806 ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION) /* XP */, "got %d\n", ret);
2807 if (ret == COMPLEXREGION)
2808 {
2809 /* XP returns COMPLEXREGION although region contains only 1 rect */
2810 ret = GetClipRgn(hdc, hrgn);
2811 ok(ret == 1, "expected 1, got %d\n", ret);
2813 ok(ret == 1, "expected 1, got %d\n", ret);
2814 }
2815 SetRect(&rc_res, -1, -1, -1, -1);
2816 ret = GetClipBox(hdc, &rc_res);
2817 ok(ret == SIMPLEREGION, "got %d\n", ret);
2818 ok(EqualRect(&rc_res, &rc_sclip), "expected %s, got %s\n", wine_dbgstr_rect(&rc_sclip),
2819 wine_dbgstr_rect(&rc_res));
2820
2821 hemf = CloseEnhMetaFile(hdc);
2822 DeleteEnhMetaFile(hemf);
2824}
2825
2826static const unsigned char MF_CLIP_BITS[] = {
2827 /* METAHEADER */
2828 0x01, 0x00, /* mtType */
2829 0x09, 0x00, /* mtHeaderSize */
2830 0x00, 0x03, /* mtVersion */
2831 0x32, 0x00, 0x00, 0x00, /* mtSize */
2832 0x01, 0x00, /* mtNoObjects */
2833 0x14, 0x00, 0x00, 0x00, /* mtMaxRecord (size in words of longest record) */
2834 0x00, 0x00, /* reserved */
2835
2836 /* METARECORD for CreateRectRgn(0x11, 0x22, 0x33, 0x44) */
2837 0x14, 0x00, 0x00, 0x00, /* rdSize in words */
2838 0xff, 0x06, /* META_CREATEREGION */
2839 0x00, 0x00, 0x06, 0x00, 0xf6, 0x02, 0x00, 0x00,
2840 0x24, 0x00, 0x01, 0x00, 0x02, 0x00, 0x11, 0x00,
2841 0x22, 0x00, 0x33, 0x00, 0x44, 0x00, 0x02, 0x00,
2842 0x22, 0x00, 0x44, 0x00, 0x11, 0x00, 0x33, 0x00,
2843 0x02, 0x00,
2844
2845 /* METARECORD for SelectObject */
2846 0x04, 0x00, 0x00, 0x00,
2847 0x2d, 0x01, /* META_SELECTOBJECT (not META_SELECTCLIPREGION?!) */
2848 0x00, 0x00,
2849
2850 /* METARECORD */
2851 0x04, 0x00, 0x00, 0x00,
2852 0xf0, 0x01, /* META_DELETEOBJECT */
2853 0x00, 0x00,
2854
2855 /* METARECORD for MoveTo(1,0x30) */
2856 0x05, 0x00, 0x00, 0x00, /* rdSize in words */
2857 0x14, 0x02, /* META_MOVETO */
2858 0x30, 0x00, /* y */
2859 0x01, 0x00, /* x */
2860
2861 /* METARECORD for LineTo(0x20, 0x30) */
2862 0x05, 0x00, 0x00, 0x00, /* rdSize in words */
2863 0x13, 0x02, /* META_LINETO */
2864 0x30, 0x00, /* y */
2865 0x20, 0x00, /* x */
2866
2867 /* EOF */
2868 0x03, 0x00, 0x00, 0x00,
2869 0x00, 0x00
2870};
2871
2874
2876 METARECORD *mr, int n_objs, LPARAM param)
2877{
2878 switch (mr->rdFunction) {
2881 break;
2882 case META_SELECTOBJECT:
2884 break;
2885 }
2886 return 1;
2887}
2888
2889static void test_mf_clipping(void)
2890{
2891 /* left top right bottom */
2892 static RECT rc_clip = { 0x11, 0x22, 0x33, 0x44 };
2893 HWND hwnd;
2894 HDC hdc;
2895 HMETAFILE hmf;
2896 HRGN hrgn;
2897 INT ret;
2898
2899 SetLastError(0xdeadbeef);
2901 ok(hdc != 0, "CreateMetaFileA error %d\n", GetLastError());
2902
2903 hrgn = CreateRectRgn(rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
2905 /* Seems like it should be SIMPLEREGION, but windows returns NULLREGION? */
2906 ok(ret == NULLREGION, "expected NULLREGION, got %d\n", ret);
2907
2908 /* Draw a line that starts off left of the clip region and ends inside it */
2909 MoveToEx(hdc, 0x1, 0x30, NULL);
2910 LineTo(hdc, 0x20, 0x30);
2911
2912 SetLastError(0xdeadbeef);
2913 hmf = CloseMetaFile(hdc);
2914 ok(hmf != 0, "CloseMetaFile error %d\n", GetLastError());
2915
2916 if (compare_mf_bits(hmf, MF_CLIP_BITS, sizeof(MF_CLIP_BITS),
2917 "mf_clipping") != 0)
2918 {
2919 dump_mf_bits(hmf, "mf_clipping");
2920 }
2921
2923
2924 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
2925 0, 0, 200, 200, 0, 0, 0, NULL);
2926 ok(hwnd != 0, "CreateWindowExA error %d\n", GetLastError());
2927
2928 hdc = GetDC(hwnd);
2929
2930 ret = EnumMetaFile(hdc, hmf, clip_mf_enum_proc, (LPARAM)&rc_clip);
2931 ok(ret, "EnumMetaFile error %d\n", GetLastError());
2932
2933 /* Oddly, windows doesn't seem to use META_SELECTCLIPREGION */
2935 "expected 0 selectclipregion, saw %d\n", clip_mf_enum_proc_seen_selectclipregion);
2937 "expected 1 selectobject, saw %d\n", clip_mf_enum_proc_seen_selectobject);
2938
2939 DeleteMetaFile(hmf);
2940 ReleaseDC(hwnd, hdc);
2942}
2943
2944static const unsigned char MF_PATH_BITS[] =
2945{
2946 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x2c, 0x00,
2947 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
2948 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x02,
2949 0x32, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00,
2950 0x13, 0x02, 0x96, 0x00, 0x32, 0x00, 0x05, 0x00,
2951 0x00, 0x00, 0x13, 0x02, 0x96, 0x00, 0x96, 0x00,
2952 0x05, 0x00, 0x00, 0x00, 0x13, 0x02, 0x32, 0x00,
2953 0x96, 0x00, 0x05, 0x00, 0x00, 0x00, 0x13, 0x02,
2954 0x32, 0x00, 0x32, 0x00, 0x07, 0x00, 0x00, 0x00,
2955 0x1b, 0x04, 0x14, 0x00, 0x14, 0x00, 0x0a, 0x00,
2956 0x0a, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
2957};
2958
2959static void test_mf_GetPath(void)
2960{
2961 HDC hdc;
2962 HMETAFILE hmf;
2963 BOOL ret;
2964 int size;
2965
2966 SetLastError(0xdeadbeef);
2968 ok(hdc != 0, "CreateMetaFileA error %d\n", GetLastError());
2969
2970 ret = BeginPath(hdc);
2971 ok(!ret, "BeginPath on metafile DC should fail\n");
2972 ret = MoveToEx(hdc, 50, 50, NULL);
2973 ok( ret, "MoveToEx error %d.\n", GetLastError());
2974 ret = LineTo(hdc, 50, 150);
2975 ok( ret, "LineTo error %d.\n", GetLastError());
2976 ret = LineTo(hdc, 150, 150);
2977 ok( ret, "LineTo error %d.\n", GetLastError());
2978 ret = LineTo(hdc, 150, 50);
2979 ok( ret, "LineTo error %d.\n", GetLastError());
2980 ret = LineTo(hdc, 50, 50);
2981 ok( ret, "LineTo error %d.\n", GetLastError());
2982 Rectangle(hdc, 10, 10, 20, 20);
2983 EndPath(hdc);
2984
2985 size = GetPath(hdc, NULL, NULL, 0);
2986 ok( size == -1, "GetPath returned %d.\n", size);
2987
2988 hmf = CloseMetaFile(hdc);
2989 ok(hmf != 0, "CloseMetaFile error %d\n", GetLastError());
2990
2991 if (compare_mf_bits (hmf, MF_PATH_BITS, sizeof(MF_PATH_BITS), "mf_GetPath") != 0)
2992 {
2993 dump_mf_bits(hmf, "mf_GetPath");
2994 EnumMetaFile(0, hmf, mf_enum_proc, 0);
2995 }
2996
2997 ret = DeleteMetaFile(hmf);
2998 ok( ret, "DeleteMetaFile error %d\n", GetLastError());
2999}
3000
3001static INT CALLBACK EmfEnumProc(HDC hdc, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR, INT nObj, LPARAM lpData)
3002{
3003 LPMETAFILEPICT lpMFP = (LPMETAFILEPICT)lpData;
3004 POINT mapping[2] = { { 0, 0 }, { 10, 10 } };
3005 /* When using MM_TEXT Win9x does not update the mapping mode
3006 * until a record is played which actually outputs something */
3007 PlayEnhMetaFileRecord(hdc, lpHTable, lpEMFR, nObj);
3008 LPtoDP(hdc, mapping, 2);
3009 trace("EMF record: iType %d, nSize %d, (%d,%d)-(%d,%d)\n",
3010 lpEMFR->iType, lpEMFR->nSize,
3011 mapping[0].x, mapping[0].y, mapping[1].x, mapping[1].y);
3012
3013 if (lpEMFR->iType == EMR_LINETO)
3014 {
3015 INT x0, y0, x1, y1;
3016 if (!lpMFP || lpMFP->mm == MM_TEXT)
3017 {
3018 x0 = 0;
3019 y0 = 0;
3020 x1 = (INT)floor(10 * 100.0 / LINE_X + 0.5);
3021 y1 = (INT)floor(10 * 100.0 / LINE_Y + 0.5);
3022 }
3023 else
3024 {
3025 ok(lpMFP->mm == MM_ANISOTROPIC, "mm=%d\n", lpMFP->mm);
3026
3031 }
3032 ok(mapping[0].x == x0 && mapping[0].y == y0 && mapping[1].x == x1 && mapping[1].y == y1,
3033 "(%d,%d)->(%d,%d), expected (%d,%d)->(%d,%d)\n",
3034 mapping[0].x, mapping[0].y, mapping[1].x, mapping[1].y,
3035 x0, y0, x1, y1);
3036 }
3037 return TRUE;
3038}
3039
3040static HENHMETAFILE create_converted_emf(const METAFILEPICT *mfp)
3041{
3042 HDC hdcMf;
3043 HMETAFILE hmf;
3044 HENHMETAFILE hemf;
3045 BOOL ret;
3046 UINT size;
3047 LPBYTE pBits;
3048
3049 hdcMf = CreateMetaFileA(NULL);
3050 ok(hdcMf != NULL, "CreateMetaFile failed with error %d\n", GetLastError());
3051 ret = LineTo(hdcMf, (INT)LINE_X, (INT)LINE_Y);
3052 ok(ret, "LineTo failed with error %d\n", GetLastError());
3053 hmf = CloseMetaFile(hdcMf);
3054 ok(hmf != NULL, "CloseMetaFile failed with error %d\n", GetLastError());
3055
3056 if (compare_mf_bits (hmf, MF_LINETO_BITS, sizeof(MF_LINETO_BITS), "mf_LineTo") != 0)
3057 {
3058 dump_mf_bits(hmf, "mf_LineTo");
3059 EnumMetaFile(0, hmf, mf_enum_proc, 0);
3060 }
3061
3062 size = GetMetaFileBitsEx(hmf, 0, NULL);
3063 ok(size, "GetMetaFileBitsEx failed with error %d\n", GetLastError());
3064 pBits = HeapAlloc(GetProcessHeap(), 0, size);
3065 GetMetaFileBitsEx(hmf, size, pBits);
3066 DeleteMetaFile(hmf);
3067 hemf = SetWinMetaFileBits(size, pBits, NULL, mfp);
3068 HeapFree(GetProcessHeap(), 0, pBits);
3069 return hemf;
3070}
3071
3072static void test_mf_conversions(void)
3073{
3074 trace("Testing MF->EMF conversion (MM_ANISOTROPIC)\n");
3075 {
3077 HENHMETAFILE hemf;
3078 METAFILEPICT mfp;
3079 RECT rect = { 0, 0, 100, 100 };
3080 mfp.mm = MM_ANISOTROPIC;
3081 mfp.xExt = 100;
3082 mfp.yExt = 100;
3083 mfp.hMF = NULL;
3084 hemf = create_converted_emf(&mfp);
3085
3087 "emf_LineTo MM_ANISOTROPIC", TRUE) != 0)
3088 {
3089 dump_emf_bits(hemf, "emf_LineTo MM_ANISOTROPIC");
3090 dump_emf_records(hemf, "emf_LineTo MM_ANISOTROPIC");
3091 }
3092
3094
3095 DeleteEnhMetaFile(hemf);
3097 }
3098
3099 trace("Testing MF->EMF conversion (MM_TEXT)\n");
3100 {
3102 HENHMETAFILE hemf;
3103 METAFILEPICT mfp;
3104 RECT rect = { 0, 0, 100, 100 };
3105 mfp.mm = MM_TEXT;
3106 mfp.xExt = 0;
3107 mfp.yExt = 0;
3108 mfp.hMF = NULL;
3109 hemf = create_converted_emf(&mfp);
3110
3112 "emf_LineTo MM_TEXT", TRUE) != 0)
3113 {
3114 dump_emf_bits(hemf, "emf_LineTo MM_TEXT");
3115 dump_emf_records(hemf, "emf_LineTo MM_TEXT");
3116 }
3117
3119
3120 DeleteEnhMetaFile(hemf);
3122 }
3123
3124 trace("Testing MF->EMF conversion (NULL mfp)\n");
3125 {
3127 HENHMETAFILE hemf;
3128 RECT rect = { 0, 0, 100, 100 };
3129 hemf = create_converted_emf(NULL);
3130
3132 "emf_LineTo NULL", TRUE) != 0)
3133 {
3134 dump_emf_bits(hemf, "emf_LineTo NULL");
3135 dump_emf_records(hemf, "emf_LineTo NULL");
3136 }
3137
3139
3140 DeleteEnhMetaFile(hemf);
3142 }
3143}
3144
3146 LONG mm, LONG xExt, LONG yExt,
3147 RECTL * rclBounds, RECTL * rclFrame)
3148{
3149 METAFILEPICT mfp;
3150 METAFILEPICT * mfpPtr = NULL;
3151 HENHMETAFILE emf;
3153 UINT res;
3154
3155 if (!mfpIsNull)
3156 {
3157 mfp.mm = mm;
3158 mfp.xExt = xExt;
3159 mfp.yExt = yExt;
3160 mfpPtr = &mfp;
3161 }
3162
3164 ok(emf != NULL, "SetWinMetaFileBits failed\n");
3165 if (!emf) return FALSE;
3167 ok(res != 0, "GetEnhMetaHeader failed\n");
3169 if (!res) return FALSE;
3170
3171 *rclBounds = header.rclBounds;
3172 *rclFrame = header.rclFrame;
3173 return TRUE;
3174}
3175
3177 LONG mm, LONG xExt, LONG yExt,
3178 RECTL * rclBoundsExpected, RECTL * rclFrameExpected)
3179{
3180 RECTL rclBounds, rclFrame;
3181
3182 if (getConvertedFrameAndBounds(buffer_size, buffer, mfpIsNull, mm, xExt, yExt, &rclBounds, &rclFrame))
3183 {
3184 const char * msg;
3185 char buf[64];
3186
3187 if (mfpIsNull)
3188 {
3189 msg = "mfp == NULL";
3190 }
3191 else
3192 {
3193 const char * mm_str;
3194 switch (mm)
3195 {
3196 case MM_ANISOTROPIC: mm_str = "MM_ANISOTROPIC"; break;
3197 case MM_ISOTROPIC: mm_str = "MM_ISOTROPIC"; break;
3198 default: mm_str = "Unexpected";
3199 }
3200 sprintf(buf, "mm=%s, xExt=%d, yExt=%d", mm_str, xExt, yExt);
3201 msg = buf;
3202 }
3203
3204 ok(rclBounds.left == rclBoundsExpected->left, "rclBounds.left: Expected %d, got %d (%s)\n", rclBoundsExpected->left, rclBounds.left, msg);
3205 ok(rclBounds.top == rclBoundsExpected->top, "rclBounds.top: Expected %d, got %d (%s)\n", rclBoundsExpected->top, rclBounds.top, msg);
3206 ok(rclBounds.right == rclBoundsExpected->right, "rclBounds.right: Expected %d, got %d (%s)\n", rclBoundsExpected->right, rclBounds.right, msg);
3207 ok(rclBounds.bottom == rclBoundsExpected->bottom, "rclBounds.bottom: Expected %d, got %d (%s)\n", rclBoundsExpected->bottom, rclBounds.bottom, msg);
3208 ok(rclFrame.left == rclFrameExpected->left, "rclFrame.left: Expected %d, got %d (%s)\n", rclFrameExpected->left, rclFrame.left, msg);
3209 ok(rclFrame.top == rclFrameExpected->top, "rclFrame.top: Expected %d, got %d (%s)\n", rclFrameExpected->top, rclFrame.top, msg);
3210 ok(rclFrame.right == rclFrameExpected->right, "rclFrame.right: Expected %d, got %d (%s)\n", rclFrameExpected->right, rclFrame.right, msg);
3211 ok(rclFrame.bottom == rclFrameExpected->bottom, "rclFrame.bottom: Expected %d, got %d (%s)\n", rclFrameExpected->bottom, rclFrame.bottom, msg);
3212 }
3213}
3214
3216{
3217 HMETAFILE wmf;
3218 HDC wmfDC;
3219 BYTE * buffer;
3221 RECT rect;
3222 UINT res;
3223 RECTL rclBoundsAnisotropic, rclFrameAnisotropic;
3224 RECTL rclBoundsIsotropic, rclFrameIsotropic;
3225 RECTL rclBounds, rclFrame;
3226 HDC dc;
3227 LONG diffx, diffy;
3228
3229 wmfDC = CreateMetaFileA(NULL);
3230 ok(wmfDC != NULL, "CreateMetaFile failed\n");
3231 if (!wmfDC) return;
3232
3233 SetWindowExtEx(wmfDC, 100, 100, NULL);
3234 SetRect(&rect, 0, 0, 50, 50);
3236 wmf = CloseMetaFile(wmfDC);
3237 ok(wmf != NULL, "Metafile creation failed\n");
3238 if (!wmf) return;
3239
3241 ok(buffer_size != 0, "GetMetaFileBitsEx failed\n");
3242 if (buffer_size == 0)
3243 {
3244 DeleteMetaFile(wmf);
3245 return;
3246 }
3247
3249 ok(buffer != NULL, "HeapAlloc failed\n");
3250 if (!buffer)
3251 {
3252 DeleteMetaFile(wmf);
3253 return;
3254 }
3255
3257 ok(res == buffer_size, "GetMetaFileBitsEx failed\n");
3258 DeleteMetaFile(wmf);
3259 if (res != buffer_size)
3260 {
3262 return;
3263 }
3264
3265 /* Get the reference bounds and frame */
3266 getConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, 0, 0, &rclBoundsAnisotropic, &rclFrameAnisotropic);
3267 getConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, 0, 0, &rclBoundsIsotropic, &rclFrameIsotropic);
3268
3269 ok(rclBoundsAnisotropic.left == 0 && rclBoundsAnisotropic.top == 0 &&
3270 rclBoundsIsotropic.left == 0 && rclBoundsIsotropic.top == 0,
3271 "SetWinMetaFileBits: Reference bounds: Left and top bound must be zero\n");
3272
3273 ok(rclBoundsAnisotropic.right >= rclBoundsIsotropic.right, "SetWinMetaFileBits: Reference bounds: Invalid right bound\n");
3274 ok(rclBoundsAnisotropic.bottom >= rclBoundsIsotropic.bottom, "SetWinMetaFileBits: Reference bounds: Invalid bottom bound\n");
3275 diffx = rclBoundsIsotropic.right - rclBoundsIsotropic.bottom;
3276 if (diffx < 0) diffx = -diffx;
3277 ok(diffx <= 1, "SetWinMetaFileBits (MM_ISOTROPIC): Reference bounds are not isotropic\n");
3278
3280
3281 /* Allow 1 mm difference (rounding errors) */
3282 diffx = rclBoundsAnisotropic.right - GetDeviceCaps(dc, HORZRES) / 2;
3283 diffy = rclBoundsAnisotropic.bottom - GetDeviceCaps(dc, VERTRES) / 2;
3284 if (diffx < 0) diffx = -diffx;
3285 if (diffy < 0) diffy = -diffy;
3286 todo_wine
3287 {
3288 ok(diffx <= 1 && diffy <= 1,
3289 "SetWinMetaFileBits (MM_ANISOTROPIC): Reference bounds: The whole device surface must be used (%dx%d), but got (%dx%d)\n",
3290 GetDeviceCaps(dc, HORZRES) / 2, GetDeviceCaps(dc, VERTRES) / 2, rclBoundsAnisotropic.right, rclBoundsAnisotropic.bottom);
3291 }
3292
3293 /* Allow 1 mm difference (rounding errors) */
3294 diffx = rclFrameAnisotropic.right / 100 - GetDeviceCaps(dc, HORZSIZE) / 2;
3295 diffy = rclFrameAnisotropic.bottom / 100 - GetDeviceCaps(dc, VERTSIZE) / 2;
3296 if (diffx < 0) diffx = -diffx;
3297 if (diffy < 0) diffy = -diffy;
3298 todo_wine
3299 {
3300 ok(diffx <= 1 && diffy <= 1,
3301 "SetWinMetaFileBits (MM_ANISOTROPIC): Reference frame: The whole device surface must be used (%dx%d), but got (%dx%d)\n",
3302 GetDeviceCaps(dc, HORZSIZE) / 2, GetDeviceCaps(dc, VERTSIZE) / 2, rclFrameAnisotropic.right / 100, rclFrameAnisotropic.bottom / 100);
3303 }
3304 DeleteDC(dc);
3305
3306 /* If the METAFILEPICT pointer is NULL, the MM_ANISOTROPIC mapping mode and the whole device surface are used */
3307 checkConvertedFrameAndBounds(buffer_size, buffer, TRUE, 0, 0, 0, &rclBoundsAnisotropic, &rclFrameAnisotropic);
3308
3309 /* If xExt or yExt is zero or negative, the whole device surface is used */
3310 checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, 10000, 0, &rclBoundsAnisotropic, &rclFrameAnisotropic);
3311 checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, 10000, 0, &rclBoundsIsotropic, &rclFrameIsotropic);
3312 checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, 0, 10000, &rclBoundsAnisotropic, &rclFrameAnisotropic);
3313 checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, 0, 10000, &rclBoundsIsotropic, &rclFrameIsotropic);
3314 checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, -10000, 0, &rclBoundsAnisotropic, &rclFrameAnisotropic);
3315 checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, -10000, 0, &rclBoundsIsotropic, &rclFrameIsotropic);
3316 checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, 0, -10000, &rclBoundsAnisotropic, &rclFrameAnisotropic);
3317 checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, 0, -10000, &rclBoundsIsotropic, &rclFrameIsotropic);
3318 checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, -10000, 10000, &rclBoundsAnisotropic, &rclFrameAnisotropic);
3319 checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, -10000, 10000, &rclBoundsIsotropic, &rclFrameIsotropic);
3320 checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, 10000, -10000, &rclBoundsAnisotropic, &rclFrameAnisotropic);
3321 checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, 10000, -10000, &rclBoundsIsotropic, &rclFrameIsotropic);
3322
3323 /* MSDN says that negative xExt and yExt values specify a ratio.
3324 Check that this is wrong and the whole device surface is used */
3325 checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, -1000, -100, &rclBoundsAnisotropic, &rclFrameAnisotropic);
3326 checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, -1000, -100, &rclBoundsIsotropic, &rclFrameIsotropic);
3327
3328 /* Ordinary conversions */
3329
3330 if (getConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, 30000, 20000, &rclBounds, &rclFrame))
3331 {
3332 ok(rclFrame.left == 0 && rclFrame.top == 0 && rclFrame.right == 30000 && rclFrame.bottom == 20000,
3333 "SetWinMetaFileBits (MM_ANISOTROPIC): rclFrame contains invalid values\n");
3334 ok(rclBounds.left == 0 && rclBounds.top == 0 && rclBounds.right > rclBounds.bottom,
3335 "SetWinMetaFileBits (MM_ANISOTROPIC): rclBounds contains invalid values\n");
3336 }
3337
3338 if (getConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, 30000, 20000, &rclBounds, &rclFrame))
3339 {
3340 ok(rclFrame.left == 0 && rclFrame.top == 0 && rclFrame.right == 30000 && rclFrame.bottom == 20000,
3341 "SetWinMetaFileBits (MM_ISOTROPIC): rclFrame contains invalid values\n");
3342 ok(rclBounds.left == 0 && rclBounds.top == 0,
3343 "SetWinMetaFileBits (MM_ISOTROPIC): rclBounds contains invalid values\n");
3344
3345 /* Wine has a rounding error */
3346 diffx = rclBounds.right - rclBounds.bottom;
3347 if (diffx < 0) diffx = -diffx;
3348 ok(diffx <= 1, "SetWinMetaFileBits (MM_ISOTROPIC): rclBounds is not isotropic\n");
3349 }
3350
3351 if (getConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_HIMETRIC, 30000, 20000, &rclBounds, &rclFrame))
3352 {
3353 ok(rclFrame.right - rclFrame.left != 30000 && rclFrame.bottom - rclFrame.top != 20000,
3354 "SetWinMetaFileBits: xExt and yExt must be ignored for mapping modes other than MM_ANISOTROPIC and MM_ISOTROPIC\n");
3355 }
3356
3358}
3359
3360static BOOL near_match(int x, int y)
3361{
3362 int epsilon = min(abs(x), abs(y));
3363
3364 epsilon = max(epsilon/100, 2);
3365
3366 if(x < y - epsilon || x > y + epsilon) return FALSE;
3367 return TRUE;
3368}
3369
3370static void getwinmetafilebits(UINT mode, int scale, RECT *rc)
3371{
3372 HENHMETAFILE emf, emf2;
3373 HDC display_dc, emf_dc;
3374 ENHMETAHEADER *enh_header, *enh2_header;
3375 UINT size, emf_size, i, emf2_size;
3376 WORD check = 0;
3377 DWORD rec_num = 0;
3378 METAHEADER *mh = NULL;
3379 METARECORD *rec;
3380 INT horz_res, vert_res, horz_size, vert_size;
3381 INT curve_caps, line_caps, poly_caps;
3382 METAFILEPICT mfp;
3383
3385 ok(display_dc != NULL, "display_dc is NULL\n");
3386
3387 horz_res = GetDeviceCaps(display_dc, HORZRES);
3388 vert_res = GetDeviceCaps(display_dc, VERTRES);
3389 horz_size = GetDeviceCaps(display_dc, HORZSIZE);
3390 vert_size = GetDeviceCaps(display_dc, VERTSIZE);
3391
3392 emf_dc = CreateEnhMetaFileA(display_dc, NULL, rc, NULL);
3393 ok(emf_dc != NULL, "emf_dc is NULL\n");
3394
3395 curve_caps = GetDeviceCaps(emf_dc, CURVECAPS);
3396 ok(curve_caps == 511, "expect 511 got %d\n", curve_caps);
3397
3398 line_caps = GetDeviceCaps(emf_dc, LINECAPS);
3399 ok(line_caps == 254, "expect 254 got %d\n", line_caps);
3400
3401 poly_caps = GetDeviceCaps(emf_dc, POLYGONALCAPS);
3402 ok(poly_caps == 255, "expect 511 got %d\n", poly_caps);
3403
3404 for(i = 0; i < 3000; i++) /* This is enough to take emf_size > 0xffff */
3405 Rectangle(emf_dc, 0, 0, 1000, 20);
3406 emf = CloseEnhMetaFile(emf_dc);
3407 ok(emf != NULL, "emf is NULL\n");
3408
3409 emf_size = GetEnhMetaFileBits(emf, 0, NULL);
3410 enh_header = HeapAlloc(GetProcessHeap(), 0, emf_size);
3411 emf_size = GetEnhMetaFileBits(emf, emf_size, (BYTE*)enh_header);
3413 /* multiply szlDevice.cx by scale, when scale != 1 the recording and playback dcs
3414 have different resolutions */
3415 enh_header->szlDevice.cx *= scale;
3416 emf = SetEnhMetaFileBits(emf_size, (BYTE*)enh_header);
3417 ok(emf != NULL, "emf is NULL\n");
3418 ok(EqualRect((RECT*)&enh_header->rclFrame, rc), "Frame rectangles differ\n");
3419
3421 ok(size ||
3422 broken(size == 0), /* some versions of winxp fail for some reason */
3423 "GetWinMetaFileBits returns 0\n");
3424 if(!size) goto end;
3425 mh = HeapAlloc(GetProcessHeap(), 0, size);
3427
3428 for(i = 0; i < size / 2; i++) check += ((WORD*)mh)[i];
3429 ok(check == 0, "check %04x\n", check);
3430
3431 rec = (METARECORD*)(mh + 1);
3432
3433 while(rec->rdSize && rec->rdFunction)
3434 {
3435 const DWORD chunk_size = 0x2000;
3436 DWORD mfcomment_chunks = (emf_size + chunk_size - 1) / chunk_size;
3437
3438 if(rec_num < mfcomment_chunks)
3439 {
3440 DWORD this_chunk_size = chunk_size;
3441
3442 if(rec_num == mfcomment_chunks - 1)
3443 this_chunk_size = emf_size - rec_num * chunk_size;
3444
3445 ok(rec->rdSize == (this_chunk_size + 44) / 2, "%04x: got %04x expected %04x\n", rec_num, rec->rdSize, (this_chunk_size + 44) / 2);
3446 ok(rec->rdFunction == META_ESCAPE, "%04x: got %04x\n", rec_num, rec->rdFunction);
3447 if(rec->rdSize < (this_chunk_size + 44) / 2) break;
3448 ok(rec->rdParm[0] == MFCOMMENT, "got %04x\n", rec->rdParm[0]);
3449 ok(rec->rdParm[1] == this_chunk_size + 34, "got %04x %x\n", rec->rdParm[1], emf_size + 34);
3450 ok(rec->rdParm[2] == 0x4d57, "got %04x\n", rec->rdParm[2]); /* WMFC */
3451 ok(rec->rdParm[3] == 0x4346, "got %04x\n", rec->rdParm[3]); /* " */
3452 ok(rec->rdParm[4] == 1, "got %04x\n", rec->rdParm[4]);
3453 ok(rec->rdParm[5] == 0, "got %04x\n", rec->rdParm[5]);
3454 ok(rec->rdParm[6] == 0, "got %04x\n", rec->rdParm[6]);
3455 ok(rec->rdParm[7] == 1, "got %04x\n", rec->rdParm[7]);
3456 /* parm[8] is the checksum, tested above */
3457 if(rec_num > 0) ok(rec->rdParm[8] == 0, "got %04x\n", rec->rdParm[8]);
3458 ok(rec->rdParm[9] == 0, "got %04x\n", rec->rdParm[9]);
3459 ok(rec->rdParm[10] == 0, "got %04x\n", rec->rdParm[10]);
3460 ok(rec->rdParm[11] == mfcomment_chunks, "got %04x\n", rec->rdParm[11]); /* num chunks */
3461 ok(rec->rdParm[12] == 0, "got %04x\n", rec->rdParm[12]);
3462 ok(rec->rdParm[13] == this_chunk_size, "got %04x expected %04x\n", rec->rdParm[13], this_chunk_size);
3463 ok(rec->rdParm[14] == 0, "got %04x\n", rec->rdParm[14]);
3464 ok(*(DWORD*)(rec->rdParm + 15) == emf_size - this_chunk_size - rec_num * chunk_size, "got %08x\n", *(DWORD*)(rec->rdParm + 15)); /* DWORD size remaining after current chunk */
3465 ok(*(DWORD*)(rec->rdParm + 17) == emf_size, "got %08x emf_size %08x\n", *(DWORD*)(rec->rdParm + 17), emf_size);
3466 ok(!memcmp(rec->rdParm + 19, (char*)enh_header + rec_num * chunk_size, this_chunk_size), "bits mismatch\n");
3467 }
3468
3469 else if(rec_num == mfcomment_chunks)
3470 {
3471 ok(rec->rdFunction == META_SETMAPMODE, "got %04x\n", rec->rdFunction);
3472 ok(rec->rdParm[0] == mode, "got %04x\n", rec->rdParm[0]);
3473 }
3474 else if(rec_num == mfcomment_chunks + 1)
3475 {
3476 POINT pt;
3477 ok(rec->rdFunction == META_SETWINDOWORG, "got %04x\n", rec->rdFunction);
3478 switch(mode)
3479 {
3480 case MM_TEXT:
3481 case MM_ISOTROPIC:
3482 case MM_ANISOTROPIC:
3483 pt.y = MulDiv(rc->top, vert_res, vert_size * 100) + 1;
3484 pt.x = MulDiv(rc->left, horz_res, horz_size * 100);
3485 break;
3486 case MM_LOMETRIC:
3487 pt.y = MulDiv(-rc->top, 1, 10) + 1;
3488 pt.x = MulDiv( rc->left, 1, 10);
3489 break;
3490 case MM_HIMETRIC:
3491 pt.y = -rc->top + 1;
3492 pt.x = (rc->left >= 0) ? rc->left : rc->left + 1; /* strange but true */
3493 break;
3494 case MM_LOENGLISH:
3495 pt.y = MulDiv(-rc->top, 10, 254) + 1;
3496 pt.x = MulDiv( rc->left, 10, 254);
3497 break;
3498 case MM_HIENGLISH:
3499 pt.y = MulDiv(-rc->top, 100, 254) + 1;
3500 pt.x = MulDiv( rc->left, 100, 254);
3501 break;
3502 case MM_TWIPS:
3503 pt.y = MulDiv(-rc->top, 72 * 20, 2540) + 1;
3504 pt.x = MulDiv( rc->left, 72 * 20, 2540);
3505 break;
3506 default:
3507 pt.x = pt.y = 0;
3508 }
3509 ok(near_match((short)rec->rdParm[0], pt.y), "got %d expect %d\n", (short)rec->rdParm[0], pt.y);
3510 ok(near_match((short)rec->rdParm[1], pt.x), "got %d expect %d\n", (short)rec->rdParm[1], pt.x);
3511 }
3512 if(rec_num == mfcomment_chunks + 2)
3513 {
3514 ok(rec->rdFunction == META_SETWINDOWEXT, "got %04x\n", rec->rdFunction);
3515 ok(near_match((short)rec->rdParm[0], MulDiv(rc->bottom - rc->top, vert_res, vert_size * 100)),
3516 "got %d\n", (short)rec->rdParm[0]);
3517 ok(near_match((short)rec->rdParm[1], MulDiv(rc->right - rc->left, horz_res, horz_size * 100)),
3518 "got %d\n", (short)rec->rdParm[1]);
3519 }
3520
3521 rec_num++;
3522 rec = (METARECORD*)((WORD*)rec + rec->rdSize);
3523 }
3524
3525 /* Show that we get the original back when we do the reverse conversion.
3526 mfp is ignored in this case. */
3527 mfp.mm = MM_ISOTROPIC;
3528 mfp.xExt = 0xcafe;
3529 mfp.yExt = 0xbeef;
3530 emf2 = SetWinMetaFileBits( size, (BYTE*)mh, NULL, &mfp );
3531 ok( !!emf2, "got NULL\n" );
3532 emf2_size = GetEnhMetaFileBits( emf2, 0, NULL );
3533 enh2_header = HeapAlloc( GetProcessHeap(), 0, emf2_size );
3534 emf2_size = GetEnhMetaFileBits( emf2, emf2_size, (BYTE*)enh2_header );
3535 ok( emf_size == emf2_size, "%d %d\n", emf_size, emf2_size );
3536 ok( !memcmp( enh_header, enh2_header, emf_size ), "mismatch\n" );
3537 HeapFree( GetProcessHeap(), 0, enh2_header );
3538 DeleteEnhMetaFile( emf2 );
3539
3540end:
3541 HeapFree(GetProcessHeap(), 0, mh);
3542 HeapFree(GetProcessHeap(), 0, enh_header);
3544
3546}
3547
3549{
3550 UINT mode;
3551 RECT frames[] =
3552 {
3553 { 1000, 2000, 3000, 6000},
3554 {-1000, 2000, 3000, 6000},
3555 { 1000, -2000, 3000, 6000},
3556 { 1005, 2005, 3000, 6000},
3557 {-1005, -2005, 3000, 6000},
3558 {-1005, -2010, 3000, 6000},
3559 {-1005, 2010, 3000, 6000},
3560 { 0, 0, 1, 1},
3561 { -1, -1, 1, 1},
3562 { 0, 0, 0, 0}
3563 };
3564
3565 for(mode = MM_MIN; mode <= MM_MAX; mode++)
3566 {
3567 RECT *rc;
3568 for(rc = frames; rc->right - rc->left > 0; rc++)
3569 {
3570 getwinmetafilebits(mode, 1, rc);
3571 getwinmetafilebits(mode, 2, rc);
3572 }
3573 }
3574}
3575
3576static BOOL (WINAPI *pGdiIsMetaPrintDC)(HDC);
3577static BOOL (WINAPI *pGdiIsMetaFileDC)(HDC);
3578static BOOL (WINAPI *pGdiIsPlayMetafileDC)(HDC);
3579
3580static void test_gdiis(void)
3581{
3582 RECT rect = {0,0,100,100};
3583 HDC hdc, hemfDC, hmfDC;
3584 HENHMETAFILE hemf;
3586
3587 /* resolve all the functions */
3588 hgdi32 = GetModuleHandleA("gdi32.dll");
3589 pGdiIsMetaPrintDC = (void*) GetProcAddress(hgdi32, "GdiIsMetaPrintDC");
3590 pGdiIsMetaFileDC = (void*) GetProcAddress(hgdi32, "GdiIsMetaFileDC");
3591 pGdiIsPlayMetafileDC = (void*) GetProcAddress(hgdi32, "GdiIsPlayMetafileDC");
3592
3593 if(!pGdiIsMetaPrintDC || !pGdiIsMetaFileDC || !pGdiIsPlayMetafileDC)
3594 {
3595 win_skip("Needed GdiIs* functions are not available\n");
3596 return;
3597 }
3598
3599 /* try with nothing */
3600 ok(!pGdiIsMetaPrintDC(NULL), "ismetaprint with NULL parameter\n");
3601 ok(!pGdiIsMetaFileDC(NULL), "ismetafile with NULL parameter\n");
3602 ok(!pGdiIsPlayMetafileDC(NULL), "isplaymetafile with NULL parameter\n");
3603
3604 /* try with a metafile */
3605 hmfDC = CreateMetaFileA(NULL);
3606 ok(!pGdiIsMetaPrintDC(hmfDC), "ismetaprint on metafile\n");
3607 ok(pGdiIsMetaFileDC(hmfDC), "ismetafile on metafile\n");
3608 ok(!pGdiIsPlayMetafileDC(hmfDC), "isplaymetafile on metafile\n");
3610
3611 /* try with an enhanced metafile */
3612 hdc = GetDC(NULL);
3613 hemfDC = CreateEnhMetaFileW(hdc, NULL, &rect, NULL);
3614 ok(hemfDC != NULL, "failed to create emf\n");
3615
3616 ok(!pGdiIsMetaPrintDC(hemfDC), "ismetaprint on emf\n");
3617 ok(pGdiIsMetaFileDC(hemfDC), "ismetafile on emf\n");
3618 ok(!pGdiIsPlayMetafileDC(hemfDC), "isplaymetafile on emf\n");
3619
3620 hemf = CloseEnhMetaFile(hemfDC);
3621 ok(hemf != NULL, "failed to close EMF\n");
3622 DeleteEnhMetaFile(hemf);
3624}
3625
3627{
3628 BYTE data[256];
3629 HENHMETAFILE hemf;
3630 ENHMETAHEADER *emh;
3631
3632 memset(data, 0xAA, sizeof(data));
3633 SetLastError(0xdeadbeef);
3634 hemf = SetEnhMetaFileBits(sizeof(data), data);
3635 ok(!hemf, "SetEnhMetaFileBits should fail\n");
3637 GetLastError() == ERROR_INVALID_PARAMETER, /* Win9x, WinMe */
3638 "expected ERROR_INVALID_DATA or ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
3639
3640 emh = (ENHMETAHEADER *)data;
3641 memset(emh, 0, sizeof(*emh));
3642
3643 emh->iType = EMR_HEADER;
3644 emh->nSize = sizeof(*emh);
3646 /* emh->nVersion = 0x10000; XP doesn't care about version */
3647 emh->nBytes = sizeof(*emh);
3648 /* emh->nRecords = 1; XP doesn't care about records */
3649 emh->nHandles = 1; /* XP refuses to load a EMF if nHandles == 0 */
3650
3651 SetLastError(0xdeadbeef);
3652 hemf = SetEnhMetaFileBits(emh->nBytes, data);
3653 ok(hemf != 0, "SetEnhMetaFileBits error %u\n", GetLastError());
3654 DeleteEnhMetaFile(hemf);
3655
3656 /* XP refuses to load unaligned EMF */
3657 emh->nBytes++;
3658 SetLastError(0xdeadbeef);
3659 hemf = SetEnhMetaFileBits(emh->nBytes, data);
3660 ok(!hemf ||
3661 broken(hemf != NULL), /* Win9x, WinMe */
3662 "SetEnhMetaFileBits should fail\n");
3663 ok(GetLastError() == 0xdeadbeef, "Expected deadbeef, got %u\n", GetLastError());
3664 DeleteEnhMetaFile(hemf);
3665
3666 emh->dSignature = 0;
3667 emh->nBytes--;
3668 SetLastError(0xdeadbeef);
3669 hemf = SetEnhMetaFileBits(emh->nBytes, data);
3670 ok(!hemf ||
3671 broken(hemf != NULL), /* Win9x, WinMe */
3672 "SetEnhMetaFileBits should fail\n");
3673 ok(GetLastError() == 0xdeadbeef, "Expected deadbeef, got %u\n", GetLastError());
3674 DeleteEnhMetaFile(hemf);
3675}
3676
3677static void test_emf_polybezier(void)
3678{
3679 HDC hdcMetafile;
3680 HENHMETAFILE hemf;
3681 POINT pts[4];
3682 BOOL ret;
3683
3684 SetLastError(0xdeadbeef);
3685 hdcMetafile = CreateEnhMetaFileA(GetDC(0), NULL, NULL, NULL);
3686 ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
3687
3688 pts[0].x = pts[0].y = 10;
3689 pts[1].x = pts[1].y = 20;
3690 pts[2].x = pts[2].y = 15;
3691 pts[3].x = pts[3].y = 25;
3692 ret = PolyBezierTo(hdcMetafile, pts, 3); /* EMR_POLYBEZIERTO16 */
3693 ok( ret, "PolyBezierTo failed\n" );
3694 ret = PolyBezier(hdcMetafile, pts, 4); /* EMR_POLYBEZIER16 */
3695 ok( ret, "PolyBezier failed\n" );
3696
3697 pts[0].x = pts[0].y = 32769;
3698 ret = PolyBezier(hdcMetafile, pts, 4); /* EMR_POLYBEZIER */
3699 ok( ret, "PolyBezier failed\n" );
3700 ret = PolyBezierTo(hdcMetafile, pts, 3); /* EMR_POLYBEZIERTO */
3701 ok( ret, "PolyBezierTo failed\n" );
3702
3703 hemf = CloseEnhMetaFile(hdcMetafile);
3704 ok(hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError());
3705
3707 "emf_Bezier", FALSE) != 0)
3708 {
3709 dump_emf_bits(hemf, "emf_Bezier");
3710 dump_emf_records(hemf, "emf_Bezier");
3711 }
3712
3713 DeleteEnhMetaFile(hemf);
3714}
3715
3716static const unsigned char EMF_PATH_BITS[] =
3717{
3718 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
3719 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
3720 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00,
3721 0x90, 0x01, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
3722 0x70, 0x17, 0x00, 0x00, 0x70, 0x17, 0x00, 0x00,
3723 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
3724 0xf8, 0x02, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
3725 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3726 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3727 0x20, 0x03, 0x00, 0x00, 0x58, 0x02, 0x00, 0x00,
3728 0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
3729 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3730 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
3731 0x80, 0xa9, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00,
3732 0x08, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00,
3733 0x10, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
3734 0x32, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
3735 0x10, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
3736 0x96, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
3737 0x10, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00,
3738 0x96, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
3739 0x10, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00,
3740 0x32, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
3741 0x10, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
3742 0x32, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
3743 0x18, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
3744 0x0a, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
3745 0x13, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00,
3746 0x28, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
3747 0x15, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
3748 0x1c, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
3749 0x1d, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
3750 0x15, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00,
3751 0x28, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
3752 0x17, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
3753 0x1a, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
3754 0x1b, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
3755 0x17, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00,
3756 0x28, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
3757 0x15, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
3758 0x1c, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
3759 0x1d, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
3760 0x15, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
3761 0x28, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
3762 0x15, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
3763 0x1c, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
3764 0x1d, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
3765 0x15, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00,
3766 0x18, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
3767 0x0a, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
3768 0x13, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
3769 0x20, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
3770 0x0a, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
3771 0x13, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
3772 0x05, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00,
3773 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3774 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
3775 0xff, 0xff, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00,
3776 0x0a, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x0a, 0x00,
3777 0x0a, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00,
3778 0x59, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
3779 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3780 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3781 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00,
3782 0x14, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x14, 0x00,
3783 0x14, 0x00, 0x14, 0x00, 0x5a, 0x00, 0x00, 0x00,
3784 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3785 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
3786 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00,
3787 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3788 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00,
3789 0x14, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x14, 0x00,
3790 0x14, 0x00, 0x14, 0x00, 0x5c, 0x00, 0x00, 0x00,
3791 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3792 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
3793 0xff, 0xff, 0xff, 0xff, 0x09, 0x00, 0x00, 0x00,
3794 0x0a, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x0a, 0x00,
3795 0x0a, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00,
3796 0x1e, 0x00, 0x1e, 0x00, 0x28, 0x00, 0x14, 0x00,
3797 0x14, 0x00, 0x1e, 0x00, 0x14, 0x00, 0x14, 0x00,
3798 0x14, 0x00, 0x0a, 0x00, 0x06, 0x02, 0x04, 0x04,
3799 0x04, 0x02, 0x03, 0x06, 0x02, 0x00, 0x00, 0x00,
3800 0x29, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
3801 0x25, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
3802 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x42,
3803 0x00, 0x00, 0x34, 0x43, 0x3c, 0x00, 0x00, 0x00,
3804 0x08, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
3805 0x18, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
3806 0x0a, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00,
3807 0x96, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
3808 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3809 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
3810 0xff, 0xff, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00,
3811 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3812 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
3813};
3814
3815static const unsigned char EMF_EMPTY_PATH_BITS[] =
3816{
3817 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
3818 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3819 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3820 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3821 0xd8, 0xff, 0xff, 0xff, 0xd8, 0xff, 0xff, 0xff,
3822 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
3823 0xc8, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
3824 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3825 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3826 0x20, 0x03, 0x00, 0x00, 0x58, 0x02, 0x00, 0x00,
3827 0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
3828 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3829 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
3830 0x80, 0xa9, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00,
3831 0x08, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00,
3832 0x08, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00,
3833 0x08, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
3834 0x08, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
3835 0x08, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00,
3836 0x08, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00,
3837 0x08, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
3838 0x08, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
3839 0x08, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
3840 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3841 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
3842};
3843
3844static void test_emf_paths(void)
3845{
3846 POINT pts[9] = {{10, 10}, {20, 10}, {10, 20}, {20, 20}, {30, 30}, {40, 20}, {20, 30}, {20, 20}, {20, 10}};
3847 DWORD counts[2] = {2, 2};
3850 HDC hdcMetafile;
3851 HENHMETAFILE hemf;
3852 BOOL ret;
3853 int size;
3854
3855 SetLastError(0xdeadbeef);
3856 hdcMetafile = CreateEnhMetaFileA(GetDC(0), NULL, NULL, NULL);
3857 ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
3858
3859 ret = BeginPath(hdcMetafile);
3860 ok(ret, "BeginPath error %d\n", GetLastError());
3861 ret = MoveToEx(hdcMetafile, 50, 50, NULL);
3862 ok( ret, "MoveToEx error %d.\n", GetLastError());
3863 ret = LineTo(hdcMetafile, 50, 150);
3864 ok( ret, "LineTo error %d.\n", GetLastError());
3865 ret = LineTo(hdcMetafile, 150, 150);
3866 ok( ret, "LineTo error %d.\n", GetLastError());
3867 ret = LineTo(hdcMetafile, 150, 50);
3868 ok( ret, "LineTo error %d.\n", GetLastError());
3869 ret = LineTo(hdcMetafile, 50, 50);
3870 ok( ret, "LineTo error %d.\n", GetLastError());
3871 Rectangle(hdcMetafile, 10, 10, 20, 20);
3872 Arc(hdcMetafile, 21, 21, 39, 29, 39, 29, 21, 21);
3873 ArcTo(hdcMetafile, 23, 23, 37, 27, 37, 27, 23, 23);
3874 Chord(hdcMetafile, 21, 21, 39, 29, 39, 29, 21, 21);
3875 Pie(hdcMetafile, 21, 21, 39, 29, 39, 29, 21, 21);
3876 Ellipse(hdcMetafile, 10, 10, 20, 20);
3877 RoundRect(hdcMetafile, 10, 10, 20, 20, 3, 5);
3878 Polyline(hdcMetafile, pts, 4);
3879 PolylineTo(hdcMetafile, pts, 4);
3880 PolyPolyline(hdcMetafile, pts, counts, 2);
3881 PolyDraw(hdcMetafile, pts, types, 9);
3882 AngleArc(hdcMetafile, 37, 36, 23, 90, 180);
3883 EndPath(hdcMetafile);
3884
3885 size = GetPath(hdcMetafile, NULL, NULL, 0);
3886 ok( size == 112, "GetPath returned %d.\n", size);
3887
3888 ret = StrokeAndFillPath( hdcMetafile );
3889 ok( ret, "StrokeAndFillPath failed err %d\n", GetLastError() );
3890 ret = StrokeAndFillPath( hdcMetafile );
3891 ok( !ret, "StrokeAndFillPath succeeded\n" );
3892
3893 hemf = CloseEnhMetaFile(hdcMetafile);
3894 ok(hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError());
3895
3896 if (compare_emf_bits(hemf, EMF_PATH_BITS, sizeof(EMF_PATH_BITS), "test_emf_paths", FALSE) != 0)
3897 {
3898 dump_emf_bits(hemf, "test_emf_paths");
3899 dump_emf_records(hemf, "test_emf_paths");
3900 }
3901
3902 DeleteEnhMetaFile(hemf);
3903
3904 SetLastError(0xdeadbeef);
3905 hdcMetafile = CreateEnhMetaFileA(GetDC(0), NULL, NULL, NULL);
3906 ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
3907
3908 ret = BeginPath(hdcMetafile);
3909 ok( ret, "BeginPath failed error %d\n", GetLastError() );
3910 ret = CloseFigure(hdcMetafile);
3911 ok( ret, "CloseFigure failed error %d\n", GetLastError() );
3912 ret = BeginPath(hdcMetafile);
3913 ok( ret, "BeginPath failed error %d\n", GetLastError() );
3914 ret = EndPath(hdcMetafile);
3915 ok( ret, "EndPath failed error %d\n", GetLastError() );
3916 ret = EndPath(hdcMetafile);
3917 ok( !ret, "EndPath succeeded\n" );
3918 ret = CloseFigure(hdcMetafile);
3919 ok( !ret, "CloseFigure succeeded\n" );
3920 ret = BeginPath(hdcMetafile);
3921 ok( ret, "BeginPath failed error %d\n", GetLastError() );
3922 ret = AbortPath(hdcMetafile);
3923 ok( ret, "AbortPath failed error %d\n", GetLastError() );
3924 ret = AbortPath(hdcMetafile);
3925 ok( ret, "AbortPath failed error %d\n", GetLastError() );
3926
3927 hemf = CloseEnhMetaFile(hdcMetafile);
3928 ok(hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError());
3929
3930 if (compare_emf_bits(hemf, EMF_EMPTY_PATH_BITS, sizeof(EMF_EMPTY_PATH_BITS), "empty path", FALSE) != 0)
3931 {
3932 dump_emf_bits(hemf, "empty path");
3933 dump_emf_records(hemf, "empty path");
3934 }
3935
3936 DeleteEnhMetaFile(hemf);
3937}
3938
3939static void test_emf_PolyPolyline(void)
3940{
3941 HDC hdcMetafile;
3942 HENHMETAFILE hemf;
3943 POINT pts[4] = {{10, 20}, {100, 200}, {0x9000,300}, {400, 500}};
3944 DWORD counts[2];
3945 BOOL ret;
3946
3947 SetLastError(0xdeadbeef);
3948 hdcMetafile = CreateEnhMetaFileA(GetDC(0), NULL, NULL, NULL);
3949 ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
3950
3951 ret = PolyPolyline(hdcMetafile, NULL, NULL, 0);
3952 ok( !ret, "PolyPolyline\n" );
3953
3954 SetLastError( 0xdeadbeef );
3955 counts[0] = 0;
3956 counts[1] = 1;
3957 ret = PolyPolyline(hdcMetafile, pts, counts, 2);
3958 ok( !ret, "PolyPolyline\n" );
3959 ok( GetLastError() == ERROR_INVALID_PARAMETER, "gle %d\n", GetLastError() );
3960
3961 SetLastError( 0xdeadbeef );
3962 counts[0] = 1;
3963 counts[1] = 1;
3964 ret = PolyPolyline(hdcMetafile, pts, counts, 2);
3965 ok( !ret, "PolyPolyline\n" );
3966 ok( GetLastError() == ERROR_INVALID_PARAMETER, "gle %d\n", GetLastError() );
3967
3968 SetLastError( 0xdeadbeef );
3969 counts[0] = 2;
3970 counts[1] = 1;
3971 ret = PolyPolyline(hdcMetafile, pts, counts, 2);
3972 ok( !ret, "PolyPolyline\n" );
3973 ok( GetLastError() == ERROR_INVALID_PARAMETER, "gle %d\n", GetLastError() );
3974
3975 counts[0] = 2;
3976 counts[1] = 2;
3977 ret = PolyPolyline(hdcMetafile, pts, counts, 2);
3978 ok( ret, "PolyPolyline\n" );
3979
3980 hemf = CloseEnhMetaFile(hdcMetafile);
3981 ok(hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError());
3982
3984 "emf_PolyPolyline", FALSE) != 0)
3985 {
3986 dump_emf_bits(hemf, "emf_PolyPolyline");
3987 dump_emf_records(hemf, "emf_PolyPolyline");
3988 }
3989
3990 DeleteEnhMetaFile(hemf);
3991}
3992
3993static void test_emf_GradientFill(void)
3994{
3995 HDC mf;
3996 HENHMETAFILE hemf;
3997 TRIVERTEX v[] =
3998 {
3999 { 1, 10, 0xff00, 0x8000, 0x0000, 0x8001 },
4000 { 200, 210, 0x0000, 0x0000, 0xff00, 0xff00 },
4001 { 180, 190, 0x1234, 0x5678, 0x9abc, 0xdef0 },
4002 { 300, 310, 0xff00, 0xff00, 0xff00, 0x0000 },
4003 { 400, 410, 0xff00, 0xff00, 0xff00, 0x0000 }
4004 };
4005 GRADIENT_TRIANGLE tri[] = { { 0, 1, 2 }, { 3, 1, 0 } };
4006 BOOL ret;
4007
4008 mf = CreateEnhMetaFileA( GetDC( 0 ), NULL, NULL, NULL );
4009 ok( mf != 0, "CreateEnhMetaFileA error %d\n", GetLastError() );
4010
4011 /* Don't test the GRADIENT_FILL_RECT_ modes since a Windows bug
4012 * means it allocates three mesh indices rather than two per
4013 * rectangle. This results in uninitialised values being written
4014 * to the EMF which is rather difficult to test against.
4015 *
4016 * Note also that the final vertex here is not required, yet it is
4017 * written to the EMF, but is not considered in the bounds
4018 * calculation.
4019 */
4020 ret = GdiGradientFill( mf, v, sizeof(v) / sizeof(v[0]), tri, sizeof(tri) / sizeof(tri[0]),
4021 GRADIENT_FILL_TRIANGLE );
4022 ok( ret, "GradientFill\n" );
4023
4024 hemf = CloseEnhMetaFile( mf );
4025 ok( hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError() );
4026
4028 "emf_GradientFill", FALSE ) != 0)
4029 {
4030 dump_emf_bits( hemf, "emf_GradientFill" );
4031 dump_emf_records( hemf, "emf_GradientFill" );
4032 }
4033
4034 DeleteEnhMetaFile( hemf );
4035}
4036
4037static void set_rotation_xform(XFORM *out, float rad, int dx, int dy)
4038{
4039 out->eM11 = cosf(rad);
4040 out->eM12 = -1.f * sinf(rad);
4041 out->eM21 = sinf(rad);
4042 out->eM22 = cosf(rad);
4043 out->eDx = dx;
4044 out->eDy = dy;
4045}
4046
4048{
4049 const char *name;
4050
4053
4056 XFORM stored; /* this is the "hidden" world transform used in PlayEnhMetaFileRecord */
4057};
4058
4059static BOOL xform_eq(const XFORM *a, const XFORM *b)
4060{
4061 return fabs(a->eM11 - b->eM11) < 0.001f &&
4062 fabs(a->eM12 - b->eM12) < 0.001f &&
4063 fabs(a->eM21 - b->eM21) < 0.001f &&
4064 fabs(a->eM22 - b->eM22) < 0.001f &&
4065 fabs(a->eDx - b->eDx) < 0.001f &&
4066 fabs(a->eDy - b->eDy) < 0.001f;
4067}
4068
4070 const ENHMETARECORD *emr, INT nobj, LPARAM param)
4071{
4072 XFORM xform = {0};
4074 BOOL ret;
4075
4076 switch(emr->iType)
4077 {
4079 {
4080 const EMRSETWORLDTRANSFORM *lpXfrm = (const EMRSETWORLDTRANSFORM *)emr;
4081
4082 /* get scale factors with an identity world transform */
4084
4085 /* play back record */
4086 ret = PlayEnhMetaFileRecord(hdc, ht, emr, nobj);
4087 ok(ret == TRUE, "%s: PlayEnhMetaFileRecord failed\n", test_data->name);
4088
4089 test_data->stored = lpXfrm->xform;
4090 CombineTransform(&test_data->expected, &test_data->stored, &test_data->scale);
4091
4092 /* verify it is updated immediately */
4093 ret = GetWorldTransform(hdc, &xform);
4094 ok(ret == TRUE, "%s: GetWorldTransform failed\n", test_data->name);
4095 ok(xform_eq(&xform, &test_data->expected),
4096 "%s: After SWT playback, got wrong world transform: %f, %f; %f %f; %f %f; expected: %f, %f; %f %f; %f %f\n",
4097 test_data->name,
4098 xform.eM11, xform.eM12,
4099 xform.eM21, xform.eM22,
4100 xform.eDx, xform.eDy,
4101 test_data->expected.eM11, test_data->expected.eM12,
4102 test_data->expected.eM21, test_data->expected.eM22,
4103 test_data->expected.eDx, test_data->expected.eDy);
4104
4105 break;
4106 }
4107
4109 {
4110 const EMRMODIFYWORLDTRANSFORM *lpXfrm = (const EMRMODIFYWORLDTRANSFORM *)emr;
4111
4112 /* transform persists across calls */
4113 ret = GetWorldTransform(hdc, &xform);
4114 ok(ret == TRUE, "%s: GetWorldTransform failed\n", test_data->name);
4115 ok(xform_eq(&xform, &test_data->expected),
4116 "%s: On MWT entry, got wrong world transform: %f, %f; %f %f; %f %f; expected: %f, %f; %f %f; %f %f\n",
4117 test_data->name,
4118 xform.eM11, xform.eM12,
4119 xform.eM21, xform.eM22,
4120 xform.eDx, xform.eDy,
4121 test_data->expected.eM11, test_data->expected.eM12,
4122 test_data->expected.eM21, test_data->expected.eM22,
4123 test_data->expected.eDx, test_data->expected.eDy);
4124
4125 if(test_data->do_playback)
4126 {
4127 /* play back record */
4128 ret = PlayEnhMetaFileRecord(hdc, ht, emr, nobj);
4129 ok(ret == TRUE, "%s: PlayEnhMetaFileRecord failed\n", test_data->name);
4130
4131 if(lpXfrm->iMode == MWT_LEFTMULTIPLY)
4132 {
4133 /* left multiply does not discard direct modifications */
4134 CombineTransform(&test_data->expected, &lpXfrm->xform, &test_data->expected);
4135
4136 /* and updates the stored matrix separately */
4137 CombineTransform(&test_data->stored, &lpXfrm->xform, &test_data->stored);
4138
4139 }
4140 else if(lpXfrm->iMode == MWT_RIGHTMULTIPLY)
4141 {
4142 /* but right multiply does discard */
4143 CombineTransform(&test_data->stored, &test_data->stored, &lpXfrm->xform);
4144
4145 CombineTransform(&test_data->expected, &test_data->stored, &test_data->scale);
4146 }
4147
4148 /* verify it is updated immediately */
4149 ret = GetWorldTransform(hdc, &xform);
4150 ok(ret == TRUE, "%s: GetWorldTransform failed\n", test_data->name);
4151 ok(xform_eq(&xform, &test_data->expected),
4152 "%s: After MWT playback, got wrong world transform: %f, %f; %f %f; %f %f; expected: %f, %f; %f %f; %f %f\n",
4153 test_data->name,
4154 xform.eM11, xform.eM12,
4155 xform.eM21, xform.eM22,
4156 xform.eDx, xform.eDy,
4157 test_data->expected.eM11, test_data->expected.eM12,
4158 test_data->expected.eM21, test_data->expected.eM22,
4159 test_data->expected.eDx, test_data->expected.eDy);
4160 }
4161
4162 if(test_data->do_modify)
4163 {
4164 /* modify directly */
4165 set_rotation_xform(&xform, M_PI / 4.f, 1, -1);
4167 ok(ret == TRUE, "%s: ModifyWorldTransform failed\n", test_data->name);
4168
4169 /* the modified transform persists across callback calls */
4170 CombineTransform(&test_data->expected, &xform, &test_data->expected);
4171
4172 ret = GetWorldTransform(hdc, &xform);
4173 ok(ret == TRUE, "%s: GetWorldTransform failed\n", test_data->name);
4174 ok(xform_eq(&xform, &test_data->expected),
4175 "%s: After ModifyWT, got wrong world transform: %f, %f; %f %f; %f %f; expected: %f, %f; %f %f; %f %f\n",
4176 test_data->name,
4177 xform.eM11, xform.eM12,
4178 xform.eM21, xform.eM22,
4179 xform.eDx, xform.eDy,
4180 test_data->expected.eM11, test_data->expected.eM12,
4181 test_data->expected.eM21, test_data->expected.eM22,
4182 test_data->expected.eDx, test_data->expected.eDy);
4183 }
4184
4185 break;
4186 }
4187
4188 case EMR_LINETO:
4189 ret = GetWorldTransform(hdc, &xform);
4190 ok(ret == TRUE, "%s: GetWorldTransform failed\n", test_data->name);
4191 ok(xform_eq(&xform, &test_data->expected),
4192 "%s: Before LINETO playback, got wrong world transform: %f, %f; %f %f; %f %f; expected: %f, %f; %f %f; %f %f\n",
4193 test_data->name,
4194 xform.eM11, xform.eM12,
4195 xform.eM21, xform.eM22,
4196 xform.eDx, xform.eDy,
4197 test_data->expected.eM11, test_data->expected.eM12,
4198 test_data->expected.eM21, test_data->expected.eM22,
4199 test_data->expected.eDx, test_data->expected.eDy);
4200
4201 ret = PlayEnhMetaFileRecord(hdc, ht, emr, nobj);
4202 ok(ret == TRUE, "%s: PlayEnhMetaFileRecord failed\n", test_data->name);
4203
4204 /* transform doesn't change during LINETO playback */
4205 ret = GetWorldTransform(hdc, &xform);
4206 ok(ret == TRUE, "%s: GetWorldTransform failed\n", test_data->name);
4207 ok(xform_eq(&xform, &test_data->expected),
4208 "%s: After LINETO playback, got wrong world transform: %f, %f; %f %f; %f %f; expected: %f, %f; %f %f; %f %f\n",
4209 test_data->name,
4210 xform.eM11, xform.eM12,
4211 xform.eM21, xform.eM22,
4212 xform.eDx, xform.eDy,
4213 test_data->expected.eM11, test_data->expected.eM12,
4214 test_data->expected.eM21, test_data->expected.eM22,
4215 test_data->expected.eDx, test_data->expected.eDy);
4216
4217 break;
4218
4219 default:
4220 PlayEnhMetaFileRecord(hdc, ht, emr, nobj);
4221 break;
4222 }
4223
4224 return 1;
4225}
4226
4228{
4229 HDC hdcMetafile, hdc;
4230 HWND hwnd;
4231 HENHMETAFILE hemf;
4232 XFORM xform;
4233 BOOL ret;
4234 RECT rect = { 0, 0, 100, 100 };
4235 int i;
4237 { "normal", FALSE, TRUE },
4238 { "playback and modify", TRUE, TRUE },
4239 { "manual modify", TRUE, FALSE }
4240 };
4241
4242 for(i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
4243 {
4244 hdcMetafile = CreateEnhMetaFileA(GetDC(0), NULL, NULL, NULL);
4245 ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
4246
4247 ret = SetGraphicsMode(hdcMetafile, GM_ADVANCED);
4248 ok(ret == TRUE, "SetGraphicsMode failed\n");
4249
4250 set_rotation_xform(&xform, M_PI / 4.f, 2, 3);
4251 ret = SetWorldTransform(hdcMetafile, &xform); /* EMR_SETWORLDTRANSFORM */
4252 ok(ret == TRUE, "SetWorldTransform failed\n");
4253
4254 set_rotation_xform(&xform, M_PI / 2.f, -2, -3);
4255 ret = ModifyWorldTransform(hdcMetafile, &xform, MWT_LEFTMULTIPLY); /* EMR_MODIFYWORLDTRANSFORM */
4256 ok(ret == TRUE, "ModifyWorldTransform failed\n");
4257
4258 set_rotation_xform(&xform, M_PI / 3.f, -2, 3);
4259 ret = ModifyWorldTransform(hdcMetafile, &xform, MWT_LEFTMULTIPLY); /* EMR_MODIFYWORLDTRANSFORM */
4260 ok(ret == TRUE, "ModifyWorldTransform failed\n");
4261
4262 set_rotation_xform(&xform, M_PI, 2, -3);
4263 ret = ModifyWorldTransform(hdcMetafile, &xform, MWT_RIGHTMULTIPLY); /* EMR_MODIFYWORLDTRANSFORM */
4264 ok(ret == TRUE, "ModifyWorldTransform failed\n");
4265
4266 ret = LineTo(hdcMetafile, 1, 1);
4267 ok(ret == TRUE, "LineTo failed\n");
4268
4269 hemf = CloseEnhMetaFile(hdcMetafile);
4270 ok(hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError());
4271
4272 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
4273 0, 0, 200, 200, 0, 0, 0, NULL);
4274 ok(hwnd != 0, "CreateWindowExA error %d\n", GetLastError());
4275
4276 hdc = GetDC(hwnd);
4277 ok(hdc != 0, "GetDC failed\n");
4278
4280 ok(ret == TRUE, "EnumEnhMetaFile failed: %u\n", GetLastError());
4281
4282 ReleaseDC(hwnd, hdc);
4284
4285 DeleteEnhMetaFile(hemf);
4286 }
4287}
4288
4290{
4292
4293 /* For enhanced metafiles (enhmfdrv) */
4296 test_SaveDC();
4306
4307 /* For win-format metafiles (mfdrv) */
4309 test_mf_Blank();
4318
4319 /* For metafile conversions */
4323
4324 test_gdiis();
4326}
static HRGN hrgn
static POBJECT_TYPE GetObjectType(IN PCWSTR TypeName)
Definition: ObTypes.c:15
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
static const char * wine_dbgstr_rect(const RECT *prc)
Definition: atltest.h:160
#define msg(x)
Definition: auth_time.c:54
struct _RGNDATAHEADER RGNDATAHEADER
#define WINDING
Definition: constants.h:279
#define ALTERNATE
Definition: constants.h:278
HFONT hFont
Definition: main.c:53
Definition: arc.h:55
#define LF_FACESIZE
Definition: dimm.idl:39
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static HBITMAP hBitmap
Definition: timezone.c:26
static const WCHAR rc2[]
Definition: oid.c:1216
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
#define FILE_SHARE_READ
Definition: compat.h:136
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static const WCHAR *const ext[]
Definition: module.c:53
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2054
int WINAPI lstrcmpA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4195
static HDC display_dc
Definition: main.c:41
const WCHAR * text
Definition: package.c:1794
#define assert(x)
Definition: debug.h:53
#define check(expected, result)
Definition: dplayx.c:32
#define pt(x, y)
Definition: drawing.c:79
static VOID BitBlt(_In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Width, _In_ ULONG Height, _In_reads_bytes_(Delta *Height) PUCHAR Buffer, _In_ ULONG BitsPerPixel, _In_ ULONG Delta)
Definition: common.c:57
#define BI_RGB
Definition: precomp.h:56
#define RGB(r, g, b)
Definition: precomp.h:71
#define ULONG_PTR
Definition: config.h:101
#define abs(i)
Definition: fconv.c:206
UINT WINAPI GetTempFileNameA(IN LPCSTR lpPathName, IN LPCSTR lpPrefixString, IN UINT uUnique, OUT LPSTR lpTempFileName)
Definition: filename.c:26
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
#define printf
Definition: freeldr.h:97
pKey DeleteObject()
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
const GLdouble * v
Definition: gl.h:2040
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLuint res
Definition: glext.h:9613
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:9032
GLuint buffer
Definition: glext.h:5915
GLuint color
Definition: glext.h:6243
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum mode
Definition: glext.h:6217
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:9031
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static const struct newhuff ht[]
Definition: huffman.h:296
#define FLOAT
Definition: i386-dis.c:525
_Check_return_ _CRT_JIT_INTRINSIC double __cdecl fabs(_In_ double x)
Definition: fabs.c:17
_Check_return_ float __cdecl cosf(_In_ float x)
Definition: math.h:224
_Check_return_ _CRTIMP double __cdecl floor(_In_ double x)
_Check_return_ float __cdecl sinf(_In_ float x)
Definition: math.h:233
#define bits
Definition: infblock.c:15
GLint dy
Definition: linetemp.h:97
GLint y0
Definition: linetemp.h:96
GLint x0
Definition: linetemp.h:95
GLint dx
Definition: linetemp.h:97
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
HDC hdcOffscreen
Definition: magnifier.c:52
static const WCHAR dc[]
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define sprintf(buf, format,...)
Definition: sprintf.c:55
HDC hdc
Definition: main.c:9
BOOL WINAPI GdiGradientFill(HDC hdc, TRIVERTEX *vert_array, ULONG nvert, void *grad_array, ULONG ngrad, ULONG mode)
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:88
static char org[]
Definition: encode.c:7456
static const WCHAR desc[]
Definition: protectdata.c:36
static HMODULE hgdi32
Definition: font.c:65
#define near_match(a, b)
Definition: font.c:39
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
static const unsigned char EMF_BITBLT[]
Definition: metafile.c:1291
static const unsigned char MF_LINETO_BITS[]
Definition: metafile.c:1167
static const unsigned char MF_PATH_BITS[]
Definition: metafile.c:2944
static void dump_mf_bits(const HMETAFILE mf, const char *desc)
Definition: metafile.c:1568
static void test_mf_Graphics(void)
Definition: metafile.c:2251
static int CALLBACK savedc_emf_enum_proc(HDC hdc, HANDLETABLE *handle_table, const ENHMETARECORD *emr, int n_objs, LPARAM param)
Definition: metafile.c:495
static void test_emf_GradientFill(void)
Definition: metafile.c:3993
static const unsigned char EMF_TEXTOUT_ON_PATH_BITS[]
Definition: metafile.c:1094
static HENHMETAFILE create_converted_emf(const METAFILEPICT *mfp)
Definition: metafile.c:3040
static int CALLBACK eto_emf_enum_proc(HDC hdc, HANDLETABLE *handle_table, const ENHMETARECORD *emr, int n_objs, LPARAM param)
Definition: metafile.c:81
static void test_SetMetaFileBits(void)
Definition: metafile.c:2151
static void test_gdiis(void)
Definition: metafile.c:3580
static void dump_emf_records(const HENHMETAFILE mf, const char *desc)
Definition: metafile.c:1692
static void test_ExtTextOutScale(void)
Definition: metafile.c:334
static int compare_emf_bits(const HENHMETAFILE mf, const unsigned char *bits, UINT bsize, const char *desc, BOOL ignore_scaling)
Definition: metafile.c:1862
static void test_mf_Blank(void)
Definition: metafile.c:2068
static COLORREF
Definition: metafile.c:44
static void test_mf_DCBrush(void)
Definition: metafile.c:2342
#define BMP_DIM
static void test_mf_GetPath(void)
Definition: metafile.c:2959
static void test_SetEnhMetaFileBits(void)
Definition: metafile.c:3626
static void test_SetWinMetaFileBits(void)
Definition: metafile.c:3215
#define LINE_Y
Definition: metafile.c:40
static void translate(POINT *pt, UINT count, const XFORM *xform)
Definition: metafile.c:2586
static const unsigned char EMF_BEZIER_BITS[]
Definition: metafile.c:1417
static void test_CopyMetaFile(void)
Definition: metafile.c:2102
static void test_emf_WorldTransform(void)
Definition: metafile.c:4227
static void test_emf_paths(void)
Definition: metafile.c:3844
static int compare_mf_disk_bits(LPCSTR name, const BYTE *bits, UINT bsize, const char *desc)
Definition: metafile.c:1629
static INT
Definition: metafile.c:43
static void init_function_pointers(void)
Definition: metafile.c:52
static void test_emf_polybezier(void)
Definition: metafile.c:3677
static void test_ExtTextOut(void)
Definition: metafile.c:179
static void test_mf_conversions(void)
Definition: metafile.c:3072
static void test_emf_DCBrush(void)
Definition: metafile.c:2014
static void dump_emf_bits(const HENHMETAFILE mf, const char *desc)
Definition: metafile.c:1668
static void dump_emf_record(const ENHMETARECORD *emr, const char *desc)
Definition: metafile.c:1716
static void dump_EMREXTTEXTOUT(const EMREXTTEXTOUTW *eto)
Definition: metafile.c:1738
static const unsigned char EMF_POLYPOLYLINE_BITS[]
Definition: metafile.c:1462
static int CALLBACK clip_emf_enum_proc(HDC hdc, HANDLETABLE *handle_table, const ENHMETARECORD *emr, int n_objs, LPARAM param)
Definition: metafile.c:2607
static void getwinmetafilebits(UINT mode, int scale, RECT *rc)
Definition: metafile.c:3370
static const unsigned char EMF_LINETO_MM_ANISOTROPIC_BITS[]
Definition: metafile.c:1217
static void checkConvertedFrameAndBounds(UINT buffer_size, BYTE *buffer, BOOL mfpIsNull, LONG mm, LONG xExt, LONG yExt, RECTL *rclBoundsExpected, RECTL *rclFrameExpected)
Definition: metafile.c:3176
static void test_mf_ExtTextOut_on_path(void)
Definition: metafile.c:2389
static const unsigned char EMF_DCBRUSH_BITS[]
Definition: metafile.c:1372
static const unsigned char MF_DCBRUSH_BITS[]
Definition: metafile.c:1068
static int clip_mf_enum_proc_seen_selectclipregion
Definition: metafile.c:2872
static void test_emf_clipping(void)
Definition: metafile.c:2713
#define MF_BUFSIZE
Definition: metafile.c:1017
static const unsigned char MF_CLIP_BITS[]
Definition: metafile.c:2826
static const unsigned char MF_GRAPHICS_BITS[]
Definition: metafile.c:1037
static const unsigned char EMF_CLIPPING[]
Definition: metafile.c:2549
static void set_rotation_xform(XFORM *out, float rad, int dx, int dy)
Definition: metafile.c:4037
static INT CALLBACK EmfEnumProc(HDC hdc, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR, INT nObj, LPARAM lpData)
Definition: metafile.c:3001
static LOGFONTA orig_lf
Definition: metafile.c:35
static DWORD rgn_rect_count(HRGN hrgn)
Definition: metafile.c:67
static const unsigned char EMF_GRADIENTFILL_BITS[]
Definition: metafile.c:1515
static const unsigned char EMF_PATH_BITS[]
Definition: metafile.c:3716
static int clip_mf_enum_proc_seen_selectobject
Definition: metafile.c:2873
static INT CALLBACK mf_enum_proc(HDC hdc, HANDLETABLE *ht, METARECORD *mr, INT nobj, LPARAM param)
Definition: metafile.c:1556
static void test_emf_BitBlt(void)
Definition: metafile.c:1937
static int CALLBACK clip_mf_enum_proc(HDC hdc, HANDLETABLE *handle_table, METARECORD *mr, int n_objs, LPARAM param)
Definition: metafile.c:2875
static const unsigned char SAMPLE_PATTERN_BRUSH[]
Definition: metafile.c:1020
static INT CALLBACK enum_emf_WorldTransform(HDC hdc, HANDLETABLE *ht, const ENHMETARECORD *emr, INT nobj, LPARAM param)
Definition: metafile.c:4069
static void check_dc_state(HDC hdc, int restore_no, int wnd_org_x, int wnd_org_y, int wnd_ext_x, int wnd_ext_y, int vp_org_x, int vp_org_y, int vp_ext_x, int vp_ext_y)
Definition: metafile.c:438
static const unsigned char MF_BLANK_BITS[]
Definition: metafile.c:1031
static const unsigned char MF_TEXTOUT_ON_PATH_BITS[]
Definition: metafile.c:1083
static int compare_mf_bits(const HMETAFILE mf, const unsigned char *bits, UINT bsize, const char *desc)
Definition: metafile.c:1599
static BOOL getConvertedFrameAndBounds(UINT buffer_size, BYTE *buffer, BOOL mfpIsNull, LONG mm, LONG xExt, LONG yExt, RECTL *rclBounds, RECTL *rclFrame)
Definition: metafile.c:3145
static void test_GetWinMetaFileBits(void)
Definition: metafile.c:3548
static BOOL emr_processed
Definition: metafile.c:36
static void test_mf_PatternBrush(void)
Definition: metafile.c:2296
static void test_mf_SaveDC(void)
Definition: metafile.c:865
static void test_mf_clipping(void)
Definition: metafile.c:2889
static void test_SaveDC(void)
Definition: metafile.c:656
static const unsigned char EMF_TEXTOUT_OUTLINE_ON_PATH_BITS[]
Definition: metafile.c:1129
static void test_emf_PolyPolyline(void)
Definition: metafile.c:3939
static BOOL xform_eq(const XFORM *a, const XFORM *b)
Definition: metafile.c:4059
#define GDI_GET_PROC(func)
Definition: metafile.c:47
static BOOL match_emf_record(const ENHMETARECORD *emr1, const ENHMETARECORD *emr2, const char *desc, BOOL ignore_scaling)
Definition: metafile.c:1754
static void test_emf_ExtTextOut_on_path(void)
Definition: metafile.c:2423
#define LINE_X
Definition: metafile.c:39
#define M_PI
Definition: metafile.c:32
static const unsigned char EMF_LINETO_MM_TEXT_BITS[]
Definition: metafile.c:1259
static const unsigned char EMF_LINETO_BITS[]
Definition: metafile.c:1175
static const unsigned char MF_PATTERN_BRUSH_BITS[]
Definition: metafile.c:1049
static BOOL is_equal_rect(const RECT *rc1, const RECT *rc2)
Definition: metafile.c:2599
static int CALLBACK eto_scale_enum_proc(HDC hdc, HANDLETABLE *handle_table, const ENHMETARECORD *emr, int n_objs, LPARAM param)
Definition: metafile.c:316
static const unsigned char EMF_EMPTY_PATH_BITS[]
Definition: metafile.c:3815
#define todo_wine
Definition: custom.c:89
static const unsigned char metafile[]
Definition: olepicture.c:138
static BOOL is_win9x
Definition: diskspace.c:33
#define min(a, b)
Definition: monoChain.cc:55
char temp_path[MAX_PATH]
Definition: mspatcha.c:123
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
Definition: muldiv.c:25
unsigned int UINT
Definition: ndis.h:50
#define RELATIVE(wait)
Definition: nfs41_driver.c:113
#define BOOL
Definition: nt_native.h:43
#define DWORD
Definition: nt_native.h:44
#define OBJ_METAFILE
Definition: objidl.idl:1417
#define OBJ_FONT
Definition: objidl.idl:1414
#define WS_POPUP
Definition: pedump.c:616
#define WS_VISIBLE
Definition: pedump.c:620
long LONG
Definition: pedump.c:60
static FILE * out
Definition: regtests2xml.c:44
#define test
Definition: rosglue.h:37
const WCHAR * str
int winetest_debug
#define win_skip
Definition: test.h:163
#define memset(x, y, z)
Definition: compat.h:39
HDC hdcBitmap
Definition: solcreate.cpp:9
& rect
Definition: startmenu.cpp:1413
LONG biYPelsPerMeter
Definition: amvideo.idl:38
LONG biXPelsPerMeter
Definition: amvideo.idl:37
BYTE lfClipPrecision
Definition: dimm.idl:52
BYTE lfQuality
Definition: dimm.idl:53
LONG lfHeight
Definition: dimm.idl:42
BYTE lfCharSet
Definition: dimm.idl:50
LONG lfWeight
Definition: dimm.idl:46
CHAR lfFaceName[LF_FACESIZE]
Definition: dimm.idl:55
long bottom
Definition: polytest.cpp:53
long right
Definition: polytest.cpp:53
long top
Definition: polytest.cpp:53
long left
Definition: polytest.cpp:53
LONG y
Definition: windef.h:330
LONG x
Definition: windef.h:329
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
FLOAT eDy
Definition: wingdi.h:1726
FLOAT eM11
Definition: wingdi.h:1721
FLOAT eM21
Definition: wingdi.h:1723
FLOAT eM22
Definition: wingdi.h:1724
FLOAT eM12
Definition: wingdi.h:1722
FLOAT eDx
Definition: wingdi.h:1725
Definition: emfdc.c:45
Definition: parser.c:49
Definition: name.c:39
DWORD iGraphicsMode
Definition: wingdi.h:1982
EMRTEXT emrtext
Definition: wingdi.h:1985
POINTS apts[1]
Definition: wingdi.h:2117
DWORD cptl
Definition: wingdi.h:2110
POINTL aptl[1]
Definition: wingdi.h:2111
LONG iRelative
Definition: wingdi.h:2151
DWORD fOptions
Definition: wingdi.h:1975
DWORD offDx
Definition: wingdi.h:1977
DWORD nChars
Definition: wingdi.h:1973
RECTL rcl
Definition: wingdi.h:1976
POINTL ptlReference
Definition: wingdi.h:1972
DWORD offString
Definition: wingdi.h:1974
DWORD iType
Definition: wingdi.h:1690
DWORD nSize
Definition: wingdi.h:1691
DWORD nRecords
Definition: wingdi.h:2327
RECTL rclFrame
Definition: wingdi.h:2323
SIZEL szlDevice
Definition: wingdi.h:2333
DWORD dSignature
Definition: wingdi.h:2324
RECTL rclBounds
Definition: wingdi.h:2322
DWORD dParm[1]
Definition: wingdi.h:2352
UINT lbStyle
Definition: wingdi.h:1747
ULONG_PTR lbHatch
Definition: wingdi.h:1749
COLORREF lbColor
Definition: wingdi.h:1748
HMETAFILE hMF
Definition: wingdi.h:2608
WORD mtHeaderSize
Definition: wingdi.h:2311
DWORD mtSize
Definition: wingdi.h:2313
WORD mtVersion
Definition: wingdi.h:2312
WORD mtType
Definition: wingdi.h:2310
DWORD rdSize
Definition: wingdi.h:2345
WORD rdParm[1]
Definition: wingdi.h:2347
WORD rdFunction
Definition: wingdi.h:2346
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
Definition: cmds.c:130
#define max(a, b)
Definition: svc.c:63
static void buffer_size(GLcontext *ctx, GLuint *width, GLuint *height)
Definition: swimpl.c:888
ecx edi movl ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl edx
Definition: synth_sse3d.h:87
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
float FLOAT
Definition: typedefs.h:69
int32_t INT
Definition: typedefs.h:58
int ret
#define RECT
Definition: precomp.h:26
HBITMAP WINAPI CreateDIBSection(HDC hDC, CONST BITMAPINFO *BitmapInfo, UINT Usage, VOID **Bits, HANDLE hSection, DWORD dwOffset)
Definition: bitmap.c:245
COLORREF WINAPI SetDCPenColor(_In_ HDC hdc, _In_ COLORREF crColor)
Definition: dc.c:941
DWORD WINAPI GetRelAbs(_In_ HDC hdc, _In_ DWORD dwIgnore)
Definition: dc.c:720
COLORREF WINAPI SetDCBrushColor(_In_ HDC hdc, _In_ COLORREF crColor)
Definition: dc.c:905
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG y1
Definition: winddi.h:3709
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3708
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
SIZE SIZEL
Definition: windef.h:338
DWORD COLORREF
Definition: windef.h:300
#define WINAPI
Definition: msvc.h:6
#define ERROR_INVALID_DATA
Definition: winerror.h:116
#define COMPLEXREGION
Definition: wingdi.h:363
BOOL WINAPI DeleteMetaFile(_In_ HMETAFILE)
#define BLACKNESS
Definition: wingdi.h:323
int WINAPI SetMapMode(_In_ HDC, _In_ int)
#define GM_COMPATIBLE
Definition: wingdi.h:864
BOOL WINAPI ArcTo(_In_ HDC hdc, _In_ INT xLeft, _In_ INT yTop, _In_ INT xRight, _In_ INT yBottom, _In_ INT xRadial1, _In_ INT yRadial1, _In_ INT xRadial2, _In_ INT yRadial2)
Definition: arc.c:79
HBRUSH WINAPI CreateBrushIndirect(_In_ const LOGBRUSH *plb)
int WINAPI GetBkMode(_In_ HDC)
#define EMR_SAVEDC
Definition: wingdi.h:107
INT WINAPI SetRelAbs(HDC, INT)
Definition: dc.c:733
#define EMR_SETWINDOWEXTEX
Definition: wingdi.h:83
UINT WINAPI GetEnhMetaFileBits(_In_ HENHMETAFILE hEMF, _In_ UINT nSize, _Out_writes_bytes_opt_(nSize) LPBYTE lpData)
#define EMR_SETVIEWPORTEXTEX
Definition: wingdi.h:85
#define DIB_RGB_COLORS
Definition: wingdi.h:367
BOOL WINAPI Chord(_In_ HDC hdc, _In_ INT xLeft, _In_ INT yTop, _In_ INT xRight, _In_ INT yBottom, _In_ INT xRadial1, _In_ INT yRadial1, _In_ INT xRadial2, _In_ INT yRadial2)
Definition: arc.c:119
#define HORZRES
Definition: wingdi.h:716
#define MM_MIN
Definition: wingdi.h:876
int WINAPI GetPolyFillMode(_In_ HDC)
BOOL WINAPI PolyBezier(_In_ HDC hdc, _In_reads_(cpt) const POINT *apt, _In_ DWORD cpt)
Definition: painting.c:263
#define MM_HIENGLISH
Definition: wingdi.h:868
#define EMR_EXTTEXTOUTA
Definition: wingdi.h:156
HGDIOBJ WINAPI GetStockObject(_In_ int)
#define MWT_LEFTMULTIPLY
Definition: wingdi.h:945
BOOL WINAPI Polyline(_In_ HDC hdc, _In_reads_(cpt) const POINT *apt, _In_ int cpt)
HBITMAP WINAPI CreateBitmap(_In_ INT cx, _In_ INT cy, _In_ UINT cPlanes, _In_ UINT cBitsPerPel, _In_opt_ const VOID *pvBits)
BOOL WINAPI Ellipse(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
#define EMR_POLYBEZIER16
Definition: wingdi.h:158
#define FW_DONTCARE
Definition: wingdi.h:368
BOOL WINAPI DeleteEnhMetaFile(_In_opt_ HENHMETAFILE)
BOOL WINAPI PolylineTo(_In_ HDC hdc, _In_reads_(cpt) const POINT *apt, _In_ DWORD cpt)
Definition: painting.c:354
#define MM_LOENGLISH
Definition: wingdi.h:871
#define EMR_SELECTOBJECT
Definition: wingdi.h:111
#define EMR_EXTSELECTCLIPRGN
Definition: wingdi.h:148
#define DT_RASDISPLAY
Definition: wingdi.h:708
int WINAPI GetClipBox(_In_ HDC, _Out_ LPRECT)
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
int WINAPI SetGraphicsMode(_In_ HDC, _In_ int)
Definition: dc.c:1233
#define GM_ADVANCED
Definition: wingdi.h:865
COLORREF WINAPI SetBkColor(_In_ HDC, _In_ COLORREF)
Definition: dc.c:999
HRGN WINAPI CreateRectRgn(_In_ int, _In_ int, _In_ int, _In_ int)
HFONT WINAPI CreateFontIndirectA(_In_ const LOGFONTA *)
int WINAPI GetObjectA(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
#define META_ESCAPE
Definition: wingdi.h:248
UINT WINAPI GetTextAlign(_In_ HDC)
Definition: text.c:838
HDC WINAPI CreateMetaFileA(_In_opt_ LPCSTR)
COLORREF WINAPI GetTextColor(_In_ HDC)
Definition: text.c:861
#define WHITENESS
Definition: wingdi.h:337
#define EMR_RESTOREDC
Definition: wingdi.h:108
#define MM_HIMETRIC
Definition: wingdi.h:869
BOOL WINAPI SetWindowOrgEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
Definition: coord.c:532
#define META_SELECTCLIPREGION
Definition: wingdi.h:254
BOOL WINAPI PlayEnhMetaFileRecord(_In_ HDC hdc, _In_reads_(cht) LPHANDLETABLE pht, _In_ CONST ENHMETARECORD *pmr, _In_ UINT cht)
#define BS_PATTERN
Definition: wingdi.h:1090
#define DEFAULT_QUALITY
Definition: wingdi.h:436
#define META_SETMAPMODE
Definition: wingdi.h:212
BOOL WINAPI SetViewportExtEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPSIZE)
Definition: coord.c:465
#define TA_UPDATECP
Definition: wingdi.h:936
#define NULLREGION
Definition: wingdi.h:361
#define VERTSIZE
Definition: wingdi.h:715
#define LOGPIXELSY
Definition: wingdi.h:719
BOOL WINAPI GetWindowOrgEx(_In_ HDC, _Out_ LPPOINT)
Definition: coord.c:439
UINT WINAPI SetTextAlign(_In_ HDC, _In_ UINT)
Definition: text.c:883
#define EMR_LINETO
Definition: wingdi.h:128
int WINAPI IntersectClipRect(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
int WINAPI ExcludeClipRect(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
#define EMR_EXTTEXTOUTW
Definition: wingdi.h:157
#define RDH_RECTANGLES
Definition: wingdi.h:669
BOOL WINAPI PolyBezierTo(_In_ HDC hdc, _In_reads_(cpt) const POINT *apt, _In_ DWORD cpt)
Definition: painting.c:281
BOOL WINAPI LPtoDP(_In_ HDC hdc, _Inout_updates_(c) LPPOINT lppt, _In_ int c)
HGDIOBJ WINAPI GetCurrentObject(_In_ HDC, _In_ UINT)
Definition: dc.c:428
#define POLYGONALCAPS
Definition: wingdi.h:779
int WINAPI SetArcDirection(_In_ HDC, _In_ int)
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
struct tagMETAFILEPICT * LPMETAFILEPICT
BOOL WINAPI MoveToEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
HDC WINAPI CreateDCA(_In_opt_ LPCSTR pszDriver, _In_opt_ LPCSTR pszDevice, _In_opt_ LPCSTR pszOutput, _In_opt_ const DEVMODEA *pdmInit)
BOOL WINAPI SelectClipPath(_In_ HDC, _In_ int)
BOOL WINAPI SetViewportOrgEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
Definition: coord.c:655
#define BLACKONWHITE
Definition: wingdi.h:952
HDC WINAPI CreateEnhMetaFileW(_In_opt_ HDC, _In_opt_ LPCWSTR, _In_opt_ LPCRECT, _In_opt_ LPCWSTR)
UINT WINAPI GetWinMetaFileBits(_In_ HENHMETAFILE hemf, _In_ UINT cbData16, _Out_writes_bytes_opt_(cbData16) LPBYTE pData16, _In_ INT iMapMode, _In_ HDC hdcRef)
#define MM_ANISOTROPIC
Definition: wingdi.h:867
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
int WINAPI GetClipRgn(_In_ HDC, _In_ HRGN)
HMETAFILE WINAPI CloseMetaFile(_In_ HDC hdc)
#define PT_LINETO
Definition: wingdi.h:885
#define EMR_EOF
Definition: wingdi.h:88
#define HORZSIZE
Definition: wingdi.h:714
#define RGN_COPY
Definition: wingdi.h:357
BOOL WINAPI SetWindowExtEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPSIZE)
BOOL WINAPI StretchBlt(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_opt_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD)
#define RGN_AND
Definition: wingdi.h:356
UINT WINAPI GetMetaFileBitsEx(_In_ HMETAFILE hMF, _In_ UINT cbBuffer, _Out_writes_bytes_opt_(cbBuffer) LPVOID lpData)
BOOL WINAPI EnumMetaFile(_In_ HDC, _In_ HMETAFILE, _In_ MFENUMPROC, _In_opt_ LPARAM)
#define CLR_INVALID
Definition: wingdi.h:883
BOOL WINAPI RestoreDC(_In_ HDC, _In_ int)
#define SRCCOPY
Definition: wingdi.h:333
#define VERTRES
Definition: wingdi.h:717
COLORREF WINAPI GetBkColor(_In_ HDC)
Definition: dc.c:978
#define MM_TWIPS
Definition: wingdi.h:874
BOOL WINAPI ExtTextOutA(_In_ HDC hdc, _In_ int x, _In_ int y, _In_ UINT options, _In_opt_ const RECT *lprect, _In_reads_opt_(c) LPCSTR lpString, _In_ UINT c, _In_reads_opt_(c) const INT *lpDx)
#define META_SETWINDOWORG
Definition: wingdi.h:221
HDC WINAPI CreateEnhMetaFileA(_In_opt_ HDC, _In_opt_ LPCSTR, _In_opt_ LPCRECT, _In_opt_ LPCSTR)
int WINAPI GetROP2(_In_ HDC)
Definition: dc.c:1093
#define TA_RTLREADING
Definition: wingdi.h:934
#define META_SETWINDOWEXT
Definition: wingdi.h:222
BOOL WINAPI GetWorldTransform(_In_ HDC, _Out_ LPXFORM)
Definition: coord.c:278
#define MM_LOMETRIC
Definition: wingdi.h:872
#define META_SELECTOBJECT
Definition: wingdi.h:255
#define EMR_SETWINDOWORGEX
Definition: wingdi.h:84
#define SIMPLEREGION
Definition: wingdi.h:362
#define ENHMETA_SIGNATURE
Definition: wingdi.h:204
int WINAPI GetStretchBltMode(_In_ HDC)
#define CURVECAPS
Definition: wingdi.h:759
HMETAFILE WINAPI SetMetaFileBitsEx(_In_ UINT cbBuffer, _In_reads_bytes_(cbBuffer) CONST BYTE *lpData)
BOOL WINAPI ExtTextOutW(_In_ HDC hdc, _In_ int x, _In_ int y, _In_ UINT options, _In_opt_ const RECT *lprect, _In_reads_opt_(c) LPCWSTR lpString, _In_ UINT c, _In_reads_opt_(c) const INT *lpDx)
#define OPAQUE
Definition: wingdi.h:949
#define MWT_RIGHTMULTIPLY
Definition: wingdi.h:946
#define MM_ISOTROPIC
Definition: wingdi.h:870
BOOL WINAPI EnumEnhMetaFile(_In_opt_ HDC, _In_ HENHMETAFILE, _In_ ENHMFENUMPROC, _In_opt_ PVOID, _In_opt_ LPCRECT)
#define ANSI_CHARSET
Definition: wingdi.h:383
#define PT_CLOSEFIGURE
Definition: wingdi.h:887
BOOL WINAPI GetWindowExtEx(_In_ HDC, _Out_ LPSIZE)
Definition: coord.c:411
#define AD_COUNTERCLOCKWISE
Definition: wingdi.h:667
#define MM_TEXT
Definition: wingdi.h:873
HENHMETAFILE WINAPI CloseEnhMetaFile(_In_ HDC hdc)
#define PT_MOVETO
Definition: wingdi.h:884
BOOL WINAPI StrokeAndFillPath(_In_ HDC)
#define BLACK_BRUSH
Definition: wingdi.h:896
#define EMR_POLYBEZIERTO16
Definition: wingdi.h:161
#define CLIP_DEFAULT_PRECIS
Definition: wingdi.h:426
BOOL WINAPI SetPixelV(_In_ HDC, _In_ int, _In_ int, _In_ COLORREF)
#define R2_NOT
Definition: wingdi.h:347
#define LOGPIXELSX
Definition: wingdi.h:718
#define PT_BEZIERTO
Definition: wingdi.h:886
HENHMETAFILE WINAPI SetEnhMetaFileBits(_In_ UINT nSize, _In_reads_bytes_(nSize) const BYTE *pb)
#define TA_BASELINE
Definition: wingdi.h:928
#define HALFTONE
Definition: wingdi.h:955
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
BOOL WINAPI Rectangle(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
DWORD WINAPI GetRegionData(_In_ HRGN hrgn, _In_ DWORD nCount, _Out_writes_bytes_to_opt_(nCount, return) LPRGNDATA lpRgnData)
HMETAFILE WINAPI CopyMetaFileA(_In_ HMETAFILE hmfSrc, _In_opt_ LPCSTR pszFile)
int WINAPI SetBkMode(_In_ HDC, _In_ int)
Definition: dc.c:1056
int WINAPI OffsetClipRgn(_In_ HDC, _In_ int, _In_ int)
COLORREF WINAPI SetTextColor(_In_ HDC, _In_ COLORREF)
Definition: text.c:918
#define LINECAPS
Definition: wingdi.h:770
#define EMR_SETVIEWPORTORGEX
Definition: wingdi.h:86
BOOL WINAPI SetWorldTransform(_In_ HDC, _In_ const XFORM *)
int WINAPI SetROP2(_In_ HDC, _In_ int)
Definition: dc.c:1114
UINT WINAPI GetEnhMetaFileHeader(_In_ HENHMETAFILE hemf, _In_ UINT nSize, _Out_writes_bytes_opt_(nSize) LPENHMETAHEADER lpEnhMetaHeader)
#define TA_CENTER
Definition: wingdi.h:931
BOOL WINAPI RoundRect(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int)
BOOL WINAPI DeleteDC(_In_ HDC)
#define DT_METAFILE
Definition: wingdi.h:712
BOOL WINAPI CombineTransform(_Out_ LPXFORM pxformResult, _In_ const XFORM *pxform1, _In_ const XFORM *pxform2)
Definition: coord.c:64
BOOL WINAPI PolyDraw(_In_ HDC hdc, _In_reads_(cpt) const POINT *apt, _In_reads_(cpt) const BYTE *aj, _In_ int cpt)
BOOL WINAPI GetViewportExtEx(_In_ HDC, _Out_ LPSIZE)
Definition: coord.c:351
int WINAPI SelectClipRgn(_In_ HDC, _In_opt_ HRGN)
#define AD_CLOCKWISE
Definition: wingdi.h:668
BOOL WINAPI EndPath(_In_ HDC)
#define EMR_POLYBEZIER
Definition: wingdi.h:76
#define EMR_HEADER
Definition: wingdi.h:75
#define EMR_POLYBEZIERTO
Definition: wingdi.h:79
#define EMR_MODIFYWORLDTRANSFORM
Definition: wingdi.h:110
BOOL WINAPI AngleArc(_In_ HDC hdc, _In_ INT x, _In_ INT y, _In_ DWORD dwRadius, _In_ FLOAT eStartAngle, _In_ FLOAT eSweepAngle)
Definition: arc.c:49
BOOL WINAPI LineTo(_In_ HDC, _In_ int, _In_ int)
BOOL WINAPI GetViewportOrgEx(_In_ HDC, _Out_ LPPOINT)
Definition: coord.c:383
BOOL WINAPI BeginPath(_In_ HDC hdc)
int WINAPI SetStretchBltMode(_In_ HDC, _In_ int)
Definition: dc.c:1373
#define R2_COPYPEN
Definition: wingdi.h:339
BOOL WINAPI GetCharWidthA(_In_ HDC hdc, _In_ UINT iFirst, _In_ UINT iLast, _Out_writes_(iLast+1 - iFirst) LPINT lpBuffer)
#define EMR_SETWORLDTRANSFORM
Definition: wingdi.h:109
BOOL WINAPI PolyPolyline(_In_ HDC hdc, _In_ const POINT *apt, _In_reads_(csz) const DWORD *asz, _In_ DWORD csz)
#define EMR_GDICOMMENT
Definition: wingdi.h:143
int WINAPI SaveDC(_In_ HDC)
BOOL WINAPI PlayEnhMetaFile(_In_ HDC, _In_ HENHMETAFILE, _In_ LPCRECT)
BOOL WINAPI ModifyWorldTransform(_In_ HDC, _In_opt_ const XFORM *, _In_ DWORD)
#define TECHNOLOGY
Definition: wingdi.h:706
#define MFCOMMENT
Definition: wingdi.h:1008
int WINAPI GetArcDirection(_In_ HDC)
Definition: dc.c:358
BOOL WINAPI CloseFigure(_In_ HDC hdc)
HENHMETAFILE WINAPI SetWinMetaFileBits(_In_ UINT nSize, _In_reads_bytes_(nSize) const BYTE *lpMeta16Data, _In_opt_ HDC hdcRef, _In_opt_ const METAFILEPICT *lpMFP)
int WINAPI GetPath(_In_ HDC hdc, _Out_writes_opt_(cpt) LPPOINT apt, _Out_writes_opt_(cpt) LPBYTE aj, int cpt)
BOOL WINAPI AbortPath(_In_ HDC hdc)
#define MM_MAX
Definition: wingdi.h:877
BOOL WINAPI Pie(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int)
int WINAPI SetPolyFillMode(_In_ HDC, _In_ int)
Definition: dc.c:1174
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
#define SM_CYSCREEN
Definition: winuser.h:963
HDC WINAPI GetDC(_In_opt_ HWND)
BOOL WINAPI OffsetRect(_Inout_ LPRECT, _In_ int, _In_ int)
#define SM_CXSCREEN
Definition: winuser.h:962
BOOL WINAPI DestroyWindow(_In_ HWND)
BOOL WINAPI EqualRect(_In_ LPCRECT, _In_ LPCRECT)
int WINAPI GetSystemMetrics(_In_ int)
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193