1 /*
2  * PROJECT:         ReactOS api tests
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * PURPOSE:         Test for MaskBlt
5  * PROGRAMMERS:     Timo Kreuzer
6  */
7 
8 #include "precomp.h"
9 
10 #include "init.h"
11 
12 void Test_MaskBlt_1bpp()
13 {
14     HDC hdcDst, hdcSrc;
15     struct
16     {
17         BITMAPINFOHEADER bmiHeader;
18         ULONG aulColors[2];
19     } bmiData = {{sizeof(BITMAPINFOHEADER), 8, 1, 1, 1, BI_RGB, 0, 10, 10, 2,0}, {0, 0xFFFFFF}};
20     PBITMAPINFO pbmi = (PBITMAPINFO)&bmiData;
21     HBITMAP hbmDst, hbmSrc, hbmMsk;
22     PUCHAR pjBitsDst, pjBitsSrc, pjBitsMsk;
23     BOOL ret;
24 
25     /* Create a dest dc and bitmap */
26     hdcDst = CreateCompatibleDC(NULL);
27     hbmDst = CreateDIBSection(hdcDst, pbmi, DIB_RGB_COLORS, (PVOID*)&pjBitsDst, NULL, 0);
28     SelectObject(hdcDst, hbmDst);
29 
30     /* Create a source dc and bitmap */
31     hdcSrc = CreateCompatibleDC(NULL);
32     hbmSrc = CreateDIBSection(hdcSrc, pbmi, DIB_RGB_COLORS, (PVOID*)&pjBitsSrc, NULL, 0);
33     SelectObject(hdcSrc, hbmSrc);
34 
35     /* Create a 1 bpp mask bitmap */
36     hbmMsk = CreateDIBSection(hdcDst, pbmi, DIB_RGB_COLORS, (PVOID*)&pjBitsMsk, NULL, 0);
37 
38     /* Do the masking (SRCCOPY / NOOP) */
39     pjBitsDst[0] = 0xAA;
40     pjBitsSrc[0] = 0xCC;
41     pjBitsMsk[0] = 0xF0;
42     ret = MaskBlt(hdcDst, 0, 0, 8, 1, hdcSrc, 0, 0, hbmMsk, 0, 0, MAKEROP4(SRCCOPY, 0xAA0000));
43     ok(ret == 1, "MaskBlt failed (%d)\n", ret);
44     ok(pjBitsDst[0] == 0xCA, "pjBitsDst[0] == 0x%x\n", pjBitsDst[0]);
45 
46     pjBitsDst[0] = 0x00;
47     pjBitsSrc[0] = 0xFF;
48     pjBitsMsk[0] = 0xF0;
49     ret = MaskBlt(hdcDst, 0, 0, 8, 1, hdcSrc, 0, 0, hbmMsk, 0, 0, MAKEROP4(SRCCOPY, 0xAA0000));
50     ok(ret == 1, "MaskBlt failed (%d)\n", ret);
51     ok(pjBitsDst[0] == 0xF0, "pjBitsDst[0] == 0x%x\n", pjBitsDst[0]);
52 
53     /* Do the masking (NOTSRCERASE / SRCINVERT) */
54     pjBitsDst[0] = 0xF0; // 11110000
55     pjBitsSrc[0] = 0xCC; // 11001100
56     pjBitsMsk[0] = 0xAA; // 10101010
57 
58     ret = MaskBlt(hdcDst, 0, 0, 8, 1, hdcSrc, 0, 0, hbmMsk, 0, 0, MAKEROP4(NOTSRCERASE, SRCINVERT)); // 22
59     ok(ret == 1, "MaskBlt failed (%d)\n", ret);
60     ok(pjBitsDst[0] == 0x16, "pjBitsDst[0] == 0x%x\n", pjBitsDst[0]);
61 
62     /* Do the masking (MERGEPAINT / DSxn) */
63     pjBitsDst[0] = 0xF0;
64     pjBitsSrc[0] = 0xCC;
65     pjBitsMsk[0] = 0xAA;
66     ret = MaskBlt(hdcDst, 0, 0, 8, 1, hdcSrc, 0, 0, hbmMsk, 0, 0, MAKEROP4(MERGEPAINT, 0x990000));
67     ok(ret == 1, "MaskBlt failed (%d)\n", ret);
68     ok(pjBitsDst[0] == 0xE3, "pjBitsDst[0] == 0x%x\n", pjBitsDst[0]);
69 
70     /* Try a ROP that needs a mask with a NULL mask bitmap handle */
71     ret = MaskBlt(hdcDst, 0, 0, 8, 1, hdcSrc, 0, 0, NULL, 0, 0, MAKEROP4(SRCCOPY, 0xAA0000));
72     ok(ret == 1, "MaskBlt failed (%d)\n", ret);
73     ok(pjBitsDst[0] == 0xCC, "pjBitsDst[0] == 0x%x\n", pjBitsDst[0]);
74 
75     /* Try a ROP that needs a mask with an invalid mask bitmap handle */
76     ret = MaskBlt(hdcDst, 0, 0, 8, 1, hdcSrc, 0, 0, (HBITMAP)0x123456, 0, 0, MAKEROP4(SRCCOPY, 0xAA0000));
77     ok(ret == 0, "MaskBlt should fail, but succeeded (%d)\n", ret);
78 
79     /* Try a ROP that needs a mask with an invalid mask bitmap */
80     ok(ghbmp24 != NULL, "ghbmp24 is NULL!\n");
81     ret = MaskBlt(hdcDst, 0, 0, 8, 1, hdcSrc, 0, 0, ghbmp24, 0, 0, MAKEROP4(SRCCOPY, 0xAA0000));
82     ok(ret == 0, "MaskBlt should fail, but succeeded (%d)\n", ret);
83 
84     /* Try a ROP that needs no mask with an invalid mask bitmap */
85     ret = MaskBlt(hdcDst, 0, 0, 8, 1, hdcSrc, 0, 0, (HBITMAP)0x123456, 0, 0, MAKEROP4(SRCCOPY, SRCCOPY));
86     ok(ret == 1, "MaskBlt failed (%d)\n", ret);
87 
88     /* Try (PATCOPY / NOOP) with a NULL source mask and bitmap */
89     ret = MaskBlt(hdcDst, 0, 0, 8, 1, NULL, 0, 0, NULL, 0, 0, MAKEROP4(PATCOPY, 0xAA0000));
90     ok(ret == 0, "MaskBlt should fail, but succeeded (%d)\n", ret);
91 
92 
93     /* Try with a mask that is smaller than the rect */
94     DeleteObject(hbmMsk);
95     pbmi->bmiHeader.biWidth = 4;
96     hbmMsk = CreateDIBSection(hdcDst, pbmi, DIB_RGB_COLORS, (PVOID*)&pjBitsMsk, NULL, 0);
97 
98     /* Do the masking (SRCCOPY / NOOP) */
99     pjBitsDst[0] = 0xAA; // 10101010
100     pjBitsSrc[0] = 0xCC; // 11001100
101     pjBitsMsk[0] = 0x33; // 00110011
102     ret = MaskBlt(hdcDst, 0, 0, 5, 1, hdcSrc, 0, 0, hbmMsk, 0, 0, MAKEROP4(SRCCOPY, 0xAA0000));
103     ok(ret == 0, "MaskBlt should fail, but succeeded (%d)\n", ret);
104     ret = MaskBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, hbmMsk, 1, 0, MAKEROP4(SRCCOPY, 0xAA0000));
105     ok(ret == 0, "MaskBlt should fail, but succeeded (%d)\n", ret);
106     ret = MaskBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, hbmMsk, 0, 1, MAKEROP4(SRCCOPY, 0xAA0000));
107     ok(ret == 0, "MaskBlt should fail, but succeeded (%d)\n", ret);
108     ret = MaskBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, hbmMsk, 0, 0, MAKEROP4(SRCCOPY, 0xAA0000));
109     ok(ret == 1, "MaskBlt failed (%d)\n", ret);
110     ok(pjBitsDst[0] == 0x8A, "pjBitsDst[0] == 0x%x\n", pjBitsDst[0]);
111 
112 }
113 
114 void Test_MaskBlt_16bpp()
115 {
116     HDC hdcDst, hdcSrc;
117     BITMAPINFO bmi1 = {{sizeof(BITMAPINFOHEADER), 8, 1, 1, 1, BI_RGB, 0, 10, 10, 0,0}};
118     BITMAPINFO bmi32 = {{sizeof(BITMAPINFOHEADER), 8, 1, 1, 16, BI_RGB, 0, 10, 10, 0,0}};
119     HBITMAP hbmDst, hbmSrc, hbmMsk;
120     PUCHAR pjBitsMsk;
121     PUSHORT pusBitsDst, pusBitsSrc;
122     BOOL ret;
123 
124     /* Create a dest dc and bitmap */
125     hdcDst = CreateCompatibleDC(NULL);
126     hbmDst = CreateDIBSection(hdcDst, &bmi32, DIB_RGB_COLORS, (PVOID*)&pusBitsDst, NULL, 0);
127     SelectObject(hdcDst, hbmDst);
128 
129     /* Create a source dc and bitmap */
130     hdcSrc = CreateCompatibleDC(NULL);
131     hbmSrc = CreateDIBSection(hdcSrc, &bmi32, DIB_RGB_COLORS, (PVOID*)&pusBitsSrc, NULL, 0);
132     SelectObject(hdcSrc, hbmSrc);
133     ok(hdcSrc && hbmSrc, "\n");
134 
135     /* Create a 1 bpp mask bitmap */
136     hbmMsk = CreateDIBSection(hdcDst, &bmi1, DIB_RGB_COLORS, (PVOID*)&pjBitsMsk, NULL, 0);
137     ok(hbmMsk != 0, "CreateDIBSection failed\n");
138 
139     /* Do the masking */
140     pusBitsDst[0] = 0x1234;
141     pusBitsDst[1] = 0x5678;
142     pusBitsSrc[0] = 0x4321;
143     pusBitsSrc[1] = 0x8765;
144     pjBitsMsk[0] = 0x80;
145     ret = MaskBlt(hdcDst, 0, 0, 8, 1, hdcSrc, 0, 0, hbmMsk, 0, 0, MAKEROP4(SRCCOPY, 0xAA0000));
146     ok(ret == 1, "MaskBlt failed (%d)\n", ret);
147     ok (pusBitsDst[0] == 0x4321, "pusBitsDst[0] == 0x%x\n", pusBitsDst[0]);
148     ok (pusBitsDst[1] == 0x5678, "pusBitsDst[0] == 0x%x\n", pusBitsDst[1]);
149 
150     pusBitsDst[0] = 0x1234;
151     pusBitsDst[1] = 0x5678;
152     ret = MaskBlt(hdcDst, 0, 0, 8, 1, hdcSrc, 0, 0, hbmMsk, 0, 0, MAKEROP4(SRCPAINT, MERGEPAINT));
153     ok(ret == 1, "MaskBlt failed (%d)\n", ret);
154     ok (pusBitsDst[0] == 0x5335, "pusBitsDst[0] == 0x%x\n", pusBitsDst[0]);
155     ok (pusBitsDst[1] == 0x7efa, "pusBitsDst[0] == 0x%x\n", pusBitsDst[1]);
156 }
157 
158 void Test_MaskBlt_32bpp()
159 {
160     HDC hdcDst, hdcSrc;
161     BITMAPINFO bmi1 = {{sizeof(BITMAPINFOHEADER), 8, 1, 1, 1, BI_RGB, 0, 10, 10, 0,0}};
162     BITMAPINFO bmi32 = {{sizeof(BITMAPINFOHEADER), 8, 1, 1, 32, BI_RGB, 0, 10, 10, 0,0}};
163     HBITMAP hbmDst, hbmSrc, hbmMsk;
164     PUCHAR pjBitsMsk;
165     PULONG pulBitsDst, pulBitsSrc;
166     BOOL ret;
167 
168     /* Create a dest dc and bitmap */
169     hdcDst = CreateCompatibleDC(NULL);
170     hbmDst = CreateDIBSection(hdcDst, &bmi32, DIB_RGB_COLORS, (PVOID*)&pulBitsDst, NULL, 0);
171     SelectObject(hdcDst, hbmDst);
172 
173     /* Create a source dc and bitmap */
174     hdcSrc = CreateCompatibleDC(NULL);
175     hbmSrc = CreateDIBSection(hdcSrc, &bmi32, DIB_RGB_COLORS, (PVOID*)&pulBitsSrc, NULL, 0);
176     SelectObject(hdcSrc, hbmSrc);
177     ok(hdcSrc && hbmSrc, "\n");
178 
179     /* Create a 1 bpp mask bitmap */
180     hbmMsk = CreateDIBSection(hdcDst, &bmi1, DIB_RGB_COLORS, (PVOID*)&pjBitsMsk, NULL, 0);
181     ok(hbmMsk != 0, "CreateDIBSection failed\n");
182 
183     /* Do the masking */
184     pulBitsDst[0] = 0x12345678;
185     pulBitsDst[1] = 0x9abcdef0;
186     pulBitsSrc[0] = 0x87684321;
187     pulBitsSrc[1] = 0x0fedcba9;
188     pjBitsMsk[0] = 0x80;
189     ret = MaskBlt(hdcDst, 0, 0, 8, 1, hdcSrc, 0, 0, hbmMsk, 0, 0, MAKEROP4(SRCCOPY, 0xAA0000));
190     ok(ret == 1, "MaskBlt failed (%d)\n", ret);
191     ok (pulBitsDst[0] == 0x87684321, "pulBitsDst[0] == 0x%lx\n", pulBitsDst[0]);
192     ok (pulBitsDst[1] == 0x9abcdef0, "pulBitsDst[0] == 0x%lx\n", pulBitsDst[1]);
193 
194     pulBitsDst[0] = 0x12345678;
195     pulBitsDst[1] = 0x9abcdef0;
196     ret = MaskBlt(hdcDst, 0, 0, 8, 1, hdcSrc, 0, 0, hbmMsk, 0, 0, MAKEROP4(SRCPAINT, MERGEPAINT));
197     ok(ret == 1, "MaskBlt failed (%d)\n", ret);
198     ok (pulBitsDst[0] == 0x977c5779, "pulBitsDst[0] == 0x%lx\n", pulBitsDst[0]);
199     ok (pulBitsDst[1] == 0xfabefef6, "pulBitsDst[0] == 0x%lx\n", pulBitsDst[1]);
200 }
201 
202 void Test_MaskBlt_Brush()
203 {
204     HDC hdcDst, hdcSrc;
205     struct
206     {
207         BITMAPINFOHEADER bmiHeader;
208         ULONG aulColors[2];
209     } bmiData = {{sizeof(BITMAPINFOHEADER), 16, 16, 1, 1, BI_RGB, 0, 10, 10, 2,0}, {0, 0xFFFFFF}};
210     PBITMAPINFO pbmi = (PBITMAPINFO)&bmiData;
211     HBITMAP hbmDst, hbmSrc, hbmMsk;
212     PULONG pulBitsDst, pulBitsSrc, pulBitsMsk;
213     BOOL ret;
214     HBRUSH hbr;
215 
216     /* Create a dest dc and bitmap */
217     hdcDst = CreateCompatibleDC(NULL);
218     hbmDst = CreateDIBSection(hdcDst, pbmi, DIB_RGB_COLORS, (PVOID*)&pulBitsDst, NULL, 0);
219     SelectObject(hdcDst, hbmDst);
220 
221     /* Create a source dc and bitmap */
222     hdcSrc = CreateCompatibleDC(NULL);
223     hbmSrc = CreateDIBSection(hdcSrc, pbmi, DIB_RGB_COLORS, (PVOID*)&pulBitsSrc, NULL, 0);
224     SelectObject(hdcSrc, hbmSrc);
225 
226     hbr = CreateHatchBrush(HS_CROSS, 0);
227     ok(hbr != 0, "failed to create brush\n");
228     ok(SelectObject(hdcDst, hbr) != 0, "failed to select brush\n");
229 
230     /* Do the masking (SRCCOPY / NOOP) */
231     pulBitsDst[0] = 0x00000000;
232     pulBitsSrc[0] = 0xFFFFFFFF;
233     ret = MaskBlt(hdcDst, 0, 0, 8, 1, hdcSrc, 0, 0, NULL, 0, 0, MAKEROP4(SRCCOPY, 0xAA0000));
234     ok(ret == 1, "MaskBlt failed (%d)\n", ret);
235     ok(pulBitsDst[0] == 0, "pulBitsDst[0] == 0x%lx\n", pulBitsDst[0]);
236 
237     /* Create a 1 bpp pattern brush */
238     pbmi->bmiHeader.biWidth = 8;
239     hbmMsk = CreateDIBSection(hdcDst, pbmi, DIB_RGB_COLORS, (PVOID*)&pulBitsMsk, NULL, 0);
240     ok(hbmMsk != 0, "CreateDIBSection failed\n");
241     hbr = CreatePatternBrush(hbmMsk);
242     ok(hbr != 0, "CreatePatternBrush failed\n");
243     ok(SelectObject(hdcDst, hbr) != 0, "failed to select brush\n");
244 
245     /* Do the masking (SRCCOPY / NOOP) */
246     pulBitsDst[0] = 0x00000000;
247     pulBitsSrc[0] = 0xFFFFFFFF;
248     pulBitsMsk[0] = 0xCCAAFF00;
249     ret = MaskBlt(hdcDst, 0, 0, 16, 1, hdcSrc, 0, 0, NULL, 0, 0, MAKEROP4(SRCCOPY, 0xAA0000));
250     ok(ret == 1, "MaskBlt failed (%d)\n", ret);
251     ok(pulBitsDst[0] == 0, "pulBitsDst[0] == 0x%lx\n", pulBitsDst[0]);
252 
253 }
254 
255 START_TEST(MaskBlt)
256 {
257     InitStuff();
258     Test_MaskBlt_1bpp();
259     Test_MaskBlt_16bpp();
260     Test_MaskBlt_32bpp();
261     Test_MaskBlt_Brush();
262 
263 }
264 
265