From acf56f57e85f5d4b282714098027f4d4e76a8908 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Mon, 9 Aug 2021 11:31:13 +0200 Subject: [PATCH] gdi32: Handle metafiles directly in RealizePalette. Signed-off-by: Jacek Caban Signed-off-by: Huw Davies Signed-off-by: Alexandre Julliard --- dlls/gdi32/gdi_private.h | 1 + dlls/gdi32/gdidc.c | 11 +++++ dlls/gdi32/metafile.c | 2 +- dlls/gdi32/mfdrv/init.c | 2 +- dlls/gdi32/mfdrv/metafiledrv.h | 1 - dlls/gdi32/mfdrv/objects.c | 19 ++------ dlls/gdi32/ntgdi_private.h | 1 - dlls/gdi32/palette.c | 20 --------- dlls/gdi32/tests/metafile.c | 81 ++++++++++++++++++++++++++++++++++ 9 files changed, 98 insertions(+), 40 deletions(-) diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 987ac52ae69..0d23b254128 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -75,6 +75,7 @@ extern BOOL METADC_PolyPolygon( HDC hdc, const POINT *points, const INT *counts, UINT polygons ) DECLSPEC_HIDDEN; extern BOOL METADC_Polygon( HDC hdc, const POINT *points, INT count ) DECLSPEC_HIDDEN; extern BOOL METADC_Polyline( HDC hdc, const POINT *points,INT count) DECLSPEC_HIDDEN; +extern BOOL METADC_RealizePalette( HDC hdc ) DECLSPEC_HIDDEN; extern BOOL METADC_Rectangle( HDC hdc, INT left, INT top, INT right, INT bottom) DECLSPEC_HIDDEN; extern BOOL METADC_RoundRect( HDC hdc, INT left, INT top, INT right, INT bottom, INT ell_width, INT ell_height ) DECLSPEC_HIDDEN; diff --git a/dlls/gdi32/gdidc.c b/dlls/gdi32/gdidc.c index aeb3ecd9ff3..fa947d56b79 100644 --- a/dlls/gdi32/gdidc.c +++ b/dlls/gdi32/gdidc.c @@ -1265,7 +1265,9 @@ BOOL WINAPI ScaleWindowExtEx( HDC hdc, INT x_num, INT x_denom, /* Pointers to USER implementation of SelectPalette/RealizePalette */ /* they will be patched by USER on startup */ extern HPALETTE WINAPI GDISelectPalette( HDC hdc, HPALETTE hpal, WORD wBkg ); +extern UINT WINAPI GDIRealizePalette( HDC hdc ); HPALETTE (WINAPI *pfnSelectPalette)( HDC hdc, HPALETTE hpal, WORD bkgnd ) = GDISelectPalette; +UINT (WINAPI *pfnRealizePalette)( HDC hdc ) = GDIRealizePalette; /*********************************************************************** * SelectPalette (GDI32.@) @@ -1280,6 +1282,15 @@ HPALETTE WINAPI SelectPalette( HDC hdc, HPALETTE palette, BOOL force_background return pfnSelectPalette( hdc, palette, force_background ); } +/*********************************************************************** + * RealizePalette (GDI32.@) + */ +UINT WINAPI RealizePalette( HDC hdc ) +{ + if (is_meta_dc( hdc )) return METADC_RealizePalette( hdc ); + return pfnRealizePalette( hdc ); +} + /*********************************************************************** * GdiSetPixelFormat (GDI32.@) */ diff --git a/dlls/gdi32/metafile.c b/dlls/gdi32/metafile.c index 0c07f60a986..2059e9baab9 100644 --- a/dlls/gdi32/metafile.c +++ b/dlls/gdi32/metafile.c @@ -797,7 +797,7 @@ BOOL WINAPI PlayMetaFileRecord( HDC hdc, HANDLETABLE *ht, METARECORD *mr, UINT break; case META_REALIZEPALETTE: - GDIRealizePalette(hdc); + RealizePalette(hdc); break; case META_ESCAPE: diff --git a/dlls/gdi32/mfdrv/init.c b/dlls/gdi32/mfdrv/init.c index ba5331f1680..2406f737362 100644 --- a/dlls/gdi32/mfdrv/init.c +++ b/dlls/gdi32/mfdrv/init.c @@ -174,7 +174,7 @@ static const struct gdi_dc_funcs MFDRV_Funcs = NULL, /* pPolylineTo */ NULL, /* pPutImage */ NULL, /* pRealizeDefaultPalette */ - MFDRV_RealizePalette, /* pRealizePalette */ + NULL, /* pRealizePalette */ NULL, /* pRectangle */ NULL, /* pResetDC */ MFDRV_RestoreDC, /* pRestoreDC */ diff --git a/dlls/gdi32/mfdrv/metafiledrv.h b/dlls/gdi32/mfdrv/metafiledrv.h index 7d3eee866f0..74015babb30 100644 --- a/dlls/gdi32/mfdrv/metafiledrv.h +++ b/dlls/gdi32/mfdrv/metafiledrv.h @@ -95,7 +95,6 @@ extern BOOL CDECL MFDRV_PolyBezierTo( PHYSDEV dev, const POINT* pt, DWORD count extern BOOL CDECL MFDRV_RestoreDC( PHYSDEV dev, INT level ) DECLSPEC_HIDDEN; extern BOOL CDECL MFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size ) DECLSPEC_HIDDEN; extern BOOL CDECL MFDRV_SelectClipPath( PHYSDEV dev, INT iMode ) DECLSPEC_HIDDEN; -extern UINT CDECL MFDRV_RealizePalette(PHYSDEV dev, HPALETTE hPalette, BOOL primary) DECLSPEC_HIDDEN; extern COLORREF CDECL MFDRV_SetBkColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN; extern COLORREF CDECL MFDRV_SetDCBrushColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN; extern COLORREF CDECL MFDRV_SetDCPenColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN; diff --git a/dlls/gdi32/mfdrv/objects.c b/dlls/gdi32/mfdrv/objects.c index 381a0f9d5b6..a933c1814cf 100644 --- a/dlls/gdi32/mfdrv/objects.c +++ b/dlls/gdi32/mfdrv/objects.c @@ -445,24 +445,11 @@ BOOL METADC_SelectPalette( HDC hdc, HPALETTE palette ) } /*********************************************************************** - * MFDRV_RealizePalette + * METADC_RealizePalette */ -UINT CDECL MFDRV_RealizePalette(PHYSDEV dev, HPALETTE hPalette, BOOL dummy) +BOOL METADC_RealizePalette( HDC hdc ) { - char buffer[sizeof(METARECORD) - sizeof(WORD)]; - METARECORD *mr = (METARECORD *)&buffer; - - mr->rdSize = (sizeof(METARECORD) - sizeof(WORD)) / sizeof(WORD); - mr->rdFunction = META_REALIZEPALETTE; - - if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD)))) return 0; - - /* The return value is suppose to be the number of entries - in the logical palette mapped to the system palette or 0 - if the function failed. Since it's not trivial here to - get that kind of information and since it's of little - use in the case of metafiles, we'll always return 1. */ - return 1; + return metadc_param0( hdc, META_REALIZEPALETTE ); } diff --git a/dlls/gdi32/ntgdi_private.h b/dlls/gdi32/ntgdi_private.h index 0282c304667..de7ed17369f 100644 --- a/dlls/gdi32/ntgdi_private.h +++ b/dlls/gdi32/ntgdi_private.h @@ -483,7 +483,6 @@ extern POINT *GDI_Bezier( const POINT *Points, INT count, INT *nPtsOut ) DECLSPE /* palette.c */ extern HPALETTE WINAPI GDISelectPalette( HDC hdc, HPALETTE hpal, WORD wBkg) DECLSPEC_HIDDEN; -extern UINT WINAPI GDIRealizePalette( HDC hdc ) DECLSPEC_HIDDEN; extern HPALETTE PALETTE_Init(void) DECLSPEC_HIDDEN; /* region.c */ diff --git a/dlls/gdi32/palette.c b/dlls/gdi32/palette.c index c46e56bea03..e767bd7e949 100644 --- a/dlls/gdi32/palette.c +++ b/dlls/gdi32/palette.c @@ -60,10 +60,6 @@ static const struct gdi_obj_funcs palette_funcs = PALETTE_DeleteObject /* pDeleteObject */ }; -/* Pointers to USER implementation of SelectPalette/RealizePalette */ -/* they will be patched by USER on startup */ -UINT (WINAPI *pfnRealizePalette)(HDC hdc) = GDIRealizePalette; - static UINT SystemPaletteUse = SYSPAL_STATIC; /* currently not considered */ static HPALETTE hPrimaryPalette = 0; /* used for WM_PALETTECHANGED */ @@ -677,22 +673,6 @@ UINT WINAPI GDIRealizePalette( HDC hdc ) } -/*********************************************************************** - * RealizePalette [GDI32.@] - * - * Maps palette entries to system palette. - * - * RETURNS - * Success: Number of entries in logical palette - * Failure: GDI_ERROR - */ -UINT WINAPI RealizePalette( - HDC hDC) /* [in] Handle of device context */ -{ - return pfnRealizePalette( hDC ); -} - - typedef HWND (WINAPI *WindowFromDC_funcptr)( HDC ); typedef BOOL (WINAPI *RedrawWindow_funcptr)( HWND, const RECT *, HRGN, UINT ); diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c index 728d2144afd..31f4027e5ba 100644 --- a/dlls/gdi32/tests/metafile.c +++ b/dlls/gdi32/tests/metafile.c @@ -3968,6 +3968,86 @@ static void test_emf_select(void) ok(ret, "DeleteEnhMetaFile(%p) error %d\n", hemf, GetLastError()); } +static const PALETTEENTRY logpalettedata[8] = { + { 0x10, 0x20, 0x30, PC_NOCOLLAPSE }, + { 0x20, 0x30, 0x40, PC_NOCOLLAPSE }, + { 0x30, 0x40, 0x50, PC_NOCOLLAPSE }, + { 0x40, 0x50, 0x60, PC_NOCOLLAPSE }, + { 0x50, 0x60, 0x70, PC_NOCOLLAPSE }, + { 0x60, 0x70, 0x80, PC_NOCOLLAPSE }, + { 0x70, 0x80, 0x90, PC_NOCOLLAPSE }, + { 0x80, 0x90, 0xA0, PC_NOCOLLAPSE }, +}; + +static void test_mf_palette(void) +{ + char logpalettebuf[sizeof(LOGPALETTE) + sizeof(logpalettedata)]; + LOGPALETTE *logpalette = (PLOGPALETTE)logpalettebuf; + HPALETTE hpal, old_pal; + HMETAFILE hmf; + HDC hdc; + BOOL ret; + + static const unsigned char palette_bits[] = + { + 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x5c, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x2d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0xf7, 0x00, + 0x00, 0x03, 0x08, 0x00, 0x10, 0x20, 0x30, 0x04, + 0x20, 0x30, 0x40, 0x04, 0x30, 0x40, 0x50, 0x04, + 0x40, 0x50, 0x60, 0x04, 0x50, 0x60, 0x70, 0x04, + 0x60, 0x70, 0x80, 0x04, 0x70, 0x80, 0x90, 0x04, + 0x80, 0x90, 0xa0, 0x04, 0x04, 0x00, 0x00, 0x00, + 0x34, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x35, 0x00, 0x2d, 0x00, 0x00, 0x00, 0xf7, 0x00, + 0x00, 0x03, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, + 0x80, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, + 0xc0, 0xc0, 0xc0, 0x00, 0xc0, 0xdc, 0xc0, 0x00, + 0xa6, 0xca, 0xf0, 0x00, 0xff, 0xfb, 0xf0, 0x00, + 0xa0, 0xa0, 0xa4, 0x00, 0x80, 0x80, 0x80, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, + 0xff, 0xff, 0xff, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x34, 0x02, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x35, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + hdc = CreateMetaFileA(NULL); + ok( hdc != 0, "CreateMetaFileA failed\n" ); + + /* Initialize the logical palette with a few colours */ + logpalette->palVersion = 0x300; + logpalette->palNumEntries = ARRAY_SIZE(logpalettedata); + memcpy( logpalette->palPalEntry, logpalettedata, sizeof(logpalettedata) ); + hpal = CreatePalette( logpalette ); + old_pal = SelectPalette( hdc, hpal, FALSE ); + ok(old_pal == ULongToHandle(TRUE), "old_pal=%p\n", old_pal); + + ret = RealizePalette(hdc); + ok(ret, "RealizePalette failed\n"); + + old_pal = SelectPalette( hdc, GetStockObject(DEFAULT_PALETTE), FALSE ); + ok(old_pal == ULongToHandle(TRUE), "old_pal=%p\n", old_pal); + + ret = RealizePalette(hdc); + ok(ret, "RealizePalette failed\n"); + + hmf = CloseMetaFile(hdc); + ok( hmf != 0, "CloseMetaFile failed\n" ); + + if (compare_mf_bits(hmf, palette_bits, sizeof(palette_bits), "mf_palette")) + { + dump_mf_bits(hmf, "mf_palette"); + EnumMetaFile(0, hmf, mf_enum_proc, 0); + } + + ret = DeleteMetaFile(hmf); + ok(ret, "DeleteMetaFile(%p) error %d\n", hmf, GetLastError()); +} + static void test_mf_ExtTextOut_on_path(void) { HDC hdcMetafile; @@ -6795,6 +6875,7 @@ START_TEST(metafile) test_mf_FloodFill(); test_mf_attrs(); test_mf_select(); + test_mf_palette(); /* For metafile conversions */ test_mf_conversions();