4 * Copyright 2011 Huw Davies
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
31 #include "wine/test.h"
33 static HCRYPTPROV crypt_prov;
34 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
36 static const DWORD rop3[256] =
38 0x000042, 0x010289, 0x020C89, 0x0300AA, 0x040C88, 0x0500A9, 0x060865, 0x0702C5,
39 0x080F08, 0x090245, 0x0A0329, 0x0B0B2A, 0x0C0324, 0x0D0B25, 0x0E08A5, 0x0F0001,
40 0x100C85, 0x1100A6, 0x120868, 0x1302C8, 0x140869, 0x1502C9, 0x165CCA, 0x171D54,
41 0x180D59, 0x191CC8, 0x1A06C5, 0x1B0768, 0x1C06CA, 0x1D0766, 0x1E01A5, 0x1F0385,
42 0x200F09, 0x210248, 0x220326, 0x230B24, 0x240D55, 0x251CC5, 0x2606C8, 0x271868,
43 0x280369, 0x2916CA, 0x2A0CC9, 0x2B1D58, 0x2C0784, 0x2D060A, 0x2E064A, 0x2F0E2A,
44 0x30032A, 0x310B28, 0x320688, 0x330008, 0x3406C4, 0x351864, 0x3601A8, 0x370388,
45 0x38078A, 0x390604, 0x3A0644, 0x3B0E24, 0x3C004A, 0x3D18A4, 0x3E1B24, 0x3F00EA,
46 0x400F0A, 0x410249, 0x420D5D, 0x431CC4, 0x440328, 0x450B29, 0x4606C6, 0x47076A,
47 0x480368, 0x4916C5, 0x4A0789, 0x4B0605, 0x4C0CC8, 0x4D1954, 0x4E0645, 0x4F0E25,
48 0x500325, 0x510B26, 0x5206C9, 0x530764, 0x5408A9, 0x550009, 0x5601A9, 0x570389,
49 0x580785, 0x590609, 0x5A0049, 0x5B18A9, 0x5C0649, 0x5D0E29, 0x5E1B29, 0x5F00E9,
50 0x600365, 0x6116C6, 0x620786, 0x630608, 0x640788, 0x650606, 0x660046, 0x6718A8,
51 0x6858A6, 0x690145, 0x6A01E9, 0x6B178A, 0x6C01E8, 0x6D1785, 0x6E1E28, 0x6F0C65,
52 0x700CC5, 0x711D5C, 0x720648, 0x730E28, 0x740646, 0x750E26, 0x761B28, 0x7700E6,
53 0x7801E5, 0x791786, 0x7A1E29, 0x7B0C68, 0x7C1E24, 0x7D0C69, 0x7E0955, 0x7F03C9,
54 0x8003E9, 0x810975, 0x820C49, 0x831E04, 0x840C48, 0x851E05, 0x8617A6, 0x8701C5,
55 0x8800C6, 0x891B08, 0x8A0E06, 0x8B0666, 0x8C0E08, 0x8D0668, 0x8E1D7C, 0x8F0CE5,
56 0x900C45, 0x911E08, 0x9217A9, 0x9301C4, 0x9417AA, 0x9501C9, 0x960169, 0x97588A,
57 0x981888, 0x990066, 0x9A0709, 0x9B07A8, 0x9C0704, 0x9D07A6, 0x9E16E6, 0x9F0345,
58 0xA000C9, 0xA11B05, 0xA20E09, 0xA30669, 0xA41885, 0xA50065, 0xA60706, 0xA707A5,
59 0xA803A9, 0xA90189, 0xAA0029, 0xAB0889, 0xAC0744, 0xAD06E9, 0xAE0B06, 0xAF0229,
60 0xB00E05, 0xB10665, 0xB21974, 0xB30CE8, 0xB4070A, 0xB507A9, 0xB616E9, 0xB70348,
61 0xB8074A, 0xB906E6, 0xBA0B09, 0xBB0226, 0xBC1CE4, 0xBD0D7D, 0xBE0269, 0xBF08C9,
62 0xC000CA, 0xC11B04, 0xC21884, 0xC3006A, 0xC40E04, 0xC50664, 0xC60708, 0xC707AA,
63 0xC803A8, 0xC90184, 0xCA0749, 0xCB06E4, 0xCC0020, 0xCD0888, 0xCE0B08, 0xCF0224,
64 0xD00E0A, 0xD1066A, 0xD20705, 0xD307A4, 0xD41D78, 0xD50CE9, 0xD616EA, 0xD70349,
65 0xD80745, 0xD906E8, 0xDA1CE9, 0xDB0D75, 0xDC0B04, 0xDD0228, 0xDE0268, 0xDF08C8,
66 0xE003A5, 0xE10185, 0xE20746, 0xE306EA, 0xE40748, 0xE506E5, 0xE61CE8, 0xE70D79,
67 0xE81D74, 0xE95CE6, 0xEA02E9, 0xEB0849, 0xEC02E8, 0xED0848, 0xEE0086, 0xEF0A08,
68 0xF00021, 0xF10885, 0xF20B05, 0xF3022A, 0xF40B0A, 0xF50225, 0xF60265, 0xF708C5,
69 0xF802E5, 0xF90845, 0xFA0089, 0xFB0A09, 0xFC008A, 0xFD0A0A, 0xFE02A9, 0xFF0062
72 static inline BOOL rop_uses_src(DWORD rop)
74 return (((rop & 0xcc0000) >> 2) != (rop & 0x330000));
77 static const char *sha1_graphics_a8r8g8b8[] =
79 "a3cadd34d95d3d5cc23344f69aab1c2e55935fcf",
80 "2426172d9e8fec27d9228088f382ef3c93717da9",
81 "9e8f27ca952cdba01dbf25d07c34e86a7820c012",
82 "664fac17803859a4015c6ae29e5538e314d5c827",
83 "17b2c177bdce5e94433574a928bda5c94a8cdfa5",
84 "fe6cc678fb13a3ead67839481bf22348adc69f52",
85 "d51bd330cec510cdccf5394328bd8e5411901e9e",
86 "df4aebf98d91f11be560dd232123b3ae327303d7",
87 "f2af53dd073a09b1031d0032d28da35c82adc566",
88 "eb5a963a6f7b25533ddfb8915e70865d037bd156",
89 "c387917268455017aa0b28bed73aa6554044bbb3",
90 "dcae44fee010dbf7a107797a503923fd8b1abe2e",
91 "6c530622a025d872a642e8f950867884d7b136cb",
92 "7c07d91b8f68fb31821701b3dcb96de018bf0c66",
93 "b2261353decda2712b83538ab434a49ce21f3172",
94 "ef654fedcb494dae79559f4db8b691ae2d522a3f",
95 "a694872f38e66a7ff471440c3e6a9310ef78328a",
96 "d7398de15b2837a58a62a701ca1b3384625afec4",
97 "e2a8eef4aeda3a0f6c950075acba38f1f9e0814d",
98 "8b66f14d51ecdeea12bc993302bb9b7d3ec085a1",
99 "7da9dd3d40d44d92deb9883fb7110443c2d5769a",
103 static const char *sha1_graphics_a8b8g8r8[] =
105 "a3cadd34d95d3d5cc23344f69aab1c2e55935fcf",
106 "e0bc877697093ed440e125154e247ca9d65e933c",
107 "c6d7faf5a502299f99d59eef3f7650bd63dbe108",
108 "9d8c05c3ebd786e7d052418e905a80a64bf7853d",
109 "3da12af0a810fd993fa3dbe23328a4fcd2b6c92a",
110 "b91c8f21cc4d7994abc551feff5b6927d267a9db",
111 "d49dd2c6a37e975b6dc3d201ccc217a788b30284",
112 "ca6753f9eb44529cf8c67cd6abcd4ed1ef758904",
113 "18c3ae944e0afb6c43c21cde093ddb22a27611e4",
114 "b753ebb39d90210cc717f57b53dd439f7de6b077",
115 "38c017dd1fff26b492a57e09f3ce2c4370faf225",
116 "94368cea5033b435454daa56d55546310675131e",
117 "bf57a6a37fb107d29ed3d45695919887abcb7902",
118 "3db0f8bcca3d94920aa57be6321202b8c3c08822",
119 "1f1fc165a4dae7ba118ddccb58a279bfe3876b0a",
120 "66da15b6780a4ca3b3d2eb1d1dba4e30f7b74964",
121 "42fefefe4435570fa8038ec759140c66c76570e9",
122 "3369889a67d6c79a24ee15f7d14374f9995215e4",
123 "4851c5b7d5bc18590e787c0c218a592ef504e738",
124 "9aa506e3df33e0d5298755aa4144e10eb4b5adcf",
125 "abdf003699364fe45fab7dc61e67c606d0063b40",
129 static const char *sha1_graphics_r5g5b5[] =
131 "2a2ab8b3c019e70b788ade028b0e9e53ffc529ae",
132 "847005cf7371f511bcc837251cde07b1796f6113",
133 "a8f75743a930843ec14d516cd048b6e0468e5d89",
134 "d094f51ce9b9daa9c1d9594ea88be2a2db651459",
135 "cf3928e240c9149788e1635b115a4e5baea0dd8f",
136 "a9034a905daa91757b4f63345c0e40638cd53ca8",
137 "15ee915d989e49bb9bab5b834d8f355bd067cd8f",
138 "99474fecf11df7b7035c35be6b8b697be9889418",
139 "cbc2898717f97ebb07c0c7cc04abde936dc5b584",
140 "29c896b591fdf4ddd23e5c0da1818c37e4686d94",
141 "4b5b275d33c1ebfe5bdc61df2ad125e865b800fa",
142 "92df731fa1f89550d9d4f7ea36c13f2e57c4b02a",
143 "420e39ff3bdd04c4b6cc2c98e99cb7993c7a0de5",
144 "1fabf0fdd046857b1974e31c1c1764fa9d1a762f",
145 "449092689226a1172b6086ba1181d6b6d6499f26",
146 "5c636ffadec10fbe440b552fe6436f3dbc607dcf",
147 "4aac89fc18c128eddb69eea658272af53138a1cb",
148 "9d21bcfdeaf1ca5d47eb823bdefc24d7a95f4f56",
149 "3a50ce21b3563a604b4fc9f247a30f5a981f1ba6",
150 "d7d97e28ed316f6596c737eb83baa5948d86b673",
151 "ecc2991277d7314f55b00e0f284ae3703aeef81e",
155 static const char *sha1_graphics_r4g4b4[] =
157 "2a2ab8b3c019e70b788ade028b0e9e53ffc529ae",
158 "cfa0ab83ee93283ad914c3748f0532da1697af1d",
159 "8bd18697d1ef27492805667a0bc956343ac08667",
160 "e8501c830321584474654f90e40eaf27dc21e6a8",
161 "d95ab10fcfb8447b41742e89f1ae8cd297a32fc4",
162 "821177710961d2cb5f7e7dfc0e06e767b6042753",
163 "667124365ffadeea1d8791bedda77a0c7b898de8",
164 "c9f23e684b600dea17575b4b17175fbd9106c3a9",
165 "7678876e50eae35d1eaa096aae25afaa0b864bf3",
166 "fb52b0c373a5f2a60b981604b120962942d2447a",
167 "5ab8dd07436681d762fa04ad7c6d71291c488924",
168 "0167981d9e1490a2ebd396ff7582f0943aa8e1b8",
169 "115a6bd382410a4a1d3c1fa71d8bf02536863e38",
170 "65c6d1228e3b6d63d42647f14217bc1658b70d9a",
171 "25fcb75aa687aac35b8f72640889fe92413e00c5",
172 "dbc8d66b419880108793db91c05766c0c6efd86d",
173 "6092ccbab6b6e073c6ac8244d122f2cfc453aa38",
174 "32b6e0aa79b7e96cd0ab2da167f6463c011023a8",
175 "d591232bbc2592462c819a9486750f64180518fd",
176 "0e183a4c30b3da345129cffe33fe0fc593d8666b",
177 "f14d9a4bd8a365b7c8f068a0dad481b6eb2b178b",
181 static const char *sha1_graphics_8[] =
183 "41728d7ff2bb425b5fc06521adeabf6cc73136f3",
184 "512246d4886ab889a090b167ba194577cb95272e",
185 "921e852d4564cb9e5ac15ff68b5207bebea871d1",
186 "9636b0ebefc443ea11949ccd28f6ca454277dd41",
187 "aa9050da55e6b6957c60b7d603fce539cb5c0048",
188 "e2b93aca15fb1233ac09a713dced1f4cd950b1e4",
189 "3e3a603fc26cc305aa27f88da7d2a3b0073877d8",
190 "390b2bf70daba36310683f46af9cd50b9a061396",
191 "82d21737e9a7247397a6c983a9b6d9a0452dd74d",
192 "2a8460af91675e01cbe9384eb6cd3eb2cb420960",
193 "1af53b1218ee9844fcda891b836d42f6b2f66bd5",
194 "da1cc34a9d9b779fc7849e03e214096026506464",
195 "5ba8f99ca034666effa556748c49a0f5a015125f",
196 "b67ba2f55659c75ac72c1112494461bb3086e1a4",
197 "73e2859ce849f756f954718ce3c90f02e31712b6",
198 "196d832d283bf642d2e481e5452ca175f7902761",
199 "9552f48b88982633a44001227abb847dae4d06b0",
200 "cfc67c325c7cdf96d90af9b3cceb8d0504cbb3b0",
201 "1f13ea0034db4b0ffa4ddcff9664fd892058f9cd",
202 "3caf512cfddfd463d0750cfe3cadb58548eb2ae8",
203 "4e5e7d5fd64818b2b3d3e793c88f603b699d2f0f",
207 static inline DWORD get_stride(BITMAPINFO *bmi)
209 return ((bmi->bmiHeader.biBitCount * bmi->bmiHeader.biWidth + 31) >> 3) & ~3;
212 static inline DWORD get_dib_size(BITMAPINFO *bmi)
214 return get_stride(bmi) * abs(bmi->bmiHeader.biHeight);
217 static char *hash_dib(BITMAPINFO *bmi, void *bits)
219 DWORD dib_size = get_dib_size(bmi);
223 DWORD hash_size = sizeof(hash_buf);
225 static const char *hex = "0123456789abcdef";
227 if(!crypt_prov) return NULL;
229 if(!CryptCreateHash(crypt_prov, CALG_SHA1, 0, 0, &hash)) return NULL;
231 CryptHashData(hash, bits, dib_size, 0);
233 CryptGetHashParam(hash, HP_HASHVAL, NULL, &hash_size, 0);
234 if(hash_size != sizeof(hash_buf)) return NULL;
236 CryptGetHashParam(hash, HP_HASHVAL, hash_buf, &hash_size, 0);
237 CryptDestroyHash(hash);
239 buf = HeapAlloc(GetProcessHeap(), 0, hash_size * 2 + 1);
241 for(i = 0; i < hash_size; i++)
243 buf[i * 2] = hex[hash_buf[i] >> 4];
244 buf[i * 2 + 1] = hex[hash_buf[i] & 0xf];
251 static void compare_hash(BITMAPINFO *bmi, BYTE *bits, const char ***sha1, const char *info)
253 char *hash = hash_dib(bmi, bits);
257 skip("SHA1 hashing unavailable on this platform\n");
263 ok(!strcmp(hash, **sha1), "%d: %s: expected hash %s got %s\n",
264 bmi->bmiHeader.biBitCount, info, **sha1, hash);
267 else ok(**sha1 != NULL, "missing hash, got \"%s\",\n", hash);
269 HeapFree(GetProcessHeap(), 0, hash);
272 static const RECT bias_check[] =
274 {100, 100, 200, 150},
275 {100, 100, 150, 200},
284 static const RECT hline_clips[] =
286 {120, 120, 140, 120}, /* unclipped */
287 {100, 122, 140, 122}, /* l edgecase */
288 { 99, 124, 140, 124}, /* l edgecase clipped */
289 {120, 126, 200, 126}, /* r edgecase */
290 {120, 128, 201, 128}, /* r edgecase clipped */
291 { 99, 130, 201, 130}, /* l and r clipped */
292 {120, 100, 140, 100}, /* t edgecase */
293 {120, 99, 140, 99}, /* t edgecase clipped */
294 {120, 199, 140, 199}, /* b edgecase */
295 {120, 200, 140, 200}, /* b edgecase clipped */
296 {120, 132, 310, 132}, /* inside two clip rects */
297 { 10, 134, 101, 134}, /* r end on l edgecase */
298 { 10, 136, 100, 136}, /* r end on l edgecase clipped */
299 {199, 138, 220, 138}, /* l end on r edgecase */
300 {200, 140, 220, 140} /* l end on r edgecase clipped */
303 static const RECT vline_clips[] =
305 {120, 120, 120, 140}, /* unclipped */
306 {100, 120, 100, 140}, /* l edgecase */
307 { 99, 120, 99, 140}, /* l edgecase clipped */
308 {199, 120, 199, 140}, /* r edgecase */
309 {200, 120, 200, 140}, /* r edgecase clipped */
310 {122, 99, 122, 201}, /* t and b clipped */
311 {124, 100, 124, 140}, /* t edgecase */
312 {126, 99, 126, 140}, /* t edgecase clipped */
313 {128, 120, 128, 200}, /* b edgecase */
314 {130, 120, 130, 201}, /* b edgecase clipped */
315 {132, 12, 132, 140}, /* inside two clip rects */
316 {134, 90, 134, 101}, /* b end on t edgecase */
317 {136, 90, 136, 100}, /* b end on t edgecase clipped */
318 {138, 199, 138, 220}, /* t end on b edgecase */
319 {140, 200, 140, 220} /* t end on b edgecase clipped */
322 static const RECT line_clips[] =
324 { 90, 110, 310, 120},
325 { 90, 120, 295, 130},
326 { 90, 190, 110, 240}, /* totally clipped, moving outcodes */
327 { 90, 130, 100, 135}, /* totally clipped, end pt on l edge */
328 { 90, 132, 101, 137}, /* end pt just inside l edge */
329 {200, 140, 210, 141}, /* totally clipped, start pt on r edge */
330 {199, 142, 210, 143} /* start pt just inside r edge */
333 static const RECT patblt_clips[] =
335 {120, 120, 140, 126}, /* unclipped */
336 {100, 130, 140, 136}, /* l edgecase */
337 { 99, 140, 140, 146}, /* l edgecase clipped */
338 {180, 130, 200, 136}, /* r edgecase */
339 {180, 140, 201, 146}, /* r edgecase clipped */
340 {120, 100, 130, 110}, /* t edgecase */
341 {140, 99, 150, 110}, /* t edgecase clipped */
342 {120, 180, 130, 200}, /* b edgecase */
343 {140, 180, 150, 201}, /* b edgecase */
344 {199, 150, 210, 156}, /* l edge on r edgecase */
345 {200, 160, 210, 166}, /* l edge on r edgecase clipped */
346 { 90, 150, 101, 156}, /* r edge on l edgecase */
347 { 90, 160, 100, 166}, /* r edge on l edgecase clipped */
348 {160, 90, 166, 101}, /* b edge on t edgecase */
349 {170, 90, 176, 101}, /* b edge on t edgecase clipped */
350 {160, 199, 166, 210}, /* t edge on b edgecase */
351 {170, 200, 176, 210}, /* t edge on b edgecase clipped */
354 static const RECT rectangles[] =
358 {120, 10, 120, 20}, /* zero width */
359 {120, 10, 130, 10}, /* zero height */
360 {120, 40, 121, 41}, /* 1 x 1 */
361 {130, 50, 132, 52}, /* 2 x 2 */
362 {140, 60, 143, 63}, /* 3 x 3 */
363 {150, 70, 154, 74}, /* 4 x 4 */
364 {120, 20, 121, 30}, /* width == 1 */
365 {130, 20, 132, 30}, /* width == 2 */
366 {140, 20, 143, 30}, /* width == 3 */
367 {200, 20, 210, 21}, /* height == 1 */
368 {200, 30, 210, 32}, /* height == 2 */
369 {200, 40, 210, 43} /* height == 3 */
372 static const BITMAPINFOHEADER dib_brush_header_32 = {sizeof(BITMAPINFOHEADER), 16, -16, 1, 32, BI_RGB, 0, 0, 0, 0, 0};
373 static const BITMAPINFOHEADER dib_brush_header_555 = {sizeof(BITMAPINFOHEADER), 16, -16, 1, 16, BI_RGB, 0, 0, 0, 0, 0};
375 static void draw_graphics(HDC hdc, BITMAPINFO *bmi, BYTE *bits, const char ***sha1)
377 DWORD dib_size = get_dib_size(bmi);
378 HPEN solid_pen, dashed_pen, orig_pen;
379 HBRUSH solid_brush, dib_brush, orig_brush;
382 BYTE dib_brush_buf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD) + 16 * 16 * sizeof(DWORD)]; /* Enough for 16 x 16 at 32 bpp */
383 BITMAPINFO *brush_bi = (BITMAPINFO*)dib_brush_buf;
386 memset(bits, 0xcc, dib_size);
387 compare_hash(bmi, bits, sha1, "empty");
389 solid_pen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0xff));
390 orig_pen = SelectObject(hdc, solid_pen);
391 SetBrushOrgEx(hdc, 0, 0, NULL);
393 /* horizontal and vertical lines */
394 for(i = 1; i <= 16; i++)
397 MoveToEx(hdc, 10, i * 3, NULL);
398 LineTo(hdc, 100, i * 3); /* l -> r */
399 MoveToEx(hdc, 100, 50 + i * 3, NULL);
400 LineTo(hdc, 10, 50 + i * 3); /* r -> l */
401 MoveToEx(hdc, 120 + i * 3, 10, NULL);
402 LineTo(hdc, 120 + i * 3, 100); /* t -> b */
403 MoveToEx(hdc, 170 + i * 3, 100, NULL);
404 LineTo(hdc, 170 + i * 3, 10); /* b -> t */
406 compare_hash(bmi, bits, sha1, "h and v solid lines");
407 memset(bits, 0xcc, dib_size);
410 SetROP2(hdc, R2_COPYPEN);
411 for(i = 0; i < 16; i++)
413 double s = sin(M_PI * i / 8.0);
414 double c = cos(M_PI * i / 8.0);
416 MoveToEx(hdc, 200.5 + 10 * c, 200.5 + 10 * s, NULL);
417 LineTo(hdc, 200.5 + 100 * c, 200.5 + 100 * s);
419 compare_hash(bmi, bits, sha1, "diagonal solid lines");
420 memset(bits, 0xcc, dib_size);
422 for(i = 0; i < sizeof(bias_check) / sizeof(bias_check[0]); i++)
424 MoveToEx(hdc, bias_check[i].left, bias_check[i].top, NULL);
425 LineTo(hdc, bias_check[i].right, bias_check[i].bottom);
427 compare_hash(bmi, bits, sha1, "more diagonal solid lines");
428 memset(bits, 0xcc, dib_size);
430 /* solid brush PatBlt */
431 solid_brush = CreateSolidBrush(RGB(0x33, 0xaa, 0xff));
432 orig_brush = SelectObject(hdc, solid_brush);
434 for(i = 0, y = 10; i < 256; i++)
438 ret = PatBlt(hdc, 10, y, 100, 10, rop3[i]);
440 if(rop_uses_src(rop3[i]))
441 ok(ret == FALSE, "got TRUE for %x\n", rop3[i]);
444 ok(ret, "got FALSE for %x\n", rop3[i]);
449 compare_hash(bmi, bits, sha1, "solid patblt");
450 memset(bits, 0xcc, dib_size);
453 hrgn = CreateRectRgn(10, 10, 200, 20);
454 hrgn2 = CreateRectRgn(100, 100, 200, 200);
455 CombineRgn(hrgn, hrgn, hrgn2, RGN_OR);
456 SetRectRgn(hrgn2, 290, 100, 300, 200);
457 CombineRgn(hrgn, hrgn, hrgn2, RGN_OR);
458 ExtSelectClipRgn(hdc, hrgn, RGN_COPY);
461 for(i = 0; i < sizeof(hline_clips)/sizeof(hline_clips[0]); i++)
463 MoveToEx(hdc, hline_clips[i].left, hline_clips[i].top, NULL);
464 LineTo(hdc, hline_clips[i].right, hline_clips[i].bottom);
466 compare_hash(bmi, bits, sha1, "clipped solid hlines");
467 memset(bits, 0xcc, dib_size);
469 for(i = 0; i < sizeof(vline_clips)/sizeof(vline_clips[0]); i++)
471 MoveToEx(hdc, vline_clips[i].left, vline_clips[i].top, NULL);
472 LineTo(hdc, vline_clips[i].right, vline_clips[i].bottom);
474 compare_hash(bmi, bits, sha1, "clipped solid vlines");
475 memset(bits, 0xcc, dib_size);
477 for(i = 0; i < sizeof(line_clips)/sizeof(line_clips[0]); i++)
479 MoveToEx(hdc, line_clips[i].left, line_clips[i].top, NULL);
480 LineTo(hdc, line_clips[i].right, line_clips[i].bottom);
482 compare_hash(bmi, bits, sha1, "clipped solid diagonal lines");
483 memset(bits, 0xcc, dib_size);
486 for(i = 0; i < sizeof(patblt_clips) / sizeof(patblt_clips[0]); i++)
488 PatBlt(hdc, patblt_clips[i].left, patblt_clips[i].top,
489 patblt_clips[i].right - patblt_clips[i].left,
490 patblt_clips[i].bottom - patblt_clips[i].top, PATCOPY);
492 compare_hash(bmi, bits, sha1, "clipped patblt");
493 memset(bits, 0xcc, dib_size);
495 /* clipped dashed lines */
496 dashed_pen = CreatePen(PS_DASH, 1, RGB(0xff, 0, 0));
497 SelectObject(hdc, dashed_pen);
498 SetBkMode(hdc, TRANSPARENT);
499 SetBkColor(hdc, RGB(0, 0xff, 0));
501 for(i = 0; i < sizeof(hline_clips)/sizeof(hline_clips[0]); i++)
503 MoveToEx(hdc, hline_clips[i].left, hline_clips[i].top, NULL);
504 LineTo(hdc, hline_clips[i].right, hline_clips[i].bottom);
506 compare_hash(bmi, bits, sha1, "clipped dashed hlines");
507 memset(bits, 0xcc, dib_size);
509 for(i = 0; i < sizeof(hline_clips)/sizeof(hline_clips[0]); i++)
511 MoveToEx(hdc, hline_clips[i].right - 1, hline_clips[i].bottom, NULL);
512 LineTo(hdc, hline_clips[i].left - 1, hline_clips[i].top);
514 compare_hash(bmi, bits, sha1, "clipped dashed hlines r -> l");
515 memset(bits, 0xcc, dib_size);
517 for(i = 0; i < sizeof(vline_clips)/sizeof(vline_clips[0]); i++)
519 MoveToEx(hdc, vline_clips[i].left, vline_clips[i].top, NULL);
520 LineTo(hdc, vline_clips[i].right, vline_clips[i].bottom);
522 compare_hash(bmi, bits, sha1, "clipped dashed vlines");
523 memset(bits, 0xcc, dib_size);
525 for(i = 0; i < sizeof(vline_clips)/sizeof(vline_clips[0]); i++)
527 MoveToEx(hdc, vline_clips[i].right, vline_clips[i].bottom - 1, NULL);
528 LineTo(hdc, vline_clips[i].left, vline_clips[i].top - 1);
530 compare_hash(bmi, bits, sha1, "clipped dashed vlines b -> t");
531 memset(bits, 0xcc, dib_size);
533 for(i = 0; i < sizeof(line_clips)/sizeof(line_clips[0]); i++)
535 MoveToEx(hdc, line_clips[i].left, line_clips[i].top, NULL);
536 LineTo(hdc, line_clips[i].right, line_clips[i].bottom);
538 compare_hash(bmi, bits, sha1, "clipped dashed diagonal lines");
539 memset(bits, 0xcc, dib_size);
541 SetBkMode(hdc, OPAQUE);
543 for(i = 0; i < sizeof(line_clips)/sizeof(line_clips[0]); i++)
545 MoveToEx(hdc, line_clips[i].left, line_clips[i].top, NULL);
546 LineTo(hdc, line_clips[i].right, line_clips[i].bottom);
548 compare_hash(bmi, bits, sha1, "clipped opaque dashed diagonal lines");
549 memset(bits, 0xcc, dib_size);
551 ExtSelectClipRgn(hdc, NULL, RGN_COPY);
553 /* DIB pattern brush */
555 brush_bi->bmiHeader = dib_brush_header_32;
556 brush_bits = (BYTE*)brush_bi + sizeof(BITMAPINFOHEADER);
557 memset(brush_bits, 0, 16 * 16 * sizeof(DWORD));
558 brush_bits[2] = 0xff;
559 brush_bits[6] = 0xff;
560 brush_bits[14] = 0xff;
561 brush_bits[65] = 0xff;
562 brush_bits[69] = 0xff;
564 dib_brush = CreateDIBPatternBrushPt(brush_bi, DIB_RGB_COLORS);
566 SelectObject(hdc, dib_brush);
567 SetBrushOrgEx(hdc, 1, 1, NULL);
569 for(i = 0, y = 10; i < 256; i++)
573 if(!rop_uses_src(rop3[i]))
575 ret = PatBlt(hdc, 10 + i, y, 100, 20, rop3[i]);
576 ok(ret, "got FALSE for %x\n", rop3[i]);
580 compare_hash(bmi, bits, sha1, "top-down dib brush patblt");
581 memset(bits, 0xcc, dib_size);
583 SelectObject(hdc, orig_brush);
584 DeleteObject(dib_brush);
586 /* Bottom-up DIB pattern brush */
588 brush_bi->bmiHeader.biHeight = -brush_bi->bmiHeader.biHeight;
590 dib_brush = CreateDIBPatternBrushPt(brush_bi, DIB_RGB_COLORS);
592 SelectObject(hdc, dib_brush);
593 SetBrushOrgEx(hdc, 100, 100, NULL);
595 for(i = 0, y = 10; i < 256; i++)
599 if(!rop_uses_src(rop3[i]))
601 ret = PatBlt(hdc, 10 + i, y, 100, 20, rop3[i]);
602 ok(ret, "got FALSE for %x\n", rop3[i]);
606 compare_hash(bmi, bits, sha1, "bottom-up dib brush patblt");
607 memset(bits, 0xcc, dib_size);
609 /* 555 dib pattern brush */
611 brush_bi->bmiHeader = dib_brush_header_555;
612 brush_bits = (BYTE*)brush_bi + sizeof(BITMAPINFOHEADER);
613 memset(brush_bits, 0, 16 * 16 * sizeof(WORD));
614 brush_bits[0] = brush_bits[1] = 0xff;
615 brush_bits[32] = brush_bits[34] = 0x7c;
617 dib_brush = CreateDIBPatternBrushPt(brush_bi, DIB_RGB_COLORS);
619 SelectObject(hdc, dib_brush);
620 SetBrushOrgEx(hdc, 1, 1, NULL);
622 for(i = 0, y = 10; i < 256; i++)
626 if(!rop_uses_src(rop3[i]))
628 ret = PatBlt(hdc, 10 + i, y, 100, 20, rop3[i]);
629 ok(ret, "got FALSE for %x\n", rop3[i]);
633 compare_hash(bmi, bits, sha1, "top-down 555 dib brush patblt");
634 memset(bits, 0xcc, dib_size);
636 SelectObject(hdc, orig_brush);
637 DeleteObject(dib_brush);
639 SetBrushOrgEx(hdc, 0, 0, NULL);
643 SelectObject(hdc, solid_pen);
644 SelectObject(hdc, solid_brush);
646 for(i = 0; i < sizeof(rectangles)/sizeof(rectangles[0]); i++)
648 Rectangle(hdc, rectangles[i].left, rectangles[i].top, rectangles[i].right, rectangles[i].bottom);
651 SelectObject(hdc, dashed_pen);
652 for(i = 0; i < sizeof(rectangles)/sizeof(rectangles[0]); i++)
654 Rectangle(hdc, rectangles[i].left, rectangles[i].top + 150, rectangles[i].right, rectangles[i].bottom + 150);
657 compare_hash(bmi, bits, sha1, "rectangles");
658 memset(bits, 0xcc, dib_size);
659 SelectObject(hdc, solid_pen);
664 compare_hash(bmi, bits, sha1, "PaintRgn");
665 memset(bits, 0xcc, dib_size);
671 win_skip("Don't have SetLayout\n");
676 pSetLayout(hdc, LAYOUT_RTL);
678 PatBlt(hdc, 10, 250, 10, 10, PATCOPY);
679 Rectangle(hdc, 100, 250, 110, 260);
680 compare_hash(bmi, bits, sha1, "rtl");
681 memset(bits, 0xcc, dib_size);
683 pSetLayout(hdc, LAYOUT_LTR);
686 SelectObject(hdc, orig_brush);
687 SelectObject(hdc, orig_pen);
689 DeleteObject(dib_brush);
690 DeleteObject(dashed_pen);
691 DeleteObject(solid_brush);
692 DeleteObject(solid_pen);
695 static void test_simple_graphics(void)
697 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
698 BITMAPINFO *bmi = (BITMAPINFO *)bmibuf;
699 DWORD *bit_fields = (DWORD*)(bmibuf + sizeof(BITMAPINFOHEADER));
702 HBITMAP dib, orig_bm;
706 mem_dc = CreateCompatibleDC(NULL);
710 memset(bmi, 0, sizeof(bmibuf));
711 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
712 bmi->bmiHeader.biHeight = 512;
713 bmi->bmiHeader.biWidth = 512;
714 bmi->bmiHeader.biBitCount = 32;
715 bmi->bmiHeader.biPlanes = 1;
716 bmi->bmiHeader.biCompression = BI_RGB;
718 dib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
719 ok(dib != NULL, "ret NULL\n");
720 ok(GetObjectW( dib, sizeof(ds), &ds ), "GetObject failed\n");
721 ok(ds.dsBitfields[0] == 0, "got %08x\n", ds.dsBitfields[0]);
722 ok(ds.dsBitfields[1] == 0, "got %08x\n", ds.dsBitfields[1]);
723 ok(ds.dsBitfields[2] == 0, "got %08x\n", ds.dsBitfields[2]);
724 ok(ds.dsBmih.biCompression == BI_RGB ||
725 broken(ds.dsBmih.biCompression == BI_BITFIELDS), /* nt4 sp1 and 2 */
726 "got %x\n", ds.dsBmih.biCompression);
728 orig_bm = SelectObject(mem_dc, dib);
730 sha1 = sha1_graphics_a8r8g8b8;
731 draw_graphics(mem_dc, bmi, bits, &sha1);
733 SelectObject(mem_dc, orig_bm);
736 /* a8r8g8b8 - bitfields. Should be the same as the regular 32 bit case.*/
737 trace("8888 - bitfields\n");
738 bmi->bmiHeader.biBitCount = 32;
739 bmi->bmiHeader.biCompression = BI_BITFIELDS;
740 bit_fields[0] = 0xff0000;
741 bit_fields[1] = 0x00ff00;
742 bit_fields[2] = 0x0000ff;
744 dib = CreateDIBSection(mem_dc, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
745 ok(dib != NULL, "ret NULL\n");
746 ok(GetObjectW( dib, sizeof(ds), &ds ), "GetObject failed\n");
747 ok(ds.dsBitfields[0] == 0xff0000, "got %08x\n", ds.dsBitfields[0]);
748 ok(ds.dsBitfields[1] == 0x00ff00, "got %08x\n", ds.dsBitfields[1]);
749 ok(ds.dsBitfields[2] == 0x0000ff, "got %08x\n", ds.dsBitfields[2]);
750 ok(ds.dsBmih.biCompression == BI_BITFIELDS, "got %x\n", ds.dsBmih.biCompression);
752 orig_bm = SelectObject(mem_dc, dib);
754 sha1 = sha1_graphics_a8r8g8b8;
755 draw_graphics(mem_dc, bmi, bits, &sha1);
757 SelectObject(mem_dc, orig_bm);
760 /* a8b8g8r8 - bitfields. */
761 trace("a8b8g8r8 - bitfields\n");
762 bmi->bmiHeader.biBitCount = 32;
763 bmi->bmiHeader.biCompression = BI_BITFIELDS;
764 bit_fields[0] = 0x0000ff;
765 bit_fields[1] = 0x00ff00;
766 bit_fields[2] = 0xff0000;
768 dib = CreateDIBSection(mem_dc, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
769 ok(dib != NULL, "ret NULL\n");
770 ok(GetObjectW( dib, sizeof(ds), &ds ), "GetObject failed\n");
771 ok(ds.dsBitfields[0] == 0x0000ff, "got %08x\n", ds.dsBitfields[0]);
772 ok(ds.dsBitfields[1] == 0x00ff00, "got %08x\n", ds.dsBitfields[1]);
773 ok(ds.dsBitfields[2] == 0xff0000, "got %08x\n", ds.dsBitfields[2]);
774 ok(ds.dsBmih.biCompression == BI_BITFIELDS, "got %x\n", ds.dsBmih.biCompression);
776 orig_bm = SelectObject(mem_dc, dib);
778 sha1 = sha1_graphics_a8b8g8r8;
779 draw_graphics(mem_dc, bmi, bits, &sha1);
781 SelectObject(mem_dc, orig_bm);
786 bmi->bmiHeader.biBitCount = 16;
787 bmi->bmiHeader.biCompression = BI_RGB;
789 dib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
790 ok(dib != NULL, "ret NULL\n");
791 ok(GetObjectW( dib, sizeof(ds), &ds ), "GetObject failed\n");
792 ok(ds.dsBitfields[0] == 0x7c00, "got %08x\n", ds.dsBitfields[0]);
793 ok(ds.dsBitfields[1] == 0x03e0, "got %08x\n", ds.dsBitfields[1]);
794 ok(ds.dsBitfields[2] == 0x001f, "got %08x\n", ds.dsBitfields[2]);
796 ok(ds.dsBmih.biCompression == BI_BITFIELDS, "got %x\n", ds.dsBmih.biCompression);
798 orig_bm = SelectObject(mem_dc, dib);
800 sha1 = sha1_graphics_r5g5b5;
801 draw_graphics(mem_dc, bmi, bits, &sha1);
803 SelectObject(mem_dc, orig_bm);
808 bmi->bmiHeader.biBitCount = 16;
809 bmi->bmiHeader.biCompression = BI_BITFIELDS;
810 bit_fields[0] = 0x0f00;
811 bit_fields[1] = 0x00f0;
812 bit_fields[2] = 0x000f;
813 dib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
814 ok(dib != NULL, "ret NULL\n");
815 ok(GetObjectW( dib, sizeof(ds), &ds ), "GetObject failed\n");
816 ok(ds.dsBitfields[0] == 0x0f00, "got %08x\n", ds.dsBitfields[0]);
817 ok(ds.dsBitfields[1] == 0x00f0, "got %08x\n", ds.dsBitfields[1]);
818 ok(ds.dsBitfields[2] == 0x000f, "got %08x\n", ds.dsBitfields[2]);
819 ok(ds.dsBmih.biCompression == BI_BITFIELDS, "got %x\n", ds.dsBmih.biCompression);
821 orig_bm = SelectObject(mem_dc, dib);
823 sha1 = sha1_graphics_r4g4b4;
824 draw_graphics(mem_dc, bmi, bits, &sha1);
826 SelectObject(mem_dc, orig_bm);
831 bmi->bmiHeader.biBitCount = 8;
832 bmi->bmiHeader.biCompression = BI_RGB;
833 bmi->bmiHeader.biClrUsed = 5;
834 bmi->bmiColors[0].rgbRed = 0xff;
835 bmi->bmiColors[0].rgbGreen = 0xff;
836 bmi->bmiColors[0].rgbBlue = 0xff;
837 bmi->bmiColors[1].rgbRed = 0;
838 bmi->bmiColors[1].rgbGreen = 0;
839 bmi->bmiColors[1].rgbBlue = 0;
840 bmi->bmiColors[2].rgbRed = 0xff;
841 bmi->bmiColors[2].rgbGreen = 0;
842 bmi->bmiColors[2].rgbBlue = 0;
843 bmi->bmiColors[3].rgbRed = 0;
844 bmi->bmiColors[3].rgbGreen = 0xff;
845 bmi->bmiColors[3].rgbBlue = 0;
846 bmi->bmiColors[4].rgbRed = 0;
847 bmi->bmiColors[4].rgbGreen = 0;
848 bmi->bmiColors[4].rgbBlue = 0xff;
850 dib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
851 ok(dib != NULL, "ret NULL\n");
853 orig_bm = SelectObject(mem_dc, dib);
855 sha1 = sha1_graphics_8;
856 draw_graphics(mem_dc, bmi, bits, &sha1);
858 SelectObject(mem_dc, orig_bm);
866 HMODULE mod = GetModuleHandleA("gdi32.dll");
867 pSetLayout = (void *)GetProcAddress( mod, "SetLayout" );
869 CryptAcquireContextW(&crypt_prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
871 test_simple_graphics();
873 CryptReleaseContext(crypt_prov, 0);