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