[INTRIN]
[reactos.git] / reactos / win32ss / gdi / 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 // The 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 shift;
86 BYTE srcmask, dstmask, xormask;
87
88 // 'd' and 's' are the dest & src buffer pointers that I use on my x-sweep
89 // 'pd' and 'ps' are the dest & src buffer pointers used on the inner y-sweep
90 PBYTE d, pd; // dest ptrs
91 PBYTE s, ps; // src ptrs
92
93 shift = (dl-sl)&7;
94
95 xormask = 0xFF * (BYTE)XLATEOBJ_iXlate(pxlo, 0);
96
97 if ( DestRect->top <= SourcePoint->y )
98 {
99 // Moving up (scan top -> bottom)
100 dy1 = DestRect->top;
101 dy2 = DestRect->bottom - 1;
102 sy1 = SourcePoint->y;
103 yinc = 1;
104 ySrcDelta = SourceSurf->lDelta;
105 yDstDelta = DestSurf->lDelta;
106 }
107 else
108 {
109 // Moving down (scan bottom -> top)
110 dy1 = DestRect->bottom - 1;
111 dy2 = DestRect->top;
112 sy1 = SourcePoint->y + dy1 - dy2;
113 yinc = -1;
114 ySrcDelta = -SourceSurf->lDelta;
115 yDstDelta = -DestSurf->lDelta;
116 }
117 if ( DestRect->left <= SourcePoint->x )
118 {
119 // Moving left (scan left->right)
120 dwx = dl&~7;
121 swx = (sl-(dl&7))&~7;
122 dwx2 = dr&~7;
123 xinc = 1;
124 }
125 else
126 {
127 // Moving right (scan right->left)
128 dwx = dr & ~7;
129 swx = (sr - (dr & 7)) & ~7; // (sr - 7) & ~7; // We need the left edge of this block. Thus the -7
130 dwx2 = dl & ~7;
131 xinc = -1;
132 }
133 d = &(((PBYTE)DestSurf->pvScan0)[dy1*DestSurf->lDelta + (dwx>>3)]);
134 s = &(((PBYTE)SourceSurf->pvScan0)[sy1*SourceSurf->lDelta + (swx>>3)]);
135 for ( ;; )
136 {
137 dy = dy1;
138 pd = d;
139 ps = s;
140 srcmask = 0xff;
141 if ( dwx < dl )
142 {
143 int diff = dl-dwx;
144 srcmask &= (1<<(8-diff))-1;
145 }
146 if ( dwx+7 > dr )
147 {
148 int diff = dr-dwx+1;
149 srcmask &= ~((1<<(8-diff))-1);
150 }
151 dstmask = ~srcmask;
152
153 // We unfortunately *must* have 5 different versions of the inner
154 // loop to be certain we don't try to read from memory that is not
155 // needed and may in fact be invalid.
156 if ( !shift )
157 {
158 for ( ;; )
159 {
160 *pd = (BYTE)((*pd & dstmask) | ((ps[0]^xormask) & srcmask));
161
162 // This *must* be here, because we could be going up *or* down...
163 if ( dy == dy2 )
164 break;
165 dy += yinc;
166 pd += yDstDelta;
167 ps += ySrcDelta;
168 }
169 }
170 else if ( !(0xFF00 & (srcmask<<shift) ) ) // Check if ps[0] not needed...
171 {
172 for ( ;; )
173 {
174 *pd = (BYTE)((*pd & dstmask)
175 | ( ( (ps[1]^xormask) >> shift ) & srcmask ));
176
177 // This *must* be here, because we could be going up *or* down...
178 if ( dy == dy2 )
179 break;
180 dy += yinc;
181 pd += yDstDelta;
182 ps += ySrcDelta;
183 }
184 }
185 else if ( !(0xFF & (srcmask<<shift) ) ) // Check if ps[1] not needed...
186 {
187 for ( ;; )
188 {
189 *pd = (*pd & dstmask)
190 | ( ( (ps[0]^xormask) << ( 8 - shift ) ) & srcmask );
191
192 // This *must* be here, because we could be going up *or* down...
193 if ( dy == dy2 )
194 break;
195 dy += yinc;
196 pd += yDstDelta;
197 ps += ySrcDelta;
198 }
199 }
200 else // Both ps[0] and ps[1] are needed
201 {
202 for ( ;; )
203 {
204 *pd = (*pd & dstmask)
205 | ( ( ( ((ps[1]^xormask))|((ps[0]^xormask)<<8) ) >> shift ) & srcmask );
206
207 // This *must* be here, because we could be going up *or* down...
208 if ( dy == dy2 )
209 break;
210 dy += yinc;
211 pd += yDstDelta;
212 ps += ySrcDelta;
213 }
214 }
215
216 // This *must* be here, because we could be going right *or* left...
217 if ( dwx == dwx2 )
218 break;
219 d += xinc;
220 s += xinc;
221 dwx += xinc<<3;
222 swx += xinc<<3;
223 }
224 }
225
226 BOOLEAN
227 DIB_1BPP_BitBltSrcCopy(PBLTINFO BltInfo)
228 {
229 ULONG Color;
230 LONG i, j, sx, sy = BltInfo->SourcePoint.y;
231
232 switch ( BltInfo->SourceSurface->iBitmapFormat )
233 {
234 case BMF_1BPP:
235 DIB_1BPP_BitBltSrcCopy_From1BPP ( BltInfo->DestSurface, BltInfo->SourceSurface, BltInfo->XlateSourceToDest, &BltInfo->DestRect, &BltInfo->SourcePoint );
236 break;
237
238 case BMF_4BPP:
239 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
240 {
241 sx = BltInfo->SourcePoint.x;
242 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
243 {
244 Color = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_4BPP_GetPixel(BltInfo->SourceSurface, sx, sy));
245 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, Color);
246 sx++;
247 }
248 sy++;
249 }
250 break;
251
252 case BMF_8BPP:
253 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
254 {
255 sx = BltInfo->SourcePoint.x;
256 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
257 {
258 Color = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_8BPP_GetPixel(BltInfo->SourceSurface, sx, sy));
259 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, Color);
260 sx++;
261 }
262 sy++;
263 }
264 break;
265
266 case BMF_16BPP:
267 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
268 {
269 sx = BltInfo->SourcePoint.x;
270 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
271 {
272 Color = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_16BPP_GetPixel(BltInfo->SourceSurface, sx, sy));
273 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, Color);
274 sx++;
275 }
276 sy++;
277 }
278 break;
279
280 case BMF_24BPP:
281 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
282 {
283 sx = BltInfo->SourcePoint.x;
284 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
285 {
286 Color = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_24BPP_GetPixel(BltInfo->SourceSurface, sx, sy));
287 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, Color);
288 sx++;
289 }
290 sy++;
291 }
292 break;
293
294 case BMF_32BPP:
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 Color = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_32BPP_GetPixel(BltInfo->SourceSurface, sx, sy));
301 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, Color);
302 sx++;
303 }
304 sy++;
305 }
306 break;
307
308 default:
309 DbgPrint("DIB_1BPP_BitBlt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat));
310 return FALSE;
311 }
312
313 return TRUE;
314 }
315
316 #ifndef _USE_DIBLIB_
317 BOOLEAN
318 DIB_1BPP_BitBlt(PBLTINFO BltInfo)
319 {
320 LONG DestX, DestY;
321 LONG SourceX, SourceY;
322 LONG PatternY = 0;
323 ULONG Dest, Source = 0, Pattern = 0;
324 ULONG Index;
325 BOOLEAN UsesSource;
326 BOOLEAN UsesPattern;
327 PULONG DestBits;
328 LONG RoundedRight;
329
330 UsesSource = ROP4_USES_SOURCE(BltInfo->Rop4);
331 UsesPattern = ROP4_USES_PATTERN(BltInfo->Rop4);
332
333 RoundedRight = BltInfo->DestRect.right -
334 ((BltInfo->DestRect.right - BltInfo->DestRect.left) & 31);
335 SourceY = BltInfo->SourcePoint.y;
336
337 if (UsesPattern)
338 {
339 if (BltInfo->PatternSurface)
340 {
341 PatternY = (BltInfo->DestRect.top + BltInfo->BrushOrigin.y) %
342 BltInfo->PatternSurface->sizlBitmap.cy;
343 }
344 else
345 {
346 /* FIXME: Shouldn't it be expanded? */
347 if (BltInfo->Brush)
348 Pattern = BltInfo->Brush->iSolidColor;
349 }
350 }
351
352 for (DestY = BltInfo->DestRect.top; DestY < BltInfo->DestRect.bottom; DestY++)
353 {
354 DestX = BltInfo->DestRect.left;
355 SourceX = BltInfo->SourcePoint.x;
356 DestBits = (PULONG)(
357 (PBYTE)BltInfo->DestSurface->pvScan0 +
358 (BltInfo->DestRect.left >> 3) +
359 DestY * BltInfo->DestSurface->lDelta);
360
361 if (DestX & 31)
362 {
363 #if 0
364 /* FIXME: This case is completely untested!!! */
365
366 Dest = *((PBYTE)DestBits);
367 NoBits = 31 - (DestX & 31);
368
369 if (UsesSource)
370 {
371 Source = 0;
372 /* FIXME: This is incorrect! */
373 for (Index = 31 - NoBits; Index >= 0; Index++)
374 Source |= (DIB_GetSource(SourceSurf, SourceX + Index, SourceY, ColorTranslation) << (31 - Index));
375 }
376
377 if (BltInfo->PatternSurface)
378 {
379 Pattern = 0;
380 for (k = 31 - NoBits; k >= 0; k++)
381 Pattern |= (DIB_GetSourceIndex(PatternObj, (X + BrushOrigin.x + k) % PatternWidth, PatternY) << (31 - k));
382 }
383
384 Dest = DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern);
385 Dest &= ~((1 << (31 - NoBits)) - 1);
386 Dest |= *((PBYTE)DestBits) & ((1 << (31 - NoBits)) - 1);
387
388 *DestBits = Dest;
389
390 DestX += NoBits;
391 SourceX += NoBits;
392 #endif
393 }
394
395 for (; DestX < RoundedRight; DestX += 32, DestBits++, SourceX += 32)
396 {
397 Dest = *DestBits;
398
399 if (UsesSource)
400 {
401 Source = 0;
402 for (Index = 0; Index < 8; Index++)
403 {
404 Source |= DIB_GetSource(BltInfo->SourceSurface, SourceX + Index, SourceY, BltInfo->XlateSourceToDest) << (7 - Index);
405 Source |= DIB_GetSource(BltInfo->SourceSurface, SourceX + Index + 8, SourceY, BltInfo->XlateSourceToDest) << (8 + (7 - Index));
406 Source |= DIB_GetSource(BltInfo->SourceSurface, SourceX + Index + 16, SourceY, BltInfo->XlateSourceToDest) << (16 + (7 - Index));
407 Source |= DIB_GetSource(BltInfo->SourceSurface, SourceX + Index + 24, SourceY, BltInfo->XlateSourceToDest) << (24 + (7 - Index));
408 }
409 }
410
411 if (BltInfo->PatternSurface)
412 {
413 Pattern = 0;
414 for (Index = 0; Index < 8; Index++)
415 {
416 Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + Index) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY) << (7 - Index);
417 Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + Index + 8) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY) << (8 + (7 - Index));
418 Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + Index + 16) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY) << (16 + (7 - Index));
419 Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + Index + 24) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY) << (24 + (7 - Index));
420 }
421 }
422
423 *DestBits = DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern);
424 }
425
426 if (DestX < BltInfo->DestRect.right)
427 {
428 for (; DestX < BltInfo->DestRect.right; DestX++, SourceX++)
429 {
430 Dest = DIB_1BPP_GetPixel(BltInfo->DestSurface, DestX, DestY);
431
432 if (UsesSource)
433 {
434 Source = DIB_GetSource(BltInfo->SourceSurface, SourceX, SourceY, BltInfo->XlateSourceToDest);
435 }
436
437 if (BltInfo->PatternSurface)
438 {
439 Pattern = DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY);
440 }
441
442 DIB_1BPP_PutPixel(BltInfo->DestSurface, DestX, DestY, DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern) & 0xF);
443 }
444 }
445
446 SourceY++;
447 if (BltInfo->PatternSurface)
448 {
449 PatternY++;
450 PatternY %= BltInfo->PatternSurface->sizlBitmap.cy;
451 }
452 }
453
454 return TRUE;
455 }
456
457 /* BitBlt Optimize */
458 BOOLEAN
459 DIB_1BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
460 {
461 LONG DestY;
462
463 for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++)
464 {
465 DIB_1BPP_HLine(DestSurface, DestRect->left, DestRect->right, DestY, color);
466 }
467 return TRUE;
468 }
469 #endif // !_USE_DIBLIB_
470
471 BOOLEAN
472 DIB_1BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
473 RECTL* DestRect, RECTL *SourceRect,
474 XLATEOBJ *ColorTranslation, ULONG iTransColor)
475 {
476 return FALSE;
477 }
478
479 /* EOF */