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