gdi32: Handle EMFs directly in SelectObject.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
5fdfe8c2d0
commit
0804dfd276
|
@ -100,10 +100,8 @@ extern BOOL CDECL EMFDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT righ
|
||||||
extern BOOL CDECL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom,
|
extern BOOL CDECL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom,
|
||||||
INT yNum, INT yDenom, SIZE *size ) DECLSPEC_HIDDEN;
|
INT yNum, INT yDenom, SIZE *size ) DECLSPEC_HIDDEN;
|
||||||
extern HBITMAP CDECL EMFDRV_SelectBitmap( PHYSDEV dev, HBITMAP handle ) DECLSPEC_HIDDEN;
|
extern HBITMAP CDECL EMFDRV_SelectBitmap( PHYSDEV dev, HBITMAP handle ) DECLSPEC_HIDDEN;
|
||||||
extern HBRUSH CDECL EMFDRV_SelectBrush( PHYSDEV dev, HBRUSH hbrush, const struct brush_pattern *pattern ) DECLSPEC_HIDDEN;
|
|
||||||
extern BOOL CDECL EMFDRV_SelectClipPath( PHYSDEV dev, INT iMode ) DECLSPEC_HIDDEN;
|
extern BOOL CDECL EMFDRV_SelectClipPath( PHYSDEV dev, INT iMode ) DECLSPEC_HIDDEN;
|
||||||
extern HFONT CDECL EMFDRV_SelectFont( PHYSDEV dev, HFONT handle, UINT *aa_flags ) DECLSPEC_HIDDEN;
|
extern HFONT CDECL EMFDRV_SelectFont( PHYSDEV dev, HFONT handle, UINT *aa_flags ) DECLSPEC_HIDDEN;
|
||||||
extern HPEN CDECL EMFDRV_SelectPen( PHYSDEV dev, HPEN handle, const struct brush_pattern *pattern ) DECLSPEC_HIDDEN;
|
|
||||||
extern HPALETTE CDECL EMFDRV_SelectPalette( PHYSDEV dev, HPALETTE hPal, BOOL force ) DECLSPEC_HIDDEN;
|
extern HPALETTE CDECL EMFDRV_SelectPalette( PHYSDEV dev, HPALETTE hPal, BOOL force ) DECLSPEC_HIDDEN;
|
||||||
extern COLORREF CDECL EMFDRV_SetBkColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
|
extern COLORREF CDECL EMFDRV_SetBkColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
|
||||||
extern COLORREF CDECL EMFDRV_SetDCBrushColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
|
extern COLORREF CDECL EMFDRV_SetDCBrushColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -115,11 +115,11 @@ static const struct gdi_dc_funcs emfdrv_driver =
|
||||||
EMFDRV_RestoreDC, /* pRestoreDC */
|
EMFDRV_RestoreDC, /* pRestoreDC */
|
||||||
EMFDRV_RoundRect, /* pRoundRect */
|
EMFDRV_RoundRect, /* pRoundRect */
|
||||||
EMFDRV_SelectBitmap, /* pSelectBitmap */
|
EMFDRV_SelectBitmap, /* pSelectBitmap */
|
||||||
EMFDRV_SelectBrush, /* pSelectBrush */
|
NULL, /* pSelectBrush */
|
||||||
EMFDRV_SelectClipPath, /* pSelectClipPath */
|
EMFDRV_SelectClipPath, /* pSelectClipPath */
|
||||||
EMFDRV_SelectFont, /* pSelectFont */
|
EMFDRV_SelectFont, /* pSelectFont */
|
||||||
EMFDRV_SelectPalette, /* pSelectPalette */
|
EMFDRV_SelectPalette, /* pSelectPalette */
|
||||||
EMFDRV_SelectPen, /* pSelectPen */
|
NULL, /* pSelectPen */
|
||||||
EMFDRV_SetBkColor, /* pSetBkColor */
|
EMFDRV_SetBkColor, /* pSetBkColor */
|
||||||
NULL, /* pSetBoundsRect */
|
NULL, /* pSetBoundsRect */
|
||||||
EMFDRV_SetDCBrushColor, /* pSetDCBrushColor*/
|
EMFDRV_SetDCBrushColor, /* pSetDCBrushColor*/
|
||||||
|
|
|
@ -194,17 +194,15 @@ DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush )
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* EMFDRV_SelectBrush
|
* EMFDC_SelectBrush
|
||||||
*/
|
*/
|
||||||
HBRUSH CDECL EMFDRV_SelectBrush( PHYSDEV dev, HBRUSH hBrush, const struct brush_pattern *pattern )
|
static BOOL EMFDC_SelectBrush( DC_ATTR *dc_attr, HBRUSH brush )
|
||||||
{
|
{
|
||||||
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
|
EMFDRV_PDEVICE *emf = dc_attr->emf;
|
||||||
EMRSELECTOBJECT emr;
|
EMRSELECTOBJECT emr;
|
||||||
DWORD index;
|
DWORD index;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (physDev->restoring) return hBrush; /* don't output SelectObject records during RestoreDC */
|
|
||||||
|
|
||||||
/* If the object is a stock brush object, do not need to create it.
|
/* If the object is a stock brush object, do not need to create it.
|
||||||
* See definitions in wingdi.h for range of stock brushes.
|
* See definitions in wingdi.h for range of stock brushes.
|
||||||
* We do however have to handle setting the higher order bit to
|
* We do however have to handle setting the higher order bit to
|
||||||
|
@ -212,23 +210,23 @@ HBRUSH CDECL EMFDRV_SelectBrush( PHYSDEV dev, HBRUSH hBrush, const struct brush_
|
||||||
*/
|
*/
|
||||||
for (i = WHITE_BRUSH; i <= DC_BRUSH; i++)
|
for (i = WHITE_BRUSH; i <= DC_BRUSH; i++)
|
||||||
{
|
{
|
||||||
if (hBrush == GetStockObject(i))
|
if (brush == GetStockObject(i))
|
||||||
{
|
{
|
||||||
index = i | 0x80000000;
|
index = i | 0x80000000;
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if((index = EMFDRV_FindObject(dev, hBrush)) != 0)
|
if((index = EMFDRV_FindObject( &emf->dev, brush )) != 0)
|
||||||
goto found;
|
goto found;
|
||||||
|
|
||||||
if (!(index = EMFDRV_CreateBrushIndirect(dev, hBrush ))) return 0;
|
if (!(index = EMFDRV_CreateBrushIndirect( &emf->dev, brush ))) return 0;
|
||||||
GDI_hdc_using_object( hBrush, dev->hdc, EMFDC_DeleteObject );
|
GDI_hdc_using_object( brush, dc_attr->hdc, EMFDC_DeleteObject );
|
||||||
|
|
||||||
found:
|
found:
|
||||||
emr.emr.iType = EMR_SELECTOBJECT;
|
emr.emr.iType = EMR_SELECTOBJECT;
|
||||||
emr.emr.nSize = sizeof(emr);
|
emr.emr.nSize = sizeof(emr);
|
||||||
emr.ihObject = index;
|
emr.ihObject = index;
|
||||||
return EMFDRV_WriteRecord( dev, &emr.emr ) ? hBrush : 0;
|
return EMFDRV_WriteRecord( &emf->dev, &emr.emr );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -277,14 +275,21 @@ static BOOL EMFDRV_CreateFontIndirect(PHYSDEV dev, HFONT hFont )
|
||||||
*/
|
*/
|
||||||
HFONT CDECL EMFDRV_SelectFont( PHYSDEV dev, HFONT hFont, UINT *aa_flags )
|
HFONT CDECL EMFDRV_SelectFont( PHYSDEV dev, HFONT hFont, UINT *aa_flags )
|
||||||
{
|
{
|
||||||
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
|
*aa_flags = GGO_BITMAP; /* no point in anti-aliasing on metafiles */
|
||||||
|
dev = GET_NEXT_PHYSDEV( dev, pSelectFont );
|
||||||
|
return dev->funcs->pSelectFont( dev, hFont, aa_flags );
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* EMFDC_SelectFont
|
||||||
|
*/
|
||||||
|
static BOOL EMFDC_SelectFont( DC_ATTR *dc_attr, HFONT font )
|
||||||
|
{
|
||||||
|
EMFDRV_PDEVICE *emf = dc_attr->emf;
|
||||||
EMRSELECTOBJECT emr;
|
EMRSELECTOBJECT emr;
|
||||||
DWORD index;
|
DWORD index;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (physDev->restoring) goto done; /* don't output SelectObject records during RestoreDC */
|
|
||||||
if (physDev->modifying_transform) goto done; /* don't output SelectObject records when modifying the world transform */
|
|
||||||
|
|
||||||
/* If the object is a stock font object, do not need to create it.
|
/* If the object is a stock font object, do not need to create it.
|
||||||
* See definitions in wingdi.h for range of stock fonts.
|
* See definitions in wingdi.h for range of stock fonts.
|
||||||
* We do however have to handle setting the higher order bit to
|
* We do however have to handle setting the higher order bit to
|
||||||
|
@ -293,34 +298,26 @@ HFONT CDECL EMFDRV_SelectFont( PHYSDEV dev, HFONT hFont, UINT *aa_flags )
|
||||||
|
|
||||||
for (i = OEM_FIXED_FONT; i <= DEFAULT_GUI_FONT; i++)
|
for (i = OEM_FIXED_FONT; i <= DEFAULT_GUI_FONT; i++)
|
||||||
{
|
{
|
||||||
if (i != DEFAULT_PALETTE && hFont == GetStockObject(i))
|
if (i != DEFAULT_PALETTE && font == GetStockObject(i))
|
||||||
{
|
{
|
||||||
index = i | 0x80000000;
|
index = i | 0x80000000;
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((index = EMFDRV_FindObject(dev, hFont)) != 0)
|
if (!(index = EMFDRV_FindObject( &emf->dev, font )))
|
||||||
goto found;
|
{
|
||||||
|
if (!(index = EMFDRV_CreateFontIndirect( &emf->dev, font ))) return FALSE;
|
||||||
if (!(index = EMFDRV_CreateFontIndirect(dev, hFont ))) return 0;
|
GDI_hdc_using_object( font, emf->dev.hdc, EMFDC_DeleteObject );
|
||||||
GDI_hdc_using_object( hFont, dev->hdc, EMFDC_DeleteObject );
|
}
|
||||||
|
|
||||||
found:
|
found:
|
||||||
emr.emr.iType = EMR_SELECTOBJECT;
|
emr.emr.iType = EMR_SELECTOBJECT;
|
||||||
emr.emr.nSize = sizeof(emr);
|
emr.emr.nSize = sizeof(emr);
|
||||||
emr.ihObject = index;
|
emr.ihObject = index;
|
||||||
if(!EMFDRV_WriteRecord( dev, &emr.emr ))
|
return EMFDRV_WriteRecord( &emf->dev, &emr.emr );
|
||||||
return 0;
|
|
||||||
done:
|
|
||||||
*aa_flags = GGO_BITMAP; /* no point in anti-aliasing on metafiles */
|
|
||||||
dev = GET_NEXT_PHYSDEV( dev, pSelectFont );
|
|
||||||
dev->funcs->pSelectFont( dev, hFont, aa_flags );
|
|
||||||
return hFont;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* EMFDRV_CreatePenIndirect
|
* EMFDRV_CreatePenIndirect
|
||||||
*/
|
*/
|
||||||
|
@ -359,18 +356,15 @@ static DWORD EMFDRV_CreatePenIndirect(PHYSDEV dev, HPEN hPen)
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* EMFDRV_SelectPen
|
* EMFDC_SelectPen
|
||||||
*/
|
*/
|
||||||
HPEN CDECL EMFDRV_SelectPen(PHYSDEV dev, HPEN hPen, const struct brush_pattern *pattern )
|
static BOOL EMFDC_SelectPen( DC_ATTR *dc_attr, HPEN pen )
|
||||||
{
|
{
|
||||||
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
|
EMFDRV_PDEVICE *emf = dc_attr->emf;
|
||||||
EMRSELECTOBJECT emr;
|
EMRSELECTOBJECT emr;
|
||||||
DWORD index;
|
DWORD index;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (physDev->restoring) return hPen; /* don't output SelectObject records during RestoreDC */
|
|
||||||
if (physDev->modifying_transform) return hPen; /* don't output SelectObject records when modifying the world transform */
|
|
||||||
|
|
||||||
/* If the object is a stock pen object, do not need to create it.
|
/* If the object is a stock pen object, do not need to create it.
|
||||||
* See definitions in wingdi.h for range of stock pens.
|
* See definitions in wingdi.h for range of stock pens.
|
||||||
* We do however have to handle setting the higher order bit to
|
* We do however have to handle setting the higher order bit to
|
||||||
|
@ -379,23 +373,23 @@ HPEN CDECL EMFDRV_SelectPen(PHYSDEV dev, HPEN hPen, const struct brush_pattern *
|
||||||
|
|
||||||
for (i = WHITE_PEN; i <= DC_PEN; i++)
|
for (i = WHITE_PEN; i <= DC_PEN; i++)
|
||||||
{
|
{
|
||||||
if (hPen == GetStockObject(i))
|
if (pen == GetStockObject(i))
|
||||||
{
|
{
|
||||||
index = i | 0x80000000;
|
index = i | 0x80000000;
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if((index = EMFDRV_FindObject(dev, hPen)) != 0)
|
if((index = EMFDRV_FindObject( &emf->dev, pen )) != 0)
|
||||||
goto found;
|
goto found;
|
||||||
|
|
||||||
if (!(index = EMFDRV_CreatePenIndirect(dev, hPen))) return 0;
|
if (!(index = EMFDRV_CreatePenIndirect( &emf->dev, pen ))) return FALSE;
|
||||||
GDI_hdc_using_object( hPen, dev->hdc, EMFDC_DeleteObject );
|
GDI_hdc_using_object( pen, dc_attr->hdc, EMFDC_DeleteObject );
|
||||||
|
|
||||||
found:
|
found:
|
||||||
emr.emr.iType = EMR_SELECTOBJECT;
|
emr.emr.iType = EMR_SELECTOBJECT;
|
||||||
emr.emr.nSize = sizeof(emr);
|
emr.emr.nSize = sizeof(emr);
|
||||||
emr.ihObject = index;
|
emr.ihObject = index;
|
||||||
return EMFDRV_WriteRecord( dev, &emr.emr ) ? hPen : 0;
|
return EMFDRV_WriteRecord( &emf->dev, &emr.emr );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -457,6 +451,22 @@ found:
|
||||||
return EMFDRV_WriteRecord( dev, &emr.emr ) ? hPal : 0;
|
return EMFDRV_WriteRecord( dev, &emr.emr ) ? hPal : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL EMFDC_SelectObject( DC_ATTR *dc_attr, HGDIOBJ obj )
|
||||||
|
{
|
||||||
|
switch (gdi_handle_type( obj ))
|
||||||
|
{
|
||||||
|
case NTGDI_OBJ_BRUSH:
|
||||||
|
return EMFDC_SelectBrush( dc_attr, obj );
|
||||||
|
case NTGDI_OBJ_FONT:
|
||||||
|
return EMFDC_SelectFont( dc_attr, obj );
|
||||||
|
case NTGDI_OBJ_PEN:
|
||||||
|
case NTGDI_OBJ_EXTPEN:
|
||||||
|
return EMFDC_SelectPen( dc_attr, obj );
|
||||||
|
default:
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* EMFDRV_SetDCBrushColor
|
* EMFDRV_SetDCBrushColor
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -149,6 +149,7 @@ extern BOOL EMFDC_ScaleViewportExtEx( DC_ATTR *dc_attr, INT x_num, INT x_denom,
|
||||||
INT y_denom ) DECLSPEC_HIDDEN;
|
INT y_denom ) DECLSPEC_HIDDEN;
|
||||||
extern BOOL EMFDC_ScaleWindowExtEx( DC_ATTR *dc_attr, INT x_num, INT x_denom, INT y_num,
|
extern BOOL EMFDC_ScaleWindowExtEx( DC_ATTR *dc_attr, INT x_num, INT x_denom, INT y_num,
|
||||||
INT y_denom ) DECLSPEC_HIDDEN;
|
INT y_denom ) DECLSPEC_HIDDEN;
|
||||||
|
extern BOOL EMFDC_SelectObject( DC_ATTR *dc_attr, HGDIOBJ obj ) DECLSPEC_HIDDEN;
|
||||||
extern BOOL EMFDC_SetArcDirection( DC_ATTR *dc_attr, INT dir ) DECLSPEC_HIDDEN;
|
extern BOOL EMFDC_SetArcDirection( DC_ATTR *dc_attr, INT dir ) DECLSPEC_HIDDEN;
|
||||||
extern BOOL EMFDC_SetBkMode( DC_ATTR *dc_attr, INT mode ) DECLSPEC_HIDDEN;
|
extern BOOL EMFDC_SetBkMode( DC_ATTR *dc_attr, INT mode ) DECLSPEC_HIDDEN;
|
||||||
extern BOOL EMFDC_SetLayout( DC_ATTR *dc_attr, DWORD layout ) DECLSPEC_HIDDEN;
|
extern BOOL EMFDC_SetLayout( DC_ATTR *dc_attr, DWORD layout ) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -270,11 +270,14 @@ void GDI_hdc_not_using_object( HGDIOBJ obj, HDC hdc )
|
||||||
*/
|
*/
|
||||||
HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ obj )
|
HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ obj )
|
||||||
{
|
{
|
||||||
|
DC_ATTR *dc_attr;
|
||||||
HGDIOBJ ret;
|
HGDIOBJ ret;
|
||||||
|
|
||||||
TRACE( "(%p,%p)\n", hdc, obj );
|
TRACE( "(%p,%p)\n", hdc, obj );
|
||||||
|
|
||||||
if (is_meta_dc( hdc )) return METADC_SelectObject( hdc, obj );
|
if (is_meta_dc( hdc )) return METADC_SelectObject( hdc, obj );
|
||||||
|
if (!(dc_attr = get_dc_attr( hdc ))) return 0;
|
||||||
|
if (dc_attr->emf && !EMFDC_SelectObject( dc_attr, obj )) return 0;
|
||||||
|
|
||||||
switch (get_object_type( obj ))
|
switch (get_object_type( obj ))
|
||||||
{
|
{
|
||||||
|
|
|
@ -3778,6 +3778,196 @@ static void test_mf_select(void)
|
||||||
ok(ret, "DeleteMetaFile(%p) error %d\n", hmf, GetLastError());
|
ok(ret, "DeleteMetaFile(%p) error %d\n", hmf, GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_emf_select(void)
|
||||||
|
{
|
||||||
|
HENHMETAFILE hemf;
|
||||||
|
HDC hdc, hdc2;
|
||||||
|
HGDIOBJ obj;
|
||||||
|
HPEN pen;
|
||||||
|
int cnt;
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
static const unsigned char select_bits[] =
|
||||||
|
{
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xe6, 0xff, 0xff, 0xff, 0xe6, 0xff, 0xff, 0xff,
|
||||||
|
0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
|
||||||
|
0xf8, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x09, 0x06, 0x00, 0x00, 0x07, 0x04, 0x00, 0x00,
|
||||||
|
0x99, 0x01, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xcd, 0x3c, 0x06, 0x00,
|
||||||
|
0x91, 0x29, 0x04, 0x00, 0x25, 0x00, 0x00, 0x00,
|
||||||
|
0x0c, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x80,
|
||||||
|
0x25, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x80, 0x26, 0x00, 0x00, 0x00,
|
||||||
|
0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00,
|
||||||
|
0x25, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
|
||||||
|
0x08, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
|
||||||
|
0x0c, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x80,
|
||||||
|
0x22, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0x25, 0x00, 0x00, 0x00,
|
||||||
|
0x0c, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x80,
|
||||||
|
0x28, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
|
||||||
|
0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char delete_not_selected_bits[] =
|
||||||
|
{
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xe6, 0xff, 0xff, 0xff, 0xe6, 0xff, 0xff, 0xff,
|
||||||
|
0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
|
||||||
|
0xc0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x09, 0x06, 0x00, 0x00, 0x07, 0x04, 0x00, 0x00,
|
||||||
|
0x99, 0x01, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xcd, 0x3c, 0x06, 0x00,
|
||||||
|
0x91, 0x29, 0x04, 0x00, 0x26, 0x00, 0x00, 0x00,
|
||||||
|
0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00,
|
||||||
|
0x25, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
|
||||||
|
0x0c, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x80,
|
||||||
|
0x28, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
|
||||||
|
0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char delete_selected_bits[] =
|
||||||
|
{
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xe6, 0xff, 0xff, 0xff, 0xe6, 0xff, 0xff, 0xff,
|
||||||
|
0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
|
||||||
|
0xb4, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x09, 0x06, 0x00, 0x00, 0x07, 0x04, 0x00, 0x00,
|
||||||
|
0x99, 0x01, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xcd, 0x3c, 0x06, 0x00,
|
||||||
|
0x91, 0x29, 0x04, 0x00, 0x26, 0x00, 0x00, 0x00,
|
||||||
|
0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00,
|
||||||
|
0x25, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
|
||||||
|
0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x14, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
hdc = CreateEnhMetaFileA(NULL, NULL, NULL, NULL);
|
||||||
|
ok(hdc != 0, "CreateEnhMetaFileA failed\n");
|
||||||
|
|
||||||
|
obj = SelectObject(hdc, GetStockObject(DC_BRUSH));
|
||||||
|
ok(obj == GetStockObject(WHITE_BRUSH), "brush is not a stock WHITE_BRUSH: %p\n", obj);
|
||||||
|
|
||||||
|
obj = SelectObject(hdc, GetStockObject(WHITE_BRUSH));
|
||||||
|
ok(obj == GetStockObject(DC_BRUSH), "brush is not a stock DC_BRUSH: %p\n", obj);
|
||||||
|
|
||||||
|
pen = CreatePen(PS_SOLID, 1, RGB(1,1,1));
|
||||||
|
obj = SelectObject(hdc, pen);
|
||||||
|
ok(obj == GetStockObject(BLACK_PEN), "pen is not a stock BLACK_PEN: %p\n", obj);
|
||||||
|
|
||||||
|
cnt = SaveDC(hdc);
|
||||||
|
ok(cnt == 1, "cnt = %d\n", cnt);
|
||||||
|
|
||||||
|
obj = SelectObject(hdc, GetStockObject(BLACK_PEN));
|
||||||
|
ok(obj == pen, "unexpected pen: %p\n", obj);
|
||||||
|
|
||||||
|
ret = RestoreDC(hdc, -1);
|
||||||
|
ok(ret, "RestoreDC failed\n");
|
||||||
|
|
||||||
|
obj = SelectObject(hdc, GetStockObject(BLACK_PEN));
|
||||||
|
/* pen is still black after RestoreDC */
|
||||||
|
ok(obj == pen, "unexpected pen: %p\n", obj);
|
||||||
|
ret = DeleteObject(pen);
|
||||||
|
ok(ret, "DeleteObject failed: %u\n", GetLastError());
|
||||||
|
|
||||||
|
obj = GetCurrentObject(hdc, OBJ_PEN);
|
||||||
|
ok(obj == GetStockObject(BLACK_PEN), "GetCurrentObject returned %p\n", obj);
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
obj = SelectObject(hdc, GetStockObject(DEFAULT_PALETTE));
|
||||||
|
ok(!obj, "SelectObject returned %p (%u).\n", obj, GetLastError());
|
||||||
|
|
||||||
|
ret = RestoreDC(hdc, -5);
|
||||||
|
ok(!ret, "RestoreDC succeeded\n");
|
||||||
|
|
||||||
|
hemf = CloseEnhMetaFile(hdc);
|
||||||
|
ok(hemf != 0, "CloseEnhMetaFile failed\n");
|
||||||
|
|
||||||
|
if (compare_emf_bits(hemf, select_bits, sizeof(select_bits), "emf_select", FALSE))
|
||||||
|
{
|
||||||
|
dump_emf_bits(hemf, "emf_select");
|
||||||
|
dump_emf_records(hemf, "emf_select");
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = DeleteEnhMetaFile(hemf);
|
||||||
|
ok(ret, "DeleteEnhMetaFile(%p) error %d\n", hemf, GetLastError());
|
||||||
|
|
||||||
|
/* create two EMFs, select the same pen to both of them,
|
||||||
|
* unselect it from only one and then delete */
|
||||||
|
hdc = CreateEnhMetaFileA(NULL, NULL, NULL, NULL);
|
||||||
|
ok(hdc != 0, "CreateEnhMetaFileA failed\n");
|
||||||
|
hdc2 = CreateEnhMetaFileA(NULL, NULL, NULL, NULL);
|
||||||
|
ok(hdc2 != 0, "CreateEnhMetaFileA failed\n");
|
||||||
|
|
||||||
|
pen = CreatePen(PS_SOLID, 1, RGB(1,1,1));
|
||||||
|
obj = SelectObject(hdc, pen);
|
||||||
|
ok(obj == GetStockObject(BLACK_PEN), "pen is not a stock BLACK_PEN: %p\n", obj);
|
||||||
|
obj = SelectObject(hdc2, pen);
|
||||||
|
ok(obj == GetStockObject(BLACK_PEN), "pen is not a stock BLACK_PEN: %p\n", obj);
|
||||||
|
|
||||||
|
obj = SelectObject(hdc, GetStockObject(BLACK_PEN));
|
||||||
|
ok(obj == pen, "unexpected pen: %p\n", obj);
|
||||||
|
ret = DeleteObject(pen);
|
||||||
|
ok(ret, "DeleteObject failed: %u\n", GetLastError());
|
||||||
|
|
||||||
|
hemf = CloseEnhMetaFile(hdc);
|
||||||
|
ok(hemf != 0, "CloseEnhMetaFile failed\n");
|
||||||
|
if (compare_emf_bits(hemf, delete_not_selected_bits, sizeof(delete_not_selected_bits),
|
||||||
|
"emf_delete_not_selected", FALSE))
|
||||||
|
{
|
||||||
|
dump_emf_bits(hemf, "emf_delete_not_selected");
|
||||||
|
dump_emf_records(hemf, "emf_delete_not_selected");
|
||||||
|
}
|
||||||
|
ret = DeleteEnhMetaFile(hemf);
|
||||||
|
ok(ret, "DeleteEnhMetaFile(%p) error %d\n", hemf, GetLastError());
|
||||||
|
|
||||||
|
hemf = CloseEnhMetaFile(hdc2);
|
||||||
|
ok(hemf != 0, "CloseEnhMetaFile failed\n");
|
||||||
|
if (compare_emf_bits(hemf, delete_selected_bits, sizeof(delete_selected_bits),
|
||||||
|
"emf_delete_selected", FALSE))
|
||||||
|
{
|
||||||
|
dump_emf_bits(hemf, "emf_delete_selected");
|
||||||
|
dump_emf_records(hemf, "emf_delete_selected");
|
||||||
|
}
|
||||||
|
ret = DeleteEnhMetaFile(hemf);
|
||||||
|
ok(ret, "DeleteEnhMetaFile(%p) error %d\n", hemf, GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
static void test_mf_ExtTextOut_on_path(void)
|
static void test_mf_ExtTextOut_on_path(void)
|
||||||
{
|
{
|
||||||
HDC hdcMetafile;
|
HDC hdcMetafile;
|
||||||
|
@ -6586,6 +6776,7 @@ START_TEST(metafile)
|
||||||
test_enhmetafile_file();
|
test_enhmetafile_file();
|
||||||
test_emf_SetPixel();
|
test_emf_SetPixel();
|
||||||
test_emf_attrs();
|
test_emf_attrs();
|
||||||
|
test_emf_select();
|
||||||
|
|
||||||
/* For win-format metafiles (mfdrv) */
|
/* For win-format metafiles (mfdrv) */
|
||||||
test_mf_SaveDC();
|
test_mf_SaveDC();
|
||||||
|
|
Loading…
Reference in New Issue