Copy msimg32
[reactos.git] / reactos / subsys / win32k / dib / dib1bpp.c
1 /*
2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id$ */
20 #include <w32k.h>
21
22 VOID
23 DIB_1BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
24 {
25 PBYTE addr = SurfObj->pvScan0 + y * SurfObj->lDelta + (x >> 3);
26
27 if (0 == (c & 0x01))
28 *addr &= ~MASK1BPP(x);
29 else
30 *addr |= MASK1BPP(x);
31 }
32
33 ULONG
34 DIB_1BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y)
35 {
36 PBYTE addr = SurfObj->pvScan0 + y * SurfObj->lDelta + (x >> 3);
37
38 return (*addr & MASK1BPP(x) ? 1 : 0);
39 }
40
41 VOID
42 DIB_1BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
43 {
44 while(x1 < x2) {
45 DIB_1BPP_PutPixel(SurfObj, x1, y, c);
46 x1++;
47 }
48 }
49
50 VOID
51 DIB_1BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
52 {
53 while(y1 < y2) {
54 DIB_1BPP_PutPixel(SurfObj, x, y1, c);
55 y1++;
56 }
57 }
58
59 static
60 void
61 DIB_1BPP_BitBltSrcCopy_From1BPP (
62 SURFOBJ* DestSurf, SURFOBJ* SourceSurf,
63 PRECTL DestRect, POINTL *SourcePoint )
64 {
65 // the 'window' in this sense is the x-position that corresponds
66 // to the left-edge of the 8-pixel byte we are currently working with.
67 // dwx is current x-window, dwx2 is the 'last' window we need to process
68 int dwx, dwx2; // destination window x-position
69 int swx; // source window y-position
70
71 // left and right edges of source and dest rectangles
72 int dl = DestRect->left; // dest left
73 int dr = DestRect->right-1; // dest right (inclusive)
74 int sl = SourcePoint->x; // source left
75 int sr = sl + dr - dl; // source right (inclusive)
76
77 // which direction are we going?
78 int xinc;
79 int yinc;
80 int ySrcDelta, yDstDelta;
81
82 // following 4 variables are used for the y-sweep
83 int dy; // dest y
84 int dy1; // dest y start
85 int dy2; // dest y end
86 int sy1; // src y start
87
88 int shift;
89 BYTE srcmask, dstmask;
90
91 // 'd' and 's' are the dest & src buffer pointers that I use on my x-sweep
92 // 'pd' and 'ps' are the dest & src buffer pointers used on the inner y-sweep
93 PBYTE d, pd; // dest ptrs
94 PBYTE s, ps; // src ptrs
95
96 shift = (dl-sl)&7;
97
98 if ( DestRect->top <= SourcePoint->y )
99 {
100 // moving up ( scan top -> bottom )
101 dy1 = DestRect->top;
102 dy2 = DestRect->bottom - 1;
103 sy1 = SourcePoint->y;
104 yinc = 1;
105 ySrcDelta = SourceSurf->lDelta;
106 yDstDelta = DestSurf->lDelta;
107 }
108 else
109 {
110 // moving down ( scan bottom -> top )
111 dy1 = DestRect->bottom - 1;
112 dy2 = DestRect->top;
113 sy1 = SourcePoint->y + dy1 - dy2;
114 yinc = -1;
115 ySrcDelta = -SourceSurf->lDelta;
116 yDstDelta = -DestSurf->lDelta;
117 }
118 if ( DestRect->left <= SourcePoint->x )
119 {
120 // moving left ( scan left->right )
121 dwx = dl&~7;
122 swx = (sl-(dl&7))&~7;
123 dwx2 = dr&~7;
124 xinc = 1;
125 }
126 else
127 {
128 // moving right ( scan right->left )
129 dwx = dr&~7;
130 swx = (sr-(dr&7))&~7; //(sr-7)&~7; // we need the left edge of this block... thus the -7
131 dwx2 = dl&~7;
132 xinc = -1;
133 }
134 d = &(((PBYTE)DestSurf->pvScan0)[dy1*DestSurf->lDelta + (dwx>>3)]);
135 s = &(((PBYTE)SourceSurf->pvScan0)[sy1*SourceSurf->lDelta + (swx>>3)]);
136 for ( ;; )
137 {
138 dy = dy1;
139 pd = d;
140 ps = s;
141 srcmask = 0xff;
142 int dx = dwx; /* dest x for this pass */
143 if ( dwx < dl )
144 {
145 int diff = dl-dwx;
146 srcmask &= (1<<(8-diff))-1;
147 dx = dl;
148 }
149 if ( dwx+7 > dr )
150 {
151 int diff = dr-dwx+1;
152 srcmask &= ~((1<<(8-diff))-1);
153 }
154 dstmask = ~srcmask;
155
156 // we unfortunately *must* have 5 different versions of the inner
157 // loop to be certain we don't try to read from memory that is not
158 // needed and may in fact be invalid
159 if ( !shift )
160 {
161 for ( ;; )
162 {
163 *pd = (BYTE)((*pd & dstmask) | (*ps & srcmask));
164
165 // this *must* be here, because we could be going up *or* down...
166 if ( dy == dy2 )
167 break;
168 dy += yinc;
169 pd += yDstDelta;
170 ps += ySrcDelta;
171 }
172 }
173 else if ( !(0xFF00 & (srcmask<<shift) ) ) // check if ps[0] not needed...
174 {
175 for ( ;; )
176 {
177 *pd = (BYTE)((*pd & dstmask)
178 | ( ( ps[1] >> shift ) & srcmask ));
179
180 // this *must* be here, because we could be going up *or* down...
181 if ( dy == dy2 )
182 break;
183 dy += yinc;
184 pd += yDstDelta;
185 ps += ySrcDelta;
186 }
187 }
188 else if ( !(0xFF & (srcmask<<shift) ) ) // check if ps[1] not needed...
189 {
190 for ( ;; )
191 {
192 *pd = (*pd & dstmask)
193 | ( ( ps[0] << ( 8 - shift ) ) & srcmask );
194
195 // this *must* be here, because we could be going up *or* down...
196 if ( dy == dy2 )
197 break;
198 dy += yinc;
199 pd += yDstDelta;
200 ps += ySrcDelta;
201 }
202 }
203 else // both ps[0] and ps[1] are needed
204 {
205 for ( ;; )
206 {
207 *pd = (*pd & dstmask)
208 | ( ( ( (ps[1])|(ps[0]<<8) ) >> shift ) & srcmask );
209
210 // this *must* be here, because we could be going up *or* down...
211 if ( dy == dy2 )
212 break;
213 dy += yinc;
214 pd += yDstDelta;
215 ps += ySrcDelta;
216 }
217 }
218
219 // this *must* be here, because we could be going right *or* left...
220 if ( dwx == dwx2 )
221 break;
222 d += xinc;
223 s += xinc;
224 dwx += xinc<<3;
225 swx += xinc<<3;
226 }
227 }
228
229 BOOLEAN
230 DIB_1BPP_BitBltSrcCopy(PBLTINFO BltInfo)
231 {
232 LONG i, j, sx, sy = BltInfo->SourcePoint.y;
233
234 switch ( BltInfo->SourceSurface->iBitmapFormat )
235 {
236 case BMF_1BPP:
237 DIB_1BPP_BitBltSrcCopy_From1BPP ( BltInfo->DestSurface, BltInfo->SourceSurface, &BltInfo->DestRect, &BltInfo->SourcePoint );
238 break;
239
240 case BMF_4BPP:
241 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
242 {
243 sx = BltInfo->SourcePoint.x;
244 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
245 {
246 if(XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_4BPP_GetPixel(BltInfo->SourceSurface, sx, sy)) == 0)
247 {
248 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, 0);
249 } else {
250 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, 1);
251 }
252 sx++;
253 }
254 sy++;
255 }
256 break;
257
258 case BMF_8BPP:
259 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
260 {
261 sx = BltInfo->SourcePoint.x;
262 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
263 {
264 if(XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_8BPP_GetPixel(BltInfo->SourceSurface, sx, sy)) == 0)
265 {
266 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, 0);
267 } else {
268 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, 1);
269 }
270 sx++;
271 }
272 sy++;
273 }
274 break;
275
276 case BMF_16BPP:
277 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
278 {
279 sx = BltInfo->SourcePoint.x;
280 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
281 {
282 if(XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_16BPP_GetPixel(BltInfo->SourceSurface, sx, sy)) == 0)
283 {
284 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, 0);
285 } else {
286 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, 1);
287 }
288 sx++;
289 }
290 sy++;
291 }
292 break;
293
294 case BMF_24BPP:
295 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
296 {
297 sx = BltInfo->SourcePoint.x;
298 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
299 {
300 if(XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_24BPP_GetPixel(BltInfo->SourceSurface, sx, sy)) == 0)
301 {
302 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, 0);
303 } else {
304 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, 1);
305 }
306 sx++;
307 }
308 sy++;
309 }
310 break;
311
312 case BMF_32BPP:
313 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
314 {
315 sx = BltInfo->SourcePoint.x;
316 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
317 {
318 if(XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_32BPP_GetPixel(BltInfo->SourceSurface, sx, sy)) == 0)
319 {
320 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, 0);
321 } else {
322 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, 1);
323 }
324 sx++;
325 }
326 sy++;
327 }
328 break;
329
330 default:
331 DbgPrint("DIB_1BPP_BitBlt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat));
332 return FALSE;
333 }
334
335 return TRUE;
336 }
337
338 BOOLEAN
339 DIB_1BPP_BitBlt(PBLTINFO BltInfo)
340 {
341 ULONG DestX, DestY;
342 ULONG SourceX, SourceY;
343 ULONG PatternY = 0;
344 ULONG Dest, Source = 0, Pattern = 0;
345 ULONG Index;
346 BOOLEAN UsesSource;
347 BOOLEAN UsesPattern;
348 PULONG DestBits;
349 ULONG RoundedRight;
350 /* BYTE NoBits;*/
351
352 UsesSource = ROP_USES_SOURCE(BltInfo->Rop4);
353 UsesPattern = ROP_USES_PATTERN(BltInfo->Rop4);
354
355 RoundedRight = BltInfo->DestRect.right -
356 ((BltInfo->DestRect.right - BltInfo->DestRect.left) & 31);
357 SourceY = BltInfo->SourcePoint.y;
358
359 if (UsesPattern)
360 {
361 if (BltInfo->PatternSurface)
362 {
363 PatternY = (BltInfo->DestRect.top + BltInfo->BrushOrigin.y) %
364 BltInfo->PatternSurface->sizlBitmap.cy;
365 }
366 else
367 {
368 /* FIXME: Shouldn't it be expanded? */
369 Pattern = BltInfo->Brush->iSolidColor;
370 }
371 }
372
373 for (DestY = BltInfo->DestRect.top; DestY < BltInfo->DestRect.bottom; DestY++)
374 {
375 DestX = BltInfo->DestRect.left;
376 SourceX = BltInfo->SourcePoint.x;
377 DestBits = (PULONG)(
378 BltInfo->DestSurface->pvScan0 +
379 (BltInfo->DestRect.left >> 3) +
380 DestY * BltInfo->DestSurface->lDelta);
381
382 if (DestX & 31)
383 {
384 #if 0
385 /* FIXME: This case is completely untested!!! */
386
387 Dest = *((PBYTE)DestBits);
388 NoBits = 31 - (DestX & 31);
389
390 if (UsesSource)
391 {
392 Source = 0;
393 /* FIXME: This is incorrect! */
394 for (Index = 31 - NoBits; Index >= 0; Index++)
395 Source |= (DIB_GetSource(SourceSurf, SourceX + Index, SourceY, ColorTranslation) << (31 - Index));
396 }
397
398 if (BltInfo->PatternSurface)
399 {
400 Pattern = 0;
401 for (k = 31 - NoBits; k >= 0; k++)
402 Pattern |= (DIB_GetSource(PatternObj, (X + BrushOrigin.x + k) % PatternWidth, PatternY, BltInfo->XlatePatternToDest) << (31 - k));
403 }
404
405 Dest = DIB_DoRop(Rop4, Dest, Source, Pattern);
406 Dest &= ~((1 << (31 - NoBits)) - 1);
407 Dest |= *((PBYTE)DestBits) & ((1 << (31 - NoBits)) - 1);
408
409 *DestBits = Dest;
410
411 DestX += NoBits;
412 SourceX += NoBits;
413 #endif
414 }
415
416 for (; DestX < RoundedRight; DestX += 32, DestBits++, SourceX++)
417 {
418 Dest = *DestBits;
419
420 if (UsesSource)
421 {
422 Source = 0;
423 for (Index = 0; Index < 8; Index++)
424 {
425 Source |= DIB_GetSource(BltInfo->SourceSurface, SourceX + Index, SourceY, BltInfo->XlateSourceToDest) << (7 - Index);
426 Source |= DIB_GetSource(BltInfo->SourceSurface, SourceX + Index + 8, SourceY, BltInfo->XlateSourceToDest) << (8 + (7 - Index));
427 Source |= DIB_GetSource(BltInfo->SourceSurface, SourceX + Index + 16, SourceY, BltInfo->XlateSourceToDest) << (16 + (7 - Index));
428 Source |= DIB_GetSource(BltInfo->SourceSurface, SourceX + Index + 24, SourceY, BltInfo->XlateSourceToDest) << (24 + (7 - Index));
429 }
430 }
431
432 if (BltInfo->PatternSurface)
433 {
434 Pattern = 0;
435 for (Index = 0; Index < 8; Index++)
436 {
437 Pattern |= DIB_GetSource(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + Index) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY, BltInfo->XlatePatternToDest) << (7 - Index);
438 Pattern |= DIB_GetSource(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + Index + 8) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY, BltInfo->XlatePatternToDest) << (8 + (7 - Index));
439 Pattern |= DIB_GetSource(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + Index + 16) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY, BltInfo->XlatePatternToDest) << (16 + (7 - Index));
440 Pattern |= DIB_GetSource(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + Index + 24) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY, BltInfo->XlatePatternToDest) << (24 + (7 - Index));
441 }
442 }
443
444 *DestBits = DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern);
445 }
446
447 if (DestX < BltInfo->DestRect.right)
448 {
449 // Dest = *DestBits;
450 for (; DestX < BltInfo->DestRect.right; DestX++, SourceX++)
451 {
452 // Dest = *DestBits;
453 Dest = DIB_1BPP_GetPixel(BltInfo->DestSurface, DestX, DestY);
454
455 if (UsesSource)
456 {
457 Source = DIB_GetSource(BltInfo->SourceSurface, SourceX, SourceY, BltInfo->XlateSourceToDest);
458 }
459
460 if (BltInfo->PatternSurface)
461 {
462 Pattern = DIB_GetSource(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY, BltInfo->XlatePatternToDest);
463 }
464
465 DIB_1BPP_PutPixel(BltInfo->DestSurface, DestX, DestY, DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern) & 0xF);
466 // Dest >>= 1;
467 }
468 }
469
470 SourceY++;
471 if (BltInfo->PatternSurface)
472 {
473 PatternY++;
474 PatternY %= BltInfo->PatternSurface->sizlBitmap.cy;
475 }
476 }
477
478 return TRUE;
479 }
480
481 BOOLEAN
482 DIB_1BPP_StretchBlt (
483 SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
484 RECTL* DestRect, RECTL *SourceRect,
485 POINTL* MaskOrigin, POINTL BrushOrigin,
486 CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
487 ULONG Mode)
488 {
489 DbgPrint("DIB_1BPP_StretchBlt: Source BPP: %u\n", BitsPerFormat(SourceSurf->iBitmapFormat));
490 return FALSE;
491 }
492
493 BOOLEAN
494 DIB_1BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
495 RECTL* DestRect, POINTL *SourcePoint,
496 XLATEOBJ *ColorTranslation, ULONG iTransColor)
497 {
498 return FALSE;
499 }
500
501 /* EOF */