| /* |
| * GDI bit-blit operations |
| * |
| * Copyright 1993, 1994 Alexandre Julliard |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| */ |
| |
| #include <string.h> |
| |
| #include "gdi.h" |
| #include "metafiledrv.h" |
| #include "wine/debug.h" |
| #include "bitmap.h" |
| |
| WINE_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->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->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->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->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; |
| } |
| |
| |