Release 20031118.
[wine/multimedia.git] / graphics / bitblt.c
blob69d1ad69188e39c022c15bfa1d9aa1ca6f12ff8e
1 /*
2 * GDI bit-blit operations
4 * Copyright 1993, 1994 Alexandre Julliard
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.
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.
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
21 #include "gdi.h"
22 #include "wine/debug.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(bitblt);
27 /***********************************************************************
28 * PatBlt (GDI32.@)
30 BOOL WINAPI PatBlt( HDC hdc, INT left, INT top,
31 INT width, INT height, DWORD rop)
33 DC * dc = DC_GetDCUpdate( hdc );
34 BOOL bRet = FALSE;
36 if (!dc) return FALSE;
38 if (dc->funcs->pPatBlt)
40 TRACE("%p %d,%d %dx%d %06lx\n", hdc, left, top, width, height, rop );
41 bRet = dc->funcs->pPatBlt( dc->physDev, left, top, width, height, rop );
43 GDI_ReleaseObj( hdc );
44 return bRet;
48 /***********************************************************************
49 * BitBlt (GDI32.@)
51 BOOL WINAPI BitBlt( HDC hdcDst, INT xDst, INT yDst, INT width,
52 INT height, HDC hdcSrc, INT xSrc, INT ySrc, DWORD rop )
54 BOOL ret = FALSE;
55 DC *dcDst, *dcSrc;
57 if ((dcSrc = DC_GetDCUpdate( hdcSrc ))) GDI_ReleaseObj( hdcSrc );
58 /* FIXME: there is a race condition here */
59 if ((dcDst = DC_GetDCUpdate( hdcDst )))
61 dcSrc = DC_GetDCPtr( hdcSrc );
62 TRACE("hdcSrc=%p %d,%d %d bpp->hdcDest=%p %d,%d %dx%dx%d rop=%06lx\n",
63 hdcSrc, xSrc, ySrc, dcSrc ? dcSrc->bitsPerPixel : 0,
64 hdcDst, xDst, yDst, width, height, dcDst->bitsPerPixel, rop);
65 if (dcDst->funcs->pBitBlt)
66 ret = dcDst->funcs->pBitBlt( dcDst->physDev, xDst, yDst, width, height,
67 dcSrc ? dcSrc->physDev : NULL, xSrc, ySrc, rop );
68 if (dcSrc) GDI_ReleaseObj( hdcSrc );
69 GDI_ReleaseObj( hdcDst );
71 return ret;
75 /***********************************************************************
76 * StretchBlt (GDI32.@)
78 BOOL WINAPI StretchBlt( HDC hdcDst, INT xDst, INT yDst,
79 INT widthDst, INT heightDst,
80 HDC hdcSrc, INT xSrc, INT ySrc,
81 INT widthSrc, INT heightSrc,
82 DWORD rop )
84 BOOL ret = FALSE;
85 DC *dcDst, *dcSrc;
87 if ((dcSrc = DC_GetDCUpdate( hdcSrc ))) GDI_ReleaseObj( hdcSrc );
88 /* FIXME: there is a race condition here */
89 if ((dcDst = DC_GetDCUpdate( hdcDst )))
91 dcSrc = DC_GetDCPtr( hdcSrc );
93 TRACE("%p %d,%d %dx%dx%d -> %p %d,%d %dx%dx%d rop=%06lx\n",
94 hdcSrc, xSrc, ySrc, widthSrc, heightSrc,
95 dcSrc ? dcSrc->bitsPerPixel : 0, hdcDst, xDst, yDst,
96 widthDst, heightDst, dcDst->bitsPerPixel, rop );
98 if (dcSrc) {
99 if (dcDst->funcs->pStretchBlt)
100 ret = dcDst->funcs->pStretchBlt( dcDst->physDev, xDst, yDst, widthDst, heightDst,
101 dcSrc->physDev, xSrc, ySrc, widthSrc, heightSrc,
102 rop );
103 GDI_ReleaseObj( hdcSrc );
105 GDI_ReleaseObj( hdcDst );
107 return ret;
110 static inline BYTE SwapROP3_SrcDst(BYTE bRop3)
112 return (bRop3 & 0x99) | ((bRop3 & 0x22) << 1) | ((bRop3 & 0x44) >> 1);
115 #define FRGND_ROP3(ROP4) ((ROP4) & 0x00FFFFFF)
116 #define BKGND_ROP3(ROP4) (ROP3Table[(SwapROP3_SrcDst((ROP4)>>24)) & 0xFF])
117 #define DSTCOPY 0x00AA0029
118 #define DSTERASE 0x00220326 /* dest = dest & (~src) : DSna */
120 /***********************************************************************
121 * MaskBlt [GDI32.@]
123 BOOL WINAPI MaskBlt(HDC hdcDest, INT nXDest, INT nYDest,
124 INT nWidth, INT nHeight, HDC hdcSrc,
125 INT nXSrc, INT nYSrc, HBITMAP hbmMask,
126 INT xMask, INT yMask, DWORD dwRop)
128 HBITMAP hOldMaskBitmap, hBitmap2, hOldBitmap2, hBitmap3, hOldBitmap3;
129 HDC hDCMask, hDC1, hDC2;
130 static const DWORD ROP3Table[256] =
132 0x00000042, 0x00010289,
133 0x00020C89, 0x000300AA,
134 0x00040C88, 0x000500A9,
135 0x00060865, 0x000702C5,
136 0x00080F08, 0x00090245,
137 0x000A0329, 0x000B0B2A,
138 0x000C0324, 0x000D0B25,
139 0x000E08A5, 0x000F0001,
140 0x00100C85, 0x001100A6,
141 0x00120868, 0x001302C8,
142 0x00140869, 0x001502C9,
143 0x00165CCA, 0x00171D54,
144 0x00180D59, 0x00191CC8,
145 0x001A06C5, 0x001B0768,
146 0x001C06CA, 0x001D0766,
147 0x001E01A5, 0x001F0385,
148 0x00200F09, 0x00210248,
149 0x00220326, 0x00230B24,
150 0x00240D55, 0x00251CC5,
151 0x002606C8, 0x00271868,
152 0x00280369, 0x002916CA,
153 0x002A0CC9, 0x002B1D58,
154 0x002C0784, 0x002D060A,
155 0x002E064A, 0x002F0E2A,
156 0x0030032A, 0x00310B28,
157 0x00320688, 0x00330008,
158 0x003406C4, 0x00351864,
159 0x003601A8, 0x00370388,
160 0x0038078A, 0x00390604,
161 0x003A0644, 0x003B0E24,
162 0x003C004A, 0x003D18A4,
163 0x003E1B24, 0x003F00EA,
164 0x00400F0A, 0x00410249,
165 0x00420D5D, 0x00431CC4,
166 0x00440328, 0x00450B29,
167 0x004606C6, 0x0047076A,
168 0x00480368, 0x004916C5,
169 0x004A0789, 0x004B0605,
170 0x004C0CC8, 0x004D1954,
171 0x004E0645, 0x004F0E25,
172 0x00500325, 0x00510B26,
173 0x005206C9, 0x00530764,
174 0x005408A9, 0x00550009,
175 0x005601A9, 0x00570389,
176 0x00580785, 0x00590609,
177 0x005A0049, 0x005B18A9,
178 0x005C0649, 0x005D0E29,
179 0x005E1B29, 0x005F00E9,
180 0x00600365, 0x006116C6,
181 0x00620786, 0x00630608,
182 0x00640788, 0x00650606,
183 0x00660046, 0x006718A8,
184 0x006858A6, 0x00690145,
185 0x006A01E9, 0x006B178A,
186 0x006C01E8, 0x006D1785,
187 0x006E1E28, 0x006F0C65,
188 0x00700CC5, 0x00711D5C,
189 0x00720648, 0x00730E28,
190 0x00740646, 0x00750E26,
191 0x00761B28, 0x007700E6,
192 0x007801E5, 0x00791786,
193 0x007A1E29, 0x007B0C68,
194 0x007C1E24, 0x007D0C69,
195 0x007E0955, 0x007F03C9,
196 0x008003E9, 0x00810975,
197 0x00820C49, 0x00831E04,
198 0x00840C48, 0x00851E05,
199 0x008617A6, 0x008701C5,
200 0x008800C6, 0x00891B08,
201 0x008A0E06, 0x008B0666,
202 0x008C0E08, 0x008D0668,
203 0x008E1D7C, 0x008F0CE5,
204 0x00900C45, 0x00911E08,
205 0x009217A9, 0x009301C4,
206 0x009417AA, 0x009501C9,
207 0x00960169, 0x0097588A,
208 0x00981888, 0x00990066,
209 0x009A0709, 0x009B07A8,
210 0x009C0704, 0x009D07A6,
211 0x009E16E6, 0x009F0345,
212 0x00A000C9, 0x00A11B05,
213 0x00A20E09, 0x00A30669,
214 0x00A41885, 0x00A50065,
215 0x00A60706, 0x00A707A5,
216 0x00A803A9, 0x00A90189,
217 0x00AA0029, 0x00AB0889,
218 0x00AC0744, 0x00AD06E9,
219 0x00AE0B06, 0x00AF0229,
220 0x00B00E05, 0x00B10665,
221 0x00B21974, 0x00B30CE8,
222 0x00B4070A, 0x00B507A9,
223 0x00B616E9, 0x00B70348,
224 0x00B8074A, 0x00B906E6,
225 0x00BA0B09, 0x00BB0226,
226 0x00BC1CE4, 0x00BD0D7D,
227 0x00BE0269, 0x00BF08C9,
228 0x00C000CA, 0x00C11B04,
229 0x00C21884, 0x00C3006A,
230 0x00C40E04, 0x00C50664,
231 0x00C60708, 0x00C707AA,
232 0x00C803A8, 0x00C90184,
233 0x00CA0749, 0x00CB06E4,
234 0x00CC0020, 0x00CD0888,
235 0x00CE0B08, 0x00CF0224,
236 0x00D00E0A, 0x00D1066A,
237 0x00D20705, 0x00D307A4,
238 0x00D41D78, 0x00D50CE9,
239 0x00D616EA, 0x00D70349,
240 0x00D80745, 0x00D906E8,
241 0x00DA1CE9, 0x00DB0D75,
242 0x00DC0B04, 0x00DD0228,
243 0x00DE0268, 0x00DF08C8,
244 0x00E003A5, 0x00E10185,
245 0x00E20746, 0x00E306EA,
246 0x00E40748, 0x00E506E5,
247 0x00E61CE8, 0x00E70D79,
248 0x00E81D74, 0x00E95CE6,
249 0x00EA02E9, 0x00EB0849,
250 0x00EC02E8, 0x00ED0848,
251 0x00EE0086, 0x00EF0A08,
252 0x00F00021, 0x00F10885,
253 0x00F20B05, 0x00F3022A,
254 0x00F40B0A, 0x00F50225,
255 0x00F60265, 0x00F708C5,
256 0x00F802E5, 0x00F90845,
257 0x00FA0089, 0x00FB0A09,
258 0x00FC008A, 0x00FD0A0A,
259 0x00FE02A9, 0x00FF0062,
262 if (!hbmMask)
263 return BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, FRGND_ROP3(dwRop));
265 /* 1. make mask bitmap's dc */
266 hDCMask = CreateCompatibleDC(hdcDest);
267 hOldMaskBitmap = (HBITMAP)SelectObject(hDCMask, hbmMask);
269 /* 2. make masked Background bitmap */
271 /* 2.1 make bitmap */
272 hDC1 = CreateCompatibleDC(hdcDest);
273 hBitmap2 = CreateCompatibleBitmap(hdcDest, nWidth, nHeight);
274 hOldBitmap2 = (HBITMAP)SelectObject(hDC1, hBitmap2);
276 /* 2.2 draw dest bitmap and mask */
277 BitBlt(hDC1, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, SRCCOPY);
278 BitBlt(hDC1, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, BKGND_ROP3(dwRop));
279 BitBlt(hDC1, 0, 0, nWidth, nHeight, hDCMask, xMask, yMask, DSTERASE);
281 /* 3. make masked Foreground bitmap */
283 /* 3.1 make bitmap */
284 hDC2 = CreateCompatibleDC(hdcDest);
285 hBitmap3 = CreateCompatibleBitmap(hdcDest, nWidth, nHeight);
286 hOldBitmap3 = (HBITMAP)SelectObject(hDC2, hBitmap3);
288 /* 3.2 draw src bitmap and mask */
289 BitBlt(hDC2, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, SRCCOPY);
290 BitBlt(hDC2, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, FRGND_ROP3(dwRop));
291 BitBlt(hDC2, 0, 0, nWidth, nHeight, hDCMask, xMask, yMask, SRCAND);
293 /* 4. combine two bitmap and copy it to hdcDest */
294 BitBlt(hDC1, 0, 0, nWidth, nHeight, hDC2, 0, 0, SRCPAINT);
295 BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hDC1, 0, 0, SRCCOPY);
297 /* 5. restore all object */
298 SelectObject(hDCMask, hOldMaskBitmap);
299 SelectObject(hDC1, hOldBitmap2);
300 SelectObject(hDC2, hOldBitmap3);
302 /* 6. delete all temp object */
303 DeleteObject(hBitmap2);
304 DeleteObject(hBitmap3);
306 DeleteDC(hDC1);
307 DeleteDC(hDC2);
308 DeleteDC(hDCMask);
310 return TRUE;
313 /*********************************************************************
314 * PlgBlt [GDI32.@]
317 BOOL WINAPI PlgBlt( HDC hdcDest, const POINT *lpPoint,
318 HDC hdcSrc, INT nXDest, INT nYDest, INT nWidth,
319 INT nHeight, HBITMAP hbmMask, INT xMask, INT yMask)
321 FIXME("PlgBlt, stub\n");
322 return 1;