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
;
59 if (pbo
&& pbo
->iSolidColor
== 0xFFFFFFFF)
61 pebo
= CONTAINING_RECORD(pbo
, EBRUSHOBJ
, BrushObject
);
63 hbmPattern
= EBRUSHOBJ_pvGetEngBrush(pebo
);
64 psurfPattern
= SURFACE_LockSurface(hbmPattern
);
65 if (psurfPattern
!= NULL
)
67 psoPattern
= &psurfPattern
->SurfObj
;
68 PatternWidth
= psoPattern
->sizlBitmap
.cx
;
69 PatternHeight
= psoPattern
->sizlBitmap
.cy
;
70 fnPattern_GetPixel
= DibFunctionsForBitmapFormat
[psoPattern
->iBitmapFormat
].DIB_GetPixel
;
76 pjMskLine
= (PBYTE
)psoMask
->pvScan0
+ pptlMask
->y
* psoMask
->lDelta
+ (pptlMask
->x
>> 3);
77 fjMaskBit0
= 0x80 >> (pptlMask
->x
& 0x07);
79 fnDest_PutPixel
= DibFunctionsForBitmapFormat
[psoDest
->iBitmapFormat
].DIB_PutPixel
;
82 PatternY
= (prclDest
->top
- pptlBrush
->y
) % PatternHeight
;
85 PatternY
+= PatternHeight
;
87 PatternX0
= (prclDest
->left
- pptlBrush
->x
) % PatternWidth
;
90 PatternX0
+= PatternWidth
;
93 for (y
= prclDest
->top
; y
< prclDest
->bottom
; y
++)
95 pjMskCurrent
= pjMskLine
;
96 fjMaskBit
= fjMaskBit0
;
99 for (x
= prclDest
->left
; x
< prclDest
->right
; x
++)
101 if (*pjMskCurrent
& fjMaskBit
)
103 fnDest_PutPixel(psoDest
, x
, y
,
104 fnPattern_GetPixel(psoPattern
, PatternX
, PatternY
));
106 fjMaskBit
= _rotr8(fjMaskBit
, 1);
107 pjMskCurrent
+= (fjMaskBit
>> 7);
109 PatternX
%= PatternWidth
;
111 pjMskLine
+= psoMask
->lDelta
;
113 PatternY
%= PatternHeight
;
118 Pattern
= pbo
? pbo
->iSolidColor
: 0;
119 for (y
= prclDest
->top
; y
< prclDest
->bottom
; y
++)
121 pjMskCurrent
= pjMskLine
;
122 fjMaskBit
= fjMaskBit0
;
124 for (x
= prclDest
->left
; x
< prclDest
->right
; x
++)
126 if (*pjMskCurrent
& fjMaskBit
)
128 fnDest_PutPixel(psoDest
, x
, y
, Pattern
);
130 fjMaskBit
= _rotr8(fjMaskBit
, 1);
131 pjMskCurrent
+= (fjMaskBit
>> 7);
133 pjMskLine
+= psoMask
->lDelta
;
138 SURFACE_UnlockSurface(psurfPattern
);
143 static BOOLEAN APIENTRY
144 BltPatCopy(SURFOBJ
* Dest
,
147 XLATEOBJ
* ColorTranslation
,
155 // These functions are assigned if we're working with a DIB
156 // The assigned functions depend on the bitsPerPixel of the DIB
158 DibFunctionsForBitmapFormat
[Dest
->iBitmapFormat
].DIB_ColorFill(Dest
, DestRect
, pbo
? pbo
->iSolidColor
: 0);
163 static BOOLEAN APIENTRY
164 CallDibBitBlt(SURFOBJ
* OutputObj
,
167 XLATEOBJ
* ColorTranslation
,
176 PEBRUSHOBJ GdiBrush
= NULL
;
177 SURFACE
*psurfPattern
;
181 BltInfo
.DestSurface
= OutputObj
;
182 BltInfo
.SourceSurface
= InputObj
;
183 BltInfo
.PatternSurface
= NULL
;
184 BltInfo
.XlateSourceToDest
= ColorTranslation
;
185 BltInfo
.DestRect
= *OutputRect
;
186 BltInfo
.SourcePoint
= *InputPoint
;
188 if (ROP3_TO_ROP4(SRCCOPY
) == Rop4
)
189 return DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_BitBltSrcCopy(&BltInfo
);
192 BltInfo
.BrushOrigin
= *BrushOrigin
;
196 if (ROP4_USES_PATTERN(Rop4
) && pbo
&& pbo
->iSolidColor
== 0xFFFFFFFF)
198 GdiBrush
= CONTAINING_RECORD(pbo
, EBRUSHOBJ
, BrushObject
);
199 hbmPattern
= EBRUSHOBJ_pvGetEngBrush(GdiBrush
);
200 psurfPattern
= SURFACE_LockSurface(hbmPattern
);
203 BltInfo
.PatternSurface
= &psurfPattern
->SurfObj
;
207 /* FIXME - What to do here? */
215 Result
= DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_BitBlt(&BltInfo
);
220 SURFACE_UnlockSurface(psurfPattern
);
226 INT __cdecl
abs(INT nm
);
243 IN POINTL
*pptlBrush
,
253 ProbeForRead(prclTrg
, sizeof(RECTL
), 1);
254 RtlCopyMemory(&rclTrg
,prclTrg
, sizeof(RECTL
));
256 ProbeForRead(pptlSrc
, sizeof(POINTL
), 1);
257 RtlCopyMemory(&ptlSrc
, pptlSrc
, sizeof(POINTL
));
259 ProbeForRead(pptlMask
, sizeof(POINTL
), 1);
260 RtlCopyMemory(&ptlMask
, pptlMask
, sizeof(POINTL
));
262 ProbeForRead(pptlBrush
, sizeof(POINTL
), 1);
263 RtlCopyMemory(&ptlBrush
, pptlBrush
, sizeof(POINTL
));
266 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
268 _SEH2_YIELD(return FALSE
);
272 return EngBitBlt(psoTrg
, psoSrc
, psoMask
, pco
, pxlo
, &rclTrg
, &ptlSrc
, &ptlMask
, pbo
, &ptlBrush
, rop4
);
279 EngBitBlt(SURFOBJ
*DestObj
,
283 XLATEOBJ
*ColorTranslation
,
298 SURFOBJ
* InputObj
= 0;
300 PBLTRECTFUNC BltRectFunc
;
308 POINTL AdjustedBrushOrigin
;
310 UsesSource
= ROP4_USES_SOURCE(rop4
);
311 UsesPattern
= ROP4_USES_PATTERN(rop4
);
314 /* Copy destination onto itself: nop */
318 OutputRect
= *DestRect
;
319 if (OutputRect
.right
< OutputRect
.left
)
321 OutputRect
.left
= DestRect
->right
;
322 OutputRect
.right
= DestRect
->left
;
324 if (OutputRect
.bottom
< OutputRect
.top
)
326 OutputRect
.left
= DestRect
->right
;
327 OutputRect
.right
= DestRect
->left
;
332 if (NULL
== SourcePoint
)
337 /* Make sure we don't try to copy anything outside the valid source
339 InputPoint
= *SourcePoint
;
340 if (InputPoint
.x
< 0)
342 OutputRect
.left
-= InputPoint
.x
;
345 if (InputPoint
.y
< 0)
347 OutputRect
.top
-= InputPoint
.y
;
350 if (SourceObj
->sizlBitmap
.cx
< InputPoint
.x
+
351 OutputRect
.right
- OutputRect
.left
)
353 OutputRect
.right
= OutputRect
.left
+
354 SourceObj
->sizlBitmap
.cx
- InputPoint
.x
;
356 if (SourceObj
->sizlBitmap
.cy
< InputPoint
.y
+
357 OutputRect
.bottom
- OutputRect
.top
)
359 OutputRect
.bottom
= OutputRect
.top
+
360 SourceObj
->sizlBitmap
.cy
- InputPoint
.y
;
363 InputRect
.left
= InputPoint
.x
;
364 InputRect
.right
= InputPoint
.x
+ (OutputRect
.right
- OutputRect
.left
);
365 InputRect
.top
= InputPoint
.y
;
366 InputRect
.bottom
= InputPoint
.y
+ (OutputRect
.bottom
- OutputRect
.top
);
368 InputObj
= SourceObj
;
373 InputRect
.right
= DestRect
->right
- DestRect
->left
;
375 InputRect
.bottom
= DestRect
->bottom
- DestRect
->top
;
378 if (NULL
!= ClipRegion
)
380 if (OutputRect
.left
< ClipRegion
->rclBounds
.left
)
382 InputRect
.left
+= ClipRegion
->rclBounds
.left
- OutputRect
.left
;
383 InputPoint
.x
+= ClipRegion
->rclBounds
.left
- OutputRect
.left
;
384 OutputRect
.left
= ClipRegion
->rclBounds
.left
;
386 if (ClipRegion
->rclBounds
.right
< OutputRect
.right
)
388 InputRect
.right
-= OutputRect
.right
- ClipRegion
->rclBounds
.right
;
389 OutputRect
.right
= ClipRegion
->rclBounds
.right
;
391 if (OutputRect
.top
< ClipRegion
->rclBounds
.top
)
393 InputRect
.top
+= ClipRegion
->rclBounds
.top
- OutputRect
.top
;
394 InputPoint
.y
+= ClipRegion
->rclBounds
.top
- OutputRect
.top
;
395 OutputRect
.top
= ClipRegion
->rclBounds
.top
;
397 if (ClipRegion
->rclBounds
.bottom
< OutputRect
.bottom
)
399 InputRect
.bottom
-= OutputRect
.bottom
- ClipRegion
->rclBounds
.bottom
;
400 OutputRect
.bottom
= ClipRegion
->rclBounds
.bottom
;
404 /* Check for degenerate case: if height or width of OutputRect is 0 pixels
405 there's nothing to do */
406 if (OutputRect
.right
<= OutputRect
.left
||
407 OutputRect
.bottom
<= OutputRect
.top
)
416 AdjustedBrushOrigin
.x
= BrushOrigin
->x
;
417 AdjustedBrushOrigin
.y
= BrushOrigin
->y
;
421 AdjustedBrushOrigin
.x
= 0;
422 AdjustedBrushOrigin
.y
= 0;
425 /* Determine clipping type */
426 if (ClipRegion
== (CLIPOBJ
*) NULL
)
428 clippingType
= DC_TRIVIAL
;
432 clippingType
= ClipRegion
->iDComplexity
;
437 BltRectFunc
= BltMask
;
439 else if (ROP3_TO_ROP4(PATCOPY
) == rop4
)
441 if (pbo
&& pbo
->iSolidColor
== 0xFFFFFFFF)
442 BltRectFunc
= CallDibBitBlt
;
444 BltRectFunc
= BltPatCopy
;
448 BltRectFunc
= CallDibBitBlt
;
452 switch (clippingType
)
455 Ret
= (*BltRectFunc
)(OutputObj
, InputObj
, Mask
, ColorTranslation
,
456 &OutputRect
, &InputPoint
, MaskOrigin
, pbo
,
457 &AdjustedBrushOrigin
, rop4
);
460 /* Clip the blt to the clip rectangle */
461 ClipRect
.left
= ClipRegion
->rclBounds
.left
;
462 ClipRect
.right
= ClipRegion
->rclBounds
.right
;
463 ClipRect
.top
= ClipRegion
->rclBounds
.top
;
464 ClipRect
.bottom
= ClipRegion
->rclBounds
.bottom
;
465 if (RECTL_bIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
467 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
468 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
469 Ret
= (*BltRectFunc
)(OutputObj
, InputObj
, Mask
, ColorTranslation
,
470 &CombinedRect
, &Pt
, MaskOrigin
, pbo
,
471 &AdjustedBrushOrigin
, rop4
);
476 if (OutputObj
== InputObj
)
478 if (OutputRect
.top
< InputPoint
.y
)
480 Direction
= OutputRect
.left
< InputPoint
.x
?
481 CD_RIGHTDOWN
: CD_LEFTDOWN
;
485 Direction
= OutputRect
.left
< InputPoint
.x
?
486 CD_RIGHTUP
: CD_LEFTUP
;
493 CLIPOBJ_cEnumStart(ClipRegion
, FALSE
, CT_RECTANGLES
, Direction
, 0);
496 EnumMore
= CLIPOBJ_bEnum(ClipRegion
,(ULONG
) sizeof(RectEnum
),
499 for (i
= 0; i
< RectEnum
.c
; i
++)
501 ClipRect
.left
= RectEnum
.arcl
[i
].left
;
502 ClipRect
.right
= RectEnum
.arcl
[i
].right
;
503 ClipRect
.top
= RectEnum
.arcl
[i
].top
;
504 ClipRect
.bottom
= RectEnum
.arcl
[i
].bottom
;
505 if (RECTL_bIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
507 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
508 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
509 Ret
= (*BltRectFunc
)(OutputObj
, InputObj
, Mask
,
510 ColorTranslation
, &CombinedRect
, &Pt
,
511 MaskOrigin
, pbo
, &AdjustedBrushOrigin
,
539 SURFACE
*psurfSrc
= NULL
;
543 // INTENG_ENTER_LEAVE EnterLeaveSource;
544 // INTENG_ENTER_LEAVE EnterLeaveDest;
545 PFN_DrvBitBlt pfnBitBlt
;
548 psurfTrg
= CONTAINING_RECORD(psoTrg
, SURFACE
, SurfObj
);
550 /* FIXME: Should we really allow to pass non-well-ordered rects? */
551 rclClipped
= *prclTrg
;
552 RECTL_vMakeWellOrdered(&rclClipped
);
554 /* Clip target rect against the bounds of the clipping region */
557 if (!RECTL_bIntersectRect(&rclClipped
, &rclClipped
, &pco
->rclBounds
))
563 /* Don't pass a clipobj with only a single rect */
564 if (pco
->iDComplexity
== DC_RECT
)
568 if (ROP4_USES_SOURCE(rop4
))
571 psurfSrc
= CONTAINING_RECORD(psoSrc
, SURFACE
, SurfObj
);
573 /* Calculate source rect */
574 rclSrc
.left
= pptlSrc
->x
+ rclClipped
.left
- prclTrg
->left
;
575 rclSrc
.top
= pptlSrc
->y
+ rclClipped
.top
- prclTrg
->top
;
576 rclSrc
.right
= rclSrc
.left
+ rclClipped
.right
- rclClipped
.left
;
577 rclSrc
.bottom
= rclSrc
.top
+ rclClipped
.bottom
- rclClipped
.top
;
587 SURFACE_LockBitmapBits(psurfTrg
);
591 if (psoSrc
!= psoTrg
)
593 SURFACE_LockBitmapBits(psurfSrc
);
595 MouseSafetyOnDrawStart(psoSrc
, rclSrc
.left
, rclSrc
.top
,
596 rclSrc
.right
, rclSrc
.bottom
);
598 MouseSafetyOnDrawStart(psoTrg
, rclClipped
.left
, rclClipped
.top
,
599 rclClipped
.right
, rclClipped
.bottom
);
602 /* Is the target surface device managed? */
603 if (psurfTrg
->flHooks
& HOOK_BITBLT
)
605 /* Is the source a different device managed surface? */
606 if (psoSrc
&& psoSrc
->hdev
!= psoTrg
->hdev
&& psurfSrc
->flHooks
& HOOK_BITBLT
)
608 DPRINT1("Need to copy to standard bitmap format!\n");
612 pfnBitBlt
= GDIDEVFUNCS(psoTrg
).BitBlt
;
615 /* Is the source surface device managed? */
616 else if (psoSrc
&& psurfSrc
->flHooks
& HOOK_BITBLT
)
618 pfnBitBlt
= GDIDEVFUNCS(psoSrc
).BitBlt
;
622 pfnBitBlt
= EngBitBlt
;
625 bResult
= pfnBitBlt(psoTrg
,
637 // FIXME: cleanup temp surface!
641 MouseSafetyOnDrawEnd(psoTrg
);
644 MouseSafetyOnDrawEnd(psoSrc
);
645 if (psoSrc
!= psoTrg
)
647 SURFACE_UnlockBitmapBits(psurfSrc
);
651 SURFACE_UnlockBitmapBits(psurfTrg
);
658 /**** REACTOS FONT RENDERING CODE *********************************************/
660 /* renders the alpha mask bitmap */
661 static BOOLEAN APIENTRY
662 AlphaBltMask(SURFOBJ
* psoDest
,
663 SURFOBJ
* psoSource
, // unused
665 XLATEOBJ
* ColorTranslation
,
666 XLATEOBJ
* SrcColorTranslation
,
668 POINTL
* pptlSource
, // unused
675 ULONG Background
, BrushColor
, NewColor
;
678 dx
= prclDest
->right
- prclDest
->left
;
679 dy
= prclDest
->bottom
- prclDest
->top
;
683 BrushColor
= XLATEOBJ_iXlate(SrcColorTranslation
, pbo
? pbo
->iSolidColor
: 0);
684 r
= (int)GetRValue(BrushColor
);
685 g
= (int)GetGValue(BrushColor
);
686 b
= (int)GetBValue(BrushColor
);
688 tMask
= (PBYTE
)psoMask
->pvScan0
+ (pptlMask
->y
* psoMask
->lDelta
) + pptlMask
->x
;
689 for (j
= 0; j
< dy
; j
++)
692 for (i
= 0; i
< dx
; i
++)
698 DibFunctionsForBitmapFormat
[psoDest
->iBitmapFormat
].DIB_PutPixel(
699 psoDest
, prclDest
->left
+ i
, prclDest
->top
+ j
, pbo
? pbo
->iSolidColor
: 0);
703 Background
= DIB_GetSource(psoDest
, prclDest
->left
+ i
, prclDest
->top
+ j
,
704 SrcColorTranslation
);
707 RGB((*lMask
* (r
- GetRValue(Background
)) >> 8) + GetRValue(Background
),
708 (*lMask
* (g
- GetGValue(Background
)) >> 8) + GetGValue(Background
),
709 (*lMask
* (b
- GetBValue(Background
)) >> 8) + GetBValue(Background
));
711 Background
= XLATEOBJ_iXlate(ColorTranslation
, NewColor
);
712 DibFunctionsForBitmapFormat
[psoDest
->iBitmapFormat
].DIB_PutPixel(
713 psoDest
, prclDest
->left
+ i
, prclDest
->top
+ j
, Background
);
718 tMask
+= psoMask
->lDelta
;
730 EngMaskBitBlt(SURFOBJ
*psoDest
,
733 XLATEOBJ
*DestColorTranslation
,
734 XLATEOBJ
*SourceColorTranslation
,
748 INTENG_ENTER_LEAVE EnterLeaveSource
;
749 INTENG_ENTER_LEAVE EnterLeaveDest
;
757 POINTL AdjustedBrushOrigin
;
763 InputRect
.left
= pptlMask
->x
;
764 InputRect
.right
= pptlMask
->x
+ (DestRect
->right
- DestRect
->left
);
765 InputRect
.top
= pptlMask
->y
;
766 InputRect
.bottom
= pptlMask
->y
+ (DestRect
->bottom
- DestRect
->top
);
771 InputRect
.right
= DestRect
->right
- DestRect
->left
;
773 InputRect
.bottom
= DestRect
->bottom
- DestRect
->top
;
776 OutputRect
= *DestRect
;
777 if (NULL
!= ClipRegion
)
779 if (OutputRect
.left
< ClipRegion
->rclBounds
.left
)
781 InputRect
.left
+= ClipRegion
->rclBounds
.left
- OutputRect
.left
;
782 OutputRect
.left
= ClipRegion
->rclBounds
.left
;
784 if (ClipRegion
->rclBounds
.right
< OutputRect
.right
)
786 InputRect
.right
-= OutputRect
.right
- ClipRegion
->rclBounds
.right
;
787 OutputRect
.right
= ClipRegion
->rclBounds
.right
;
789 if (OutputRect
.top
< ClipRegion
->rclBounds
.top
)
791 InputRect
.top
+= ClipRegion
->rclBounds
.top
- OutputRect
.top
;
792 OutputRect
.top
= ClipRegion
->rclBounds
.top
;
794 if (ClipRegion
->rclBounds
.bottom
< OutputRect
.bottom
)
796 InputRect
.bottom
-= OutputRect
.bottom
- ClipRegion
->rclBounds
.bottom
;
797 OutputRect
.bottom
= ClipRegion
->rclBounds
.bottom
;
801 if (! IntEngEnter(&EnterLeaveSource
, psoMask
, &InputRect
, TRUE
, &Translate
, &psoInput
))
806 InputPoint
.x
= InputRect
.left
+ Translate
.x
;
807 InputPoint
.y
= InputRect
.top
+ Translate
.y
;
809 /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
811 if (OutputRect
.right
<= OutputRect
.left
|| OutputRect
.bottom
<= OutputRect
.top
)
813 IntEngLeave(&EnterLeaveSource
);
817 if (! IntEngEnter(&EnterLeaveDest
, psoDest
, &OutputRect
, FALSE
, &Translate
, &psoOutput
))
819 IntEngLeave(&EnterLeaveSource
);
823 OutputRect
.left
= DestRect
->left
+ Translate
.x
;
824 OutputRect
.right
= DestRect
->right
+ Translate
.x
;
825 OutputRect
.top
= DestRect
->top
+ Translate
.y
;
826 OutputRect
.bottom
= DestRect
->bottom
+ Translate
.y
;
830 AdjustedBrushOrigin
.x
= BrushOrigin
->x
+ Translate
.x
;
831 AdjustedBrushOrigin
.y
= BrushOrigin
->y
+ Translate
.y
;
834 AdjustedBrushOrigin
= Translate
;
836 // Determine clipping type
837 if (ClipRegion
== (CLIPOBJ
*) NULL
)
839 clippingType
= DC_TRIVIAL
;
841 clippingType
= ClipRegion
->iDComplexity
;
844 switch (clippingType
)
847 if (psoMask
->iBitmapFormat
== BMF_8BPP
)
848 Ret
= AlphaBltMask(psoOutput
, NULL
, psoInput
, DestColorTranslation
, SourceColorTranslation
,
849 &OutputRect
, &InputPoint
, pptlMask
, pbo
, &AdjustedBrushOrigin
);
851 Ret
= BltMask(psoOutput
, NULL
, psoInput
, DestColorTranslation
,
852 &OutputRect
, &InputPoint
, pptlMask
, pbo
, &AdjustedBrushOrigin
,
856 // Clip the blt to the clip rectangle
857 ClipRect
.left
= ClipRegion
->rclBounds
.left
+ Translate
.x
;
858 ClipRect
.right
= ClipRegion
->rclBounds
.right
+ Translate
.x
;
859 ClipRect
.top
= ClipRegion
->rclBounds
.top
+ Translate
.y
;
860 ClipRect
.bottom
= ClipRegion
->rclBounds
.bottom
+ Translate
.y
;
861 if (RECTL_bIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
863 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
864 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
865 if (psoMask
->iBitmapFormat
== BMF_8BPP
)
867 Ret
= AlphaBltMask(psoOutput
, psoInput
, psoMask
, DestColorTranslation
, SourceColorTranslation
,
868 &CombinedRect
, &Pt
, pptlMask
, pbo
, &AdjustedBrushOrigin
);
872 Ret
= BltMask(psoOutput
, psoInput
, psoMask
, DestColorTranslation
,
873 &CombinedRect
, &Pt
, pptlMask
, pbo
, &AdjustedBrushOrigin
, R4_MASK
);
879 if (psoOutput
== psoInput
)
881 if (OutputRect
.top
< InputPoint
.y
)
883 Direction
= OutputRect
.left
< InputPoint
.x
? CD_RIGHTDOWN
: CD_LEFTDOWN
;
887 Direction
= OutputRect
.left
< InputPoint
.x
? CD_RIGHTUP
: CD_LEFTUP
;
894 CLIPOBJ_cEnumStart(ClipRegion
, FALSE
, CT_RECTANGLES
, Direction
, 0);
897 EnumMore
= CLIPOBJ_bEnum(ClipRegion
,(ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
899 for (i
= 0; i
< RectEnum
.c
; i
++)
901 ClipRect
.left
= RectEnum
.arcl
[i
].left
+ Translate
.x
;
902 ClipRect
.right
= RectEnum
.arcl
[i
].right
+ Translate
.x
;
903 ClipRect
.top
= RectEnum
.arcl
[i
].top
+ Translate
.y
;
904 ClipRect
.bottom
= RectEnum
.arcl
[i
].bottom
+ Translate
.y
;
905 if (RECTL_bIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
907 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
908 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
909 if (psoMask
->iBitmapFormat
== BMF_8BPP
)
911 Ret
= AlphaBltMask(psoOutput
, psoInput
, psoMask
,
912 DestColorTranslation
,
913 SourceColorTranslation
,
914 &CombinedRect
, &Pt
, pptlMask
, pbo
,
915 &AdjustedBrushOrigin
) && Ret
;
919 Ret
= BltMask(psoOutput
, psoInput
, psoMask
,
920 DestColorTranslation
, &CombinedRect
, &Pt
,
921 pptlMask
, pbo
, &AdjustedBrushOrigin
,
932 IntEngLeave(&EnterLeaveDest
);
933 IntEngLeave(&EnterLeaveSource
);
939 IntEngMaskBlt(SURFOBJ
*psoDest
,
942 XLATEOBJ
*DestColorTranslation
,
943 XLATEOBJ
*SourceColorTranslation
,
958 InputPoint
= *pptlMask
;
961 /* Clip against the bounds of the clipping region so we won't try to write
962 * outside the surface */
963 if (NULL
!= ClipRegion
)
965 if (!RECTL_bIntersectRect(&OutputRect
, DestRect
, &ClipRegion
->rclBounds
))
969 InputPoint
.x
+= OutputRect
.left
- DestRect
->left
;
970 InputPoint
.y
+= OutputRect
.top
- DestRect
->top
;
974 OutputRect
= *DestRect
;
980 psurfDest
= CONTAINING_RECORD(psoDest
, SURFACE
, SurfObj
);
982 SURFACE_LockBitmapBits(psurfDest
);
983 MouseSafetyOnDrawStart(psoDest
, OutputRect
.left
, OutputRect
.top
,
984 OutputRect
.right
, OutputRect
.bottom
);
986 /* Dummy BitBlt to let driver know that it should flush its changes.
987 This should really be done using a call to DrvSynchronizeSurface,
988 but the VMware driver doesn't hook that call. */
989 IntEngBitBltEx(psoDest
, NULL
, psoMask
, ClipRegion
, DestColorTranslation
,
990 DestRect
, pptlMask
, pptlMask
, pbo
, BrushOrigin
,
993 ret
= EngMaskBitBlt(psoDest
, psoMask
, ClipRegion
, DestColorTranslation
, SourceColorTranslation
,
994 &OutputRect
, &InputPoint
, pbo
, BrushOrigin
);
996 /* Dummy BitBlt to let driver know that something has changed. */
997 IntEngBitBltEx(psoDest
, NULL
, psoMask
, ClipRegion
, DestColorTranslation
,
998 DestRect
, pptlMask
, pptlMask
, pbo
, BrushOrigin
,
1001 MouseSafetyOnDrawEnd(psoDest
);
1002 SURFACE_UnlockBitmapBits(psurfDest
);