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.15 2004/03/21 04:17:33 royce Exp $ */
21 #undef WIN32_LEAN_AND_MEAN
24 #include <win32k/bitmaps.h>
25 #include <win32k/debug.h>
27 #include <ddk/winddi.h>
28 #include "../eng/objects.h"
32 DIB_1BPP_PutPixel(PSURFOBJ SurfObj
, LONG x
, LONG y
, ULONG c
)
34 PBYTE addr
= SurfObj
->pvScan0
+ y
* SurfObj
->lDelta
+ (x
>> 3);
37 *addr
&= ~MASK1BPP(x
);
43 DIB_1BPP_GetPixel(PSURFOBJ SurfObj
, LONG x
, LONG y
)
45 PBYTE addr
= SurfObj
->pvScan0
+ y
* SurfObj
->lDelta
+ (x
>> 3);
47 return (*addr
& MASK1BPP(x
) ? 1 : 0);
51 DIB_1BPP_HLine(PSURFOBJ SurfObj
, LONG x1
, LONG x2
, LONG y
, ULONG c
)
54 DIB_1BPP_PutPixel(SurfObj
, x1
, y
, c
);
60 DIB_1BPP_VLine(PSURFOBJ SurfObj
, LONG x
, LONG y1
, LONG y2
, ULONG c
)
63 DIB_1BPP_PutPixel(SurfObj
, x
, y1
, c
);
70 DIB_1BPP_BitBltSrcCopy_From1BPP (
71 SURFOBJ
* DestSurf
, SURFOBJ
* SourceSurf
,
72 PRECTL DestRect
, POINTL
*SourcePoint
)
74 // the 'window' in this sense is the x-position that corresponds
75 // to the left-edge of the 8-pixel byte we are currently working with.
76 // dwx is current x-window, dwx2 is the 'last' window we need to process
77 int dwx
, dwx2
; // destination window x-position
78 int swx
; // source window y-position
80 // left and right edges of source and dest rectangles
81 int dl
= DestRect
->left
; // dest left
82 int dr
= DestRect
->right
-1; // dest right (inclusive)
83 int sl
= SourcePoint
->x
; // source left
84 int sr
= sl
+ dr
- dl
; // source right (inclusive)
86 // which direction are we going?
90 // following 4 variables are used for the y-sweep
92 int dy1
; // dest y start
93 int dy2
; // dest y end
94 int sy1
; // src y start
97 BYTE srcmask
, dstmask
;
99 // 'd' and 's' are the dest & src buffer pointers that I use on my x-sweep
100 // 'pd' and 'ps' are the dest & src buffer pointers used on the inner y-sweep
101 PBYTE d
, pd
; // dest ptrs
102 PBYTE s
, ps
; // src ptrs
106 if ( DestRect
->top
<= SourcePoint
->y
)
108 // moving up ( scan top -> bottom )
110 dy2
= DestRect
->bottom
- 1;
111 sy1
= SourcePoint
->y
;
116 // moving down ( scan bottom -> top )
117 dy1
= DestRect
->bottom
- 1;
119 sy1
= SourcePoint
->y
+ dy1
- dy2
;
122 if ( DestRect
->left
<= SourcePoint
->x
)
124 // moving left ( scan left->right )
126 swx
= (sl
-(dl
&7))&~7;
132 // moving right ( scan right->left )
134 swx
= (sr
-(dr
&7))&~7; //(sr-7)&~7; // we need the left edge of this block... thus the -7
138 d
= &(((PBYTE
)DestSurf
->pvScan0
)[dy1
*DestSurf
->lDelta
+ (dwx
>>3)]);
139 s
= &(((PBYTE
)SourceSurf
->pvScan0
)[sy1
*SourceSurf
->lDelta
+ (swx
>>3)]);
146 int dx
= dwx
; /* dest x for this pass */
150 srcmask
&= (1<<(8-diff
))-1;
156 srcmask
&= ~((1<<(8-diff
))-1);
160 // we unfortunately *must* have 5 different versions of the inner
161 // loop to be certain we don't try to read from memory that is not
162 // needed and may in fact be invalid
167 *pd
= (BYTE
)((*pd
& dstmask
) | (*ps
& srcmask
));
169 // this *must* be here, because we could be going up *or* down...
173 pd
+= yinc
* DestSurf
->lDelta
;
174 ps
+= yinc
* SourceSurf
->lDelta
;
177 else if ( !(0xFF00 & (srcmask
<<shift
) ) ) // check if ps[0] not needed...
181 *pd
= (BYTE
)((*pd
& dstmask
)
182 | ( ( ps
[1] >> shift
) & srcmask
));
184 // this *must* be here, because we could be going up *or* down...
188 pd
+= yinc
* DestSurf
->lDelta
;
189 ps
+= yinc
* SourceSurf
->lDelta
;
192 else if ( !(0xFF & (srcmask
<<shift
) ) ) // check if ps[1] not needed...
196 *pd
= (*pd
& dstmask
)
197 | ( ( ps
[0] << ( 8 - shift
) ) & srcmask
);
199 // this *must* be here, because we could be going up *or* down...
203 pd
+= yinc
* DestSurf
->lDelta
;
204 ps
+= yinc
* SourceSurf
->lDelta
;
207 else // both ps[0] and ps[1] are needed
211 *pd
= (*pd
& dstmask
)
212 | ( ( ( (ps
[1])|(ps
[0]<<8) ) >> shift
) & srcmask
);
214 // this *must* be here, because we could be going up *or* down...
218 pd
+= yinc
* DestSurf
->lDelta
;
219 ps
+= yinc
* SourceSurf
->lDelta
;
223 // this *must* be here, because we could be going right *or* left...
234 DIB_1BPP_BitBltSrcCopy(
235 SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
236 SURFGDI
*DestGDI
, SURFGDI
*SourceGDI
,
237 PRECTL DestRect
, POINTL
*SourcePoint
,
238 XLATEOBJ
*ColorTranslation
)
240 LONG i
, j
, sx
, sy
= SourcePoint
->y
;
242 switch ( SourceGDI
->BitsPerPixel
)
245 DIB_1BPP_BitBltSrcCopy_From1BPP ( DestSurf
, SourceSurf
, DestRect
, SourcePoint
);
249 for (j
=DestRect
->top
; j
<DestRect
->bottom
; j
++)
252 for (i
=DestRect
->left
; i
<DestRect
->right
; i
++)
254 if(XLATEOBJ_iXlate(ColorTranslation
, DIB_4BPP_GetPixel(SourceSurf
, sx
, sy
)) == 0)
256 DIB_1BPP_PutPixel(DestSurf
, i
, j
, 0);
258 DIB_1BPP_PutPixel(DestSurf
, i
, j
, 1);
267 for (j
=DestRect
->top
; j
<DestRect
->bottom
; j
++)
270 for (i
=DestRect
->left
; i
<DestRect
->right
; i
++)
272 if(XLATEOBJ_iXlate(ColorTranslation
, DIB_8BPP_GetPixel(SourceSurf
, sx
, sy
)) == 0)
274 DIB_1BPP_PutPixel(DestSurf
, i
, j
, 0);
276 DIB_1BPP_PutPixel(DestSurf
, i
, j
, 1);
285 for (j
=DestRect
->top
; j
<DestRect
->bottom
; j
++)
288 for (i
=DestRect
->left
; i
<DestRect
->right
; i
++)
290 if(XLATEOBJ_iXlate(ColorTranslation
, DIB_16BPP_GetPixel(SourceSurf
, sx
, sy
)) == 0)
292 DIB_1BPP_PutPixel(DestSurf
, i
, j
, 0);
294 DIB_1BPP_PutPixel(DestSurf
, i
, j
, 1);
303 for (j
=DestRect
->top
; j
<DestRect
->bottom
; j
++)
306 for (i
=DestRect
->left
; i
<DestRect
->right
; i
++)
308 if(XLATEOBJ_iXlate(ColorTranslation
, DIB_24BPP_GetPixel(SourceSurf
, sx
, sy
)) == 0)
310 DIB_1BPP_PutPixel(DestSurf
, i
, j
, 0);
312 DIB_1BPP_PutPixel(DestSurf
, i
, j
, 1);
321 for (j
=DestRect
->top
; j
<DestRect
->bottom
; j
++)
324 for (i
=DestRect
->left
; i
<DestRect
->right
; i
++)
326 if(XLATEOBJ_iXlate(ColorTranslation
, DIB_32BPP_GetPixel(SourceSurf
, sx
, sy
)) == 0)
328 DIB_1BPP_PutPixel(DestSurf
, i
, j
, 0);
330 DIB_1BPP_PutPixel(DestSurf
, i
, j
, 1);
339 DbgPrint("DIB_1BPP_BitBlt: Unhandled Source BPP: %u\n", SourceGDI
->BitsPerPixel
);
348 SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
349 SURFGDI
*DestGDI
, SURFGDI
*SourceGDI
,
350 PRECTL DestRect
, POINTL
*SourcePoint
,
351 PBRUSHOBJ Brush
, PPOINTL BrushOrigin
,
352 XLATEOBJ
*ColorTranslation
, ULONG Rop4
)
354 LONG i
, j
, k
, sx
, sy
;
355 ULONG Dest
, Source
, Pattern
;
357 BOOL UsesSource
= ((Rop4
& 0xCC0000) >> 2) != (Rop4
& 0x330000);
358 BOOL UsesPattern
= ((Rop4
& 0xF00000) >> 4) != (Rop4
& 0x0F0000);
359 LONG RoundedRight
= DestRect
->right
- ((DestRect
->right
- DestRect
->left
) & 0x7);
363 return(DIB_1BPP_BitBltSrcCopy(DestSurf
, SourceSurf
, DestGDI
, SourceGDI
, DestRect
, SourcePoint
, ColorTranslation
));
369 for (j
=DestRect
->top
; j
<DestRect
->bottom
; j
++)
372 DestBits
= (PULONG
)(DestSurf
->pvScan0
+ (DestRect
->left
>>3) + j
* DestSurf
->lDelta
);
373 for (i
=DestRect
->left
; i
<RoundedRight
; i
+=32, DestBits
++)
379 for (k
= 0; k
< 32; k
++)
381 Source
|= (DIB_GetSource(SourceSurf
, SourceGDI
, sx
+ (i
- DestRect
->left
) + k
, sy
, ColorTranslation
) << k
);
386 /* FIXME: No support for pattern brushes. */
387 Pattern
= Brush
->iSolidColor
? 0xFFFFFFFF : 0x00000000;
389 *DestBits
= DIB_DoRop(Rop4
, Dest
, Source
, Pattern
);
391 if (i
< DestRect
->right
)
394 for (; i
< DestRect
->right
; i
++)
398 Source
= DIB_GetSource(SourceSurf
, SourceGDI
, sx
+ (i
- DestRect
->left
), sy
, ColorTranslation
);
402 /* FIXME: No support for pattern brushes. */
403 Pattern
= Brush
->iSolidColor
? 0xFFFFFFFF : 0x00000000;
405 DIB_1BPP_PutPixel(DestSurf
, i
, j
, DIB_DoRop(Rop4
, Dest
, Source
, Pattern
) & 0xF);
416 DIB_1BPP_StretchBlt (
417 SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
418 SURFGDI
*DestGDI
, SURFGDI
*SourceGDI
,
419 RECTL
* DestRect
, RECTL
*SourceRect
,
420 POINTL
* MaskOrigin
, POINTL
* BrushOrigin
,
421 XLATEOBJ
*ColorTranslation
, ULONG Mode
)
423 DbgPrint("DIB_1BPP_StretchBlt: Source BPP: %u\n", SourceGDI
->BitsPerPixel
);