Implement ResetDC and PHYSICALOFFSET[X|Y] devcaps.
[wine] / dlls / gdi / mfdrv / bitblt.c
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <string.h>
22
23 #include "gdi.h"
24 #include "mfdrv/metafiledrv.h"
25 #include "wine/debug.h"
26 #include "bitmap.h"
27
28 WINE_DEFAULT_DEBUG_CHANNEL(metafile);
29
30 /***********************************************************************
31  *           MFDRV_PatBlt
32  */
33 BOOL MFDRV_PatBlt( PHYSDEV dev, INT left, INT top, INT width, INT height, DWORD rop )
34 {
35     MFDRV_MetaParam6( dev, META_PATBLT, left, top, width, height, HIWORD(rop), LOWORD(rop) );
36     return TRUE;
37 }
38
39
40 /***********************************************************************
41  *           MFDRV_BitBlt
42  */
43 BOOL MFDRV_BitBlt( PHYSDEV devDst, INT xDst, INT yDst, INT width, INT height,
44                    PHYSDEV devSrc, INT xSrc, INT ySrc, DWORD rop )
45 {
46     BOOL ret;
47     DWORD len;
48     METARECORD *mr;
49     BITMAP16  BM;
50     METAFILEDRV_PDEVICE *physDevSrc = (METAFILEDRV_PDEVICE *)devSrc;
51     DC *dcSrc = physDevSrc->dc;
52
53     GetObject16(dcSrc->hBitmap, sizeof(BITMAP16), &BM);
54     len = sizeof(METARECORD) + 12 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
55     if (!(mr = HeapAlloc(GetProcessHeap(), 0, len)))
56         return FALSE;
57     mr->rdFunction = META_BITBLT;
58     *(mr->rdParm + 7) = BM.bmWidth;
59     *(mr->rdParm + 8) = BM.bmHeight;
60     *(mr->rdParm + 9) = BM.bmWidthBytes;
61     *(mr->rdParm +10) = BM.bmPlanes;
62     *(mr->rdParm +11) = BM.bmBitsPixel;
63     TRACE("len = %ld  rop=%lx  \n",len,rop);
64     if (GetBitmapBits(dcSrc->hBitmap,BM.bmWidthBytes * BM.bmHeight,
65                         mr->rdParm +12))
66     {
67       mr->rdSize = len / sizeof(INT16);
68       *(mr->rdParm) = HIWORD(rop);
69       *(mr->rdParm + 1) = ySrc;
70       *(mr->rdParm + 2) = xSrc;
71       *(mr->rdParm + 3) = height;
72       *(mr->rdParm + 4) = width;
73       *(mr->rdParm + 5) = yDst;
74       *(mr->rdParm + 6) = xDst;
75       ret = MFDRV_WriteRecord( devDst, mr, mr->rdSize * 2);
76     } 
77     else
78         ret = FALSE;
79     HeapFree( GetProcessHeap(), 0, mr);
80     return ret;
81 }
82
83
84
85 /***********************************************************************
86  *           MFDRV_StretchBlt
87  * this function contains TWO ways for procesing StretchBlt in metafiles,
88  * decide between rdFunction values  META_STRETCHBLT or META_DIBSTRETCHBLT
89  * via #define STRETCH_VIA_DIB
90  */
91 #define STRETCH_VIA_DIB
92 #undef  STRETCH_VIA_DIB
93
94 BOOL MFDRV_StretchBlt( PHYSDEV devDst, INT xDst, INT yDst, INT widthDst,
95                        INT heightDst, PHYSDEV devSrc, INT xSrc, INT ySrc,
96                        INT widthSrc, INT heightSrc, DWORD rop )
97 {
98     BOOL ret;
99     DWORD len;
100     METARECORD *mr;
101     BITMAP16  BM;
102     METAFILEDRV_PDEVICE *physDevSrc = (METAFILEDRV_PDEVICE *)devSrc;
103     DC *dcSrc = physDevSrc->dc;
104 #ifdef STRETCH_VIA_DIB    
105     LPBITMAPINFOHEADER lpBMI;
106     WORD nBPP;
107 #endif  
108     GetObject16(dcSrc->hBitmap, sizeof(BITMAP16), &BM);
109 #ifdef STRETCH_VIA_DIB
110     nBPP = BM.bmPlanes * BM.bmBitsPixel;
111     len = sizeof(METARECORD) + 10 * sizeof(INT16) 
112             + sizeof(BITMAPINFOHEADER) + (nBPP != 24 ? 1 << nBPP: 0) * sizeof(RGBQUAD) 
113               + ((BM.bmWidth * nBPP + 31) / 32) * 4 * BM.bmHeight;
114     if (!(mr = HeapAlloc( GetProcessHeap(), 0, len)))
115         return FALSE;
116     mr->rdFunction = META_DIBSTRETCHBLT;
117     lpBMI=(LPBITMAPINFOHEADER)(mr->rdParm+10);
118     lpBMI->biSize      = sizeof(BITMAPINFOHEADER);
119     lpBMI->biWidth     = BM.bmWidth;
120     lpBMI->biHeight    = BM.bmHeight;
121     lpBMI->biPlanes    = 1;
122     lpBMI->biBitCount  = nBPP;                              /* 1,4,8 or 24 */
123     lpBMI->biClrUsed   = nBPP != 24 ? 1 << nBPP : 0;
124     lpBMI->biSizeImage = ((lpBMI->biWidth * nBPP + 31) / 32) * 4 * lpBMI->biHeight;
125     lpBMI->biCompression = BI_RGB;
126     lpBMI->biXPelsPerMeter = MulDiv(GetDeviceCaps(dcSrc->hSelf,LOGPIXELSX),3937,100);
127     lpBMI->biYPelsPerMeter = MulDiv(GetDeviceCaps(dcSrc->hSelf,LOGPIXELSY),3937,100);
128     lpBMI->biClrImportant  = 0;                          /* 1 meter  = 39.37 inch */
129
130     TRACE("MF_StretchBltViaDIB->len = %ld  rop=%lx  PixYPM=%ld Caps=%d\n",
131                len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(hdcSrc,LOGPIXELSY));
132     if (GetDIBits(hdcSrc,dcSrc->w.hBitmap,0,(UINT)lpBMI->biHeight,
133                   (LPSTR)lpBMI + DIB_BitmapInfoSize( (BITMAPINFO *)lpBMI,
134                                                      DIB_RGB_COLORS ),
135                   (LPBITMAPINFO)lpBMI, DIB_RGB_COLORS))
136 #else
137     len = sizeof(METARECORD) + 15 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
138     if (!(mr = HeapAlloc( GetProcessHeap(), 0, len )))
139         return FALSE;
140     mr->rdFunction = META_STRETCHBLT;
141     *(mr->rdParm +10) = BM.bmWidth;
142     *(mr->rdParm +11) = BM.bmHeight;
143     *(mr->rdParm +12) = BM.bmWidthBytes;
144     *(mr->rdParm +13) = BM.bmPlanes;
145     *(mr->rdParm +14) = BM.bmBitsPixel;
146     TRACE("len = %ld  rop=%lx  \n",len,rop);
147     if (GetBitmapBits( dcSrc->hBitmap, BM.bmWidthBytes * BM.bmHeight,
148                          mr->rdParm +15))
149 #endif    
150     {
151       mr->rdSize = len / sizeof(INT16);
152       *(mr->rdParm) = LOWORD(rop);
153       *(mr->rdParm + 1) = HIWORD(rop);
154       *(mr->rdParm + 2) = heightSrc;
155       *(mr->rdParm + 3) = widthSrc;
156       *(mr->rdParm + 4) = ySrc;
157       *(mr->rdParm + 5) = xSrc;
158       *(mr->rdParm + 6) = heightDst;
159       *(mr->rdParm + 7) = widthDst;
160       *(mr->rdParm + 8) = yDst;
161       *(mr->rdParm + 9) = xDst;
162       ret = MFDRV_WriteRecord( devDst, mr, mr->rdSize * 2);
163     }  
164     else
165         ret = FALSE;
166     HeapFree( GetProcessHeap(), 0, mr);
167     return ret;
168 }
169
170
171 /***********************************************************************
172  *           MFDRV_StretchDIBits
173  */
174 INT MFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
175                          INT heightDst, INT xSrc, INT ySrc, INT widthSrc,
176                          INT heightSrc, const void *bits,
177                          const BITMAPINFO *info, UINT wUsage, DWORD dwRop )
178 {
179     DWORD len, infosize, imagesize;
180     METARECORD *mr;
181
182     infosize = DIB_BitmapInfoSize(info, wUsage);
183     imagesize = DIB_GetDIBImageBytes( info->bmiHeader.biWidth,
184                                       info->bmiHeader.biHeight,
185                                       info->bmiHeader.biBitCount );
186
187     len = sizeof(METARECORD) + 10 * sizeof(WORD) + infosize + imagesize;
188     mr = (METARECORD *)HeapAlloc( GetProcessHeap(), 0, len );
189     if(!mr) return 0;
190
191     mr->rdSize = len / 2;
192     mr->rdFunction = META_STRETCHDIB;
193     mr->rdParm[0] = LOWORD(dwRop);
194     mr->rdParm[1] = HIWORD(dwRop);
195     mr->rdParm[2] = wUsage;
196     mr->rdParm[3] = (INT16)heightSrc;
197     mr->rdParm[4] = (INT16)widthSrc;
198     mr->rdParm[5] = (INT16)ySrc;
199     mr->rdParm[6] = (INT16)xSrc;
200     mr->rdParm[7] = (INT16)heightDst;
201     mr->rdParm[8] = (INT16)widthDst;
202     mr->rdParm[9] = (INT16)yDst;
203     mr->rdParm[10] = (INT16)xDst;
204     memcpy(mr->rdParm + 11, info, infosize);
205     memcpy(mr->rdParm + 11 + infosize / 2, bits, imagesize);
206     MFDRV_WriteRecord( dev, mr, mr->rdSize * 2 );
207     HeapFree( GetProcessHeap(), 0, mr );
208     return heightSrc;
209 }
210
211         
212 /***********************************************************************
213  *           MFDRV_SetDIBitsToDeivce
214  */
215 INT MFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDst, INT yDst, DWORD cx,
216                              DWORD cy, INT xSrc, INT ySrc, UINT startscan,
217                              UINT lines, LPCVOID bits, const BITMAPINFO *info,
218                              UINT coloruse )
219
220 {
221     DWORD len, infosize, imagesize;
222     METARECORD *mr;
223
224     infosize = DIB_BitmapInfoSize(info, coloruse);
225     imagesize = DIB_GetDIBImageBytes( info->bmiHeader.biWidth,
226                                       info->bmiHeader.biHeight,
227                                       info->bmiHeader.biBitCount );
228
229     len = sizeof(METARECORD) + 8 * sizeof(WORD) + infosize + imagesize;
230     mr = (METARECORD *)HeapAlloc( GetProcessHeap(), 0, len );
231     if(!mr) return 0;
232
233     mr->rdSize = len / 2;
234     mr->rdFunction = META_SETDIBTODEV;
235     mr->rdParm[0] = coloruse;
236     mr->rdParm[1] = lines;
237     mr->rdParm[2] = startscan;
238     mr->rdParm[3] = (INT16)ySrc;
239     mr->rdParm[4] = (INT16)xSrc;
240     mr->rdParm[5] = (INT16)cy;
241     mr->rdParm[6] = (INT16)cx;
242     mr->rdParm[7] = (INT16)yDst;
243     mr->rdParm[8] = (INT16)xDst;
244     memcpy(mr->rdParm + 9, info, infosize);
245     memcpy(mr->rdParm + 9 + infosize / 2, bits, imagesize);
246     MFDRV_WriteRecord( dev, mr, mr->rdSize * 2 );
247     HeapFree( GetProcessHeap(), 0, mr );
248     return lines;
249 }
250
251