1 /* 2 * PROJECT: ReactOS API tests 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Tests for the StretchBlt API 5 * COPYRIGHT: Copyright 2020, 2021 Doug Lyons (douglyons at douglyons dot com) 6 * Some Code copied and modified from Wine gdi32:bitmap test. 7 */ 8 9 #include <stdarg.h> 10 #include <assert.h> 11 #include <string.h> 12 13 #include "ntstatus.h" 14 #define WIN32_NO_STATUS 15 #include "windef.h" 16 #include "winbase.h" 17 #include "winerror.h" 18 #include "wingdi.h" 19 #include "winuser.h" 20 #include "wine/test.h" 21 #include <debug.h> 22 23 /* Notes on using the StretchBlt function's general flip ability. 24 * 25 * The critical values for flipping are the signs of the values for DestWidth, DestHeight, SourceWidth and SourceHeight. 26 * If we assign a '0' to values having a negative sign and a '1' to values having a positive sign these can be CaseWXYZ's. 27 * Where the W, X, Y, and Z are replaced with the '0's and '1's representing the signs of the values in sequential order. 28 * 29 * If we take the normal StretchBlt function's copy/scaling with no flips, the generalized code can be represented as follows: 30 * 31 * StretchBlt(DestDC, DestX, DestY, (DestWidth), (DestHeight), 32 * SourceDC, SourceX, SourceY, (SourceWidth), (SourceHeight), SRCCOPY); // Case1111 (15) (all positive signs) 33 * 34 * For Horizontal flipping then the generalized form on the Destination side can be represented as follows: 35 * 36 * StretchBlt(DestDC, DestX + DestWidth - 1, DestY, -DestWidth, DestHeight, 37 * SourceDC, SourceX, SourceY, SourceWidth, SourceHeight, SRCCOPY); // Case 0111 (7) 38 * 39 * and for Horizontal flipping the generalized form on the Source side can be represented as follows: 40 * 41 * StretchBlt(DestDC, DestX, DestY, DestWidth, DestHeight, 42 * SourceDC, SourceX + SourceWidth - 1, SourceY, -SourceWidth, SourceHeight, SRCCOPY); // Case 1101 (13) 43 * 44 * I believe that the "- 1" is used because we are moving from the rightmost position back to the 0th position. 45 * 46 * But there are three "special" cases where no flip is done (there is a copy/scale only) and the "-1" is not used. 47 * These are as follows: 48 * 1) 49 * StretchBlt(DestDC, DestX + DestWidth, DestY, -DestWidth, DestHeight, // Both Widths negative 50 * SourceDC, SourceX + SourceWidth, SourceY, -SourceWidth, SourceHeight, SRCCOPY); // Case0101 (5) 51 * 2) 52 * StretchBlt(DestDC, DestX, DestY + DestHeight, DestWidth, -DestHeight, // Both heights negative 53 * SourceDC, SourceX, SourceY + SourceHeight, SourceWidth, -SourceHeight, SRCCOPY); // Case1010 (10) 54 * 3) 55 * StretchBlt(DestDC, DestX + DestWidth, DestY + DestHeight, -DestWidth, -DestHeight, // widths AND heights neg 56 * SourceDC, SourceX + SourceWidth, SourceY + SourceHeight, -SourceWidth, -SourceHeight, SRCCOPY); // Case0000 (0) 57 * 58 * I suspect that these are like this because of legacy reasons when StretchBlt did not support so many flip options. 59 * 60 * For Vertical flipping the generalized form on the Destination side can be represented as follows: 61 * 62 * StretchBlt(DestDC, DestX, DestY + DestHeight - 1, DestWidth, -DestHeight, 63 * SourceDC, SourceX, SourceY, SourceWidth, SourceHeight, SRCCOPY); // Case1011 (11) 64 * 65 * and for Vertical on the Source Side as folows: 66 * 67 * StretchBlt(DestDC, DestX, DestY, DestWidth, -DestHeight, 68 * SourceDC, SourceX, SourceY + SourceHeight - 1, SourceWidth, -SourceHeight, SRCCOPY); // Case 1010 (10) 69 */ 70 71 static inline int get_dib_stride( int width, int bpp ) 72 { 73 return ((width * bpp + 31) >> 3) & ~3; 74 } 75 76 static inline int get_dib_image_size( const BITMAPINFO *info ) 77 { 78 return get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount ) 79 * abs( info->bmiHeader.biHeight ); 80 } 81 82 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer, 83 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, 84 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, 85 UINT32 *expected, int line) 86 { 87 int dst_size = get_dib_image_size( dst_info ); 88 89 memset(dstBuffer, 0, dst_size); 90 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, 91 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY); 92 ok(memcmp(dstBuffer, expected, dst_size) == 0, 93 "StretchBlt \nexp { %08X, %08X, %08X, %08X } \ngot { %08X, %08X, %08X, %08X } \n" 94 "destination { %d, %d, %d, %d } source { %d, %d, %d, %d } from line %d\n", 95 expected[0], expected[1], expected[2], expected[3], 96 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3], 97 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, 98 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, line); 99 } 100 101 static void test_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer, 102 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, 103 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, 104 UINT32 *expected, int line, BOOL SrcTopDown, BOOL DstTopDown ) 105 { 106 int dst_size = get_dib_image_size( dst_info ); 107 108 memset(dstBuffer, 0, dst_size); 109 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, 110 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY); 111 ok(memcmp(dstBuffer, expected, dst_size) == 0, 112 "Case%c%c%c%c %s - %s \nexp { %08X, %08X, %08X, %08X } \ngot { %08X, %08X, %08X, %08X }\n" 113 "destination { %d, %d, %d, %d } source { %d, %d, %d, %d } from line %d\n", 114 (nWidthDest < 0) ? '0' : '1', (nHeightDest < 0) ? '0' : '1', 115 (nWidthSrc < 0) ? '0' : '1', (nHeightSrc < 0) ? '0' : '1', 116 SrcTopDown ? "SrcTopDown" : "SrcBottomUp", DstTopDown ? "DstTopDown" : "DstBottomUp", 117 expected[0], expected[1], expected[2], expected[3], 118 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3], 119 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, 120 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, line); 121 } 122 123 static void test_StretchBlt(void) 124 { 125 HBITMAP bmpDst, bmpSrc; 126 HBITMAP oldDst, oldSrc; 127 HDC hdcScreen, hdcDst, hdcSrc; 128 UINT32 *dstBuffer, *srcBuffer; 129 BITMAPINFO biDst, biSrc; 130 UINT32 expected[256]; 131 RGBQUAD colors[2]; 132 133 memset(&biDst, 0, sizeof(BITMAPINFO)); 134 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 135 biDst.bmiHeader.biWidth = 16; 136 biDst.bmiHeader.biHeight = -16; 137 biDst.bmiHeader.biPlanes = 1; 138 biDst.bmiHeader.biBitCount = 32; 139 biDst.bmiHeader.biCompression = BI_RGB; 140 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO)); 141 142 hdcScreen = CreateCompatibleDC(NULL); 143 hdcDst = CreateCompatibleDC(hdcScreen); 144 hdcSrc = CreateCompatibleDC(hdcDst); 145 146 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0); 147 oldDst = SelectObject(hdcDst, bmpDst); 148 149 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0); 150 oldSrc = SelectObject(hdcSrc, bmpSrc); 151 152 /* Top-down to top-down tests */ 153 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE; 154 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210; 155 156 memset( expected, 0, get_dib_image_size( &biDst ) ); 157 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE; 158 expected[16] = 0xFEDCBA98, expected[17] = 0x76543210; 159 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 160 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__); 161 162 expected[0] = 0xCAFED00D, expected[1] = 0x00000000; 163 expected[16] = 0x00000000, expected[17] = 0x00000000; 164 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 165 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__); 166 167 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D; 168 expected[16] = 0xCAFED00D, expected[17] = 0xCAFED00D; 169 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 170 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__); 171 172 /* This is an example of the dst width (height) == 1 exception, explored below */ 173 expected[0] = 0xCAFED00D, expected[1] = 0x00000000; 174 expected[16] = 0x00000000, expected[17] = 0x00000000; 175 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 176 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__); 177 178 expected[0] = 0xCAFED00D, expected[1] = 0x00000000; 179 expected[16] = 0x00000000, expected[17] = 0x00000000; 180 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 181 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__); 182 183 expected[0] = 0x00000000, expected[1] = 0x00000000; 184 expected[16] = 0x00000000, expected[17] = 0xCAFED00D, expected[18] = 0xFEEDFACE; 185 expected[32] = 0x00000000, expected[33] = 0xFEDCBA98, expected[34] = 0x76543210; 186 187 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 188 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__); 189 190 /* when dst width is 1 merge src width - 1 pixels */ 191 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) ); 192 srcBuffer[0] = 0x0000ff00, srcBuffer[1] = 0x0000f0f0, srcBuffer[2] = 0x0000cccc, srcBuffer[3] = 0x0000aaaa; 193 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210; 194 195 memset( expected, 0, get_dib_image_size( &biDst ) ); 196 expected[0] = srcBuffer[0]; 197 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 198 0, 0, 1, 1, 0, 0, 2, 1, expected, __LINE__); 199 200 /* similarly in the vertical direction */ 201 memset( expected, 0, get_dib_image_size( &biDst ) ); 202 expected[0] = srcBuffer[0]; 203 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 204 0, 0, 1, 1, 0, 0, 1, 2, expected, __LINE__); 205 206 /* check that it's the dst size in device units that needs to be 1 */ 207 SetMapMode( hdcDst, MM_ISOTROPIC ); 208 SetWindowExtEx( hdcDst, 200, 200, NULL ); 209 SetViewportExtEx( hdcDst, 100, 100, NULL ); 210 211 SetMapMode( hdcDst, MM_TEXT ); 212 213 SelectObject(hdcDst, oldDst); 214 DeleteObject(bmpDst); 215 216 /* Top-down to bottom-up tests */ 217 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) ); 218 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE; 219 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210; 220 221 biDst.bmiHeader.biHeight = 16; 222 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0); 223 oldDst = SelectObject(hdcDst, bmpDst); 224 225 memset( expected, 0, get_dib_image_size( &biDst ) ); 226 227 expected[224] = 0xFEDCBA98, expected[225] = 0x76543210; 228 expected[240] = 0xCAFED00D, expected[241] = 0xFEEDFACE; 229 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 230 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__); 231 232 SelectObject(hdcSrc, oldSrc); 233 DeleteObject(bmpSrc); 234 235 /* Bottom-up to bottom-up tests */ 236 biSrc.bmiHeader.biHeight = 16; 237 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0); 238 srcBuffer[224] = 0xCAFED00D, srcBuffer[225] = 0xFEEDFACE; 239 srcBuffer[240] = 0xFEDCBA98, srcBuffer[241] = 0x76543210; 240 oldSrc = SelectObject(hdcSrc, bmpSrc); 241 242 memset( expected, 0, get_dib_image_size( &biDst ) ); 243 244 expected[224] = 0xCAFED00D, expected[225] = 0xFEEDFACE; 245 expected[240] = 0xFEDCBA98, expected[241] = 0x76543210; 246 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 247 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__); 248 249 SelectObject(hdcDst, oldDst); 250 DeleteObject(bmpDst); 251 252 /* Bottom-up to top-down tests */ 253 biDst.bmiHeader.biHeight = -16; 254 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0); 255 oldDst = SelectObject(hdcDst, bmpDst); 256 257 memset( expected, 0, get_dib_image_size( &biDst ) ); 258 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210; 259 expected[16] = 0xCAFED00D, expected[17] = 0xFEEDFACE; 260 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 261 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__); 262 263 SelectObject(hdcSrc, oldSrc); 264 DeleteObject(bmpSrc); 265 266 biSrc.bmiHeader.biHeight = -2; 267 biSrc.bmiHeader.biBitCount = 24; 268 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0); 269 oldSrc = SelectObject(hdcSrc, bmpSrc); 270 271 memset( expected, 0, get_dib_image_size( &biDst ) ); 272 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D; 273 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98; 274 memcpy(dstBuffer, expected, 4 * sizeof(*dstBuffer)); 275 StretchBlt(hdcSrc, 0, 0, 4, 1, hdcDst, 0, 0, 4, 1, SRCCOPY ); 276 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer)); 277 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY ); 278 expected[0] = 0x00EDFACE, expected[1] = 0x00FED00D; 279 expected[2] = 0x00543210, expected[3] = 0x00DCBA98; 280 ok(!memcmp(dstBuffer, expected, 16), 281 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n", 282 expected[0], expected[1], expected[2], expected[3], 283 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] ); 284 285 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D; 286 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98; 287 memcpy(srcBuffer, expected, 4 * sizeof(*dstBuffer)); 288 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer)); 289 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY ); 290 expected[0] = 0x00EDFACE, expected[1] = 0x00D00DFE; 291 expected[2] = 0x0010CAFE, expected[3] = 0x00765432; 292 ok(!memcmp(dstBuffer, expected, 16), 293 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n", 294 expected[0], expected[1], expected[2], expected[3], 295 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] ); 296 297 SelectObject(hdcSrc, oldSrc); 298 DeleteObject(bmpSrc); 299 300 biSrc.bmiHeader.biBitCount = 1; 301 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0); 302 oldSrc = SelectObject(hdcSrc, bmpSrc); 303 *((DWORD *)colors + 0) = 0x123456; 304 *((DWORD *)colors + 1) = 0x335577; 305 SetDIBColorTable( hdcSrc, 0, 2, colors ); 306 srcBuffer[0] = 0x55555555; 307 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer)); 308 SetTextColor( hdcDst, 0 ); 309 SetBkColor( hdcDst, 0 ); 310 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY ); 311 expected[0] = expected[2] = 0x00123456; 312 expected[1] = expected[3] = 0x00335577; 313 ok(!memcmp(dstBuffer, expected, 16), 314 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n", 315 expected[0], expected[1], expected[2], expected[3], 316 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] ); 317 318 SelectObject(hdcSrc, oldSrc); 319 DeleteObject(bmpSrc); 320 321 bmpSrc = CreateBitmap( 16, 16, 1, 1, 0 ); 322 oldSrc = SelectObject(hdcSrc, bmpSrc); 323 SetPixel( hdcSrc, 0, 0, 0 ); 324 SetPixel( hdcSrc, 1, 0, 0xffffff ); 325 SetPixel( hdcSrc, 2, 0, 0xffffff ); 326 SetPixel( hdcSrc, 3, 0, 0 ); 327 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer)); 328 SetTextColor(hdcDst, RGB(0x22, 0x44, 0x66)); 329 SetBkColor(hdcDst, RGB(0x65, 0x43, 0x21)); 330 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY ); 331 expected[0] = expected[3] = 0x00224466; 332 expected[1] = expected[2] = 0x00654321; 333 ok(!memcmp(dstBuffer, expected, 16), 334 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n", 335 expected[0], expected[1], expected[2], expected[3], 336 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] ); 337 338 SelectObject(hdcSrc, oldSrc); 339 DeleteObject(bmpSrc); 340 341 SelectObject(hdcSrc, oldSrc); 342 DeleteObject(bmpSrc); 343 SelectObject(hdcDst, oldDst); 344 DeleteObject(bmpDst); 345 346 memset(&biDst, 0, sizeof(BITMAPINFO)); // Clear our Bitmap to to all zeroes 347 348 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); // Set our Size to the header size 349 biDst.bmiHeader.biWidth = 2; // Set our Width to 2 (left-to-right) 350 biDst.bmiHeader.biHeight = -2; // Set our Height to -2 that's negative for top-down 351 biDst.bmiHeader.biPlanes = 1; // Set out planes to 1 (1 required by Windows) 352 biDst.bmiHeader.biBitCount = 32; // Set out BitCount to 32 (Full Color) 353 biDst.bmiHeader.biCompression = BI_RGB; // Set our Compression to BI_RBG (uncompressed) 354 355 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO)); // Put same Destination params into the Source 356 357 bmpSrc = CreateDIBSection(hdcSrc, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0); 358 oldSrc = SelectObject(hdcSrc, bmpSrc); 359 bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0); 360 oldDst = SelectObject(hdcDst, bmpDst); 361 362 srcBuffer[0] = 0x000000FF; // BLUE 363 srcBuffer[1] = 0x0000FF00; // GREEN 364 srcBuffer[2] = 0x00FF0000; // RED 365 srcBuffer[3] = 0xFF000000; // ALPHA (Opacity) 366 367 expected[0] = 0x000000FF; 368 expected[1] = 0x0000FF00; 369 expected[2] = 0x00FF0000; 370 expected[3] = 0xFF000000; 371 372 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 373 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__); // Case 1111 (15) - No flip. Just copy. 374 375 expected[0] = 0x00FF0000; 376 expected[1] = 0xFF000000; 377 expected[2] = 0x000000FF; 378 expected[3] = 0x0000FF00; 379 380 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 381 0, 0, 2, 2, 0, 1, 2, -2, expected, __LINE__); // Case 1110 (14) - Vertical flip. 382 383 expected[0] = 0x0000FF00; 384 expected[1] = 0x000000FF; 385 expected[2] = 0xFF000000; 386 expected[3] = 0x00FF0000; 387 388 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 389 0, 0, 2, 2, 1, 0, -2, 2, expected, __LINE__); // Case 1101 (13) - Horizontal flip. 390 391 expected[0] = 0xFF000000; 392 expected[1] = 0x00FF0000; 393 expected[2] = 0x0000FF00; 394 expected[3] = 0x000000FF; 395 396 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 397 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__); // Case 1100 (12) - Both flip. 398 399 expected[0] = 0x00FF0000; 400 expected[1] = 0xFF000000; 401 expected[2] = 0x000000FF; 402 expected[3] = 0x0000FF00; 403 404 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 405 0, 1, 2, -2, 0, 0, 2, 2, expected, __LINE__); // Case 1011 (11) - Vertical Flip. 406 407 expected[0] = 0x000000FF; 408 expected[1] = 0x0000FF00; 409 expected[2] = 0x00FF0000; 410 expected[3] = 0xFF000000; 411 412 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 413 0, 2, 2, -2, 0, 2, 2, -2, expected, __LINE__); // Case 1010 (10) - No Flip. Special Case. 414 415 expected[0] = 0xFF000000; 416 expected[1] = 0x00FF0000; 417 expected[2] = 0x0000FF00; 418 expected[3] = 0x000000FF; 419 420 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 421 0, 1, 2, -2, 1, 0, -2, 2, expected, __LINE__); // Case 1001 (9) - Both Flip. 422 423 expected[0] = 0x0000FF00; 424 expected[1] = 0x000000FF; 425 expected[2] = 0xFF000000; 426 expected[3] = 0x00FF0000; 427 428 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 429 0, 1, 2, -2, 1, 1, -2, -2, expected, __LINE__); // Case 1000 (8) - Horizontal Flip. 430 431 expected[0] = 0x0000FF00; 432 expected[1] = 0x000000FF; 433 expected[2] = 0xFF000000; 434 expected[3] = 0x00FF0000; 435 436 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 437 1, 0, -2, 2, 0, 0, 2, 2, expected, __LINE__); // Case 0111 (7) - Horizontal Flip. 438 439 expected[0] = 0xFF000000; 440 expected[1] = 0x00FF0000; 441 expected[2] = 0x0000FF00; 442 expected[3] = 0x000000FF; 443 444 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 445 1, 0, -2, 2, 0, 1, 2, -2, expected, __LINE__); // Case 0110 (6) - Both Flip. 446 447 expected[0] = 0x000000FF; 448 expected[1] = 0x0000FF00; 449 expected[2] = 0x00FF0000; 450 expected[3] = 0xFF000000; 451 452 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 453 2, 0, -2, 2, 2, 0, -2, 2, expected, __LINE__); // Case 0101 (5) - No Flip. Special Case. 454 455 expected[0] = 0x00FF0000; 456 expected[1] = 0xFF000000; 457 expected[2] = 0x000000FF; 458 expected[3] = 0x0000FF00; 459 460 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 461 1, 0, -2, 2, 1, 1, -2, -2, expected, __LINE__); // Case 0100 (4) - Vertical Flip. 462 463 expected[0] = 0xFF000000; 464 expected[1] = 0x00FF0000; 465 expected[2] = 0x0000FF00; 466 expected[3] = 0x000000FF; 467 468 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 469 1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__); // Case 0011 (3) - Both Flip. 470 471 expected[0] = 0x0000FF00; 472 expected[1] = 0x000000FF; 473 expected[2] = 0xFF000000; 474 expected[3] = 0x00FF0000; 475 476 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 477 1, 1, -2, -2, 0, 1, 2, -2, expected, __LINE__); // Case 0010 (2) - Horizontal Flip. 478 479 expected[0] = 0x00FF0000; 480 expected[1] = 0xFF000000; 481 expected[2] = 0x000000FF; 482 expected[3] = 0x0000FF00; 483 484 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 485 1, 1, -2, -2, 1, 0, -2, 2, expected, __LINE__); // Case 0001 (1) - Vertical Flip. 486 487 expected[0] = 0x000000FF; 488 expected[1] = 0x0000FF00; 489 expected[2] = 0x00FF0000; 490 expected[3] = 0xFF000000; 491 492 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 493 2, 2, -2, -2, 2, 2, -2, -2, expected, __LINE__); // Case 0000 (0) - No Flip. Special Case. 494 495 DeleteDC(hdcSrc); 496 497 SelectObject(hdcDst, oldDst); 498 DeleteObject(bmpDst); 499 DeleteDC(hdcDst); 500 501 DeleteDC(hdcScreen); 502 } 503 504 static void test_StretchBlt_TopDownOptions(BOOL SrcTopDown, BOOL DstTopDown) 505 { 506 HBITMAP bmpDst, bmpSrc; 507 HBITMAP oldDst, oldSrc; 508 HDC hdcScreen, hdcDst, hdcSrc; 509 UINT32 *dstBuffer, *srcBuffer; 510 BITMAPINFO biDst, biSrc; 511 UINT32 expected[256]; 512 513 memset(&biDst, 0, sizeof(BITMAPINFO)); 514 515 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 516 biDst.bmiHeader.biWidth = 2; 517 biDst.bmiHeader.biHeight = 2; 518 biDst.bmiHeader.biPlanes = 1; 519 biDst.bmiHeader.biBitCount = 32; 520 biDst.bmiHeader.biCompression = BI_RGB; 521 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO)); 522 523 if (!SrcTopDown && !DstTopDown) 524 { 525 biSrc.bmiHeader.biHeight = -2; // Converts Source bitmap to top down 526 biDst.bmiHeader.biHeight = -2; // Converts Destination bitmap to top down 527 } 528 529 if (SrcTopDown) 530 { 531 biSrc.bmiHeader.biHeight = -2; // Converts Source bitmap to top down 532 } 533 534 if (DstTopDown) 535 { 536 biDst.bmiHeader.biHeight = -2; // Converts Destination bitmap to top down 537 } 538 539 hdcScreen = CreateCompatibleDC(NULL); 540 hdcDst = CreateCompatibleDC(hdcScreen); 541 hdcSrc = CreateCompatibleDC(hdcDst); 542 543 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0); 544 oldSrc = SelectObject(hdcSrc, bmpSrc); 545 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0); 546 oldDst = SelectObject(hdcDst, bmpDst); 547 548 srcBuffer[0] = 0x000000FF; // BLUE 549 srcBuffer[1] = 0x0000FF00; // GREEN 550 srcBuffer[2] = 0x00FF0000; // RED 551 srcBuffer[3] = 0xFF000000; // ALPHA (Opacity) 552 553 if ((SrcTopDown || DstTopDown) && !(SrcTopDown && DstTopDown)) 554 { 555 expected[0] = 0x00FF0000; 556 expected[1] = 0xFF000000; 557 expected[2] = 0x000000FF; 558 expected[3] = 0x0000FF00; 559 } 560 else 561 { 562 expected[0] = 0x000000FF; 563 expected[1] = 0x0000FF00; 564 expected[2] = 0x00FF0000; 565 expected[3] = 0xFF000000; 566 } 567 568 test_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 569 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__, SrcTopDown, DstTopDown); // Case 1111 (15) - No flip. Just copy. 570 571 if ((SrcTopDown || DstTopDown) && !(SrcTopDown && DstTopDown)) 572 { 573 expected[0] = 0x000000FF; 574 expected[1] = 0x0000FF00; 575 expected[2] = 0x00FF0000; 576 expected[3] = 0xFF000000; 577 } 578 else 579 { 580 expected[0] = 0x00FF0000; 581 expected[1] = 0xFF000000; 582 expected[2] = 0x000000FF; 583 expected[3] = 0x0000FF00; 584 } 585 586 test_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 587 0, 0, 2, 2, 0, 1, 2, -2, expected, __LINE__, SrcTopDown, DstTopDown); // Case 1110 (14) - Vertical flip. 588 589 if ((SrcTopDown || DstTopDown) && !(SrcTopDown && DstTopDown)) 590 { 591 expected[0] = 0xFF000000; 592 expected[1] = 0x00FF0000; 593 expected[2] = 0x0000FF00; 594 expected[3] = 0x000000FF; 595 } 596 else 597 { 598 expected[0] = 0x0000FF00; 599 expected[1] = 0x000000FF; 600 expected[2] = 0xFF000000; 601 expected[3] = 0x00FF0000; 602 } 603 604 test_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 605 0, 0, 2, 2, 1, 0, -2, 2, expected, __LINE__, SrcTopDown, DstTopDown); // Case 1101 (13) - Horizontal flip. 606 607 if ((SrcTopDown || DstTopDown) && !(SrcTopDown && DstTopDown)) 608 { 609 expected[0] = 0x0000FF00; 610 expected[1] = 0x000000FF; 611 expected[2] = 0xFF000000; 612 expected[3] = 0x00FF0000; 613 } 614 else 615 { 616 expected[0] = 0xFF000000; 617 expected[1] = 0x00FF0000; 618 expected[2] = 0x0000FF00; 619 expected[3] = 0x000000FF; 620 } 621 622 test_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 623 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__, SrcTopDown, DstTopDown); // Case 1100 (12) - Both flip. 624 625 if ((SrcTopDown || DstTopDown) && !(SrcTopDown && DstTopDown)) 626 { 627 expected[0] = 0x000000FF; 628 expected[1] = 0x0000FF00; 629 expected[2] = 0x00FF0000; 630 expected[3] = 0xFF000000; 631 } 632 else 633 { 634 expected[0] = 0x00FF0000; 635 expected[1] = 0xFF000000; 636 expected[2] = 0x000000FF; 637 expected[3] = 0x0000FF00; 638 } 639 640 test_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 641 0, 1, 2, -2, 0, 0, 2, 2, expected, __LINE__, SrcTopDown, DstTopDown); // Case 1011 (11) - Vertical Flip. 642 643 if ((SrcTopDown || DstTopDown) && !(SrcTopDown && DstTopDown)) 644 { 645 expected[0] = 0x00FF0000; 646 expected[1] = 0xFF000000; 647 expected[2] = 0x000000FF; 648 expected[3] = 0x0000FF00; 649 } 650 else 651 { 652 expected[0] = 0x000000FF; 653 expected[1] = 0x0000FF00; 654 expected[2] = 0x00FF0000; 655 expected[3] = 0xFF000000; 656 } 657 658 test_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 659 0, 2, 2, -2, 0, 2, 2, -2, expected, __LINE__, SrcTopDown, DstTopDown); // Case 1010 (10) - No Flip. Special Case. 660 661 if ((SrcTopDown || DstTopDown) && !(SrcTopDown && DstTopDown)) 662 { 663 expected[0] = 0x0000FF00; 664 expected[1] = 0x000000FF; 665 expected[2] = 0xFF000000; 666 expected[3] = 0x00FF0000; 667 } 668 else 669 { 670 expected[0] = 0xFF000000; 671 expected[1] = 0x00FF0000; 672 expected[2] = 0x0000FF00; 673 expected[3] = 0x000000FF; 674 } 675 676 test_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 677 0, 1, 2, -2, 1, 0, -2, 2, expected, __LINE__, SrcTopDown, DstTopDown); // Case 1001 (9) - Both Flip. 678 679 if ((SrcTopDown || DstTopDown) && !(SrcTopDown && DstTopDown)) 680 { 681 expected[0] = 0xFF000000; 682 expected[1] = 0x00FF0000; 683 expected[2] = 0x0000FF00; 684 expected[3] = 0x000000FF; 685 } 686 else 687 { 688 expected[0] = 0x0000FF00; 689 expected[1] = 0x000000FF; 690 expected[2] = 0xFF000000; 691 expected[3] = 0x00FF0000; 692 } 693 694 test_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 695 0, 1, 2, -2, 1, 1, -2, -2, expected, __LINE__, SrcTopDown, DstTopDown); // Case 1000 (8) - Horizontal Flip 696 697 if ((SrcTopDown || DstTopDown) && !(SrcTopDown && DstTopDown)) 698 { 699 expected[0] = 0xFF000000; 700 expected[1] = 0x00FF0000; 701 expected[2] = 0x0000FF00; 702 expected[3] = 0x000000FF; 703 } 704 else 705 { 706 expected[0] = 0x0000FF00; 707 expected[1] = 0x000000FF; 708 expected[2] = 0xFF000000; 709 expected[3] = 0x00FF0000; 710 } 711 712 test_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 713 1, 0, -2, 2, 0, 0, 2, 2, expected, __LINE__, SrcTopDown, DstTopDown); // Case 0111 (7) - Horizontal Flip 714 715 if ((SrcTopDown || DstTopDown) && !(SrcTopDown && DstTopDown)) 716 { 717 expected[0] = 0x0000FF00; 718 expected[1] = 0x000000FF; 719 expected[2] = 0xFF000000; 720 expected[3] = 0x00FF0000; 721 } 722 else 723 { 724 expected[0] = 0xFF000000; 725 expected[1] = 0x00FF0000; 726 expected[2] = 0x0000FF00; 727 expected[3] = 0x000000FF; 728 } 729 730 test_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 731 1, 0, -2, 2, 0, 1, 2, -2, expected, __LINE__, SrcTopDown, DstTopDown); // Case 0110 (6) - Both Flip. 732 733 if ((SrcTopDown || DstTopDown) && !(SrcTopDown && DstTopDown)) 734 { 735 expected[0] = 0x00FF0000; 736 expected[1] = 0xFF000000; 737 expected[2] = 0x000000FF; 738 expected[3] = 0x0000FF00; 739 } 740 else 741 { 742 expected[0] = 0x000000FF; 743 expected[1] = 0x0000FF00; 744 expected[2] = 0x00FF0000; 745 expected[3] = 0xFF000000; 746 } 747 748 test_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 749 2, 0, -2, 2, 2, 0, -2, 2, expected, __LINE__, SrcTopDown, DstTopDown); // Case 0101 (5) - No Flip. Special Case. 750 751 if ((SrcTopDown || DstTopDown) && !(SrcTopDown && DstTopDown)) 752 { 753 expected[0] = 0x000000FF; 754 expected[1] = 0x0000FF00; 755 expected[2] = 0x00FF0000; 756 expected[3] = 0xFF000000; 757 } 758 else 759 { 760 expected[0] = 0x00FF0000; 761 expected[1] = 0xFF000000; 762 expected[2] = 0x000000FF; 763 expected[3] = 0x0000FF00; 764 } 765 766 test_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 767 1, 0, -2, 2, 1, 1, -2, -2, expected, __LINE__, SrcTopDown, DstTopDown); // Case 0100 (4) - Vertical Flip. 768 769 if ((SrcTopDown || DstTopDown) && !(SrcTopDown && DstTopDown)) 770 { 771 expected[0] = 0x0000FF00; 772 expected[1] = 0x000000FF; 773 expected[2] = 0xFF000000; 774 expected[3] = 0x00FF0000; 775 } 776 else 777 { 778 expected[0] = 0xFF000000; 779 expected[1] = 0x00FF0000; 780 expected[2] = 0x0000FF00; 781 expected[3] = 0x000000FF; 782 } 783 784 test_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 785 1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__, SrcTopDown, DstTopDown); // Case 0011 (3) - Both Flip. 786 787 if ((SrcTopDown || DstTopDown) && !(SrcTopDown && DstTopDown)) 788 { 789 expected[0] = 0xFF000000; 790 expected[1] = 0x00FF0000; 791 expected[2] = 0x0000FF00; 792 expected[3] = 0x000000FF; 793 } 794 else 795 { 796 expected[0] = 0x0000FF00; 797 expected[1] = 0x000000FF; 798 expected[2] = 0xFF000000; 799 expected[3] = 0x00FF0000; 800 } 801 802 test_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 803 1, 1, -2, -2, 0, 1, 2, -2, expected, __LINE__, SrcTopDown, DstTopDown); // Case 0010 (2) - Horizontal Flip. 804 805 if ((SrcTopDown || DstTopDown) && !(SrcTopDown && DstTopDown)) 806 { 807 expected[0] = 0x000000FF; 808 expected[1] = 0x0000FF00; 809 expected[2] = 0x00FF0000; 810 expected[3] = 0xFF000000; 811 } 812 else 813 { 814 expected[0] = 0x00FF0000; 815 expected[1] = 0xFF000000; 816 expected[2] = 0x000000FF; 817 expected[3] = 0x0000FF00; 818 } 819 820 test_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 821 1, 1, -2, -2, 1, 0, -2, 2, expected, __LINE__, SrcTopDown, DstTopDown); // Case 0001 (1) - Vertical Flip. 822 823 if ((SrcTopDown || DstTopDown) && !(SrcTopDown && DstTopDown)) 824 { 825 expected[0] = 0x00FF0000; 826 expected[1] = 0xFF000000; 827 expected[2] = 0x000000FF; 828 expected[3] = 0x0000FF00; 829 830 } 831 else 832 { 833 expected[0] = 0x000000FF; 834 expected[1] = 0x0000FF00; 835 expected[2] = 0x00FF0000; 836 expected[3] = 0xFF000000; 837 } 838 839 test_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 840 2, 2, -2, -2, 2, 2, -2, -2, expected, __LINE__, SrcTopDown, DstTopDown); // Case 0000 (0) - No Flip. Special Case. 841 842 SelectObject(hdcSrc, oldSrc); 843 DeleteObject(bmpSrc); 844 DeleteDC(hdcSrc); 845 846 SelectObject(hdcDst, oldDst); 847 DeleteObject(bmpDst); 848 DeleteDC(hdcDst); 849 850 DeleteDC(hdcScreen); 851 } 852 853 START_TEST(StretchBlt) 854 { 855 trace("\n\n## Start of generalized StretchBlt tests.\n\n"); 856 test_StretchBlt(); 857 858 trace("\n\n## Start of source top-down and destination top-down tests.\n\n"); 859 test_StretchBlt_TopDownOptions(TRUE, TRUE); 860 861 trace("\n\n## Start of source top-down and destination bottom-up tests.\n\n"); 862 test_StretchBlt_TopDownOptions(TRUE, FALSE); 863 864 trace("\n\n## Start of source bottom-up and destination top-down tests.\n\n"); 865 test_StretchBlt_TopDownOptions(FALSE, TRUE); 866 867 trace("\n\n## Start of source bottom-up and destination bottom-up tests.\n\n"); 868 test_StretchBlt_TopDownOptions(FALSE, FALSE); 869 } 870