| /* | |
| * GDI bit-blit operations | |
| * | |
| * Copyright 1993, 1994 Alexandre Julliard | |
| */ | |
| #include <string.h> | |
| #include "gdi.h" | |
| #include "metafiledrv.h" | |
| #include "heap.h" | |
| #include "debugtools.h" | |
| #include "bitmap.h" | |
| DEFAULT_DEBUG_CHANNEL(metafile) | |
| /*********************************************************************** | |
| * MFDRV_PatBlt | |
| */ | |
| BOOL MFDRV_PatBlt( DC *dc, INT left, INT top, | |
| INT width, INT height, DWORD rop ) | |
| { | |
| MFDRV_MetaParam6( dc, META_PATBLT, left, top, width, height, | |
| HIWORD(rop), LOWORD(rop) ); | |
| return TRUE; | |
| } | |
| /*********************************************************************** | |
| * MFDRV_BitBlt | |
| */ | |
| BOOL MFDRV_BitBlt( DC *dcDst, INT xDst, INT yDst, INT width, INT height, | |
| DC *dcSrc, INT xSrc, INT ySrc, DWORD rop ) | |
| { | |
| BOOL ret; | |
| DWORD len; | |
| METARECORD *mr; | |
| BITMAP16 BM; | |
| GetObject16(dcSrc->w.hBitmap, sizeof(BITMAP16), &BM); | |
| len = sizeof(METARECORD) + 12 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight; | |
| if (!(mr = HeapAlloc(GetProcessHeap(), 0, len))) | |
| return FALSE; | |
| mr->rdFunction = META_BITBLT; | |
| *(mr->rdParm + 7) = BM.bmWidth; | |
| *(mr->rdParm + 8) = BM.bmHeight; | |
| *(mr->rdParm + 9) = BM.bmWidthBytes; | |
| *(mr->rdParm +10) = BM.bmPlanes; | |
| *(mr->rdParm +11) = BM.bmBitsPixel; | |
| TRACE("len = %ld rop=%lx \n",len,rop); | |
| if (GetBitmapBits(dcSrc->w.hBitmap,BM.bmWidthBytes * BM.bmHeight, | |
| mr->rdParm +12)) | |
| { | |
| mr->rdSize = len / sizeof(INT16); | |
| *(mr->rdParm) = HIWORD(rop); | |
| *(mr->rdParm + 1) = ySrc; | |
| *(mr->rdParm + 2) = xSrc; | |
| *(mr->rdParm + 3) = height; | |
| *(mr->rdParm + 4) = width; | |
| *(mr->rdParm + 5) = yDst; | |
| *(mr->rdParm + 6) = xDst; | |
| ret = MFDRV_WriteRecord( dcDst, mr, mr->rdSize * 2); | |
| } | |
| else | |
| ret = FALSE; | |
| HeapFree( GetProcessHeap(), 0, mr); | |
| return ret; | |
| } | |
| /*********************************************************************** | |
| * MFDRV_StretchBlt | |
| * this function contains TWO ways for procesing StretchBlt in metafiles, | |
| * decide between rdFunction values META_STRETCHBLT or META_DIBSTRETCHBLT | |
| * via #define STRETCH_VIA_DIB | |
| */ | |
| #define STRETCH_VIA_DIB | |
| #undef STRETCH_VIA_DIB | |
| BOOL MFDRV_StretchBlt( DC *dcDst, INT xDst, INT yDst, INT widthDst, | |
| INT heightDst, DC *dcSrc, INT xSrc, INT ySrc, | |
| INT widthSrc, INT heightSrc, DWORD rop ) | |
| { | |
| BOOL ret; | |
| DWORD len; | |
| METARECORD *mr; | |
| BITMAP16 BM; | |
| #ifdef STRETCH_VIA_DIB | |
| LPBITMAPINFOHEADER lpBMI; | |
| WORD nBPP; | |
| #endif | |
| GetObject16(dcSrc->w.hBitmap, sizeof(BITMAP16), &BM); | |
| #ifdef STRETCH_VIA_DIB | |
| nBPP = BM.bmPlanes * BM.bmBitsPixel; | |
| len = sizeof(METARECORD) + 10 * sizeof(INT16) | |
| + sizeof(BITMAPINFOHEADER) + (nBPP != 24 ? 1 << nBPP: 0) * sizeof(RGBQUAD) | |
| + ((BM.bmWidth * nBPP + 31) / 32) * 4 * 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; /* 1,4,8 or 24 */ | |
| lpBMI->biClrUsed = nBPP != 24 ? 1 << nBPP : 0; | |
| lpBMI->biSizeImage = ((lpBMI->biWidth * nBPP + 31) / 32) * 4 * lpBMI->biHeight; | |
| lpBMI->biCompression = BI_RGB; | |
| lpBMI->biXPelsPerMeter = MulDiv(GetDeviceCaps(dcSrc->hSelf,LOGPIXELSX),3937,100); | |
| lpBMI->biYPelsPerMeter = MulDiv(GetDeviceCaps(dcSrc->hSelf,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(hdcSrc,LOGPIXELSY)); | |
| if (GetDIBits(hdcSrc,dcSrc->w.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( dcSrc->w.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( dcDst, mr, mr->rdSize * 2); | |
| } | |
| else | |
| ret = FALSE; | |
| HeapFree( GetProcessHeap(), 0, mr); | |
| return ret; | |
| } | |
| /*********************************************************************** | |
| * MFDRV_StretchDIBits | |
| */ | |
| INT MFDRV_StretchDIBits( DC *dc, 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 ) | |
| { | |
| DWORD len, infosize, imagesize; | |
| METARECORD *mr; | |
| infosize = DIB_BitmapInfoSize(info, wUsage); | |
| imagesize = DIB_GetDIBImageBytes( info->bmiHeader.biWidth, | |
| info->bmiHeader.biHeight, | |
| info->bmiHeader.biBitCount ); | |
| len = sizeof(METARECORD) + 10 * sizeof(WORD) + infosize + imagesize; | |
| mr = (METARECORD *)HeapAlloc( GetProcessHeap(), 0, len ); | |
| if(!mr) return 0; | |
| mr->rdSize = len / 2; | |
| mr->rdFunction = META_STRETCHDIB; | |
| mr->rdParm[0] = LOWORD(dwRop); | |
| mr->rdParm[1] = HIWORD(dwRop); | |
| mr->rdParm[2] = wUsage; | |
| mr->rdParm[3] = (INT16)heightSrc; | |
| mr->rdParm[4] = (INT16)widthSrc; | |
| mr->rdParm[5] = (INT16)ySrc; | |
| mr->rdParm[6] = (INT16)xSrc; | |
| mr->rdParm[7] = (INT16)heightDst; | |
| mr->rdParm[8] = (INT16)widthDst; | |
| mr->rdParm[9] = (INT16)yDst; | |
| mr->rdParm[10] = (INT16)xDst; | |
| memcpy(mr->rdParm + 11, info, infosize); | |
| memcpy(mr->rdParm + 11 + infosize / 2, bits, imagesize); | |
| MFDRV_WriteRecord( dc, mr, mr->rdSize * 2 ); | |
| HeapFree( GetProcessHeap(), 0, mr ); | |
| return heightSrc; | |
| } | |
| /*********************************************************************** | |
| * MFDRV_SetDIBitsToDeivce | |
| */ | |
| INT MFDRV_SetDIBitsToDevice( DC *dc, INT xDst, INT yDst, DWORD cx, | |
| DWORD cy, INT xSrc, INT ySrc, UINT startscan, | |
| UINT lines, LPCVOID bits, const BITMAPINFO *info, | |
| UINT coloruse ) | |
| { | |
| DWORD len, infosize, imagesize; | |
| METARECORD *mr; | |
| infosize = DIB_BitmapInfoSize(info, coloruse); | |
| imagesize = DIB_GetDIBImageBytes( info->bmiHeader.biWidth, | |
| info->bmiHeader.biHeight, | |
| info->bmiHeader.biBitCount ); | |
| len = sizeof(METARECORD) + 8 * sizeof(WORD) + infosize + imagesize; | |
| mr = (METARECORD *)HeapAlloc( GetProcessHeap(), 0, len ); | |
| if(!mr) return 0; | |
| mr->rdSize = len / 2; | |
| mr->rdFunction = META_SETDIBTODEV; | |
| mr->rdParm[0] = coloruse; | |
| mr->rdParm[1] = lines; | |
| mr->rdParm[2] = startscan; | |
| mr->rdParm[3] = (INT16)ySrc; | |
| mr->rdParm[4] = (INT16)xSrc; | |
| mr->rdParm[5] = (INT16)cy; | |
| mr->rdParm[6] = (INT16)cx; | |
| mr->rdParm[7] = (INT16)yDst; | |
| mr->rdParm[8] = (INT16)xDst; | |
| memcpy(mr->rdParm + 9, info, infosize); | |
| memcpy(mr->rdParm + 9 + infosize / 2, bits, imagesize); | |
| MFDRV_WriteRecord( dc, mr, mr->rdSize * 2 ); | |
| HeapFree( GetProcessHeap(), 0, mr ); | |
| return lines; | |
| } | |