BOOL MFDRV_StretchBlt( PHYSDEV devDst, INT xDst, INT yDst, INT widthDst, INT heightDst, PHYSDEV devSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, DWORD rop ) { BOOL ret; DWORD len; METARECORD *mr; BITMAP BM; METAFILEDRV_PDEVICE *physDevSrc = (METAFILEDRV_PDEVICE *)devSrc; #ifdef STRETCH_VIA_DIB LPBITMAPINFOHEADER lpBMI; WORD nBPP; #endif HBITMAP hBitmap = GetCurrentObject(physDevSrc->hdc, OBJ_BITMAP); if (GetObjectW(hBitmap, sizeof(BITMAP), &BM) != sizeof(BITMAP)) { WARN("bad bitmap object %p passed for hdc %p\n", hBitmap, physDevSrc->hdc); return FALSE; } #ifdef STRETCH_VIA_DIB nBPP = BM.bmPlanes * BM.bmBitsPixel; if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */ len = sizeof(METARECORD) + 10 * sizeof(INT16) + sizeof(BITMAPINFOHEADER) + (nBPP <= 8 ? 1 << nBPP: 0) * sizeof(RGBQUAD) + DIB_GetDIBWidthBytes(BM.bmWidth, nBPP) * BM.bmHeight; if (!(mr = HeapAlloc( GetProcessHeap(), 0, len))) return FALSE; mr->rdFunction = META_DIBSTRETCHBLT; lpBMI=(LPBITMAPINFOHEADER)(mr->rdParm+10); lpBMI->biSize = sizeof(BITMAPINFOHEADER); lpBMI->biWidth = BM.bmWidth; lpBMI->biHeight = BM.bmHeight; lpBMI->biPlanes = 1; lpBMI->biBitCount = nBPP; lpBMI->biSizeImage = DIB_GetDIBWidthBytes(BM.bmWidth, nBPP) * lpBMI->biHeight; lpBMI->biClrUsed = nBPP <= 8 ? 1 << nBPP : 0; lpBMI->biCompression = BI_RGB; lpBMI->biXPelsPerMeter = MulDiv(GetDeviceCaps(physDevSrc->hdc,LOGPIXELSX),3937,100); lpBMI->biYPelsPerMeter = MulDiv(GetDeviceCaps(physDevSrc->hdc,LOGPIXELSY),3937,100); lpBMI->biClrImportant = 0; /* 1 meter = 39.37 inch */ TRACE("MF_StretchBltViaDIB->len = %ld rop=%lx PixYPM=%ld Caps=%d\n", len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(physDevSrc->hdc, LOGPIXELSY)); if (GetDIBits(physDevSrc->hdc, hBitmap, 0, (UINT)lpBMI->biHeight, (LPSTR)lpBMI + DIB_BitmapInfoSize( (BITMAPINFO *)lpBMI, DIB_RGB_COLORS ), (LPBITMAPINFO)lpBMI, DIB_RGB_COLORS)) #else len = sizeof(METARECORD) + 15 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight; if (!(mr = HeapAlloc( GetProcessHeap(), 0, len ))) return FALSE; mr->rdFunction = META_STRETCHBLT; *(mr->rdParm +10) = BM.bmWidth; *(mr->rdParm +11) = BM.bmHeight; *(mr->rdParm +12) = BM.bmWidthBytes; *(mr->rdParm +13) = BM.bmPlanes; *(mr->rdParm +14) = BM.bmBitsPixel; TRACE("len = %ld rop=%lx\n", len, rop); if (GetBitmapBits( hBitmap, BM.bmWidthBytes * BM.bmHeight, mr->rdParm + 15)) #endif { mr->rdSize = len / sizeof(INT16); *(mr->rdParm) = LOWORD(rop); *(mr->rdParm + 1) = HIWORD(rop); *(mr->rdParm + 2) = heightSrc; *(mr->rdParm + 3) = widthSrc; *(mr->rdParm + 4) = ySrc; *(mr->rdParm + 5) = xSrc; *(mr->rdParm + 6) = heightDst; *(mr->rdParm + 7) = widthDst; *(mr->rdParm + 8) = yDst; *(mr->rdParm + 9) = xDst; ret = MFDRV_WriteRecord( devDst, mr, mr->rdSize * 2); } else ret = FALSE; HeapFree( GetProcessHeap(), 0, mr); return ret; }
static BOOL EMFDRV_BitBlockTransfer( PHYSDEV devDst, INT xDst, INT yDst, INT widthDst, INT heightDst, PHYSDEV devSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, DWORD rop, DWORD emrType) { BOOL ret; PEMRBITBLT pEMR; UINT emrSize; UINT bmiSize; UINT bitsSize; UINT size; BITMAP BM; WORD nBPP; LPBITMAPINFOHEADER lpBmiH; EMFDRV_PDEVICE* physDevSrc = (EMFDRV_PDEVICE*)devSrc; HBITMAP hBitmap = GetCurrentObject(physDevSrc->hdc, OBJ_BITMAP); if (emrType == EMR_BITBLT) emrSize = sizeof(EMRBITBLT); else if (emrType == EMR_STRETCHBLT) emrSize = sizeof(EMRSTRETCHBLT); else return FALSE; if(sizeof(BITMAP) != GetObjectW(hBitmap, sizeof(BITMAP), &BM)) return FALSE; nBPP = BM.bmPlanes * BM.bmBitsPixel; if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */ bitsSize = DIB_GetDIBWidthBytes(BM.bmWidth, nBPP) * BM.bmHeight; bmiSize = sizeof(BITMAPINFOHEADER) + (nBPP <= 8 ? 1 << nBPP : 0) * sizeof(RGBQUAD); size = emrSize + bmiSize + bitsSize; pEMR = HeapAlloc(GetProcessHeap(), 0, size); if (!pEMR) return FALSE; /* Initialize EMR */ pEMR->emr.iType = emrType; pEMR->emr.nSize = size; pEMR->rclBounds.left = xDst; pEMR->rclBounds.top = yDst; pEMR->rclBounds.right = xDst + widthDst - 1; pEMR->rclBounds.bottom = yDst + heightDst - 1; pEMR->xDest = xDst; pEMR->yDest = yDst; pEMR->cxDest = widthDst; pEMR->cyDest = heightDst; pEMR->dwRop = rop; pEMR->xSrc = xSrc; pEMR->ySrc = ySrc; 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 = GetBkColor(physDevSrc->hdc); pEMR->iUsageSrc = DIB_RGB_COLORS; pEMR->offBmiSrc = emrSize; pEMR->cbBmiSrc = bmiSize; pEMR->offBitsSrc = emrSize + bmiSize; pEMR->cbBitsSrc = bitsSize; if (emrType == EMR_STRETCHBLT) { PEMRSTRETCHBLT pEMRStretch = (PEMRSTRETCHBLT)pEMR; pEMRStretch->cxSrc = widthSrc; pEMRStretch->cySrc = heightSrc; } /* Initialize BITMAPINFO structure */ lpBmiH = (LPBITMAPINFOHEADER)((BYTE*)pEMR + pEMR->offBmiSrc); lpBmiH->biSize = sizeof(BITMAPINFOHEADER); lpBmiH->biWidth = BM.bmWidth; lpBmiH->biHeight = BM.bmHeight; lpBmiH->biPlanes = BM.bmPlanes; lpBmiH->biBitCount = nBPP; /* Assume the bitmap isn't compressed and set the BI_RGB flag. */ lpBmiH->biCompression = BI_RGB; lpBmiH->biSizeImage = bitsSize; lpBmiH->biYPelsPerMeter = /* 1 meter = 39.37 inch */ MulDiv(GetDeviceCaps(physDevSrc->hdc,LOGPIXELSX),3937,100); lpBmiH->biXPelsPerMeter = MulDiv(GetDeviceCaps(physDevSrc->hdc,LOGPIXELSY),3937,100); lpBmiH->biClrUsed = nBPP <= 8 ? 1 << nBPP : 0; /* Set biClrImportant to 0, indicating that all of the device colors are important. */ lpBmiH->biClrImportant = 0; /* Initialize bitmap bits */ if (GetDIBits(physDevSrc->hdc, hBitmap, 0, (UINT)lpBmiH->biHeight, (BYTE*)pEMR + pEMR->offBitsSrc, (LPBITMAPINFO)lpBmiH, DIB_RGB_COLORS)) { ret = EMFDRV_WriteRecord(devDst, (EMR*)pEMR); if (ret) EMFDRV_UpdateBBox(devDst, &(pEMR->rclBounds)); } else ret = FALSE; HeapFree( GetProcessHeap(), 0, pEMR); return ret; }