2 * Unit test suite for metafiles
4 * Copyright (C) 2011 Vincent Povirk for CodeWeavers
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.
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.
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
24 #include "wine/test.h"
26 #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
28 typedef struct emfplus_record
34 typedef struct emfplus_check_state
38 const struct emfplus_record
*expected
;
39 } emfplus_check_state
;
41 static void check_record(int count
, const char *desc
, const struct emfplus_record
*expected
, const struct emfplus_record
*actual
)
43 ok(expected
->record_type
== actual
->record_type
,
44 "%s.%i: Expected record type 0x%x, got 0x%x\n", desc
, count
,
45 expected
->record_type
, actual
->record_type
);
48 typedef struct EmfPlusRecordHeader
54 } EmfPlusRecordHeader
;
56 static int CALLBACK
enum_emf_proc(HDC hDC
, HANDLETABLE
*lpHTable
, const ENHMETARECORD
*lpEMFR
,
57 int nObj
, LPARAM lpData
)
59 emfplus_check_state
*state
= (emfplus_check_state
*)lpData
;
60 emfplus_record actual
;
62 if (lpEMFR
->iType
== EMR_GDICOMMENT
)
64 const EMRGDICOMMENT
*comment
= (const EMRGDICOMMENT
*)lpEMFR
;
66 if (comment
->cbData
>= 4 && memcmp(comment
->Data
, "EMF+", 4) == 0)
70 while (offset
+ sizeof(EmfPlusRecordHeader
) <= comment
->cbData
)
72 const EmfPlusRecordHeader
*record
= (const EmfPlusRecordHeader
*)&comment
->Data
[offset
];
74 ok(record
->Size
== record
->DataSize
+ sizeof(EmfPlusRecordHeader
),
75 "%s: EMF+ record datasize %u and size %u mismatch\n", state
->desc
, record
->DataSize
, record
->Size
);
77 ok(offset
+ record
->DataSize
<= comment
->cbData
,
78 "%s: EMF+ record truncated\n", state
->desc
);
80 if (offset
+ record
->DataSize
> comment
->cbData
)
83 if (state
->expected
[state
->count
].record_type
)
86 actual
.record_type
= record
->Type
;
88 check_record(state
->count
, state
->desc
, &state
->expected
[state
->count
], &actual
);
94 ok(0, "%s: Unexpected EMF+ 0x%x record\n", state
->desc
, record
->Type
);
97 offset
+= record
->Size
;
100 ok(offset
== comment
->cbData
, "%s: truncated EMF+ record data?\n", state
->desc
);
106 if (state
->expected
[state
->count
].record_type
)
109 actual
.record_type
= lpEMFR
->iType
;
111 check_record(state
->count
, state
->desc
, &state
->expected
[state
->count
], &actual
);
117 ok(0, "%s: Unexpected EMF 0x%x record\n", state
->desc
, lpEMFR
->iType
);
123 static void check_emfplus(HENHMETAFILE hemf
, const emfplus_record
*expected
, const char *desc
)
125 emfplus_check_state state
;
129 state
.expected
= expected
;
131 EnumEnhMetaFile(0, hemf
, enum_emf_proc
, &state
, NULL
);
133 ok(expected
[state
.count
].record_type
== 0, "%s: Got %i records, expecting more\n", desc
, state
.count
);
136 static BOOL CALLBACK
enum_metafile_proc(EmfPlusRecordType record_type
, unsigned int flags
,
137 unsigned int dataSize
, const unsigned char *pStr
, void *userdata
)
139 emfplus_check_state
*state
= (emfplus_check_state
*)userdata
;
140 emfplus_record actual
;
143 actual
.record_type
= record_type
;
146 ok(pStr
== NULL
, "non-NULL pStr\n");
148 if (state
->expected
[state
->count
].record_type
)
150 check_record(state
->count
, state
->desc
, &state
->expected
[state
->count
], &actual
);
156 ok(0, "%s: Unexpected EMF 0x%x record\n", state
->desc
, record_type
);
162 static void check_metafile(GpMetafile
*metafile
, const emfplus_record
*expected
, const char *desc
,
163 const GpPointF
*dst_points
, const GpRectF
*src_rect
, Unit src_unit
)
167 GpGraphics
*graphics
;
168 emfplus_check_state state
;
172 state
.expected
= expected
;
174 hdc
= CreateCompatibleDC(0);
176 stat
= GdipCreateFromHDC(hdc
, &graphics
);
179 stat
= GdipEnumerateMetafileSrcRectDestPoints(graphics
, metafile
, dst_points
,
180 3, src_rect
, src_unit
, enum_metafile_proc
, &state
, NULL
);
181 todo_wine
expect(Ok
, stat
);
183 todo_wine
ok(expected
[state
.count
].record_type
== 0, "%s: Got %i records, expecting more\n", desc
, state
.count
);
185 GdipDeleteGraphics(graphics
);
190 static const emfplus_record empty_records
[] = {
192 {0, EmfPlusRecordTypeHeader
},
193 {0, EmfPlusRecordTypeEndOfFile
},
198 static void test_empty(void)
201 GpMetafile
*metafile
;
202 GpGraphics
*graphics
;
204 HENHMETAFILE hemf
, dummy
;
206 static const GpRectF frame
= {0.0, 0.0, 100.0, 100.0};
207 static const GpPointF dst_points
[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
208 static const WCHAR description
[] = {'w','i','n','e','t','e','s','t',0};
210 hdc
= CreateCompatibleDC(0);
212 stat
= GdipRecordMetafile(NULL
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
213 expect(InvalidParameter
, stat
);
215 stat
= GdipRecordMetafile(hdc
, MetafileTypeInvalid
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
216 expect(InvalidParameter
, stat
);
218 stat
= GdipRecordMetafile(hdc
, MetafileTypeWmf
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
219 expect(InvalidParameter
, stat
);
221 stat
= GdipRecordMetafile(hdc
, MetafileTypeWmfPlaceable
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
222 expect(InvalidParameter
, stat
);
224 stat
= GdipRecordMetafile(hdc
, MetafileTypeEmfPlusDual
+1, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
225 expect(InvalidParameter
, stat
);
227 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitPixel
, description
, NULL
);
228 expect(InvalidParameter
, stat
);
230 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
238 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
239 expect(InvalidParameter
, stat
);
241 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
244 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
245 expect(InvalidParameter
, stat
);
247 stat
= GdipDeleteGraphics(graphics
);
250 check_metafile(metafile
, empty_records
, "empty metafile", dst_points
, &frame
, UnitPixel
);
252 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
255 stat
= GdipGetHemfFromMetafile(metafile
, &dummy
);
256 expect(InvalidParameter
, stat
);
258 stat
= GdipDisposeImage((GpImage
*)metafile
);
261 check_emfplus(hemf
, empty_records
, "empty emf");
263 ret
= DeleteEnhMetaFile(hemf
);
264 ok(ret
!= 0, "Failed to delete enhmetafile %p\n", hemf
);
269 struct GdiplusStartupInput gdiplusStartupInput
;
270 ULONG_PTR gdiplusToken
;
272 gdiplusStartupInput
.GdiplusVersion
= 1;
273 gdiplusStartupInput
.DebugEventCallback
= NULL
;
274 gdiplusStartupInput
.SuppressBackgroundThread
= 0;
275 gdiplusStartupInput
.SuppressExternalCodecs
= 0;
277 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, NULL
);
281 GdiplusShutdown(gdiplusToken
);