static void set_initial_bitmap_bits( HBITMAP hbitmap, BITMAPOBJ *bmp ) { char src_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *src_info = (BITMAPINFO *)src_bmibuf; char dst_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *dst_info = (BITMAPINFO *)dst_bmibuf; DWORD err; struct gdi_image_bits bits; struct bitblt_coords src, dst; if (!bmp->bitmap.bmBits) return; if (bmp->funcs->pPutImage == nulldrv_PutImage) return; get_ddb_bitmapinfo( bmp, src_info ); bits.ptr = bmp->bitmap.bmBits; bits.is_copy = FALSE; bits.free = NULL; bits.param = NULL; src.x = 0; src.y = 0; src.width = bmp->bitmap.bmWidth; src.height = bmp->bitmap.bmHeight; src.visrect.left = 0; src.visrect.top = 0; src.visrect.right = bmp->bitmap.bmWidth; src.visrect.bottom = bmp->bitmap.bmHeight; dst = src; copy_bitmapinfo( dst_info, src_info ); err = bmp->funcs->pPutImage( NULL, hbitmap, 0, dst_info, &bits, &src, &dst, 0 ); if (err == ERROR_BAD_FORMAT) { err = convert_bits( src_info, &src, dst_info, &bits, FALSE ); if (!err) err = bmp->funcs->pPutImage( NULL, hbitmap, 0, dst_info, &bits, &src, &dst, 0 ); if (bits.free) bits.free( &bits ); } }
BOOL nulldrv_AlphaBlend( PHYSDEV dst_dev, struct bitblt_coords *dst, PHYSDEV src_dev, struct bitblt_coords *src, BLENDFUNCTION func ) { DC *dc_src, *dc_dst = get_nulldrv_dc( dst_dev ); char src_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; char dst_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *src_info = (BITMAPINFO *)src_buffer; BITMAPINFO *dst_info = (BITMAPINFO *)dst_buffer; DWORD err; struct gdi_image_bits bits; if (!(dc_src = get_dc_ptr( src_dev->hdc ))) return FALSE; src_dev = GET_DC_PHYSDEV( dc_src, pGetImage ); err = src_dev->funcs->pGetImage( src_dev, src_info, &bits, src ); if (err) goto done; dst_dev = GET_DC_PHYSDEV( dc_dst, pBlendImage ); copy_bitmapinfo( dst_info, src_info ); err = dst_dev->funcs->pBlendImage( dst_dev, dst_info, &bits, src, dst, func ); if (err == ERROR_BAD_FORMAT) { err = convert_bits( src_info, src, dst_info, &bits ); if (!err) err = dst_dev->funcs->pBlendImage( dst_dev, dst_info, &bits, src, dst, func ); } if (err == ERROR_TRANSFORM_NOT_SUPPORTED && ((src->width != dst->width) || (src->height != dst->height))) { copy_bitmapinfo( src_info, dst_info ); err = stretch_bits( src_info, src, dst_info, dst, &bits, COLORONCOLOR ); if (!err) err = dst_dev->funcs->pBlendImage( dst_dev, dst_info, &bits, src, dst, func ); } if (bits.free) bits.free( &bits ); done: release_dc_ptr( dc_src ); if (err) SetLastError( err ); return !err; }
BOOL nulldrv_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst, PHYSDEV src_dev, struct bitblt_coords *src, DWORD rop ) { DC *dc_src, *dc_dst = get_nulldrv_dc( dst_dev ); char src_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; char dst_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *src_info = (BITMAPINFO *)src_buffer; BITMAPINFO *dst_info = (BITMAPINFO *)dst_buffer; DWORD err; struct gdi_image_bits bits; if (!(dc_src = get_dc_ptr( src_dev->hdc ))) return FALSE; src_dev = GET_DC_PHYSDEV( dc_src, pGetImage ); if (src_dev->funcs->pGetImage( src_dev, src_info, &bits, src )) { release_dc_ptr( dc_src ); return FALSE; } dst_dev = GET_DC_PHYSDEV( dc_dst, pPutImage ); copy_bitmapinfo( dst_info, src_info ); err = dst_dev->funcs->pPutImage( dst_dev, 0, dst_info, &bits, src, dst, rop ); if (err == ERROR_BAD_FORMAT) { DWORD dst_colors = dst_info->bmiHeader.biClrUsed; /* 1-bpp source without a color table uses the destination DC colors */ if (src_info->bmiHeader.biBitCount == 1 && !src_info->bmiHeader.biClrUsed) get_mono_dc_colors( dst_dev->hdc, src_info, 2 ); if (dst_info->bmiHeader.biBitCount == 1 && !dst_colors) { /* 1-bpp destination without a color table requires a fake 1-entry table * that contains only the background color; except with a 1-bpp source, * in which case it uses the source colors */ if (src_info->bmiHeader.biBitCount > 1) get_mono_dc_colors( src_dev->hdc, dst_info, 1 ); else get_mono_dc_colors( src_dev->hdc, dst_info, 2 ); } if (!(err = convert_bits( src_info, src, dst_info, &bits ))) { /* get rid of the fake destination table */ dst_info->bmiHeader.biClrUsed = dst_colors; err = dst_dev->funcs->pPutImage( dst_dev, 0, dst_info, &bits, src, dst, rop ); } } if (err == ERROR_TRANSFORM_NOT_SUPPORTED && ((src->width != dst->width) || (src->height != dst->height))) { copy_bitmapinfo( src_info, dst_info ); err = stretch_bits( src_info, src, dst_info, dst, &bits, GetStretchBltMode( dst_dev->hdc )); if (!err) err = dst_dev->funcs->pPutImage( dst_dev, 0, dst_info, &bits, src, dst, rop ); } if (bits.free) bits.free( &bits ); release_dc_ptr( dc_src ); return !err; }