gdi32/enhmfdrv: When blitting, don't crash if the source is NULL.

This commit is contained in:
Charles Davis 2009-11-22 13:25:38 -07:00 committed by Alexandre Julliard
parent 5e17b04df7
commit b6f841eaca
1 changed files with 75 additions and 38 deletions

View File

@ -79,10 +79,14 @@ static BOOL EMFDRV_BitBlockTransfer(
UINT bitsSize; UINT bitsSize;
UINT size; UINT size;
BITMAP BM; BITMAP BM;
WORD nBPP; WORD nBPP = 0;
LPBITMAPINFOHEADER lpBmiH; LPBITMAPINFOHEADER lpBmiH;
BOOL useSrc;
EMFDRV_PDEVICE* physDevSrc = (EMFDRV_PDEVICE*)devSrc; EMFDRV_PDEVICE* physDevSrc = (EMFDRV_PDEVICE*)devSrc;
HBITMAP hBitmap = GetCurrentObject(physDevSrc->hdc, OBJ_BITMAP); HBITMAP hBitmap = NULL;
useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000));
if (!physDevSrc && useSrc) return FALSE;
if (emrType == EMR_BITBLT) if (emrType == EMR_BITBLT)
emrSize = sizeof(EMRBITBLT); emrSize = sizeof(EMRBITBLT);
@ -91,16 +95,25 @@ static BOOL EMFDRV_BitBlockTransfer(
else else
return FALSE; return FALSE;
if(sizeof(BITMAP) != GetObjectW(hBitmap, sizeof(BITMAP), &BM)) if(useSrc)
return FALSE; {
hBitmap = GetCurrentObject(physDevSrc->hdc, OBJ_BITMAP);
nBPP = BM.bmPlanes * BM.bmBitsPixel; if(sizeof(BITMAP) != GetObjectW(hBitmap, sizeof(BITMAP), &BM))
if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */ return FALSE;
bitsSize = DIB_GetDIBWidthBytes(BM.bmWidth, nBPP) * BM.bmHeight; nBPP = BM.bmPlanes * BM.bmBitsPixel;
bmiSize = sizeof(BITMAPINFOHEADER) + if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */
(nBPP <= 8 ? 1 << nBPP : 0) * sizeof(RGBQUAD); bitsSize = DIB_GetDIBWidthBytes(BM.bmWidth, nBPP) * BM.bmHeight;
size = emrSize + bmiSize + bitsSize; bmiSize = sizeof(BITMAPINFOHEADER) +
(nBPP <= 8 ? 1 << nBPP : 0) * sizeof(RGBQUAD);
}
else
{
bitsSize = bmiSize = 0;
}
size = emrSize + bmiSize + bitsSize;
pEMR = HeapAlloc(GetProcessHeap(), 0, size); pEMR = HeapAlloc(GetProcessHeap(), 0, size);
if (!pEMR) return FALSE; if (!pEMR) return FALSE;
@ -119,12 +132,28 @@ static BOOL EMFDRV_BitBlockTransfer(
pEMR->dwRop = rop; pEMR->dwRop = rop;
pEMR->xSrc = xSrc; pEMR->xSrc = xSrc;
pEMR->ySrc = ySrc; pEMR->ySrc = ySrc;
GetWorldTransform(physDevSrc->hdc, &pEMR->xformSrc); if (useSrc)
pEMR->crBkColorSrc = GetBkColor(physDevSrc->hdc); {
pEMR->iUsageSrc = DIB_RGB_COLORS; GetWorldTransform(physDevSrc->hdc, &pEMR->xformSrc);
pEMR->offBmiSrc = emrSize; pEMR->crBkColorSrc = GetBkColor(physDevSrc->hdc);
pEMR->iUsageSrc = DIB_RGB_COLORS;
pEMR->offBmiSrc = emrSize;
pEMR->offBitsSrc = emrSize + bmiSize;
}
else
{
pEMR->xformSrc.eM11 = 1.0; /** FIXME: */
pEMR->xformSrc.eM12 = 0.0; /** Setting default */
pEMR->xformSrc.eM21 = 0.0; /** value. */
pEMR->xformSrc.eM22 = 1.0; /** Where should we */
pEMR->xformSrc.eDx = 0.0; /** get that info */
pEMR->xformSrc.eDy = 0.0; /** ???? */
pEMR->crBkColorSrc = 0;
pEMR->iUsageSrc = 0;
pEMR->offBmiSrc = 0;
pEMR->offBitsSrc = 0;
}
pEMR->cbBmiSrc = bmiSize; pEMR->cbBmiSrc = bmiSize;
pEMR->offBitsSrc = emrSize + bmiSize;
pEMR->cbBitsSrc = bitsSize; pEMR->cbBitsSrc = bitsSize;
if (emrType == EMR_STRETCHBLT) if (emrType == EMR_STRETCHBLT)
{ {
@ -133,34 +162,42 @@ static BOOL EMFDRV_BitBlockTransfer(
pEMRStretch->cySrc = heightSrc; pEMRStretch->cySrc = heightSrc;
} }
/* Initialize BITMAPINFO structure */ if (useSrc)
lpBmiH = (LPBITMAPINFOHEADER)((BYTE*)pEMR + pEMR->offBmiSrc); {
/* Initialize BITMAPINFO structure */
lpBmiH = (LPBITMAPINFOHEADER)((BYTE*)pEMR + pEMR->offBmiSrc);
lpBmiH->biSize = sizeof(BITMAPINFOHEADER); lpBmiH->biSize = sizeof(BITMAPINFOHEADER);
lpBmiH->biWidth = BM.bmWidth; lpBmiH->biWidth = BM.bmWidth;
lpBmiH->biHeight = BM.bmHeight; lpBmiH->biHeight = BM.bmHeight;
lpBmiH->biPlanes = BM.bmPlanes; lpBmiH->biPlanes = BM.bmPlanes;
lpBmiH->biBitCount = nBPP; lpBmiH->biBitCount = nBPP;
/* Assume the bitmap isn't compressed and set the BI_RGB flag. */ /* Assume the bitmap isn't compressed and set the BI_RGB flag. */
lpBmiH->biCompression = BI_RGB; lpBmiH->biCompression = BI_RGB;
lpBmiH->biSizeImage = bitsSize; lpBmiH->biSizeImage = bitsSize;
lpBmiH->biYPelsPerMeter = 0; lpBmiH->biYPelsPerMeter = 0;
lpBmiH->biXPelsPerMeter = 0; lpBmiH->biXPelsPerMeter = 0;
lpBmiH->biClrUsed = nBPP <= 8 ? 1 << nBPP : 0; lpBmiH->biClrUsed = nBPP <= 8 ? 1 << nBPP : 0;
/* Set biClrImportant to 0, indicating that all of the /* Set biClrImportant to 0, indicating that all of the
device colors are important. */ device colors are important. */
lpBmiH->biClrImportant = 0; lpBmiH->biClrImportant = 0;
/* Initialize bitmap bits */ /* Initialize bitmap bits */
if (GetDIBits(physDevSrc->hdc, hBitmap, 0, (UINT)lpBmiH->biHeight, if (GetDIBits(physDevSrc->hdc, hBitmap, 0, (UINT)lpBmiH->biHeight,
(BYTE*)pEMR + pEMR->offBitsSrc, (BYTE*)pEMR + pEMR->offBitsSrc,
(LPBITMAPINFO)lpBmiH, DIB_RGB_COLORS)) (LPBITMAPINFO)lpBmiH, DIB_RGB_COLORS))
{
ret = EMFDRV_WriteRecord(devDst, (EMR*)pEMR);
if (ret) EMFDRV_UpdateBBox(devDst, &(pEMR->rclBounds));
}
else
ret = FALSE;
}
else
{ {
ret = EMFDRV_WriteRecord(devDst, (EMR*)pEMR); ret = EMFDRV_WriteRecord(devDst, (EMR*)pEMR);
if (ret) EMFDRV_UpdateBBox(devDst, &(pEMR->rclBounds)); if (ret) EMFDRV_UpdateBBox(devDst, &(pEMR->rclBounds));
} }
else
ret = FALSE;
HeapFree( GetProcessHeap(), 0, pEMR); HeapFree( GetProcessHeap(), 0, pEMR);
return ret; return ret;