gdi32: Implement EMFDRV_AlphaBlend().
Fix a bug that Tally produces a blank print preview when images have to be scaled. Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
0893240da5
commit
8ae18d055a
|
@ -27,6 +27,94 @@
|
|||
#include "enhmetafiledrv.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
BOOL CDECL EMFDRV_AlphaBlend( PHYSDEV dev_dst, struct bitblt_coords *dst,
|
||||
PHYSDEV dev_src, struct bitblt_coords *src, BLENDFUNCTION func )
|
||||
{
|
||||
unsigned char src_buffer[FIELD_OFFSET(BITMAPINFO, bmiColors[256])];
|
||||
BITMAPINFO *src_info = (BITMAPINFO *)src_buffer;
|
||||
UINT bits_size, bmi_size, emr_size, size, bpp;
|
||||
struct gdi_image_bits bits;
|
||||
EMRALPHABLEND *emr;
|
||||
BITMAPINFO *bmi;
|
||||
DC *dc_src;
|
||||
DWORD err;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
dc_src = get_physdev_dc(dev_src);
|
||||
dev_src = GET_DC_PHYSDEV(dc_src, pGetImage);
|
||||
err = dev_src->funcs->pGetImage(dev_src, src_info, &bits, src);
|
||||
if (err)
|
||||
{
|
||||
SetLastError(err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bpp = src_info->bmiHeader.biBitCount;
|
||||
if (bpp <= 8)
|
||||
bmi_size = sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD);
|
||||
else if (bpp == 16 || bpp == 32)
|
||||
bmi_size = sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD);
|
||||
else
|
||||
bmi_size = sizeof(BITMAPINFOHEADER);
|
||||
emr_size = sizeof(EMRALPHABLEND);
|
||||
bits_size = src_info->bmiHeader.biSizeImage;
|
||||
size = emr_size + bmi_size + bits_size;
|
||||
|
||||
emr = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
if (!emr) goto err;
|
||||
|
||||
emr->emr.iType = EMR_ALPHABLEND;
|
||||
emr->emr.nSize = size;
|
||||
emr->rclBounds.left = dst->log_x;
|
||||
emr->rclBounds.top = dst->log_y;
|
||||
emr->rclBounds.right = dst->log_x + dst->log_width - 1;
|
||||
emr->rclBounds.bottom = dst->log_y + dst->log_height - 1;
|
||||
emr->xDest = dst->log_x;
|
||||
emr->yDest = dst->log_y;
|
||||
emr->cxDest = dst->log_width;
|
||||
emr->cyDest = dst->log_height;
|
||||
emr->xSrc = src->log_x;
|
||||
emr->ySrc = src->log_y;
|
||||
emr->cxSrc = src->log_width;
|
||||
emr->cySrc = src->log_height;
|
||||
emr->dwRop = *(DWORD *)&func;
|
||||
GetTransform(dev_src->hdc, 0x204, &emr->xformSrc);
|
||||
emr->crBkColorSrc = GetBkColor(dev_src->hdc);
|
||||
emr->iUsageSrc = DIB_RGB_COLORS;
|
||||
emr->offBmiSrc = emr_size;
|
||||
emr->cbBmiSrc = bmi_size;
|
||||
emr->offBitsSrc = emr_size + bmi_size;
|
||||
emr->cbBitsSrc = bits_size;
|
||||
|
||||
bmi = (BITMAPINFO *)((BYTE *)emr + emr->offBmiSrc);
|
||||
memcpy(bmi, src_info, bmi_size);
|
||||
memcpy((BYTE *)emr + emr->offBitsSrc, bits.ptr, bits_size);
|
||||
|
||||
bmi->bmiHeader.biClrUsed = 0;
|
||||
if (bmi->bmiHeader.biCompression == BI_RGB && bmi->bmiHeader.biBitCount == 16)
|
||||
{
|
||||
bmi->bmiHeader.biCompression = BI_BITFIELDS;
|
||||
((DWORD *)bmi->bmiColors)[0] = 0xf800;
|
||||
((DWORD *)bmi->bmiColors)[1] = 0x07e0;
|
||||
((DWORD *)bmi->bmiColors)[2] = 0x001f;
|
||||
}
|
||||
else if (bmi->bmiHeader.biCompression == BI_RGB && bmi->bmiHeader.biBitCount == 32)
|
||||
{
|
||||
bmi->bmiHeader.biCompression = BI_BITFIELDS;
|
||||
((DWORD *)bmi->bmiColors)[0] = 0xff0000;
|
||||
((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
|
||||
((DWORD *)bmi->bmiColors)[2] = 0x0000ff;
|
||||
}
|
||||
|
||||
ret = EMFDRV_WriteRecord(dev_dst, (EMR *)emr);
|
||||
if (ret) EMFDRV_UpdateBBox(dev_dst, &emr->rclBounds);
|
||||
|
||||
err:
|
||||
HeapFree(GetProcessHeap(), 0, emr);
|
||||
if (bits.free) bits.free(&bits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL CDECL EMFDRV_PatBlt( PHYSDEV dev, struct bitblt_coords *dst, DWORD rop )
|
||||
{
|
||||
EMRBITBLT emr;
|
||||
|
|
|
@ -58,6 +58,8 @@ extern DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush ) DECLSPEC_H
|
|||
|
||||
/* Metafile driver functions */
|
||||
extern BOOL CDECL EMFDRV_AbortPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
|
||||
extern BOOL CDECL EMFDRV_AlphaBlend( PHYSDEV dev_dst, struct bitblt_coords *dst,
|
||||
PHYSDEV dev_src, struct bitblt_coords *src, BLENDFUNCTION func ) DECLSPEC_HIDDEN;
|
||||
extern BOOL CDECL EMFDRV_AngleArc( PHYSDEV dev, INT x, INT y, DWORD radius, FLOAT start, FLOAT sweep ) DECLSPEC_HIDDEN;
|
||||
extern BOOL CDECL EMFDRV_Arc( PHYSDEV dev, INT left, INT top, INT right,
|
||||
INT bottom, INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -38,7 +38,7 @@ static const struct gdi_dc_funcs emfdrv_driver =
|
|||
{
|
||||
NULL, /* pAbortDoc */
|
||||
EMFDRV_AbortPath, /* pAbortPath */
|
||||
NULL, /* pAlphaBlend */
|
||||
EMFDRV_AlphaBlend, /* pAlphaBlend */
|
||||
EMFDRV_AngleArc, /* pAngleArc */
|
||||
EMFDRV_Arc, /* pArc */
|
||||
EMFDRV_ArcTo, /* pArcTo */
|
||||
|
|
|
@ -5001,15 +5001,13 @@ static void test_emf_AlphaBlend(void)
|
|||
ret = BitBlt(hdc_bitmap, 0, 0, bitmap_width, bitmap_height, 0, 0, 0, BLACKNESS);
|
||||
ok(ret, "Test %d: BitBlt failed, error %d\n", test_idx, GetLastError());
|
||||
ret = GdiAlphaBlend(hdc_emf, 0, 0, bitmap_width, bitmap_height, hdc_bitmap, 0, 0, 400, 400, blend);
|
||||
todo_wine
|
||||
ok(ret, "Test %d: GdiAlphaBlend failed, error %d\n", test_idx, GetLastError());
|
||||
|
||||
hemf = CloseEnhMetaFile(hdc_emf);
|
||||
ok(!!hemf, "Test %d: CloseEnhMetaFile failed, %d\n", test_idx, GetLastError());
|
||||
|
||||
sprintf(comment, "test_emf_AlphaBlend() test %d", test_idx);
|
||||
if (ret)
|
||||
ret = compare_emf_bits(hemf, tests[test_idx].bits, tests[test_idx].bits_count, comment, FALSE);
|
||||
ret = compare_emf_bits(hemf, tests[test_idx].bits, tests[test_idx].bits_count, comment, FALSE);
|
||||
if (ret)
|
||||
{
|
||||
dump_emf_bits(hemf, comment);
|
||||
|
|
Loading…
Reference in New Issue