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.
26 DIB_1BPP_PutPixel(SURFOBJ
*SurfObj
, LONG x
, LONG y
, ULONG c
)
28 PBYTE addr
= (PBYTE
)SurfObj
->pvScan0
+ y
* SurfObj
->lDelta
+ (x
>> 3);
31 *addr
&= ~MASK1BPP(x
);
37 DIB_1BPP_GetPixel(SURFOBJ
*SurfObj
, LONG x
, LONG y
)
39 PBYTE addr
= (PBYTE
)SurfObj
->pvScan0
+ y
* SurfObj
->lDelta
+ (x
>> 3);
41 return (*addr
& MASK1BPP(x
) ? 1 : 0);
45 DIB_1BPP_HLine(SURFOBJ
*SurfObj
, LONG x1
, LONG x2
, LONG y
, ULONG c
)
48 DIB_1BPP_PutPixel(SurfObj
, x1
, y
, c
);
54 DIB_1BPP_VLine(SURFOBJ
*SurfObj
, LONG x
, LONG y1
, LONG y2
, ULONG c
)
57 DIB_1BPP_PutPixel(SurfObj
, x
, y1
, c
);
64 DIB_1BPP_BitBltSrcCopy_From1BPP (
65 SURFOBJ
* DestSurf
, SURFOBJ
* SourceSurf
,
66 PRECTL DestRect
, POINTL
*SourcePoint
)
68 // the 'window' in this sense is the x-position that corresponds
69 // to the left-edge of the 8-pixel byte we are currently working with.
70 // dwx is current x-window, dwx2 is the 'last' window we need to process
71 int dwx
, dwx2
; // destination window x-position
72 int swx
; // source window y-position
74 // left and right edges of source and dest rectangles
75 int dl
= DestRect
->left
; // dest left
76 int dr
= DestRect
->right
-1; // dest right (inclusive)
77 int sl
= SourcePoint
->x
; // source left
78 int sr
= sl
+ dr
- dl
; // source right (inclusive)
80 // which direction are we going?
83 int ySrcDelta
, yDstDelta
;
85 // following 4 variables are used for the y-sweep
87 int dy1
; // dest y start
88 int dy2
; // dest y end
89 int sy1
; // src y start
93 BYTE srcmask
, dstmask
;
95 // 'd' and 's' are the dest & src buffer pointers that I use on my x-sweep
96 // 'pd' and 'ps' are the dest & src buffer pointers used on the inner y-sweep
97 PBYTE d
, pd
; // dest ptrs
98 PBYTE s
, ps
; // src ptrs
102 if ( DestRect
->top
<= SourcePoint
->y
)
104 // moving up ( scan top -> bottom )
106 dy2
= DestRect
->bottom
- 1;
107 sy1
= SourcePoint
->y
;
109 ySrcDelta
= SourceSurf
->lDelta
;
110 yDstDelta
= DestSurf
->lDelta
;
114 // moving down ( scan bottom -> top )
115 dy1
= DestRect
->bottom
- 1;
117 sy1
= SourcePoint
->y
+ dy1
- dy2
;
119 ySrcDelta
= -SourceSurf
->lDelta
;
120 yDstDelta
= -DestSurf
->lDelta
;
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 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...
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...
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...
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...
223 // this *must* be here, because we could be going right *or* left...
234 DIB_1BPP_BitBltSrcCopy(PBLTINFO BltInfo
)
236 LONG i
, j
, sx
, sy
= BltInfo
->SourcePoint
.y
;
238 switch ( BltInfo
->SourceSurface
->iBitmapFormat
)
241 DIB_1BPP_BitBltSrcCopy_From1BPP ( BltInfo
->DestSurface
, BltInfo
->SourceSurface
, &BltInfo
->DestRect
, &BltInfo
->SourcePoint
);
245 for (j
=BltInfo
->DestRect
.top
; j
<BltInfo
->DestRect
.bottom
; j
++)
247 sx
= BltInfo
->SourcePoint
.x
;
248 for (i
=BltInfo
->DestRect
.left
; i
<BltInfo
->DestRect
.right
; i
++)
250 if(XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, DIB_4BPP_GetPixel(BltInfo
->SourceSurface
, sx
, sy
)) == 0)
252 DIB_1BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, 0);
254 DIB_1BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, 1);
263 for (j
=BltInfo
->DestRect
.top
; j
<BltInfo
->DestRect
.bottom
; j
++)
265 sx
= BltInfo
->SourcePoint
.x
;
266 for (i
=BltInfo
->DestRect
.left
; i
<BltInfo
->DestRect
.right
; i
++)
268 if(XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, DIB_8BPP_GetPixel(BltInfo
->SourceSurface
, sx
, sy
)) == 0)
270 DIB_1BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, 0);
272 DIB_1BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, 1);
281 for (j
=BltInfo
->DestRect
.top
; j
<BltInfo
->DestRect
.bottom
; j
++)
283 sx
= BltInfo
->SourcePoint
.x
;
284 for (i
=BltInfo
->DestRect
.left
; i
<BltInfo
->DestRect
.right
; i
++)
286 if(XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, DIB_16BPP_GetPixel(BltInfo
->SourceSurface
, sx
, sy
)) == 0)
288 DIB_1BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, 0);
290 DIB_1BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, 1);
299 for (j
=BltInfo
->DestRect
.top
; j
<BltInfo
->DestRect
.bottom
; j
++)
301 sx
= BltInfo
->SourcePoint
.x
;
302 for (i
=BltInfo
->DestRect
.left
; i
<BltInfo
->DestRect
.right
; i
++)
304 if(XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, DIB_24BPP_GetPixel(BltInfo
->SourceSurface
, sx
, sy
)) == 0)
306 DIB_1BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, 0);
308 DIB_1BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, 1);
317 for (j
=BltInfo
->DestRect
.top
; j
<BltInfo
->DestRect
.bottom
; j
++)
319 sx
= BltInfo
->SourcePoint
.x
;
320 for (i
=BltInfo
->DestRect
.left
; i
<BltInfo
->DestRect
.right
; i
++)
322 if(XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, DIB_32BPP_GetPixel(BltInfo
->SourceSurface
, sx
, sy
)) == 0)
324 DIB_1BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, 0);
326 DIB_1BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, 1);
335 DbgPrint("DIB_1BPP_BitBlt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo
->SourceSurface
->iBitmapFormat
));
343 DIB_1BPP_BitBlt(PBLTINFO BltInfo
)
346 ULONG SourceX
, SourceY
;
348 ULONG Dest
, Source
= 0, Pattern
= 0;
356 UsesSource
= ROP4_USES_SOURCE(BltInfo
->Rop4
);
357 UsesPattern
= ROP4_USES_PATTERN(BltInfo
->Rop4
);
359 RoundedRight
= BltInfo
->DestRect
.right
-
360 ((BltInfo
->DestRect
.right
- BltInfo
->DestRect
.left
) & 31);
361 SourceY
= BltInfo
->SourcePoint
.y
;
365 if (BltInfo
->PatternSurface
)
367 PatternY
= (BltInfo
->DestRect
.top
+ BltInfo
->BrushOrigin
.y
) %
368 BltInfo
->PatternSurface
->sizlBitmap
.cy
;
372 /* FIXME: Shouldn't it be expanded? */
373 Pattern
= BltInfo
->Brush
->iSolidColor
;
377 for (DestY
= BltInfo
->DestRect
.top
; DestY
< BltInfo
->DestRect
.bottom
; DestY
++)
379 DestX
= BltInfo
->DestRect
.left
;
380 SourceX
= BltInfo
->SourcePoint
.x
;
382 (PBYTE
)BltInfo
->DestSurface
->pvScan0
+
383 (BltInfo
->DestRect
.left
>> 3) +
384 DestY
* BltInfo
->DestSurface
->lDelta
);
389 /* FIXME: This case is completely untested!!! */
391 Dest
= *((PBYTE
)DestBits
);
392 NoBits
= 31 - (DestX
& 31);
397 /* FIXME: This is incorrect! */
398 for (Index
= 31 - NoBits
; Index
>= 0; Index
++)
399 Source
|= (DIB_GetSource(SourceSurf
, SourceX
+ Index
, SourceY
, ColorTranslation
) << (31 - Index
));
402 if (BltInfo
->PatternSurface
)
405 for (k
= 31 - NoBits
; k
>= 0; k
++)
406 Pattern
|= (DIB_GetSource(PatternObj
, (X
+ BrushOrigin
.x
+ k
) % PatternWidth
, PatternY
, BltInfo
->XlatePatternToDest
) << (31 - k
));
409 Dest
= DIB_DoRop(Rop4
, Dest
, Source
, Pattern
);
410 Dest
&= ~((1 << (31 - NoBits
)) - 1);
411 Dest
|= *((PBYTE
)DestBits
) & ((1 << (31 - NoBits
)) - 1);
420 for (; DestX
< RoundedRight
; DestX
+= 32, DestBits
++, SourceX
++)
427 for (Index
= 0; Index
< 8; Index
++)
429 Source
|= DIB_GetSource(BltInfo
->SourceSurface
, SourceX
+ Index
, SourceY
, BltInfo
->XlateSourceToDest
) << (7 - Index
);
430 Source
|= DIB_GetSource(BltInfo
->SourceSurface
, SourceX
+ Index
+ 8, SourceY
, BltInfo
->XlateSourceToDest
) << (8 + (7 - Index
));
431 Source
|= DIB_GetSource(BltInfo
->SourceSurface
, SourceX
+ Index
+ 16, SourceY
, BltInfo
->XlateSourceToDest
) << (16 + (7 - Index
));
432 Source
|= DIB_GetSource(BltInfo
->SourceSurface
, SourceX
+ Index
+ 24, SourceY
, BltInfo
->XlateSourceToDest
) << (24 + (7 - Index
));
436 if (BltInfo
->PatternSurface
)
439 for (Index
= 0; Index
< 8; Index
++)
441 Pattern
|= DIB_GetSource(BltInfo
->PatternSurface
, (DestX
+ BltInfo
->BrushOrigin
.x
+ Index
) % BltInfo
->PatternSurface
->sizlBitmap
.cx
, PatternY
, BltInfo
->XlatePatternToDest
) << (7 - Index
);
442 Pattern
|= DIB_GetSource(BltInfo
->PatternSurface
, (DestX
+ BltInfo
->BrushOrigin
.x
+ Index
+ 8) % BltInfo
->PatternSurface
->sizlBitmap
.cx
, PatternY
, BltInfo
->XlatePatternToDest
) << (8 + (7 - Index
));
443 Pattern
|= DIB_GetSource(BltInfo
->PatternSurface
, (DestX
+ BltInfo
->BrushOrigin
.x
+ Index
+ 16) % BltInfo
->PatternSurface
->sizlBitmap
.cx
, PatternY
, BltInfo
->XlatePatternToDest
) << (16 + (7 - Index
));
444 Pattern
|= DIB_GetSource(BltInfo
->PatternSurface
, (DestX
+ BltInfo
->BrushOrigin
.x
+ Index
+ 24) % BltInfo
->PatternSurface
->sizlBitmap
.cx
, PatternY
, BltInfo
->XlatePatternToDest
) << (24 + (7 - Index
));
448 *DestBits
= DIB_DoRop(BltInfo
->Rop4
, Dest
, Source
, Pattern
);
451 if (DestX
< BltInfo
->DestRect
.right
)
454 for (; DestX
< BltInfo
->DestRect
.right
; DestX
++, SourceX
++)
457 Dest
= DIB_1BPP_GetPixel(BltInfo
->DestSurface
, DestX
, DestY
);
461 Source
= DIB_GetSource(BltInfo
->SourceSurface
, SourceX
, SourceY
, BltInfo
->XlateSourceToDest
);
464 if (BltInfo
->PatternSurface
)
466 Pattern
= DIB_GetSource(BltInfo
->PatternSurface
, (DestX
+ BltInfo
->BrushOrigin
.x
) % BltInfo
->PatternSurface
->sizlBitmap
.cx
, PatternY
, BltInfo
->XlatePatternToDest
);
469 DIB_1BPP_PutPixel(BltInfo
->DestSurface
, DestX
, DestY
, DIB_DoRop(BltInfo
->Rop4
, Dest
, Source
, Pattern
) & 0xF);
475 if (BltInfo
->PatternSurface
)
478 PatternY
%= BltInfo
->PatternSurface
->sizlBitmap
.cy
;
485 /* BitBlt Optimize */
487 DIB_1BPP_ColorFill(SURFOBJ
* DestSurface
, RECTL
* DestRect
, ULONG color
)
491 for (DestY
= DestRect
->top
; DestY
< DestRect
->bottom
; DestY
++)
493 DIB_1BPP_HLine(DestSurface
, DestRect
->left
, DestRect
->right
, DestY
, color
);
499 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
501 BOOLEAN
DIB_1BPP_StretchBlt(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
502 RECTL
* DestRect
, RECTL
*SourceRect
,
503 POINTL
* MaskOrigin
, POINTL BrushOrigin
,
504 CLIPOBJ
*ClipRegion
, XLATEOBJ
*ColorTranslation
,
517 SrcSizeY
= SourceRect
->bottom
- SourceRect
->top
;
518 SrcSizeX
= SourceRect
->right
- SourceRect
->left
;
520 DesSizeY
= DestRect
->bottom
- DestRect
->top
;
521 DesSizeX
= DestRect
->right
- DestRect
->left
;
523 switch(SourceSurf
->iBitmapFormat
)
526 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
527 /* This is a reference implementation, it hasn't been optimized for speed */
529 for (DesY
=DestRect
->top
; DesY
<DestRect
->bottom
; DesY
++)
531 sy
= (((DesY
- DestRect
->top
) * SrcSizeY
) / DesSizeY
) + SourceRect
->top
;
533 for (DesX
=DestRect
->left
; DesX
<DestRect
->right
; DesX
++)
535 sx
= (((DesX
- DestRect
->left
) * SrcSizeX
) / DesSizeX
) + SourceRect
->left
;
537 color
= DIB_1BPP_GetPixel(SourceSurf
, sx
, sy
);
538 DIB_1BPP_PutPixel(DestSurf
, DesX
, DesY
, XLATEOBJ_iXlate(ColorTranslation
, color
));
545 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
546 /* This is a reference implementation, it hasn't been optimized for speed */
548 for (DesY
=DestRect
->top
; DesY
<DestRect
->bottom
; DesY
++)
550 sy
= (((DesY
- DestRect
->top
) * SrcSizeY
) / DesSizeY
) + SourceRect
->top
;
552 for (DesX
=DestRect
->left
; DesX
<DestRect
->right
; DesX
++)
554 sx
= (((DesX
- DestRect
->left
) * SrcSizeX
) / DesSizeX
) + SourceRect
->left
;
555 color
= DIB_4BPP_GetPixel(SourceSurf
, sx
, sy
);
556 DIB_1BPP_PutPixel(DestSurf
, DesX
, DesY
, XLATEOBJ_iXlate(ColorTranslation
, color
));
562 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
563 /* This is a reference implementation, it hasn't been optimized for speed */
565 for (DesY
=DestRect
->top
; DesY
<DestRect
->bottom
; DesY
++)
567 sy
= (((DesY
- DestRect
->top
) * SrcSizeY
) / DesSizeY
) + SourceRect
->top
;
569 for (DesX
=DestRect
->left
; DesX
<DestRect
->right
; DesX
++)
571 sx
= (((DesX
- DestRect
->left
) * SrcSizeX
) / DesSizeX
) + SourceRect
->left
;
572 color
= DIB_8BPP_GetPixel(SourceSurf
, sx
, sy
);
573 DIB_1BPP_PutPixel(DestSurf
, DesX
, DesY
, XLATEOBJ_iXlate(ColorTranslation
, color
));
579 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
580 /* This is a reference implementation, it hasn't been optimized for speed */
582 for (DesY
=DestRect
->top
; DesY
<DestRect
->bottom
; DesY
++)
584 sy
= (((DesY
- DestRect
->top
) * SrcSizeY
) / DesSizeY
) + SourceRect
->top
;
586 for (DesX
=DestRect
->left
; DesX
<DestRect
->right
; DesX
++)
588 sx
= (((DesX
- DestRect
->left
) * SrcSizeX
) / DesSizeX
) + SourceRect
->left
;
589 color
= DIB_16BPP_GetPixel(SourceSurf
, sx
, sy
);
590 DIB_1BPP_PutPixel(DestSurf
, DesX
, DesY
, XLATEOBJ_iXlate(ColorTranslation
, color
));
596 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
597 /* This is a reference implementation, it hasn't been optimized for speed */
599 for (DesY
=DestRect
->top
; DesY
<DestRect
->bottom
; DesY
++)
601 sy
= (((DesY
- DestRect
->top
) * SrcSizeY
) / DesSizeY
) + SourceRect
->top
;
603 for (DesX
=DestRect
->left
; DesX
<DestRect
->right
; DesX
++)
605 sx
= (((DesX
- DestRect
->left
) * SrcSizeX
) / DesSizeX
) + SourceRect
->left
;
606 color
= DIB_24BPP_GetPixel(SourceSurf
, sx
, sy
);
607 DIB_1BPP_PutPixel(DestSurf
, DesX
, DesY
, XLATEOBJ_iXlate(ColorTranslation
, color
));
613 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
614 /* This is a reference implementation, it hasn't been optimized for speed */
616 for (DesY
=DestRect
->top
; DesY
<DestRect
->bottom
; DesY
++)
618 sy
= (((DesY
- DestRect
->top
) * SrcSizeY
) / DesSizeY
) + SourceRect
->top
;
620 for (DesX
=DestRect
->left
; DesX
<DestRect
->right
; DesX
++)
622 sx
= (((DesX
- DestRect
->left
) * SrcSizeX
) / DesSizeX
) + SourceRect
->left
;
623 color
= DIB_32BPP_GetPixel(SourceSurf
, sx
, sy
);
624 DIB_1BPP_PutPixel(DestSurf
, DesX
, DesY
, XLATEOBJ_iXlate(ColorTranslation
, color
));
630 //DPRINT1("DIB_1BPP_StretchBlt: Unhandled Source BPP: %u\n", BitsPerFormat(SourceSurf->iBitmapFormat));
638 DIB_1BPP_TransparentBlt(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
639 RECTL
* DestRect
, POINTL
*SourcePoint
,
640 XLATEOBJ
*ColorTranslation
, ULONG iTransColor
)
646 DIB_1BPP_AlphaBlend(SURFOBJ
* Dest
, SURFOBJ
* Source
, RECTL
* DestRect
,
647 RECTL
* SourceRect
, CLIPOBJ
* ClipRegion
,
648 XLATEOBJ
* ColorTranslation
, BLENDOBJ
* BlendObj
)