[WINSOCK]
[reactos.git] / reactos / subsystems / win32 / win32k / dib / dib1bpp.c
1 /*
2 * PROJECT: Win32 subsystem
3 * LICENSE: See COPYING in the top level directory
4 * FILE: subsystems/win32/win32k/dib/dib1bpp.c
5 * PURPOSE: Device Independant Bitmap functions, 1bpp
6 * PROGRAMMERS: Jason Filby
7 */
8
9 #include <win32k.h>
10
11 #define NDEBUG
12 #include <debug.h>
13
14 VOID
15 DIB_1BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
16 {
17 PBYTE addr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + (x >> 3);
18
19 if (0 == (c & 0x01))
20 *addr &= ~MASK1BPP(x);
21 else
22 *addr |= MASK1BPP(x);
23 }
24
25 ULONG
26 DIB_1BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y)
27 {
28 PBYTE addr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + (x >> 3);
29
30 return (*addr & MASK1BPP(x) ? 1 : 0);
31 }
32
33 VOID
34 DIB_1BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
35 {
36 while(x1 < x2)
37 {
38 DIB_1BPP_PutPixel(SurfObj, x1, y, c);
39 x1++;
40 }
41 }
42
43 VOID
44 DIB_1BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
45 {
46 while(y1 < y2)
47 {
48 DIB_1BPP_PutPixel(SurfObj, x, y1, c);
49 y1++;
50 }
51 }
52
53 static
54 void
55 DIB_1BPP_BitBltSrcCopy_From1BPP (
56 SURFOBJ* DestSurf,
57 SURFOBJ* SourceSurf,
58 XLATEOBJ* pxlo,
59 PRECTL DestRect,
60 POINTL *SourcePoint )
61 {
62 // the 'window' in this sense is the x-position that corresponds
63 // to the left-edge of the 8-pixel byte we are currently working with.
64 // dwx is current x-window, dwx2 is the 'last' window we need to process
65 int dwx, dwx2; // destination window x-position
66 int swx; // source window y-position
67
68 // left and right edges of source and dest rectangles
69 int dl = DestRect->left; // dest left
70 int dr = DestRect->right-1; // dest right (inclusive)
71 int sl = SourcePoint->x; // source left
72 int sr = sl + dr - dl; // source right (inclusive)
73
74 // which direction are we going?
75 int xinc;
76 int yinc;
77 int ySrcDelta, yDstDelta;
78
79 // following 4 variables are used for the y-sweep
80 int dy; // dest y
81 int dy1; // dest y start
82 int dy2; // dest y end
83 int sy1; // src y start
84
85 int dx;
86 int shift;
87 BYTE srcmask, dstmask, xormask;
88
89 // 'd' and 's' are the dest & src buffer pointers that I use on my x-sweep
90 // 'pd' and 'ps' are the dest & src buffer pointers used on the inner y-sweep
91 PBYTE d, pd; // dest ptrs
92 PBYTE s, ps; // src ptrs
93
94 shift = (dl-sl)&7;
95
96 xormask = 0xFF * XLATEOBJ_iXlate(pxlo, 0);
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 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[0]^xormask) & 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]^xormask) >> 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]^xormask) << ( 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]^xormask))|((ps[0]^xormask)<<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 ULONG Color;
233 LONG i, j, sx, sy = BltInfo->SourcePoint.y;
234
235 switch ( BltInfo->SourceSurface->iBitmapFormat )
236 {
237 case BMF_1BPP:
238 DIB_1BPP_BitBltSrcCopy_From1BPP ( BltInfo->DestSurface, BltInfo->SourceSurface, BltInfo->XlateSourceToDest, &BltInfo->DestRect, &BltInfo->SourcePoint );
239 break;
240
241 case BMF_4BPP:
242 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
243 {
244 sx = BltInfo->SourcePoint.x;
245 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
246 {
247 Color = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_4BPP_GetPixel(BltInfo->SourceSurface, sx, sy));
248 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, Color);
249 sx++;
250 }
251 sy++;
252 }
253 break;
254
255 case BMF_8BPP:
256 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
257 {
258 sx = BltInfo->SourcePoint.x;
259 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
260 {
261 Color = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_8BPP_GetPixel(BltInfo->SourceSurface, sx, sy));
262 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, Color);
263 sx++;
264 }
265 sy++;
266 }
267 break;
268
269 case BMF_16BPP:
270 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
271 {
272 sx = BltInfo->SourcePoint.x;
273 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
274 {
275 Color = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_16BPP_GetPixel(BltInfo->SourceSurface, sx, sy));
276 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, Color);
277 sx++;
278 }
279 sy++;
280 }
281 break;
282
283 case BMF_24BPP:
284 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
285 {
286 sx = BltInfo->SourcePoint.x;
287 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
288 {
289 Color = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_24BPP_GetPixel(BltInfo->SourceSurface, sx, sy));
290 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, Color);
291 sx++;
292 }
293 sy++;
294 }
295 break;
296
297 case BMF_32BPP:
298 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
299 {
300 sx = BltInfo->SourcePoint.x;
301 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
302 {
303 Color = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_32BPP_GetPixel(BltInfo->SourceSurface, sx, sy));
304 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, Color);
305 sx++;
306 }
307 sy++;
308 }
309 break;
310
311 default:
312 DbgPrint("DIB_1BPP_BitBlt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat));
313 return FALSE;
314 }
315
316 return TRUE;
317 }
318
319 BOOLEAN
320 DIB_1BPP_BitBlt(PBLTINFO BltInfo)
321 {
322 ULONG DestX, DestY;
323 ULONG SourceX, SourceY;
324 ULONG PatternY = 0;
325 ULONG Dest, Source = 0, Pattern = 0;
326 ULONG Index;
327 BOOLEAN UsesSource;
328 BOOLEAN UsesPattern;
329 PULONG DestBits;
330 ULONG RoundedRight;
331
332 UsesSource = ROP4_USES_SOURCE(BltInfo->Rop4);
333 UsesPattern = ROP4_USES_PATTERN(BltInfo->Rop4);
334
335 RoundedRight = BltInfo->DestRect.right -
336 ((BltInfo->DestRect.right - BltInfo->DestRect.left) & 31);
337 SourceY = BltInfo->SourcePoint.y;
338
339 if (UsesPattern)
340 {
341 if (BltInfo->PatternSurface)
342 {
343 PatternY = (BltInfo->DestRect.top + BltInfo->BrushOrigin.y) %
344 BltInfo->PatternSurface->sizlBitmap.cy;
345 }
346 else
347 {
348 /* FIXME: Shouldn't it be expanded? */
349 if (BltInfo->Brush)
350 Pattern = BltInfo->Brush->iSolidColor;
351 }
352 }
353
354 for (DestY = BltInfo->DestRect.top; DestY < BltInfo->DestRect.bottom; DestY++)
355 {
356 DestX = BltInfo->DestRect.left;
357 SourceX = BltInfo->SourcePoint.x;
358 DestBits = (PULONG)(
359 (PBYTE)BltInfo->DestSurface->pvScan0 +
360 (BltInfo->DestRect.left >> 3) +
361 DestY * BltInfo->DestSurface->lDelta);
362
363 if (DestX & 31)
364 {
365 #if 0
366 /* FIXME: This case is completely untested!!! */
367
368 Dest = *((PBYTE)DestBits);
369 NoBits = 31 - (DestX & 31);
370
371 if (UsesSource)
372 {
373 Source = 0;
374 /* FIXME: This is incorrect! */
375 for (Index = 31 - NoBits; Index >= 0; Index++)
376 Source |= (DIB_GetSource(SourceSurf, SourceX + Index, SourceY, ColorTranslation) << (31 - Index));
377 }
378
379 if (BltInfo->PatternSurface)
380 {
381 Pattern = 0;
382 for (k = 31 - NoBits; k >= 0; k++)
383 Pattern |= (DIB_GetSourceIndex(PatternObj, (X + BrushOrigin.x + k) % PatternWidth, PatternY) << (31 - k));
384 }
385
386 Dest = DIB_DoRop(Rop4, Dest, Source, Pattern);
387 Dest &= ~((1 << (31 - NoBits)) - 1);
388 Dest |= *((PBYTE)DestBits) & ((1 << (31 - NoBits)) - 1);
389
390 *DestBits = Dest;
391
392 DestX += NoBits;
393 SourceX += NoBits;
394 #endif
395 }
396
397 for (; DestX < RoundedRight; DestX += 32, DestBits++, SourceX += 32)
398 {
399 Dest = *DestBits;
400
401 if (UsesSource)
402 {
403 Source = 0;
404 for (Index = 0; Index < 8; Index++)
405 {
406 Source |= DIB_GetSource(BltInfo->SourceSurface, SourceX + Index, SourceY, BltInfo->XlateSourceToDest) << (7 - Index);
407 Source |= DIB_GetSource(BltInfo->SourceSurface, SourceX + Index + 8, SourceY, BltInfo->XlateSourceToDest) << (8 + (7 - Index));
408 Source |= DIB_GetSource(BltInfo->SourceSurface, SourceX + Index + 16, SourceY, BltInfo->XlateSourceToDest) << (16 + (7 - Index));
409 Source |= DIB_GetSource(BltInfo->SourceSurface, SourceX + Index + 24, SourceY, BltInfo->XlateSourceToDest) << (24 + (7 - Index));
410 }
411 }
412
413 if (BltInfo->PatternSurface)
414 {
415 Pattern = 0;
416 for (Index = 0; Index < 8; Index++)
417 {
418 Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + Index) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY) << (7 - Index);
419 Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + Index + 8) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY) << (8 + (7 - Index));
420 Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + Index + 16) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY) << (16 + (7 - Index));
421 Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + Index + 24) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY) << (24 + (7 - Index));
422 }
423 }
424
425 *DestBits = DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern);
426 }
427
428 if (DestX < BltInfo->DestRect.right)
429 {
430 for (; DestX < BltInfo->DestRect.right; DestX++, SourceX++)
431 {
432 Dest = DIB_1BPP_GetPixel(BltInfo->DestSurface, DestX, DestY);
433
434 if (UsesSource)
435 {
436 Source = DIB_GetSource(BltInfo->SourceSurface, SourceX, SourceY, BltInfo->XlateSourceToDest);
437 }
438
439 if (BltInfo->PatternSurface)
440 {
441 Pattern = DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY);
442 }
443
444 DIB_1BPP_PutPixel(BltInfo->DestSurface, DestX, DestY, DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern) & 0xF);
445 }
446 }
447
448 SourceY++;
449 if (BltInfo->PatternSurface)
450 {
451 PatternY++;
452 PatternY %= BltInfo->PatternSurface->sizlBitmap.cy;
453 }
454 }
455
456 return TRUE;
457 }
458
459 /* BitBlt Optimize */
460 BOOLEAN
461 DIB_1BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
462 {
463 ULONG DestY;
464
465 for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++)
466 {
467 DIB_1BPP_HLine(DestSurface, DestRect->left, DestRect->right, DestY, color);
468 }
469 return TRUE;
470 }
471
472 BOOLEAN
473 DIB_1BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
474 RECTL* DestRect, RECTL *SourceRect,
475 XLATEOBJ *ColorTranslation, ULONG iTransColor)
476 {
477 return FALSE;
478 }
479
480 BOOLEAN
481 DIB_1BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
482 RECTL* SourceRect, CLIPOBJ* ClipRegion,
483 XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
484 {
485 UNIMPLEMENTED;
486 return FALSE;
487 }
488
489 /* EOF */