1 2 #include <stdio.h> 3 #include <windows.h> 4 #include <wine/test.h> 5 6 enum 7 { 8 BMF_1BPP = 0, 9 BMF_4BPP = 1, 10 BMF_8BPP = 2, 11 BMF_16BPP_555 = 3, 12 BMF_16BPP_565 = 4, 13 BMF_24BPP_RGB = 5, 14 BMF_24BPP_BGR = 6, 15 BMF_32BPP_RGB = 7, 16 BMF_32BPP_BGR = 8 17 }; 18 19 ULONG bpp[] = {1, 4, 8, 15, 16, 24, 24, 32, 32}; 20 21 static BYTE ajBits1[] = {0xAA, 0xAA, 0xAA, 0xAA, 0,0,0,0}; 22 static BYTE ajBits8[] = {0x00, 0xFF, 0x80, 0xCC, 0,0,0,0}; 23 static WORD ajBits16[] = {0x0000, 0xFFFF, 0x1000, 0x0C0C, 0,0,0,0}; 24 static DWORD ajBits24[] = {0x0000, 0xFFFF, 0x1000, 0x0C0C, 0,0,0,0}; 25 static DWORD ajBits32[] = {0x0000, 0xFFFF, 0x1000, 0x0C0C, 0,0,0,0}; 26 static HBITMAP hbmp1bpp_a, hbmp1bpp_b; 27 static HBITMAP hbmp8bpp_a, hbmp8bpp_b; 28 static HBITMAP hbmp16bpp_a, hbmp16bpp_b; 29 static HBITMAP hbmp24bpp_a, hbmp24bpp_b; 30 static HBITMAP hbmp32bpp_a, hbmp32bpp_b; 31 static HBITMAP hbmpCompat; 32 static HDC hdcSrc, hdcDst; 33 static ULONG iDcFormat; 34 35 ULONG 36 GetRealColorDepth() 37 { 38 HBITMAP hbmp; 39 HDC hdc; 40 struct 41 { 42 BITMAPINFOHEADER bmiHeader; 43 ULONG aulMasks[3]; 44 } bmi; 45 PBITMAPINFO pbmi = (PBITMAPINFO)&bmi; 46 ULONG ulColorDepth; 47 48 /* Get the screen DC */ 49 hdc = GetDC(NULL); 50 51 /* Create a compatible bitmap */ 52 hbmp = CreateCompatibleBitmap(hdc, 1, 1); 53 54 /* Fill BITMAPINFOHEADER */ 55 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 56 GetDIBits(hdc, hbmp, 0, 1, NULL, pbmi, DIB_RGB_COLORS); 57 58 /* Call again to fill in the bitfields */ 59 GetDIBits(hdc, hbmp, 0, 1, NULL, pbmi, DIB_RGB_COLORS); 60 61 /* Get the basic color depth */ 62 ulColorDepth = bmi.bmiHeader.biBitCount; 63 64 DeleteObject(hbmp); 65 66 switch (ulColorDepth) 67 { 68 case 1: 69 return BMF_1BPP; 70 case 4: 71 return BMF_4BPP; 72 case 8: 73 return BMF_8BPP; 74 case 16: 75 /* Check the red mask */ 76 if (bmi.aulMasks[0] == 0x7c00) 77 return BMF_16BPP_555; 78 else 79 return BMF_16BPP_565; 80 case 24: 81 return BMF_4BPP; 82 case 32: 83 if (bmi.bmiHeader.biCompression == BI_BITFIELDS && 84 bmi.aulMasks[0] == 0xff) 85 return BMF_32BPP_RGB; 86 else 87 return BMF_32BPP_BGR; 88 } 89 90 /* Cleanup and return */ 91 return BMF_32BPP_RGB; 92 } 93 94 static 95 ULONG 96 iXlateFromRGB(ULONG iFormat, COLORREF crColor) 97 { 98 ULONG ulRed, ulGreen, ulBlue; 99 100 ulRed = GetRValue(crColor); 101 ulGreen = GetGValue(crColor); 102 ulBlue = GetBValue(crColor); 103 104 switch (iFormat) 105 { 106 case BMF_1BPP: 107 return crColor ? 0xffffff : 0; 108 109 case BMF_4BPP: 110 case BMF_8BPP: 111 case BMF_16BPP_555: 112 ulRed = (ulRed & 0xF8) >> 3; 113 ulGreen = (ulGreen & 0xF8) >> 3; 114 ulBlue = (ulBlue & 0xF8) >> 3; 115 return ulRed << 10 | ulGreen << 5 | ulBlue; 116 117 case BMF_16BPP_565: 118 ulRed = (ulRed & 0xF8) >> 3; 119 ulGreen = (ulGreen & 0xFC) >> 2; 120 ulBlue = (ulBlue & 0xF8) >> 3; 121 return ulRed << 11 | ulGreen << 5 | ulBlue; 122 123 case BMF_24BPP_RGB: 124 case BMF_32BPP_RGB: 125 return crColor; 126 127 case BMF_24BPP_BGR: 128 case BMF_32BPP_BGR: 129 return RGB(ulBlue, ulGreen, ulRed); 130 } 131 return 0; 132 } 133 134 static 135 COLORREF 136 iXlateToRGB(ULONG iFormat, ULONG ulColor) 137 { 138 ULONG ulRed, ulGreen, ulBlue; 139 140 switch (iFormat) 141 { 142 case BMF_1BPP: 143 return ulColor ? 0xffffff : 0; 144 145 case BMF_4BPP: 146 case BMF_8BPP: 147 case BMF_16BPP_555: 148 ulRed = (ulColor & 0x7C00) >> 7; 149 ulRed |= ulRed >> 5; 150 ulGreen = (ulColor & 0x3E0) >> 2; 151 ulGreen |= ulGreen >> 5; 152 ulBlue = (ulColor & 0x1F) << 3; 153 ulBlue |= ulBlue >> 5; 154 return RGB(ulRed, ulGreen, ulBlue); 155 156 case BMF_16BPP_565: 157 ulRed = (ulColor & 0xF800) >> 8; 158 ulRed |= ulRed >> 5; 159 ulGreen = (ulColor & 0x7E0) >> 3; 160 ulGreen |= ulGreen >> 6; 161 ulBlue = (ulColor & 0x1F) << 3; 162 ulBlue |= ulBlue >> 5; 163 return RGB(ulRed, ulGreen, ulBlue); 164 165 case BMF_24BPP_RGB: 166 case BMF_32BPP_RGB: 167 return ulColor; 168 169 case BMF_24BPP_BGR: 170 case BMF_32BPP_BGR: 171 ulRed = GetRValue(ulColor); 172 ulGreen = GetGValue(ulColor); 173 ulBlue = GetBValue(ulColor); 174 return RGB(ulBlue, ulGreen, ulRed); 175 } 176 return 0; 177 } 178 179 static 180 ULONG 181 GetClosestColor(ULONG iFormat, COLORREF crColor, COLORREF crBackColor) 182 { 183 if (iFormat == BMF_1BPP) 184 return crBackColor; 185 return iXlateToRGB(iFormat, iXlateFromRGB(iFormat, crColor)); 186 } 187 188 ULONG 189 GetDIBPixel(ULONG iFormat, PVOID pvBits, ULONG x) 190 { 191 switch (iFormat) 192 { 193 case BMF_1BPP: 194 // 195 case BMF_16BPP_555: 196 case BMF_16BPP_565: 197 return *(WORD*)((PCHAR)pvBits + x * sizeof(WORD)); 198 199 case BMF_24BPP_RGB: 200 case BMF_24BPP_BGR: 201 return (*(DWORD*)((PCHAR)pvBits + x * 3)) & 0xffffff; 202 203 case BMF_32BPP_RGB: 204 case BMF_32BPP_BGR: 205 return *(DWORD*)((PCHAR)pvBits + x * sizeof(DWORD)); 206 } 207 return 0; 208 } 209 210 static 211 void 212 Initialize() 213 { 214 hdcSrc = CreateCompatibleDC(0); 215 hdcDst = CreateCompatibleDC(0); 216 217 hbmpCompat = CreateCompatibleBitmap(GetDC(0), 4, 2); 218 ok(hbmpCompat != 0, "CreateCompatibleBitmap failed\n"); 219 220 iDcFormat = GetRealColorDepth(); 221 printf("got iDcFormat = %ld\n", iDcFormat); 222 223 hbmp1bpp_a = CreateBitmap(4, 2, 1, 1, ajBits1); 224 ok(hbmp1bpp_a != 0, "CreateBitmap failed\n"); 225 226 hbmp1bpp_b = CreateBitmap(4, 2, 1, 1, ajBits1); 227 ok(hbmp1bpp_b != 0, "CreateBitmap failed\n"); 228 229 hbmp8bpp_a = CreateBitmap(4, 2, 1, 8, ajBits8); 230 ok(hbmp8bpp_a != 0, "CreateBitmap failed\n"); 231 232 hbmp8bpp_b = CreateBitmap(4, 2, 1, 8, ajBits8); 233 ok(hbmp8bpp_b != 0, "CreateBitmap failed\n"); 234 235 hbmp16bpp_a = CreateBitmap(4, 2, 1, 16, ajBits16); 236 ok(hbmp16bpp_a != 0, "CreateBitmap failed\n"); 237 238 hbmp16bpp_b = CreateBitmap(4, 2, 1, 16, ajBits16); 239 ok(hbmp16bpp_b != 0, "CreateBitmap failed\n"); 240 241 hbmp24bpp_a = CreateBitmap(4, 2, 1, 24, ajBits24); 242 ok(hbmp24bpp_a != 0, "CreateBitmap failed\n"); 243 244 hbmp24bpp_b = CreateBitmap(4, 2, 1, 24, ajBits24); 245 ok(hbmp24bpp_b != 0, "CreateBitmap failed\n"); 246 247 hbmp32bpp_a = CreateBitmap(4, 2, 1, 32, ajBits32); 248 ok(hbmp32bpp_a != 0, "CreateBitmap failed\n"); 249 250 hbmp32bpp_b = CreateBitmap(4, 2, 1, 32, ajBits32); 251 ok(hbmp32bpp_b != 0, "CreateBitmap failed\n"); 252 253 } 254 255 void 256 Test_SrcMono1(ULONG iBmpFormat, HBITMAP hbmpDst, PVOID pvBits) 257 { 258 COLORREF c, expected; 259 HBRUSH hbr; 260 RECT rect; 261 struct 262 { 263 BITMAPINFOHEADER bmiHeader; 264 ULONG bmiColors[2]; 265 BYTE aj[32]; 266 } bmi; 267 268 SelectObject(hdcSrc, hbmp1bpp_a); 269 SelectObject(hdcDst, hbmpDst); 270 271 /* Set default dc fore and back colors */ 272 SetTextColor(hdcSrc, 0x000000); 273 SetBkColor(hdcSrc, 0xffffff); 274 SetTextColor(hdcDst, 0x000000); 275 SetBkColor(hdcDst, 0xffffff); 276 277 /* Do a bitblt operation */ 278 ok(BitBlt(hdcDst, 0, 0, 2, 2, hdcSrc, 0, 0, SRCCOPY), "(%ld): BitBlt failed", iBmpFormat); 279 280 /* Test background color */ 281 c = GetPixel(hdcDst, 0, 0); 282 expected = 0xffffff; 283 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 284 285 /* Test foreground color */ 286 c = GetPixel(hdcDst, 1, 0); 287 expected = 0x000000; 288 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 289 290 if (pvBits) 291 { 292 c = GetDIBPixel(iBmpFormat, pvBits, 0); 293 expected = iXlateFromRGB(iBmpFormat, GetBkColor(hdcSrc)); 294 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 295 296 c = GetDIBPixel(iBmpFormat, pvBits, 1); 297 expected = iXlateFromRGB(iBmpFormat, GetTextColor(hdcSrc)); 298 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 299 } 300 301 /* Set different dc fore and back colors */ 302 SetTextColor(hdcSrc, 0xf00f0f); 303 SetBkColor(hdcSrc, 0xf0ff0f); 304 SetTextColor(hdcDst, 0xefFee5); 305 SetBkColor(hdcDst, 0x100121); 306 307 /* Make sure this alone didn't affect the resulting colors */ 308 c = GetPixel(hdcDst, 0, 0); 309 expected = 0xffffff; 310 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 311 c = GetPixel(hdcDst, 1, 0); 312 expected = 0x000000; 313 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 314 315 /* Repeat the bitblt operation */ 316 ok(BitBlt(hdcDst, 0, 0, 2, 2, hdcSrc, 0, 0, SRCCOPY), "(%ld): BitBlt failed", iBmpFormat); 317 318 /* Test background color */ 319 c = GetPixel(hdcDst, 0, 0); 320 expected = GetClosestColor(iBmpFormat, GetBkColor(hdcDst), 0xffffff); 321 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 322 323 /* Test foreground color */ 324 c = GetPixel(hdcDst, 1, 0); 325 expected = GetClosestColor(iBmpFormat, GetTextColor(hdcDst), 0); 326 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 327 328 if (pvBits) 329 { 330 c = GetDIBPixel(iBmpFormat, pvBits, 0); 331 expected = iXlateFromRGB(iBmpFormat, GetBkColor(hdcDst)); 332 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 333 334 c = GetDIBPixel(iBmpFormat, pvBits, 1); 335 expected = iXlateFromRGB(iBmpFormat, GetTextColor(hdcDst)); 336 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 337 } 338 339 /* Set inverted fore and back colors */ 340 SetTextColor(hdcSrc, 0); 341 SetBkColor(hdcSrc, 0xffffff); 342 SetTextColor(hdcDst, 0xffffff); 343 SetBkColor(hdcDst, 0x000000); 344 345 /* Repeat the bitblt operation */ 346 ok(BitBlt(hdcDst, 0, 0, 2, 2, hdcSrc, 0, 0, SRCCOPY), "(%ld): BitBlt failed", iBmpFormat); 347 348 /* Test background color */ 349 c = GetPixel(hdcDst, 0, 0); 350 expected = GetClosestColor(iBmpFormat, GetBkColor(hdcDst), 0xffffff); 351 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 352 353 /* Test foreground color */ 354 c = GetPixel(hdcDst, 1, 0); 355 expected = GetClosestColor(iBmpFormat, GetTextColor(hdcDst), 0); 356 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 357 358 if (pvBits) 359 { 360 c = GetDIBPixel(iBmpFormat, pvBits, 0); 361 expected = iXlateFromRGB(iBmpFormat, GetBkColor(hdcDst)); 362 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 363 364 c = GetDIBPixel(iBmpFormat, pvBits, 1); 365 expected = iXlateFromRGB(iBmpFormat, GetTextColor(hdcDst)); 366 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 367 } 368 369 370 /* Hatch brush ****************************************************************/ 371 372 /* Set dc fore and back colors */ 373 SetTextColor(hdcDst, 0x102030); 374 SetBkColor(hdcDst, 0xeeccdd); 375 SetBkMode(hdcDst, OPAQUE); 376 377 /* Create a hatch brush */ 378 hbr = CreateHatchBrush(HS_DIAGCROSS, 0x123456); 379 380 /* Fill the destination bitmap */ 381 rect.left = rect.top = 0; 382 rect.bottom = rect.right = 4; 383 ok(FillRect(hdcDst, &rect, hbr), "FillRect failed\n"); 384 385 /* Test the fore color of the hatch brush */ 386 c = GetPixel(hdcDst, 0, 0); 387 expected = GetClosestColor(iBmpFormat, 0x123456, 0); 388 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 389 390 /* Test the back color of the hatch brush */ 391 c = GetPixel(hdcDst, 1, 0); 392 expected = GetClosestColor(iBmpFormat, GetBkColor(hdcDst), 0xffffff); 393 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 394 395 if (pvBits) 396 { 397 c = GetDIBPixel(iBmpFormat, pvBits, 0); 398 expected = iXlateFromRGB(iBmpFormat, 0x123456); 399 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 400 401 c = GetDIBPixel(iBmpFormat, pvBits, 1); 402 expected = iXlateFromRGB(iBmpFormat, GetBkColor(hdcDst)); 403 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 404 } 405 406 DeleteObject(hbr); 407 408 /* DIB brush ******************************************************************/ 409 410 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 411 bmi.bmiHeader.biWidth = 8; 412 bmi.bmiHeader.biHeight = 8; 413 bmi.bmiHeader.biPlanes = 1; 414 bmi.bmiHeader.biBitCount = 1; 415 bmi.bmiHeader.biCompression = BI_RGB; 416 bmi.bmiHeader.biSizeImage = 0; 417 bmi.bmiHeader.biXPelsPerMeter = 1; 418 bmi.bmiHeader.biYPelsPerMeter = 1; 419 bmi.bmiHeader.biClrUsed = 2; 420 bmi.bmiHeader.biClrImportant = 2; 421 bmi.bmiColors[0] = 0xeeeeee; 422 bmi.bmiColors[1] = 0x111111; 423 memset(bmi.aj, 0xaaaa, sizeof(bmi.aj)); 424 hbr = CreateDIBPatternBrushPt(&bmi, DIB_RGB_COLORS); 425 ok(hbr != 0, "CreateDIBPatternBrushPt failed\n"); 426 427 rect.left = rect.top = 0; 428 rect.bottom = rect.right = 4; 429 ok(FillRect(hdcDst, &rect, hbr),"FillRect failed\n"); 430 431 /* Test color 1 of the dib brush */ 432 c = GetPixel(hdcDst, 0, 0); 433 expected = GetClosestColor(iBmpFormat, bmi.bmiColors[1], 0); 434 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 435 436 /* Test color 0 of the dib brush */ 437 c = GetPixel(hdcDst, 1, 0); 438 expected = GetClosestColor(iBmpFormat, bmi.bmiColors[0], 0xffffff); 439 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 440 441 if (pvBits) 442 { 443 c = GetDIBPixel(iBmpFormat, pvBits, 0); 444 expected = iXlateFromRGB(iBmpFormat, bmi.bmiColors[1]); 445 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 446 447 c = GetDIBPixel(iBmpFormat, pvBits, 1); 448 expected = iXlateFromRGB(iBmpFormat, bmi.bmiColors[0]); 449 ok(c == expected, "(%ld): wrong color, expected %lx, got %lx\n", iBmpFormat, expected, c); 450 } 451 452 DeleteObject(hbr); 453 454 455 } 456 457 void 458 Test_SrcMono() 459 { 460 HBITMAP hbmp; 461 struct 462 { 463 BITMAPINFOHEADER bmiHeader; 464 ULONG bmiColors[3]; 465 } bmi; 466 PVOID pvBits; 467 ULONG c, expected; 468 469 SelectObject(hdcSrc, hbmp1bpp_a); 470 471 Test_SrcMono1(BMF_1BPP, hbmp1bpp_b, 0); 472 Test_SrcMono1(iDcFormat, hbmpCompat, 0); 473 474 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 475 bmi.bmiHeader.biWidth = 2; 476 bmi.bmiHeader.biHeight = -2; 477 bmi.bmiHeader.biPlanes = 1; 478 bmi.bmiHeader.biBitCount = 16; 479 bmi.bmiHeader.biCompression = BI_RGB; 480 bmi.bmiHeader.biSizeImage = 0; 481 bmi.bmiHeader.biXPelsPerMeter = 1; 482 bmi.bmiHeader.biYPelsPerMeter = 1; 483 bmi.bmiHeader.biClrUsed = 0; 484 bmi.bmiHeader.biClrImportant = 0; 485 hbmp = CreateDIBSection(hdcDst, (LPBITMAPINFO)&bmi, DIB_RGB_COLORS, &pvBits, NULL, 0); 486 ok(hbmp != 0, "CreateDIBSection failed\n"); 487 memset(pvBits, 0x55555555, 8 * 8 * 2); 488 489 SelectObject(hdcDst, hbmp); 490 491 c = GetPixel(hdcDst, 0, 0); 492 expected = iXlateToRGB(BMF_16BPP_555, 0x5555); 493 ok(c == expected, "expected %lx, got %lx\n", expected, c); 494 495 expected = 0x123456; 496 SetPixel(hdcDst, 0, 0, expected); 497 expected = iXlateFromRGB(BMF_16BPP_555, expected); 498 c = *(volatile WORD*)pvBits; 499 ok(c == expected, "expected %lx, got %lx\n", expected, c); 500 501 Test_SrcMono1(BMF_16BPP_555, hbmp, pvBits); 502 503 DeleteObject(hbmp); 504 505 /* Create a 565 DIB section */ 506 bmi.bmiHeader.biCompression = BI_BITFIELDS; 507 bmi.bmiHeader.biClrUsed = 3; 508 bmi.bmiHeader.biClrImportant = 3; 509 bmi.bmiColors[0] = 0xF800; 510 bmi.bmiColors[1] = 0x7E0; 511 bmi.bmiColors[2] = 0x1F; 512 hbmp = CreateDIBSection(hdcDst, (LPBITMAPINFO)&bmi, DIB_RGB_COLORS, &pvBits, NULL, 0); 513 ok(hbmp != 0, "CreateDIBSection failed\n"); 514 SelectObject(hdcDst, hbmp); 515 516 Test_SrcMono1(BMF_16BPP_565, hbmp, pvBits); 517 518 DeleteObject(hbmp); 519 520 /* Create a 32 bpp DIB section */ 521 bmi.bmiHeader.biBitCount = 32; 522 bmi.bmiHeader.biCompression = BI_RGB; 523 bmi.bmiHeader.biClrUsed = 0; 524 bmi.bmiHeader.biClrImportant = 0; 525 hbmp = CreateDIBSection(hdcDst, (LPBITMAPINFO)&bmi, DIB_RGB_COLORS, &pvBits, NULL, 0); 526 ok(hbmp != 0, "CreateDIBSection failed\n"); 527 SelectObject(hdcDst, hbmp); 528 529 Test_SrcMono1(BMF_32BPP_BGR, hbmp, pvBits); 530 531 DeleteObject(hbmp); 532 533 } 534 535 536 START_TEST(xlate) 537 { 538 Initialize(); 539 540 Test_SrcMono(); 541 } 542 543 // trunk: 41 failures 544 545