2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: GDI BitBlt Functions
5 * FILE: subsys/win32k/eng/bitblt.c
6 * PROGRAMER: Jason Filby
17 typedef BOOLEAN (APIENTRY
*PBLTRECTFUNC
)(SURFOBJ
* OutputObj
,
20 XLATEOBJ
* ColorTranslation
,
28 static BOOLEAN APIENTRY
29 BltMask(SURFOBJ
* psoDest
,
30 SURFOBJ
* psoSource
, // unused
32 XLATEOBJ
* ColorTranslation
, // unused
34 POINTL
* pptlSource
, // unused
41 BYTE
*pjMskLine
, *pjMskCurrent
;
42 BYTE fjMaskBit0
, fjMaskBit
;
44 PEBRUSHOBJ pebo
= NULL
;
45 SURFOBJ
*psoPattern
= NULL
;
46 PSURFACE psurfPattern
;
47 ULONG PatternWidth
= 0, PatternHeight
= 0;
48 LONG PatternX0
= 0, PatternX
= 0, PatternY
= 0;
49 PFN_DIB_PutPixel fnDest_PutPixel
= NULL
;
50 PFN_DIB_GetPixel fnPattern_GetPixel
= NULL
;
54 ASSERT(psoSource
== NULL
);
55 ASSERT(pptlSource
== NULL
);
62 if (pbo
&& pbo
->iSolidColor
== 0xFFFFFFFF)
64 pebo
= CONTAINING_RECORD(pbo
, EBRUSHOBJ
, BrushObject
);
66 hbmPattern
= EBRUSHOBJ_pvGetEngBrush(pebo
);
67 psurfPattern
= SURFACE_LockSurface(hbmPattern
);
68 if (psurfPattern
!= NULL
)
70 psoPattern
= &psurfPattern
->SurfObj
;
71 PatternWidth
= psoPattern
->sizlBitmap
.cx
;
72 PatternHeight
= psoPattern
->sizlBitmap
.cy
;
73 fnPattern_GetPixel
= DibFunctionsForBitmapFormat
[psoPattern
->iBitmapFormat
].DIB_GetPixel
;
79 pjMskLine
= (PBYTE
)psoMask
->pvScan0
+ pptlMask
->y
* psoMask
->lDelta
+ (pptlMask
->x
>> 3);
80 fjMaskBit0
= 0x80 >> (pptlMask
->x
& 0x07);
82 fnDest_PutPixel
= DibFunctionsForBitmapFormat
[psoDest
->iBitmapFormat
].DIB_PutPixel
;
85 PatternY
= (prclDest
->top
- pptlBrush
->y
) % PatternHeight
;
88 PatternY
+= PatternHeight
;
90 PatternX0
= (prclDest
->left
- pptlBrush
->x
) % PatternWidth
;
93 PatternX0
+= PatternWidth
;
96 for (y
= prclDest
->top
; y
< prclDest
->bottom
; y
++)
98 pjMskCurrent
= pjMskLine
;
99 fjMaskBit
= fjMaskBit0
;
100 PatternX
= PatternX0
;
102 for (x
= prclDest
->left
; x
< prclDest
->right
; x
++)
104 if (*pjMskCurrent
& fjMaskBit
)
106 fnDest_PutPixel(psoDest
, x
, y
,
107 fnPattern_GetPixel(psoPattern
, PatternX
, PatternY
));
109 fjMaskBit
= _rotr8(fjMaskBit
, 1);
110 pjMskCurrent
+= (fjMaskBit
>> 7);
112 PatternX
%= PatternWidth
;
114 pjMskLine
+= psoMask
->lDelta
;
116 PatternY
%= PatternHeight
;
121 Pattern
= pbo
? pbo
->iSolidColor
: 0;
122 for (y
= prclDest
->top
; y
< prclDest
->bottom
; y
++)
124 pjMskCurrent
= pjMskLine
;
125 fjMaskBit
= fjMaskBit0
;
127 for (x
= prclDest
->left
; x
< prclDest
->right
; x
++)
129 if (*pjMskCurrent
& fjMaskBit
)
131 fnDest_PutPixel(psoDest
, x
, y
, Pattern
);
133 fjMaskBit
= _rotr8(fjMaskBit
, 1);
134 pjMskCurrent
+= (fjMaskBit
>> 7);
136 pjMskLine
+= psoMask
->lDelta
;
141 SURFACE_UnlockSurface(psurfPattern
);
146 static BOOLEAN APIENTRY
147 BltPatCopy(SURFOBJ
* Dest
,
150 XLATEOBJ
* ColorTranslation
,
158 // These functions are assigned if we're working with a DIB
159 // The assigned functions depend on the bitsPerPixel of the DIB
161 DibFunctionsForBitmapFormat
[Dest
->iBitmapFormat
].DIB_ColorFill(Dest
, DestRect
, pbo
? pbo
->iSolidColor
: 0);
166 static BOOLEAN APIENTRY
167 CallDibBitBlt(SURFOBJ
* OutputObj
,
170 XLATEOBJ
* ColorTranslation
,
179 PEBRUSHOBJ GdiBrush
= NULL
;
180 SURFACE
*psurfPattern
;
184 BltInfo
.DestSurface
= OutputObj
;
185 BltInfo
.SourceSurface
= InputObj
;
186 BltInfo
.PatternSurface
= NULL
;
187 BltInfo
.XlateSourceToDest
= ColorTranslation
;
188 BltInfo
.DestRect
= *OutputRect
;
189 BltInfo
.SourcePoint
= *InputPoint
;
191 if (ROP3_TO_ROP4(SRCCOPY
) == Rop4
)
192 return DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_BitBltSrcCopy(&BltInfo
);
195 BltInfo
.BrushOrigin
= *BrushOrigin
;
199 if (ROP4_USES_PATTERN(Rop4
) && pbo
&& pbo
->iSolidColor
== 0xFFFFFFFF)
201 GdiBrush
= CONTAINING_RECORD(pbo
, EBRUSHOBJ
, BrushObject
);
202 hbmPattern
= EBRUSHOBJ_pvGetEngBrush(GdiBrush
);
203 psurfPattern
= SURFACE_LockSurface(hbmPattern
);
206 BltInfo
.PatternSurface
= &psurfPattern
->SurfObj
;
210 /* FIXME - What to do here? */
218 Result
= DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_BitBlt(&BltInfo
);
223 SURFACE_UnlockSurface(psurfPattern
);
229 INT __cdecl
abs(INT nm
);
246 IN POINTL
*pptlBrush
,
256 ProbeForRead(prclTrg
, sizeof(RECTL
), 1);
257 RtlCopyMemory(&rclTrg
,prclTrg
, sizeof(RECTL
));
259 ProbeForRead(pptlSrc
, sizeof(POINTL
), 1);
260 RtlCopyMemory(&ptlSrc
, pptlSrc
, sizeof(POINTL
));
262 ProbeForRead(pptlMask
, sizeof(POINTL
), 1);
263 RtlCopyMemory(&ptlMask
, pptlMask
, sizeof(POINTL
));
265 ProbeForRead(pptlBrush
, sizeof(POINTL
), 1);
266 RtlCopyMemory(&ptlBrush
, pptlBrush
, sizeof(POINTL
));
269 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
271 _SEH2_YIELD(return FALSE
);
275 return EngBitBlt(psoTrg
, psoSrc
, psoMask
, pco
, pxlo
, &rclTrg
, &ptlSrc
, &ptlMask
, pbo
, &ptlBrush
, rop4
);
282 EngBitBlt(SURFOBJ
*DestObj
,
286 XLATEOBJ
*ColorTranslation
,
301 SURFOBJ
* InputObj
= 0;
303 PBLTRECTFUNC BltRectFunc
;
311 POINTL AdjustedBrushOrigin
;
313 UsesSource
= ROP4_USES_SOURCE(rop4
);
314 UsesPattern
= ROP4_USES_PATTERN(rop4
);
317 /* Copy destination onto itself: nop */
321 OutputRect
= *DestRect
;
322 if (OutputRect
.right
< OutputRect
.left
)
324 OutputRect
.left
= DestRect
->right
;
325 OutputRect
.right
= DestRect
->left
;
327 if (OutputRect
.bottom
< OutputRect
.top
)
329 OutputRect
.left
= DestRect
->right
;
330 OutputRect
.right
= DestRect
->left
;
335 if (NULL
== SourcePoint
)
340 /* Make sure we don't try to copy anything outside the valid source
342 InputPoint
= *SourcePoint
;
343 if (InputPoint
.x
< 0)
345 OutputRect
.left
-= InputPoint
.x
;
348 if (InputPoint
.y
< 0)
350 OutputRect
.top
-= InputPoint
.y
;
353 if (SourceObj
->sizlBitmap
.cx
< InputPoint
.x
+
354 OutputRect
.right
- OutputRect
.left
)
356 OutputRect
.right
= OutputRect
.left
+
357 SourceObj
->sizlBitmap
.cx
- InputPoint
.x
;
359 if (SourceObj
->sizlBitmap
.cy
< InputPoint
.y
+
360 OutputRect
.bottom
- OutputRect
.top
)
362 OutputRect
.bottom
= OutputRect
.top
+
363 SourceObj
->sizlBitmap
.cy
- InputPoint
.y
;
366 InputRect
.left
= InputPoint
.x
;
367 InputRect
.right
= InputPoint
.x
+ (OutputRect
.right
- OutputRect
.left
);
368 InputRect
.top
= InputPoint
.y
;
369 InputRect
.bottom
= InputPoint
.y
+ (OutputRect
.bottom
- OutputRect
.top
);
371 InputObj
= SourceObj
;
376 InputRect
.right
= DestRect
->right
- DestRect
->left
;
378 InputRect
.bottom
= DestRect
->bottom
- DestRect
->top
;
381 if (NULL
!= ClipRegion
)
383 if (OutputRect
.left
< ClipRegion
->rclBounds
.left
)
385 InputRect
.left
+= ClipRegion
->rclBounds
.left
- OutputRect
.left
;
386 InputPoint
.x
+= ClipRegion
->rclBounds
.left
- OutputRect
.left
;
387 OutputRect
.left
= ClipRegion
->rclBounds
.left
;
389 if (ClipRegion
->rclBounds
.right
< OutputRect
.right
)
391 InputRect
.right
-= OutputRect
.right
- ClipRegion
->rclBounds
.right
;
392 OutputRect
.right
= ClipRegion
->rclBounds
.right
;
394 if (OutputRect
.top
< ClipRegion
->rclBounds
.top
)
396 InputRect
.top
+= ClipRegion
->rclBounds
.top
- OutputRect
.top
;
397 InputPoint
.y
+= ClipRegion
->rclBounds
.top
- OutputRect
.top
;
398 OutputRect
.top
= ClipRegion
->rclBounds
.top
;
400 if (ClipRegion
->rclBounds
.bottom
< OutputRect
.bottom
)
402 InputRect
.bottom
-= OutputRect
.bottom
- ClipRegion
->rclBounds
.bottom
;
403 OutputRect
.bottom
= ClipRegion
->rclBounds
.bottom
;
407 /* Check for degenerate case: if height or width of OutputRect is 0 pixels
408 there's nothing to do */
409 if (OutputRect
.right
<= OutputRect
.left
||
410 OutputRect
.bottom
<= OutputRect
.top
)
419 AdjustedBrushOrigin
.x
= BrushOrigin
->x
;
420 AdjustedBrushOrigin
.y
= BrushOrigin
->y
;
424 AdjustedBrushOrigin
.x
= 0;
425 AdjustedBrushOrigin
.y
= 0;
428 /* Determine clipping type */
429 if (ClipRegion
== (CLIPOBJ
*) NULL
)
431 clippingType
= DC_TRIVIAL
;
435 clippingType
= ClipRegion
->iDComplexity
;
440 BltRectFunc
= BltMask
;
442 else if (ROP3_TO_ROP4(PATCOPY
) == rop4
)
444 if (pbo
&& pbo
->iSolidColor
== 0xFFFFFFFF)
445 BltRectFunc
= CallDibBitBlt
;
447 BltRectFunc
= BltPatCopy
;
451 BltRectFunc
= CallDibBitBlt
;
455 switch (clippingType
)
458 Ret
= (*BltRectFunc
)(OutputObj
, InputObj
, Mask
, ColorTranslation
,
459 &OutputRect
, &InputPoint
, MaskOrigin
, pbo
,
460 &AdjustedBrushOrigin
, rop4
);
463 /* Clip the blt to the clip rectangle */
464 ClipRect
.left
= ClipRegion
->rclBounds
.left
;
465 ClipRect
.right
= ClipRegion
->rclBounds
.right
;
466 ClipRect
.top
= ClipRegion
->rclBounds
.top
;
467 ClipRect
.bottom
= ClipRegion
->rclBounds
.bottom
;
468 if (RECTL_bIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
470 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
471 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
472 Ret
= (*BltRectFunc
)(OutputObj
, InputObj
, Mask
, ColorTranslation
,
473 &CombinedRect
, &Pt
, MaskOrigin
, pbo
,
474 &AdjustedBrushOrigin
, rop4
);
479 if (OutputObj
== InputObj
)
481 if (OutputRect
.top
< InputPoint
.y
)
483 Direction
= OutputRect
.left
< InputPoint
.x
?
484 CD_RIGHTDOWN
: CD_LEFTDOWN
;
488 Direction
= OutputRect
.left
< InputPoint
.x
?
489 CD_RIGHTUP
: CD_LEFTUP
;
496 CLIPOBJ_cEnumStart(ClipRegion
, FALSE
, CT_RECTANGLES
, Direction
, 0);
499 EnumMore
= CLIPOBJ_bEnum(ClipRegion
,(ULONG
) sizeof(RectEnum
),
502 for (i
= 0; i
< RectEnum
.c
; i
++)
504 ClipRect
.left
= RectEnum
.arcl
[i
].left
;
505 ClipRect
.right
= RectEnum
.arcl
[i
].right
;
506 ClipRect
.top
= RectEnum
.arcl
[i
].top
;
507 ClipRect
.bottom
= RectEnum
.arcl
[i
].bottom
;
508 if (RECTL_bIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
510 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
511 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
512 Ret
= (*BltRectFunc
)(OutputObj
, InputObj
, Mask
,
513 ColorTranslation
, &CombinedRect
, &Pt
,
514 MaskOrigin
, pbo
, &AdjustedBrushOrigin
,
541 SURFACE
*psurfSrc
= NULL
;
545 // INTENG_ENTER_LEAVE EnterLeaveSource;
546 // INTENG_ENTER_LEAVE EnterLeaveDest;
547 PFN_DrvBitBlt pfnBitBlt
;
550 psurfTrg
= CONTAINING_RECORD(psoTrg
, SURFACE
, SurfObj
);
552 /* FIXME: Should we really allow to pass non-well-ordered rects? */
553 rclClipped
= *prclTrg
;
554 RECTL_vMakeWellOrdered(&rclClipped
);
556 /* Clip target rect against the bounds of the clipping region */
559 if (!RECTL_bIntersectRect(&rclClipped
, &rclClipped
, &pco
->rclBounds
))
565 /* Don't pass a clipobj with only a single rect */
566 if (pco
->iDComplexity
== DC_RECT
)
570 if (ROP4_USES_SOURCE(rop4
))
573 psurfSrc
= CONTAINING_RECORD(psoSrc
, SURFACE
, SurfObj
);
575 /* Calculate source rect */
576 rclSrc
.left
= pptlSrc
->x
+ rclClipped
.left
- prclTrg
->left
;
577 rclSrc
.top
= pptlSrc
->y
+ rclClipped
.top
- prclTrg
->top
;
578 rclSrc
.right
= rclSrc
.left
+ rclClipped
.right
- rclClipped
.left
;
579 rclSrc
.bottom
= rclSrc
.top
+ rclClipped
.bottom
- rclClipped
.top
;
587 /* Is the target surface device managed? */
588 if (psurfTrg
->flags
& HOOK_BITBLT
)
590 /* Is the source a different device managed surface? */
591 if (psoSrc
&& psoSrc
->hdev
!= psoTrg
->hdev
&& psurfSrc
->flags
& HOOK_BITBLT
)
593 DPRINT1("Need to copy to standard bitmap format!\n");
597 pfnBitBlt
= GDIDEVFUNCS(psoTrg
).BitBlt
;
600 /* Is the source surface device managed? */
601 else if (psoSrc
&& psurfSrc
->flags
& HOOK_BITBLT
)
603 pfnBitBlt
= GDIDEVFUNCS(psoSrc
).BitBlt
;
607 pfnBitBlt
= EngBitBlt
;
610 bResult
= pfnBitBlt(psoTrg
,
622 // FIXME: cleanup temp surface!
628 /**** REACTOS FONT RENDERING CODE *********************************************/
630 /* renders the alpha mask bitmap */
631 static BOOLEAN APIENTRY
632 AlphaBltMask(SURFOBJ
* psoDest
,
633 SURFOBJ
* psoSource
, // unused
635 XLATEOBJ
* pxloRGB2Dest
,
638 POINTL
* pptlSource
, // unused
645 ULONG Background
, BrushColor
, NewColor
;
648 ASSERT(psoSource
== NULL
);
649 ASSERT(pptlSource
== NULL
);
651 dx
= prclDest
->right
- prclDest
->left
;
652 dy
= prclDest
->bottom
- prclDest
->top
;
656 BrushColor
= XLATEOBJ_iXlate(pxloBrush
, pbo
? pbo
->iSolidColor
: 0);
657 r
= (int)GetRValue(BrushColor
);
658 g
= (int)GetGValue(BrushColor
);
659 b
= (int)GetBValue(BrushColor
);
661 tMask
= (PBYTE
)psoMask
->pvScan0
+ (pptlMask
->y
* psoMask
->lDelta
) + pptlMask
->x
;
662 for (j
= 0; j
< dy
; j
++)
665 for (i
= 0; i
< dx
; i
++)
671 DibFunctionsForBitmapFormat
[psoDest
->iBitmapFormat
].DIB_PutPixel(
672 psoDest
, prclDest
->left
+ i
, prclDest
->top
+ j
, pbo
? pbo
->iSolidColor
: 0);
676 Background
= DIB_GetSource(psoDest
, prclDest
->left
+ i
, prclDest
->top
+ j
,
680 RGB((*lMask
* (r
- GetRValue(Background
)) >> 8) + GetRValue(Background
),
681 (*lMask
* (g
- GetGValue(Background
)) >> 8) + GetGValue(Background
),
682 (*lMask
* (b
- GetBValue(Background
)) >> 8) + GetBValue(Background
));
684 Background
= XLATEOBJ_iXlate(pxloRGB2Dest
, NewColor
);
685 DibFunctionsForBitmapFormat
[psoDest
->iBitmapFormat
].DIB_PutPixel(
686 psoDest
, prclDest
->left
+ i
, prclDest
->top
+ j
, Background
);
691 tMask
+= psoMask
->lDelta
;
703 EngMaskBitBlt(SURFOBJ
*psoDest
,
706 XLATEOBJ
*DestColorTranslation
,
707 XLATEOBJ
*SourceColorTranslation
,
721 INTENG_ENTER_LEAVE EnterLeaveSource
;
722 INTENG_ENTER_LEAVE EnterLeaveDest
;
730 POINTL AdjustedBrushOrigin
;
736 InputRect
.left
= pptlMask
->x
;
737 InputRect
.right
= pptlMask
->x
+ (DestRect
->right
- DestRect
->left
);
738 InputRect
.top
= pptlMask
->y
;
739 InputRect
.bottom
= pptlMask
->y
+ (DestRect
->bottom
- DestRect
->top
);
744 InputRect
.right
= DestRect
->right
- DestRect
->left
;
746 InputRect
.bottom
= DestRect
->bottom
- DestRect
->top
;
749 OutputRect
= *DestRect
;
750 if (NULL
!= ClipRegion
)
752 if (OutputRect
.left
< ClipRegion
->rclBounds
.left
)
754 InputRect
.left
+= ClipRegion
->rclBounds
.left
- OutputRect
.left
;
755 OutputRect
.left
= ClipRegion
->rclBounds
.left
;
757 if (ClipRegion
->rclBounds
.right
< OutputRect
.right
)
759 InputRect
.right
-= OutputRect
.right
- ClipRegion
->rclBounds
.right
;
760 OutputRect
.right
= ClipRegion
->rclBounds
.right
;
762 if (OutputRect
.top
< ClipRegion
->rclBounds
.top
)
764 InputRect
.top
+= ClipRegion
->rclBounds
.top
- OutputRect
.top
;
765 OutputRect
.top
= ClipRegion
->rclBounds
.top
;
767 if (ClipRegion
->rclBounds
.bottom
< OutputRect
.bottom
)
769 InputRect
.bottom
-= OutputRect
.bottom
- ClipRegion
->rclBounds
.bottom
;
770 OutputRect
.bottom
= ClipRegion
->rclBounds
.bottom
;
774 if (! IntEngEnter(&EnterLeaveSource
, psoMask
, &InputRect
, TRUE
, &Translate
, &psoInput
))
779 InputPoint
.x
= InputRect
.left
+ Translate
.x
;
780 InputPoint
.y
= InputRect
.top
+ Translate
.y
;
782 /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
784 if (OutputRect
.right
<= OutputRect
.left
|| OutputRect
.bottom
<= OutputRect
.top
)
786 IntEngLeave(&EnterLeaveSource
);
790 if (! IntEngEnter(&EnterLeaveDest
, psoDest
, &OutputRect
, FALSE
, &Translate
, &psoOutput
))
792 IntEngLeave(&EnterLeaveSource
);
796 OutputRect
.left
= DestRect
->left
+ Translate
.x
;
797 OutputRect
.right
= DestRect
->right
+ Translate
.x
;
798 OutputRect
.top
= DestRect
->top
+ Translate
.y
;
799 OutputRect
.bottom
= DestRect
->bottom
+ Translate
.y
;
803 AdjustedBrushOrigin
.x
= BrushOrigin
->x
+ Translate
.x
;
804 AdjustedBrushOrigin
.y
= BrushOrigin
->y
+ Translate
.y
;
807 AdjustedBrushOrigin
= Translate
;
809 // Determine clipping type
810 if (ClipRegion
== (CLIPOBJ
*) NULL
)
812 clippingType
= DC_TRIVIAL
;
814 clippingType
= ClipRegion
->iDComplexity
;
817 switch (clippingType
)
820 if (psoMask
->iBitmapFormat
== BMF_8BPP
)
821 Ret
= AlphaBltMask(psoOutput
, NULL
, psoInput
, DestColorTranslation
, SourceColorTranslation
,
822 &OutputRect
, NULL
, &InputPoint
, pbo
, &AdjustedBrushOrigin
);
824 Ret
= BltMask(psoOutput
, NULL
, psoInput
, DestColorTranslation
,
825 &OutputRect
, NULL
, &InputPoint
, pbo
, &AdjustedBrushOrigin
,
829 // Clip the blt to the clip rectangle
830 ClipRect
.left
= ClipRegion
->rclBounds
.left
+ Translate
.x
;
831 ClipRect
.right
= ClipRegion
->rclBounds
.right
+ Translate
.x
;
832 ClipRect
.top
= ClipRegion
->rclBounds
.top
+ Translate
.y
;
833 ClipRect
.bottom
= ClipRegion
->rclBounds
.bottom
+ Translate
.y
;
834 if (RECTL_bIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
836 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
837 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
838 if (psoMask
->iBitmapFormat
== BMF_8BPP
)
840 Ret
= AlphaBltMask(psoOutput
, NULL
, psoInput
, DestColorTranslation
, SourceColorTranslation
,
841 &CombinedRect
, NULL
, &Pt
, pbo
, &AdjustedBrushOrigin
);
845 Ret
= BltMask(psoOutput
, NULL
, psoInput
, DestColorTranslation
,
846 &CombinedRect
, NULL
, &Pt
, pbo
, &AdjustedBrushOrigin
, R4_MASK
);
852 if (psoOutput
== psoInput
)
854 if (OutputRect
.top
< InputPoint
.y
)
856 Direction
= OutputRect
.left
< InputPoint
.x
? CD_RIGHTDOWN
: CD_LEFTDOWN
;
860 Direction
= OutputRect
.left
< InputPoint
.x
? CD_RIGHTUP
: CD_LEFTUP
;
867 CLIPOBJ_cEnumStart(ClipRegion
, FALSE
, CT_RECTANGLES
, Direction
, 0);
870 EnumMore
= CLIPOBJ_bEnum(ClipRegion
,(ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
872 for (i
= 0; i
< RectEnum
.c
; i
++)
874 ClipRect
.left
= RectEnum
.arcl
[i
].left
+ Translate
.x
;
875 ClipRect
.right
= RectEnum
.arcl
[i
].right
+ Translate
.x
;
876 ClipRect
.top
= RectEnum
.arcl
[i
].top
+ Translate
.y
;
877 ClipRect
.bottom
= RectEnum
.arcl
[i
].bottom
+ Translate
.y
;
878 if (RECTL_bIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
880 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
881 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
882 if (psoMask
->iBitmapFormat
== BMF_8BPP
)
884 Ret
= AlphaBltMask(psoOutput
, NULL
, psoInput
,
885 DestColorTranslation
,
886 SourceColorTranslation
,
887 &CombinedRect
, NULL
, &Pt
, pbo
,
888 &AdjustedBrushOrigin
) && Ret
;
892 Ret
= BltMask(psoOutput
, NULL
, psoInput
,
893 DestColorTranslation
, &CombinedRect
, NULL
,
894 &Pt
, pbo
, &AdjustedBrushOrigin
,
905 IntEngLeave(&EnterLeaveDest
);
906 IntEngLeave(&EnterLeaveSource
);
912 IntEngMaskBlt(SURFOBJ
*psoDest
,
915 XLATEOBJ
*DestColorTranslation
,
916 XLATEOBJ
*SourceColorTranslation
,
931 InputPoint
= *pptlMask
;
934 /* Clip against the bounds of the clipping region so we won't try to write
935 * outside the surface */
936 if (NULL
!= ClipRegion
)
938 if (!RECTL_bIntersectRect(&OutputRect
, DestRect
, &ClipRegion
->rclBounds
))
942 InputPoint
.x
+= OutputRect
.left
- DestRect
->left
;
943 InputPoint
.y
+= OutputRect
.top
- DestRect
->top
;
947 OutputRect
= *DestRect
;
953 psurfDest
= CONTAINING_RECORD(psoDest
, SURFACE
, SurfObj
);
955 /* Dummy BitBlt to let driver know that it should flush its changes.
956 This should really be done using a call to DrvSynchronizeSurface,
957 but the VMware driver doesn't hook that call. */
958 IntEngBitBlt(psoDest
, NULL
, psoMask
, ClipRegion
, DestColorTranslation
,
959 DestRect
, pptlMask
, pptlMask
, pbo
, BrushOrigin
,
962 ret
= EngMaskBitBlt(psoDest
, psoMask
, ClipRegion
, DestColorTranslation
, SourceColorTranslation
,
963 &OutputRect
, &InputPoint
, pbo
, BrushOrigin
);
965 /* Dummy BitBlt to let driver know that something has changed. */
966 IntEngBitBlt(psoDest
, NULL
, psoMask
, ClipRegion
, DestColorTranslation
,
967 DestRect
, pptlMask
, pptlMask
, pbo
, BrushOrigin
,