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_24BPP_PutPixel(SURFOBJ
*SurfObj
, LONG x
, LONG y
, ULONG c
)
29 PBYTE addr
= (PBYTE
)SurfObj
->pvScan0
+ (y
* SurfObj
->lDelta
) + (x
<< 1) + x
;
30 *(PUSHORT
)(addr
) = c
& 0xFFFF;
31 *(addr
+ 2) = (c
>> 16) & 0xFF;
35 DIB_24BPP_GetPixel(SURFOBJ
*SurfObj
, LONG x
, LONG y
)
37 PBYTE addr
= (PBYTE
)SurfObj
->pvScan0
+ y
* SurfObj
->lDelta
+ (x
<< 1) + x
;
38 return *(PUSHORT
)(addr
) + (*(addr
+ 2) << 16);
44 DIB_24BPP_VLine(SURFOBJ
*SurfObj
, LONG x
, LONG y1
, LONG y2
, ULONG c
)
46 PBYTE addr
= (PBYTE
)SurfObj
->pvScan0
+ y1
* SurfObj
->lDelta
+ (x
<< 1) + x
;
47 LONG lDelta
= SurfObj
->lDelta
;
51 *(PUSHORT
)(addr
) = c
& 0xFFFF;
52 *(addr
+ 2) = c
>> 16;
59 DIB_24BPP_BitBltSrcCopy(PBLTINFO BltInfo
)
61 LONG i
, j
, sx
, sy
, xColor
, f1
;
62 PBYTE SourceBits
, DestBits
, SourceLine
, DestLine
;
63 PBYTE SourceBits_4BPP
, SourceLine_4BPP
;
64 PWORD SourceBits_16BPP
, SourceLine_16BPP
;
66 DestBits
= (PBYTE
)BltInfo
->DestSurface
->pvScan0
+ (BltInfo
->DestRect
.top
* BltInfo
->DestSurface
->lDelta
) + BltInfo
->DestRect
.left
* 3;
68 switch(BltInfo
->SourceSurface
->iBitmapFormat
)
71 sx
= BltInfo
->SourcePoint
.x
;
72 sy
= BltInfo
->SourcePoint
.y
;
74 for (j
=BltInfo
->DestRect
.top
; j
<BltInfo
->DestRect
.bottom
; j
++)
76 sx
= BltInfo
->SourcePoint
.x
;
77 for (i
=BltInfo
->DestRect
.left
; i
<BltInfo
->DestRect
.right
; i
++)
79 if(DIB_1BPP_GetPixel(BltInfo
->SourceSurface
, sx
, sy
) == 0)
81 DIB_24BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, 0));
83 DIB_24BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, 1));
92 SourceBits_4BPP
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + (BltInfo
->SourcePoint
.x
>> 1);
94 for (j
=BltInfo
->DestRect
.top
; j
<BltInfo
->DestRect
.bottom
; j
++)
96 SourceLine_4BPP
= SourceBits_4BPP
;
98 sx
= BltInfo
->SourcePoint
.x
;
101 for (i
=BltInfo
->DestRect
.left
; i
<BltInfo
->DestRect
.right
; i
++)
103 xColor
= XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
,
104 (*SourceLine_4BPP
& altnotmask
[f1
]) >> (4 * (1 - f1
)));
105 *DestLine
++ = xColor
& 0xff;
106 *(PWORD
)DestLine
= xColor
>> 8;
108 if(f1
== 1) { SourceLine_4BPP
++; f1
= 0; } else { f1
= 1; }
112 SourceBits_4BPP
+= BltInfo
->SourceSurface
->lDelta
;
113 DestBits
+= BltInfo
->DestSurface
->lDelta
;
118 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + BltInfo
->SourcePoint
.x
;
121 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
123 SourceBits
= SourceLine
;
126 for (i
= BltInfo
->DestRect
.left
; i
< BltInfo
->DestRect
.right
; i
++)
128 xColor
= XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, *SourceBits
);
129 *DestBits
= xColor
& 0xff;
130 *(PWORD
)(DestBits
+ 1) = xColor
>> 8;
135 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
136 DestLine
+= BltInfo
->DestSurface
->lDelta
;
141 SourceBits_16BPP
= (PWORD
)((PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + 2 * BltInfo
->SourcePoint
.x
);
143 for (j
=BltInfo
->DestRect
.top
; j
<BltInfo
->DestRect
.bottom
; j
++)
145 SourceLine_16BPP
= SourceBits_16BPP
;
148 for (i
=BltInfo
->DestRect
.left
; i
<BltInfo
->DestRect
.right
; i
++)
150 xColor
= XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, *SourceLine_16BPP
);
151 *DestLine
++ = xColor
& 0xff;
152 *(PWORD
)DestLine
= xColor
>> 8;
157 SourceBits_16BPP
= (PWORD
)((PBYTE
)SourceBits_16BPP
+ BltInfo
->SourceSurface
->lDelta
);
158 DestBits
+= BltInfo
->DestSurface
->lDelta
;
163 if (NULL
== BltInfo
->XlateSourceToDest
|| 0 != (BltInfo
->XlateSourceToDest
->flXlate
& XO_TRIVIAL
))
165 if (BltInfo
->DestRect
.top
< BltInfo
->SourcePoint
.y
)
167 SourceBits
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + 3 * BltInfo
->SourcePoint
.x
;
168 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
170 RtlMoveMemory(DestBits
, SourceBits
, 3 * (BltInfo
->DestRect
.right
- BltInfo
->DestRect
.left
));
171 SourceBits
+= BltInfo
->SourceSurface
->lDelta
;
172 DestBits
+= BltInfo
->DestSurface
->lDelta
;
177 SourceBits
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ ((BltInfo
->SourcePoint
.y
+ BltInfo
->DestRect
.bottom
- BltInfo
->DestRect
.top
- 1) * BltInfo
->SourceSurface
->lDelta
) + 3 * BltInfo
->SourcePoint
.x
;
178 DestBits
= (PBYTE
)BltInfo
->DestSurface
->pvScan0
+ ((BltInfo
->DestRect
.bottom
- 1) * BltInfo
->DestSurface
->lDelta
) + 3 * BltInfo
->DestRect
.left
;
179 for (j
= BltInfo
->DestRect
.bottom
- 1; BltInfo
->DestRect
.top
<= j
; j
--)
181 RtlMoveMemory(DestBits
, SourceBits
, 3 * (BltInfo
->DestRect
.right
- BltInfo
->DestRect
.left
));
182 SourceBits
-= BltInfo
->SourceSurface
->lDelta
;
183 DestBits
-= BltInfo
->DestSurface
->lDelta
;
189 sx
= BltInfo
->SourcePoint
.x
;
190 sy
= BltInfo
->SourcePoint
.y
;
192 for (j
=BltInfo
->DestRect
.top
; j
<BltInfo
->DestRect
.bottom
; j
++)
194 sx
= BltInfo
->SourcePoint
.x
;
195 for (i
=BltInfo
->DestRect
.left
; i
<BltInfo
->DestRect
.right
; i
++)
197 DWORD pixel
= DIB_24BPP_GetPixel(BltInfo
->SourceSurface
, sx
, sy
);
198 DIB_24BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, pixel
));
207 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + 4 * BltInfo
->SourcePoint
.x
;
210 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
212 SourceBits
= SourceLine
;
215 for (i
= BltInfo
->DestRect
.left
; i
< BltInfo
->DestRect
.right
; i
++)
217 xColor
= XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, *((PDWORD
) SourceBits
));
218 *DestBits
= xColor
& 0xff;
219 *(PWORD
)(DestBits
+ 1) = xColor
>> 8;
224 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
225 DestLine
+= BltInfo
->DestSurface
->lDelta
;
230 DbgPrint("DIB_24BPP_Bitblt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo
->SourceSurface
->iBitmapFormat
));
238 DIB_24BPP_BitBlt(PBLTINFO BltInfo
)
241 ULONG SourceX
, SourceY
;
243 ULONG Dest
, Source
= 0, Pattern
= 0;
248 UsesSource
= ROP4_USES_SOURCE(BltInfo
->Rop4
);
249 UsesPattern
= ROP4_USES_PATTERN(BltInfo
->Rop4
);
251 SourceY
= BltInfo
->SourcePoint
.y
;
253 (PBYTE
)BltInfo
->DestSurface
->pvScan0
+
254 (BltInfo
->DestRect
.left
<< 1) + BltInfo
->DestRect
.left
+
255 BltInfo
->DestRect
.top
* BltInfo
->DestSurface
->lDelta
);
259 if (BltInfo
->PatternSurface
)
261 PatternY
= (BltInfo
->DestRect
.top
+ BltInfo
->BrushOrigin
.y
) %
262 BltInfo
->PatternSurface
->sizlBitmap
.cy
;
266 Pattern
= BltInfo
->Brush
->iSolidColor
;
270 for (DestY
= BltInfo
->DestRect
.top
; DestY
< BltInfo
->DestRect
.bottom
; DestY
++)
272 SourceX
= BltInfo
->SourcePoint
.x
;
274 for (DestX
= BltInfo
->DestRect
.left
; DestX
< BltInfo
->DestRect
.right
; DestX
++, DestBits
+= 3, SourceX
++)
276 Dest
= *((PUSHORT
)DestBits
) + (*(DestBits
+ 2) << 16);
280 Source
= DIB_GetSource(BltInfo
->SourceSurface
, SourceX
, SourceY
, BltInfo
->XlateSourceToDest
);
283 if (BltInfo
->PatternSurface
)
285 Pattern
= DIB_GetSource(BltInfo
->PatternSurface
, (DestX
+ BltInfo
->BrushOrigin
.x
) % BltInfo
->PatternSurface
->sizlBitmap
.cx
, PatternY
, BltInfo
->XlatePatternToDest
);
288 Dest
= DIB_DoRop(BltInfo
->Rop4
, Dest
, Source
, Pattern
) & 0xFFFFFF;
289 *(PUSHORT
)(DestBits
) = Dest
& 0xFFFF;
290 *(DestBits
+ 2) = Dest
>> 16;
294 if (BltInfo
->PatternSurface
)
297 PatternY
%= BltInfo
->PatternSurface
->sizlBitmap
.cy
;
299 DestBits
-= (BltInfo
->DestRect
.right
- BltInfo
->DestRect
.left
) * 3;
300 DestBits
+= BltInfo
->DestSurface
->lDelta
;
306 /* BitBlt Optimize */
308 DIB_24BPP_ColorFill(SURFOBJ
* DestSurface
, RECTL
* DestRect
, ULONG color
)
312 #if defined(_M_IX86) && !defined(_MSC_VER)
313 PBYTE xaddr
= (PBYTE
)DestSurface
->pvScan0
+ DestRect
->top
* DestSurface
->lDelta
+ (DestRect
->left
<< 1) + DestRect
->left
;
316 ULONG xCount
=DestRect
->right
- DestRect
->left
;
318 for (DestY
= DestRect
->top
; DestY
< DestRect
->bottom
; DestY
++)
322 xaddr
= (PBYTE
)((ULONG_PTR
)addr
+ DestSurface
->lDelta
);
326 /* For small fills, don't bother doing anything fancy */
329 *(PUSHORT
)(addr
) = color
;
331 *(addr
) = color
>> 16;
337 /* Align to 4-byte address */
338 while (0 != ((ULONG_PTR
) addr
& 0x3))
340 *(PUSHORT
)(addr
) = color
;
342 *(addr
) = color
>> 16;
346 /* If the color we need to fill with is 0ABC, then the final mem pattern
347 * (note little-endianness) would be:
349 * |C.B.A|C.B.A|C.B.A|C.B.A| <- pixel borders
350 * |C.B.A.C|B.A.C.B|A.C.B.A| <- ULONG borders
352 * So, taking endianness into account again, we need to fill with these
353 * ULONGs: CABC BCAB ABCA */
355 /* This is about 30% faster than the generic C code below */
356 __asm__
__volatile__ (
358 " andl $0xffffff, %%ecx\n" /* 0ABC */
359 " movl %%ecx, %%ebx\n" /* Construct BCAB in ebx */
361 " movl %%ecx, %%eax\n"
363 " orl %%eax, %%ebx\n"
364 " movl %%ecx, %%edx\n" /* Construct ABCA in edx */
366 " movl %%ecx, %%eax\n"
368 " orl %%eax, %%edx\n"
369 " movl %%ecx, %%eax\n" /* Construct CABC in eax */
371 " orl %%ecx, %%eax\n"
372 " movl %2, %%ecx\n" /* Load count */
374 " movl %3, %%edi\n" /* Load dest */
376 " movl %%eax, (%%edi)\n" /* Store 4 pixels, 12 bytes */
377 " movl %%ebx, 4(%%edi)\n"
378 " movl %%edx, 8(%%edi)\n"
384 : "m"(color
), "m"(Count
), "m"(addr
)
385 : "%eax", "%ebx", "%ecx", "%edx", "%edi");
386 Count
= Count
& 0x03;
389 *(PUSHORT
)(addr
) = color
;
391 *(addr
) = color
>> 16;
398 for (DestY
= DestRect
->top
; DestY
< DestRect
->bottom
; DestY
++)
400 DIB_24BPP_HLine(DestSurface
, DestRect
->left
, DestRect
->right
, DestY
, color
);
406 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
407 BOOLEAN
DIB_24BPP_StretchBlt(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
408 RECTL
* DestRect
, RECTL
*SourceRect
,
409 POINTL
* MaskOrigin
, POINTL BrushOrigin
,
410 CLIPOBJ
*ClipRegion
, XLATEOBJ
*ColorTranslation
,
434 DPRINT("DIB_24BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
435 BitsPerFormat(SourceSurf
->iBitmapFormat
), SourceRect
->left
, SourceRect
->top
, SourceRect
->right
, SourceRect
->bottom
,
436 DestRect
->left
, DestRect
->top
, DestRect
->right
, DestRect
->bottom
);
438 /* Calc the Zoom height of Source */
439 SrcSizeY
= SourceRect
->bottom
- SourceRect
->top
;
441 /* Calc the Zoom Width of Source */
442 SrcSizeX
= SourceRect
->right
- SourceRect
->left
;
444 /* Calc the Zoom height of Destinations */
445 DesSizeY
= DestRect
->bottom
- DestRect
->top
;
447 /* Calc the Zoom width of Destinations */
448 DesSizeX
= DestRect
->right
- DestRect
->left
;
450 /* Calc the zoom factor of source height */
451 SrcZoomYHight
= SrcSizeY
/ DesSizeY
;
452 SrcZoomYLow
= SrcSizeY
- (SrcZoomYHight
* DesSizeY
);
454 /* Calc the zoom factor of source width */
455 SrcZoomXHight
= SrcSizeX
/ DesSizeX
;
456 SrcZoomXLow
= SrcSizeX
- (SrcZoomXHight
* DesSizeX
);
460 sy
= SourceRect
->top
;
462 switch(SourceSurf
->iBitmapFormat
)
465 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
466 /* This is a reference implementation, it hasn't been optimized for speed */
468 for (DesY
=DestRect
->top
; DesY
<DestRect
->bottom
; DesY
++)
470 sx
= SourceRect
->left
;
473 for (DesX
=DestRect
->left
; DesX
<DestRect
->right
; DesX
++)
475 color
= XLATEOBJ_iXlate(ColorTranslation
,
476 DIB_1BPP_GetPixel(SourceSurf
, sx
, sy
));
478 DIB_24BPP_PutPixel(DestSurf
, DesX
, DesY
, color
);
481 sx_dec
+= SrcZoomXLow
;
482 if (sx_dec
>= sx_max
)
490 sy_dec
+= SrcZoomYLow
;
491 if (sy_dec
>= sy_max
)
501 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
502 /* This is a reference implementation, it hasn't been optimized for speed */
504 for (DesY
=DestRect
->top
; DesY
<DestRect
->bottom
; DesY
++)
506 sx
= SourceRect
->left
;
509 for (DesX
=DestRect
->left
; DesX
<DestRect
->right
; DesX
++)
511 color
= XLATEOBJ_iXlate(ColorTranslation
,
512 DIB_4BPP_GetPixel(SourceSurf
, sx
, sy
));
514 DIB_24BPP_PutPixel(DestSurf
, DesX
, DesY
, color
);
517 sx_dec
+= SrcZoomXLow
;
518 if (sx_dec
>= sx_max
)
526 sy_dec
+= SrcZoomYLow
;
527 if (sy_dec
>= sy_max
)
536 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
537 /* This is a reference implementation, it hasn't been optimized for speed */
539 for (DesY
=DestRect
->top
; DesY
<DestRect
->bottom
; DesY
++)
541 sx
= SourceRect
->left
;
544 for (DesX
=DestRect
->left
; DesX
<DestRect
->right
; DesX
++)
546 color
= XLATEOBJ_iXlate(ColorTranslation
,
547 DIB_8BPP_GetPixel(SourceSurf
, sx
, sy
));
549 DIB_24BPP_PutPixel(DestSurf
, DesX
, DesY
, color
);
552 sx_dec
+= SrcZoomXLow
;
553 if (sx_dec
>= sx_max
)
561 sy_dec
+= SrcZoomYLow
;
562 if (sy_dec
>= sy_max
)
571 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
572 /* This is a reference implementation, it hasn't been optimized for speed */
574 for (DesY
=DestRect
->top
; DesY
<DestRect
->bottom
; DesY
++)
576 sx
= SourceRect
->left
;
579 for (DesX
=DestRect
->left
; DesX
<DestRect
->right
; DesX
++)
581 color
= XLATEOBJ_iXlate(ColorTranslation
,
582 DIB_16BPP_GetPixel(SourceSurf
, sx
, sy
));
584 DIB_24BPP_PutPixel(DestSurf
, DesX
, DesY
, color
);
587 sx_dec
+= SrcZoomXLow
;
588 if (sx_dec
>= sx_max
)
596 sy_dec
+= SrcZoomYLow
;
597 if (sy_dec
>= sy_max
)
606 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
607 /* This is a reference implementation, it hasn't been optimized for speed */
609 for (DesY
=DestRect
->top
; DesY
<DestRect
->bottom
; DesY
++)
611 sx
= SourceRect
->left
;
614 for (DesX
=DestRect
->left
; DesX
<DestRect
->right
; DesX
++)
616 color
= XLATEOBJ_iXlate(ColorTranslation
,
617 DIB_24BPP_GetPixel(SourceSurf
, sx
, sy
));
619 DIB_24BPP_PutPixel(DestSurf
, DesX
, DesY
, color
);
622 sx_dec
+= SrcZoomXLow
;
623 if (sx_dec
>= sx_max
)
631 sy_dec
+= SrcZoomYLow
;
632 if (sy_dec
>= sy_max
)
641 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
642 /* This is a reference implementation, it hasn't been optimized for speed */
644 for (DesY
=DestRect
->top
; DesY
<DestRect
->bottom
; DesY
++)
646 sx
= SourceRect
->left
;
649 for (DesX
=DestRect
->left
; DesX
<DestRect
->right
; DesX
++)
651 color
= XLATEOBJ_iXlate(ColorTranslation
,
652 DIB_32BPP_GetPixel(SourceSurf
, sx
, sy
));
654 DIB_24BPP_PutPixel(DestSurf
, DesX
, DesY
, color
);
657 sx_dec
+= SrcZoomXLow
;
658 if (sx_dec
>= sx_max
)
666 sy_dec
+= SrcZoomYLow
;
667 if (sy_dec
>= sy_max
)
676 DPRINT1("DIB_24BPP_StretchBlt: Unhandled Source BPP: %u\n", BitsPerFormat(SourceSurf
->iBitmapFormat
));
684 DIB_24BPP_TransparentBlt(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
685 RECTL
* DestRect
, POINTL
*SourcePoint
,
686 XLATEOBJ
*ColorTranslation
, ULONG iTransColor
)
688 ULONG X
, Y
, SourceX
, SourceY
, Source
, wd
, Dest
;
691 SourceY
= SourcePoint
->y
;
692 DestBits
= (BYTE
*)((PBYTE
)DestSurf
->pvScan0
+
693 (DestRect
->left
* 3) +
694 DestRect
->top
* DestSurf
->lDelta
);
695 wd
= DestSurf
->lDelta
- ((DestRect
->right
- DestRect
->left
) * 3);
697 for(Y
= DestRect
->top
; Y
< DestRect
->bottom
; Y
++)
699 SourceX
= SourcePoint
->x
;
700 for(X
= DestRect
->left
; X
< DestRect
->right
; X
++, DestBits
+= 3, SourceX
++)
702 Source
= DIB_GetSourceIndex(SourceSurf
, SourceX
, SourceY
);
703 if(Source
!= iTransColor
)
705 Dest
= XLATEOBJ_iXlate(ColorTranslation
, Source
) & 0xFFFFFF;
706 *(PUSHORT
)(DestBits
) = Dest
& 0xFFFF;
707 *(DestBits
+ 2) = Dest
>> 16;
712 DestBits
= (BYTE
*)((ULONG_PTR
)DestBits
+ wd
);
728 static __inline UCHAR
731 return (val
> 255) ? 255 : val
;
735 DIB_24BPP_AlphaBlend(SURFOBJ
* Dest
, SURFOBJ
* Source
, RECTL
* DestRect
,
736 RECTL
* SourceRect
, CLIPOBJ
* ClipRegion
,
737 XLATEOBJ
* ColorTranslation
, BLENDOBJ
* BlendObj
)
739 INT Rows
, Cols
, SrcX
, SrcY
;
742 BLENDFUNCTION BlendFunc
;
743 register NICEPIXEL32 DstPixel
, SrcPixel
;
746 DPRINT("DIB_24BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
747 SourceRect
->left
, SourceRect
->top
, SourceRect
->right
, SourceRect
->bottom
,
748 DestRect
->left
, DestRect
->top
, DestRect
->right
, DestRect
->bottom
);
750 ASSERT(DestRect
->bottom
- DestRect
->top
== SourceRect
->bottom
- SourceRect
->top
&&
751 DestRect
->right
- DestRect
->left
== SourceRect
->right
- SourceRect
->left
);
753 BlendFunc
= BlendObj
->BlendFunction
;
754 if (BlendFunc
.BlendOp
!= AC_SRC_OVER
)
756 DPRINT1("BlendOp != AC_SRC_OVER\n");
759 if (BlendFunc
.BlendFlags
!= 0)
761 DPRINT1("BlendFlags != 0\n");
764 if ((BlendFunc
.AlphaFormat
& ~AC_SRC_ALPHA
) != 0)
766 DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc
.AlphaFormat
);
769 if ((BlendFunc
.AlphaFormat
& AC_SRC_ALPHA
) != 0 &&
770 BitsPerFormat(Source
->iBitmapFormat
) != 32)
772 DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n");
776 Dst
= (PUCHAR
)((ULONG_PTR
)Dest
->pvScan0
+ (DestRect
->top
* Dest
->lDelta
) +
777 (DestRect
->left
* 3));
778 DstDelta
= Dest
->lDelta
- ((DestRect
->right
- DestRect
->left
) * 3);
779 SrcBpp
= BitsPerFormat(Source
->iBitmapFormat
);
781 Rows
= DestRect
->bottom
- DestRect
->top
;
782 SrcY
= SourceRect
->top
;
785 Cols
= DestRect
->right
- DestRect
->left
;
786 SrcX
= SourceRect
->left
;
789 SrcPixel
.ul
= DIB_GetSource(Source
, SrcX
++, SrcY
, ColorTranslation
);
790 SrcPixel
.col
.red
= SrcPixel
.col
.red
* BlendFunc
.SourceConstantAlpha
/ 255;
791 SrcPixel
.col
.green
= SrcPixel
.col
.green
* BlendFunc
.SourceConstantAlpha
/ 255;
792 SrcPixel
.col
.blue
= SrcPixel
.col
.blue
* BlendFunc
.SourceConstantAlpha
/ 255;
793 SrcPixel
.col
.alpha
= (SrcBpp
== 32) ? (SrcPixel
.col
.alpha
* BlendFunc
.SourceConstantAlpha
/ 255) : BlendFunc
.SourceConstantAlpha
;
795 Alpha
= ((BlendFunc
.AlphaFormat
& AC_SRC_ALPHA
) != 0) ?
796 SrcPixel
.col
.alpha
: BlendFunc
.SourceConstantAlpha
;
798 /* copy only 24bits of dst */
799 DstPixel
.ul
= *(PUSHORT
)(Dst
) + (*(Dst
+2) << 16);
800 DstPixel
.col
.red
= Clamp8(DstPixel
.col
.red
* (255 - Alpha
) / 255 + SrcPixel
.col
.red
);
801 DstPixel
.col
.green
= Clamp8(DstPixel
.col
.green
* (255 - Alpha
) / 255 + SrcPixel
.col
.green
);
802 DstPixel
.col
.blue
= Clamp8(DstPixel
.col
.blue
* (255 - Alpha
) / 255 + SrcPixel
.col
.blue
);
803 /* copy back 24bits of result */
804 *(PUSHORT
)(Dst
) = (USHORT
)(DstPixel
.ul
& 0xFFFF);
805 *(Dst
+ 2) = (UCHAR
)((DstPixel
.ul
>> 16) & 0xFF);
806 Dst
= (PUCHAR
)((ULONG_PTR
)Dst
+ 3);
808 Dst
= (PUCHAR
)((ULONG_PTR
)Dst
+ DstDelta
);