blob: 69d1ad69188e39c022c15bfa1d9aa1ca6f12ff8e [file] [log] [blame]
Alexandre Julliard75d86e11996-11-17 18:59:11 +00001/*
2 * GDI bit-blit operations
3 *
4 * Copyright 1993, 1994 Alexandre Julliard
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00005 *
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
Alexandre Julliard75d86e11996-11-17 18:59:11 +000019 */
20
Alexandre Julliard2239abb2000-11-05 02:05:07 +000021#include "gdi.h"
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000022#include "wine/debug.h"
Alexandre Julliard75d86e11996-11-17 18:59:11 +000023
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000024WINE_DEFAULT_DEBUG_CHANNEL(bitblt);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000025
Alexandre Julliard75d86e11996-11-17 18:59:11 +000026
27/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +000028 * PatBlt (GDI32.@)
Alexandre Julliard75d86e11996-11-17 18:59:11 +000029 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000030BOOL WINAPI PatBlt( HDC hdc, INT left, INT top,
31 INT width, INT height, DWORD rop)
Alexandre Julliard75d86e11996-11-17 18:59:11 +000032{
Alexandre Julliard0baa4e02000-08-22 20:01:47 +000033 DC * dc = DC_GetDCUpdate( hdc );
Alexandre Julliard2a2321b2000-08-19 21:38:55 +000034 BOOL bRet = FALSE;
Alexandre Julliard75d86e11996-11-17 18:59:11 +000035
Alexandre Julliard2a2321b2000-08-19 21:38:55 +000036 if (!dc) return FALSE;
37
38 if (dc->funcs->pPatBlt)
39 {
Alexandre Julliard547cdc22002-11-22 22:16:53 +000040 TRACE("%p %d,%d %dx%d %06lx\n", hdc, left, top, width, height, rop );
Alexandre Julliarde21c15e2002-03-28 22:22:05 +000041 bRet = dc->funcs->pPatBlt( dc->physDev, left, top, width, height, rop );
Alexandre Julliard2a2321b2000-08-19 21:38:55 +000042 }
43 GDI_ReleaseObj( hdc );
44 return bRet;
Alexandre Julliard75d86e11996-11-17 18:59:11 +000045}
46
47
48/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +000049 * BitBlt (GDI32.@)
Alexandre Julliard75d86e11996-11-17 18:59:11 +000050 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000051BOOL WINAPI BitBlt( HDC hdcDst, INT xDst, INT yDst, INT width,
Alexandre Julliard2a2321b2000-08-19 21:38:55 +000052 INT height, HDC hdcSrc, INT xSrc, INT ySrc, DWORD rop )
Alexandre Julliard75d86e11996-11-17 18:59:11 +000053{
Alexandre Julliard2a2321b2000-08-19 21:38:55 +000054 BOOL ret = FALSE;
Alexandre Julliard75d86e11996-11-17 18:59:11 +000055 DC *dcDst, *dcSrc;
56
Alexandre Julliard2a2321b2000-08-19 21:38:55 +000057 if ((dcSrc = DC_GetDCUpdate( hdcSrc ))) GDI_ReleaseObj( hdcSrc );
58 /* FIXME: there is a race condition here */
59 if ((dcDst = DC_GetDCUpdate( hdcDst )))
60 {
61 dcSrc = DC_GetDCPtr( hdcSrc );
Alexandre Julliard547cdc22002-11-22 22:16:53 +000062 TRACE("hdcSrc=%p %d,%d %d bpp->hdcDest=%p %d,%d %dx%dx%d rop=%06lx\n",
Alexandre Julliard2239abb2000-11-05 02:05:07 +000063 hdcSrc, xSrc, ySrc, dcSrc ? dcSrc->bitsPerPixel : 0,
64 hdcDst, xDst, yDst, width, height, dcDst->bitsPerPixel, rop);
Alexandre Julliard2a2321b2000-08-19 21:38:55 +000065 if (dcDst->funcs->pBitBlt)
Alexandre Julliarde21c15e2002-03-28 22:22:05 +000066 ret = dcDst->funcs->pBitBlt( dcDst->physDev, xDst, yDst, width, height,
Alexandre Julliardc71417c2002-04-02 03:00:00 +000067 dcSrc ? dcSrc->physDev : NULL, xSrc, ySrc, rop );
Alexandre Julliard2a2321b2000-08-19 21:38:55 +000068 if (dcSrc) GDI_ReleaseObj( hdcSrc );
69 GDI_ReleaseObj( hdcDst );
70 }
71 return ret;
Alexandre Julliard75d86e11996-11-17 18:59:11 +000072}
73
74
75/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +000076 * StretchBlt (GDI32.@)
Alexandre Julliard75d86e11996-11-17 18:59:11 +000077 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000078BOOL WINAPI StretchBlt( HDC hdcDst, INT xDst, INT yDst,
79 INT widthDst, INT heightDst,
80 HDC hdcSrc, INT xSrc, INT ySrc,
Vincent Béron9a624912002-05-31 23:06:46 +000081 INT widthSrc, INT heightSrc,
Alexandre Julliard2a2321b2000-08-19 21:38:55 +000082 DWORD rop )
Alexandre Julliard75d86e11996-11-17 18:59:11 +000083{
Alexandre Julliard2a2321b2000-08-19 21:38:55 +000084 BOOL ret = FALSE;
Alexandre Julliard75d86e11996-11-17 18:59:11 +000085 DC *dcDst, *dcSrc;
86
Alexandre Julliard2a2321b2000-08-19 21:38:55 +000087 if ((dcSrc = DC_GetDCUpdate( hdcSrc ))) GDI_ReleaseObj( hdcSrc );
88 /* FIXME: there is a race condition here */
89 if ((dcDst = DC_GetDCUpdate( hdcDst )))
90 {
91 dcSrc = DC_GetDCPtr( hdcSrc );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +000092
Alexandre Julliard547cdc22002-11-22 22:16:53 +000093 TRACE("%p %d,%d %dx%dx%d -> %p %d,%d %dx%dx%d rop=%06lx\n",
Alexandre Julliard2a2321b2000-08-19 21:38:55 +000094 hdcSrc, xSrc, ySrc, widthSrc, heightSrc,
Alexandre Julliard2239abb2000-11-05 02:05:07 +000095 dcSrc ? dcSrc->bitsPerPixel : 0, hdcDst, xDst, yDst,
96 widthDst, heightDst, dcDst->bitsPerPixel, rop );
Alexandre Julliard2a2321b2000-08-19 21:38:55 +000097
98 if (dcSrc) {
99 if (dcDst->funcs->pStretchBlt)
Alexandre Julliarde21c15e2002-03-28 22:22:05 +0000100 ret = dcDst->funcs->pStretchBlt( dcDst->physDev, xDst, yDst, widthDst, heightDst,
101 dcSrc->physDev, xSrc, ySrc, widthSrc, heightSrc,
102 rop );
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000103 GDI_ReleaseObj( hdcSrc );
104 }
105 GDI_ReleaseObj( hdcDst );
106 }
107 return ret;
Alexandre Julliard75d86e11996-11-17 18:59:11 +0000108}
109
Jaekil Leea6e95a82003-05-16 20:11:36 +0000110static inline BYTE SwapROP3_SrcDst(BYTE bRop3)
111{
112 return (bRop3 & 0x99) | ((bRop3 & 0x22) << 1) | ((bRop3 & 0x44) >> 1);
113}
114
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 */
Alexandre Julliard75d86e11996-11-17 18:59:11 +0000119
120/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000121 * MaskBlt [GDI32.@]
Paul Quinn1beaae51998-12-15 15:38:36 +0000122 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000123BOOL WINAPI MaskBlt(HDC hdcDest, INT nXDest, INT nYDest,
Jaekil Leea6e95a82003-05-16 20:11:36 +0000124 INT nWidth, INT nHeight, HDC hdcSrc,
Alexandre Julliarda3960291999-02-26 11:11:13 +0000125 INT nXSrc, INT nYSrc, HBITMAP hbmMask,
126 INT xMask, INT yMask, DWORD dwRop)
Paul Quinn1beaae51998-12-15 15:38:36 +0000127{
Jaekil Leea6e95a82003-05-16 20:11:36 +0000128 HBITMAP hOldMaskBitmap, hBitmap2, hOldBitmap2, hBitmap3, hOldBitmap3;
129 HDC hDCMask, hDC1, hDC2;
130 static const DWORD ROP3Table[256] =
131 {
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,
260 };
261
262 if (!hbmMask)
263 return BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, FRGND_ROP3(dwRop));
264
265 /* 1. make mask bitmap's dc */
266 hDCMask = CreateCompatibleDC(hdcDest);
267 hOldMaskBitmap = (HBITMAP)SelectObject(hDCMask, hbmMask);
268
269 /* 2. make masked Background bitmap */
270
271 /* 2.1 make bitmap */
272 hDC1 = CreateCompatibleDC(hdcDest);
273 hBitmap2 = CreateCompatibleBitmap(hdcDest, nWidth, nHeight);
274 hOldBitmap2 = (HBITMAP)SelectObject(hDC1, hBitmap2);
275
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);
280
281 /* 3. make masked Foreground bitmap */
282
283 /* 3.1 make bitmap */
284 hDC2 = CreateCompatibleDC(hdcDest);
285 hBitmap3 = CreateCompatibleBitmap(hdcDest, nWidth, nHeight);
286 hOldBitmap3 = (HBITMAP)SelectObject(hDC2, hBitmap3);
287
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);
292
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);
296
297 /* 5. restore all object */
298 SelectObject(hDCMask, hOldMaskBitmap);
299 SelectObject(hDC1, hOldBitmap2);
300 SelectObject(hDC2, hOldBitmap3);
301
302 /* 6. delete all temp object */
303 DeleteObject(hBitmap2);
304 DeleteObject(hBitmap3);
305
306 DeleteDC(hDC1);
307 DeleteDC(hDC2);
308 DeleteDC(hDCMask);
309
310 return TRUE;
Paul Quinn1beaae51998-12-15 15:38:36 +0000311}
Vincent Béron9a624912002-05-31 23:06:46 +0000312
Paul Quinn1beaae51998-12-15 15:38:36 +0000313/*********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000314 * PlgBlt [GDI32.@]
Paul Quinn1beaae51998-12-15 15:38:36 +0000315 *
316 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000317BOOL 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)
Paul Quinn1beaae51998-12-15 15:38:36 +0000320{
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000321 FIXME("PlgBlt, stub\n");
Paul Quinn1beaae51998-12-15 15:38:36 +0000322 return 1;
323}