From: Anton Baskanov Subject: gdi32: Return default palette entries from GetSystemPaletteEntries for non-palette-based devices. Message-Id: <1430463748-1792-1-git-send-email-baskanov@gmail.com> Date: Fri, 1 May 2015 13:02:28 +0600 Fixes rendering artifacts in Marble Drop. --- dlls/gdi32/palette.c | 35 ++++++++++++++++++++++++-- dlls/gdi32/tests/palette.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 2 deletions(-) diff --git a/dlls/gdi32/palette.c b/dlls/gdi32/palette.c index d850d0f..fa3e638 100644 --- a/dlls/gdi32/palette.c +++ b/dlls/gdi32/palette.c @@ -418,8 +418,39 @@ UINT WINAPI GetSystemPaletteEntries( if ((dc = get_dc_ptr( hdc ))) { - PHYSDEV physdev = GET_DC_PHYSDEV( dc, pGetSystemPaletteEntries ); - ret = physdev->funcs->pGetSystemPaletteEntries( physdev, start, count, entries ); + if (!(GetDeviceCaps( hdc, RASTERCAPS ) & RC_PALETTE)) + { + if (entries && start < 256) + { + UINT i; + const RGBQUAD *default_entries; + + if (start + count > 256) count = 256 - start; + + default_entries = get_default_color_table( 8 ); + for (i = 0; i < count; ++i) + { + if (i < 10 || i >= 246) + { + entries[i].peRed = default_entries[start + i].rgbRed; + entries[i].peGreen = default_entries[start + i].rgbGreen; + entries[i].peBlue = default_entries[start + i].rgbBlue; + } + else + { + entries[i].peRed = 0; + entries[i].peGreen = 0; + entries[i].peBlue = 0; + } + entries[i].peFlags = 0; + } + } + } + else + { + PHYSDEV physdev = GET_DC_PHYSDEV( dc, pGetSystemPaletteEntries ); + ret = physdev->funcs->pGetSystemPaletteEntries( physdev, start, count, entries ); + } release_dc_ptr( dc ); } return ret; diff --git a/dlls/gdi32/tests/palette.c b/dlls/gdi32/tests/palette.c index f95c0d3..a6492fd 100644 --- a/dlls/gdi32/tests/palette.c +++ b/dlls/gdi32/tests/palette.c @@ -191,9 +191,70 @@ static void test_halftone_palette(void) ReleaseDC( 0, hdc ); } +static void test_system_palette_entries(void) +{ + HDC hdc; + PALETTEENTRY entries[256]; + PALETTEENTRY defpal[20]; + int i, count; + + hdc = GetDC(0); + + if (!(GetDeviceCaps( hdc, RASTERCAPS ) & RC_PALETTE)) + { + memset( defpal, 0xaa, sizeof(defpal) ); + + count = GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, defpal ); + ok( count == 20, "wrong size %u\n", count ); + + memset( entries, 0x55, sizeof(entries) ); + + count = GetSystemPaletteEntries( hdc, 0, 256, entries ); + ok( count == 0, "wrong size %u\n", count); + + for (i = 0; i < 10; i++) + { + ok( entries[i].peRed == defpal[i].peRed && + entries[i].peGreen == defpal[i].peGreen && + entries[i].peBlue == defpal[i].peBlue && + !entries[i].peFlags, + "%u: wrong color %02x,%02x,%02x,%02x instead of %02x,%02x,%02x\n", i, + entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags, + defpal[i].peRed, defpal[i].peGreen, defpal[i].peBlue ); + } + for (i = 10; i < 246; ++i) + { + ok( !entries[i].peRed && + !entries[i].peGreen && + !entries[i].peBlue && + !entries[i].peFlags, + "%u: wrong color %02x,%02x,%02x,%02x instead of 0,0,0\n", i, + entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags); + } + for (i = 246; i < 256; i++) + { + int idx = i - 246 + 10; + ok( entries[i].peRed == defpal[idx].peRed && + entries[i].peGreen == defpal[idx].peGreen && + entries[i].peBlue == defpal[idx].peBlue && + !entries[i].peFlags, + "%u: wrong color %02x,%02x,%02x,%02x instead of %02x,%02x,%02x\n", i, + entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags, + defpal[idx].peRed, defpal[idx].peGreen, defpal[idx].peBlue ); + } + } + else + { + skip( "device is palette-based, skipping test\n" ); + } + + ReleaseDC( 0, hdc ); +} + START_TEST(palette) { test_DIB_PAL_COLORS(); test_palette_entries(); test_halftone_palette(); + test_system_palette_entries(); } -- 2.1.0