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
15 typedef BOOLEAN (APIENTRY
*PBLTRECTFUNC
)(SURFOBJ
* OutputObj
,
18 XLATEOBJ
* ColorTranslation
,
26 static BOOLEAN APIENTRY
27 BltMask(SURFOBJ
* psoDest
,
30 XLATEOBJ
* ColorTranslation
,
39 BYTE
*pjMskLine
, *pjMskCurrent
;
40 BYTE fjMaskBit0
, fjMaskBit
;
42 PEBRUSHOBJ pebo
= NULL
;
43 SURFOBJ
*psoPattern
= NULL
;
44 PSURFACE psurfPattern
;
45 ULONG PatternWidth
= 0, PatternHeight
= 0;
46 LONG PatternX0
= 0, PatternX
= 0, PatternY
= 0;
47 LONG SrcX
= 0, SrcY
= 0;
48 PFN_DIB_PutPixel fnDest_PutPixel
= NULL
;
49 PFN_DIB_GetPixel fnPattern_GetPixel
= NULL
, fnSrc_GetPixel
= NULL
, fnDest_GetPixel
;
50 ULONG Pattern
= 0, Source
= 0, Dest
= 0;
52 DWORD fgndRop
, bkgndRop
;
54 ASSERT(IS_VALID_ROP4(Rop4
));
56 fgndRop
= ROP4_FGND(Rop4
);
57 bkgndRop
= ROP4_BKGND(Rop4
);
59 //DPRINT1("Rop4 : 0x%08x\n", Rop4);
61 /* Determine pattern */
62 if (pbo
&& pbo
->iSolidColor
== 0xFFFFFFFF)
64 pebo
= CONTAINING_RECORD(pbo
, EBRUSHOBJ
, BrushObject
);
66 hbmPattern
= EBRUSHOBJ_pvGetEngBrush(pebo
);
67 psurfPattern
= SURFACE_ShareLockSurface(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
;
83 fnDest_GetPixel
= DibFunctionsForBitmapFormat
[psoDest
->iBitmapFormat
].DIB_GetPixel
;
85 /* Do we have a source */
89 ASSERT(ROP4_USES_SOURCE(Rop4
));
90 fnSrc_GetPixel
= DibFunctionsForBitmapFormat
[psoSource
->iBitmapFormat
].DIB_GetPixel
;
97 PatternY
= (prclDest
->top
- pptlBrush
->y
) % PatternHeight
;
100 PatternY
+= PatternHeight
;
102 PatternX0
= (prclDest
->left
- pptlBrush
->x
) % PatternWidth
;
105 PatternX0
+= PatternWidth
;
107 PatternX
= PatternX0
;
111 Pattern
= pbo
? pbo
->iSolidColor
: 0;
114 for (y
= prclDest
->top
; y
< prclDest
->bottom
; y
++)
116 pjMskCurrent
= pjMskLine
;
117 fjMaskBit
= fjMaskBit0
;
119 for (x
= prclDest
->left
; x
< prclDest
->right
; x
++)
121 Rop4
= (*pjMskCurrent
& fjMaskBit
) ? fgndRop
: bkgndRop
;
125 if(ROP4_USES_PATTERN(Rop4
))
126 Pattern
= fnPattern_GetPixel(psoPattern
, PatternX
, PatternY
);
128 PatternX
%= PatternWidth
;
133 if(ROP4_USES_SOURCE(Rop4
))
135 Source
= XLATEOBJ_iXlate(ColorTranslation
,
136 fnSrc_GetPixel(psoSource
, SrcX
, SrcY
));
141 if(ROP4_USES_DEST(Rop4
))
142 Dest
= fnDest_GetPixel(psoDest
, x
, y
);
144 fnDest_PutPixel(psoDest
,
151 fjMaskBit
= _rotr8(fjMaskBit
, 1);
152 pjMskCurrent
+= (fjMaskBit
>> 7);
154 pjMskLine
+= psoMask
->lDelta
;
158 PatternY
%= PatternHeight
;
159 PatternX
= PatternX0
;
164 SrcX
= pptlSource
->x
;
169 SURFACE_ShareUnlockSurface(psurfPattern
);
174 static BOOLEAN APIENTRY
175 BltPatCopy(SURFOBJ
* Dest
,
178 XLATEOBJ
* ColorTranslation
,
186 // These functions are assigned if we're working with a DIB
187 // The assigned functions depend on the bitsPerPixel of the DIB
189 DibFunctionsForBitmapFormat
[Dest
->iBitmapFormat
].DIB_ColorFill(Dest
, DestRect
, pbo
? pbo
->iSolidColor
: 0);
194 static BOOLEAN APIENTRY
195 CallDibBitBlt(SURFOBJ
* OutputObj
,
198 XLATEOBJ
* ColorTranslation
,
207 PEBRUSHOBJ GdiBrush
= NULL
;
208 SURFACE
*psurfPattern
;
212 BltInfo
.DestSurface
= OutputObj
;
213 BltInfo
.SourceSurface
= InputObj
;
214 BltInfo
.PatternSurface
= NULL
;
215 BltInfo
.XlateSourceToDest
= ColorTranslation
;
216 BltInfo
.DestRect
= *OutputRect
;
217 BltInfo
.SourcePoint
= *InputPoint
;
219 if ((Rop4
& 0xFF) == R3_OPINDEX_SRCCOPY
)
220 return DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_BitBltSrcCopy(&BltInfo
);
223 BltInfo
.BrushOrigin
= *BrushOrigin
;
227 if (ROP4_USES_PATTERN(Rop4
) && pbo
&& pbo
->iSolidColor
== 0xFFFFFFFF)
229 GdiBrush
= CONTAINING_RECORD(pbo
, EBRUSHOBJ
, BrushObject
);
230 hbmPattern
= EBRUSHOBJ_pvGetEngBrush(GdiBrush
);
231 psurfPattern
= SURFACE_ShareLockSurface(hbmPattern
);
234 BltInfo
.PatternSurface
= &psurfPattern
->SurfObj
;
238 /* FIXME - What to do here? */
246 Result
= DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_BitBlt(&BltInfo
);
251 SURFACE_ShareUnlockSurface(psurfPattern
);
257 INT __cdecl
abs(INT nm
);
274 IN POINTL
*pptlBrush
,
284 ProbeForRead(prclTrg
, sizeof(RECTL
), 1);
285 RtlCopyMemory(&rclTrg
,prclTrg
, sizeof(RECTL
));
287 ProbeForRead(pptlSrc
, sizeof(POINTL
), 1);
288 RtlCopyMemory(&ptlSrc
, pptlSrc
, sizeof(POINTL
));
290 ProbeForRead(pptlMask
, sizeof(POINTL
), 1);
291 RtlCopyMemory(&ptlMask
, pptlMask
, sizeof(POINTL
));
293 ProbeForRead(pptlBrush
, sizeof(POINTL
), 1);
294 RtlCopyMemory(&ptlBrush
, pptlBrush
, sizeof(POINTL
));
297 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
299 _SEH2_YIELD(return FALSE
);
303 return EngBitBlt(psoTrg
, psoSrc
, psoMask
, pco
, pxlo
, &rclTrg
, &ptlSrc
, &ptlMask
, pbo
, &ptlBrush
, Rop4
);
310 EngBitBlt(SURFOBJ
*DestObj
,
314 XLATEOBJ
*ColorTranslation
,
329 SURFOBJ
* InputObj
= 0;
331 PBLTRECTFUNC BltRectFunc
;
337 BOOL UsesSource
, UsesMask
;
338 POINTL AdjustedBrushOrigin
;
340 UsesSource
= ROP4_USES_SOURCE(Rop4
);
341 UsesMask
= ROP4_USES_MASK(Rop4
);
343 if (Rop4
== ROP4_NOOP
)
345 /* Copy destination onto itself: nop */
349 //DPRINT1("Rop4 : 0x%08x\n", Rop4);
351 OutputRect
= *DestRect
;
352 if (OutputRect
.right
< OutputRect
.left
)
354 OutputRect
.left
= DestRect
->right
;
355 OutputRect
.right
= DestRect
->left
;
357 if (OutputRect
.bottom
< OutputRect
.top
)
359 OutputRect
.left
= DestRect
->right
;
360 OutputRect
.right
= DestRect
->left
;
365 if (NULL
== SourcePoint
)
370 /* Make sure we don't try to copy anything outside the valid source
372 InputPoint
= *SourcePoint
;
373 if (InputPoint
.x
< 0)
375 OutputRect
.left
-= InputPoint
.x
;
378 if (InputPoint
.y
< 0)
380 OutputRect
.top
-= InputPoint
.y
;
383 if (SourceObj
->sizlBitmap
.cx
< InputPoint
.x
+
384 OutputRect
.right
- OutputRect
.left
)
386 OutputRect
.right
= OutputRect
.left
+
387 SourceObj
->sizlBitmap
.cx
- InputPoint
.x
;
389 if (SourceObj
->sizlBitmap
.cy
< InputPoint
.y
+
390 OutputRect
.bottom
- OutputRect
.top
)
392 OutputRect
.bottom
= OutputRect
.top
+
393 SourceObj
->sizlBitmap
.cy
- InputPoint
.y
;
396 InputRect
.left
= InputPoint
.x
;
397 InputRect
.right
= InputPoint
.x
+ (OutputRect
.right
- OutputRect
.left
);
398 InputRect
.top
= InputPoint
.y
;
399 InputRect
.bottom
= InputPoint
.y
+ (OutputRect
.bottom
- OutputRect
.top
);
401 InputObj
= SourceObj
;
405 InputPoint
.x
= InputPoint
.y
= 0;
407 InputRect
.right
= DestRect
->right
- DestRect
->left
;
409 InputRect
.bottom
= DestRect
->bottom
- DestRect
->top
;
412 if (NULL
!= ClipRegion
)
414 if (OutputRect
.left
< ClipRegion
->rclBounds
.left
)
416 InputRect
.left
+= ClipRegion
->rclBounds
.left
- OutputRect
.left
;
417 InputPoint
.x
+= ClipRegion
->rclBounds
.left
- OutputRect
.left
;
418 OutputRect
.left
= ClipRegion
->rclBounds
.left
;
420 if (ClipRegion
->rclBounds
.right
< OutputRect
.right
)
422 InputRect
.right
-= OutputRect
.right
- ClipRegion
->rclBounds
.right
;
423 OutputRect
.right
= ClipRegion
->rclBounds
.right
;
425 if (OutputRect
.top
< ClipRegion
->rclBounds
.top
)
427 InputRect
.top
+= ClipRegion
->rclBounds
.top
- OutputRect
.top
;
428 InputPoint
.y
+= ClipRegion
->rclBounds
.top
- OutputRect
.top
;
429 OutputRect
.top
= ClipRegion
->rclBounds
.top
;
431 if (ClipRegion
->rclBounds
.bottom
< OutputRect
.bottom
)
433 InputRect
.bottom
-= OutputRect
.bottom
- ClipRegion
->rclBounds
.bottom
;
434 OutputRect
.bottom
= ClipRegion
->rclBounds
.bottom
;
438 /* Check for degenerate case: if height or width of OutputRect is 0 pixels
439 there's nothing to do */
440 if (OutputRect
.right
<= OutputRect
.left
||
441 OutputRect
.bottom
<= OutputRect
.top
)
450 AdjustedBrushOrigin
.x
= BrushOrigin
->x
;
451 AdjustedBrushOrigin
.y
= BrushOrigin
->y
;
455 AdjustedBrushOrigin
.x
= 0;
456 AdjustedBrushOrigin
.y
= 0;
459 /* Determine clipping type */
460 if (ClipRegion
== (CLIPOBJ
*) NULL
)
462 clippingType
= DC_TRIVIAL
;
466 clippingType
= ClipRegion
->iDComplexity
;
471 BltRectFunc
= BltMask
;
473 else if ((Rop4
& 0xFF) == R3_OPINDEX_PATCOPY
)
475 if (pbo
&& pbo
->iSolidColor
== 0xFFFFFFFF)
476 BltRectFunc
= CallDibBitBlt
;
478 BltRectFunc
= BltPatCopy
;
482 BltRectFunc
= CallDibBitBlt
;
486 switch (clippingType
)
489 Ret
= (*BltRectFunc
)(OutputObj
, InputObj
, Mask
, ColorTranslation
,
490 &OutputRect
, &InputPoint
, MaskOrigin
, pbo
,
491 &AdjustedBrushOrigin
, Rop4
);
494 /* Clip the blt to the clip rectangle */
495 ClipRect
.left
= ClipRegion
->rclBounds
.left
;
496 ClipRect
.right
= ClipRegion
->rclBounds
.right
;
497 ClipRect
.top
= ClipRegion
->rclBounds
.top
;
498 ClipRect
.bottom
= ClipRegion
->rclBounds
.bottom
;
499 if (RECTL_bIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
501 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
502 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
503 Ret
= (*BltRectFunc
)(OutputObj
, InputObj
, Mask
, ColorTranslation
,
504 &CombinedRect
, &Pt
, MaskOrigin
, pbo
,
505 &AdjustedBrushOrigin
, Rop4
);
510 if (OutputObj
== InputObj
)
512 if (OutputRect
.top
< InputPoint
.y
)
514 Direction
= OutputRect
.left
< InputPoint
.x
?
515 CD_RIGHTDOWN
: CD_LEFTDOWN
;
519 Direction
= OutputRect
.left
< InputPoint
.x
?
520 CD_RIGHTUP
: CD_LEFTUP
;
527 CLIPOBJ_cEnumStart(ClipRegion
, FALSE
, CT_RECTANGLES
, Direction
, 0);
530 EnumMore
= CLIPOBJ_bEnum(ClipRegion
,(ULONG
) sizeof(RectEnum
),
533 for (i
= 0; i
< RectEnum
.c
; i
++)
535 ClipRect
.left
= RectEnum
.arcl
[i
].left
;
536 ClipRect
.right
= RectEnum
.arcl
[i
].right
;
537 ClipRect
.top
= RectEnum
.arcl
[i
].top
;
538 ClipRect
.bottom
= RectEnum
.arcl
[i
].bottom
;
539 if (RECTL_bIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
541 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
542 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
543 Ret
= (*BltRectFunc
)(OutputObj
, InputObj
, Mask
,
544 ColorTranslation
, &CombinedRect
, &Pt
,
545 MaskOrigin
, pbo
, &AdjustedBrushOrigin
,
572 SURFACE
*psurfSrc
= NULL
;
576 PFN_DrvBitBlt pfnBitBlt
;
579 psurfTrg
= CONTAINING_RECORD(psoTrg
, SURFACE
, SurfObj
);
581 /* FIXME: Should we really allow to pass non-well-ordered rects? */
582 rclClipped
= *prclTrg
;
583 RECTL_vMakeWellOrdered(&rclClipped
);
585 //DPRINT1("Rop4 : 0x%08x\n", Rop4);
588 ASSERT(IS_VALID_ROP4(Rop4
));
592 /* Clip target rect against the bounds of the clipping region */
593 if (!RECTL_bIntersectRect(&rclClipped
, &rclClipped
, &pco
->rclBounds
))
599 /* Don't pass a clipobj with only a single rect */
600 if (pco
->iDComplexity
== DC_RECT
)
604 if (ROP4_USES_SOURCE(Rop4
))
607 psurfSrc
= CONTAINING_RECORD(psoSrc
, SURFACE
, SurfObj
);
609 /* Calculate source rect */
610 rclSrc
.left
= pptlSrc
->x
+ rclClipped
.left
- prclTrg
->left
;
611 rclSrc
.top
= pptlSrc
->y
+ rclClipped
.top
- prclTrg
->top
;
612 rclSrc
.right
= rclSrc
.left
+ rclClipped
.right
- rclClipped
.left
;
613 rclSrc
.bottom
= rclSrc
.top
+ rclClipped
.bottom
- rclClipped
.top
;
621 /* Is the target surface device managed? */
622 if (psurfTrg
->flags
& HOOK_BITBLT
)
624 /* Is the source a different device managed surface? */
625 if (psoSrc
&& psoSrc
->hdev
!= psoTrg
->hdev
&& psurfSrc
->flags
& HOOK_BITBLT
)
627 DPRINT1("Need to copy to standard bitmap format!\n");
631 pfnBitBlt
= GDIDEVFUNCS(psoTrg
).BitBlt
;
634 /* Is the source surface device managed? */
635 else if (psoSrc
&& psurfSrc
->flags
& HOOK_BITBLT
)
637 pfnBitBlt
= GDIDEVFUNCS(psoSrc
).BitBlt
;
641 pfnBitBlt
= EngBitBlt
;
644 bResult
= pfnBitBlt(psoTrg
,
656 // FIXME: cleanup temp surface!
662 /**** REACTOS FONT RENDERING CODE *********************************************/
664 /* renders the alpha mask bitmap */
665 static BOOLEAN APIENTRY
666 AlphaBltMask(SURFOBJ
* psoDest
,
667 SURFOBJ
* psoSource
, // unused
669 XLATEOBJ
* pxloRGB2Dest
,
672 POINTL
* pptlSource
, // unused
679 ULONG Background
, BrushColor
, NewColor
;
682 ASSERT(psoSource
== NULL
);
683 ASSERT(pptlSource
== NULL
);
685 dx
= prclDest
->right
- prclDest
->left
;
686 dy
= prclDest
->bottom
- prclDest
->top
;
690 BrushColor
= XLATEOBJ_iXlate(pxloBrush
, pbo
? pbo
->iSolidColor
: 0);
691 r
= (int)GetRValue(BrushColor
);
692 g
= (int)GetGValue(BrushColor
);
693 b
= (int)GetBValue(BrushColor
);
695 tMask
= (PBYTE
)psoMask
->pvScan0
+ (pptlMask
->y
* psoMask
->lDelta
) + pptlMask
->x
;
696 for (j
= 0; j
< dy
; j
++)
699 for (i
= 0; i
< dx
; i
++)
705 DibFunctionsForBitmapFormat
[psoDest
->iBitmapFormat
].DIB_PutPixel(
706 psoDest
, prclDest
->left
+ i
, prclDest
->top
+ j
, pbo
? pbo
->iSolidColor
: 0);
710 Background
= DIB_GetSource(psoDest
, prclDest
->left
+ i
, prclDest
->top
+ j
,
714 RGB((*lMask
* (r
- GetRValue(Background
)) >> 8) + GetRValue(Background
),
715 (*lMask
* (g
- GetGValue(Background
)) >> 8) + GetGValue(Background
),
716 (*lMask
* (b
- GetBValue(Background
)) >> 8) + GetBValue(Background
));
718 Background
= XLATEOBJ_iXlate(pxloRGB2Dest
, NewColor
);
719 DibFunctionsForBitmapFormat
[psoDest
->iBitmapFormat
].DIB_PutPixel(
720 psoDest
, prclDest
->left
+ i
, prclDest
->top
+ j
, Background
);
725 tMask
+= psoMask
->lDelta
;
737 EngMaskBitBlt(SURFOBJ
*psoDest
,
740 XLATEOBJ
*DestColorTranslation
,
741 XLATEOBJ
*SourceColorTranslation
,
755 INTENG_ENTER_LEAVE EnterLeaveSource
;
756 INTENG_ENTER_LEAVE EnterLeaveDest
;
764 POINTL AdjustedBrushOrigin
;
770 InputRect
.left
= pptlMask
->x
;
771 InputRect
.right
= pptlMask
->x
+ (DestRect
->right
- DestRect
->left
);
772 InputRect
.top
= pptlMask
->y
;
773 InputRect
.bottom
= pptlMask
->y
+ (DestRect
->bottom
- DestRect
->top
);
778 InputRect
.right
= DestRect
->right
- DestRect
->left
;
780 InputRect
.bottom
= DestRect
->bottom
- DestRect
->top
;
783 OutputRect
= *DestRect
;
784 if (NULL
!= ClipRegion
)
786 if (OutputRect
.left
< ClipRegion
->rclBounds
.left
)
788 InputRect
.left
+= ClipRegion
->rclBounds
.left
- OutputRect
.left
;
789 OutputRect
.left
= ClipRegion
->rclBounds
.left
;
791 if (ClipRegion
->rclBounds
.right
< OutputRect
.right
)
793 InputRect
.right
-= OutputRect
.right
- ClipRegion
->rclBounds
.right
;
794 OutputRect
.right
= ClipRegion
->rclBounds
.right
;
796 if (OutputRect
.top
< ClipRegion
->rclBounds
.top
)
798 InputRect
.top
+= ClipRegion
->rclBounds
.top
- OutputRect
.top
;
799 OutputRect
.top
= ClipRegion
->rclBounds
.top
;
801 if (ClipRegion
->rclBounds
.bottom
< OutputRect
.bottom
)
803 InputRect
.bottom
-= OutputRect
.bottom
- ClipRegion
->rclBounds
.bottom
;
804 OutputRect
.bottom
= ClipRegion
->rclBounds
.bottom
;
808 if (! IntEngEnter(&EnterLeaveSource
, psoMask
, &InputRect
, TRUE
, &Translate
, &psoInput
))
813 InputPoint
.x
= InputRect
.left
+ Translate
.x
;
814 InputPoint
.y
= InputRect
.top
+ Translate
.y
;
816 /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
818 if (OutputRect
.right
<= OutputRect
.left
|| OutputRect
.bottom
<= OutputRect
.top
)
820 IntEngLeave(&EnterLeaveSource
);
824 if (! IntEngEnter(&EnterLeaveDest
, psoDest
, &OutputRect
, FALSE
, &Translate
, &psoOutput
))
826 IntEngLeave(&EnterLeaveSource
);
830 OutputRect
.left
= DestRect
->left
+ Translate
.x
;
831 OutputRect
.right
= DestRect
->right
+ Translate
.x
;
832 OutputRect
.top
= DestRect
->top
+ Translate
.y
;
833 OutputRect
.bottom
= DestRect
->bottom
+ Translate
.y
;
837 AdjustedBrushOrigin
.x
= BrushOrigin
->x
+ Translate
.x
;
838 AdjustedBrushOrigin
.y
= BrushOrigin
->y
+ Translate
.y
;
841 AdjustedBrushOrigin
= Translate
;
843 // Determine clipping type
844 if (ClipRegion
== (CLIPOBJ
*) NULL
)
846 clippingType
= DC_TRIVIAL
;
848 clippingType
= ClipRegion
->iDComplexity
;
851 switch (clippingType
)
854 if (psoMask
->iBitmapFormat
== BMF_8BPP
)
855 Ret
= AlphaBltMask(psoOutput
, NULL
, psoInput
, DestColorTranslation
, SourceColorTranslation
,
856 &OutputRect
, NULL
, &InputPoint
, pbo
, &AdjustedBrushOrigin
);
858 Ret
= BltMask(psoOutput
, NULL
, psoInput
, DestColorTranslation
,
859 &OutputRect
, NULL
, &InputPoint
, pbo
, &AdjustedBrushOrigin
,
863 // Clip the blt to the clip rectangle
864 ClipRect
.left
= ClipRegion
->rclBounds
.left
+ Translate
.x
;
865 ClipRect
.right
= ClipRegion
->rclBounds
.right
+ Translate
.x
;
866 ClipRect
.top
= ClipRegion
->rclBounds
.top
+ Translate
.y
;
867 ClipRect
.bottom
= ClipRegion
->rclBounds
.bottom
+ Translate
.y
;
868 if (RECTL_bIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
870 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
871 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
872 if (psoMask
->iBitmapFormat
== BMF_8BPP
)
874 Ret
= AlphaBltMask(psoOutput
, NULL
, psoInput
, DestColorTranslation
, SourceColorTranslation
,
875 &CombinedRect
, NULL
, &Pt
, pbo
, &AdjustedBrushOrigin
);
879 Ret
= BltMask(psoOutput
, NULL
, psoInput
, DestColorTranslation
,
880 &CombinedRect
, NULL
, &Pt
, pbo
, &AdjustedBrushOrigin
, ROP4_MASK
);
886 if (psoOutput
== psoInput
)
888 if (OutputRect
.top
< InputPoint
.y
)
890 Direction
= OutputRect
.left
< InputPoint
.x
? CD_RIGHTDOWN
: CD_LEFTDOWN
;
894 Direction
= OutputRect
.left
< InputPoint
.x
? CD_RIGHTUP
: CD_LEFTUP
;
901 CLIPOBJ_cEnumStart(ClipRegion
, FALSE
, CT_RECTANGLES
, Direction
, 0);
904 EnumMore
= CLIPOBJ_bEnum(ClipRegion
,(ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
906 for (i
= 0; i
< RectEnum
.c
; i
++)
908 ClipRect
.left
= RectEnum
.arcl
[i
].left
+ Translate
.x
;
909 ClipRect
.right
= RectEnum
.arcl
[i
].right
+ Translate
.x
;
910 ClipRect
.top
= RectEnum
.arcl
[i
].top
+ Translate
.y
;
911 ClipRect
.bottom
= RectEnum
.arcl
[i
].bottom
+ Translate
.y
;
912 if (RECTL_bIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
914 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
915 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
916 if (psoMask
->iBitmapFormat
== BMF_8BPP
)
918 Ret
= AlphaBltMask(psoOutput
, NULL
, psoInput
,
919 DestColorTranslation
,
920 SourceColorTranslation
,
921 &CombinedRect
, NULL
, &Pt
, pbo
,
922 &AdjustedBrushOrigin
) && Ret
;
926 Ret
= BltMask(psoOutput
, NULL
, psoInput
,
927 DestColorTranslation
, &CombinedRect
, NULL
,
928 &Pt
, pbo
, &AdjustedBrushOrigin
,
939 IntEngLeave(&EnterLeaveDest
);
940 IntEngLeave(&EnterLeaveSource
);
946 IntEngMaskBlt(SURFOBJ
*psoDest
,
949 XLATEOBJ
*DestColorTranslation
,
950 XLATEOBJ
*SourceColorTranslation
,
959 //SURFACE *psurfDest;
965 InputPoint
= *pptlMask
;
968 /* Clip against the bounds of the clipping region so we won't try to write
969 * outside the surface */
970 if (NULL
!= ClipRegion
)
972 if (!RECTL_bIntersectRect(&OutputRect
, DestRect
, &ClipRegion
->rclBounds
))
976 InputPoint
.x
+= OutputRect
.left
- DestRect
->left
;
977 InputPoint
.y
+= OutputRect
.top
- DestRect
->top
;
981 OutputRect
= *DestRect
;
987 //psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
989 /* Dummy BitBlt to let driver know that it should flush its changes.
990 This should really be done using a call to DrvSynchronizeSurface,
991 but the VMware driver doesn't hook that call. */
992 IntEngBitBlt(psoDest
, NULL
, psoMask
, ClipRegion
, DestColorTranslation
,
993 DestRect
, pptlMask
, pptlMask
, pbo
, BrushOrigin
,
996 ret
= EngMaskBitBlt(psoDest
, psoMask
, ClipRegion
, DestColorTranslation
, SourceColorTranslation
,
997 &OutputRect
, &InputPoint
, pbo
, BrushOrigin
);
999 /* Dummy BitBlt to let driver know that something has changed. */
1000 IntEngBitBlt(psoDest
, NULL
, psoMask
, ClipRegion
, DestColorTranslation
,
1001 DestRect
, pptlMask
, pptlMask
, pbo
, BrushOrigin
,