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.
27 DIB_8BPP_PutPixel(SURFOBJ
*SurfObj
, LONG x
, LONG y
, ULONG c
)
29 PBYTE byteaddr
= (PBYTE
)SurfObj
->pvScan0
+ y
* SurfObj
->lDelta
+ x
;
35 DIB_8BPP_GetPixel(SURFOBJ
*SurfObj
, LONG x
, LONG y
)
37 PBYTE byteaddr
= (PBYTE
)SurfObj
->pvScan0
+ y
* SurfObj
->lDelta
+ x
;
39 return (ULONG
)(*byteaddr
);
43 DIB_8BPP_HLine(SURFOBJ
*SurfObj
, LONG x1
, LONG x2
, LONG y
, ULONG c
)
45 memset((PBYTE
)SurfObj
->pvScan0
+ y
* SurfObj
->lDelta
+ x1
, (BYTE
) c
, x2
- x1
);
49 DIB_8BPP_VLine(SURFOBJ
*SurfObj
, LONG x
, LONG y1
, LONG y2
, ULONG c
)
51 PBYTE byteaddr
= (PBYTE
)SurfObj
->pvScan0
+ y1
* SurfObj
->lDelta
;
52 PBYTE addr
= byteaddr
+ x
;
53 LONG lDelta
= SurfObj
->lDelta
;
64 DIB_8BPP_BitBltSrcCopy(PBLTINFO BltInfo
)
66 LONG i
, j
, sx
, sy
, xColor
, f1
;
67 PBYTE SourceBits
, DestBits
, SourceLine
, DestLine
;
68 PBYTE SourceBits_4BPP
, SourceLine_4BPP
;
70 DestBits
= (PBYTE
)BltInfo
->DestSurface
->pvScan0
+ (BltInfo
->DestRect
.top
* BltInfo
->DestSurface
->lDelta
) + BltInfo
->DestRect
.left
;
72 switch(BltInfo
->SourceSurface
->iBitmapFormat
)
75 sx
= BltInfo
->SourcePoint
.x
;
76 sy
= BltInfo
->SourcePoint
.y
;
78 for (j
=BltInfo
->DestRect
.top
; j
<BltInfo
->DestRect
.bottom
; j
++)
80 sx
= BltInfo
->SourcePoint
.x
;
81 for (i
=BltInfo
->DestRect
.left
; i
<BltInfo
->DestRect
.right
; i
++)
83 if(DIB_1BPP_GetPixel(BltInfo
->SourceSurface
, sx
, sy
) == 0)
85 DIB_8BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, 0));
87 DIB_8BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, 1));
96 SourceBits_4BPP
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + (BltInfo
->SourcePoint
.x
>> 1);
98 for (j
=BltInfo
->DestRect
.top
; j
<BltInfo
->DestRect
.bottom
; j
++)
100 SourceLine_4BPP
= SourceBits_4BPP
;
101 sx
= BltInfo
->SourcePoint
.x
;
104 for (i
=BltInfo
->DestRect
.left
; i
<BltInfo
->DestRect
.right
; i
++)
106 xColor
= XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
,
107 (*SourceLine_4BPP
& altnotmask
[f1
]) >> (4 * (1 - f1
)));
108 DIB_8BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, xColor
);
109 if(f1
== 1) { SourceLine_4BPP
++; f1
= 0; } else { f1
= 1; }
113 SourceBits_4BPP
+= BltInfo
->SourceSurface
->lDelta
;
118 if (NULL
== BltInfo
->XlateSourceToDest
|| 0 != (BltInfo
->XlateSourceToDest
->flXlate
& XO_TRIVIAL
))
120 if (BltInfo
->DestRect
.top
< BltInfo
->SourcePoint
.y
)
122 SourceBits
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + BltInfo
->SourcePoint
.x
;
123 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
125 RtlMoveMemory(DestBits
, SourceBits
, BltInfo
->DestRect
.right
- BltInfo
->DestRect
.left
);
126 SourceBits
+= BltInfo
->SourceSurface
->lDelta
;
127 DestBits
+= BltInfo
->DestSurface
->lDelta
;
132 SourceBits
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ ((BltInfo
->SourcePoint
.y
+ BltInfo
->DestRect
.bottom
- BltInfo
->DestRect
.top
- 1) * BltInfo
->SourceSurface
->lDelta
) + BltInfo
->SourcePoint
.x
;
133 DestBits
= (PBYTE
)BltInfo
->DestSurface
->pvScan0
+ ((BltInfo
->DestRect
.bottom
- 1) * BltInfo
->DestSurface
->lDelta
) + BltInfo
->DestRect
.left
;
134 for (j
= BltInfo
->DestRect
.bottom
- 1; BltInfo
->DestRect
.top
<= j
; j
--)
136 RtlMoveMemory(DestBits
, SourceBits
, BltInfo
->DestRect
.right
- BltInfo
->DestRect
.left
);
137 SourceBits
-= BltInfo
->SourceSurface
->lDelta
;
138 DestBits
-= BltInfo
->DestSurface
->lDelta
;
144 if (BltInfo
->DestRect
.top
< BltInfo
->SourcePoint
.y
)
146 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + BltInfo
->SourcePoint
.x
;
148 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
150 SourceBits
= SourceLine
;
152 for (i
=BltInfo
->DestRect
.left
; i
<BltInfo
->DestRect
.right
; i
++)
154 *DestBits
++ = XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, *SourceBits
++);
156 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
157 DestLine
+= BltInfo
->DestSurface
->lDelta
;
162 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ ((BltInfo
->SourcePoint
.y
+ BltInfo
->DestRect
.bottom
- BltInfo
->DestRect
.top
- 1) * BltInfo
->SourceSurface
->lDelta
) + BltInfo
->SourcePoint
.x
;
163 DestLine
= (PBYTE
)BltInfo
->DestSurface
->pvScan0
+ ((BltInfo
->DestRect
.bottom
- 1) * BltInfo
->DestSurface
->lDelta
) + BltInfo
->DestRect
.left
;
164 for (j
= BltInfo
->DestRect
.bottom
- 1; BltInfo
->DestRect
.top
<= j
; j
--)
166 SourceBits
= SourceLine
;
168 for (i
=BltInfo
->DestRect
.left
; i
<BltInfo
->DestRect
.right
; i
++)
170 *DestBits
++ = XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, *SourceBits
++);
172 SourceLine
-= BltInfo
->SourceSurface
->lDelta
;
173 DestLine
-= BltInfo
->DestSurface
->lDelta
;
180 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + 2 * BltInfo
->SourcePoint
.x
;
183 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
185 SourceBits
= SourceLine
;
188 for (i
= BltInfo
->DestRect
.left
; i
< BltInfo
->DestRect
.right
; i
++)
190 xColor
= *((PWORD
) SourceBits
);
191 *DestBits
= XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, xColor
);
196 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
197 DestLine
+= BltInfo
->DestSurface
->lDelta
;
202 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + 3 * BltInfo
->SourcePoint
.x
;
205 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
207 SourceBits
= SourceLine
;
210 for (i
= BltInfo
->DestRect
.left
; i
< BltInfo
->DestRect
.right
; i
++)
212 xColor
= (*(SourceBits
+ 2) << 0x10) +
213 (*(SourceBits
+ 1) << 0x08) +
215 *DestBits
= XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, xColor
);
220 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
221 DestLine
+= BltInfo
->DestSurface
->lDelta
;
226 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + 4 * BltInfo
->SourcePoint
.x
;
229 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
231 SourceBits
= SourceLine
;
234 for (i
= BltInfo
->DestRect
.left
; i
< BltInfo
->DestRect
.right
; i
++)
236 xColor
= *((PDWORD
) SourceBits
);
237 *DestBits
= XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, xColor
);
242 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
243 DestLine
+= BltInfo
->DestSurface
->lDelta
;
248 DPRINT1("DIB_8BPP_Bitblt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo
->SourceSurface
->iBitmapFormat
));
255 /* BitBlt Optimize */
257 DIB_8BPP_ColorFill(SURFOBJ
* DestSurface
, RECTL
* DestRect
, ULONG color
)
260 for (DestY
= DestRect
->top
; DestY
< DestRect
->bottom
; DestY
++)
262 DIB_8BPP_HLine(DestSurface
, DestRect
->left
, DestRect
->right
, DestY
, color
);
270 DIB_8BPP_TransparentBlt(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
271 RECTL
* DestRect
, RECTL
*SourceRect
,
272 XLATEOBJ
*ColorTranslation
, ULONG iTransColor
)
274 ULONG RoundedRight
, X
, Y
, SourceX
= 0, SourceY
= 0, Source
, wd
, Dest
;
282 DstHeight
= DestRect
->bottom
- DestRect
->top
;
283 DstWidth
= DestRect
->right
- DestRect
->left
;
284 SrcHeight
= SourceRect
->bottom
- SourceRect
->top
;
285 SrcWidth
= SourceRect
->right
- SourceRect
->left
;
287 RoundedRight
= DestRect
->right
- ((DestRect
->right
- DestRect
->left
) & 0x3);
288 DestBits
= (ULONG
*)((PBYTE
)DestSurf
->pvScan0
+ DestRect
->left
+
289 (DestRect
->top
* DestSurf
->lDelta
));
290 wd
= DestSurf
->lDelta
- (DestRect
->right
- DestRect
->left
);
292 for(Y
= DestRect
->top
; Y
< DestRect
->bottom
; Y
++)
294 DestBits
= (ULONG
*)((PBYTE
)DestSurf
->pvScan0
+ DestRect
->left
+
295 (Y
* DestSurf
->lDelta
));
296 SourceY
= SourceRect
->top
+(Y
- DestRect
->top
) * SrcHeight
/ DstHeight
;
297 for (X
= DestRect
->left
; X
< RoundedRight
; X
+= 4, DestBits
++)
301 SourceX
= SourceRect
->left
+(X
- DestRect
->left
) * SrcWidth
/ DstWidth
;
302 if (SourceX
>= 0 && SourceY
>= 0 &&
303 SourceSurf
->sizlBitmap
.cx
> SourceX
&& SourceSurf
->sizlBitmap
.cy
> SourceY
)
305 Source
= DIB_GetSourceIndex(SourceSurf
, SourceX
, SourceY
);
306 if(Source
!= iTransColor
)
309 Dest
|= (XLATEOBJ_iXlate(ColorTranslation
, Source
) & 0xFF);
313 SourceX
= SourceRect
->left
+(X
+1 - DestRect
->left
) * SrcWidth
/ DstWidth
;
314 if (SourceX
>= 0 && SourceY
>= 0 &&
315 SourceSurf
->sizlBitmap
.cx
> SourceX
&& SourceSurf
->sizlBitmap
.cy
> SourceY
)
317 Source
= DIB_GetSourceIndex(SourceSurf
, SourceX
, SourceY
);
318 if(Source
!= iTransColor
)
321 Dest
|= ((XLATEOBJ_iXlate(ColorTranslation
, Source
) << 8) & 0xFF00);
325 SourceX
= SourceRect
->left
+(X
+2 - DestRect
->left
) * SrcWidth
/ DstWidth
;
326 if (SourceX
>= 0 && SourceY
>= 0 &&
327 SourceSurf
->sizlBitmap
.cx
> SourceX
&& SourceSurf
->sizlBitmap
.cy
> SourceY
)
329 Source
= DIB_GetSourceIndex(SourceSurf
, SourceX
, SourceY
);
330 if(Source
!= iTransColor
)
333 Dest
|= ((XLATEOBJ_iXlate(ColorTranslation
, Source
) << 16) & 0xFF0000);
337 SourceX
= SourceRect
->left
+(X
+3 - DestRect
->left
) * SrcWidth
/ DstWidth
;
338 if (SourceX
>= 0 && SourceY
>= 0 &&
339 SourceSurf
->sizlBitmap
.cx
> SourceX
&& SourceSurf
->sizlBitmap
.cy
> SourceY
)
341 Source
= DIB_GetSourceIndex(SourceSurf
, SourceX
, SourceY
);
342 if(Source
!= iTransColor
)
345 Dest
|= ((XLATEOBJ_iXlate(ColorTranslation
, Source
) << 24) & 0xFF000000);
352 if(X
< DestRect
->right
)
354 for (; X
< DestRect
->right
; X
++)
356 SourceX
= SourceRect
->left
+(X
- DestRect
->left
) * SrcWidth
/ DstWidth
;
357 if (SourceX
>= 0 && SourceY
>= 0 &&
358 SourceSurf
->sizlBitmap
.cx
> SourceX
&& SourceSurf
->sizlBitmap
.cy
> SourceY
)
360 Source
= DIB_GetSourceIndex(SourceSurf
, SourceX
, SourceY
);
361 if(Source
!= iTransColor
)
363 *((BYTE
*)DestBits
) = (BYTE
)(XLATEOBJ_iXlate(ColorTranslation
, Source
) & 0xFF);
366 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ 1);
393 static __inline UCHAR
396 return (val
> 255) ? 255 : val
;
400 DIB_8BPP_AlphaBlend(SURFOBJ
* Dest
, SURFOBJ
* Source
, RECTL
* DestRect
,
401 RECTL
* SourceRect
, CLIPOBJ
* ClipRegion
,
402 XLATEOBJ
* ColorTranslation
, BLENDOBJ
* BlendObj
)
404 INT Rows
, Cols
, SrcX
, SrcY
;
407 BLENDFUNCTION BlendFunc
;
408 register NICEPIXEL32 DstPixel32
;
409 register NICEPIXEL32 SrcPixel32
;
410 register NICEPIXEL16 SrcPixel16
;
413 XLATEOBJ
* SrcXlateObj
;
415 DPRINT("DIB_8BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
416 SourceRect
->left
, SourceRect
->top
, SourceRect
->right
, SourceRect
->bottom
,
417 DestRect
->left
, DestRect
->top
, DestRect
->right
, DestRect
->bottom
);
419 ASSERT(DestRect
->bottom
- DestRect
->top
== SourceRect
->bottom
- SourceRect
->top
&&
420 DestRect
->right
- DestRect
->left
== SourceRect
->right
- SourceRect
->left
);
422 BlendFunc
= BlendObj
->BlendFunction
;
423 if (BlendFunc
.BlendOp
!= AC_SRC_OVER
)
425 DPRINT1("BlendOp != AC_SRC_OVER\n");
428 if (BlendFunc
.BlendFlags
!= 0)
430 DPRINT1("BlendFlags != 0\n");
433 if ((BlendFunc
.AlphaFormat
& ~AC_SRC_ALPHA
) != 0)
435 DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc
.AlphaFormat
);
438 if ((BlendFunc
.AlphaFormat
& AC_SRC_ALPHA
) != 0 &&
439 BitsPerFormat(Source
->iBitmapFormat
) != 32)
441 DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n");
444 if (!ColorTranslation
)
446 DPRINT1("ColorTranslation must not be NULL!\n");
450 XlateGDI
= ObjToGDI(ColorTranslation
, XLATE
);
451 SrcXlateObj
= IntEngCreateXlate(0, 0, XlateGDI
->SourcePal
, XlateGDI
->DestPal
);
455 DPRINT1("IntEngCreateXlate failed\n");
459 Dst
= (PUCHAR
)((ULONG_PTR
)Dest
->pvScan0
+ (DestRect
->top
* Dest
->lDelta
) +
461 DstDelta
= Dest
->lDelta
- (DestRect
->right
- DestRect
->left
);
462 SrcBpp
= BitsPerFormat(Source
->iBitmapFormat
);
464 Rows
= DestRect
->bottom
- DestRect
->top
;
465 SrcY
= SourceRect
->top
;
468 Cols
= DestRect
->right
- DestRect
->left
;
469 SrcX
= SourceRect
->left
;
474 SrcPixel16
.us
= DIB_GetSource(Source
, SrcX
++, SrcY
, ColorTranslation
);
475 SrcPixel32
.col
.red
= (SrcPixel16
.col
.red
<< 3) | (SrcPixel16
.col
.red
>> 2);
476 SrcPixel32
.col
.green
= (SrcPixel16
.col
.green
<< 2) | (SrcPixel16
.col
.green
>> 4);
477 SrcPixel32
.col
.blue
= (SrcPixel16
.col
.blue
<< 3) | (SrcPixel16
.col
.blue
>> 2);
481 SrcPixel32
.ul
= DIB_GetSourceIndex(Source
, SrcX
++, SrcY
);
483 SrcPixel32
.col
.red
= SrcPixel32
.col
.red
* BlendFunc
.SourceConstantAlpha
/ 255;
484 SrcPixel32
.col
.green
= SrcPixel32
.col
.green
* BlendFunc
.SourceConstantAlpha
/ 255;
485 SrcPixel32
.col
.blue
= SrcPixel32
.col
.blue
* BlendFunc
.SourceConstantAlpha
/ 255;
486 SrcPixel32
.col
.alpha
= (SrcBpp
== 32) ? (SrcPixel32
.col
.alpha
* BlendFunc
.SourceConstantAlpha
/ 255) : BlendFunc
.SourceConstantAlpha
;
488 Alpha
= ((BlendFunc
.AlphaFormat
& AC_SRC_ALPHA
) != 0) ?
489 SrcPixel32
.col
.alpha
: BlendFunc
.SourceConstantAlpha
;
491 DstPixel32
.ul
= XLATEOBJ_iXlate(SrcXlateObj
, *Dst
);
492 SrcPixel32
.col
.red
= Clamp8(DstPixel32
.col
.red
* (255 - Alpha
) / 255 + SrcPixel32
.col
.red
);
493 SrcPixel32
.col
.green
= Clamp8(DstPixel32
.col
.green
* (255 - Alpha
) / 255 + SrcPixel32
.col
.green
);
494 SrcPixel32
.col
.blue
= Clamp8(DstPixel32
.col
.blue
* (255 - Alpha
) / 255 + SrcPixel32
.col
.blue
);
495 *Dst
++ = XLATEOBJ_iXlate(ColorTranslation
, SrcPixel32
.ul
);
497 Dst
= (PUCHAR
)((ULONG_PTR
)Dst
+ DstDelta
);
502 EngDeleteXlate(SrcXlateObj
);