diff --git a/dlls/gdi/enhmfdrv/bitblt.c b/dlls/gdi/enhmfdrv/bitblt.c index 640f0e24598..92910ffd5ae 100644 --- a/dlls/gdi/enhmfdrv/bitblt.c +++ b/dlls/gdi/enhmfdrv/bitblt.c @@ -28,8 +28,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile); -extern BOOL EMFDRV_PatBlt( PHYSDEV dev, INT left, INT top, - INT width, INT height, DWORD rop ) +BOOL EMFDRV_PatBlt( PHYSDEV dev, INT left, INT top, + INT width, INT height, DWORD rop ) { EMRBITBLT emr; BOOL ret; @@ -65,3 +65,98 @@ extern BOOL EMFDRV_PatBlt( PHYSDEV dev, INT left, INT top, EMFDRV_UpdateBBox( dev, &emr.rclBounds ); return ret; } + + +INT EMFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, + INT heightDst, INT xSrc, INT ySrc, + INT widthSrc, INT heightSrc, + const void *bits, const BITMAPINFO *info, + UINT wUsage, DWORD dwRop ) +{ + EMRSTRETCHDIBITS *emr; + BOOL ret; + UINT bmi_size=0, bits_size, emr_size; + UINT width_bytes; + + /* calculate the size of the bits we need to store */ + switch(info->bmiHeader.biBitCount) + { + case 1: + width_bytes = (info->bmiHeader.biWidth+7)/8; + break; + case 4: + width_bytes = (info->bmiHeader.biWidth+1)/2; + break; + case 8: + width_bytes = info->bmiHeader.biWidth; + break; + case 16: + width_bytes = info->bmiHeader.biWidth*2; + break; + case 24: + width_bytes = info->bmiHeader.biWidth*3; + break; + case 32: + width_bytes = info->bmiHeader.biWidth*4; + break; + default: + FIXME("bi.biCount has and unknown value (%d)\n", info->bmiHeader.biBitCount); + return FALSE; + } + width_bytes = ((width_bytes+3)/4) << 2; + bits_size = width_bytes * info->bmiHeader.biHeight; + + /* calculate the size of the colour table */ + bmi_size = sizeof (BITMAPINFO); + if ( info->bmiHeader.biBitCount <= 8 ) + { + UINT num_colors = info->bmiHeader.biClrUsed; + if ( num_colors == 0 ) + num_colors = (1<bmiHeader.biBitCount); + bmi_size += num_colors*sizeof(RGBQUAD); + } + + emr_size = sizeof (EMRSTRETCHDIBITS) + bmi_size + bits_size; + emr = HeapAlloc(GetProcessHeap(), 0, emr_size ); + + /* write a bitmap info header (with colours) to the record */ + memcpy( &emr[1], info, bmi_size); + + /* write bitmap bits to the record */ + memcpy ( ( (BYTE *) (&emr[1]) ) + bmi_size, bits, bits_size); + + /* fill in the EMR header at the front of our piece of memory */ + emr->emr.iType = EMR_STRETCHDIBITS; + emr->emr.nSize = emr_size; + + emr->xDest = xDst; + emr->yDest = yDst; + emr->cxDest = widthDst; + emr->cyDest = heightDst; + emr->dwRop = dwRop; + emr->xSrc = xSrc; /* FIXME: only save the piece of the bitmap needed */ + emr->ySrc = ySrc; + + emr->iUsageSrc = DIB_RGB_COLORS; + emr->offBmiSrc = sizeof (EMRSTRETCHDIBITS); + emr->cbBmiSrc = bmi_size; + emr->offBitsSrc = emr->offBmiSrc + bmi_size; + emr->cbBitsSrc = bits_size; + + emr->cxSrc = widthSrc; + emr->cySrc = heightSrc; + + emr->rclBounds.left = xDst; + emr->rclBounds.top = yDst; + emr->rclBounds.right = xDst + widthDst; + emr->rclBounds.bottom = yDst + heightDst; + + /* save the record we just created */ + ret = EMFDRV_WriteRecord( dev, &emr->emr ); + if(ret) + EMFDRV_UpdateBBox( dev, &emr->rclBounds ); + + HeapFree(GetProcessHeap(), 0, emr); + + return ret; +} diff --git a/dlls/gdi/enhmfdrv/init.c b/dlls/gdi/enhmfdrv/init.c index 3c445aebb8b..30963affb7a 100644 --- a/dlls/gdi/enhmfdrv/init.c +++ b/dlls/gdi/enhmfdrv/init.c @@ -136,11 +136,11 @@ static const DC_FUNCTIONS EMFDRV_Funcs = NULL, /* pStartDoc */ NULL, /* pStartPage */ NULL, /* pStretchBlt */ - NULL, /* pStretchDIBits */ + EMFDRV_StretchDIBits, /* pStretchDIBits */ EMFDRV_StrokeAndFillPath, /* pStrokeAndFillPath */ EMFDRV_StrokePath, /* pStrokePath */ NULL, /* pSwapBuffers */ - EMFDRV_WidenPath /* pWiddenPath */ + EMFDRV_WidenPath /* pWidenPath */ };