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