1 /* 2 * Unit test suite for palettes 3 * 4 * Copyright 2005 Glenn Wurster 5 * 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. 10 * 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. 15 * 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 19 */ 20 21 #include "precomp.h" 22 23 static const PALETTEENTRY logpalettedata[8] = { 24 { 0x10, 0x20, 0x30, PC_NOCOLLAPSE }, 25 { 0x20, 0x30, 0x40, PC_NOCOLLAPSE }, 26 { 0x30, 0x40, 0x50, PC_NOCOLLAPSE }, 27 { 0x40, 0x50, 0x60, PC_NOCOLLAPSE }, 28 { 0x50, 0x60, 0x70, PC_NOCOLLAPSE }, 29 { 0x60, 0x70, 0x80, PC_NOCOLLAPSE }, 30 { 0x70, 0x80, 0x90, PC_NOCOLLAPSE }, 31 { 0x80, 0x90, 0xA0, PC_NOCOLLAPSE }, 32 }; 33 34 static void test_DIB_PAL_COLORS(void) { 35 HDC hdc = GetDC( NULL ); 36 HDC memhdc = CreateCompatibleDC( hdc ); 37 HBITMAP hbmp, hbmpOld; 38 char bmpbuf[sizeof(BITMAPINFO) + 10 * sizeof(WORD)]; 39 PBITMAPINFO bmp = (PBITMAPINFO)bmpbuf; 40 WORD * bmpPalPtr; 41 char logpalettebuf[sizeof(LOGPALETTE) + sizeof(logpalettedata)]; 42 PLOGPALETTE logpalette = (PLOGPALETTE)logpalettebuf; 43 HPALETTE hpal, hpalOld; 44 COLORREF setColor, chkColor, getColor; 45 int i; 46 47 /* Initialize the logical palette with a few colours */ 48 logpalette->palVersion = 0x300; 49 logpalette->palNumEntries = 8; 50 memcpy( logpalette->palPalEntry, logpalettedata, sizeof(logpalettedata) ); 51 hpal = CreatePalette( logpalette ); 52 hpalOld = SelectPalette( memhdc, hpal, FALSE ); 53 ok( hpalOld != NULL, "error=%d\n", GetLastError() ); 54 55 /* Create a DIB BMP which references colours in the logical palette */ 56 memset( bmp, 0x00, sizeof(BITMAPINFO) ); 57 bmp->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 58 bmp->bmiHeader.biWidth = 1; 59 bmp->bmiHeader.biHeight = 1; 60 bmp->bmiHeader.biPlanes = 1; 61 bmp->bmiHeader.biBitCount = 8; 62 bmp->bmiHeader.biCompression = BI_RGB; 63 bmp->bmiHeader.biClrUsed = 10; 64 bmp->bmiHeader.biClrImportant = 0; 65 bmpPalPtr = (WORD *)&bmp->bmiColors; 66 for( i = 0; i < 8; i++ ) { 67 *bmpPalPtr++ = i; 68 } 69 *bmpPalPtr++ = 8; /* Pointer to logical palette index just outside range */ 70 *bmpPalPtr++ = 19; /* Pointer to bad logical palette index */ 71 72 hbmp = CreateDIBSection( memhdc, bmp, DIB_PAL_COLORS, 0, 0, 0 ); 73 ok( hbmp != NULL, "error=%d\n", GetLastError() ); 74 hbmpOld = SelectObject( memhdc, hbmp ); 75 ok( hbmpOld != NULL, "error=%d\n", GetLastError() ); 76 77 /* Test with a RGB to DIB_PAL_COLORS */ 78 setColor = RGB( logpalettedata[1].peRed, logpalettedata[1].peGreen, logpalettedata[1].peBlue ); 79 SetPixel( memhdc, 0, 0, setColor ); 80 chkColor = RGB( logpalettedata[1].peRed, logpalettedata[1].peGreen, logpalettedata[1].peBlue ); 81 getColor = GetPixel( memhdc, 0, 0 ); 82 ok( getColor == chkColor, "getColor=%08X\n", (UINT)getColor ); 83 84 /* Test with a valid DIBINDEX to DIB_PAL_COLORS */ 85 setColor = DIBINDEX( 2 ); 86 SetPixel( memhdc, 0, 0, setColor ); 87 chkColor = RGB( logpalettedata[2].peRed, logpalettedata[2].peGreen, logpalettedata[2].peBlue ); 88 getColor = GetPixel( memhdc, 0, 0 ); 89 ok( getColor == chkColor, "getColor=%08X\n", (UINT)getColor ); 90 91 /* Test with an invalid DIBINDEX to DIB_PAL_COLORS */ 92 setColor = DIBINDEX( 12 ); 93 SetPixel( memhdc, 0, 0, setColor ); 94 chkColor = RGB( 0, 0, 0 ); 95 getColor = GetPixel( memhdc, 0, 0 ); 96 ok( getColor == chkColor, "getColor=%08X\n", (UINT)getColor ); 97 98 /* Test for double wraparound on logical palette references from */ 99 /* DIBINDEX by DIB_PAL_COLORS. */ 100 setColor = DIBINDEX( 9 ); 101 SetPixel( memhdc, 0, 0, setColor ); 102 chkColor = RGB( logpalettedata[3].peRed, logpalettedata[3].peGreen, logpalettedata[3].peBlue ); 103 getColor = GetPixel( memhdc, 0, 0 ); 104 ok( getColor == chkColor, "getColor=%08X\n", (UINT)getColor ); 105 106 SelectPalette( memhdc, hpalOld, FALSE ); 107 DeleteObject( hpal ); 108 SelectObject( memhdc, hbmpOld ); 109 DeleteObject( hbmp ); 110 DeleteDC( memhdc ); 111 ReleaseDC( NULL, hdc ); 112 } 113 114 static void test_palette_entries(void) 115 { 116 char logpalettebuf[sizeof(LOGPALETTE) + sizeof(logpalettedata)]; 117 PLOGPALETTE logpalette = (PLOGPALETTE)logpalettebuf; 118 HPALETTE hpal; 119 UINT res=0; 120 PALETTEENTRY palEntry = { 0x1, 0x2, 0x3, 0xff }; 121 PALETTEENTRY getEntryResult; 122 123 /* Initialize the logical palette with a few colours */ 124 logpalette->palVersion = 0x300; 125 logpalette->palNumEntries = 8; 126 memcpy( logpalette->palPalEntry, logpalettedata, sizeof(logpalettedata) ); 127 hpal = CreatePalette( logpalette ); 128 129 /* Set a new entry with peFlags to 0xff */ 130 SetPaletteEntries(hpal, 0, 1, &palEntry); 131 132 /* Retrieve the entry to see if GDI32 performs any filtering on peFlags */ 133 res = GetPaletteEntries(hpal, 0, 1, &getEntryResult); 134 ok(res == 1, "GetPaletteEntries should have returned 1 but returned %d\n", res); 135 136 ok( palEntry.peFlags == getEntryResult.peFlags, "palEntry.peFlags (%#x) != getEntryResult.peFlags (%#x)\n", palEntry.peFlags, getEntryResult.peFlags ); 137 } 138 139 static void test_halftone_palette(void) 140 { 141 HDC hdc; 142 HPALETTE pal; 143 PALETTEENTRY entries[256]; 144 PALETTEENTRY defpal[20]; 145 int i, count; 146 147 hdc = GetDC(0); 148 149 count = GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, defpal ); 150 ok( count == 20, "wrong size %u\n", count ); 151 152 pal = CreateHalftonePalette( hdc ); 153 count = GetPaletteEntries( pal, 0, 256, entries ); 154 ok( count == 256 || broken(count <= 20), /* nt 4 */ 155 "wrong size %u\n", count ); 156 157 /* first and last 8 match the default palette */ 158 if (count >= 20) 159 { 160 for (i = 0; i < 8; i++) 161 { 162 ok( entries[i].peRed == defpal[i].peRed && 163 entries[i].peGreen == defpal[i].peGreen && 164 entries[i].peBlue == defpal[i].peBlue && 165 !entries[i].peFlags, 166 "%u: wrong color %02x,%02x,%02x,%02x instead of %02x,%02x,%02x\n", i, 167 entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags, 168 defpal[i].peRed, defpal[i].peGreen, defpal[i].peBlue ); 169 } 170 for (i = count - 8; i < count; i++) 171 { 172 int idx = i - count + 20; 173 ok( entries[i].peRed == defpal[idx].peRed && 174 entries[i].peGreen == defpal[idx].peGreen && 175 entries[i].peBlue == defpal[idx].peBlue && 176 !entries[i].peFlags, 177 "%u: wrong color %02x,%02x,%02x,%02x instead of %02x,%02x,%02x\n", i, 178 entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags, 179 defpal[idx].peRed, defpal[idx].peGreen, defpal[idx].peBlue ); 180 } 181 } 182 DeleteObject( pal ); 183 ReleaseDC( 0, hdc ); 184 } 185 186 static void check_system_palette_entries(HDC hdc) 187 { 188 PALETTEENTRY entries[256]; 189 PALETTEENTRY defpal[20]; 190 int i, count; 191 192 memset( defpal, 0xaa, sizeof(defpal) ); 193 count = GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, defpal ); 194 ok( count == 20, "wrong size %u\n", count ); 195 196 memset( entries, 0x55, sizeof(entries) ); 197 count = GetSystemPaletteEntries( hdc, 0, 256, entries ); 198 ok( count == 0, "wrong size %u\n", count); 199 for (i = 0; i < 10; i++) 200 { 201 ok( entries[i].peRed == defpal[i].peRed && 202 entries[i].peGreen == defpal[i].peGreen && 203 entries[i].peBlue == defpal[i].peBlue && 204 !entries[i].peFlags, 205 "%u: wrong color %02x,%02x,%02x,%02x instead of %02x,%02x,%02x\n", i, 206 entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags, 207 defpal[i].peRed, defpal[i].peGreen, defpal[i].peBlue ); 208 } 209 for (i = 10; i < 246; ++i) 210 { 211 ok( !entries[i].peRed && 212 !entries[i].peGreen && 213 !entries[i].peBlue && 214 !entries[i].peFlags, 215 "%u: wrong color %02x,%02x,%02x,%02x instead of 0,0,0\n", i, 216 entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags); 217 } 218 for (i = 246; i < 256; i++) 219 { 220 int idx = i - 246 + 10; 221 ok( entries[i].peRed == defpal[idx].peRed && 222 entries[i].peGreen == defpal[idx].peGreen && 223 entries[i].peBlue == defpal[idx].peBlue && 224 !entries[i].peFlags, 225 "%u: wrong color %02x,%02x,%02x,%02x instead of %02x,%02x,%02x\n", i, 226 entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags, 227 defpal[idx].peRed, defpal[idx].peGreen, defpal[idx].peBlue ); 228 } 229 230 memset( entries, 0x55, sizeof(entries) ); 231 count = GetSystemPaletteEntries( hdc, 0, 10, entries ); 232 ok( count == 0, "wrong size %u\n", count); 233 for (i = 0; i < 10; i++) 234 { 235 ok( entries[i].peRed == defpal[i].peRed && 236 entries[i].peGreen == defpal[i].peGreen && 237 entries[i].peBlue == defpal[i].peBlue && 238 !entries[i].peFlags, 239 "%u: wrong color %02x,%02x,%02x,%02x instead of %02x,%02x,%02x\n", i, 240 entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags, 241 defpal[i].peRed, defpal[i].peGreen, defpal[i].peBlue ); 242 } 243 244 memset( entries, 0x55, sizeof(entries) ); 245 count = GetSystemPaletteEntries( hdc, 10, 246, entries ); 246 ok( count == 0, "wrong size %u\n", count); 247 for (i = 0; i < 236; ++i) 248 { 249 ok( !entries[i].peRed && 250 !entries[i].peGreen && 251 !entries[i].peBlue && 252 !entries[i].peFlags, 253 "%u: wrong color %02x,%02x,%02x,%02x instead of 0,0,0\n", i, 254 entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags); 255 } 256 for (i = 236; i < 246; i++) 257 { 258 int idx = i - 236 + 10; 259 ok( entries[i].peRed == defpal[idx].peRed && 260 entries[i].peGreen == defpal[idx].peGreen && 261 entries[i].peBlue == defpal[idx].peBlue && 262 !entries[i].peFlags, 263 "%u: wrong color %02x,%02x,%02x,%02x instead of %02x,%02x,%02x\n", i, 264 entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags, 265 defpal[idx].peRed, defpal[idx].peGreen, defpal[idx].peBlue ); 266 } 267 268 memset( entries, 0x55, sizeof(entries) ); 269 count = GetSystemPaletteEntries( hdc, 246, 10, entries ); 270 ok( count == 0, "wrong size %u\n", count); 271 for (i = 0; i < 10; i++) 272 { 273 int idx = i + 10; 274 ok( entries[i].peRed == defpal[idx].peRed && 275 entries[i].peGreen == defpal[idx].peGreen && 276 entries[i].peBlue == defpal[idx].peBlue && 277 !entries[i].peFlags, 278 "%u: wrong color %02x,%02x,%02x,%02x instead of %02x,%02x,%02x\n", i, 279 entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags, 280 defpal[idx].peRed, defpal[idx].peGreen, defpal[idx].peBlue ); 281 } 282 } 283 284 static void test_system_palette_entries(void) 285 { 286 HDC hdc; 287 HDC metafile_dc; 288 HMETAFILE metafile; 289 290 hdc = GetDC(0); 291 292 if (!(GetDeviceCaps( hdc, RASTERCAPS ) & RC_PALETTE)) 293 { 294 check_system_palette_entries(hdc); 295 } 296 else 297 { 298 skip( "device is palette-based, skipping test\n" ); 299 } 300 301 ReleaseDC( 0, hdc ); 302 303 metafile_dc = CreateMetaFileA(NULL); 304 305 check_system_palette_entries(metafile_dc); 306 307 metafile = CloseMetaFile(metafile_dc); 308 DeleteMetaFile(metafile); 309 } 310 311 START_TEST(palette) 312 { 313 test_DIB_PAL_COLORS(); 314 test_palette_entries(); 315 test_halftone_palette(); 316 test_system_palette_entries(); 317 } 318