gdi32: Add a separate set of GDI object functions for DIBs.
This commit is contained in:
parent
40bf321e5a
commit
a51b2c8bd5
|
@ -566,7 +566,7 @@ static BOOL BITMAP_SetOwnerDC( HBITMAP hbitmap, PHYSDEV physdev )
|
|||
|
||||
if (!(bitmap = GDI_GetObjPtr( hbitmap, OBJ_BITMAP ))) return FALSE;
|
||||
|
||||
if (!bitmap->dib && bitmap->funcs != physdev->funcs)
|
||||
if (bitmap->funcs != physdev->funcs)
|
||||
{
|
||||
/* we can only change from the null driver to some other driver */
|
||||
if (bitmap->funcs == &null_driver)
|
||||
|
@ -634,7 +634,7 @@ static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc )
|
|||
old_physdev = pop_dc_driver( &dc->physDev );
|
||||
|
||||
physdev = GET_DC_PHYSDEV( dc, pSelectBitmap );
|
||||
if (bitmap->dib || physdev->funcs == &null_driver)
|
||||
if (physdev->funcs == &null_driver)
|
||||
{
|
||||
physdev = dc->dibdrv;
|
||||
if (physdev) push_dc_driver( &dc->physDev, physdev, physdev->funcs );
|
||||
|
@ -701,26 +701,6 @@ static BOOL BITMAP_DeleteObject( HGDIOBJ handle )
|
|||
if (!(bmp = free_gdi_handle( handle ))) return FALSE;
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, bmp->bitmap.bmBits );
|
||||
|
||||
if (bmp->dib)
|
||||
{
|
||||
DIBSECTION *dib = bmp->dib;
|
||||
|
||||
if (dib->dsBm.bmBits)
|
||||
{
|
||||
if (dib->dshSection)
|
||||
{
|
||||
SYSTEM_INFO SystemInfo;
|
||||
GetSystemInfo( &SystemInfo );
|
||||
UnmapViewOfFile( (char *)dib->dsBm.bmBits -
|
||||
(dib->dsOffset % SystemInfo.dwAllocationGranularity) );
|
||||
}
|
||||
else if (!dib->dsOffset)
|
||||
VirtualFree(dib->dsBm.bmBits, 0L, MEM_RELEASE );
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, dib);
|
||||
HeapFree(GetProcessHeap(), 0, bmp->color_table);
|
||||
}
|
||||
return HeapFree( GetProcessHeap(), 0, bmp );
|
||||
}
|
||||
|
||||
|
@ -730,30 +710,13 @@ static BOOL BITMAP_DeleteObject( HGDIOBJ handle )
|
|||
*/
|
||||
static INT BITMAP_GetObject( HGDIOBJ handle, INT count, LPVOID buffer )
|
||||
{
|
||||
INT ret;
|
||||
INT ret = 0;
|
||||
BITMAPOBJ *bmp = GDI_GetObjPtr( handle, OBJ_BITMAP );
|
||||
|
||||
if (!bmp) return 0;
|
||||
|
||||
if (!buffer) ret = sizeof(BITMAP);
|
||||
else if (count < sizeof(BITMAP)) ret = 0;
|
||||
else if (bmp->dib)
|
||||
{
|
||||
if (count >= sizeof(DIBSECTION))
|
||||
{
|
||||
DIBSECTION *dib = buffer;
|
||||
*dib = *bmp->dib;
|
||||
dib->dsBmih.biHeight = abs( dib->dsBmih.biHeight );
|
||||
ret = sizeof(DIBSECTION);
|
||||
}
|
||||
else /* if (count >= sizeof(BITMAP)) */
|
||||
{
|
||||
DIBSECTION *dib = bmp->dib;
|
||||
memcpy( buffer, &dib->dsBm, sizeof(BITMAP) );
|
||||
ret = sizeof(BITMAP);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (count >= sizeof(BITMAP))
|
||||
{
|
||||
memcpy( buffer, &bmp->bitmap, sizeof(BITMAP) );
|
||||
((BITMAP *) buffer)->bmBits = NULL;
|
||||
|
|
146
dlls/gdi32/dib.c
146
dlls/gdi32/dib.c
|
@ -72,6 +72,19 @@
|
|||
WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
|
||||
|
||||
|
||||
static HGDIOBJ DIB_SelectObject( HGDIOBJ handle, HDC hdc );
|
||||
static INT DIB_GetObject( HGDIOBJ handle, INT count, LPVOID buffer );
|
||||
static BOOL DIB_DeleteObject( HGDIOBJ handle );
|
||||
|
||||
static const struct gdi_obj_funcs dib_funcs =
|
||||
{
|
||||
DIB_SelectObject, /* pSelectObject */
|
||||
DIB_GetObject, /* pGetObjectA */
|
||||
DIB_GetObject, /* pGetObjectW */
|
||||
NULL, /* pUnrealizeObject */
|
||||
DIB_DeleteObject /* pDeleteObject */
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* bitmap_info_size
|
||||
*
|
||||
|
@ -1576,6 +1589,7 @@ HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
|
|||
{
|
||||
PHYSDEV physdev = GET_DC_PHYSDEV( dc, pCreateDIBSection );
|
||||
bmp->dib = dib;
|
||||
bmp->header.funcs = &dib_funcs;
|
||||
bmp->funcs = physdev->funcs;
|
||||
bmp->color_table = color_table;
|
||||
GDI_ReleaseObj( ret );
|
||||
|
@ -1600,3 +1614,135 @@ error:
|
|||
HeapFree( GetProcessHeap(), 0, dib );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DIB_SelectObject
|
||||
*/
|
||||
static HGDIOBJ DIB_SelectObject( HGDIOBJ handle, HDC hdc )
|
||||
{
|
||||
HGDIOBJ ret;
|
||||
BITMAPOBJ *bitmap;
|
||||
DC *dc;
|
||||
PHYSDEV physdev = NULL, old_physdev = NULL, pathdev = NULL;
|
||||
|
||||
if (!(dc = get_dc_ptr( hdc ))) return 0;
|
||||
|
||||
if (GetObjectType( hdc ) != OBJ_MEMDC)
|
||||
{
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
ret = dc->hBitmap;
|
||||
if (handle == dc->hBitmap) goto done; /* nothing to do */
|
||||
|
||||
if (!(bitmap = GDI_GetObjPtr( handle, OBJ_BITMAP )))
|
||||
{
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (bitmap->header.selcount)
|
||||
{
|
||||
WARN( "Bitmap already selected in another DC\n" );
|
||||
GDI_ReleaseObj( handle );
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (dc->physDev->funcs == &path_driver) pathdev = pop_dc_driver( &dc->physDev );
|
||||
|
||||
old_physdev = GET_DC_PHYSDEV( dc, pSelectBitmap );
|
||||
physdev = dc->dibdrv;
|
||||
if (old_physdev != dc->dibdrv)
|
||||
{
|
||||
if (physdev) push_dc_driver( &dc->physDev, physdev, physdev->funcs );
|
||||
else
|
||||
{
|
||||
if (!dib_driver.pCreateDC( &dc->physDev, NULL, NULL, NULL, NULL )) goto done;
|
||||
dc->dibdrv = physdev = dc->physDev;
|
||||
}
|
||||
}
|
||||
|
||||
if (!physdev->funcs->pSelectBitmap( physdev, handle ))
|
||||
{
|
||||
GDI_ReleaseObj( handle );
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dc->hBitmap = handle;
|
||||
GDI_inc_ref_count( handle );
|
||||
dc->dirty = 0;
|
||||
dc->vis_rect.left = 0;
|
||||
dc->vis_rect.top = 0;
|
||||
dc->vis_rect.right = bitmap->bitmap.bmWidth;
|
||||
dc->vis_rect.bottom = bitmap->bitmap.bmHeight;
|
||||
GDI_ReleaseObj( handle );
|
||||
DC_InitDC( dc );
|
||||
GDI_dec_ref_count( ret );
|
||||
}
|
||||
|
||||
done:
|
||||
if(!ret)
|
||||
{
|
||||
if (old_physdev && old_physdev != dc->dibdrv) pop_dc_driver( &dc->physDev );
|
||||
}
|
||||
if (pathdev) push_dc_driver( &dc->physDev, pathdev, pathdev->funcs );
|
||||
release_dc_ptr( dc );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DIB_GetObject
|
||||
*/
|
||||
static INT DIB_GetObject( HGDIOBJ handle, INT count, LPVOID buffer )
|
||||
{
|
||||
INT ret = 0;
|
||||
BITMAPOBJ *bmp = GDI_GetObjPtr( handle, OBJ_BITMAP );
|
||||
|
||||
if (!bmp) return 0;
|
||||
|
||||
if (!buffer) ret = sizeof(BITMAP);
|
||||
else if (count >= sizeof(DIBSECTION))
|
||||
{
|
||||
DIBSECTION *dib = buffer;
|
||||
*dib = *bmp->dib;
|
||||
dib->dsBmih.biHeight = abs( dib->dsBmih.biHeight );
|
||||
ret = sizeof(DIBSECTION);
|
||||
}
|
||||
else if (count >= sizeof(BITMAP))
|
||||
{
|
||||
BITMAP *bitmap = buffer;
|
||||
*bitmap = bmp->dib->dsBm;
|
||||
ret = sizeof(BITMAP);
|
||||
}
|
||||
|
||||
GDI_ReleaseObj( handle );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DIB_DeleteObject
|
||||
*/
|
||||
static BOOL DIB_DeleteObject( HGDIOBJ handle )
|
||||
{
|
||||
BITMAPOBJ *bmp;
|
||||
|
||||
if (!(bmp = free_gdi_handle( handle ))) return FALSE;
|
||||
|
||||
if (bmp->dib->dshSection)
|
||||
{
|
||||
SYSTEM_INFO SystemInfo;
|
||||
GetSystemInfo( &SystemInfo );
|
||||
UnmapViewOfFile( (char *)bmp->dib->dsBm.bmBits -
|
||||
(bmp->dib->dsOffset % SystemInfo.dwAllocationGranularity) );
|
||||
}
|
||||
else VirtualFree( bmp->dib->dsBm.bmBits, 0, MEM_RELEASE );
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, bmp->dib);
|
||||
HeapFree(GetProcessHeap(), 0, bmp->color_table);
|
||||
return HeapFree( GetProcessHeap(), 0, bmp );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue