push c6fcfc519a04d046be60ec60e33d075a2146cc03
[wine/hacks.git] / dlls / gdi32 / tests / pen.c
blob2948467fba9c6ca0ccb7035e2a910eb0e424e07f
1 /*
2 * Unit test suite for pens
4 * Copyright 2006 Dmitry Timoshkov
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 <stdarg.h>
22 #include <assert.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wingdi.h"
27 #include "winuser.h"
29 #include "wine/test.h"
31 #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
32 #define expect2(expected, alt, got) ok(got == expected || got == alt, \
33 "Expected %.8x or %.8x, got %.8x\n", expected, alt, got)
35 static void test_logpen(void)
37 static const struct
39 UINT style;
40 INT width;
41 COLORREF color;
42 UINT ret_style;
43 INT ret_width;
44 COLORREF ret_color;
45 } pen[] = {
46 { PS_SOLID, -123, RGB(0x12,0x34,0x56), PS_SOLID, 123, RGB(0x12,0x34,0x56) },
47 { PS_SOLID, 0, RGB(0x12,0x34,0x56), PS_SOLID, 0, RGB(0x12,0x34,0x56) },
48 { PS_SOLID, 123, RGB(0x12,0x34,0x56), PS_SOLID, 123, RGB(0x12,0x34,0x56) },
49 { PS_DASH, 123, RGB(0x12,0x34,0x56), PS_DASH, 123, RGB(0x12,0x34,0x56) },
50 { PS_DOT, 123, RGB(0x12,0x34,0x56), PS_DOT, 123, RGB(0x12,0x34,0x56) },
51 { PS_DASHDOT, 123, RGB(0x12,0x34,0x56), PS_DASHDOT, 123, RGB(0x12,0x34,0x56) },
52 { PS_DASHDOTDOT, 123, RGB(0x12,0x34,0x56), PS_DASHDOTDOT, 123, RGB(0x12,0x34,0x56) },
53 { PS_NULL, -123, RGB(0x12,0x34,0x56), PS_NULL, 1, 0 },
54 { PS_NULL, 123, RGB(0x12,0x34,0x56), PS_NULL, 1, 0 },
55 { PS_INSIDEFRAME, 123, RGB(0x12,0x34,0x56), PS_INSIDEFRAME, 123, RGB(0x12,0x34,0x56) },
56 { PS_USERSTYLE, 123, RGB(0x12,0x34,0x56), PS_SOLID, 123, RGB(0x12,0x34,0x56) },
57 { PS_ALTERNATE, 123, RGB(0x12,0x34,0x56), PS_SOLID, 123, RGB(0x12,0x34,0x56) }
59 INT i, size;
60 HPEN hpen;
61 LOGPEN lp;
62 EXTLOGPEN elp;
63 LOGBRUSH lb;
64 DWORD_PTR unset_hatch;
65 DWORD obj_type, user_style[2] = { 0xabc, 0xdef };
66 struct
68 EXTLOGPEN elp;
69 DWORD style_data[10];
70 } ext_pen;
72 for (i = 0; i < sizeof(pen)/sizeof(pen[0]); i++)
74 trace("%d: testing style %u\n", i, pen[i].style);
76 /********************** cosmetic pens **********************/
77 /* CreatePenIndirect behaviour */
78 lp.lopnStyle = pen[i].style,
79 lp.lopnWidth.x = pen[i].width;
80 lp.lopnWidth.y = 11; /* just in case */
81 lp.lopnColor = pen[i].color;
82 SetLastError(0xdeadbeef);
83 hpen = CreatePenIndirect(&lp);
84 ok(hpen != 0, "CreatePen error %d\n", GetLastError());
86 obj_type = GetObjectType(hpen);
87 ok(obj_type == OBJ_PEN, "wrong object type %u\n", obj_type);
89 memset(&lp, 0xb0, sizeof(lp));
90 SetLastError(0xdeadbeef);
91 size = GetObject(hpen, sizeof(lp), &lp);
92 ok(size == sizeof(lp), "GetObject returned %d, error %d\n", size, GetLastError());
94 ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
95 ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %d\n", pen[i].ret_width, lp.lopnWidth.x);
96 ok(lp.lopnWidth.y == 0, "expected 0, got %d\n", lp.lopnWidth.y);
97 ok(lp.lopnColor == pen[i].ret_color, "expected %08x, got %08x\n", pen[i].ret_color, lp.lopnColor);
99 DeleteObject(hpen);
101 /* CreatePen behaviour */
102 SetLastError(0xdeadbeef);
103 hpen = CreatePen(pen[i].style, pen[i].width, pen[i].color);
104 ok(hpen != 0, "CreatePen error %d\n", GetLastError());
106 obj_type = GetObjectType(hpen);
107 ok(obj_type == OBJ_PEN, "wrong object type %u\n", obj_type);
109 /* check what's the real size of the object */
110 size = GetObject(hpen, 0, NULL);
111 ok(size == sizeof(lp), "GetObject returned %d, error %d\n", size, GetLastError());
113 /* ask for truncated data */
114 memset(&lp, 0xb0, sizeof(lp));
115 SetLastError(0xdeadbeef);
116 size = GetObject(hpen, sizeof(lp.lopnStyle), &lp);
117 ok(!size, "GetObject should fail: size %d, error %d\n", size, GetLastError());
119 /* see how larger buffer sizes are handled */
120 memset(&lp, 0xb0, sizeof(lp));
121 SetLastError(0xdeadbeef);
122 size = GetObject(hpen, sizeof(lp) * 4, &lp);
123 ok(size == sizeof(lp), "GetObject returned %d, error %d\n", size, GetLastError());
125 /* see how larger buffer sizes are handled */
126 memset(&elp, 0xb0, sizeof(elp));
127 SetLastError(0xdeadbeef);
128 size = GetObject(hpen, sizeof(elp) * 2, &elp);
129 ok(size == sizeof(lp), "GetObject returned %d, error %d\n", size, GetLastError());
131 memset(&lp, 0xb0, sizeof(lp));
132 SetLastError(0xdeadbeef);
133 size = GetObject(hpen, sizeof(lp), &lp);
134 ok(size == sizeof(lp), "GetObject returned %d, error %d\n", size, GetLastError());
136 ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
137 ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %d\n", pen[i].ret_width, lp.lopnWidth.x);
138 ok(lp.lopnWidth.y == 0, "expected 0, got %d\n", lp.lopnWidth.y);
139 ok(lp.lopnColor == pen[i].ret_color, "expected %08x, got %08x\n", pen[i].ret_color, lp.lopnColor);
141 memset(&elp, 0xb0, sizeof(elp));
142 SetLastError(0xdeadbeef);
143 size = GetObject(hpen, sizeof(elp), &elp);
145 /* for some reason XP differentiates PS_NULL here */
146 if (pen[i].style == PS_NULL)
148 ok(hpen == GetStockObject(NULL_PEN), "hpen should be a stock NULL_PEN\n");
149 ok(size == sizeof(EXTLOGPEN), "GetObject returned %d, error %d\n", size, GetLastError());
150 ok(elp.elpPenStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, elp.elpPenStyle);
151 ok(elp.elpWidth == 0, "expected 0, got %u\n", elp.elpWidth);
152 ok(elp.elpColor == pen[i].ret_color, "expected %08x, got %08x\n", pen[i].ret_color, elp.elpColor);
153 ok(elp.elpBrushStyle == BS_SOLID, "expected BS_SOLID, got %u\n", elp.elpBrushStyle);
154 ok(elp.elpHatch == 0, "expected 0, got %p\n", (void *)elp.elpHatch);
155 ok(elp.elpNumEntries == 0, "expected 0, got %x\n", elp.elpNumEntries);
157 else
159 ok(size == sizeof(LOGPEN), "GetObject returned %d, error %d\n", size, GetLastError());
160 memcpy(&lp, &elp, sizeof(lp));
161 ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
162 ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %d\n", pen[i].ret_width, lp.lopnWidth.x);
163 ok(lp.lopnWidth.y == 0, "expected 0, got %d\n", lp.lopnWidth.y);
164 ok(lp.lopnColor == pen[i].ret_color, "expected %08x, got %08x\n", pen[i].ret_color, lp.lopnColor);
167 DeleteObject(hpen);
169 /********** cosmetic pens created by ExtCreatePen ***********/
170 lb.lbStyle = BS_SOLID;
171 lb.lbColor = pen[i].color;
172 lb.lbHatch = HS_CROSS; /* just in case */
173 SetLastError(0xdeadbeef);
174 hpen = ExtCreatePen(pen[i].style, pen[i].width, &lb, 2, user_style);
175 if (pen[i].style != PS_USERSTYLE)
177 ok(hpen == 0, "ExtCreatePen should fail\n");
178 ok(GetLastError() == ERROR_INVALID_PARAMETER,
179 "wrong last error value %d\n", GetLastError());
180 SetLastError(0xdeadbeef);
181 hpen = ExtCreatePen(pen[i].style, pen[i].width, &lb, 0, NULL);
182 if (pen[i].style != PS_NULL)
184 ok(hpen == 0, "ExtCreatePen with width != 1 should fail\n");
185 ok(GetLastError() == ERROR_INVALID_PARAMETER,
186 "wrong last error value %d\n", GetLastError());
188 SetLastError(0xdeadbeef);
189 hpen = ExtCreatePen(pen[i].style, 1, &lb, 0, NULL);
192 else
194 ok(hpen == 0, "ExtCreatePen with width != 1 should fail\n");
195 ok(GetLastError() == ERROR_INVALID_PARAMETER,
196 "wrong last error value %d\n", GetLastError());
197 SetLastError(0xdeadbeef);
198 hpen = ExtCreatePen(pen[i].style, 1, &lb, 2, user_style);
200 if (pen[i].style == PS_INSIDEFRAME)
202 /* This style is applicable only for geometric pens */
203 ok(hpen == 0, "ExtCreatePen should fail\n");
204 goto test_geometric_pens;
206 ok(hpen != 0, "ExtCreatePen error %d\n", GetLastError());
208 obj_type = GetObjectType(hpen);
209 /* for some reason XP differentiates PS_NULL here */
210 if (pen[i].style == PS_NULL)
212 ok(obj_type == OBJ_PEN, "wrong object type %u\n", obj_type);
213 ok(hpen == GetStockObject(NULL_PEN), "hpen should be a stock NULL_PEN\n");
215 else
216 ok(obj_type == OBJ_EXTPEN, "wrong object type %u\n", obj_type);
218 /* check what's the real size of the object */
219 SetLastError(0xdeadbeef);
220 size = GetObject(hpen, 0, NULL);
221 switch (pen[i].style)
223 case PS_NULL:
224 ok(size == sizeof(LOGPEN),
225 "GetObject returned %d, error %d\n", size, GetLastError());
226 break;
228 case PS_USERSTYLE:
229 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry) + sizeof(user_style),
230 "GetObject returned %d, error %d\n", size, GetLastError());
231 break;
233 default:
234 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry),
235 "GetObject returned %d, error %d\n", size, GetLastError());
236 break;
239 /* ask for truncated data */
240 memset(&elp, 0xb0, sizeof(elp));
241 SetLastError(0xdeadbeef);
242 size = GetObject(hpen, sizeof(elp.elpPenStyle), &elp);
243 ok(!size, "GetObject should fail: size %d, error %d\n", size, GetLastError());
245 /* see how larger buffer sizes are handled */
246 memset(&ext_pen, 0xb0, sizeof(ext_pen));
247 SetLastError(0xdeadbeef);
248 size = GetObject(hpen, sizeof(ext_pen), &ext_pen.elp);
249 switch (pen[i].style)
251 case PS_NULL:
252 ok(size == sizeof(LOGPEN),
253 "GetObject returned %d, error %d\n", size, GetLastError());
254 memcpy(&lp, &ext_pen.elp, sizeof(lp));
255 ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
256 ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %d\n", pen[i].ret_width, lp.lopnWidth.x);
257 ok(lp.lopnWidth.y == 0, "expected 0, got %d\n", lp.lopnWidth.y);
258 ok(lp.lopnColor == pen[i].ret_color, "expected %08x, got %08x\n", pen[i].ret_color, lp.lopnColor);
260 /* for PS_NULL it also works this way */
261 memset(&elp, 0xb0, sizeof(elp));
262 memset(&unset_hatch, 0xb0, sizeof(unset_hatch));
263 SetLastError(0xdeadbeef);
264 size = GetObject(hpen, sizeof(elp), &elp);
265 ok(size == sizeof(EXTLOGPEN),
266 "GetObject returned %d, error %d\n", size, GetLastError());
267 ok(ext_pen.elp.elpHatch == unset_hatch, "expected 0xb0b0b0b0, got %p\n", (void *)ext_pen.elp.elpHatch);
268 ok(ext_pen.elp.elpNumEntries == 0xb0b0b0b0, "expected 0xb0b0b0b0, got %x\n", ext_pen.elp.elpNumEntries);
269 break;
271 case PS_USERSTYLE:
272 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry) + sizeof(user_style),
273 "GetObject returned %d, error %d\n", size, GetLastError());
274 ok(ext_pen.elp.elpHatch == HS_CROSS, "expected HS_CROSS, got %p\n", (void *)ext_pen.elp.elpHatch);
275 ok(ext_pen.elp.elpNumEntries == 2, "expected 0, got %x\n", ext_pen.elp.elpNumEntries);
276 ok(ext_pen.elp.elpStyleEntry[0] == 0xabc, "expected 0xabc, got %x\n", ext_pen.elp.elpStyleEntry[0]);
277 ok(ext_pen.elp.elpStyleEntry[1] == 0xdef, "expected 0xabc, got %x\n", ext_pen.elp.elpStyleEntry[1]);
278 break;
280 default:
281 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry),
282 "GetObject returned %d, error %d\n", size, GetLastError());
283 ok(ext_pen.elp.elpHatch == HS_CROSS, "expected HS_CROSS, got %p\n", (void *)ext_pen.elp.elpHatch);
284 ok(ext_pen.elp.elpNumEntries == 0, "expected 0, got %x\n", ext_pen.elp.elpNumEntries);
285 break;
288 if (pen[i].style == PS_USERSTYLE)
290 todo_wine
291 ok(ext_pen.elp.elpPenStyle == pen[i].style, "expected %x, got %x\n", pen[i].style, ext_pen.elp.elpPenStyle);
293 else
294 ok(ext_pen.elp.elpPenStyle == pen[i].style, "expected %x, got %x\n", pen[i].style, ext_pen.elp.elpPenStyle);
295 ok(ext_pen.elp.elpWidth == 1, "expected 1, got %x\n", ext_pen.elp.elpWidth);
296 ok(ext_pen.elp.elpColor == pen[i].ret_color, "expected %08x, got %08x\n", pen[i].ret_color, ext_pen.elp.elpColor);
297 ok(ext_pen.elp.elpBrushStyle == BS_SOLID, "expected BS_SOLID, got %x\n", ext_pen.elp.elpBrushStyle);
299 DeleteObject(hpen);
301 test_geometric_pens:
302 /********************** geometric pens **********************/
303 lb.lbStyle = BS_SOLID;
304 lb.lbColor = pen[i].color;
305 lb.lbHatch = HS_CROSS; /* just in case */
306 SetLastError(0xdeadbeef);
307 hpen = ExtCreatePen(PS_GEOMETRIC | pen[i].style, pen[i].width, &lb, 2, user_style);
308 if (pen[i].style != PS_USERSTYLE)
310 ok(hpen == 0, "ExtCreatePen should fail\n");
311 SetLastError(0xdeadbeef);
312 hpen = ExtCreatePen(PS_GEOMETRIC | pen[i].style, pen[i].width, &lb, 0, NULL);
314 if (pen[i].style == PS_ALTERNATE)
316 /* This style is applicable only for cosmetic pens */
317 ok(hpen == 0, "ExtCreatePen should fail\n");
318 continue;
320 ok(hpen != 0, "ExtCreatePen error %d\n", GetLastError());
322 obj_type = GetObjectType(hpen);
323 /* for some reason XP differentiates PS_NULL here */
324 if (pen[i].style == PS_NULL)
325 ok(obj_type == OBJ_PEN, "wrong object type %u\n", obj_type);
326 else
327 ok(obj_type == OBJ_EXTPEN, "wrong object type %u\n", obj_type);
329 /* check what's the real size of the object */
330 size = GetObject(hpen, 0, NULL);
331 switch (pen[i].style)
333 case PS_NULL:
334 ok(size == sizeof(LOGPEN),
335 "GetObject returned %d, error %d\n", size, GetLastError());
336 break;
338 case PS_USERSTYLE:
339 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry) + sizeof(user_style),
340 "GetObject returned %d, error %d\n", size, GetLastError());
341 break;
343 default:
344 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry),
345 "GetObject returned %d, error %d\n", size, GetLastError());
346 break;
349 /* ask for truncated data */
350 memset(&lp, 0xb0, sizeof(lp));
351 SetLastError(0xdeadbeef);
352 size = GetObject(hpen, sizeof(lp.lopnStyle), &lp);
353 ok(!size, "GetObject should fail: size %d, error %d\n", size, GetLastError());
355 memset(&lp, 0xb0, sizeof(lp));
356 SetLastError(0xdeadbeef);
357 size = GetObject(hpen, sizeof(lp), &lp);
358 /* for some reason XP differentiates PS_NULL here */
359 if (pen[i].style == PS_NULL)
361 ok(size == sizeof(LOGPEN), "GetObject returned %d, error %d\n", size, GetLastError());
362 ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
363 ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %d\n", pen[i].ret_width, lp.lopnWidth.x);
364 ok(lp.lopnWidth.y == 0, "expected 0, got %d\n", lp.lopnWidth.y);
365 ok(lp.lopnColor == pen[i].ret_color, "expected %08x, got %08x\n", pen[i].ret_color, lp.lopnColor);
367 else
368 /* XP doesn't set last error here */
369 ok(!size /*&& GetLastError() == ERROR_INVALID_PARAMETER*/,
370 "GetObject should fail: size %d, error %d\n", size, GetLastError());
372 memset(&ext_pen, 0xb0, sizeof(ext_pen));
373 SetLastError(0xdeadbeef);
374 /* buffer is too small for user styles */
375 size = GetObject(hpen, sizeof(elp), &ext_pen.elp);
376 switch (pen[i].style)
378 case PS_NULL:
379 ok(size == sizeof(EXTLOGPEN),
380 "GetObject returned %d, error %d\n", size, GetLastError());
381 ok(ext_pen.elp.elpHatch == 0, "expected 0, got %p\n", (void *)ext_pen.elp.elpHatch);
382 ok(ext_pen.elp.elpNumEntries == 0, "expected 0, got %x\n", ext_pen.elp.elpNumEntries);
384 /* for PS_NULL it also works this way */
385 SetLastError(0xdeadbeef);
386 size = GetObject(hpen, sizeof(ext_pen), &lp);
387 ok(size == sizeof(LOGPEN),
388 "GetObject returned %d, error %d\n", size, GetLastError());
389 ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
390 ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %d\n", pen[i].ret_width, lp.lopnWidth.x);
391 ok(lp.lopnWidth.y == 0, "expected 0, got %d\n", lp.lopnWidth.y);
392 ok(lp.lopnColor == pen[i].ret_color, "expected %08x, got %08x\n", pen[i].ret_color, lp.lopnColor);
393 break;
395 case PS_USERSTYLE:
396 ok(!size /*&& GetLastError() == ERROR_INVALID_PARAMETER*/,
397 "GetObject should fail: size %d, error %d\n", size, GetLastError());
398 size = GetObject(hpen, sizeof(ext_pen), &ext_pen.elp);
399 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry) + sizeof(user_style),
400 "GetObject returned %d, error %d\n", size, GetLastError());
401 ok(ext_pen.elp.elpHatch == HS_CROSS, "expected HS_CROSS, got %p\n", (void *)ext_pen.elp.elpHatch);
402 ok(ext_pen.elp.elpNumEntries == 2, "expected 0, got %x\n", ext_pen.elp.elpNumEntries);
403 ok(ext_pen.elp.elpStyleEntry[0] == 0xabc, "expected 0xabc, got %x\n", ext_pen.elp.elpStyleEntry[0]);
404 ok(ext_pen.elp.elpStyleEntry[1] == 0xdef, "expected 0xabc, got %x\n", ext_pen.elp.elpStyleEntry[1]);
405 break;
407 default:
408 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry),
409 "GetObject returned %d, error %d\n", size, GetLastError());
410 ok(ext_pen.elp.elpHatch == HS_CROSS, "expected HS_CROSS, got %p\n", (void *)ext_pen.elp.elpHatch);
411 ok(ext_pen.elp.elpNumEntries == 0, "expected 0, got %x\n", ext_pen.elp.elpNumEntries);
412 break;
415 /* for some reason XP differentiates PS_NULL here */
416 if (pen[i].style == PS_NULL)
417 ok(ext_pen.elp.elpPenStyle == pen[i].ret_style, "expected %x, got %x\n", pen[i].ret_style, ext_pen.elp.elpPenStyle);
418 else
420 ok(ext_pen.elp.elpPenStyle == (PS_GEOMETRIC | pen[i].style), "expected %x, got %x\n", PS_GEOMETRIC | pen[i].style, ext_pen.elp.elpPenStyle);
423 if (pen[i].style == PS_NULL)
424 ok(ext_pen.elp.elpWidth == 0, "expected 0, got %x\n", ext_pen.elp.elpWidth);
425 else
426 ok(ext_pen.elp.elpWidth == pen[i].ret_width, "expected %u, got %x\n", pen[i].ret_width, ext_pen.elp.elpWidth);
427 ok(ext_pen.elp.elpColor == pen[i].ret_color, "expected %08x, got %08x\n", pen[i].ret_color, ext_pen.elp.elpColor);
428 ok(ext_pen.elp.elpBrushStyle == BS_SOLID, "expected BS_SOLID, got %x\n", ext_pen.elp.elpBrushStyle);
430 DeleteObject(hpen);
434 static unsigned int atoi2(const char *s)
436 unsigned int ret = 0;
437 while(*s) ret = (ret << 1) | (*s++ == '1');
438 return ret;
441 #define TEST_LINE(x1, x2, z) \
442 { int buf = 0; \
443 SetBitmapBits(bmp, sizeof(buf), &buf); \
444 MoveToEx(hdc, x1, 0, NULL); \
445 LineTo(hdc, x2, 0); \
446 GetBitmapBits(bmp, sizeof(buf), &buf); \
447 expect(atoi2(z), buf); }
449 static void test_ps_alternate(void)
451 HDC hdc;
452 HBITMAP bmp;
453 HPEN pen;
454 LOGBRUSH lb;
456 lb.lbStyle = BS_SOLID;
457 lb.lbColor = RGB(0xff,0xff,0xff);
459 SetLastError(0xdeadbeef);
460 pen = ExtCreatePen(PS_COSMETIC|PS_ALTERNATE, 1, &lb, 0, NULL);
461 if(pen == NULL && GetLastError() == 0xdeadbeef) {
462 skip("looks like 9x, skipping PS_ALTERNATE tests\n");
463 return;
465 ok(pen != NULL, "gle=%d\n", GetLastError());
466 hdc = CreateCompatibleDC(NULL);
467 ok(hdc != NULL, "gle=%d\n", GetLastError());
468 bmp = CreateBitmap(8, 1, 1, 1, NULL);
469 ok(bmp != NULL, "gle=%d\n", GetLastError());
470 ok(SelectObject(hdc, bmp) != NULL, "gle=%d\n", GetLastError());
471 ok(SelectObject(hdc, pen) != NULL, "gle=%d\n", GetLastError());
472 ok(SetBkMode(hdc, TRANSPARENT), "gle=%d\n", GetLastError());
474 TEST_LINE(0, 1, "10000000")
475 TEST_LINE(0, 2, "10000000")
476 TEST_LINE(0, 3, "10100000")
477 TEST_LINE(0, 4, "10100000")
478 TEST_LINE(1, 4, "01010000")
479 TEST_LINE(1, 5, "01010000")
480 TEST_LINE(4, 8, "00001010")
482 DeleteObject(pen);
483 DeleteObject(bmp);
484 DeleteDC(hdc);
487 static void test_ps_userstyle(void)
489 static DWORD style[17] = {0, 2, 0, 4, 5, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 17};
490 static DWORD bad_style[5] = {0, 0, 0, 0, 0};
491 static DWORD bad_style2[5] = {4, 7, 8, 3, -1};
493 LOGBRUSH lb;
494 HPEN pen;
495 INT size, i;
497 struct
499 EXTLOGPEN elp;
500 DWORD style_data[15];
501 } ext_pen;
503 lb.lbColor = 0x00ff0000;
504 lb.lbStyle = BS_SOLID;
505 lb.lbHatch = 0;
507 pen = ExtCreatePen(PS_GEOMETRIC | PS_USERSTYLE, 50, &lb, 3, NULL);
508 ok(pen == 0, "ExtCreatePen should fail\n");
509 expect(ERROR_INVALID_PARAMETER, GetLastError());
510 DeleteObject(pen);
511 SetLastError(0xdeadbeef);
513 pen = ExtCreatePen(PS_GEOMETRIC | PS_USERSTYLE, 50, &lb, 0, style);
514 ok(pen == 0, "ExtCreatePen should fail\n");
515 expect2(0xdeadbeef, ERROR_INVALID_PARAMETER, GetLastError());
516 DeleteObject(pen);
517 SetLastError(0xdeadbeef);
519 pen = ExtCreatePen(PS_GEOMETRIC | PS_USERSTYLE, 50, &lb, 17, style);
520 ok(pen == 0, "ExtCreatePen should fail\n");
521 expect(ERROR_INVALID_PARAMETER, GetLastError());
522 DeleteObject(pen);
523 SetLastError(0xdeadbeef);
525 pen = ExtCreatePen(PS_GEOMETRIC | PS_USERSTYLE, 50, &lb, -1, style);
526 ok(pen == 0, "ExtCreatePen should fail\n");
527 expect(0xdeadbeef, GetLastError());
528 DeleteObject(pen);
529 SetLastError(0xdeadbeef);
531 pen = ExtCreatePen(PS_GEOMETRIC | PS_USERSTYLE, 50, &lb, 5, bad_style);
532 ok(pen == 0, "ExtCreatePen should fail\n");
533 expect(ERROR_INVALID_PARAMETER, GetLastError());
534 DeleteObject(pen);
535 SetLastError(0xdeadbeef);
537 pen = ExtCreatePen(PS_GEOMETRIC | PS_USERSTYLE, 50, &lb, 5, bad_style2);
538 ok(pen == 0, "ExtCreatePen should fail\n");
539 expect(ERROR_INVALID_PARAMETER, GetLastError());
540 DeleteObject(pen);
541 SetLastError(0xdeadbeef);
543 pen = ExtCreatePen(PS_GEOMETRIC | PS_USERSTYLE, 50, &lb, 16, style);
544 ok(pen != 0, "ExtCreatePen should not fail\n");
546 size = GetObject(pen, sizeof(ext_pen), &ext_pen);
547 expect(FIELD_OFFSET(EXTLOGPEN,elpStyleEntry[16]), size);
549 for(i = 0; i < 16; i++)
550 expect(style[i], ext_pen.elp.elpStyleEntry[i]);
552 DeleteObject(pen);
555 START_TEST(pen)
557 test_logpen();
558 test_ps_alternate();
559 test_ps_userstyle();