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 "a78b28472bb7ff480ddedd06b9cf2daa775fa7ae",
98 "e2a8eef4aeda3a0f6c950075acba38f1f9e0814d",
99 "8b66f14d51ecdeea12bc993302bb9b7d3ec085a1",
100 "7da9dd3d40d44d92deb9883fb7110443c2d5769a",
104 static const char *sha1_graphics_a8b8g8r8[] =
106 "a3cadd34d95d3d5cc23344f69aab1c2e55935fcf",
107 "e0bc877697093ed440e125154e247ca9d65e933c",
108 "c6d7faf5a502299f99d59eef3f7650bd63dbe108",
109 "9d8c05c3ebd786e7d052418e905a80a64bf7853d",
110 "3da12af0a810fd993fa3dbe23328a4fcd2b6c92a",
111 "b91c8f21cc4d7994abc551feff5b6927d267a9db",
112 "d49dd2c6a37e975b6dc3d201ccc217a788b30284",
113 "ca6753f9eb44529cf8c67cd6abcd4ed1ef758904",
114 "18c3ae944e0afb6c43c21cde093ddb22a27611e4",
115 "b753ebb39d90210cc717f57b53dd439f7de6b077",
116 "38c017dd1fff26b492a57e09f3ce2c4370faf225",
117 "94368cea5033b435454daa56d55546310675131e",
118 "bf57a6a37fb107d29ed3d45695919887abcb7902",
119 "3db0f8bcca3d94920aa57be6321202b8c3c08822",
120 "1f1fc165a4dae7ba118ddccb58a279bfe3876b0a",
121 "66da15b6780a4ca3b3d2eb1d1dba4e30f7b74964",
122 "42fefefe4435570fa8038ec759140c66c76570e9",
123 "3369889a67d6c79a24ee15f7d14374f9995215e4",
124 "473a1fd07df800c87a5d3286b642ace10c61c6af",
125 "4851c5b7d5bc18590e787c0c218a592ef504e738",
126 "9aa506e3df33e0d5298755aa4144e10eb4b5adcf",
127 "abdf003699364fe45fab7dc61e67c606d0063b40",
131 static const char *sha1_graphics_r5g5b5[] =
133 "2a2ab8b3c019e70b788ade028b0e9e53ffc529ae",
134 "847005cf7371f511bcc837251cde07b1796f6113",
135 "a8f75743a930843ec14d516cd048b6e0468e5d89",
136 "d094f51ce9b9daa9c1d9594ea88be2a2db651459",
137 "cf3928e240c9149788e1635b115a4e5baea0dd8f",
138 "a9034a905daa91757b4f63345c0e40638cd53ca8",
139 "15ee915d989e49bb9bab5b834d8f355bd067cd8f",
140 "99474fecf11df7b7035c35be6b8b697be9889418",
141 "cbc2898717f97ebb07c0c7cc04abde936dc5b584",
142 "29c896b591fdf4ddd23e5c0da1818c37e4686d94",
143 "4b5b275d33c1ebfe5bdc61df2ad125e865b800fa",
144 "92df731fa1f89550d9d4f7ea36c13f2e57c4b02a",
145 "420e39ff3bdd04c4b6cc2c98e99cb7993c7a0de5",
146 "1fabf0fdd046857b1974e31c1c1764fa9d1a762f",
147 "449092689226a1172b6086ba1181d6b6d6499f26",
148 "5c636ffadec10fbe440b552fe6436f3dbc607dcf",
149 "4aac89fc18c128eddb69eea658272af53138a1cb",
150 "9d21bcfdeaf1ca5d47eb823bdefc24d7a95f4f56",
151 "6daaf945a955928c5c124c880522ca4634fb2343",
152 "3a50ce21b3563a604b4fc9f247a30f5a981f1ba6",
153 "d7d97e28ed316f6596c737eb83baa5948d86b673",
154 "ecc2991277d7314f55b00e0f284ae3703aeef81e",
158 static const char *sha1_graphics_r4g4b4[] =
160 "2a2ab8b3c019e70b788ade028b0e9e53ffc529ae",
161 "cfa0ab83ee93283ad914c3748f0532da1697af1d",
162 "8bd18697d1ef27492805667a0bc956343ac08667",
163 "e8501c830321584474654f90e40eaf27dc21e6a8",
164 "d95ab10fcfb8447b41742e89f1ae8cd297a32fc4",
165 "821177710961d2cb5f7e7dfc0e06e767b6042753",
166 "667124365ffadeea1d8791bedda77a0c7b898de8",
167 "c9f23e684b600dea17575b4b17175fbd9106c3a9",
168 "7678876e50eae35d1eaa096aae25afaa0b864bf3",
169 "fb52b0c373a5f2a60b981604b120962942d2447a",
170 "5ab8dd07436681d762fa04ad7c6d71291c488924",
171 "0167981d9e1490a2ebd396ff7582f0943aa8e1b8",
172 "115a6bd382410a4a1d3c1fa71d8bf02536863e38",
173 "65c6d1228e3b6d63d42647f14217bc1658b70d9a",
174 "25fcb75aa687aac35b8f72640889fe92413e00c5",
175 "dbc8d66b419880108793db91c05766c0c6efd86d",
176 "6092ccbab6b6e073c6ac8244d122f2cfc453aa38",
177 "32b6e0aa79b7e96cd0ab2da167f6463c011023a8",
178 "1d283aa4d2b2114f7809fe59357d590c7c779aa7",
179 "d591232bbc2592462c819a9486750f64180518fd",
180 "0e183a4c30b3da345129cffe33fe0fc593d8666b",
181 "f14d9a4bd8a365b7c8f068a0dad481b6eb2b178b",
185 static const char *sha1_graphics_8[] =
187 "41728d7ff2bb425b5fc06521adeabf6cc73136f3",
188 "512246d4886ab889a090b167ba194577cb95272e",
189 "921e852d4564cb9e5ac15ff68b5207bebea871d1",
190 "9636b0ebefc443ea11949ccd28f6ca454277dd41",
191 "aa9050da55e6b6957c60b7d603fce539cb5c0048",
192 "e2b93aca15fb1233ac09a713dced1f4cd950b1e4",
193 "3e3a603fc26cc305aa27f88da7d2a3b0073877d8",
194 "390b2bf70daba36310683f46af9cd50b9a061396",
195 "82d21737e9a7247397a6c983a9b6d9a0452dd74d",
196 "2a8460af91675e01cbe9384eb6cd3eb2cb420960",
197 "1af53b1218ee9844fcda891b836d42f6b2f66bd5",
198 "da1cc34a9d9b779fc7849e03e214096026506464",
199 "5ba8f99ca034666effa556748c49a0f5a015125f",
200 "b67ba2f55659c75ac72c1112494461bb3086e1a4",
201 "73e2859ce849f756f954718ce3c90f02e31712b6",
202 "196d832d283bf642d2e481e5452ca175f7902761",
203 "9552f48b88982633a44001227abb847dae4d06b0",
204 "cfc67c325c7cdf96d90af9b3cceb8d0504cbb3b0",
205 "7262364067e03c7fa498af1d59d228d6c63b460e",
206 "1f13ea0034db4b0ffa4ddcff9664fd892058f9cd",
207 "3caf512cfddfd463d0750cfe3cadb58548eb2ae8",
208 "4e5e7d5fd64818b2b3d3e793c88f603b699d2f0f",
212 static inline DWORD get_stride(BITMAPINFO *bmi)
214 return ((bmi->bmiHeader.biBitCount * bmi->bmiHeader.biWidth + 31) >> 3) & ~3;
217 static inline DWORD get_dib_size(BITMAPINFO *bmi)
219 return get_stride(bmi) * abs(bmi->bmiHeader.biHeight);
222 static char *hash_dib(BITMAPINFO *bmi, void *bits)
224 DWORD dib_size = get_dib_size(bmi);
228 DWORD hash_size = sizeof(hash_buf);
230 static const char *hex = "0123456789abcdef";
232 if(!crypt_prov) return NULL;
234 if(!CryptCreateHash(crypt_prov, CALG_SHA1, 0, 0, &hash)) return NULL;
236 CryptHashData(hash, bits, dib_size, 0);
238 CryptGetHashParam(hash, HP_HASHVAL, NULL, &hash_size, 0);
239 if(hash_size != sizeof(hash_buf)) return NULL;
241 CryptGetHashParam(hash, HP_HASHVAL, hash_buf, &hash_size, 0);
242 CryptDestroyHash(hash);
244 buf = HeapAlloc(GetProcessHeap(), 0, hash_size * 2 + 1);
246 for(i = 0; i < hash_size; i++)
248 buf[i * 2] = hex[hash_buf[i] >> 4];
249 buf[i * 2 + 1] = hex[hash_buf[i] & 0xf];
256 static void compare_hash(BITMAPINFO *bmi, BYTE *bits, const char ***sha1, const char *info)
258 char *hash = hash_dib(bmi, bits);
262 skip("SHA1 hashing unavailable on this platform\n");
268 ok(!strcmp(hash, **sha1), "%d: %s: expected hash %s got %s\n",
269 bmi->bmiHeader.biBitCount, info, **sha1, hash);
272 else ok(**sha1 != NULL, "missing hash, got \"%s\",\n", hash);
274 HeapFree(GetProcessHeap(), 0, hash);
277 static const RECT bias_check[] =
279 {100, 100, 200, 150},
280 {100, 100, 150, 200},
289 static const RECT hline_clips[] =
291 {120, 120, 140, 120}, /* unclipped */
292 {100, 122, 140, 122}, /* l edgecase */
293 { 99, 124, 140, 124}, /* l edgecase clipped */
294 {120, 126, 200, 126}, /* r edgecase */
295 {120, 128, 201, 128}, /* r edgecase clipped */
296 { 99, 130, 201, 130}, /* l and r clipped */
297 {120, 100, 140, 100}, /* t edgecase */
298 {120, 99, 140, 99}, /* t edgecase clipped */
299 {120, 199, 140, 199}, /* b edgecase */
300 {120, 200, 140, 200}, /* b edgecase clipped */
301 {120, 132, 310, 132}, /* inside two clip rects */
302 { 10, 134, 101, 134}, /* r end on l edgecase */
303 { 10, 136, 100, 136}, /* r end on l edgecase clipped */
304 {199, 138, 220, 138}, /* l end on r edgecase */
305 {200, 140, 220, 140} /* l end on r edgecase clipped */
308 static const RECT vline_clips[] =
310 {120, 120, 120, 140}, /* unclipped */
311 {100, 120, 100, 140}, /* l edgecase */
312 { 99, 120, 99, 140}, /* l edgecase clipped */
313 {199, 120, 199, 140}, /* r edgecase */
314 {200, 120, 200, 140}, /* r edgecase clipped */
315 {122, 99, 122, 201}, /* t and b clipped */
316 {124, 100, 124, 140}, /* t edgecase */
317 {126, 99, 126, 140}, /* t edgecase clipped */
318 {128, 120, 128, 200}, /* b edgecase */
319 {130, 120, 130, 201}, /* b edgecase clipped */
320 {132, 12, 132, 140}, /* inside two clip rects */
321 {134, 90, 134, 101}, /* b end on t edgecase */
322 {136, 90, 136, 100}, /* b end on t edgecase clipped */
323 {138, 199, 138, 220}, /* t end on b edgecase */
324 {140, 200, 140, 220} /* t end on b edgecase clipped */
327 static const RECT line_clips[] =
329 { 90, 110, 310, 120},
330 { 90, 120, 295, 130},
331 { 90, 190, 110, 240}, /* totally clipped, moving outcodes */
332 { 90, 130, 100, 135}, /* totally clipped, end pt on l edge */
333 { 90, 132, 101, 137}, /* end pt just inside l edge */
334 {200, 140, 210, 141}, /* totally clipped, start pt on r edge */
335 {199, 142, 210, 143} /* start pt just inside r edge */
338 static const RECT patblt_clips[] =
340 {120, 120, 140, 126}, /* unclipped */
341 {100, 130, 140, 136}, /* l edgecase */
342 { 99, 140, 140, 146}, /* l edgecase clipped */
343 {180, 130, 200, 136}, /* r edgecase */
344 {180, 140, 201, 146}, /* r edgecase clipped */
345 {120, 100, 130, 110}, /* t edgecase */
346 {140, 99, 150, 110}, /* t edgecase clipped */
347 {120, 180, 130, 200}, /* b edgecase */
348 {140, 180, 150, 201}, /* b edgecase */
349 {199, 150, 210, 156}, /* l edge on r edgecase */
350 {200, 160, 210, 166}, /* l edge on r edgecase clipped */
351 { 90, 150, 101, 156}, /* r edge on l edgecase */
352 { 90, 160, 100, 166}, /* r edge on l edgecase clipped */
353 {160, 90, 166, 101}, /* b edge on t edgecase */
354 {170, 90, 176, 101}, /* b edge on t edgecase clipped */
355 {160, 199, 166, 210}, /* t edge on b edgecase */
356 {170, 200, 176, 210}, /* t edge on b edgecase clipped */
359 static const RECT rectangles[] =
363 {120, 10, 120, 20}, /* zero width */
364 {120, 10, 130, 10}, /* zero height */
365 {120, 40, 121, 41}, /* 1 x 1 */
366 {130, 50, 132, 52}, /* 2 x 2 */
367 {140, 60, 143, 63}, /* 3 x 3 */
368 {150, 70, 154, 74}, /* 4 x 4 */
369 {120, 20, 121, 30}, /* width == 1 */
370 {130, 20, 132, 30}, /* width == 2 */
371 {140, 20, 143, 30}, /* width == 3 */
372 {200, 20, 210, 21}, /* height == 1 */
373 {200, 30, 210, 32}, /* height == 2 */
374 {200, 40, 210, 43} /* height == 3 */
377 static const BITMAPINFOHEADER dib_brush_header_32 = {sizeof(BITMAPINFOHEADER), 16, -16, 1, 32, BI_RGB, 0, 0, 0, 0, 0};
378 static const BITMAPINFOHEADER dib_brush_header_555 = {sizeof(BITMAPINFOHEADER), 16, -16, 1, 16, BI_RGB, 0, 0, 0, 0, 0};
379 static const BITMAPINFOHEADER dib_brush_header_8 = {sizeof(BITMAPINFOHEADER), 16, -16, 1, 8, BI_RGB, 0, 0, 0, 0, 0};
381 static void draw_graphics(HDC hdc, BITMAPINFO *bmi, BYTE *bits, const char ***sha1)
383 DWORD dib_size = get_dib_size(bmi);
384 HPEN solid_pen, dashed_pen, orig_pen;
385 HBRUSH solid_brush, dib_brush, orig_brush;
388 BYTE dib_brush_buf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD) + 16 * 16 * sizeof(DWORD)]; /* Enough for 16 x 16 at 32 bpp */
389 BITMAPINFO *brush_bi = (BITMAPINFO*)dib_brush_buf;
392 memset(bits, 0xcc, dib_size);
393 compare_hash(bmi, bits, sha1, "empty");
395 solid_pen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0xff));
396 orig_pen = SelectObject(hdc, solid_pen);
397 SetBrushOrgEx(hdc, 0, 0, NULL);
399 /* horizontal and vertical lines */
400 for(i = 1; i <= 16; i++)
403 MoveToEx(hdc, 10, i * 3, NULL);
404 LineTo(hdc, 100, i * 3); /* l -> r */
405 MoveToEx(hdc, 100, 50 + i * 3, NULL);
406 LineTo(hdc, 10, 50 + i * 3); /* r -> l */
407 MoveToEx(hdc, 120 + i * 3, 10, NULL);
408 LineTo(hdc, 120 + i * 3, 100); /* t -> b */
409 MoveToEx(hdc, 170 + i * 3, 100, NULL);
410 LineTo(hdc, 170 + i * 3, 10); /* b -> t */
412 compare_hash(bmi, bits, sha1, "h and v solid lines");
413 memset(bits, 0xcc, dib_size);
416 SetROP2(hdc, R2_COPYPEN);
417 for(i = 0; i < 16; i++)
419 double s = sin(M_PI * i / 8.0);
420 double c = cos(M_PI * i / 8.0);
422 MoveToEx(hdc, 200.5 + 10 * c, 200.5 + 10 * s, NULL);
423 LineTo(hdc, 200.5 + 100 * c, 200.5 + 100 * s);
425 compare_hash(bmi, bits, sha1, "diagonal solid lines");
426 memset(bits, 0xcc, dib_size);
428 for(i = 0; i < sizeof(bias_check) / sizeof(bias_check[0]); i++)
430 MoveToEx(hdc, bias_check[i].left, bias_check[i].top, NULL);
431 LineTo(hdc, bias_check[i].right, bias_check[i].bottom);
433 compare_hash(bmi, bits, sha1, "more diagonal solid lines");
434 memset(bits, 0xcc, dib_size);
436 /* solid brush PatBlt */
437 solid_brush = CreateSolidBrush(RGB(0x33, 0xaa, 0xff));
438 orig_brush = SelectObject(hdc, solid_brush);
440 for(i = 0, y = 10; i < 256; i++)
444 ret = PatBlt(hdc, 10, y, 100, 10, rop3[i]);
446 if(rop_uses_src(rop3[i]))
447 ok(ret == FALSE, "got TRUE for %x\n", rop3[i]);
450 ok(ret, "got FALSE for %x\n", rop3[i]);
455 compare_hash(bmi, bits, sha1, "solid patblt");
456 memset(bits, 0xcc, dib_size);
459 hrgn = CreateRectRgn(10, 10, 200, 20);
460 hrgn2 = CreateRectRgn(100, 100, 200, 200);
461 CombineRgn(hrgn, hrgn, hrgn2, RGN_OR);
462 SetRectRgn(hrgn2, 290, 100, 300, 200);
463 CombineRgn(hrgn, hrgn, hrgn2, RGN_OR);
464 ExtSelectClipRgn(hdc, hrgn, RGN_COPY);
467 for(i = 0; i < sizeof(hline_clips)/sizeof(hline_clips[0]); i++)
469 MoveToEx(hdc, hline_clips[i].left, hline_clips[i].top, NULL);
470 LineTo(hdc, hline_clips[i].right, hline_clips[i].bottom);
472 compare_hash(bmi, bits, sha1, "clipped solid hlines");
473 memset(bits, 0xcc, dib_size);
475 for(i = 0; i < sizeof(vline_clips)/sizeof(vline_clips[0]); i++)
477 MoveToEx(hdc, vline_clips[i].left, vline_clips[i].top, NULL);
478 LineTo(hdc, vline_clips[i].right, vline_clips[i].bottom);
480 compare_hash(bmi, bits, sha1, "clipped solid vlines");
481 memset(bits, 0xcc, dib_size);
483 for(i = 0; i < sizeof(line_clips)/sizeof(line_clips[0]); i++)
485 MoveToEx(hdc, line_clips[i].left, line_clips[i].top, NULL);
486 LineTo(hdc, line_clips[i].right, line_clips[i].bottom);
488 compare_hash(bmi, bits, sha1, "clipped solid diagonal lines");
489 memset(bits, 0xcc, dib_size);
492 for(i = 0; i < sizeof(patblt_clips) / sizeof(patblt_clips[0]); i++)
494 PatBlt(hdc, patblt_clips[i].left, patblt_clips[i].top,
495 patblt_clips[i].right - patblt_clips[i].left,
496 patblt_clips[i].bottom - patblt_clips[i].top, PATCOPY);
498 compare_hash(bmi, bits, sha1, "clipped patblt");
499 memset(bits, 0xcc, dib_size);
501 /* clipped dashed lines */
502 dashed_pen = CreatePen(PS_DASH, 1, RGB(0xff, 0, 0));
503 SelectObject(hdc, dashed_pen);
504 SetBkMode(hdc, TRANSPARENT);
505 SetBkColor(hdc, RGB(0, 0xff, 0));
507 for(i = 0; i < sizeof(hline_clips)/sizeof(hline_clips[0]); i++)
509 MoveToEx(hdc, hline_clips[i].left, hline_clips[i].top, NULL);
510 LineTo(hdc, hline_clips[i].right, hline_clips[i].bottom);
512 compare_hash(bmi, bits, sha1, "clipped dashed hlines");
513 memset(bits, 0xcc, dib_size);
515 for(i = 0; i < sizeof(hline_clips)/sizeof(hline_clips[0]); i++)
517 MoveToEx(hdc, hline_clips[i].right - 1, hline_clips[i].bottom, NULL);
518 LineTo(hdc, hline_clips[i].left - 1, hline_clips[i].top);
520 compare_hash(bmi, bits, sha1, "clipped dashed hlines r -> l");
521 memset(bits, 0xcc, dib_size);
523 for(i = 0; i < sizeof(vline_clips)/sizeof(vline_clips[0]); i++)
525 MoveToEx(hdc, vline_clips[i].left, vline_clips[i].top, NULL);
526 LineTo(hdc, vline_clips[i].right, vline_clips[i].bottom);
528 compare_hash(bmi, bits, sha1, "clipped dashed vlines");
529 memset(bits, 0xcc, dib_size);
531 for(i = 0; i < sizeof(vline_clips)/sizeof(vline_clips[0]); i++)
533 MoveToEx(hdc, vline_clips[i].right, vline_clips[i].bottom - 1, NULL);
534 LineTo(hdc, vline_clips[i].left, vline_clips[i].top - 1);
536 compare_hash(bmi, bits, sha1, "clipped dashed vlines b -> t");
537 memset(bits, 0xcc, dib_size);
539 for(i = 0; i < sizeof(line_clips)/sizeof(line_clips[0]); i++)
541 MoveToEx(hdc, line_clips[i].left, line_clips[i].top, NULL);
542 LineTo(hdc, line_clips[i].right, line_clips[i].bottom);
544 compare_hash(bmi, bits, sha1, "clipped dashed diagonal lines");
545 memset(bits, 0xcc, dib_size);
547 SetBkMode(hdc, OPAQUE);
549 for(i = 0; i < sizeof(line_clips)/sizeof(line_clips[0]); i++)
551 MoveToEx(hdc, line_clips[i].left, line_clips[i].top, NULL);
552 LineTo(hdc, line_clips[i].right, line_clips[i].bottom);
554 compare_hash(bmi, bits, sha1, "clipped opaque dashed diagonal lines");
555 memset(bits, 0xcc, dib_size);
557 ExtSelectClipRgn(hdc, NULL, RGN_COPY);
559 /* DIB pattern brush */
561 brush_bi->bmiHeader = dib_brush_header_32;
562 brush_bits = (BYTE*)brush_bi + sizeof(BITMAPINFOHEADER);
563 memset(brush_bits, 0, 16 * 16 * sizeof(DWORD));
564 brush_bits[2] = 0xff;
565 brush_bits[6] = 0xff;
566 brush_bits[14] = 0xff;
567 brush_bits[65] = 0xff;
568 brush_bits[69] = 0xff;
570 dib_brush = CreateDIBPatternBrushPt(brush_bi, DIB_RGB_COLORS);
572 SelectObject(hdc, dib_brush);
573 SetBrushOrgEx(hdc, 1, 1, NULL);
575 for(i = 0, y = 10; i < 256; i++)
579 if(!rop_uses_src(rop3[i]))
581 ret = PatBlt(hdc, 10 + i, y, 100, 20, rop3[i]);
582 ok(ret, "got FALSE for %x\n", rop3[i]);
586 compare_hash(bmi, bits, sha1, "top-down dib brush patblt");
587 memset(bits, 0xcc, dib_size);
589 SelectObject(hdc, orig_brush);
590 DeleteObject(dib_brush);
592 /* Bottom-up DIB pattern brush */
594 brush_bi->bmiHeader.biHeight = -brush_bi->bmiHeader.biHeight;
596 dib_brush = CreateDIBPatternBrushPt(brush_bi, DIB_RGB_COLORS);
598 SelectObject(hdc, dib_brush);
599 SetBrushOrgEx(hdc, 100, 100, NULL);
601 for(i = 0, y = 10; i < 256; i++)
605 if(!rop_uses_src(rop3[i]))
607 ret = PatBlt(hdc, 10 + i, y, 100, 20, rop3[i]);
608 ok(ret, "got FALSE for %x\n", rop3[i]);
612 compare_hash(bmi, bits, sha1, "bottom-up dib brush patblt");
613 memset(bits, 0xcc, dib_size);
615 /* 555 dib pattern brush */
617 brush_bi->bmiHeader = dib_brush_header_555;
618 brush_bits = (BYTE*)brush_bi + sizeof(BITMAPINFOHEADER);
619 memset(brush_bits, 0, 16 * 16 * sizeof(WORD));
620 brush_bits[0] = brush_bits[1] = 0xff;
621 brush_bits[32] = brush_bits[34] = 0x7c;
623 dib_brush = CreateDIBPatternBrushPt(brush_bi, DIB_RGB_COLORS);
625 SelectObject(hdc, dib_brush);
626 SetBrushOrgEx(hdc, 1, 1, NULL);
628 for(i = 0, y = 10; i < 256; i++)
632 if(!rop_uses_src(rop3[i]))
634 ret = PatBlt(hdc, 10 + i, y, 100, 20, rop3[i]);
635 ok(ret, "got FALSE for %x\n", rop3[i]);
639 compare_hash(bmi, bits, sha1, "top-down 555 dib brush patblt");
640 memset(bits, 0xcc, dib_size);
642 SelectObject(hdc, orig_brush);
643 DeleteObject(dib_brush);
645 SetBrushOrgEx(hdc, 0, 0, NULL);
647 /* 8 bpp dib pattern brush */
649 brush_bi->bmiHeader = dib_brush_header_8;
650 brush_bi->bmiHeader.biClrUsed = 3;
651 memset(brush_bi->bmiColors, 0, brush_bi->bmiHeader.biClrUsed * sizeof(RGBQUAD));
652 brush_bi->bmiColors[0].rgbRed = 0xff;
653 brush_bi->bmiColors[1].rgbRed = 0xff;
654 brush_bi->bmiColors[1].rgbGreen = 0xff;
655 brush_bi->bmiColors[1].rgbBlue = 0xff;
657 brush_bits = (BYTE*)brush_bi + sizeof(BITMAPINFOHEADER) + brush_bi->bmiHeader.biClrUsed * sizeof(RGBQUAD);
658 memset(brush_bits, 0, 16 * 16 * sizeof(BYTE));
659 brush_bits[0] = brush_bits[1] = 1;
660 brush_bits[16] = brush_bits[17] = 2;
661 brush_bits[32] = brush_bits[33] = 6;
663 dib_brush = CreateDIBPatternBrushPt(brush_bi, DIB_RGB_COLORS);
665 SelectObject(hdc, dib_brush);
666 SetBrushOrgEx(hdc, 1, 1, NULL);
668 for(i = 0, y = 10; i < 256; i++)
672 if(!rop_uses_src(rop3[i]))
674 ret = PatBlt(hdc, 10 + i, y, 100, 20, rop3[i]);
675 ok(ret, "got FALSE for %x\n", rop3[i]);
679 compare_hash(bmi, bits, sha1, "top-down 8 bpp dib brush patblt");
680 memset(bits, 0xcc, dib_size);
682 SelectObject(hdc, orig_brush);
683 DeleteObject(dib_brush);
687 SelectObject(hdc, solid_pen);
688 SelectObject(hdc, solid_brush);
690 for(i = 0; i < sizeof(rectangles)/sizeof(rectangles[0]); i++)
692 Rectangle(hdc, rectangles[i].left, rectangles[i].top, rectangles[i].right, rectangles[i].bottom);
695 SelectObject(hdc, dashed_pen);
696 for(i = 0; i < sizeof(rectangles)/sizeof(rectangles[0]); i++)
698 Rectangle(hdc, rectangles[i].left, rectangles[i].top + 150, rectangles[i].right, rectangles[i].bottom + 150);
701 compare_hash(bmi, bits, sha1, "rectangles");
702 memset(bits, 0xcc, dib_size);
703 SelectObject(hdc, solid_pen);
708 compare_hash(bmi, bits, sha1, "PaintRgn");
709 memset(bits, 0xcc, dib_size);
715 win_skip("Don't have SetLayout\n");
720 pSetLayout(hdc, LAYOUT_RTL);
722 PatBlt(hdc, 10, 250, 10, 10, PATCOPY);
723 Rectangle(hdc, 100, 250, 110, 260);
724 compare_hash(bmi, bits, sha1, "rtl");
725 memset(bits, 0xcc, dib_size);
727 pSetLayout(hdc, LAYOUT_LTR);
730 SelectObject(hdc, orig_brush);
731 SelectObject(hdc, orig_pen);
733 DeleteObject(dib_brush);
734 DeleteObject(dashed_pen);
735 DeleteObject(solid_brush);
736 DeleteObject(solid_pen);
739 static void test_simple_graphics(void)
741 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
742 BITMAPINFO *bmi = (BITMAPINFO *)bmibuf;
743 DWORD *bit_fields = (DWORD*)(bmibuf + sizeof(BITMAPINFOHEADER));
746 HBITMAP dib, orig_bm;
750 mem_dc = CreateCompatibleDC(NULL);
754 memset(bmi, 0, sizeof(bmibuf));
755 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
756 bmi->bmiHeader.biHeight = 512;
757 bmi->bmiHeader.biWidth = 512;
758 bmi->bmiHeader.biBitCount = 32;
759 bmi->bmiHeader.biPlanes = 1;
760 bmi->bmiHeader.biCompression = BI_RGB;
762 dib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
763 ok(dib != NULL, "ret NULL\n");
764 ok(GetObjectW( dib, sizeof(ds), &ds ), "GetObject failed\n");
765 ok(ds.dsBitfields[0] == 0, "got %08x\n", ds.dsBitfields[0]);
766 ok(ds.dsBitfields[1] == 0, "got %08x\n", ds.dsBitfields[1]);
767 ok(ds.dsBitfields[2] == 0, "got %08x\n", ds.dsBitfields[2]);
768 ok(ds.dsBmih.biCompression == BI_RGB ||
769 broken(ds.dsBmih.biCompression == BI_BITFIELDS), /* nt4 sp1 and 2 */
770 "got %x\n", ds.dsBmih.biCompression);
772 orig_bm = SelectObject(mem_dc, dib);
774 sha1 = sha1_graphics_a8r8g8b8;
775 draw_graphics(mem_dc, bmi, bits, &sha1);
777 SelectObject(mem_dc, orig_bm);
780 /* a8r8g8b8 - bitfields. Should be the same as the regular 32 bit case.*/
781 trace("8888 - bitfields\n");
782 bmi->bmiHeader.biBitCount = 32;
783 bmi->bmiHeader.biCompression = BI_BITFIELDS;
784 bit_fields[0] = 0xff0000;
785 bit_fields[1] = 0x00ff00;
786 bit_fields[2] = 0x0000ff;
788 dib = CreateDIBSection(mem_dc, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
789 ok(dib != NULL, "ret NULL\n");
790 ok(GetObjectW( dib, sizeof(ds), &ds ), "GetObject failed\n");
791 ok(ds.dsBitfields[0] == 0xff0000, "got %08x\n", ds.dsBitfields[0]);
792 ok(ds.dsBitfields[1] == 0x00ff00, "got %08x\n", ds.dsBitfields[1]);
793 ok(ds.dsBitfields[2] == 0x0000ff, "got %08x\n", ds.dsBitfields[2]);
794 ok(ds.dsBmih.biCompression == BI_BITFIELDS, "got %x\n", ds.dsBmih.biCompression);
796 orig_bm = SelectObject(mem_dc, dib);
798 sha1 = sha1_graphics_a8r8g8b8;
799 draw_graphics(mem_dc, bmi, bits, &sha1);
801 SelectObject(mem_dc, orig_bm);
804 /* a8b8g8r8 - bitfields. */
805 trace("a8b8g8r8 - bitfields\n");
806 bmi->bmiHeader.biBitCount = 32;
807 bmi->bmiHeader.biCompression = BI_BITFIELDS;
808 bit_fields[0] = 0x0000ff;
809 bit_fields[1] = 0x00ff00;
810 bit_fields[2] = 0xff0000;
812 dib = CreateDIBSection(mem_dc, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
813 ok(dib != NULL, "ret NULL\n");
814 ok(GetObjectW( dib, sizeof(ds), &ds ), "GetObject failed\n");
815 ok(ds.dsBitfields[0] == 0x0000ff, "got %08x\n", ds.dsBitfields[0]);
816 ok(ds.dsBitfields[1] == 0x00ff00, "got %08x\n", ds.dsBitfields[1]);
817 ok(ds.dsBitfields[2] == 0xff0000, "got %08x\n", ds.dsBitfields[2]);
818 ok(ds.dsBmih.biCompression == BI_BITFIELDS, "got %x\n", ds.dsBmih.biCompression);
820 orig_bm = SelectObject(mem_dc, dib);
822 sha1 = sha1_graphics_a8b8g8r8;
823 draw_graphics(mem_dc, bmi, bits, &sha1);
825 SelectObject(mem_dc, orig_bm);
830 bmi->bmiHeader.biBitCount = 16;
831 bmi->bmiHeader.biCompression = BI_RGB;
833 dib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
834 ok(dib != NULL, "ret NULL\n");
835 ok(GetObjectW( dib, sizeof(ds), &ds ), "GetObject failed\n");
836 ok(ds.dsBitfields[0] == 0x7c00, "got %08x\n", ds.dsBitfields[0]);
837 ok(ds.dsBitfields[1] == 0x03e0, "got %08x\n", ds.dsBitfields[1]);
838 ok(ds.dsBitfields[2] == 0x001f, "got %08x\n", ds.dsBitfields[2]);
840 ok(ds.dsBmih.biCompression == BI_BITFIELDS, "got %x\n", ds.dsBmih.biCompression);
842 orig_bm = SelectObject(mem_dc, dib);
844 sha1 = sha1_graphics_r5g5b5;
845 draw_graphics(mem_dc, bmi, bits, &sha1);
847 SelectObject(mem_dc, orig_bm);
852 bmi->bmiHeader.biBitCount = 16;
853 bmi->bmiHeader.biCompression = BI_BITFIELDS;
854 bit_fields[0] = 0x0f00;
855 bit_fields[1] = 0x00f0;
856 bit_fields[2] = 0x000f;
857 dib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
858 ok(dib != NULL, "ret NULL\n");
859 ok(GetObjectW( dib, sizeof(ds), &ds ), "GetObject failed\n");
860 ok(ds.dsBitfields[0] == 0x0f00, "got %08x\n", ds.dsBitfields[0]);
861 ok(ds.dsBitfields[1] == 0x00f0, "got %08x\n", ds.dsBitfields[1]);
862 ok(ds.dsBitfields[2] == 0x000f, "got %08x\n", ds.dsBitfields[2]);
863 ok(ds.dsBmih.biCompression == BI_BITFIELDS, "got %x\n", ds.dsBmih.biCompression);
865 orig_bm = SelectObject(mem_dc, dib);
867 sha1 = sha1_graphics_r4g4b4;
868 draw_graphics(mem_dc, bmi, bits, &sha1);
870 SelectObject(mem_dc, orig_bm);
875 bmi->bmiHeader.biBitCount = 8;
876 bmi->bmiHeader.biCompression = BI_RGB;
877 bmi->bmiHeader.biClrUsed = 5;
878 bmi->bmiColors[0].rgbRed = 0xff;
879 bmi->bmiColors[0].rgbGreen = 0xff;
880 bmi->bmiColors[0].rgbBlue = 0xff;
881 bmi->bmiColors[1].rgbRed = 0;
882 bmi->bmiColors[1].rgbGreen = 0;
883 bmi->bmiColors[1].rgbBlue = 0;
884 bmi->bmiColors[2].rgbRed = 0xff;
885 bmi->bmiColors[2].rgbGreen = 0;
886 bmi->bmiColors[2].rgbBlue = 0;
887 bmi->bmiColors[3].rgbRed = 0;
888 bmi->bmiColors[3].rgbGreen = 0xff;
889 bmi->bmiColors[3].rgbBlue = 0;
890 bmi->bmiColors[4].rgbRed = 0;
891 bmi->bmiColors[4].rgbGreen = 0;
892 bmi->bmiColors[4].rgbBlue = 0xff;
894 dib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
895 ok(dib != NULL, "ret NULL\n");
897 orig_bm = SelectObject(mem_dc, dib);
899 sha1 = sha1_graphics_8;
900 draw_graphics(mem_dc, bmi, bits, &sha1);
902 SelectObject(mem_dc, orig_bm);
910 HMODULE mod = GetModuleHandleA("gdi32.dll");
911 pSetLayout = (void *)GetProcAddress( mod, "SetLayout" );
913 CryptAcquireContextW(&crypt_prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
915 test_simple_graphics();
917 CryptReleaseContext(crypt_prov, 0);