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.
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * PURPOSE: GDI BitBlt Functions
24 * FILE: subsys/win32k/eng/bitblt.c
25 * PROGRAMER: Jason Filby
31 typedef BOOLEAN
STDCALL (*PBLTRECTFUNC
)(SURFOBJ
* OutputObj
,
34 XLATEOBJ
* ColorTranslation
,
41 typedef BOOLEAN
STDCALL (*PSTRETCHRECTFUNC
)(SURFOBJ
* OutputObj
,
45 XLATEOBJ
* ColorTranslation
,
52 BOOL STDCALL
EngIntersectRect(RECTL
* prcDst
, RECTL
* prcSrc1
, RECTL
* prcSrc2
)
54 static const RECTL rclEmpty
= { 0, 0, 0, 0 };
56 prcDst
->left
= max(prcSrc1
->left
, prcSrc2
->left
);
57 prcDst
->right
= min(prcSrc1
->right
, prcSrc2
->right
);
59 if (prcDst
->left
< prcDst
->right
)
61 prcDst
->top
= max(prcSrc1
->top
, prcSrc2
->top
);
62 prcDst
->bottom
= min(prcSrc1
->bottom
, prcSrc2
->bottom
);
64 if (prcDst
->top
< prcDst
->bottom
)
75 static BOOLEAN STDCALL
76 BltMask(SURFOBJ
* Dest
,
79 XLATEOBJ
* ColorTranslation
,
87 LONG i
, j
, dx
, dy
, c8
;
89 static BYTE maskbit
[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
91 PGDIBRUSHINST GdiBrush
= NULL
;
92 SURFOBJ
*PatternObj
= NULL
;
93 PBITMAPOBJ PatternBitmap
;
94 ULONG PatternWidth
= 0, PatternHeight
= 0, PatternY
= 0;
101 dx
= DestRect
->right
- DestRect
->left
;
102 dy
= DestRect
->bottom
- DestRect
->top
;
104 if (Brush
->iSolidColor
== 0xFFFFFFFF)
106 GdiBrush
= CONTAINING_RECORD(
111 PatternBitmap
= BITMAPOBJ_LockBitmap(GdiBrush
->GdiBrushObject
->hbmPattern
);
112 if(PatternBitmap
!= NULL
)
114 PatternObj
= &PatternBitmap
->SurfObj
;
115 PatternWidth
= PatternObj
->sizlBitmap
.cx
;
116 PatternHeight
= PatternObj
->sizlBitmap
.cy
;
120 PatternBitmap
= NULL
;
122 tMask
= Mask
->pvScan0
+ SourcePoint
->y
* Mask
->lDelta
+ (SourcePoint
->x
>> 3);
123 for (j
= 0; j
< dy
; j
++)
126 c8
= SourcePoint
->x
& 0x07;
128 if(PatternBitmap
!= NULL
)
129 PatternY
= (DestRect
->top
+ j
) % PatternHeight
;
131 for (i
= 0; i
< dx
; i
++)
133 if (0 != (*lMask
& maskbit
[c8
]))
135 if (PatternBitmap
== NULL
)
137 DibFunctionsForBitmapFormat
[Dest
->iBitmapFormat
].DIB_PutPixel(
138 Dest
, DestRect
->left
+ i
, DestRect
->top
+ j
, Brush
->iSolidColor
);
142 DibFunctionsForBitmapFormat
[Dest
->iBitmapFormat
].DIB_PutPixel(
143 Dest
, DestRect
->left
+ i
, DestRect
->top
+ j
,
144 DIB_GetSource(PatternObj
, (DestRect
->left
+ i
) % PatternWidth
, PatternY
, GdiBrush
->XlateObject
));
154 tMask
+= Mask
->lDelta
;
157 if (PatternBitmap
!= NULL
)
158 BITMAPOBJ_UnlockBitmap(PatternBitmap
);
163 static BOOLEAN STDCALL
164 BltPatCopy(SURFOBJ
* Dest
,
167 XLATEOBJ
* ColorTranslation
,
175 // These functions are assigned if we're working with a DIB
176 // The assigned functions depend on the bitsPerPixel of the DIB
178 DibFunctionsForBitmapFormat
[Dest
->iBitmapFormat
].DIB_ColorFill(Dest
, DestRect
, Brush
->iSolidColor
);
183 static BOOLEAN STDCALL
184 CallDibBitBlt(SURFOBJ
* OutputObj
,
187 XLATEOBJ
* ColorTranslation
,
196 PGDIBRUSHINST GdiBrush
= NULL
;
197 BITMAPOBJ
*bmPattern
;
200 BltInfo
.DestSurface
= OutputObj
;
201 BltInfo
.SourceSurface
= InputObj
;
202 BltInfo
.PatternSurface
= NULL
;
203 BltInfo
.XlateSourceToDest
= ColorTranslation
;
204 BltInfo
.DestRect
= *OutputRect
;
205 BltInfo
.SourcePoint
= *InputPoint
;
207 if (ROP3_TO_ROP4(SRCCOPY
) == Rop4
)
208 return DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_BitBltSrcCopy(&BltInfo
);
210 BltInfo
.XlatePatternToDest
= NULL
;
211 BltInfo
.Brush
= Brush
;
212 BltInfo
.BrushOrigin
= *BrushOrigin
;
216 if (ROP4_USES_PATTERN(Rop4
) && Brush
->iSolidColor
== 0xFFFFFFFF)
218 GdiBrush
= CONTAINING_RECORD(Brush
, GDIBRUSHINST
, BrushObject
);
219 if((bmPattern
= BITMAPOBJ_LockBitmap(GdiBrush
->GdiBrushObject
->hbmPattern
)))
221 BltInfo
.PatternSurface
= &bmPattern
->SurfObj
;
225 /* FIXME - What to do here? */
227 BltInfo
.XlatePatternToDest
= GdiBrush
->XlateObject
;
234 Result
= DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_BitBlt(&BltInfo
);
237 if (bmPattern
!= NULL
)
239 BITMAPOBJ_UnlockBitmap(bmPattern
);
251 EngBitBlt(SURFOBJ
*DestObj
,
255 XLATEOBJ
*ColorTranslation
,
271 INTENG_ENTER_LEAVE EnterLeaveSource
;
272 INTENG_ENTER_LEAVE EnterLeaveDest
;
275 PBLTRECTFUNC BltRectFunc
;
283 POINTL AdjustedBrushOrigin
;
285 UsesSource
= ROP4_USES_SOURCE(Rop4
);
286 UsesPattern
= ROP4_USES_PATTERN(Rop4
);
289 /* Copy destination onto itself: nop */
293 if (UsesSource
&& NULL
!= SourcePoint
)
295 InputRect
.left
= SourcePoint
->x
;
296 InputRect
.right
= SourcePoint
->x
+ (DestRect
->right
- DestRect
->left
);
297 InputRect
.top
= SourcePoint
->y
;
298 InputRect
.bottom
= SourcePoint
->y
+ (DestRect
->bottom
- DestRect
->top
);
303 InputRect
.right
= DestRect
->right
- DestRect
->left
;
305 InputRect
.bottom
= DestRect
->bottom
- DestRect
->top
;
308 if (! IntEngEnter(&EnterLeaveSource
, SourceObj
, &InputRect
, TRUE
, &Translate
, &InputObj
))
313 if (NULL
!= SourcePoint
)
315 InputPoint
.x
= SourcePoint
->x
+ Translate
.x
;
316 InputPoint
.y
= SourcePoint
->y
+ Translate
.y
;
324 OutputRect
= *DestRect
;
325 if (NULL
!= ClipRegion
)
327 if (OutputRect
.left
< ClipRegion
->rclBounds
.left
)
329 InputRect
.left
+= ClipRegion
->rclBounds
.left
- OutputRect
.left
;
330 InputPoint
.x
+= ClipRegion
->rclBounds
.left
- OutputRect
.left
;
331 OutputRect
.left
= ClipRegion
->rclBounds
.left
;
333 if (ClipRegion
->rclBounds
.right
< OutputRect
.right
)
335 InputRect
.right
-= OutputRect
.right
- ClipRegion
->rclBounds
.right
;
336 OutputRect
.right
= ClipRegion
->rclBounds
.right
;
338 if (OutputRect
.top
< ClipRegion
->rclBounds
.top
)
340 InputRect
.top
+= ClipRegion
->rclBounds
.top
- OutputRect
.top
;
341 InputPoint
.y
+= ClipRegion
->rclBounds
.top
- OutputRect
.top
;
342 OutputRect
.top
= ClipRegion
->rclBounds
.top
;
344 if (ClipRegion
->rclBounds
.bottom
< OutputRect
.bottom
)
346 InputRect
.bottom
-= OutputRect
.bottom
- ClipRegion
->rclBounds
.bottom
;
347 OutputRect
.bottom
= ClipRegion
->rclBounds
.bottom
;
351 /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
353 if (OutputRect
.right
<= OutputRect
.left
|| OutputRect
.bottom
<= OutputRect
.top
)
355 IntEngLeave(&EnterLeaveSource
);
359 if (! IntEngEnter(&EnterLeaveDest
, DestObj
, &OutputRect
, FALSE
, &Translate
, &OutputObj
))
361 IntEngLeave(&EnterLeaveSource
);
365 OutputRect
.left
+= Translate
.x
;
366 OutputRect
.right
+= Translate
.x
;
367 OutputRect
.top
+= Translate
.y
;
368 OutputRect
.bottom
+= Translate
.y
;
372 AdjustedBrushOrigin
.x
= BrushOrigin
->x
+ Translate
.x
;
373 AdjustedBrushOrigin
.y
= BrushOrigin
->y
+ Translate
.y
;
376 AdjustedBrushOrigin
= Translate
;
378 // Determine clipping type
379 if (ClipRegion
== (CLIPOBJ
*) NULL
)
381 clippingType
= DC_TRIVIAL
;
383 clippingType
= ClipRegion
->iDComplexity
;
388 BltRectFunc
= BltMask
;
390 else if (ROP3_TO_ROP4(PATCOPY
) == Rop4
)
392 if (Brush
->iSolidColor
== 0xFFFFFFFF)
393 BltRectFunc
= CallDibBitBlt
;
395 BltRectFunc
= BltPatCopy
;
399 BltRectFunc
= CallDibBitBlt
;
406 Ret
= (*BltRectFunc
)(OutputObj
, InputObj
, Mask
, ColorTranslation
,
407 &OutputRect
, &InputPoint
, MaskOrigin
, Brush
, &AdjustedBrushOrigin
, Rop4
);
410 // Clip the blt to the clip rectangle
411 ClipRect
.left
= ClipRegion
->rclBounds
.left
+ Translate
.x
;
412 ClipRect
.right
= ClipRegion
->rclBounds
.right
+ Translate
.x
;
413 ClipRect
.top
= ClipRegion
->rclBounds
.top
+ Translate
.y
;
414 ClipRect
.bottom
= ClipRegion
->rclBounds
.bottom
+ Translate
.y
;
415 if (EngIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
417 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
418 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
419 Ret
= (*BltRectFunc
)(OutputObj
, InputObj
, Mask
, ColorTranslation
,
420 &CombinedRect
, &Pt
, MaskOrigin
, Brush
, &AdjustedBrushOrigin
, Rop4
);
425 if (OutputObj
== InputObj
)
427 if (OutputRect
.top
< InputPoint
.y
)
429 Direction
= OutputRect
.left
< InputPoint
.x
? CD_RIGHTDOWN
: CD_LEFTDOWN
;
433 Direction
= OutputRect
.left
< InputPoint
.x
? CD_RIGHTUP
: CD_LEFTUP
;
440 CLIPOBJ_cEnumStart(ClipRegion
, FALSE
, CT_RECTANGLES
, Direction
, 0);
443 EnumMore
= CLIPOBJ_bEnum(ClipRegion
,(ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
445 for (i
= 0; i
< RectEnum
.c
; i
++)
447 ClipRect
.left
= RectEnum
.arcl
[i
].left
+ Translate
.x
;
448 ClipRect
.right
= RectEnum
.arcl
[i
].right
+ Translate
.x
;
449 ClipRect
.top
= RectEnum
.arcl
[i
].top
+ Translate
.y
;
450 ClipRect
.bottom
= RectEnum
.arcl
[i
].bottom
+ Translate
.y
;
451 if (EngIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
453 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
454 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
455 Ret
= (*BltRectFunc
)(OutputObj
, InputObj
, Mask
,
456 ColorTranslation
, &CombinedRect
, &Pt
,
457 MaskOrigin
, Brush
, &AdjustedBrushOrigin
,
467 IntEngLeave(&EnterLeaveDest
);
468 IntEngLeave(&EnterLeaveSource
);
474 IntEngBitBlt(BITMAPOBJ
*DestObj
,
475 BITMAPOBJ
*SourceObj
,
478 XLATEOBJ
*ColorTranslation
,
487 RECTL InputClippedRect
;
492 SURFOBJ
*SourceSurf
= SourceObj
? &SourceObj
->SurfObj
: NULL
;
493 SURFOBJ
*MaskSurf
= MaskObj
? &MaskObj
->SurfObj
: NULL
;
496 DestSurf
= &DestObj
->SurfObj
;
499 InputClippedRect
= *DestRect
;
500 if (InputClippedRect
.right
< InputClippedRect
.left
)
502 InputClippedRect
.left
= DestRect
->right
;
503 InputClippedRect
.right
= DestRect
->left
;
505 if (InputClippedRect
.bottom
< InputClippedRect
.top
)
507 InputClippedRect
.top
= DestRect
->bottom
;
508 InputClippedRect
.bottom
= DestRect
->top
;
510 UsesSource
= ROP4_USES_SOURCE(Rop4
);
513 if (NULL
== SourcePoint
|| NULL
== SourceSurf
)
517 InputPoint
= *SourcePoint
;
519 /* Make sure we don't try to copy anything outside the valid source region */
520 if (InputPoint
.x
< 0)
522 InputClippedRect
.left
-= InputPoint
.x
;
525 if (InputPoint
.y
< 0)
527 InputClippedRect
.top
-= InputPoint
.y
;
530 if (SourceSurf
->sizlBitmap
.cx
< InputPoint
.x
+ InputClippedRect
.right
- InputClippedRect
.left
)
532 InputClippedRect
.right
= InputClippedRect
.left
+ SourceSurf
->sizlBitmap
.cx
- InputPoint
.x
;
534 if (SourceSurf
->sizlBitmap
.cy
< InputPoint
.y
+ InputClippedRect
.bottom
- InputClippedRect
.top
)
536 InputClippedRect
.bottom
= InputClippedRect
.top
+ SourceSurf
->sizlBitmap
.cy
- InputPoint
.y
;
539 if (InputClippedRect
.right
< InputClippedRect
.left
||
540 InputClippedRect
.bottom
< InputClippedRect
.top
)
542 /* Everything clipped away, nothing to do */
547 /* Clip against the bounds of the clipping region so we won't try to write
548 * outside the surface */
549 if (NULL
!= ClipRegion
)
551 if (! EngIntersectRect(&OutputRect
, &InputClippedRect
, &ClipRegion
->rclBounds
))
555 InputPoint
.x
+= OutputRect
.left
- InputClippedRect
.left
;
556 InputPoint
.y
+= OutputRect
.top
- InputClippedRect
.top
;
560 OutputRect
= InputClippedRect
;
565 MouseSafetyOnDrawStart(SourceSurf
, InputPoint
.x
, InputPoint
.y
,
566 (InputPoint
.x
+ abs(DestRect
->right
- DestRect
->left
)),
567 (InputPoint
.y
+ abs(DestRect
->bottom
- DestRect
->top
)));
572 MouseSafetyOnDrawStart(DestSurf
, OutputRect
.left
, OutputRect
.top
,
573 OutputRect
.right
, OutputRect
.bottom
);
575 /* Call the driver's DrvBitBlt if available */
576 if (DestObj
->flHooks
& HOOK_BITBLT
)
578 ret
= GDIDEVFUNCS(DestSurf
).BitBlt(
579 DestSurf
, SourceSurf
, MaskSurf
, ClipRegion
, ColorTranslation
,
580 &OutputRect
, &InputPoint
, MaskOrigin
, Brush
, BrushOrigin
,
586 ret
= EngBitBlt(DestSurf
, SourceSurf
, MaskSurf
, ClipRegion
, ColorTranslation
,
587 &OutputRect
, &InputPoint
, MaskOrigin
, Brush
, BrushOrigin
,
591 MouseSafetyOnDrawEnd(DestSurf
);
594 MouseSafetyOnDrawEnd(SourceSurf
);
600 static BOOLEAN STDCALL
601 CallDibStretchBlt(SURFOBJ
* OutputObj
,
605 XLATEOBJ
* ColorTranslation
,
612 POINTL RealBrushOrigin
;
613 if (BrushOrigin
== NULL
)
615 RealBrushOrigin
.x
= RealBrushOrigin
.y
= 0;
619 RealBrushOrigin
= *BrushOrigin
;
621 return DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_StretchBlt(
622 OutputObj
, InputObj
, OutputRect
, InputRect
, MaskOrigin
, RealBrushOrigin
, ClipRegion
, ColorTranslation
, Mode
);
630 IN SURFOBJ
*SourceObj
,
632 IN CLIPOBJ
*ClipRegion
,
633 IN XLATEOBJ
*ColorTranslation
,
634 IN COLORADJUSTMENT
*pca
,
635 IN POINTL
*BrushOrigin
,
638 IN POINTL
*MaskOrigin
,
642 // www.osr.com/ddk/graphics/gdifncs_0bs7.htm
648 INTENG_ENTER_LEAVE EnterLeaveSource
;
649 INTENG_ENTER_LEAVE EnterLeaveDest
;
652 PSTRETCHRECTFUNC BltRectFunc
;
654 POINTL AdjustedBrushOrigin
;
656 InputRect
.left
= prclSrc
->left
;
657 InputRect
.right
= prclSrc
->right
;
658 InputRect
.top
= prclSrc
->top
;
659 InputRect
.bottom
= prclSrc
->bottom
;
661 if (! IntEngEnter(&EnterLeaveSource
, SourceObj
, &InputRect
, TRUE
, &Translate
, &InputObj
))
666 InputPoint
.x
= InputRect
.left
+ Translate
.x
;
667 InputPoint
.y
= InputRect
.top
+ Translate
.y
;
669 OutputRect
= *prclDest
;
671 /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
673 if (OutputRect
.right
<= OutputRect
.left
|| OutputRect
.bottom
<= OutputRect
.top
)
675 IntEngLeave(&EnterLeaveSource
);
679 if (! IntEngEnter(&EnterLeaveDest
, DestObj
, &OutputRect
, FALSE
, &Translate
, &OutputObj
))
681 IntEngLeave(&EnterLeaveSource
);
685 OutputRect
.left
= prclDest
->left
+ Translate
.x
;
686 OutputRect
.right
= prclDest
->right
+ Translate
.x
;
687 OutputRect
.top
= prclDest
->top
+ Translate
.y
;
688 OutputRect
.bottom
= prclDest
->bottom
+ Translate
.y
;
690 if (NULL
!= BrushOrigin
)
692 AdjustedBrushOrigin
.x
= BrushOrigin
->x
+ Translate
.x
;
693 AdjustedBrushOrigin
.y
= BrushOrigin
->y
+ Translate
.y
;
697 AdjustedBrushOrigin
= Translate
;
702 //BltRectFunc = BltMask;
703 DPRINT("EngStretchBlt isn't capable of handling mask yet.\n");
704 IntEngLeave(&EnterLeaveDest
);
705 IntEngLeave(&EnterLeaveSource
);
711 BltRectFunc
= CallDibStretchBlt
;
715 Ret
= (*BltRectFunc
)(OutputObj
, InputObj
, Mask
, ClipRegion
,
716 ColorTranslation
, &OutputRect
, &InputRect
, MaskOrigin
,
717 &AdjustedBrushOrigin
, Mode
);
719 IntEngLeave(&EnterLeaveDest
);
720 IntEngLeave(&EnterLeaveSource
);
726 IntEngStretchBlt(BITMAPOBJ
*DestObj
,
727 BITMAPOBJ
*SourceObj
,
730 XLATEOBJ
*ColorTranslation
,
742 SURFOBJ
*SourceSurf
= SourceObj
? &SourceObj
->SurfObj
: NULL
;
743 SURFOBJ
*MaskSurf
= MaskObj
? &MaskObj
->SurfObj
: NULL
;
746 DestSurf
= &DestObj
->SurfObj
;
749 if (pMaskOrigin
!= NULL
)
751 MaskOrigin
.x
= pMaskOrigin
->x
; MaskOrigin
.y
= pMaskOrigin
->y
;
754 if (NULL
!= SourceSurf
)
757 MouseSafetyOnDrawStart(SourceSurf
, SourceRect
->left
, SourceRect
->top
,
758 SourceRect
->right
, SourceRect
->bottom
);
764 MouseSafetyOnDrawStart(DestSurf
, DestRect
->left
, DestRect
->top
,
765 DestRect
->right
, DestRect
->bottom
);
767 /* Prepare color adjustment */
769 /* Call the driver's DrvStretchBlt if available */
770 if (DestObj
->flHooks
& HOOK_STRETCHBLT
)
772 /* Drv->StretchBlt (look at http://www.osr.com/ddk/graphics/ddifncs_3ew7.htm )
773 SURFOBJ *psoMask // optional, if it exists, then rop4=0xCCAA, otherwise rop4=0xCCCC */
774 // FIXME: MaskOrigin is always NULL !
775 ret
= GDIDEVFUNCS(DestSurf
).StretchBlt(
776 DestSurf
, SourceSurf
, MaskSurf
, ClipRegion
, ColorTranslation
,
777 &ca
, BrushOrigin
, DestRect
, SourceRect
, NULL
, Mode
);
782 // FIXME: see previous fixme
783 ret
= EngStretchBlt(DestSurf
, SourceSurf
, MaskSurf
, ClipRegion
, ColorTranslation
,
784 &ca
, BrushOrigin
, DestRect
, SourceRect
, NULL
, Mode
);
787 MouseSafetyOnDrawEnd(DestSurf
);
788 if (NULL
!= SourceSurf
)
790 MouseSafetyOnDrawEnd(SourceSurf
);
796 /**** REACTOS FONT RENDERING CODE *********************************************/
798 /* renders the alpha mask bitmap */
799 static BOOLEAN STDCALL
800 AlphaBltMask(SURFOBJ
* Dest
,
803 XLATEOBJ
* ColorTranslation
,
804 XLATEOBJ
* SrcColorTranslation
,
813 ULONG Background
, BrushColor
, NewColor
;
816 dx
= DestRect
->right
- DestRect
->left
;
817 dy
= DestRect
->bottom
- DestRect
->top
;
821 BrushColor
= XLATEOBJ_iXlate(SrcColorTranslation
, Brush
->iSolidColor
);
822 r
= (int)GetRValue(BrushColor
);
823 g
= (int)GetGValue(BrushColor
);
824 b
= (int)GetBValue(BrushColor
);
826 tMask
= Mask
->pvScan0
+ (SourcePoint
->y
* Mask
->lDelta
) + SourcePoint
->x
;
827 for (j
= 0; j
< dy
; j
++)
830 for (i
= 0; i
< dx
; i
++)
836 DibFunctionsForBitmapFormat
[Dest
->iBitmapFormat
].DIB_PutPixel(
837 Dest
, DestRect
->left
+ i
, DestRect
->top
+ j
, Brush
->iSolidColor
);
841 Background
= DIB_GetSource(Dest
, DestRect
->left
+ i
, DestRect
->top
+ j
,
842 SrcColorTranslation
);
845 RGB((*lMask
* (r
- GetRValue(Background
)) >> 8) + GetRValue(Background
),
846 (*lMask
* (g
- GetGValue(Background
)) >> 8) + GetGValue(Background
),
847 (*lMask
* (b
- GetBValue(Background
)) >> 8) + GetBValue(Background
));
849 Background
= XLATEOBJ_iXlate(ColorTranslation
, NewColor
);
850 DibFunctionsForBitmapFormat
[Dest
->iBitmapFormat
].DIB_PutPixel(
851 Dest
, DestRect
->left
+ i
, DestRect
->top
+ j
, Background
);
856 tMask
+= Mask
->lDelta
;
867 EngMaskBitBlt(SURFOBJ
*DestObj
,
870 XLATEOBJ
*DestColorTranslation
,
871 XLATEOBJ
*SourceColorTranslation
,
886 INTENG_ENTER_LEAVE EnterLeaveSource
;
887 INTENG_ENTER_LEAVE EnterLeaveDest
;
895 POINTL AdjustedBrushOrigin
;
899 if (NULL
!= SourcePoint
)
901 InputRect
.left
= SourcePoint
->x
;
902 InputRect
.right
= SourcePoint
->x
+ (DestRect
->right
- DestRect
->left
);
903 InputRect
.top
= SourcePoint
->y
;
904 InputRect
.bottom
= SourcePoint
->y
+ (DestRect
->bottom
- DestRect
->top
);
909 InputRect
.right
= DestRect
->right
- DestRect
->left
;
911 InputRect
.bottom
= DestRect
->bottom
- DestRect
->top
;
914 if (! IntEngEnter(&EnterLeaveSource
, DestObj
, &InputRect
, TRUE
, &Translate
, &InputObj
))
919 if (NULL
!= SourcePoint
)
921 InputPoint
.x
= SourcePoint
->x
+ Translate
.x
;
922 InputPoint
.y
= SourcePoint
->y
+ Translate
.y
;
930 OutputRect
= *DestRect
;
931 if (NULL
!= ClipRegion
)
933 if (OutputRect
.left
< ClipRegion
->rclBounds
.left
)
935 InputRect
.left
+= ClipRegion
->rclBounds
.left
- OutputRect
.left
;
936 InputPoint
.x
+= ClipRegion
->rclBounds
.left
- OutputRect
.left
;
937 OutputRect
.left
= ClipRegion
->rclBounds
.left
;
939 if (ClipRegion
->rclBounds
.right
< OutputRect
.right
)
941 InputRect
.right
-= OutputRect
.right
- ClipRegion
->rclBounds
.right
;
942 OutputRect
.right
= ClipRegion
->rclBounds
.right
;
944 if (OutputRect
.top
< ClipRegion
->rclBounds
.top
)
946 InputRect
.top
+= ClipRegion
->rclBounds
.top
- OutputRect
.top
;
947 InputPoint
.y
+= ClipRegion
->rclBounds
.top
- OutputRect
.top
;
948 OutputRect
.top
= ClipRegion
->rclBounds
.top
;
950 if (ClipRegion
->rclBounds
.bottom
< OutputRect
.bottom
)
952 InputRect
.bottom
-= OutputRect
.bottom
- ClipRegion
->rclBounds
.bottom
;
953 OutputRect
.bottom
= ClipRegion
->rclBounds
.bottom
;
957 /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
959 if (OutputRect
.right
<= OutputRect
.left
|| OutputRect
.bottom
<= OutputRect
.top
)
961 IntEngLeave(&EnterLeaveSource
);
965 if (! IntEngEnter(&EnterLeaveDest
, DestObj
, &OutputRect
, FALSE
, &Translate
, &OutputObj
))
967 IntEngLeave(&EnterLeaveSource
);
971 OutputRect
.left
= DestRect
->left
+ Translate
.x
;
972 OutputRect
.right
= DestRect
->right
+ Translate
.x
;
973 OutputRect
.top
= DestRect
->top
+ Translate
.y
;
974 OutputRect
.bottom
= DestRect
->bottom
+ Translate
.y
;
978 AdjustedBrushOrigin
.x
= BrushOrigin
->x
+ Translate
.x
;
979 AdjustedBrushOrigin
.y
= BrushOrigin
->y
+ Translate
.y
;
982 AdjustedBrushOrigin
= Translate
;
984 // Determine clipping type
985 if (ClipRegion
== (CLIPOBJ
*) NULL
)
987 clippingType
= DC_TRIVIAL
;
989 clippingType
= ClipRegion
->iDComplexity
;
995 if(Mask
->iBitmapFormat
== BMF_8BPP
)
996 Ret
= AlphaBltMask(OutputObj
, InputObj
, Mask
, DestColorTranslation
, SourceColorTranslation
,
997 &OutputRect
, &InputPoint
, MaskOrigin
, Brush
, &AdjustedBrushOrigin
);
999 Ret
= BltMask(OutputObj
, InputObj
, Mask
, DestColorTranslation
,
1000 &OutputRect
, &InputPoint
, MaskOrigin
, Brush
, &AdjustedBrushOrigin
,
1004 // Clip the blt to the clip rectangle
1005 ClipRect
.left
= ClipRegion
->rclBounds
.left
+ Translate
.x
;
1006 ClipRect
.right
= ClipRegion
->rclBounds
.right
+ Translate
.x
;
1007 ClipRect
.top
= ClipRegion
->rclBounds
.top
+ Translate
.y
;
1008 ClipRect
.bottom
= ClipRegion
->rclBounds
.bottom
+ Translate
.y
;
1009 if (EngIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
1011 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
1012 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
1013 if(Mask
->iBitmapFormat
== BMF_8BPP
)
1015 Ret
= AlphaBltMask(OutputObj
, InputObj
, Mask
, DestColorTranslation
, SourceColorTranslation
,
1016 &CombinedRect
, &Pt
, MaskOrigin
, Brush
, &AdjustedBrushOrigin
);
1020 Ret
= BltMask(OutputObj
, InputObj
, Mask
, DestColorTranslation
,
1021 &CombinedRect
, &Pt
, MaskOrigin
, Brush
, &AdjustedBrushOrigin
, R4_MASK
);
1027 if (OutputObj
== InputObj
)
1029 if (OutputRect
.top
< InputPoint
.y
)
1031 Direction
= OutputRect
.left
< InputPoint
.x
? CD_RIGHTDOWN
: CD_LEFTDOWN
;
1035 Direction
= OutputRect
.left
< InputPoint
.x
? CD_RIGHTUP
: CD_LEFTUP
;
1042 CLIPOBJ_cEnumStart(ClipRegion
, FALSE
, CT_RECTANGLES
, Direction
, 0);
1045 EnumMore
= CLIPOBJ_bEnum(ClipRegion
,(ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
1047 for (i
= 0; i
< RectEnum
.c
; i
++)
1049 ClipRect
.left
= RectEnum
.arcl
[i
].left
+ Translate
.x
;
1050 ClipRect
.right
= RectEnum
.arcl
[i
].right
+ Translate
.x
;
1051 ClipRect
.top
= RectEnum
.arcl
[i
].top
+ Translate
.y
;
1052 ClipRect
.bottom
= RectEnum
.arcl
[i
].bottom
+ Translate
.y
;
1053 if (EngIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
1055 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
1056 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
1057 if(Mask
->iBitmapFormat
== BMF_8BPP
)
1059 Ret
= AlphaBltMask(OutputObj
, InputObj
, Mask
,
1060 DestColorTranslation
,
1061 SourceColorTranslation
,
1062 &CombinedRect
, &Pt
, MaskOrigin
, Brush
,
1063 &AdjustedBrushOrigin
) && Ret
;
1067 Ret
= BltMask(OutputObj
, InputObj
, Mask
,
1068 DestColorTranslation
, &CombinedRect
, &Pt
,
1069 MaskOrigin
, Brush
, &AdjustedBrushOrigin
,
1080 IntEngLeave(&EnterLeaveDest
);
1081 IntEngLeave(&EnterLeaveSource
);
1087 IntEngMaskBlt(SURFOBJ
*DestObj
,
1089 CLIPOBJ
*ClipRegion
,
1090 XLATEOBJ
*DestColorTranslation
,
1091 XLATEOBJ
*SourceColorTranslation
,
1093 POINTL
*SourcePoint
,
1096 POINTL
*BrushOrigin
)
1104 if (NULL
!= SourcePoint
)
1106 InputPoint
= *SourcePoint
;
1109 /* Clip against the bounds of the clipping region so we won't try to write
1110 * outside the surface */
1111 if (NULL
!= ClipRegion
)
1113 if (! EngIntersectRect(&OutputRect
, DestRect
, &ClipRegion
->rclBounds
))
1117 InputPoint
.x
+= OutputRect
.left
- DestRect
->left
;
1118 InputPoint
.y
+= OutputRect
.top
- DestRect
->top
;
1122 OutputRect
= *DestRect
;
1125 /* No success yet */
1128 MouseSafetyOnDrawStart(DestObj
, OutputRect
.left
, OutputRect
.top
,
1129 OutputRect
.right
, OutputRect
.bottom
);
1131 /* Dummy BitBlt to let driver know that it should flush its changes.
1132 This should really be done using a call to DrvSynchronizeSurface,
1133 but the VMware driver doesn't hook that call. */
1134 /* FIXME: Remove the typecast! */
1135 IntEngBitBlt((BITMAPOBJ
*)DestObj
, NULL
, (BITMAPOBJ
*)Mask
, ClipRegion
, DestColorTranslation
,
1136 DestRect
, SourcePoint
, MaskOrigin
, Brush
, BrushOrigin
, R4_NOOP
);
1138 ret
= EngMaskBitBlt(DestObj
, Mask
, ClipRegion
, DestColorTranslation
, SourceColorTranslation
,
1139 &OutputRect
, &InputPoint
, MaskOrigin
, Brush
, BrushOrigin
);
1141 /* Dummy BitBlt to let driver know that something has changed. */
1142 /* FIXME: Remove the typecast! */
1143 IntEngBitBlt((BITMAPOBJ
*)DestObj
, NULL
, (BITMAPOBJ
*)Mask
, ClipRegion
, DestColorTranslation
,
1144 DestRect
, SourcePoint
, MaskOrigin
, Brush
, BrushOrigin
, R4_NOOP
);
1146 MouseSafetyOnDrawEnd(DestObj
);