2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
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.
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.
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.
19 /* $Id: dib1bpp.c,v 1.25 2004/04/25 11:34:12 weiden Exp $ */
21 #undef WIN32_LEAN_AND_MEAN
24 #include <win32k/bitmaps.h>
25 #include <win32k/brush.h>
26 #include <win32k/debug.h>
27 #include <include/object.h>
29 #include <ddk/winddi.h>
30 #include "../eng/objects.h"
34 DIB_1BPP_PutPixel(SURFOBJ
*SurfObj
, LONG x
, LONG y
, ULONG c
)
36 PBYTE addr
= SurfObj
->pvScan0
+ y
* SurfObj
->lDelta
+ (x
>> 3);
39 *addr
&= ~MASK1BPP(x
);
45 DIB_1BPP_GetPixel(SURFOBJ
*SurfObj
, LONG x
, LONG y
)
47 PBYTE addr
= SurfObj
->pvScan0
+ y
* SurfObj
->lDelta
+ (x
>> 3);
49 return (*addr
& MASK1BPP(x
) ? 1 : 0);
53 DIB_1BPP_HLine(SURFOBJ
*SurfObj
, LONG x1
, LONG x2
, LONG y
, ULONG c
)
56 DIB_1BPP_PutPixel(SurfObj
, x1
, y
, c
);
62 DIB_1BPP_VLine(SURFOBJ
*SurfObj
, LONG x
, LONG y1
, LONG y2
, ULONG c
)
65 DIB_1BPP_PutPixel(SurfObj
, x
, y1
, c
);
72 DIB_1BPP_BitBltSrcCopy_From1BPP (
73 SURFOBJ
* DestSurf
, SURFOBJ
* SourceSurf
,
74 PRECTL DestRect
, POINTL
*SourcePoint
)
76 // the 'window' in this sense is the x-position that corresponds
77 // to the left-edge of the 8-pixel byte we are currently working with.
78 // dwx is current x-window, dwx2 is the 'last' window we need to process
79 int dwx
, dwx2
; // destination window x-position
80 int swx
; // source window y-position
82 // left and right edges of source and dest rectangles
83 int dl
= DestRect
->left
; // dest left
84 int dr
= DestRect
->right
-1; // dest right (inclusive)
85 int sl
= SourcePoint
->x
; // source left
86 int sr
= sl
+ dr
- dl
; // source right (inclusive)
88 // which direction are we going?
92 // following 4 variables are used for the y-sweep
94 int dy1
; // dest y start
95 int dy2
; // dest y end
96 int sy1
; // src y start
99 BYTE srcmask
, dstmask
;
101 // 'd' and 's' are the dest & src buffer pointers that I use on my x-sweep
102 // 'pd' and 'ps' are the dest & src buffer pointers used on the inner y-sweep
103 PBYTE d
, pd
; // dest ptrs
104 PBYTE s
, ps
; // src ptrs
108 if ( DestRect
->top
<= SourcePoint
->y
)
110 // moving up ( scan top -> bottom )
112 dy2
= DestRect
->bottom
- 1;
113 sy1
= SourcePoint
->y
;
118 // moving down ( scan bottom -> top )
119 dy1
= DestRect
->bottom
- 1;
121 sy1
= SourcePoint
->y
+ dy1
- dy2
;
124 if ( DestRect
->left
<= SourcePoint
->x
)
126 // moving left ( scan left->right )
128 swx
= (sl
-(dl
&7))&~7;
134 // moving right ( scan right->left )
136 swx
= (sr
-(dr
&7))&~7; //(sr-7)&~7; // we need the left edge of this block... thus the -7
140 d
= &(((PBYTE
)DestSurf
->pvScan0
)[dy1
*DestSurf
->lDelta
+ (dwx
>>3)]);
141 s
= &(((PBYTE
)SourceSurf
->pvScan0
)[sy1
*SourceSurf
->lDelta
+ (swx
>>3)]);
148 int dx
= dwx
; /* dest x for this pass */
152 srcmask
&= (1<<(8-diff
))-1;
158 srcmask
&= ~((1<<(8-diff
))-1);
162 // we unfortunately *must* have 5 different versions of the inner
163 // loop to be certain we don't try to read from memory that is not
164 // needed and may in fact be invalid
169 *pd
= (BYTE
)((*pd
& dstmask
) | (*ps
& srcmask
));
171 // this *must* be here, because we could be going up *or* down...
175 pd
+= yinc
* DestSurf
->lDelta
;
176 ps
+= yinc
* SourceSurf
->lDelta
;
179 else if ( !(0xFF00 & (srcmask
<<shift
) ) ) // check if ps[0] not needed...
183 *pd
= (BYTE
)((*pd
& dstmask
)
184 | ( ( ps
[1] >> shift
) & srcmask
));
186 // this *must* be here, because we could be going up *or* down...
190 pd
+= yinc
* DestSurf
->lDelta
;
191 ps
+= yinc
* SourceSurf
->lDelta
;
194 else if ( !(0xFF & (srcmask
<<shift
) ) ) // check if ps[1] not needed...
198 *pd
= (*pd
& dstmask
)
199 | ( ( ps
[0] << ( 8 - shift
) ) & srcmask
);
201 // this *must* be here, because we could be going up *or* down...
205 pd
+= yinc
* DestSurf
->lDelta
;
206 ps
+= yinc
* SourceSurf
->lDelta
;
209 else // both ps[0] and ps[1] are needed
213 *pd
= (*pd
& dstmask
)
214 | ( ( ( (ps
[1])|(ps
[0]<<8) ) >> shift
) & srcmask
);
216 // this *must* be here, because we could be going up *or* down...
220 pd
+= yinc
* DestSurf
->lDelta
;
221 ps
+= yinc
* SourceSurf
->lDelta
;
225 // this *must* be here, because we could be going right *or* left...
236 DIB_1BPP_BitBltSrcCopy(
237 SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
238 SURFGDI
*DestGDI
, SURFGDI
*SourceGDI
,
239 PRECTL DestRect
, POINTL
*SourcePoint
,
240 XLATEOBJ
*ColorTranslation
)
242 LONG i
, j
, sx
, sy
= SourcePoint
->y
;
244 switch ( SourceGDI
->BitsPerPixel
)
247 DIB_1BPP_BitBltSrcCopy_From1BPP ( DestSurf
, SourceSurf
, DestRect
, SourcePoint
);
251 for (j
=DestRect
->top
; j
<DestRect
->bottom
; j
++)
254 for (i
=DestRect
->left
; i
<DestRect
->right
; i
++)
256 if(XLATEOBJ_iXlate(ColorTranslation
, DIB_4BPP_GetPixel(SourceSurf
, sx
, sy
)) == 0)
258 DIB_1BPP_PutPixel(DestSurf
, i
, j
, 0);
260 DIB_1BPP_PutPixel(DestSurf
, i
, j
, 1);
269 for (j
=DestRect
->top
; j
<DestRect
->bottom
; j
++)
272 for (i
=DestRect
->left
; i
<DestRect
->right
; i
++)
274 if(XLATEOBJ_iXlate(ColorTranslation
, DIB_8BPP_GetPixel(SourceSurf
, sx
, sy
)) == 0)
276 DIB_1BPP_PutPixel(DestSurf
, i
, j
, 0);
278 DIB_1BPP_PutPixel(DestSurf
, i
, j
, 1);
287 for (j
=DestRect
->top
; j
<DestRect
->bottom
; j
++)
290 for (i
=DestRect
->left
; i
<DestRect
->right
; i
++)
292 if(XLATEOBJ_iXlate(ColorTranslation
, DIB_16BPP_GetPixel(SourceSurf
, sx
, sy
)) == 0)
294 DIB_1BPP_PutPixel(DestSurf
, i
, j
, 0);
296 DIB_1BPP_PutPixel(DestSurf
, i
, j
, 1);
305 for (j
=DestRect
->top
; j
<DestRect
->bottom
; j
++)
308 for (i
=DestRect
->left
; i
<DestRect
->right
; i
++)
310 if(XLATEOBJ_iXlate(ColorTranslation
, DIB_24BPP_GetPixel(SourceSurf
, sx
, sy
)) == 0)
312 DIB_1BPP_PutPixel(DestSurf
, i
, j
, 0);
314 DIB_1BPP_PutPixel(DestSurf
, i
, j
, 1);
323 for (j
=DestRect
->top
; j
<DestRect
->bottom
; j
++)
326 for (i
=DestRect
->left
; i
<DestRect
->right
; i
++)
328 if(XLATEOBJ_iXlate(ColorTranslation
, DIB_32BPP_GetPixel(SourceSurf
, sx
, sy
)) == 0)
330 DIB_1BPP_PutPixel(DestSurf
, i
, j
, 0);
332 DIB_1BPP_PutPixel(DestSurf
, i
, j
, 1);
341 DbgPrint("DIB_1BPP_BitBlt: Unhandled Source BPP: %u\n", SourceGDI
->BitsPerPixel
);
350 SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
351 SURFGDI
*DestGDI
, SURFGDI
*SourceGDI
,
352 PRECTL DestRect
, POINTL
*SourcePoint
,
353 BRUSHOBJ
*Brush
, POINTL BrushOrigin
,
354 XLATEOBJ
*ColorTranslation
, ULONG Rop4
)
356 ULONG X
, Y
, SourceX
, SourceY
, k
;
357 ULONG Dest
, Source
, Pattern
= 0;
363 /* Pattern brushes */
364 PGDIBRUSHOBJ GdiBrush
;
365 HBITMAP PatternSurface
= NULL
;
367 ULONG PatternWidth
, PatternHeight
;
371 return DIB_1BPP_BitBltSrcCopy(
381 UsesSource
= ((Rop4
& 0xCC0000) >> 2) != (Rop4
& 0x330000);
382 UsesPattern
= (((Rop4
& 0xF00000) >> 4) != (Rop4
& 0x0F0000)) && Brush
;
386 if (Brush
->iSolidColor
== 0xFFFFFFFF)
388 PBITMAPOBJ PatternBitmap
;
390 GdiBrush
= CONTAINING_RECORD(
395 PatternBitmap
= BITMAPOBJ_LockBitmap(GdiBrush
->hbmPattern
);
396 PatternSurface
= BitmapToSurf(PatternBitmap
, NULL
);
397 BITMAPOBJ_UnlockBitmap(GdiBrush
->hbmPattern
);
399 PatternObj
= (SURFOBJ
*)AccessUserObject((ULONG
)PatternSurface
);
400 PatternWidth
= PatternObj
->sizlBitmap
.cx
;
401 PatternHeight
= PatternObj
->sizlBitmap
.cy
;
408 Pattern
= Brush
->iSolidColor
;
412 RoundedRight
= DestRect
->right
- ((DestRect
->right
- DestRect
->left
) & 31);
413 SourceY
= SourcePoint
->y
;
415 for (Y
= DestRect
->top
; Y
< DestRect
->bottom
; Y
++)
419 SourceX
= SourcePoint
->x
;
422 (DestRect
->left
>> 3) +
423 Y
* DestSurf
->lDelta
);
426 PatternY
= (Y
+ BrushOrigin
.y
) % PatternHeight
;
431 /* FIXME: This case is completely untested!!! */
433 Dest
= *((PBYTE
)DestBits
);
434 NoBits
= 31 - (X
& 31);
439 for (k
= 31 - NoBits
; k
< NoBits
; k
++)
440 Source
|= (DIB_GetSource(SourceSurf
, SourceGDI
, SourceX
+ k
, SourceY
, ColorTranslation
) << (31 - k
));
446 for (k
= 31 - NoBits
; k
< NoBits
; k
++)
447 Pattern
|= (DIB_1BPP_GetPixel(PatternObj
, (X
+ BrushOrigin
.x
+ k
) % PatternWidth
, PatternY
) << (31 - k
));
450 Dest
= DIB_DoRop(Rop4
, Dest
, Source
, Pattern
);
451 Dest
&= ~((1 << (31 - NoBits
)) - 1);
452 Dest
|= *((PBYTE
)DestBits
) & ((1 << (31 - NoBits
)) - 1);
460 for (; X
< RoundedRight
; X
+= 32, DestBits
++, SourceX
++)
467 for (k
= 0; k
< 8; k
++)
469 Source
|= (DIB_GetSource(SourceSurf
, SourceGDI
, SourceX
+ k
, SourceY
, ColorTranslation
) << (7 - k
));
470 Source
|= (DIB_GetSource(SourceSurf
, SourceGDI
, SourceX
+ k
+ 8, SourceY
, ColorTranslation
) << (8 + (7 - k
)));
471 Source
|= (DIB_GetSource(SourceSurf
, SourceGDI
, SourceX
+ k
+ 16, SourceY
, ColorTranslation
) << (16 + (7 - k
)));
472 Source
|= (DIB_GetSource(SourceSurf
, SourceGDI
, SourceX
+ k
+ 24, SourceY
, ColorTranslation
) << (24 + (7 - k
)));
479 for (k
= 0; k
< 8; k
++)
481 Pattern
|= (DIB_1BPP_GetPixel(PatternObj
, (X
+ BrushOrigin
.x
+ k
) % PatternWidth
, PatternY
) << (7 - k
));
482 Pattern
|= (DIB_1BPP_GetPixel(PatternObj
, (X
+ BrushOrigin
.x
+ k
+ 8) % PatternWidth
, PatternY
) << (8 + (7 - k
)));
483 Pattern
|= (DIB_1BPP_GetPixel(PatternObj
, (X
+ BrushOrigin
.x
+ k
+ 16) % PatternWidth
, PatternY
) << (16 + (7 - k
)));
484 Pattern
|= (DIB_1BPP_GetPixel(PatternObj
, (X
+ BrushOrigin
.x
+ k
+ 24) % PatternWidth
, PatternY
) << (24 + (7 - k
)));
488 *DestBits
= DIB_DoRop(Rop4
, Dest
, Source
, Pattern
);
491 if (X
< DestRect
->right
)
494 for (; X
< DestRect
->right
; X
++, SourceX
++)
497 Dest
= DIB_1BPP_GetPixel(DestSurf
, X
, Y
);
501 Source
= DIB_GetSource(SourceSurf
, SourceGDI
, SourceX
, SourceY
, ColorTranslation
);
506 Pattern
= DIB_1BPP_GetPixel(PatternObj
, (X
+ BrushOrigin
.x
) % PatternWidth
, PatternY
);
509 DIB_1BPP_PutPixel(DestSurf
, X
, Y
, DIB_DoRop(Rop4
, Dest
, Source
, Pattern
) & 0xF);
517 if (PatternSurface
!= NULL
)
518 EngDeleteSurface((HSURF
)PatternSurface
);
524 DIB_1BPP_StretchBlt (
525 SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
526 SURFGDI
*DestGDI
, SURFGDI
*SourceGDI
,
527 RECTL
* DestRect
, RECTL
*SourceRect
,
528 POINTL
* MaskOrigin
, POINTL BrushOrigin
,
529 XLATEOBJ
*ColorTranslation
, ULONG Mode
)
531 DbgPrint("DIB_1BPP_StretchBlt: Source BPP: %u\n", SourceGDI
->BitsPerPixel
);
536 DIB_1BPP_TransparentBlt(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
537 PSURFGDI DestGDI
, PSURFGDI SourceGDI
,
538 RECTL
* DestRect
, POINTL
*SourcePoint
,
539 XLATEOBJ
*ColorTranslation
, ULONG iTransColor
)