1 /* 2 * GDI bit-blit operations 3 * 4 * Copyright 1993, 1994 Alexandre Julliard 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include <string.h> 22 23 #include "mfdrv/metafiledrv.h" 24 #include "wine/debug.h" 25 26 WINE_DEFAULT_DEBUG_CHANNEL(metafile); 27 28 /*********************************************************************** 29 * MFDRV_PatBlt 30 */ 31 BOOL MFDRV_PatBlt( PHYSDEV dev, struct bitblt_coords *dst, DWORD rop ) 32 { 33 MFDRV_MetaParam6( dev, META_PATBLT, dst->log_x, dst->log_y, dst->log_width, dst->log_height, 34 HIWORD(rop), LOWORD(rop) ); 35 return TRUE; 36 } 37 38 39 /*********************************************************************** 40 * MFDRV_StretchBlt 41 * this function contains TWO ways for processing StretchBlt in metafiles, 42 * decide between rdFunction values META_STRETCHBLT or META_DIBSTRETCHBLT 43 * via #define STRETCH_VIA_DIB 44 */ 45 #define STRETCH_VIA_DIB 46 47 BOOL MFDRV_StretchBlt( PHYSDEV devDst, struct bitblt_coords *dst, 48 PHYSDEV devSrc, struct bitblt_coords *src, DWORD rop ) 49 { 50 BOOL ret; 51 DWORD len; 52 METARECORD *mr; 53 BITMAP BM; 54 #ifdef STRETCH_VIA_DIB 55 LPBITMAPINFOHEADER lpBMI; 56 WORD nBPP; 57 #endif 58 HBITMAP hBitmap = GetCurrentObject(devSrc->hdc, OBJ_BITMAP); 59 60 if (devSrc->funcs == devDst->funcs) return FALSE; /* can't use a metafile DC as source */ 61 62 if (GetObjectW(hBitmap, sizeof(BITMAP), &BM) != sizeof(BITMAP)) 63 { 64 WARN("bad bitmap object %p passed for hdc %p\n", hBitmap, devSrc->hdc); 65 return FALSE; 66 } 67 #ifdef STRETCH_VIA_DIB 68 nBPP = BM.bmPlanes * BM.bmBitsPixel; 69 if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */ 70 len = sizeof(METARECORD) + 10 * sizeof(INT16) 71 + sizeof(BITMAPINFOHEADER) + (nBPP <= 8 ? 1 << nBPP: 0) * sizeof(RGBQUAD) 72 + get_dib_stride( BM.bmWidth, nBPP ) * BM.bmHeight; 73 if (!(mr = HeapAlloc( GetProcessHeap(), 0, len))) 74 return FALSE; 75 mr->rdFunction = META_DIBSTRETCHBLT; 76 lpBMI=(LPBITMAPINFOHEADER)(mr->rdParm+10); 77 lpBMI->biSize = sizeof(BITMAPINFOHEADER); 78 lpBMI->biWidth = BM.bmWidth; 79 lpBMI->biHeight = BM.bmHeight; 80 lpBMI->biPlanes = 1; 81 lpBMI->biBitCount = nBPP; 82 lpBMI->biSizeImage = get_dib_image_size( (BITMAPINFO *)lpBMI ); 83 lpBMI->biClrUsed = nBPP <= 8 ? 1 << nBPP : 0; 84 lpBMI->biCompression = BI_RGB; 85 lpBMI->biXPelsPerMeter = MulDiv(GetDeviceCaps(devSrc->hdc,LOGPIXELSX),3937,100); 86 lpBMI->biYPelsPerMeter = MulDiv(GetDeviceCaps(devSrc->hdc,LOGPIXELSY),3937,100); 87 lpBMI->biClrImportant = 0; /* 1 meter = 39.37 inch */ 88 89 TRACE("MF_StretchBltViaDIB->len = %d rop=%x PixYPM=%d Caps=%d\n", 90 len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(devSrc->hdc, LOGPIXELSY)); 91 92 if (GetDIBits(devSrc->hdc, hBitmap, 0, (UINT)lpBMI->biHeight, 93 (LPSTR)lpBMI + get_dib_info_size( (BITMAPINFO *)lpBMI, DIB_RGB_COLORS ), 94 (LPBITMAPINFO)lpBMI, DIB_RGB_COLORS)) 95 #else 96 len = sizeof(METARECORD) + 15 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight; 97 if (!(mr = HeapAlloc( GetProcessHeap(), 0, len ))) 98 return FALSE; 99 mr->rdFunction = META_STRETCHBLT; 100 *(mr->rdParm +10) = BM.bmWidth; 101 *(mr->rdParm +11) = BM.bmHeight; 102 *(mr->rdParm +12) = BM.bmWidthBytes; 103 *(mr->rdParm +13) = BM.bmPlanes; 104 *(mr->rdParm +14) = BM.bmBitsPixel; 105 TRACE("len = %ld rop=%lx\n", len, rop); 106 if (GetBitmapBits( hBitmap, BM.bmWidthBytes * BM.bmHeight, mr->rdParm + 15)) 107 #endif 108 { 109 mr->rdSize = len / sizeof(INT16); 110 *(mr->rdParm) = LOWORD(rop); 111 *(mr->rdParm + 1) = HIWORD(rop); 112 *(mr->rdParm + 2) = src->log_height; 113 *(mr->rdParm + 3) = src->log_width; 114 *(mr->rdParm + 4) = src->log_y; 115 *(mr->rdParm + 5) = src->log_x; 116 *(mr->rdParm + 6) = dst->log_height; 117 *(mr->rdParm + 7) = dst->log_width; 118 *(mr->rdParm + 8) = dst->log_y; 119 *(mr->rdParm + 9) = dst->log_x; 120 ret = MFDRV_WriteRecord( devDst, mr, mr->rdSize * 2); 121 } 122 else 123 ret = FALSE; 124 HeapFree( GetProcessHeap(), 0, mr); 125 return ret; 126 } 127 128 129 /*********************************************************************** 130 * MFDRV_StretchDIBits 131 */ 132 INT MFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, 133 INT heightDst, INT xSrc, INT ySrc, INT widthSrc, 134 INT heightSrc, const void *bits, 135 BITMAPINFO *info, UINT wUsage, DWORD dwRop ) 136 { 137 DWORD infosize = get_dib_info_size(info, wUsage); 138 DWORD len = sizeof(METARECORD) + 10 * sizeof(WORD) + infosize + info->bmiHeader.biSizeImage; 139 METARECORD *mr = HeapAlloc( GetProcessHeap(), 0, len ); 140 if(!mr) return 0; 141 142 mr->rdSize = len / 2; 143 mr->rdFunction = META_STRETCHDIB; 144 mr->rdParm[0] = LOWORD(dwRop); 145 mr->rdParm[1] = HIWORD(dwRop); 146 mr->rdParm[2] = wUsage; 147 mr->rdParm[3] = (INT16)heightSrc; 148 mr->rdParm[4] = (INT16)widthSrc; 149 mr->rdParm[5] = (INT16)ySrc; 150 mr->rdParm[6] = (INT16)xSrc; 151 mr->rdParm[7] = (INT16)heightDst; 152 mr->rdParm[8] = (INT16)widthDst; 153 mr->rdParm[9] = (INT16)yDst; 154 mr->rdParm[10] = (INT16)xDst; 155 memcpy(mr->rdParm + 11, info, infosize); 156 memcpy(mr->rdParm + 11 + infosize / 2, bits, info->bmiHeader.biSizeImage); 157 MFDRV_WriteRecord( dev, mr, mr->rdSize * 2 ); 158 HeapFree( GetProcessHeap(), 0, mr ); 159 return heightSrc; 160 } 161 162 163 /*********************************************************************** 164 * MFDRV_SetDIBitsToDevice 165 */ 166 INT MFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDst, INT yDst, DWORD cx, 167 DWORD cy, INT xSrc, INT ySrc, UINT startscan, 168 UINT lines, LPCVOID bits, BITMAPINFO *info, UINT coloruse ) 169 170 { 171 DWORD infosize = get_dib_info_size(info, coloruse); 172 DWORD len = sizeof(METARECORD) + 8 * sizeof(WORD) + infosize + info->bmiHeader.biSizeImage; 173 METARECORD *mr = HeapAlloc( GetProcessHeap(), 0, len ); 174 if(!mr) return 0; 175 176 mr->rdSize = len / 2; 177 mr->rdFunction = META_SETDIBTODEV; 178 mr->rdParm[0] = coloruse; 179 mr->rdParm[1] = lines; 180 mr->rdParm[2] = startscan; 181 mr->rdParm[3] = (INT16)ySrc; 182 mr->rdParm[4] = (INT16)xSrc; 183 mr->rdParm[5] = (INT16)cy; 184 mr->rdParm[6] = (INT16)cx; 185 mr->rdParm[7] = (INT16)yDst; 186 mr->rdParm[8] = (INT16)xDst; 187 memcpy(mr->rdParm + 9, info, infosize); 188 memcpy(mr->rdParm + 9 + infosize / 2, bits, info->bmiHeader.biSizeImage); 189 MFDRV_WriteRecord( dev, mr, mr->rdSize * 2 ); 190 HeapFree( GetProcessHeap(), 0, mr ); 191 return lines; 192 } 193