diff --git a/dlls/gdi32/bitmap.c b/dlls/gdi32/bitmap.c index 226f358d448..9e2cd320e4d 100644 --- a/dlls/gdi32/bitmap.c +++ b/dlls/gdi32/bitmap.c @@ -54,55 +54,31 @@ DWORD nulldrv_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info, struct gdi_image_bits *bits, struct bitblt_coords *src ) { BITMAPOBJ *bmp; - int height, width_bytes; + DWORD ret; if (!hbitmap) return ERROR_NOT_SUPPORTED; if (!(bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP ))) return ERROR_INVALID_HANDLE; - info->bmiHeader.biSize = sizeof(info->bmiHeader); - info->bmiHeader.biPlanes = 1; - info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel; - info->bmiHeader.biCompression = BI_RGB; - info->bmiHeader.biXPelsPerMeter = 0; - info->bmiHeader.biYPelsPerMeter = 0; - info->bmiHeader.biClrUsed = 0; - info->bmiHeader.biClrImportant = 0; - if (bmp->bitmap.bmBitsPixel == 16) + if (bmp->bitmap.bmBits || !bits) { - DWORD *masks = (DWORD *)info->bmiColors; - masks[0] = 0x7c00; - masks[1] = 0x03e0; - masks[2] = 0x001f; - info->bmiHeader.biCompression = BI_BITFIELDS; + ret = dib_driver.pGetImage( 0, hbitmap, info, bits, src ); } - if (!bits) goto done; - - height = src->visrect.bottom - src->visrect.top; - width_bytes = get_dib_stride( bmp->bitmap.bmWidth, bmp->bitmap.bmBitsPixel ); - info->bmiHeader.biWidth = bmp->bitmap.bmWidth; - info->bmiHeader.biHeight = -height; - info->bmiHeader.biSizeImage = height * width_bytes; - - /* make the source rectangle relative to the returned bits */ - src->y -= src->visrect.top; - offset_rect( &src->visrect, 0, -src->visrect.top ); - - if (bmp->bitmap.bmBits) - { - bits->ptr = (char *)bmp->bitmap.bmBits + src->visrect.top * width_bytes; - bits->is_copy = FALSE; - bits->free = NULL; - } - else + else if (!(ret = dib_driver.pGetImage( 0, hbitmap, info, NULL, src ))) { + info->bmiHeader.biHeight = -(src->visrect.bottom - src->visrect.top); + info->bmiHeader.biSizeImage = get_dib_image_size( info ); + + /* make the source rectangle relative to the returned bits */ + src->y -= src->visrect.top; + offset_rect( &src->visrect, 0, -src->visrect.top ); + /* return all-zero bits */ bits->ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage ); bits->is_copy = TRUE; bits->free = free_heap_bits; } -done: GDI_ReleaseObj( hbitmap ); - return ERROR_SUCCESS; + return ret; } DWORD nulldrv_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMAPINFO *info, diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c index 7ab2982c8f6..78dbd148002 100644 --- a/dlls/gdi32/dib.c +++ b/dlls/gdi32/dib.c @@ -895,6 +895,22 @@ static void fill_default_color_table( BITMAPINFO *info ) } } +void get_ddb_bitmapinfo( BITMAPOBJ *bmp, BITMAPINFO *info ) +{ + info->bmiHeader.biSize = sizeof(info->bmiHeader); + info->bmiHeader.biWidth = bmp->bitmap.bmWidth; + info->bmiHeader.biHeight = -bmp->bitmap.bmHeight; + info->bmiHeader.biPlanes = 1; + info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel; + info->bmiHeader.biCompression = BI_RGB; + info->bmiHeader.biXPelsPerMeter = 0; + info->bmiHeader.biYPelsPerMeter = 0; + info->bmiHeader.biClrUsed = 0; + info->bmiHeader.biClrImportant = 0; + if (info->bmiHeader.biBitCount <= 8) fill_default_color_table( info ); +} + + /****************************************************************************** * GetDIBits [GDI32.@] * diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c index 245e7c73601..7caea01c187 100644 --- a/dlls/gdi32/dibdrv/dc.c +++ b/dlls/gdi32/dibdrv/dc.c @@ -213,7 +213,14 @@ BOOL init_dib_info_from_bitmapinfo(dib_info *dib, const BITMAPINFO *info, void * BOOL init_dib_info_from_bitmapobj(dib_info *dib, BITMAPOBJ *bmp, enum dib_info_flags flags) { - assert(bmp->dib); + if (!bmp->dib) + { + char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; + BITMAPINFO *info = (BITMAPINFO *)buffer; + + get_ddb_bitmapinfo( bmp, info ); + return init_dib_info_from_bitmapinfo( dib, info, bmp->bitmap.bmBits, flags ); + } return init_dib_info( dib, &bmp->dib->dsBmih, bmp->dib->dsBitfields, bmp->color_table, bmp->nb_colors, bmp->dib->dsBm.bmBits, flags ); } diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 2189040dc72..1b855ca65a6 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -308,6 +308,7 @@ extern BOOL BIDI_Reorder( HDC hDC, LPCWSTR lpString, INT uCount, DWORD dwFlags, LPWSTR lpOutString, INT uCountOut, UINT *lpOrder, WORD **lpGlyphs, INT* cGlyphs ) DECLSPEC_HIDDEN; /* bitmap.c */ +extern void get_ddb_bitmapinfo( BITMAPOBJ *bmp, BITMAPINFO *info ) DECLSPEC_HIDDEN; extern BOOL get_bitmap_image( HBITMAP hbitmap, BITMAPINFO *info, struct gdi_image_bits *bits ) DECLSPEC_HIDDEN; extern HBITMAP BITMAP_CopyBitmap( HBITMAP hbitmap ) DECLSPEC_HIDDEN; extern BOOL BITMAP_SetOwnerDC( HBITMAP hbitmap, PHYSDEV physdev ) DECLSPEC_HIDDEN;