wininet: Support the Cache-Control max-age directive for setting url cache entry...
[wine/testsucceed.git] / dlls / gdiplus / tests / metafile.c
blobb467ce3ecf31322ec9baae50a5b148e32f3b3ad4
1 /*
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
21 #include "windows.h"
22 #include <stdio.h>
23 #include "gdiplus.h"
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
30 ULONG todo;
31 ULONG record_type;
32 int is_emfplus;
33 } emfplus_record;
35 typedef struct emfplus_check_state
37 const char *desc;
38 int count;
39 const struct emfplus_record *expected;
40 } emfplus_check_state;
42 static void check_record(int count, const char *desc, const struct emfplus_record *expected, const struct emfplus_record *actual)
44 ok(expected->record_type == actual->record_type,
45 "%s.%i: Expected record type 0x%x, got 0x%x\n", desc, count,
46 expected->record_type, actual->record_type);
48 ok(expected->is_emfplus == actual->is_emfplus,
49 "%s.%i: Expected is_emfplus %i, got %i\n", desc, count,
50 expected->record_type, actual->record_type);
53 typedef struct EmfPlusRecordHeader
55 WORD Type;
56 WORD Flags;
57 DWORD Size;
58 DWORD DataSize;
59 } EmfPlusRecordHeader;
61 static int CALLBACK enum_emf_proc(HDC hDC, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR,
62 int nObj, LPARAM lpData)
64 emfplus_check_state *state = (emfplus_check_state*)lpData;
65 emfplus_record actual;
67 if (lpEMFR->iType == EMR_GDICOMMENT)
69 const EMRGDICOMMENT *comment = (const EMRGDICOMMENT*)lpEMFR;
71 if (comment->cbData >= 4 && memcmp(comment->Data, "EMF+", 4) == 0)
73 int offset = 4;
75 while (offset + sizeof(EmfPlusRecordHeader) <= comment->cbData)
77 const EmfPlusRecordHeader *record = (const EmfPlusRecordHeader*)&comment->Data[offset];
79 ok(record->Size == record->DataSize + sizeof(EmfPlusRecordHeader),
80 "%s: EMF+ record datasize %u and size %u mismatch\n", state->desc, record->DataSize, record->Size);
82 ok(offset + record->DataSize <= comment->cbData,
83 "%s: EMF+ record truncated\n", state->desc);
85 if (offset + record->DataSize > comment->cbData)
86 return 0;
88 if (state->expected[state->count].record_type)
90 actual.todo = 0;
91 actual.record_type = record->Type;
92 actual.is_emfplus = 1;
94 check_record(state->count, state->desc, &state->expected[state->count], &actual);
96 state->count++;
98 else
100 ok(0, "%s: Unexpected EMF+ 0x%x record\n", state->desc, record->Type);
103 offset += record->Size;
106 ok(offset == comment->cbData, "%s: truncated EMF+ record data?\n", state->desc);
108 return 1;
112 if (state->expected[state->count].record_type)
114 actual.todo = 0;
115 actual.record_type = lpEMFR->iType;
116 actual.is_emfplus = 0;
118 check_record(state->count, state->desc, &state->expected[state->count], &actual);
120 state->count++;
122 else
124 ok(0, "%s: Unexpected EMF 0x%x record\n", state->desc, lpEMFR->iType);
127 return 1;
130 static void check_emfplus(HENHMETAFILE hemf, const emfplus_record *expected, const char *desc)
132 emfplus_check_state state;
134 state.desc = desc;
135 state.count = 0;
136 state.expected = expected;
138 EnumEnhMetaFile(0, hemf, enum_emf_proc, &state, NULL);
140 ok(expected[state.count].record_type == 0, "%s: Got %i records, expecting more\n", desc, state.count);
143 static const emfplus_record empty_records[] = {
144 {0, EMR_HEADER, 0},
145 {0, EmfPlusRecordTypeHeader, 1},
146 {0, EmfPlusRecordTypeEndOfFile, 1},
147 {0, EMR_EOF, 0},
151 static void test_empty(void)
153 GpStatus stat;
154 GpMetafile *metafile;
155 GpGraphics *graphics;
156 HDC hdc;
157 HENHMETAFILE hemf, dummy;
158 BOOL ret;
159 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
160 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
162 hdc = CreateCompatibleDC(0);
164 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
165 todo_wine expect(Ok, stat);
167 DeleteDC(hdc);
169 if (stat != Ok)
170 return;
172 stat = GdipGetHemfFromMetafile(metafile, &hemf);
173 expect(InvalidParameter, stat);
175 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
176 expect(Ok, stat);
178 stat = GdipGetHemfFromMetafile(metafile, &hemf);
179 expect(InvalidParameter, stat);
181 stat = GdipDeleteGraphics(graphics);
182 expect(Ok, stat);
184 stat = GdipGetHemfFromMetafile(metafile, &hemf);
185 expect(Ok, stat);
187 stat = GdipGetHemfFromMetafile(metafile, &dummy);
188 expect(InvalidParameter, stat);
190 stat = GdipDisposeImage((GpImage*)metafile);
191 expect(Ok, stat);
193 check_emfplus(hemf, empty_records, "empty");
195 ret = DeleteEnhMetaFile(hemf);
196 ok(ret != 0, "Failed to delete enhmetafile %p\n", hemf);
199 START_TEST(metafile)
201 struct GdiplusStartupInput gdiplusStartupInput;
202 ULONG_PTR gdiplusToken;
204 gdiplusStartupInput.GdiplusVersion = 1;
205 gdiplusStartupInput.DebugEventCallback = NULL;
206 gdiplusStartupInput.SuppressBackgroundThread = 0;
207 gdiplusStartupInput.SuppressExternalCodecs = 0;
209 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
211 test_empty();
213 GdiplusShutdown(gdiplusToken);